更新YooAsset 2.3.3 -> 2.3.7 优化YooAsset.RuntimeExtension以及YooAsset.EditorExtension目录结构

更新YooAsset 2.3.3 -> 2.3.7 优化YooAsset.RuntimeExtension以及YooAsset.EditorExtension目录结构
This commit is contained in:
Alex-Rachel
2025-04-17 12:59:23 +08:00
parent 32418326b1
commit 227283864f
206 changed files with 1641 additions and 461 deletions

View File

@@ -2,12 +2,117 @@
All notable changes to this package will be documented in this file.
## [2.3.7] - 2025-04-01
### Improvements
- (#526) 运行时资源清单的哈希值验证兼容了MD5和CRC32两种方式。
- (#515) 优化了资源路径大小写不敏感的逻辑代码减少字符串操作产生的GC。
- (#523) UnloadUnusedAssetsOperation方法支持了分帧处理。
### Fixed
- (#520) 修复了UWP平台获取WWW加载路径未适配的问题。
### Added
- 新增了文件系统初始化参数INSTALL_CLEAR_MODE
```csharp
/// <summary>
/// 覆盖安装清理模式
/// </summary>
public enum EOverwriteInstallClearMode
{
/// <summary>
/// 不做任何处理
/// </summary>
None = 0,
/// <summary>
/// 清理所有缓存文件(包含资源文件和清单文件)
/// </summary>
ClearAllCacheFiles = 1,
/// <summary>
/// 清理所有缓存的资源文件
/// </summary>
ClearAllBundleFiles = 2,
/// <summary>
/// 清理所有缓存的清单文件
/// </summary>
ClearAllManifestFiles = 3,
}
```
- 新增了初始化参数BundleLoadingMaxConcurrency
```csharp
public abstract class InitializeParameters
{
/// <summary>
/// 同时加载Bundle文件的最大并发数
/// </summary>
public int BundleLoadingMaxConcurrency = int.MaxValue;
}
```
## [2.3.6] - 2025-03-25
### Improvements
- 构建管线新增了TaskCreateCatalog任务节点。
- 内置文件系统的catalog文件现在存储在streammingAssets目录下。
### Fixed
- (#486) 修复了微信小游戏文件系统调用ClearUnusedBundleFiles时候的异常。
## [2.3.5-preview] - 2025-03-14
### Fixed
- (#502) 修复了原生缓存文件由于文件格式变动导致的加载本地缓存文件失败的问题。
- (#504) 修复了MacOS平台Offline Play Mode模式请求本地资源清单失败的问题。
- (#506) 修复了v2.3x版本LoadAllAssets方法计算依赖Bundle不完整的问题。
- (#506) 修复了微信小游戏文件系统在启用加密算法后卸载bundle报错的问题。
## [2.3.4-preview] - 2025-03-08
### Improvements
- YooAsset支持了版本宏定义。
```csharp
YOO_ASSET_2
YOO_ASSET_2_3
YOO_ASSET_2_3_OR_NEWER
```
### Fixed
- (#389) 修复了禁用域重载(Reload Domain)的情况下,再次启动游戏报错的问题。
- (#496) 修复了文件系统参数RESUME_DOWNLOAD_MINMUM_SIZE传入int值会导致异常的错误。
- (#498) 修复了v2.3版本尝试加载安卓包内的原生资源包失败的问题。
### Added
- 新增了YooAssets.GetAllPackages()方法
```csharp
/// <summary>
/// 获取所有资源包裹
/// </summary>
public static List<ResourcePackage> GetAllPackages()
```
## [2.3.3-preview] - 2025-03-06
### Improvements
- 新增了异步操作任务调试器AssetBundleDebugger窗口-->OperationView视图模式
- 编辑器下模拟构建默认启用依赖关系数据库,可以大幅增加编辑器下开始游戏时间。
- 编辑器下模拟构建默认启用依赖关系数据库,可以大幅降低编辑器下启动游戏时间。
- 单元测试用例增加加密解密测试用例。
### Fixed

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: caf4d6b8aba38514fa2d00c93b086073
guid: fab3cd742c11be2479b07f5d447a78c9
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace YooAsset.Editor
{
public class MacroDefine
{
/// <summary>
/// YooAsset版本宏定义
/// </summary>
public static readonly List<string> Macros = new List<string>()
{
"YOO_ASSET_2",
"YOO_ASSET_2_3",
"YOO_ASSET_2_3_OR_NEWER",
};
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 56ea224b45d314e4a86b558404e9b6c8
guid: a61e5c2ca04aab647b1ed0492086aa8f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,96 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using UnityEditor;
namespace YooAsset.Editor
{
[InitializeOnLoad]
public class MacroProcessor : AssetPostprocessor
{
static string OnGeneratedCSProject(string path, string content)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(content);
if (IsCSProjectReferenced(xmlDoc.DocumentElement) == false)
return content;
if (ProcessDefineConstants(xmlDoc.DocumentElement) == false)
return content;
// 将修改后的XML结构重新输出为文本
var stringWriter = new StringWriter();
var writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
var xmlWriter = XmlWriter.Create(stringWriter, writerSettings);
xmlDoc.WriteTo(xmlWriter);
xmlWriter.Flush();
return stringWriter.ToString();
}
/// <summary>
/// 处理宏定义
/// </summary>
private static bool ProcessDefineConstants(XmlElement element)
{
if (element == null)
return false;
bool processed = false;
foreach (XmlNode node in element.ChildNodes)
{
if (node.Name != "PropertyGroup")
continue;
foreach (XmlNode childNode in node.ChildNodes)
{
if (childNode.Name != "DefineConstants")
continue;
string[] defines = childNode.InnerText.Split(';');
HashSet<string> hashSets = new HashSet<string>(defines);
foreach (string yooMacro in MacroDefine.Macros)
{
string tmpMacro = yooMacro.Trim();
if (hashSets.Contains(tmpMacro) == false)
hashSets.Add(tmpMacro);
}
childNode.InnerText = string.Join(";", hashSets.ToArray());
processed = true;
}
}
return processed;
}
/// <summary>
/// 检测工程是否引用了YooAsset
/// </summary>
private static bool IsCSProjectReferenced(XmlElement element)
{
if (element == null)
return false;
foreach (XmlNode node in element.ChildNodes)
{
if (node.Name != "ItemGroup")
continue;
foreach (XmlNode childNode in node.ChildNodes)
{
if (childNode.Name != "Reference" && childNode.Name != "ProjectReference")
continue;
string include = childNode.Attributes["Include"].Value;
if (include.Contains("YooAsset"))
return true;
}
}
return false;
}
}
}

View File

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

View File

@@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using UnityEditor;
using UnityEngine;
#if YOO_ASSET_EXPERIMENT
namespace YooAsset.Editor.Experiment
{
[InitializeOnLoad]
public class RspGenerator
{
// csc.rsp文件路径
private static string RspFilePath => Path.Combine(Application.dataPath, "csc.rsp");
static RspGenerator()
{
UpdateRspFile(MacroDefine.Macros, null);
}
/// <summary>
/// 更新csc.rsp文件
/// </summary>
private static void UpdateRspFile(List<string> addMacros, List<string> removeMacros)
{
var existingDefines = new HashSet<string>();
var otherLines = new List<string>();
// 1. 读取现有内容
ReadRspFile(existingDefines, otherLines);
// 2. 添加新宏
if (addMacros != null && addMacros.Count > 0)
{
addMacros.ForEach(x =>
{
if (existingDefines.Contains(x) == false)
existingDefines.Add(x);
});
}
// 3. 移除指定宏
if (removeMacros != null && removeMacros.Count > 0)
{
removeMacros.ForEach(x =>
{
existingDefines.Remove(x);
});
}
// 4. 重新生成内容
WriteRspFile(existingDefines, otherLines);
// 5. 刷新AssetDatabase
AssetDatabase.Refresh();
EditorUtility.RequestScriptReload();
}
/// <summary>
/// 读取csc.rsp文件,返回宏定义和其他行
/// </summary>
private static void ReadRspFile(HashSet<string> defines, List<string> others)
{
if (defines == null)
defines = new HashSet<string>();
if (others == null)
others = new List<string>();
if (File.Exists(RspFilePath) == false)
return;
foreach (string line in File.ReadAllLines(RspFilePath))
{
if (line.StartsWith("-define:"))
{
string[] parts = line.Split(new[] { ':' }, 2);
if (parts.Length == 2)
{
defines.Add(parts[1].Trim());
}
}
else
{
others.Add(line);
}
}
}
/// <summary>
/// 重新写入csc.rsp文件
/// </summary>
private static void WriteRspFile(HashSet<string> defines, List<string> others)
{
StringBuilder sb = new StringBuilder();
if (others != null && others.Count > 0)
{
others.ForEach(o => sb.AppendLine(o));
}
if (defines != null && defines.Count > 0)
{
foreach (string define in defines)
{
sb.AppendLine($"-define:{define}");
}
}
File.WriteAllText(RspFilePath, sb.ToString());
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace YooAsset.Editor
{
public class TaskCreateCatalog
{
/// <summary>
/// 生成内置资源记录文件
/// </summary>
internal void CreateCatalogFile(BuildParametersContext buildParametersContext)
{
string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory();
string buildPackageName = buildParametersContext.Parameters.PackageName;
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(buildPackageName, buildinRootDirectory);
// 刷新目录
AssetDatabase.Refresh();
}
}
}

View File

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

View File

@@ -30,7 +30,7 @@ namespace YooAsset.Editor
// 创建新补丁清单
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
manifest.FileVersion = ManifestDefine.FileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
public class TaskCreateCatalog_BBP : TaskCreateCatalog, IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
if (buildParametersContext.Parameters.BuildinFileCopyOption != EBuildinFileCopyOption.None)
{
CreateCatalogFile(buildParametersContext);
}
}
}
}

View File

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

View File

@@ -36,6 +36,7 @@ namespace YooAsset.Editor
new TaskCreateReport_BBP(),
new TaskCreatePackage_BBP(),
new TaskCopyBuildinFiles_BBP(),
new TaskCreateCatalog_BBP()
};
return pipeline;
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
public class TaskCreateCatalog_RFBP : TaskCreateCatalog, IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
if (buildParametersContext.Parameters.BuildinFileCopyOption != EBuildinFileCopyOption.None)
{
CreateCatalogFile(buildParametersContext);
}
}
}
}

View File

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

View File

@@ -38,6 +38,7 @@ namespace YooAsset.Editor
new TaskCreateReport_RFBP(),
new TaskCreatePackage_RFBP(),
new TaskCopyBuildinFiles_RFBP(),
new TaskCreateCatalog_RFBP()
};
return pipeline;
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
public class TaskCreateCatalog_SBP : TaskCreateCatalog, IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
if (buildParametersContext.Parameters.BuildinFileCopyOption != EBuildinFileCopyOption.None)
{
CreateCatalogFile(buildParametersContext);
}
}
}
}

View File

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

View File

@@ -36,6 +36,7 @@ namespace YooAsset.Editor
new TaskCreateReport_SBP(),
new TaskCreatePackage_SBP(),
new TaskCopyBuildinFiles_SBP(),
new TaskCreateCatalog_SBP()
};
return pipeline;
}

View File

@@ -10,7 +10,7 @@ namespace YooAsset.Editor
/// <summary>
/// 忽略的文件类型
/// </summary>
public readonly static HashSet<string> IgnoreFileExtensions = new HashSet<string>() { "", ".so", ".dll", ".cs", ".js", ".boo", ".meta", ".cginc", ".hlsl" };
public readonly static HashSet<string> IgnoreFileExtensions = new HashSet<string>() { "", ".so", ".cs", ".js", ".boo", ".meta", ".cginc", ".hlsl" };
}
/// <summary>

View File

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

View File

@@ -51,10 +51,6 @@ namespace YooAsset.Editor
string manifestFileName = Path.GetFileNameWithoutExtension(manifestFilePath);
string outputDirectory = Path.GetDirectoryName(manifestFilePath);
// 加载补丁清单
byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath);
PackageManifest manifest = ManifestTools.DeserializeFromBinary(bytesData);
// 拷贝核心文件
{
string sourcePath = $"{outputDirectory}/{manifestFileName}.bytes";
@@ -67,12 +63,16 @@ namespace YooAsset.Editor
EditorTools.CopyFile(sourcePath, destPath, true);
}
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(manifest.PackageName);
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
string sourcePath = $"{outputDirectory}/{fileName}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 加载补丁清单
byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath);
PackageManifest manifest = ManifestTools.DeserializeFromBinary(bytesData);
// 拷贝文件列表
int fileCount = 0;
foreach (var packageBundle in manifest.BundleList)

