Compare commits

...

31 Commits

Author SHA1 Message Date
Blank ba0d193eb1
Merge 60fe96fb9c into f0ed677d86 2024-12-16 15:02:45 +08:00
何冠峰 f0ed677d86 refactor : remove DryRunBuild build mode
移除演练构建模式
2024-12-13 14:32:17 +08:00
何冠峰 4b0c52d2dd fix #404 2024-12-13 14:10:12 +08:00
何冠峰 5f4e1d0b2f update package
scriptablebuildpipeline版本切换为1.21.25
2024-12-13 11:44:55 +08:00
何冠峰 a98a48a58d Update TaskCreateManifest.cs 2024-12-13 11:12:09 +08:00
何冠峰 763054884b fix #387 2024-12-13 11:00:30 +08:00
何冠峰 376088e63c update space shoot 2024-12-13 10:25:56 +08:00
何冠峰 c614ba4705 fix #402 2024-12-13 10:25:16 +08:00
何冠峰 14ea408fec fix #386 2024-12-12 18:13:33 +08:00
何冠峰 038a52f7fc Update ResourcePackage.cs 2024-12-12 17:59:04 +08:00
何冠峰 341bd5947f update extension sample 2024-12-12 17:55:39 +08:00
何冠峰 b5d857d2f1 fix #380
新增示例文件 CopyBuildinManifestOperation
2024-12-12 17:53:34 +08:00
何冠峰 97f9a3d4b1 refactor : default cache file system 2024-12-12 17:35:42 +08:00
何冠峰 9607d7135b refactor : cache system 2024-12-12 15:16:34 +08:00
何冠峰 b1338a9ffd refactor : cache file system 2024-12-12 15:00:08 +08:00
何冠峰 bf1e3da298 feat : remove delivery file system
Host Play Mode 移除了DeliveryFileSystemParameters
2024-12-11 18:43:15 +08:00
何冠峰 a91cbee50c update space shooter 2024-12-11 18:24:55 +08:00
何冠峰 15fbbf3873 Update InitializeParameters.cs 2024-12-11 18:24:40 +08:00
何冠峰 f73abba79f feat : web play mode support remote services
WebPlayMode支持跨域加载。
2024-12-11 18:19:09 +08:00
何冠峰 5fa9ebee80 feat : package manifest add note info
清单文件增加备注信息
2024-12-11 11:22:50 +08:00
何冠峰 d890ccd5e6 feat : default editor file system support async simulate frame
编辑器文件系统支持异步模拟加载帧数
2024-12-11 10:43:13 +08:00
何冠峰 e76a782a80 Update ResourcePackage.cs 2024-12-11 10:04:33 +08:00
何冠峰 0f7c5b2564 Update ResourcePackage.cs 2024-12-10 18:41:09 +08:00
何冠峰 fcf0f34d5a update resource manager 2024-12-10 18:00:13 +08:00
何冠峰 acf2301028 refactor : wait for sync complete 2024-12-10 16:48:08 +08:00
何冠峰 9bc0577423 Update DefaultIgnoreRule.cs
忽略Gizmos和编辑器资源
2024-12-10 15:18:34 +08:00
何冠峰 d037ce5b86 Update LoadBundleFileOperation.cs 2024-12-10 15:17:49 +08:00
Blank 60fe96fb9c
[增加]增加下载状态变化的时候包名称的返回
1.主要是如果在同时下载包的时候且注册到统一的返回事件的时候无法识别当前是什么包下载的返回结果.这样给开发者有一定的操作成本.需要独立的去记录包和下载列表的关系
2024-08-27 19:19:42 +08:00
Blank dda2a4c659
[增加] 增加日志打印的标记和时间
1. 该日志标记在查询定位的时候非常有用.主要区分是否是业务日志还是资源日志.
2. 关于时间:可以查看在真机上的资源加载时间长短和资源问题的定位.
2024-08-27 19:16:18 +08:00
Blank a6b333fe35
[修改] 修改外部可以获取当前操作对象的包名称
1. 主要是外部如果是回调的时候,不一定在之前的代码位置了.所需要需要从操作对象中直接获取当前的包名
2024-08-27 19:13:36 +08:00
Blank 850ae88bc6
[增加]1. 增加是否加载成功的快捷判断属性
1. 该接口主要方便于外部直接判断是否成功,而无需再次使用枚举的方式判断
2024-08-27 19:10:43 +08:00
146 changed files with 2536 additions and 1433 deletions

View File

@ -46,6 +46,10 @@ namespace YooAsset.Editor
/// </summary>
public string PackageVersion;
/// <summary>
/// 构建的包裹备注
/// </summary>
public string PackageNote;
/// <summary>
/// 是否启用共享资源打包
@ -159,6 +163,12 @@ namespace YooAsset.Editor
{
BuildLogger.Log($"Create pipeline output directory: {pipelineOutputDirectory}");
}
// 设置默认备注信息
if (string.IsNullOrEmpty(PackageNote))
{
PackageNote = DateTime.Now.ToString();
}
}

View File

@ -25,6 +25,9 @@ namespace YooAsset.Editor
var buildParameters = buildParametersContext.Parameters;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
// 检测资源包哈希冲突
CheckBundleHashConflict(buildMapContext);
// 创建新补丁清单
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
@ -35,6 +38,7 @@ namespace YooAsset.Editor
manifest.BuildPipeline = buildParameters.BuildPipeline;
manifest.PackageName = buildParameters.PackageName;
manifest.PackageVersion = buildParameters.PackageVersion;
manifest.PackageNote = buildParameters.PackageNote;
manifest.BundleList = GetAllPackageBundle(buildMapContext);
manifest.AssetList = GetAllPackageAsset(buildMapContext);
@ -87,6 +91,28 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 检测资源包哈希冲突
/// </summary>
private void CheckBundleHashConflict(BuildMapContext buildMapContext)
{
// 说明:在特殊情况下,例如某些文件加密算法会导致加密后的文件哈希值冲突!
// 说明:二进制完全相同的原生文件也会冲突!
HashSet<string> guids = new HashSet<string>();
foreach (var bundleInfo in buildMapContext.Collection)
{
if (guids.Contains(bundleInfo.PackageFileHash))
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BundleHashConflict, $"Bundle hash conflict : {bundleInfo.BundleName}");
throw new Exception(message);
}
else
{
guids.Add(bundleInfo.PackageFileHash);
}
}
}
/// <summary>
/// 获取资源包的依赖集合
/// </summary>

View File

@ -31,6 +31,7 @@ namespace YooAsset.Editor
buildReport.Summary.BuildMode = buildParameters.BuildMode;
buildReport.Summary.BuildPackageName = buildParameters.PackageName;
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.BuildPackageNote = buildParameters.PackageNote;
// 收集器配置
buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;

View File

@ -35,14 +35,12 @@ namespace YooAsset.Editor
throw new Exception(message);
}
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
// 检测输出目录
string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
if (System.IO.File.Exists(unityOutputManifestFilePath) == false)
{
string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
if (System.IO.File.Exists(unityOutputManifestFilePath) == false)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.UnityEngineBuildFatal, $"Not found output {nameof(AssetBundleManifest)} file : {unityOutputManifestFilePath}");
throw new Exception(message);
}
string message = BuildLogger.GetErrorMessage(ErrorCode.UnityEngineBuildFatal, $"Not found output {nameof(AssetBundleManifest)} file : {unityOutputManifestFilePath}");
throw new Exception(message);
}
BuildLogger.Log("UnityEngine build success !");

View File

@ -10,7 +10,7 @@ namespace YooAsset.Editor
var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode != EBuildMode.SimulateBuild && buildMode != EBuildMode.DryRunBuild)
if (buildMode != EBuildMode.SimulateBuild)
{
CreatePackageCatalog(buildParameters, buildMapContext);
}

View File

