2024-07-04 20:36:26 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace YooAsset
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 缓存文件系统
|
|
|
|
|
|
/// 说明:正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作!
|
|
|
|
|
|
/// </summary>
|
2024-12-12 15:00:08 +08:00
|
|
|
|
internal class DefaultCacheFileSystem : IFileSystem, ICacheSystem
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-12 15:00:08 +08:00
|
|
|
|
protected readonly Dictionary<string, CacheWrapper> _wrappers = new Dictionary<string, CacheWrapper>(10000);
|
2024-07-04 20:36:26 +08:00
|
|
|
|
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);
|
2024-12-17 17:14:59 +08:00
|
|
|
|
protected DefaultCacheDownloadCenter _downloadCenter;
|
2024-12-12 17:35:42 +08:00
|
|
|
|
|
2024-07-04 20:36:26 +08:00
|
|
|
|
protected string _packageRoot;
|
2024-12-12 15:16:34 +08:00
|
|
|
|
protected string _cacheFileRoot;
|
2024-07-04 20:36:26 +08:00
|
|
|
|
protected string _tempFileRoot;
|
|
|
|
|
|
protected string _manifestFileRoot;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 包裹名称
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string PackageName { private set; get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 文件根目录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string FileRoot
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _packageRoot;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 文件数量
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int FileCount
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _wrappers.Count;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 自定义参数
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:远程服务接口
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public IRemoteServices RemoteServices { private set; get; } = null;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:初始化的时候缓存文件校验级别
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:数据文件追加文件格式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool AppendFileExtension { private set; get; } = false;
|
|
|
|
|
|
|
2024-12-17 17:14:59 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:最大并发连接数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int DownloadMaxConcurrency { private set; get; } = int.MaxValue;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:每帧发起的最大请求数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int DownloadMaxRequestPerFrame { private set; get; } = int.MaxValue;
|
|
|
|
|
|
|
2024-07-04 20:36:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:启用断点续传的最小尺寸
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public long ResumeDownloadMinimumSize { private set; get; } = long.MaxValue;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:断点续传下载器关注的错误码
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<long> ResumeDownloadResponseCodes { private set; get; } = null;
|
2024-07-27 15:25:21 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义参数:解密方法类
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public IDecryptionServices DecryptionServices { private set; get; }
|
2024-07-04 20:36:26 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DefaultCacheFileSystem()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var operation = new DCFSInitializeOperation(this);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-07-07 00:52:17 +08:00
|
|
|
|
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
var operation = new DCFSLoadPackageManifestOperation(this, packageVersion, timeout);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-07-07 00:52:17 +08:00
|
|
|
|
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-12-13 10:25:16 +08:00
|
|
|
|
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-17 17:14:59 +08:00
|
|
|
|
if (clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
|
2024-12-13 10:25:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
var operation = new ClearAllCacheFilesOperation(this);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-12-17 17:14:59 +08:00
|
|
|
|
else if (clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
|
2024-12-13 10:25:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
var operation = new ClearUnusedCacheFilesOperation(this, manifest);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-12-17 17:14:59 +08:00
|
|
|
|
else if (clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
|
2024-12-13 10:25:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-07 00:52:17 +08:00
|
|
|
|
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-17 17:14:59 +08:00
|
|
|
|
return _downloadCenter.DownloadFileAsync(bundle, param);
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
|
|
|
|
|
|
{
|
2024-12-24 18:23:19 +08:00
|
|
|
|
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle)
|
2024-07-05 19:29:34 +08:00
|
|
|
|
{
|
2024-12-24 18:23:19 +08:00
|
|
|
|
var operation = new DCFSLoadAssetBundleOperation(this, bundle);
|
2024-07-05 19:29:34 +08:00
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-12-24 18:23:19 +08:00
|
|
|
|
else if (bundle.BundleType == (int)EBuildBundleType.RawBundle)
|
2024-07-05 19:29:34 +08:00
|
|
|
|
{
|
2024-12-24 18:23:19 +08:00
|
|
|
|
var operation = new DCFSLoadRawBundleOperation(this, bundle);
|
2024-07-05 19:29:34 +08:00
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
|
|
|
|
|
}
|
2024-12-24 18:23:19 +08:00
|
|
|
|
else
|
2024-07-05 19:29:34 +08:00
|
|
|
|
{
|
2024-12-24 18:23:19 +08:00
|
|
|
|
string error = $"{nameof(DefaultCacheFileSystem)} not support load bundle type : {bundle.BundleType}";
|
|
|
|
|
|
var operation = new FSLoadBundleCompleteOperation(error);
|
|
|
|
|
|
OperationSystem.StartOperation(PackageName, operation);
|
|
|
|
|
|
return operation;
|
2024-07-05 19:29:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-07-04 20:36:26 +08:00
|
|
|
|
|
|
|
|
|
|
public virtual void SetParameter(string name, object value)
|
|
|
|
|
|
{
|
2024-08-03 18:43:12 +08:00
|
|
|
|
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
RemoteServices = (IRemoteServices)value;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
FileVerifyLevel = (EFileVerifyLevel)value;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
AppendFileExtension = (bool)value;
|
|
|
|
|
|
}
|
2024-12-17 17:14:59 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY)
|
|
|
|
|
|
{
|
|
|
|
|
|
DownloadMaxConcurrency = (int)value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME)
|
|
|
|
|
|
{
|
|
|
|
|
|
DownloadMaxRequestPerFrame = (int)value;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
ResumeDownloadMinimumSize = (long)value;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
ResumeDownloadResponseCodes = (List<long>)value;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
|
2024-07-27 15:25:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
DecryptionServices = (IDecryptionServices)value;
|
|
|
|
|
|
}
|
2024-07-04 20:36:26 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
YooLogger.Warning($"Invalid parameter : {name}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public virtual void OnCreate(string packageName, string rootDirectory)
|
|
|
|
|
|
{
|
|
|
|
|
|
PackageName = packageName;
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(rootDirectory))
|
2024-12-17 15:27:36 +08:00
|
|
|
|
rootDirectory = GetDefaultCacheRoot();
|
2024-07-04 20:36:26 +08:00
|
|
|
|
|
|
|
|
|
|
_packageRoot = PathUtility.Combine(rootDirectory, packageName);
|
2024-12-12 15:16:34 +08:00
|
|
|
|
_cacheFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName);
|
2024-07-04 20:36:26 +08:00
|
|
|
|
_tempFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
|
|
|
|
|
|
_manifestFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
|
2024-12-17 17:14:59 +08:00
|
|
|
|
_downloadCenter = new DefaultCacheDownloadCenter(this);
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
public virtual void OnUpdate()
|
|
|
|
|
|
{
|
2024-12-17 17:14:59 +08:00
|
|
|
|
_downloadCenter.Update();
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public virtual bool Belong(PackageBundle bundle)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 注意:缓存文件系统保底加载!
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-07-05 15:10:07 +08:00
|
|
|
|
public virtual bool Exists(PackageBundle bundle)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-07-05 19:29:34 +08:00
|
|
|
|
return _wrappers.ContainsKey(bundle.BundleGUID);
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
public virtual bool NeedDownload(PackageBundle bundle)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (Belong(bundle) == false)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return Exists(bundle) == false;
|
|
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
public virtual bool NeedUnpack(PackageBundle bundle)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
public virtual bool NeedImport(PackageBundle bundle)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (Belong(bundle) == false)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return Exists(bundle) == false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-24 18:23:19 +08:00
|
|
|
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetCacheFileLoadPath(bundle);
|
|
|
|
|
|
}
|
|
|
|
|
|
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
|
2024-07-08 17:36:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (Exists(bundle) == false)
|
|
|
|
|
|
return null;
|
2024-07-27 18:37:17 +08:00
|
|
|
|
|
|
|
|
|
|
if (bundle.Encrypted)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DecryptionServices == null)
|
|
|
|
|
|
{
|
2024-08-03 18:43:12 +08:00
|
|
|
|
YooLogger.Error($"The {nameof(IDecryptionServices)} is null !");
|
2024-07-27 18:37:17 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
|
|
|
|
|
var fileInfo = new DecryptFileInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
BundleName = bundle.BundleName,
|
|
|
|
|
|
FileLoadCRC = bundle.UnityCRC,
|
|
|
|
|
|
FileLoadPath = filePath,
|
|
|
|
|
|
};
|
|
|
|
|
|
return DecryptionServices.ReadFileData(fileInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
|
|
|
|
|
return FileUtility.ReadAllBytes(filePath);
|
2024-07-27 18:37:17 +08:00
|
|
|
|
}
|
2024-07-08 17:36:25 +08:00
|
|
|
|
}
|
2024-12-24 18:23:19 +08:00
|
|
|
|
public virtual string ReadBundleFileText(PackageBundle bundle)
|
2024-07-08 17:36:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (Exists(bundle) == false)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
2024-07-27 18:37:17 +08:00
|
|
|
|
if (bundle.Encrypted)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DecryptionServices == null)
|
|
|
|
|
|
{
|
2024-08-03 18:43:12 +08:00
|
|
|
|
YooLogger.Error($"The {nameof(IDecryptionServices)} is null !");
|
2024-07-27 18:37:17 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2024-08-03 18:43:12 +08:00
|
|
|
|
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
|
|
|
|
|
var fileInfo = new DecryptFileInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
BundleName = bundle.BundleName,
|
|
|
|
|
|
FileLoadCRC = bundle.UnityCRC,
|
|
|
|
|
|
FileLoadPath = filePath,
|
|
|
|
|
|
};
|
|
|
|
|
|
return DecryptionServices.ReadFileText(fileInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
|
|
|
|
|
return FileUtility.ReadAllText(filePath);
|
2024-07-27 18:37:17 +08:00
|
|
|
|
}
|
2024-07-08 17:36:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-12 15:00:08 +08:00
|
|
|
|
#region 缓存系统
|
|
|
|
|
|
public string GetCacheFileRoot()
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-12 15:16:34 +08:00
|
|
|
|
return _cacheFileRoot;
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-12-12 17:35:42 +08:00
|
|
|
|
public string GetTempFilePath(PackageBundle bundle)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
filePath = PathUtility.Combine(_tempFileRoot, bundle.BundleGUID);
|
|
|
|
|
|
_tempFilePaths.Add(bundle.BundleGUID, filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
return filePath;
|
|
|
|
|
|
}
|
|
|
|
|
|
public string GetDataFilePath(PackageBundle 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 GetInfoFilePath(PackageBundle bundle)
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2024-12-12 15:00:08 +08:00
|
|
|
|
public List<string> GetAllCachedBundleGUIDs()
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-12 15:00:08 +08:00
|
|
|
|
return _wrappers.Keys.ToList();
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
|
|
|
|
|
|
public bool IsRecordFile(string bundleGUID)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-07-05 19:29:34 +08:00
|
|
|
|
return _wrappers.ContainsKey(bundleGUID);
|
|
|
|
|
|
}
|
2024-12-12 15:00:08 +08:00
|
|
|
|
public bool RecordFile(string bundleGUID, CacheWrapper wrapper)
|
2024-07-05 19:29:34 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (_wrappers.ContainsKey(bundleGUID))
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-07-05 19:29:34 +08:00
|
|
|
|
YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}");
|
|
|
|
|
|
return false;
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
|
|
|
|
|
|
_wrappers.Add(bundleGUID, wrapper);
|
|
|
|
|
|
return true;
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
|
|
|
|
|
|
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-12-12 15:00:08 +08:00
|
|
|
|
if (_wrappers.TryGetValue(bundle.BundleGUID, out CacheWrapper wrapper) == false)
|
2024-07-05 19:29:34 +08:00
|
|
|
|
return EFileVerifyResult.CacheNotFound;
|
|
|
|
|
|
|
2024-12-12 15:16:34 +08:00
|
|
|
|
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
|
2024-07-05 19:29:34 +08:00
|
|
|
|
return result;
|
2024-07-04 20:36:26 +08:00
|
|
|
|
}
|
2024-07-05 19:29:34 +08:00
|
|
|
|
public bool WriteCacheFile(PackageBundle bundle, string copyPath)
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-07-05 19:29:34 +08:00
|
|
|
|
if (_wrappers.ContainsKey(bundle.BundleGUID))
|
2024-07-04 20:36:26 +08:00
|
|
|
|
{
|
2024-07-05 19:29:34 +08:00
|
|
|
|
throw new Exception("Should never get here !");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string infoFilePath = GetInfoFilePath(bundle);
|
|
|
|
|
|
string dataFilePath = GetDataFilePath(bundle);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (File.Exists(infoFilePath))
|
|
|
|
|
|
File.Delete(infoFilePath);
|
|
|
|
|
|
if (File.Exists(dataFilePath))
|
|
|
|
|
|
File.Delete(dataFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
FileUtility.CreateFileDirectory(dataFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
// 拷贝数据文件
|
|
|
|
|
|
FileInfo fileInfo = new FileInfo(copyPath);
|
|
|
|
|
|
fileInfo.CopyTo(dataFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
// 写入文件信息
|
|
|
|
|
|
WriteInfoFile(infoFilePath, bundle.FileCRC, bundle.FileSize);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
YooLogger.Error($"Failed to write cache file ! {e.Message}");
|
2024-07-04 20:36:26 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-12 15:00:08 +08:00
|
|
|
|
var wrapper = new CacheWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
|
2024-07-05 19:29:34 +08:00
|
|
|
|
return RecordFile(bundle.BundleGUID, wrapper);
|
|
|
|
|
|
}
|
|
|
|
|
|
public bool DeleteCacheFile(string bundleGUID)
|
|
|
|
|
|
{
|
2024-12-12 15:00:08 +08:00
|
|
|
|
if (_wrappers.TryGetValue(bundleGUID, out CacheWrapper wrapper))
|
2024-07-05 19:29:34 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
string dataFilePath = wrapper.DataFilePath;
|
|
|
|
|
|
FileInfo fileInfo = new FileInfo(dataFilePath);
|
|
|
|
|
|
if (fileInfo.Exists)
|
|
|
|
|
|
fileInfo.Directory.Delete(true);
|
|
|
|
|
|
_wrappers.Remove(bundleGUID);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-12 15:00:08 +08:00
|
|
|
|
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 内部方法
|
2024-12-17 15:27:36 +08:00
|
|
|
|
public string GetDefaultCacheRoot()
|
|
|
|
|
|
{
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
return YooAssetSettingsData.GetYooEditorCacheRoot();
|
|
|
|
|
|
#elif UNITY_STANDALONE
|
|
|
|
|
|
return YooAssetSettingsData.GetYooStandaloneCacheRoot();
|
|
|
|
|
|
#else
|
|
|
|
|
|
return YooAssetSettingsData.GetYooMobileCacheRoot();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
2024-12-12 15:00:08 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-05 19:29:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除所有清单文件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void DeleteAllManifestFiles()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Directory.Exists(_manifestFileRoot))
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.Delete(_manifestFileRoot, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-03 18:43:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载加密资源文件
|
|
|
|
|
|
/// </summary>
|
2024-12-24 18:23:19 +08:00
|
|
|
|
public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle)
|
2024-07-27 15:25:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
2024-08-03 18:43:12 +08:00
|
|
|
|
var fileInfo = new DecryptFileInfo()
|
2024-07-27 15:25:21 +08:00
|
|
|
|
{
|
2024-08-03 18:43:12 +08:00
|
|
|
|
BundleName = bundle.BundleName,
|
|
|
|
|
|
FileLoadCRC = bundle.UnityCRC,
|
|
|
|
|
|
FileLoadPath = filePath,
|
|
|
|
|
|
};
|
2024-12-24 18:23:19 +08:00
|
|
|
|
return DecryptionServices.LoadAssetBundle(fileInfo);
|
2024-07-27 15:25:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-03 18:43:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载加密资源文件
|
|
|
|
|
|
/// </summary>
|
2024-12-24 18:23:19 +08:00
|
|
|
|
public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle)
|
2024-07-27 15:25:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
string filePath = GetCacheFileLoadPath(bundle);
|
2024-08-03 18:43:12 +08:00
|
|
|
|
var fileInfo = new DecryptFileInfo()
|
2024-07-27 15:25:21 +08:00
|
|
|
|
{
|
2024-08-03 18:43:12 +08:00
|
|
|
|
BundleName = bundle.BundleName,
|
|
|
|
|
|
FileLoadCRC = bundle.UnityCRC,
|
|
|
|
|
|
FileLoadPath = filePath,
|
|
|
|
|
|
};
|
2024-12-24 18:23:19 +08:00
|
|
|
|
return DecryptionServices.LoadAssetBundleAsync(fileInfo);
|
2024-07-27 15:25:21 +08:00
|
|
|
|
}
|
2024-07-04 20:36:26 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|