View File

@@ -0,0 +1,21 @@
{
"name": "YooAsset.EditorExtension",
"rootNamespace": "",
"references": [
"YooAsset",
"Unity.ScriptableBuildPipeline",
"Unity.ScriptableBuildPipeline.Editor",
"YooAsset.Editor"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 281f3f16cd2cf7944b9b7886a4c9a40f
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -7,6 +7,15 @@ namespace YooAsset
{
internal class RemoteDebuggerInRuntime : MonoBehaviour
{
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
_sampleOnce = false;
_autoSample = false;
}
#endif
private static bool _sampleOnce = false;
private static bool _autoSample = false;

View File

@@ -8,6 +8,14 @@ namespace YooAsset
{
internal class RemoteEditorConnection
{
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
_instance = null;
}
#endif
private static RemoteEditorConnection _instance;
public static RemoteEditorConnection Instance
{

View File

@@ -8,6 +8,14 @@ namespace YooAsset
{
internal class RemotePlayerConnection
{
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
_instance = null;
}
#endif
private static RemotePlayerConnection _instance;
public static RemotePlayerConnection Instance
{

View File

@@ -1,30 +0,0 @@

namespace YooAsset
{
internal class DownloadParam
{
public readonly int FailedTryAgain;
public readonly int Timeout;
/// <summary>
/// 导入的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { set; get; }
public DownloadParam(int failedTryAgain, int timeout)
{
FailedTryAgain = failedTryAgain;
Timeout = timeout;
}
}
}

View File

@@ -1,4 +1,5 @@
using UnityEngine.Networking;
using UnityEngine;
namespace YooAsset
{
@@ -9,6 +10,14 @@ namespace YooAsset
internal class DownloadSystemHelper
{
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
UnityWebRequestCreater = null;
}
#endif
public static UnityWebRequestDelegate UnityWebRequestCreater = null;
public static UnityWebRequest NewUnityWebRequestGet(string requestURL)
{
@@ -28,7 +37,9 @@ namespace YooAsset
string url;
// 获取对应平台的URL地址
#if UNITY_EDITOR
#if UNITY_EDITOR_OSX
url = StringUtility.Format("file://{0}", path);
#elif UNITY_EDITOR
url = StringUtility.Format("file:///{0}", path);
#elif UNITY_WEBGL
url = path;
@@ -56,7 +67,7 @@ namespace YooAsset
}
#elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE
#elif UNITY_STANDALONE || UNITY_WSA
url = StringUtility.Format("file:///{0}", path);
#else
throw new System.NotImplementedException();

View File

@@ -6,6 +6,14 @@ namespace YooAsset
{
internal class WebRequestCounter
{
#if UNITY_EDITOR
[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
_requestFailedRecorder.Clear();
}
#endif
/// <summary>
/// 记录网络请求失败事件的次数
/// </summary>

View File

@@ -0,0 +1,21 @@

namespace YooAsset
{
internal class CatalogDefine
{
/// <summary>
/// 文件极限大小100MB
/// </summary>
public const int FileMaxSize = 104857600;
/// <summary>
/// 文件头标记
/// </summary>
public const uint FileSign = 0x133C5EE;
/// <summary>
/// 文件格式版本
/// </summary>
public const string FileVersion = "1.0.0";
}
}

View File

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

View File

@@ -0,0 +1,102 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal static class CatalogTools
{
/// <summary>
/// 序列化JSON文件
/// </summary>
public static void SerializeToJson(string savePath, DefaultBuildinFileCatalog catalog)
{
string json = JsonUtility.ToJson(catalog, true);
FileUtility.WriteAllText(savePath, json);
}
/// <summary>
/// 反序列化JSON文件
/// </summary>
public static DefaultBuildinFileCatalog DeserializeFromJson(string jsonContent)
{
return JsonUtility.FromJson<DefaultBuildinFileCatalog>(jsonContent);
}
/// <summary>
/// 序列化(二进制文件)
/// </summary>
public static void SerializeToBinary(string savePath, DefaultBuildinFileCatalog catalog)
{
using (FileStream fs = new FileStream(savePath, FileMode.Create))
{
// 创建缓存器
BufferWriter buffer = new BufferWriter(CatalogDefine.FileMaxSize);
// 写入文件标记
buffer.WriteUInt32(CatalogDefine.FileSign);
// 写入文件版本
buffer.WriteUTF8(CatalogDefine.FileVersion);
// 写入文件头信息
buffer.WriteUTF8(catalog.PackageName);
buffer.WriteUTF8(catalog.PackageVersion);
// 写入资源包列表
buffer.WriteInt32(catalog.Wrappers.Count);
for (int i = 0; i < catalog.Wrappers.Count; i++)
{
var fileWrapper = catalog.Wrappers[i];
buffer.WriteUTF8(fileWrapper.BundleGUID);
buffer.WriteUTF8(fileWrapper.FileName);
}
// 写入文件流
buffer.WriteToStream(fs);
fs.Flush();
}
}
/// <summary>
/// 反序列化(二进制文件)
/// </summary>
public static DefaultBuildinFileCatalog DeserializeFromBinary(byte[] binaryData)
{
// 创建缓存器
BufferReader buffer = new BufferReader(binaryData);
// 读取文件标记
uint fileSign = buffer.ReadUInt32();
if (fileSign != CatalogDefine.FileSign)
throw new Exception("Invalid catalog file !");
// 读取文件版本
string fileVersion = buffer.ReadUTF8();
if (fileVersion != CatalogDefine.FileVersion)
throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogDefine.FileVersion}");
DefaultBuildinFileCatalog catalog = new DefaultBuildinFileCatalog();
{
// 读取文件头信息
catalog.FileVersion = fileVersion;
catalog.PackageName = buffer.ReadUTF8();
catalog.PackageVersion = buffer.ReadUTF8();
// 读取资源包列表
int fileCount = buffer.ReadInt32();
catalog.Wrappers = new List<DefaultBuildinFileCatalog.FileWrapper>(fileCount);
for (int i = 0; i < fileCount; i++)
{
var fileWrapper = new DefaultBuildinFileCatalog.FileWrapper();
fileWrapper.BundleGUID = buffer.ReadUTF8();
fileWrapper.FileName = buffer.ReadUTF8();
catalog.Wrappers.Add(fileWrapper);
}
}
return catalog;
}
}
}

View File

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

View File

@@ -1,27 +1,27 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 内置资源清单目录
/// </summary>
internal class DefaultBuildinFileCatalog : ScriptableObject
[Serializable]
internal class DefaultBuildinFileCatalog
{
[Serializable]
public class FileWrapper
{
public string BundleGUID;
public string FileName;
public FileWrapper(string bundleGUID, string fileName)
{
BundleGUID = bundleGUID;
FileName = fileName;
}
}
/// <summary>
/// 文件版本
/// </summary>
public string FileVersion;
/// <summary>
/// 包裹名称
/// </summary>

View File

@@ -58,6 +58,11 @@ namespace YooAsset
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary>
/// 自定义参数:数据文件追加文件格式
/// </summary>
@@ -104,15 +109,15 @@ namespace YooAsset
var operation = new DBFSRequestPackageVersionOperation(this);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
return _unpackFileSystem.ClearCacheFilesAsync(manifest, clearMode, clearParam);
return _unpackFileSystem.ClearCacheFilesAsync(manifest, options);
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
// 注意:业务层的解压下载器会依赖内置文件系统的下载方法
param.ImportFilePath = GetBuildinFileLoadPath(bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, param);
options.ImportFilePath = GetBuildinFileLoadPath(bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, options);
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{
@@ -145,17 +150,21 @@ namespace YooAsset
{
FileVerifyLevel = (EFileVerifyLevel)value;
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{
AppendFileExtension = (bool)value;
AppendFileExtension = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.DISABLE_CATALOG_FILE)
{
DisableCatalogFile = (bool)value;
DisableCatalogFile = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST)
{
CopyBuildinPackageManifest = (bool)value;
CopyBuildinPackageManifest = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT)
{
@@ -184,6 +193,7 @@ namespace YooAsset
_unpackFileSystem = new DefaultUnpackFileSystem();
_unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices);
_unpackFileSystem.OnCreate(packageName, null);
@@ -239,6 +249,11 @@ namespace YooAsset
if (Exists(bundle) == false)
return null;
#if UNITY_ANDROID
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
YooLogger.Error($"Android platform not support read buildin bundle file data !");
return null;
#else
if (bundle.Encrypted)
{
if (DecryptionServices == null)
@@ -261,6 +276,7 @@ namespace YooAsset
string filePath = GetBuildinFileLoadPath(bundle);
return FileUtility.ReadAllBytes(filePath);
}
#endif
}
public virtual string ReadBundleFileText(PackageBundle bundle)
{
@@ -270,6 +286,11 @@ namespace YooAsset
if (Exists(bundle) == false)
return null;
#if UNITY_ANDROID
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
YooLogger.Error($"Android platform not support read buildin bundle file text !");
return null;
#else
if (bundle.Encrypted)
{
if (DecryptionServices == null)
@@ -292,6 +313,7 @@ namespace YooAsset
string filePath = GetBuildinFileLoadPath(bundle);
return FileUtility.ReadAllText(filePath);
}
#endif
}
#region
@@ -324,10 +346,9 @@ namespace YooAsset
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(_packageRoot, fileName);
}
public string GetCatalogFileLoadPath()
public string GetCatalogBinaryFileLoadPath()
{
string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName);
return YooAssetSettingsData.GetYooResourcesLoadPath(PackageName, fileName);
return PathUtility.Combine(_packageRoot, DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName);
}
/// <summary>

View File

@@ -17,10 +17,6 @@ namespace YooAsset
{
YooLogger.Log("Begin to create catalog file !");
string savePath = YooAssetSettingsData.GetYooResourcesFullPath();
if (UnityEditor.AssetDatabase.DeleteAsset(savePath))
UnityEditor.AssetDatabase.Refresh();
string rootPath = YooAssetSettingsData.GetYooDefaultBuildinRoot();
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists == false)
@@ -87,10 +83,25 @@ namespace YooAsset
}
// 创建内置清单实例
var buildinFileCatalog = ScriptableObject.CreateInstance<DefaultBuildinFileCatalog>();
var buildinFileCatalog = new DefaultBuildinFileCatalog();
buildinFileCatalog.FileVersion = CatalogDefine.FileVersion;
buildinFileCatalog.PackageName = packageName;
buildinFileCatalog.PackageVersion = packageVersion;
// 创建白名单查询集合
HashSet<string> whiteFileList = new HashSet<string>
{
"link.xml",
"buildlogtep.json",
$"{packageName}.version",
$"{packageName}_{packageVersion}.bytes",
$"{packageName}_{packageVersion}.hash",
$"{packageName}_{packageVersion}.json",
$"{packageName}_{packageVersion}.report",
DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName,
DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName
};
// 记录所有内置资源文件
DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory);
FileInfo[] fileInfos = rootDirectory.GetFiles();
@@ -99,23 +110,15 @@ namespace YooAsset
if (fileInfo.Extension == ".meta")
continue;
if (fileInfo.Name == "link.xml" || fileInfo.Name == "buildlogtep.json")
continue;
if (fileInfo.Name == $"{packageName}.version")
continue;
if (fileInfo.Name == $"{packageName}_{packageVersion}.bytes")
continue;
if (fileInfo.Name == $"{packageName}_{packageVersion}.hash")
continue;
if (fileInfo.Name == $"{packageName}_{packageVersion}.json")
continue;
if (fileInfo.Name == $"{packageName}_{packageVersion}.report")
if (whiteFileList.Contains(fileInfo.Name))
continue;
string fileName = fileInfo.Name;
if (fileMapping.TryGetValue(fileName, out string bundleGUID))
{
var wrapper = new DefaultBuildinFileCatalog.FileWrapper(bundleGUID, fileName);
var wrapper = new DefaultBuildinFileCatalog.FileWrapper();
wrapper.BundleGUID = bundleGUID;
wrapper.FileName = fileName;
buildinFileCatalog.Wrappers.Add(wrapper);
}
else
@@ -124,21 +127,20 @@ namespace YooAsset
}
}
// 创建输出目录
string fullPath = YooAssetSettingsData.GetYooResourcesFullPath();
string saveFilePath = $"{fullPath}/{packageName}/{DefaultBuildinFileSystemDefine.BuildinCatalogFileName}";
FileUtility.CreateFileDirectory(saveFilePath);
// 创建输出文件
string jsonFilePath = $"{pacakgeDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName}";
if (File.Exists(jsonFilePath))
File.Delete(jsonFilePath);
CatalogTools.SerializeToJson(jsonFilePath, buildinFileCatalog);
// 创建输出文件
UnityEditor.AssetDatabase.CreateAsset(buildinFileCatalog, saveFilePath);
UnityEditor.EditorUtility.SetDirty(buildinFileCatalog);
#if UNITY_2019
UnityEditor.AssetDatabase.SaveAssets();
#else
UnityEditor.AssetDatabase.SaveAssetIfDirty(buildinFileCatalog);
#endif
string binaryFilePath = $"{pacakgeDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName}";
if (File.Exists(binaryFilePath))
File.Delete(binaryFilePath);
CatalogTools.SerializeToBinary(binaryFilePath, buildinFileCatalog);
Debug.Log($"Succeed to save buildin file catalog : {saveFilePath}");
UnityEditor.AssetDatabase.Refresh();
Debug.Log($"Succeed to save buildin file catalog : {binaryFilePath}");
return true;
}
}

View File

@@ -4,8 +4,13 @@ namespace YooAsset
internal class DefaultBuildinFileSystemDefine
{
/// <summary>
/// 内置清单文件名称
/// 内置清单JSON文件名称
/// </summary>
public const string BuildinCatalogFileName = "BuildinCatalog.asset";
public const string BuildinCatalogJsonFileName = "BuildinCatalog.json";
/// <summary>
/// 内置清单二进制文件名称
/// </summary>
public const string BuildinCatalogBinaryFileName = "BuildinCatalog.bytes";
}
}

View File

@@ -176,6 +176,12 @@ namespace YooAsset
if (_steps == ESteps.LoadBuildinRawBundle)
{
#if UNITY_ANDROID
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
_steps = ESteps.Done;
Result = new RawBundleResult(_fileSystem, _bundle);
Status = EOperationStatus.Succeed;
#else
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
if (File.Exists(filePath))
{
@@ -190,6 +196,7 @@ namespace YooAsset
Error = $"Can not found buildin raw bundle file : {filePath}";
YooLogger.Error(Error);
}
#endif
}
}
internal override void InternalWaitForAsyncComplete()