@ -18,7 +18,7 @@ namespace YooAsset.Editor
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
if (buildMode == EBuildMode.SimulateBuild)
{
return "00000000000000000000000000000000"; //32位
}
@ -42,7 +42,7 @@ namespace YooAsset.Editor
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
if (buildMode == EBuildMode.SimulateBuild)
{
return 0;
}
@ -64,7 +64,7 @@ namespace YooAsset.Editor
{
string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
if (buildMode == EBuildMode.SimulateBuild)
return GetFilePathTempHash(filePath);
else
return HashUtility.FileMD5(filePath);
@ -73,7 +73,7 @@ namespace YooAsset.Editor
{
string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
if ( buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位
else
return HashUtility.FileCRC32(filePath);
@ -82,7 +82,7 @@ namespace YooAsset.Editor
{
string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
if (buildMode == EBuildMode.SimulateBuild)
return GetBundleTempSize(bundleInfo);
else
return FileUtility.GetFileSize(filePath);

View File

@ -34,12 +34,6 @@ namespace YooAsset.Editor
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
if (BuildMode == EBuildMode.DryRunBuild)
{
opt |= BuildAssetBundleOptions.DryRunBuild;
return opt;
}
if (CompressOption == ECompressOption.Uncompressed)
opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
else if (CompressOption == ECompressOption.LZ4)

View File

@ -24,11 +24,6 @@ namespace YooAsset.Editor
}
// 检测不被支持的构建模式
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.RawFileBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
throw new Exception(message);
}
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.RawFileBuildPipeline)} not support {nameof(EBuildMode.IncrementalBuild)} build mode !");

View File

@ -32,7 +32,7 @@ namespace YooAsset.Editor
// 开始构建
IBundleBuildResults buildResults;
var buildParameters = scriptableBuildParameters.GetBundleBuildParameters();
var taskList = SBPBuildTasks.Create(buildMapContext.Command.ShadersBundleName);
var taskList = SBPBuildTasks.Create(buildMapContext.Command.ShadersBundleName, null);
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
if (exitCode < 0)
{

View File

@ -17,11 +17,6 @@ namespace YooAsset.Editor
buildParametersContext.CheckBuildParameters();
// 检测不被支持的构建模式
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
throw new Exception(message);
}
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");

View File

@ -9,7 +9,7 @@ namespace UnityEditor.Build.Pipeline.Tasks
{
public static class SBPBuildTasks
{
public static IList<IBuildTask> Create(string builtInShaderBundleName)
public static IList<IBuildTask> Create(string builtInShaderBundleName, string unityMonoScriptsBundleName)
{
var buildTasks = new List<IBuildTask>();
@ -28,13 +28,10 @@ namespace UnityEditor.Build.Pipeline.Tasks
#endif
buildTasks.Add(new CalculateAssetDependencyData());
buildTasks.Add(new StripUnusedSpriteSources());
#if TUANJIE_1_0_OR_NEWER
buildTasks.Add(new CreateBuiltInShadersBundle(builtInShaderBundleName));
#else
buildTasks.Add(new CreateBuiltInBundle(builtInShaderBundleName));
#endif
if (string.IsNullOrEmpty(builtInShaderBundleName) == false)
buildTasks.Add(new CreateBuiltInShadersBundle(builtInShaderBundleName));
if (string.IsNullOrEmpty(unityMonoScriptsBundleName) == false)
buildTasks.Add(new CreateMonoScriptBundle(unityMonoScriptsBundleName));
buildTasks.Add(new PostDependencyCallback());
// Packing

View File

@ -39,5 +39,6 @@ namespace YooAsset.Editor
// TaskCreateManifest
NotFoundUnityBundleInBuildResult = 600,
FoundStrayBundle = 601,
BundleHashConflict = 602,
}
}

View File

@ -16,11 +16,6 @@ namespace YooAsset.Editor
/// </summary>
IncrementalBuild,
/// <summary>
/// 演练构建模式
/// </summary>
DryRunBuild,
/// <summary>
/// 模拟构建模式
/// </summary>

View File

@ -55,7 +55,6 @@ namespace YooAsset.Editor
List<Enum> buildModeList = new List<Enum>();
buildModeList.Add(EBuildMode.ForceRebuild);
buildModeList.Add(EBuildMode.IncrementalBuild);
buildModeList.Add(EBuildMode.DryRunBuild);
buildModeList.Add(EBuildMode.SimulateBuild);
return buildModeList;
}

View File

@ -33,6 +33,14 @@ namespace YooAsset.Editor
if (AssetDatabase.IsValidFolder(assetInfo.AssetPath))
return true;
// 忽略编辑器图标资源
if (assetInfo.AssetPath.Contains("/Gizmos/"))
return true;
// 忽略编辑器专属资源
if (assetInfo.AssetPath.Contains("/Editor/") || assetInfo.AssetPath.Contains("/Editor Resources/"))
return true;
// 忽略编辑器下的类型资源
if (assetInfo.AssetType == typeof(LightingDataAsset))
return true;

View File

@ -53,6 +53,11 @@ namespace YooAsset.Editor
/// </summary>
public string BuildPackageVersion;
/// <summary>
/// 构建包裹备注
/// </summary>
public string BuildPackageNote;
// 收集器配置
public bool UniqueBundleName;
public bool EnableAddressable;

View File

@ -65,6 +65,7 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("Build Mode", $"{buildReport.Summary.BuildMode}"));
_items.Add(new ItemWrapper("Package Name", buildReport.Summary.BuildPackageName));
_items.Add(new ItemWrapper("Package Version", buildReport.Summary.BuildPackageVersion));
_items.Add(new ItemWrapper("Package Note", buildReport.Summary.BuildPackageNote));
_items.Add(new ItemWrapper(string.Empty, string.Empty));
_items.Add(new ItemWrapper("Collect Settings", string.Empty));

View File

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

View File