View File

@@ -1,4 +1,4 @@
using UnityEngine;
using System;
namespace YooAsset
{
@@ -7,56 +7,84 @@ namespace YooAsset
private enum ESteps
{
None,
RequestData,
LoadCatalog,
Done,
}
private readonly DefaultBuildinFileSystem _fileSystem;
private UnityWebDataRequestOperation _webDataRequestOp;
private ESteps _steps = ESteps.None;
internal LoadBuildinCatalogFileOperation(DefaultBuildinFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_steps = ESteps.LoadCatalog;
_steps = ESteps.RequestData;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestData)
{
if (_webDataRequestOp == null)
{
string filePath = _fileSystem.GetCatalogBinaryFileLoadPath();
string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_webDataRequestOp = new UnityWebDataRequestOperation(url);
_webDataRequestOp.StartOperation();
AddChildOperation(_webDataRequestOp);
}
_webDataRequestOp.UpdateOperation();
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCatalog;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
}
}
if (_steps == ESteps.LoadCatalog)
{
string catalogFilePath = _fileSystem.GetCatalogFileLoadPath();
var catalog = Resources.Load<DefaultBuildinFileCatalog>(catalogFilePath);
if (catalog == null)
try
{
var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result);
if (catalog.PackageName != _fileSystem.PackageName)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
return;
}
foreach (var wrapper in catalog.Wrappers)
{
var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper);
}
YooLogger.Log($"Package '{_fileSystem.PackageName}' buildin catalog files count : {catalog.Wrappers.Count}");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
catch (Exception e)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load catalog file : {catalogFilePath}";
return;
Error = $"Failed to load catalog file : {e.Message}";
}
if (catalog.PackageName != _fileSystem.PackageName)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
return;
}
foreach (var wrapper in catalog.Wrappers)
{
var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper);
}
YooLogger.Log($"Package '{_fileSystem.PackageName}' buildin catalog files count : {catalog.Wrappers.Count}");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}

View File

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -65,6 +65,11 @@ namespace YooAsset
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary>
/// 自定义参数:数据文件追加文件格式
/// </summary>
@@ -115,43 +120,43 @@ namespace YooAsset
var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
if (clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{
var operation = new ClearAllCacheBundleFilesOperation(this);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{
var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest);
return operation;
}
else if (clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, clearParam);
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, options.ClearParam);
return operation;
}
else if (clearMode == EFileClearMode.ClearAllManifestFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString())
{
var operation = new ClearAllCacheManifestFilesOperation(this);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
{
var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest);
return operation;
}
else
{
string error = $"Invalid clear mode : {clearMode}";
string error = $"Invalid clear mode : {options.ClearMode}";
var operation = new FSClearCacheFilesCompleteOperation(error);
return operation;
}
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
var downloader = DownloadCenter.DownloadFileAsync(bundle, param);
var downloader = DownloadCenter.DownloadFileAsync(bundle, options);
downloader.Reference(); //增加下载器的引用计数
// 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!
@@ -188,21 +193,25 @@ namespace YooAsset
{
FileVerifyLevel = (EFileVerifyLevel)value;
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{
AppendFileExtension = (bool)value;
AppendFileExtension = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY)
{
DownloadMaxConcurrency = (int)value;
DownloadMaxConcurrency = Convert.ToInt32(value);
}
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME)
{
DownloadMaxRequestPerFrame = (int)value;
DownloadMaxRequestPerFrame = Convert.ToInt32(value);
}
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
{
ResumeDownloadMinimumSize = (long)value;
ResumeDownloadMinimumSize = Convert.ToInt64(value);
}
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES)
{
@@ -227,8 +236,8 @@ namespace YooAsset
_packageRoot = packageRoot;
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
}
public virtual void OnDestroy()
{
@@ -333,6 +342,13 @@ namespace YooAsset
{
return _records.Keys.ToList();
}
public RecordFileElement GetRecordFileElement(PackageBundle bundle)
{
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element))
return element;
else
return null;
}
public string GetTempFilePath(PackageBundle bundle)
{
@@ -384,10 +400,10 @@ namespace YooAsset
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
{
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element) == false)
return EFileVerifyResult.CacheNotFound;
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
EFileVerifyResult result = FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, EFileVerifyLevel.High);
return result;
}
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
@@ -427,22 +443,10 @@ namespace YooAsset
}
public bool DeleteCacheBundleFile(string bundleGUID)
{
if (_records.TryGetValue(bundleGUID, out RecordFileElement wrapper))
if (_records.TryGetValue(bundleGUID, out RecordFileElement element))
{
try
{
string dataFilePath = wrapper.DataFilePath;
FileInfo fileInfo = new FileInfo(dataFilePath);
if (fileInfo.Exists)
fileInfo.Directory.Delete(true);
_records.Remove(bundleGUID);
return true;
}
catch (Exception e)
{
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
return false;
}
_records.Remove(bundleGUID);
return element.DeleteFolder();
}
else
{
@@ -505,7 +509,18 @@ namespace YooAsset
}
/// <summary>
/// 删除所有清单文件
/// 删除所有缓存的资源文件
/// </summary>
public void DeleteAllBundleFiles()
{
if (Directory.Exists(_cacheBundleFilesRoot))
{
Directory.Delete(_cacheBundleFilesRoot, true);
}
}
/// <summary>
/// 删除所有缓存的清单文件
/// </summary>
public void DeleteAllManifestFiles()
{

View File

@@ -0,0 +1,29 @@

namespace YooAsset
{
/// <summary>
/// 覆盖安装清理模式
/// </summary>
public enum EOverwriteInstallClearMode
{
/// <summary>
/// 不做任何处理
/// </summary>
None = 0,
/// <summary>
/// 清理所有缓存文件(包含资源文件和清单文件)
/// </summary>
ClearAllCacheFiles = 1,
/// <summary>
/// 清理所有缓存的资源文件
/// </summary>
ClearAllBundleFiles = 2,
/// <summary>
/// 清理所有缓存的清单文件
/// </summary>
ClearAllManifestFiles = 3,
}
}

View File

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

View File

@@ -1,4 +1,6 @@

using System;
using System.IO;
namespace YooAsset
{
internal class RecordFileElement
@@ -7,7 +9,7 @@ namespace YooAsset
public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; }
public long DataFileSize { private set; get; }
public RecordFileElement(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
@@ -15,5 +17,31 @@ namespace YooAsset
DataFileCRC = dataFileCRC;
DataFileSize = dataFileSize;
}
/// <summary>
/// 删除记录文件
/// </summary>
public bool DeleteFolder()
{
try
{
string directory = Path.GetDirectoryName(InfoFilePath);
DirectoryInfo directoryInfo = new DirectoryInfo(directory);
if (directoryInfo.Exists)
{
directoryInfo.Delete(true);
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
return false;
}
}
}
}

View File

@@ -46,9 +46,32 @@ namespace YooAsset
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty())
{
_fileSystem.DeleteAllManifestFiles();
if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.None)
{
YooLogger.Warning("Do nothing when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllCacheFiles)
{
_fileSystem.DeleteAllBundleFiles();
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all cache files when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllBundleFiles)
{
_fileSystem.DeleteAllBundleFiles();
YooLogger.Warning("Delete all bundle files when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllManifestFiles)
{
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all manifest files when overwrite install application !");
}
else
{
throw new System.NotImplementedException(_fileSystem.InstallClearMode.ToString());
}
appFootPrint.Coverage(_fileSystem.PackageName);
YooLogger.Warning("Delete manifest files when application foot print dirty !");
}
_steps = ESteps.SearchCacheFiles;

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using UnityEngine;
namespace YooAsset
@@ -57,8 +58,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp);
}
@@ -260,9 +261,30 @@ namespace YooAsset
{
if (_fileSystem.Exists(_bundle))
{
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
_steps = ESteps.LoadCacheRawBundle;
// 注意:缓存的原生文件的格式,可能会在业务端根据需求发生变动!
// 注意:这里需要校验文件格式,如果不一致对本地文件进行修正!
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
if (File.Exists(filePath) == false)
{
try
{
var recordFileElement = _fileSystem.GetRecordFileElement(_bundle);
File.Move(recordFileElement.DataFilePath, filePath);
_steps = ESteps.LoadCacheRawBundle;
}
catch (Exception e)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Faild rename raw data file : {e.Message}";
}
}
else
{
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
_steps = ESteps.LoadCacheRawBundle;
}
}
else
{
@@ -275,8 +297,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp);
}