@ -0,0 +1,38 @@
using System.IO;
namespace YooAsset
{
internal class CacheFileElement
{
public string PackageName { private set; get; }
public string BundleGUID { private set; get; }
public string FileRootPath { private set; get; }
public string DataFilePath { private set; get; }
public string InfoFilePath { private set; get; }
public EFileVerifyResult Result;
public string DataFileCRC;
public long DataFileSize;
public CacheFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath)
{
PackageName = packageName;
BundleGUID = bundleGUID;
FileRootPath = fileRootPath;
DataFilePath = dataFilePath;
InfoFilePath = infoFilePath;
}
public void DeleteFiles()
{
try
{
Directory.Delete(FileRootPath, true);
}
catch (System.Exception e)
{
YooLogger.Warning($"Failed to delete cache bundle folder : {e}");
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e9fe9171073a87746a7393f7d1fcb924
guid: 0c361449cdcbd8746ba3fb948798ae1b
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,25 @@
using System;
using System.IO;
namespace YooAsset
{
internal class CacheHelper
{
/// <summary>
/// 获取默认的缓存根目录
/// </summary>
public static string GetDefaultCacheRoot()
{
#if UNITY_EDITOR
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
projectPath = PathUtility.RegularPath(projectPath);
return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#elif UNITY_STANDALONE
return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#else
return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#endif
}
}
}

View File

@ -0,0 +1,19 @@

namespace YooAsset
{
internal class CacheWrapper
{
public string InfoFilePath { private set; get; }
public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; }
public long DataFileSize { private set; get; }
public CacheWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;
DataFileCRC = dataFileCRC;
DataFileSize = dataFileSize;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 857423cdfd4f9184eab094be01c62480
guid: ae2176c4ea6fbb3478bf8757def34cd7
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

@ -0,0 +1,67 @@
using System.Collections.Generic;
namespace YooAsset
{
internal interface ICacheSystem
{
/// <summary>
/// 获取缓存文件的根目录
/// </summary>
string GetCacheFileRoot();
/// <summary>
/// 获取临时缓存文件路径
/// </summary>
string GetTempFilePath(PackageBundle bundle);
/// <summary>
/// 获取数据文件路径
/// </summary>
string GetDataFilePath(PackageBundle bundle);
/// <summary>
/// 获取信息文件路径
/// </summary>
string GetInfoFilePath(PackageBundle bundle);
/// <summary>
/// 获取所有缓存文件的GUID
/// </summary>
List<string> GetAllCachedBundleGUIDs();
/// <summary>
/// 是否记录了文件
/// </summary>
bool IsRecordFile(string bundleGUID);
/// <summary>
/// 记录指定文件
/// </summary>
bool RecordFile(string bundleGUID, CacheWrapper wrapper);
/// <summary>
/// 验证缓存文件
/// </summary>
EFileVerifyResult VerifyCacheFile(PackageBundle bundle);
/// <summary>
/// 写入缓存文件
/// </summary>
bool WriteCacheFile(PackageBundle bundle, string copyPath);
/// <summary>
/// 删除缓存文件
/// </summary>
bool DeleteCacheFile(string bundleGUID);
/// <summary>
/// 写入文件信息
/// </summary>
void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize);
/// <summary>
/// 读取文件信息
/// </summary>
void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize);
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 4f25029d71d0d8c4dad70987bda364bf
guid: f878bc9a12f5d2d40aee754ddfaada86
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace YooAsset
{
internal sealed class DCFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation
internal sealed class ClearAllCacheFilesOperation : FSClearCacheBundleFilesOperation
{
private enum ESteps
{
@ -13,15 +13,15 @@ namespace YooAsset
Done,
}
private readonly DefaultCacheFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private List<string> _allBundleGUIDs;
private int _fileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal DCFSClearAllBundleFilesOperation(DefaultCacheFileSystem fileSystem)
internal ClearAllCacheFilesOperation(ICacheSystem cacheSystem)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
}
internal override void InternalOnStart()
{
@ -34,7 +34,7 @@ namespace YooAsset
if (_steps == ESteps.GetAllCacheFiles)
{
_allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
_allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
_fileTotalCount = _allBundleGUIDs.Count;
_steps = ESteps.ClearAllCacheFiles;
YooLogger.Log($"Found all cache files count : {_fileTotalCount}");
@ -45,7 +45,7 @@ namespace YooAsset
for (int i = _allBundleGUIDs.Count - 1; i >= 0; i--)
{
string bundleGUID = _allBundleGUIDs[i];
_fileSystem.DeleteCacheFile(bundleGUID);
_cacheSystem.DeleteCacheFile(bundleGUID);
_allBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;

View File

@ -0,0 +1,120 @@
using System.Collections.Generic;
namespace YooAsset
{
internal class ClearCacheFilesByTagsOperaiton : FSClearCacheBundleFilesOperation
{
private enum ESteps
{
None,
CheckArgs,
GetTagsCacheFiles,
ClearTagsCacheFiles,
Done,
}
private readonly ICacheSystem _cacheSystem;
private readonly PackageManifest _manifest;
private readonly object _clearParam;
private string[] _tags;
private List<string> _clearBundleGUIDs;
private int _clearFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearCacheFilesByTagsOperaiton(ICacheSystem cacheSystem, PackageManifest manifest, object clearParam)
{
_cacheSystem = cacheSystem;
_manifest = manifest;
_clearParam = clearParam;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckArgs;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckArgs)
{
if (_clearParam == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Clear param is null !";
return;
}
if (_clearParam is string)
{
_tags = new string[] { _clearParam as string };
}
else if (_clearParam is List<string>)
{
var tempList = _clearParam as List<string>;
_tags = tempList.ToArray();
}
else if (_clearParam is string[])
{
_tags = _clearParam as string[];
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Invalid clear param : {_clearParam.GetType().FullName}";
return;
}
_steps = ESteps.GetTagsCacheFiles;
}
if (_steps == ESteps.GetTagsCacheFiles)
{
_clearBundleGUIDs = GetTagsBundleGUIDs();
_clearFileTotalCount = _clearBundleGUIDs.Count;
_steps = ESteps.ClearTagsCacheFiles;
}
if (_steps == ESteps.ClearTagsCacheFiles)
{
for (int i = _clearBundleGUIDs.Count - 1; i >= 0; i--)
{
string bundleGUID = _clearBundleGUIDs[i];
_cacheSystem.DeleteCacheFile(bundleGUID);
_clearBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
if (_clearFileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_clearBundleGUIDs.Count / _clearFileTotalCount);
if (_clearBundleGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
private List<string> GetTagsBundleGUIDs()
{
var allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
List<string> result = new List<string>(allBundleGUIDs.Count);
foreach (var bundleGUID in allBundleGUIDs)
{
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle bundle))
{
if (bundle.HasTag(_tags))
{
result.Add(bundleGUID);
}
}
}
return result;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d6f813e2460f55e4ba3f54527e6999e3
guid: c42345c14a903274fb160a813ee174dc
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace YooAsset
{
internal sealed class DCFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation
internal sealed class ClearUnusedCacheFilesOperation : FSClearCacheBundleFilesOperation
{
private enum ESteps
{
@ -13,16 +13,16 @@ namespace YooAsset
Done,
}
private readonly DefaultCacheFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly PackageManifest _manifest;
private List<string> _unusedBundleGUIDs;
private int _unusedFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal DCFSClearUnusedBundleFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest)
internal ClearUnusedCacheFilesOperation(ICacheSystem cacheSystem, PackageManifest manifest)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
_manifest = manifest;
}
internal override void InternalOnStart()
@ -47,7 +47,7 @@ namespace YooAsset
for (int i = _unusedBundleGUIDs.Count - 1; i >= 0; i--)
{
string bundleGUID = _unusedBundleGUIDs[i];
_fileSystem.DeleteCacheFile(bundleGUID);
_cacheSystem.DeleteCacheFile(bundleGUID);
_unusedBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
@ -68,7 +68,7 @@ namespace YooAsset
private List<string> GetUnusedBundleGUIDs()
{
var allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
var allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
List<string> result = new List<string>(allBundleGUIDs.Count);
foreach (var bundleGUID in allBundleGUIDs)
{

View File

@ -0,0 +1,199 @@
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal sealed class DownloadNormalFileOperation : DefaultDownloadFileOperation
{
private readonly IFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private VerifyTempFileOperation _verifyOperation;
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DownloadNormalFileOperation(IFileSystem fileSystem, ICacheSystem cacheSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
}
internal override void InternalOnStart()
{
_tempFilePath = _cacheSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 检测文件是否存在
if (_steps == ESteps.CheckExists)
{
if (_fileSystem.Exists(Bundle))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.CreateRequest;
}
}
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
FileUtility.CreateFileDirectory(_tempFilePath);
// 删除临时文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
// 获取请求地址
_requestURL = GetRequestURL();
// 重置请求
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
_steps = ESteps.VerifyTempFile;
else
_steps = ESteps.TryAgain;
// 注意:最终释放请求器
DisposeWebRequest();
}
// 验证下载文件
if (_steps == ESteps.VerifyTempFile)
{
var element = new TempFileElement(_tempFilePath, Bundle.FileCRC, Bundle.FileSize);
_verifyOperation = new VerifyTempFileOperation(element);
OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation);
_steps = ESteps.CheckVerifyTempFile;
}
// 等待验证完成
if (_steps == ESteps.CheckVerifyTempFile)
{
if (IsWaitForAsyncComplete)
_verifyOperation.WaitForAsyncComplete();
if (_verifyOperation.IsDone == false)
return;
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_cacheSystem.WriteCacheFile(Bundle, _tempFilePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
YooLogger.Error(Error);
}
}
else
{
_steps = ESteps.TryAgain;
Error = _verifyOperation.Error;
}
// 注意:验证完成后直接删除文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
internal override void InternalWaitForAsyncComplete()
{
bool isReuqestLocalFile = IsRequestLocalFile();
while (true)
{
// 注意:如果是导入或解压本地文件,执行等待完毕
if (isReuqestLocalFile)
{
InternalOnUpdate();
if (IsDone)
break;
}
else
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
}
private void CreateWebRequest()
{
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}

View File

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

View File

@ -1,203 +1,15 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal sealed class DCFSDownloadNormalFileOperation : DefaultDownloadFileOperation
internal sealed class DownloadResumeFileOperation : DefaultDownloadFileOperation
{
private readonly DefaultCacheFileSystem _fileSystem;
private VerifyTempFileOperation _verifyOperation;
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DCFSDownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 检测文件是否存在
if (_steps == ESteps.CheckExists)
{
if (_fileSystem.Exists(Bundle))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.CreateRequest;
}
}
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
FileUtility.CreateFileDirectory(_tempFilePath);
// 删除临时文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
// 获取请求地址
_requestURL = GetRequestURL();
// 重置请求
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
_steps = ESteps.VerifyTempFile;
else
_steps = ESteps.TryAgain;
// 注意:最终释放请求器
DisposeWebRequest();
}
// 验证下载文件
if (_steps == ESteps.VerifyTempFile)
{
var element = new TempFileElement(_tempFilePath, Bundle.FileCRC, Bundle.FileSize);
_verifyOperation = new VerifyTempFileOperation(element);
OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation);
_steps = ESteps.CheckVerifyTempFile;
}
// 等待验证完成
if (_steps == ESteps.CheckVerifyTempFile)
{
if (_verifyOperation.IsDone == false)
return;
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_fileSystem.WriteCacheFile(Bundle, _tempFilePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
YooLogger.Error(Error);
}
}
else
{
_steps = ESteps.TryAgain;
Error = _verifyOperation.Error;
}
// 注意:验证完成后直接删除文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
internal override void InternalWaitForAsyncComplete()
{
bool isReuqestLocalFile = IsRequestLocalFile();
while (true)
{
if (_verifyOperation != null)
_verifyOperation.WaitForAsyncComplete();
// 注意:如果是导入或解压本地文件,执行等待完毕
if (isReuqestLocalFile)
{
InternalOnUpdate();
if (IsDone)
break;
}
else
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
}
private void CreateWebRequest()
{
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
internal sealed class DCFSDownloadResumeFileOperation : DefaultDownloadFileOperation
{
private readonly DefaultCacheFileSystem _fileSystem;
private readonly IFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly List<long> _responseCodes;
private DownloadHandlerFileRange _downloadHandle;
private VerifyTempFileOperation _verifyOperation;
private long _fileOriginLength = 0;
@ -205,13 +17,15 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DCFSDownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadResumeFileOperation(IFileSystem fileSystem, ICacheSystem cacheSystem, PackageBundle bundle, DownloadParam param, List<long> responseCodes) : base(bundle, param)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
_responseCodes = responseCodes;
}
internal override void InternalOnStart()
{
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_tempFilePath = _cacheSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalOnUpdate()
@ -305,12 +119,15 @@ namespace YooAsset
// 等待验证完成
if (_steps == ESteps.CheckVerifyTempFile)
{
if (IsWaitForAsyncComplete)
_verifyOperation.WaitForAsyncComplete();
if (_verifyOperation.IsDone == false)
return;
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_fileSystem.WriteCacheFile(Bundle, _tempFilePath))
if (_cacheSystem.WriteCacheFile(Bundle, _tempFilePath))
{
Status = EOperationStatus.Succeed;
_steps = ESteps.Done;
@ -364,9 +181,6 @@ namespace YooAsset
while (true)
{
if (_verifyOperation != null)
_verifyOperation.WaitForAsyncComplete();
// 注意:如果是导入或解压本地文件,执行等待完毕
if (isReuqestLocalFile)
{
@ -418,11 +232,11 @@ namespace YooAsset
}
private void ClearTempFileWhenError()
{
if (_fileSystem.ResumeDownloadResponseCodes == null)
if (_responseCodes == null)
return;
//说明:如果遇到以下错误返回码,验证失败直接删除文件
if (_fileSystem.ResumeDownloadResponseCodes.Contains(HttpCode))
if (_responseCodes.Contains(HttpCode))
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);

View File

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

View File

@ -15,7 +15,9 @@ namespace YooAsset
Done,
}
private readonly DefaultCacheFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly string _packageName;
private readonly bool _appendFileExtension;
private IEnumerator<DirectoryInfo> _filesEnumerator = null;
private float _verifyStartTime;
private ESteps _steps = ESteps.None;
@ -26,9 +28,11 @@ namespace YooAsset
public readonly List<CacheFileElement> Result = new List<CacheFileElement>(5000);
internal SearchCacheFilesOperation(DefaultCacheFileSystem fileSystem)
internal SearchCacheFilesOperation(ICacheSystem cacheSystem, string packageName, bool appendFileExtension)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
_packageName = packageName;
_appendFileExtension = appendFileExtension;
}
internal override void InternalOnStart()
{
@ -42,7 +46,7 @@ namespace YooAsset
if (_steps == ESteps.Prepare)
{
DirectoryInfo rootDirectory = new DirectoryInfo(_fileSystem.GetCacheFilesRoot());
DirectoryInfo rootDirectory = new DirectoryInfo(_cacheSystem.GetCacheFileRoot());
if (rootDirectory.Exists)
{
var directorieInfos = rootDirectory.EnumerateDirectories();
@ -80,7 +84,7 @@ namespace YooAsset
foreach (var chidDirectory in childDirectories)
{
string bundleGUID = chidDirectory.Name;
if (_fileSystem.IsRecordFile(bundleGUID))
if (_cacheSystem.IsRecordFile(bundleGUID))
continue;
// 创建验证元素类
@ -89,14 +93,14 @@ namespace YooAsset
string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleInfoFileName}";
// 存储的数据文件追加文件格式
if (_fileSystem.AppendFileExtension)
if (_appendFileExtension)
{
string dataFileExtension = FindDataFileExtension(chidDirectory);
if (string.IsNullOrEmpty(dataFileExtension) == false)
dataFilePath += dataFileExtension;
}
var element = new CacheFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);
var element = new CacheFileElement(_packageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);
Result.Add(element);
}

View File

@ -6,44 +6,10 @@ using System.Threading;
namespace YooAsset
{
internal class CacheFileElement
{
public string PackageName { private set; get; }
public string BundleGUID { private set; get; }
public string FileRootPath { private set; get; }
public string DataFilePath { private set; get; }
public string InfoFilePath { private set; get; }
public EFileVerifyResult Result;
public string DataFileCRC;
public long DataFileSize;
public CacheFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath)
{
PackageName = packageName;
BundleGUID = bundleGUID;
FileRootPath = fileRootPath;
DataFilePath = dataFilePath;
InfoFilePath = infoFilePath;
}
public void DeleteFiles()
{
try
{
Directory.Delete(FileRootPath, true);
}
catch (System.Exception e)
{
YooLogger.Warning($"Failed to delete cache bundle folder : {e}");
}
}
}
/// <summary>
/// 缓存文件验证(线程版)
/// </summary>
internal class VerifyCacheFilesOperation : AsyncOperationBase
internal sealed class VerifyCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
@ -54,10 +20,10 @@ namespace YooAsset
}
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
private readonly DefaultCacheFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly EFileVerifyLevel _verifyLevel;
private List<CacheFileElement> _waitingList;
private List<CacheFileElement> _verifyingList;
private EFileVerifyLevel _verifyLevel = EFileVerifyLevel.Middle;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
@ -66,11 +32,11 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal VerifyCacheFilesOperation(DefaultCacheFileSystem fileSystem, List<CacheFileElement> elements)
internal VerifyCacheFilesOperation(ICacheSystem cacheSystem, EFileVerifyLevel verifyLevel, List<CacheFileElement> elements)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
_verifyLevel = verifyLevel;
_waitingList = elements;
_verifyLevel = _fileSystem.FileVerifyLevel;
}
internal override void InternalOnStart()
{
@ -158,8 +124,8 @@ namespace YooAsset
if (element.Result == EFileVerifyResult.Succeed)
{
_succeedCount++;
var fileWrapper = new DefaultCacheFileSystem.FileWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_fileSystem.RecordFile(element.BundleGUID, fileWrapper);
var fileWrapper = new CacheWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cacheSystem.RecordFile(element.BundleGUID, fileWrapper);
}
else
{
@ -191,7 +157,7 @@ namespace YooAsset
return EFileVerifyResult.InfoFileNotExisted;
// 解析信息文件获取验证数据
_fileSystem.ReadInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
_cacheSystem.ReadInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
}
}
catch (Exception)
@ -199,7 +165,7 @@ namespace YooAsset
return EFileVerifyResult.Exception;
}
return FileSystemHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
return FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
}
}
}

View File

@ -3,29 +3,10 @@ using System.Threading;
namespace YooAsset
{
internal class TempFileElement
{
public string TempFilePath { private set; get; }
public string TempFileCRC { private set; get; }
public long TempFileSize { private set; get; }
/// <summary>
/// 注意:原子操作对象
/// </summary>
public int Result = 0;
public TempFileElement(string filePath, string fileCRC, long fileSize)
{
TempFilePath = filePath;
TempFileCRC = fileCRC;
TempFileSize = fileSize;
}
}
/// <summary>
/// 下载文件验证(线程版)
/// </summary>
internal class VerifyTempFileOperation : AsyncOperationBase
internal sealed class VerifyTempFileOperation : AsyncOperationBase
{
private enum ESteps
{
@ -41,7 +22,7 @@ namespace YooAsset
/// <summary>
/// 验证结果
/// </summary>
public EFileVerifyResult VerifyResult { protected set; get; }
public EFileVerifyResult VerifyResult { private set; get; }
internal VerifyTempFileOperation(TempFileElement element)
@ -103,7 +84,7 @@ namespace YooAsset
private void VerifyInThread(object obj)
{
TempFileElement element = (TempFileElement)obj;
int result = (int)FileSystemHelper.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High);
int result = (int)FileVerifyHelper.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High);
element.Result = result;
}
}

View File

@ -0,0 +1,22 @@

namespace YooAsset
{
internal class TempFileElement
{
public string TempFilePath { private set; get; }
public string TempFileCRC { private set; get; }
public long TempFileSize { private set; get; }
/// <summary>
/// 注意:原子操作对象
/// </summary>
public int Result = 0;
public TempFileElement(string filePath, string fileCRC, long fileSize)
{
TempFilePath = filePath;
TempFileCRC = fileCRC;
TempFileSize = fileSize;
}
}
}

View File

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

View File

@ -10,36 +10,6 @@ namespace YooAsset
/// </summary>
internal class DefaultBuildinFileSystem : IFileSystem
{
private class UnpackRemoteServices : IRemoteServices
{
private readonly string _buildinPackageRoot;
protected readonly Dictionary<string, string> _mapping = new Dictionary<string, string>(10000);
public UnpackRemoteServices(string buildinPackRoot)
{
_buildinPackageRoot = 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(_buildinPackageRoot, fileName);
url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_mapping.Add(fileName, url);
}
return url;
}
}
public class FileWrapper
{
public string FileName { private set; get; }
@ -127,13 +97,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync()
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
return _unpackFileSystem.ClearAllBundleFilesAsync();
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
return _unpackFileSystem.ClearUnusedBundleFilesAsync(manifest);
return _unpackFileSystem.ClearCacheBundleFilesAsync(manifest, clearMode, clearParam);
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{
@ -220,7 +186,7 @@ namespace YooAsset
_packageRoot = PathUtility.Combine(rootDirectory, packageName);
// 创建解压文件系统
var remoteServices = new UnpackRemoteServices(_packageRoot);
var remoteServices = new DefaultUnpackRemoteServices(_packageRoot);
_unpackFileSystem = new DefaultUnpackFileSystem();
_unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
@ -231,6 +197,7 @@ namespace YooAsset
}
public virtual void OnUpdate()
{
_unpackFileSystem.OnUpdate();
}
public virtual bool Belong(PackageBundle bundle)

View File

@ -10,33 +10,18 @@ namespace YooAsset
/// 缓存文件系统
/// 说明正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作
/// </summary>
internal class DefaultCacheFileSystem : IFileSystem
internal class DefaultCacheFileSystem : IFileSystem, ICacheSystem
{
public class FileWrapper
{
public string InfoFilePath { private set; get; }
public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; }
public long DataFileSize { private set; get; }
public FileWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;
DataFileCRC = dataFileCRC;
DataFileSize = dataFileSize;
}
}
protected readonly Dictionary<string, DefaultDownloadFileOperation> _downloaders = new Dictionary<string, DefaultDownloadFileOperation>(1000);
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, CacheWrapper> _wrappers = new Dictionary<string, CacheWrapper>(10000);
protected readonly Dictionary<string, Stream> _loadedStream = new Dictionary<string, Stream>(10000);
protected readonly Dictionary<string, string> _dataFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _infoFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _tempFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, DefaultDownloadFileOperation> _downloaders = new Dictionary<string, DefaultDownloadFileOperation>(1000);
protected readonly List<string> _removeList = new List<string>(1000);
protected string _packageRoot;
protected string _saveFileRoot;
protected string _cacheFileRoot;
protected string _tempFileRoot;
protected string _manifestFileRoot;
@ -126,17 +111,33 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync()
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new DCFSClearAllBundleFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new DCFSClearUnusedBundleFilesOperation(this, manifest);
OperationSystem.StartOperation(PackageName, operation);
return operation;
if(clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{
var operation = new ClearAllCacheFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if(clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{
var operation = new ClearUnusedCacheFilesOperation(this, manifest);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if(clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
var operation = new ClearCacheFilesByTagsOperaiton(this, manifest, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else
{
string error = $"Invalid clear mode : {clearMode}";
var operation = new FSClearCacheBundleFilesCompleteOperation(error);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{
@ -163,7 +164,7 @@ namespace YooAsset
if (bundle.FileSize >= ResumeDownloadMinimumSize)
{
var newDownloader = new DCFSDownloadResumeFileOperation(this, bundle, param);
var newDownloader = new DownloadResumeFileOperation(this, this, bundle, param, ResumeDownloadResponseCodes);
newDownloader.Reference();
_downloaders.Add(bundle.BundleGUID, newDownloader);
OperationSystem.StartOperation(PackageName, newDownloader);
@ -171,7 +172,7 @@ namespace YooAsset
}
else
{
var newDownloader = new DCFSDownloadNormalFileOperation(this, bundle, param);
var newDownloader = new DownloadNormalFileOperation(this, this, bundle, param);
newDownloader.Reference();
_downloaders.Add(bundle.BundleGUID, newDownloader);
OperationSystem.StartOperation(PackageName, newDownloader);
@ -254,10 +255,10 @@ namespace YooAsset
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
rootDirectory = GetDefaultRoot();
rootDirectory = CacheHelper.GetDefaultCacheRoot();
_packageRoot = PathUtility.Combine(rootDirectory, packageName);
_saveFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName);
_cacheFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName);
_tempFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_manifestFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
}
@ -372,61 +373,10 @@ namespace YooAsset
}
}
#region 内部方法
private readonly BufferWriter _sharedBuffer = new BufferWriter(1024);
public void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize)
#region 缓存系统
public string GetCacheFileRoot()
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
_sharedBuffer.Clear();
_sharedBuffer.WriteUTF8(dataFileCRC);
_sharedBuffer.WriteInt64(dataFileSize);
_sharedBuffer.WriteToStream(fs);
fs.Flush();
}
}
public void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize)
{
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8();
dataFileSize = buffer.ReadInt64();
}
protected string GetDefaultRoot()
{
#if UNITY_EDITOR
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
projectPath = PathUtility.RegularPath(projectPath);
return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#elif UNITY_STANDALONE
return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#else
return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#endif
}
protected string GetDataFilePath(PackageBundle bundle)
{
if (_dataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_dataFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
protected string GetInfoFilePath(PackageBundle bundle)
{
if (_infoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleInfoFileName);
_infoFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
return _cacheFileRoot;
}
public string GetTempFilePath(PackageBundle bundle)
{
@ -437,41 +387,38 @@ namespace YooAsset
}
return filePath;
}
public string GetCacheFileLoadPath(PackageBundle bundle)
public string GetDataFilePath(PackageBundle bundle)
{
return GetDataFilePath(bundle);
if (_dataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_dataFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetCacheFilesRoot()
public string GetInfoFilePath(PackageBundle bundle)
{
return _saveFileRoot;
if (_infoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleInfoFileName);
_infoFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetCachePackageHashFilePath(string packageVersion)
public List<string> GetAllCachedBundleGUIDs()
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
}
public string GetCachePackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
}
public string GetSandboxAppFootPrintFilePath()
{
return PathUtility.Combine(_manifestFileRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
return _wrappers.Keys.ToList();
}
/// <summary>
/// 是否已经记录了文件
/// </summary>
public bool IsRecordFile(string bundleGUID)
{
return _wrappers.ContainsKey(bundleGUID);
}
/// <summary>
/// 记录文件信息
/// </summary>
public bool RecordFile(string bundleGUID, FileWrapper wrapper)
public bool RecordFile(string bundleGUID, CacheWrapper wrapper)
{
if (_wrappers.ContainsKey(bundleGUID))
{
@ -483,21 +430,14 @@ namespace YooAsset
return true;
}
/// <summary>
/// 验证缓存文件
/// </summary>
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
{
if (_wrappers.TryGetValue(bundle.BundleGUID, out FileWrapper wrapper) == false)
if (_wrappers.TryGetValue(bundle.BundleGUID, out CacheWrapper wrapper) == false)
return EFileVerifyResult.CacheNotFound;
EFileVerifyResult result = FileSystemHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
return result;
}
/// <summary>
/// 写入缓存文件
/// </summary>
public bool WriteCacheFile(PackageBundle bundle, string copyPath)
{
if (_wrappers.ContainsKey(bundle.BundleGUID))
@ -530,16 +470,12 @@ namespace YooAsset
return false;
}
FileWrapper wrapper = new FileWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
var wrapper = new CacheWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
return RecordFile(bundle.BundleGUID, wrapper);
}
/// <summary>
/// 删除缓存文件
/// </summary>
public bool DeleteCacheFile(string bundleGUID)
{
if (_wrappers.TryGetValue(bundleGUID, out FileWrapper wrapper))
if (_wrappers.TryGetValue(bundleGUID, out CacheWrapper wrapper))
{
try
{
@ -562,6 +498,47 @@ namespace YooAsset
}
}
private readonly BufferWriter _sharedBuffer = new BufferWriter(1024);
public void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
_sharedBuffer.Clear();
_sharedBuffer.WriteUTF8(dataFileCRC);
_sharedBuffer.WriteInt64(dataFileSize);
_sharedBuffer.WriteToStream(fs);
fs.Flush();
}
}
public void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize)
{
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8();
dataFileSize = buffer.ReadInt64();
}
#endregion
#region 内部方法
public string GetCacheFileLoadPath(PackageBundle bundle)
{
return GetDataFilePath(bundle);
}
public string GetCachePackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
}
public string GetCachePackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
}
public string GetSandboxAppFootPrintFilePath()
{
return PathUtility.Combine(_manifestFileRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
}
/// <summary>
/// 删除所有清单文件
/// </summary>
@ -573,14 +550,6 @@ namespace YooAsset
}
}
/// <summary>
/// 获取所有缓存文件GUID
/// </summary>
public List<string> GetAllCachedBundleGUIDs()
{
return _wrappers.Keys.ToList();
}
/// <summary>
/// 加载加密资源文件
/// </summary>

View File

@ -12,7 +12,7 @@ namespace YooAsset
Done,
}
private readonly DefaultCacheFileSystem _fileSytem;
private readonly DefaultCacheFileSystem _fileSystem;
private SearchCacheFilesOperation _searchCacheFilesOp;
private VerifyCacheFilesOperation _verifyCacheFilesOp;
private ESteps _steps = ESteps.None;
@ -20,7 +20,7 @@ namespace YooAsset
internal DCFSInitializeOperation(DefaultCacheFileSystem fileSystem)
{
_fileSytem = fileSystem;
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
@ -39,14 +39,14 @@ namespace YooAsset
if (_steps == ESteps.CheckAppFootPrint)
{
var appFootPrint = new ApplicationFootPrint(_fileSytem);
appFootPrint.Load(_fileSytem.PackageName);
var appFootPrint = new ApplicationFootPrint(_fileSystem);
appFootPrint.Load(_fileSystem.PackageName);
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty())
{
_fileSytem.DeleteAllManifestFiles();
appFootPrint.Coverage(_fileSytem.PackageName);
_fileSystem.DeleteAllManifestFiles();
appFootPrint.Coverage(_fileSystem.PackageName);
YooLogger.Warning("Delete manifest files when application foot print dirty !");
}
@ -57,8 +57,8 @@ namespace YooAsset
{
if (_searchCacheFilesOp == null)
{
_searchCacheFilesOp = new SearchCacheFilesOperation(_fileSytem);
OperationSystem.StartOperation(_fileSytem.PackageName, _searchCacheFilesOp);
_searchCacheFilesOp = new SearchCacheFilesOperation(_fileSystem, _fileSystem.PackageName, _fileSystem.AppendFileExtension);
OperationSystem.StartOperation(_fileSystem.PackageName, _searchCacheFilesOp);
}
Progress = _searchCacheFilesOp.Progress;
@ -72,8 +72,8 @@ namespace YooAsset
{
if (_verifyCacheFilesOp == null)
{
_verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSytem, _searchCacheFilesOp.Result);
OperationSystem.StartOperation(_fileSytem.PackageName, _verifyCacheFilesOp);
_verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSystem, _fileSystem.FileVerifyLevel, _searchCacheFilesOp.Result);
OperationSystem.StartOperation(_fileSystem.PackageName, _verifyCacheFilesOp);
}
Progress = _verifyCacheFilesOp.Progress;
@ -84,7 +84,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
YooLogger.Log($"Package '{_fileSytem.PackageName}' cached files count : {_fileSytem.FileCount}");
YooLogger.Log($"Package '{_fileSystem.PackageName}' cached files count : {_fileSystem.FileCount}");
}
else
{

View File

@ -58,6 +58,9 @@ namespace YooAsset
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
}
if (IsWaitForAsyncComplete)
_downloadFileOp.WaitForAsyncComplete();
DownloadProgress = _downloadFileOp.DownloadProgress;
DownloadedBytes = _downloadFileOp.DownloadedBytes;
if (_downloadFileOp.IsDone == false)
@ -198,9 +201,6 @@ namespace YooAsset
{
while (true)
{
if (_downloadFileOp != null)
_downloadFileOp.WaitForAsyncComplete();
if (ExecuteWhileDone())
{
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)
@ -274,6 +274,9 @@ namespace YooAsset
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
}
if (IsWaitForAsyncComplete)
_downloadFileOp.WaitForAsyncComplete();
DownloadProgress = _downloadFileOp.DownloadProgress;
DownloadedBytes = _downloadFileOp.DownloadedBytes;
if (_downloadFileOp.IsDone == false)
@ -313,9 +316,6 @@ namespace YooAsset
{
while (true)
{
if (_downloadFileOp != null)
_downloadFileOp.WaitForAsyncComplete();
if (ExecuteWhileDone())
{
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)

View File

@ -36,6 +36,17 @@ namespace YooAsset
}
}
#region 自定义参数
/// <summary>
/// 异步模拟加载最小帧数
/// </summary>
public int _asyncSimulateMinFrame = 1;
/// <summary>
/// 异步模拟加载最大帧数
/// </summary>
public int _asyncSimulateMaxFrame = 1;
#endregion
public DefaultEditorFileSystem()
{
@ -58,15 +69,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync()
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearAllBundleFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new FSClearUnusedBundleFilesCompleteOperation();
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@ -86,7 +91,18 @@ namespace YooAsset
public virtual void SetParameter(string name, object value)
{
YooLogger.Warning($"Invalid parameter : {name}");
if (name == FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME)
{
_asyncSimulateMinFrame = (int)value;
}
else if (name == FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME)
{
_asyncSimulateMaxFrame = (int)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
{
@ -148,6 +164,15 @@ namespace YooAsset
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(FileRoot, fileName);
}
public int GetAsyncSimulateFrame()
{
if (_asyncSimulateMinFrame > _asyncSimulateMaxFrame)
{
_asyncSimulateMinFrame = _asyncSimulateMaxFrame;
}
return UnityEngine.Random.Range(_asyncSimulateMinFrame, _asyncSimulateMaxFrame + 1);
}
#endregion
}
}

View File

@ -3,8 +3,19 @@ namespace YooAsset
{
internal class DEFSLoadBundleOperation : FSLoadBundleOperation
{
protected enum ESteps
{
None,
DownloadFile,
LoadAssetBundle,
CheckResult,
Done,
}
private readonly DefaultEditorFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private int _asyncSimulateFrame;
private ESteps _steps = ESteps.None;
internal DEFSLoadBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle)
{
@ -13,15 +24,53 @@ namespace YooAsset
}
internal override void InternalOnStart()
{
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
Status = EOperationStatus.Succeed;
_steps = ESteps.DownloadFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
{
_asyncSimulateFrame = _fileSystem.GetAsyncSimulateFrame();
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
_steps = ESteps.LoadAssetBundle;
}
if (_steps == ESteps.LoadAssetBundle)
{
if (IsWaitForAsyncComplete)
{
_steps = ESteps.CheckResult;
}
else
{
if (_asyncSimulateFrame <= 0)
_steps = ESteps.CheckResult;
else
_asyncSimulateFrame--;
}
}
if (_steps == ESteps.CheckResult)
{
_steps = ESteps.Done;
Result = new VirtualBundle(_fileSystem, _bundle);
Status = EOperationStatus.Succeed;
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
public override void AbortDownloadOperation()
{

View File

@ -14,7 +14,7 @@ namespace YooAsset
base.OnCreate(packageName, rootDirectory);
// 注意:重写保存根目录和临时目录
_saveFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveFilesFolderName);
_cacheFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveFilesFolderName);
_tempFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName);
}
}

View File

@ -0,0 +1,34 @@
using System.Collections.Generic;
namespace YooAsset
{
internal class DefaultUnpackRemoteServices : IRemoteServices
{
private readonly string _buildinPackageRoot;
protected readonly Dictionary<string, string> _mapping = new Dictionary<string, string>(10000);
public DefaultUnpackRemoteServices(string buildinPackRoot)
{
_buildinPackageRoot = 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(_buildinPackageRoot, fileName);
url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_mapping.Add(fileName, url);
}
return url;
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,156 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// Web文件系统
/// </summary>
internal class DefaultWebRemoteFileSystem : IFileSystem
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 文件根目录
/// </summary>
public string FileRoot
{
get
{
return string.Empty;
}
}
/// <summary>
/// 文件数量
/// </summary>
public int FileCount
{
get
{
return 0;
}
}
#region 自定义参数
/// <summary>
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { private set; get; } = false;
/// <summary>
/// 自定义参数:跨域下载服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
#endregion
public DefaultWebRemoteFileSystem()
{
}
public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
{
var operation = new DWRFSInitializeOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout)
{
var operation = new DWRFSLoadPackageManifestOperation(this, packageVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{
throw new System.NotImplementedException();
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{
var operation = new DWRFSLoadAssetBundleOperation(this, bundle);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual void UnloadBundleFile(PackageBundle bundle, object result)
{
AssetBundle assetBundle = result as AssetBundle;
if (assetBundle == null)
return;
if (assetBundle != null)
assetBundle.Unload(true);
}
public virtual void SetParameter(string name, object value)
{
if (name == FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE)
{
DisableUnityWebCache = (bool)value;
}
else if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
{
PackageName = packageName;
}
public virtual void OnUpdate()
{
}
public virtual bool Belong(PackageBundle bundle)
{
return true;
}
public virtual bool Exists(PackageBundle bundle)
{
return true;
}
public virtual bool NeedDownload(PackageBundle bundle)
{
return false;
}
public virtual bool NeedUnpack(PackageBundle bundle)
{
return false;
}
public virtual bool NeedImport(PackageBundle bundle)
{
return false;
}
public virtual byte[] ReadFileData(PackageBundle bundle)
{
throw new System.NotImplementedException();
}
public virtual string ReadFileText(PackageBundle bundle)
{
throw new System.NotImplementedException();
}
#region 内部方法
#endregion
}
}

View File

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

View File

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

View File

@ -0,0 +1,20 @@

namespace YooAsset
{
internal class DWRFSInitializeOperation : FSInitializeFileSystemOperation
{
private readonly DefaultWebRemoteFileSystem _fileSystem;
public DWRFSInitializeOperation(DefaultWebRemoteFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
}

View File

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

View File

@ -0,0 +1,83 @@

namespace YooAsset
{
internal class DWRFSLoadAssetBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
DownloadFile,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private ESteps _steps = ESteps.None;
internal DWRFSLoadAssetBundleOperation(DefaultWebRemoteFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
}
internal override void InternalOnStart()
{
_steps = ESteps.DownloadFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
{
if (_downloadhanlderAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
}
DownloadProgress = _downloadhanlderAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadhanlderAssetBundleOp.DownloadedBytes;
Progress = _downloadhanlderAssetBundleOp.Progress;
if (_downloadhanlderAssetBundleOp.IsDone == false)
return;
if (_downloadhanlderAssetBundleOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Result = _downloadhanlderAssetBundleOp.Result;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadhanlderAssetBundleOp.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);
}
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
{
if (_downloadhanlderAssetBundleOp != null)
_downloadhanlderAssetBundleOp.SetAbort();
}
}
}
}

View File

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

View File

@ -1,68 +1,44 @@

namespace YooAsset
{
internal class DWFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
internal class DWRFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
{
private enum ESteps
{
None,
RequestWebPackageVersion,
RequestWebPackageHash,
LoadWebPackageManifest,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private RequestWebPackageHashOperation _requestWebPackageHashOp;
private LoadWebPackageManifestOperation _loadWebPackageManifestOp;
private RequestWebRemotePackageHashOperation _requestWebPackageHashOp;
private LoadWebRemotePackageManifestOperation _loadWebPackageManifestOp;
private ESteps _steps = ESteps.None;
public DWFSLoadPackageManifestOperation(DefaultWebFileSystem fileSystem, int timeout)
public DWRFSLoadPackageManifestOperation(DefaultWebRemoteFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestWebPackageVersion;
_steps = ESteps.RequestWebPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestWebPackageVersion)
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp);
}
if (_requestWebPackageVersionOp.IsDone == false)
return;
if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.RequestWebPackageHash;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestWebPackageVersionOp.Error;
}
}
if (_steps == ESteps.RequestWebPackageHash)
{
if (_requestWebPackageHashOp == null)
{
string packageVersion = _requestWebPackageVersionOp.PackageVersion;
_requestWebPackageHashOp = new RequestWebPackageHashOperation(_fileSystem, packageVersion, _timeout);
_requestWebPackageHashOp = new RequestWebRemotePackageHashOperation(_fileSystem, _packageVersion, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageHashOp);
}
@ -85,9 +61,8 @@ namespace YooAsset
{
if (_loadWebPackageManifestOp == null)
{
string packageVersion = _requestWebPackageVersionOp.PackageVersion;
string packageHash = _requestWebPackageHashOp.PackageHash;
_loadWebPackageManifestOp = new LoadWebPackageManifestOperation(_fileSystem, packageVersion, packageHash);
_loadWebPackageManifestOp = new LoadWebRemotePackageManifestOperation(_fileSystem, _packageVersion, packageHash);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadWebPackageManifestOp);
}

View File

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

View File

@ -0,0 +1,62 @@

namespace YooAsset
{
internal class DWRFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
{
private enum ESteps
{
None,
RequestPackageVersion,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestWebRemotePackageVersionOperation _requestWebPackageVersionOp;
private ESteps _steps = ESteps.None;
internal DWRFSRequestPackageVersionOperation(DefaultWebRemoteFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageVersion)
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebRemotePackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp);
}
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;
}
}
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,122 @@

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 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)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_packageHash = packageHash;
}
internal override void InternalOnStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadWebRemotePackageManifestOperation));
_steps = ESteps.RequestFileData;
}
internal override void InternalOnUpdate()
{
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);
OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp);
}
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)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
if (fileHash == _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(_webDataRequestOp.Result);
OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer);
}
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 GetWebRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
}

View File

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

View File

@ -0,0 +1,90 @@

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 InternalOnStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWebRemotePackageHashOperation));
_steps = ESteps.RequestPackageHash;
}
internal override void InternalOnUpdate()
{
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);
OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
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

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

View File

@ -0,0 +1,98 @@

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 InternalOnStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWebRemotePackageVersionOperation));
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalOnUpdate()
{
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);
OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
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

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