View File

@@ -7,9 +7,10 @@ namespace YooAsset
private enum ESteps
{
None,
CheckManifest,
CheckArgs,
GetTagsCacheFiles,
ClearTagsCacheFiles,
GetClearCacheFiles,
ClearFilterCacheFiles,
Done,
}
@@ -29,13 +30,27 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.CheckArgs;
_steps = ESteps.CheckManifest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckManifest)
{
if (_manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Can not found active package manifest !";
}
else
{
_steps = ESteps.CheckArgs;
}
}
if (_steps == ESteps.CheckArgs)
{
if (_clearParam == null)
@@ -67,17 +82,17 @@ namespace YooAsset
return;
}
_steps = ESteps.GetTagsCacheFiles;
_steps = ESteps.GetClearCacheFiles;
}
if (_steps == ESteps.GetTagsCacheFiles)
if (_steps == ESteps.GetClearCacheFiles)
{
_clearBundleGUIDs = GetTagsBundleGUIDs();
_clearBundleGUIDs = GetBundleGUIDsByTag();
_clearFileTotalCount = _clearBundleGUIDs.Count;
_steps = ESteps.ClearTagsCacheFiles;
_steps = ESteps.ClearFilterCacheFiles;
}
if (_steps == ESteps.ClearTagsCacheFiles)
if (_steps == ESteps.ClearFilterCacheFiles)
{
for (int i = _clearBundleGUIDs.Count - 1; i >= 0; i--)
{
@@ -100,7 +115,7 @@ namespace YooAsset
}
}
}
private List<string> GetTagsBundleGUIDs()
private List<string> GetBundleGUIDsByTag()
{
var allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
List<string> result = new List<string>(allBundleGUIDs.Count);

View File

@@ -8,6 +8,7 @@ namespace YooAsset
private enum ESteps
{
None,
CheckManifest,
GetUnusedCacheFiles,
ClearUnusedCacheFiles,
Done,
@@ -19,7 +20,7 @@ namespace YooAsset
private int _unusedFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearUnusedCacheBundleFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest)
{
_fileSystem = fileSystem;
@@ -27,15 +28,29 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.GetUnusedCacheFiles;
_steps = ESteps.CheckManifest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckManifest)
{
if (_manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Can not found active package manifest !";
}
else
{
_steps = ESteps.GetUnusedCacheFiles;
}
}
if (_steps == ESteps.GetUnusedCacheFiles)
{
{
_unusedBundleGUIDs = GetUnusedBundleGUIDs();
_unusedFileTotalCount = _unusedBundleGUIDs.Count;
_steps = ESteps.ClearUnusedCacheFiles;

View File

@@ -8,6 +8,7 @@ namespace YooAsset
private enum ESteps
{
None,
CheckManifest,
ClearUnusedCacheFiles,
Done,
}
@@ -24,13 +25,27 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.ClearUnusedCacheFiles;
_steps = ESteps.CheckManifest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckManifest)
{
if (_manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Can not found active package manifest !";
}
else
{
_steps = ESteps.ClearUnusedCacheFiles;
}
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
try

View File

@@ -74,7 +74,7 @@ namespace YooAsset
/// <summary>
/// 创建下载任务
/// </summary>
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
// 查询旧的下载器
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
@@ -83,29 +83,29 @@ namespace YooAsset
}
// 设置请求URL
if (string.IsNullOrEmpty(param.ImportFilePath))
if (string.IsNullOrEmpty(options.ImportFilePath))
{
param.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(bundle.FileName);
param.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(bundle.FileName);
}
else
{
// 注意:把本地文件路径指定为远端下载地址
param.MainURL = DownloadSystemHelper.ConvertToWWWPath(param.ImportFilePath);
param.FallbackURL = param.MainURL;
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath);
options.FallbackURL = options.MainURL;
}
// 创建新的下载器
DefaultDownloadFileOperation newDownloader;
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
{
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, param);
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}
else
{
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, param);
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}

View File

@@ -12,13 +12,13 @@ namespace YooAsset
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}

View File

@@ -15,13 +15,13 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}

View File

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_fileData);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -85,15 +85,17 @@ namespace YooAsset
// 创建验证元素类
string fileRootPath = chidDirectory.FullName;
string dataFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.BundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.BundleInfoFileName}";
string dataFilePath = $"{fileRootPath}/{DefaultCacheFileSystemDefine.BundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{DefaultCacheFileSystemDefine.BundleInfoFileName}";
// 存储的数据文件追加文件格式
if (_fileSystem.AppendFileExtension)
{
string dataFileExtension = FindDataFileExtension(chidDirectory);
if (string.IsNullOrEmpty(dataFileExtension) == false)
{
dataFilePath += dataFileExtension;
}
}
var element = new VerifyFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);

View File

@@ -66,12 +66,12 @@ namespace YooAsset
var operation = new DEFSRequestPackageVersionOperation(this);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}
@@ -94,11 +94,11 @@ namespace YooAsset
{
if (name == FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME)
{
_asyncSimulateMinFrame = (int)value;
_asyncSimulateMinFrame = Convert.ToInt32(value);
}
else if (name == FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME)
{
_asyncSimulateMaxFrame = (int)value;
_asyncSimulateMaxFrame = Convert.ToInt32(value);
}
else
{

View File

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_fileData);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

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

View File

@@ -11,8 +11,13 @@ namespace YooAsset
/// <summary>
/// 保存的资源文件的文件夹名称
/// </summary>
public const string SaveFilesFolderName = "UnpackFiles";
public const string SaveBundleFilesFolderName = "UnpackBundleFiles";
/// <summary>
/// 保存的清单文件的文件夹名称
/// </summary>
public const string SaveManifestFilesFolderName = "UnpackManifestFiles";
/// <summary>
/// 下载的临时文件的文件夹名称
/// </summary>

View File

@@ -73,12 +73,12 @@ namespace YooAsset
var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}
@@ -101,7 +101,7 @@ namespace YooAsset
{
if (name == FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE)
{
DisableUnityWebCache = (bool)value;
DisableUnityWebCache = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{

View File

@@ -34,19 +34,19 @@ namespace YooAsset
{
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}

View File

@@ -72,8 +72,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -82,12 +82,12 @@ namespace YooAsset
var operation = new DWSFSRequestPackageVersionOperation(this, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}
@@ -110,7 +110,7 @@ namespace YooAsset
{
if (name == FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE)
{
DisableUnityWebCache = (bool)value;
DisableUnityWebCache = Convert.ToBoolean(value);
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
@@ -198,10 +198,9 @@ namespace YooAsset
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(FileRoot, fileName);
}
public string GetCatalogFileLoadPath()
public string GetCatalogBinaryFileLoadPath()
{
string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName);
return YooAssetSettingsData.GetYooResourcesLoadPath(PackageName, fileName);
return PathUtility.Combine(_webPackageRoot, DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName);
}
/// <summary>

View File

@@ -34,20 +34,20 @@ namespace YooAsset
{
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
downloadParam.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
downloadParam.FallbackURL = downloadParam.MainURL;
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
options.FallbackURL = options.MainURL;
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}

View File

@@ -2,7 +2,6 @@
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
@@ -11,61 +10,84 @@ namespace YooAsset
private enum ESteps
{
None,
RequestData,
LoadCatalog,
Done,
}
private readonly DefaultWebServerFileSystem _fileSystem;
private UnityWebDataRequestOperation _webDataRequestOp;
private ESteps _steps = ESteps.None;
/// <summary>
/// 内置清单版本
/// </summary>
public string PackageVersion { private set; get; }
internal LoadWebServerCatalogFileOperation(DefaultWebServerFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_steps = ESteps.LoadCatalog;
_steps = ESteps.RequestData;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestData)
{
if (_webDataRequestOp == null)
{
string filePath = _fileSystem.GetCatalogBinaryFileLoadPath();
string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_webDataRequestOp = new UnityWebDataRequestOperation(url);
_webDataRequestOp.StartOperation();
AddChildOperation(_webDataRequestOp);
}
_webDataRequestOp.UpdateOperation();
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCatalog;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
}
}
if (_steps == ESteps.LoadCatalog)
{
string catalogFilePath = _fileSystem.GetCatalogFileLoadPath();
var catalog = Resources.Load<DefaultBuildinFileCatalog>(catalogFilePath);
if (catalog == null)
try
{
var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result);
if (catalog.PackageName != _fileSystem.PackageName)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
return;
}
foreach (var wrapper in catalog.Wrappers)
{
var fileWrapper = new DefaultWebServerFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper);
}
YooLogger.Log($"Package '{_fileSystem.PackageName}' buildin catalog files count : {catalog.Wrappers.Count}");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
catch (Exception e)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load web server catalog file : {catalogFilePath}";
return;
Error = $"Failed to load catalog file : {e.Message}";
}
if (catalog.PackageName != _fileSystem.PackageName)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
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 DefaultWebServerFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper);
}
YooLogger.Log($"Package '{_fileSystem.PackageName}' catalog files count : {catalog.Wrappers.Count}");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}