View File

@ -8,7 +8,7 @@ namespace YooAsset
/// <summary>
/// Web文件系统
/// </summary>
internal class DefaultWebFileSystem : IFileSystem
internal class DefaultWebServerFileSystem : IFileSystem
{
public class FileWrapper
{
@ -59,36 +59,30 @@ namespace YooAsset
#endregion
public DefaultWebFileSystem()
public DefaultWebServerFileSystem()
{
}
public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
{
var operation = new DWFSInitializeOperation(this);
var operation = new DWSFSInitializeOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout)
{
var operation = new DWFSLoadPackageManifestOperation(this, timeout);
var operation = new DWSFSLoadPackageManifestOperation(this, packageVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new DWFSRequestPackageVersionOperation(this, timeout);
var operation = new DWSFSRequestPackageVersionOperation(this, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync()
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearAllBundleFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new FSClearUnusedBundleFilesCompleteOperation();
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@ -98,7 +92,7 @@ namespace YooAsset
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{
var operation = new DWFSLoadAssetBundleOperation(this, bundle);
var operation = new DWSFSLoadAssetBundleOperation(this, bundle);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@ -214,7 +208,7 @@ namespace YooAsset
{
if (_wrappers.ContainsKey(bundleGUID))
{
YooLogger.Error($"{nameof(DefaultWebFileSystem)} has element : {bundleGUID}");
YooLogger.Error($"{nameof(DefaultWebServerFileSystem)} has element : {bundleGUID}");
return false;
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class DWFSInitializeOperation : FSInitializeFileSystemOperation
internal class DWSFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
@ -10,12 +10,12 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private LoadWebCatalogFileOperation _loadCatalogFileOp;
private readonly DefaultWebServerFileSystem _fileSystem;
private LoadWebServerCatalogFileOperation _loadCatalogFileOp;
private ESteps _steps = ESteps.None;
public DWFSInitializeOperation(DefaultWebFileSystem fileSystem)
public DWSFSInitializeOperation(DefaultWebServerFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
@ -39,7 +39,7 @@ namespace YooAsset
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot);
#endif
_loadCatalogFileOp = new LoadWebCatalogFileOperation(_fileSystem);
_loadCatalogFileOp = new LoadWebServerCatalogFileOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadCatalogFileOp);
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class DWFSLoadAssetBundleOperation : FSLoadBundleOperation
internal class DWSFSLoadAssetBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
@ -10,13 +10,13 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private ESteps _steps = ESteps.None;
internal DWFSLoadAssetBundleOperation(DefaultWebFileSystem fileSystem, PackageBundle bundle)
internal DWSFSLoadAssetBundleOperation(DefaultWebServerFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
@ -38,7 +38,7 @@ namespace YooAsset
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
downloadParam.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
downloadParam.FallbackURL = downloadParam.MainURL;
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem, _bundle, downloadParam);
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
}

View File

@ -0,0 +1,88 @@

namespace YooAsset
{
internal class DWSFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
{
private enum ESteps
{
None,
RequestWebPackageHash,
LoadWebPackageManifest,
Done,
}
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestWebServerPackageHashOperation _requestWebPackageHashOp;
private LoadWebServerPackageManifestOperation _loadWebPackageManifestOp;
private ESteps _steps = ESteps.None;
public DWSFSLoadPackageManifestOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestWebPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestWebPackageHash)
{
if (_requestWebPackageHashOp == null)
{
_requestWebPackageHashOp = new RequestWebServerPackageHashOperation(_fileSystem, _packageVersion, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageHashOp);
}
if (_requestWebPackageHashOp.IsDone == false)
return;
if (_requestWebPackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadWebPackageManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestWebPackageHashOp.Error;
}
}
if (_steps == ESteps.LoadWebPackageManifest)
{
if (_loadWebPackageManifestOp == null)
{
string packageHash = _requestWebPackageHashOp.PackageHash;
_loadWebPackageManifestOp = new LoadWebServerPackageManifestOperation(_fileSystem, _packageVersion, packageHash);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadWebPackageManifestOp);
}
Progress = _loadWebPackageManifestOp.Progress;
if (_loadWebPackageManifestOp.IsDone == false)
return;
if (_loadWebPackageManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _loadWebPackageManifestOp.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebPackageManifestOp.Error;
}
}
}
}
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class DWFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
internal class DWSFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
{
private enum ESteps
{
@ -10,13 +10,13 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly int _timeout;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private RequestWebServerPackageVersionOperation _requestWebPackageVersionOp;
private ESteps _steps = ESteps.None;
internal DWFSRequestPackageVersionOperation(DefaultWebFileSystem fileSystem, int timeout)
internal DWSFSRequestPackageVersionOperation(DefaultWebServerFileSystem fileSystem, int timeout)
{
_fileSystem = fileSystem;
_timeout = timeout;
@ -34,7 +34,7 @@ namespace YooAsset
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem, _timeout);
_requestWebPackageVersionOp = new RequestWebServerPackageVersionOperation(_fileSystem, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp);
}

View File

@ -6,7 +6,7 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class LoadWebCatalogFileOperation : AsyncOperationBase
internal sealed class LoadWebServerCatalogFileOperation : AsyncOperationBase
{
private enum ESteps
{
@ -15,7 +15,7 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
/// <summary>
@ -23,7 +23,7 @@ namespace YooAsset
/// </summary>
public string PackageVersion { private set; get; }
internal LoadWebCatalogFileOperation(DefaultWebFileSystem fileSystem)
internal LoadWebServerCatalogFileOperation(DefaultWebServerFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
@ -44,7 +44,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load web catalog file : {catalogFilePath}";
Error = $"Failed to load web server catalog file : {catalogFilePath}";
return;
}
@ -52,14 +52,14 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
Error = $"Web server catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
return;
}
PackageVersion = catalog.PackageVersion;
foreach (var wrapper in catalog.Wrappers)
{
var fileWrapper = new DefaultWebFileSystem.FileWrapper(wrapper.FileName);
var fileWrapper = new DefaultWebServerFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.RecordFile(wrapper.BundleGUID, fileWrapper);
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class LoadWebPackageManifestOperation : AsyncOperationBase
internal class LoadWebServerPackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
@ -12,7 +12,7 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private UnityWebDataRequestOperation _webDataRequestOp;
@ -25,7 +25,7 @@ namespace YooAsset
public PackageManifest Manifest { private set; get; }
internal LoadWebPackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, string packageHash)
internal LoadWebServerPackageManifestOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, string packageHash)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
@ -76,7 +76,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify web package manifest file!";
Error = "Failed to verify web server package manifest file!";
}
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class RequestWebPackageHashOperation : AsyncOperationBase
internal class RequestWebServerPackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
@ -10,7 +10,7 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
@ -22,7 +22,7 @@ namespace YooAsset
public string PackageHash { private set; get; }
public RequestWebPackageHashOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout)
public RequestWebServerPackageHashOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
@ -58,7 +58,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web package hash file content is empty !";
Error = $"Web server package hash file content is empty !";
}
else
{

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class RequestWebPackageVersionOperation : AsyncOperationBase
internal class RequestWebServerPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
@ -10,7 +10,7 @@ namespace YooAsset
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private ESteps _steps = ESteps.None;
@ -21,7 +21,7 @@ namespace YooAsset
public string PackageVersion { private set; get; }
internal RequestWebPackageVersionOperation(DefaultWebFileSystem fileSystem, int timeout)
internal RequestWebServerPackageVersionOperation(DefaultWebServerFileSystem fileSystem, int timeout)
{
_fileSystem = fileSystem;
_timeout = timeout;
@ -55,7 +55,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web package version file content is empty !";
Error = $"Web server package version file content is empty !";
}
else
{

View File

@ -0,0 +1,25 @@

namespace YooAsset
{
/// <summary>
/// 文件清理方式
/// </summary>
public enum EFileClearMode
{
/// <summary>
/// 清理所有文件
/// </summary>
ClearAllBundleFiles = 1,
/// <summary>
/// 清理未在使用的文件
/// </summary>
ClearUnusedBundleFiles = 2,
/// <summary>
/// 清理指定标签的文件
/// 说明需要指定参数可选string, string[], List<string>
/// </summary>
ClearBundleFilesByTags = 3,
}
}

View File

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

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class FileSystemParametersDefine
public class FileSystemParametersDefine
{
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
@ -11,5 +11,7 @@ namespace YooAsset
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME";
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
}
}

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