View File

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

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

View File

@@ -37,13 +37,13 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
/// <summary>
/// 下载Bundle文件
/// </summary>
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param);
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
/// <summary>
/// 加载Bundle文件
/// </summary>

View File

@@ -1,6 +1,19 @@

namespace YooAsset
{
internal class ClearCacheFilesOptions
{
/// <summary>
/// 清理模式
/// </summary>
public string ClearMode;
/// <summary>
/// 附加参数
/// </summary>
public object ClearParam;
}
internal abstract class FSClearCacheFilesOperation : AsyncOperationBase
{
}

View File

@@ -1,6 +1,40 @@

namespace YooAsset
{
internal class DownloadFileOptions
{
/// <summary>
/// 失败后重试次数
/// </summary>
public readonly int FailedTryAgain;
/// <summary>
/// 超时时间
/// </summary>
public readonly int Timeout;
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { set; get; }
/// <summary>
/// 导入的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
public DownloadFileOptions(int failedTryAgain, int timeout)
{
FailedTryAgain = failedTryAgain;
Timeout = timeout;
}
}
internal abstract class FSDownloadFileOperation : AsyncOperationBase
{
public PackageBundle Bundle { private set; get; }

View File

@@ -18,7 +18,7 @@ namespace YooAsset
}
// 下载参数
protected readonly DownloadParam Param;
protected readonly DownloadFileOptions Options;
// 请求相关
protected UnityWebRequest _webRequest;
@@ -35,10 +35,10 @@ namespace YooAsset
protected int FailedTryAgain;
internal DefaultDownloadFileOperation(PackageBundle bundle, DownloadParam param) : base(bundle)
internal DefaultDownloadFileOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle)
{
Param = param;
FailedTryAgain = param.FailedTryAgain;
Options = options;
FailedTryAgain = options.FailedTryAgain;
}
/// <summary>
@@ -49,9 +49,9 @@ namespace YooAsset
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return Param.FallbackURL;
return Options.FallbackURL;
else
return Param.MainURL;
return Options.MainURL;
}
/// <summary>
@@ -87,7 +87,7 @@ namespace YooAsset
}
float offset = UnityEngine.Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > Param.Timeout)
if (offset > Options.Timeout)
{
YooLogger.Warning($"Download request timeout : {_requestURL}");
if (_webRequest != null)

View File

@@ -4,7 +4,7 @@ namespace YooAsset
{
internal abstract class DownloadAssetBundleOperation : DefaultDownloadFileOperation
{
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
}

View File

@@ -10,7 +10,7 @@ namespace YooAsset
private DownloadHandlerBuffer _downloadhandler;
private ESteps _steps = ESteps.None;
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_checkTimeout = checkTimeout;
_decryptionServices = decryptionServices;

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