Compare commits

...

50 Commits

Author SHA1 Message Date
何冠峰
2a8761c29e Update CHANGELOG.md 2025-01-03 18:10:59 +08:00
何冠峰
0c732755ec Update package.json 2025-01-03 18:10:53 +08:00
何冠峰
5c638d713e update space shooter 2025-01-03 17:49:20 +08:00
何冠峰
8ff16f7205 update test sample 2025-01-03 17:27:04 +08:00
何冠峰
6bf8e3643b fix #428 2025-01-03 15:44:44 +08:00
何冠峰
6ab704bb77 fix #435 2025-01-03 15:37:32 +08:00
何冠峰
41329f3bbc update space shooter 2025-01-03 15:09:29 +08:00
何冠峰
a59ebd69b4 update extension sample 2025-01-03 15:09:20 +08:00
何冠峰
278b6e3cc8 fix #429
ClearCacheBundleFilesAsync重命名为ClearCacheFilesAsync
2025-01-03 15:08:57 +08:00
何冠峰
1d0c0ee7cb update asset bundle collector 2025-01-03 10:23:27 +08:00
何冠峰
a8bf0a62fa update asset bundle collector
增加视频文件打包规则
2025-01-02 20:56:18 +08:00
何冠峰
fc58fb27e2 Update AssemblyInfo.cs 2025-01-02 20:55:57 +08:00
何冠峰
b1abeb4ec2 update test sample
单元测试用例
2025-01-02 20:55:47 +08:00
何冠峰
d9b7f33bde update space shooter 2025-01-02 20:15:20 +08:00
何冠峰
c0a1061204 update extension sample
更新抖音小游戏文件系统
2025-01-02 18:45:54 +08:00
何冠峰
7cbdfeec51 fix #434 2025-01-02 15:58:49 +08:00
何冠峰
381c16d574 update space shooter 2025-01-02 14:10:21 +08:00
何冠峰
3e6be2f293 update resource package 2025-01-02 14:10:11 +08:00
何冠峰
1bd62c4673 update space shooter 2025-01-02 10:51:32 +08:00
何冠峰
04aa4067cd update space shooter 2025-01-02 10:47:07 +08:00
何冠峰
499fb8239e fix #433 2025-01-02 10:46:52 +08:00
何冠峰
fe75491024 update resource manager
整理文件目录结构
2025-01-02 10:45:56 +08:00
何冠峰
8803003cf7 fix #432
FileSystemParameters.RootDirectory字段重命名为PackageRoot
2024-12-31 19:22:00 +08:00
何冠峰
5a850aef07 Update AssetBundleCollectorSettingData.cs 2024-12-31 16:43:50 +08:00
何冠峰
d1d6e023c4 update space shooter 2024-12-31 15:13:13 +08:00
何冠峰
4370ed544f update cache system 2024-12-31 11:15:46 +08:00
何冠峰
42c87519e1 Update SceneHandle.cs 2024-12-31 10:16:29 +08:00
何冠峰
769134eaf9 update cache system
移除ThreadSyncContext类
2024-12-31 10:16:20 +08:00
何冠峰
51b688bbdd fix #426 2024-12-31 10:02:01 +08:00
何冠峰
748e74e515 Update CHANGELOG.md 2024-12-30 17:13:07 +08:00
何冠峰
d1d3ad9869 Update package.json 2024-12-30 17:12:59 +08:00
何冠峰
f9b72a22ae fix #423 2024-12-30 16:27:50 +08:00
何冠峰
766cf90a19 fix #422 2024-12-30 10:27:04 +08:00
何冠峰
8a2dc86cf7 update code summary 2024-12-27 18:37:29 +08:00
何冠峰
5ca54b88fa update download system 2024-12-27 17:51:21 +08:00
何冠峰
7257c8778d Merge pull request #332 from Pro-Ly/dev
fix url path special cases
2024-12-27 17:45:00 +08:00
何冠峰
dc21696ae1 update extension sample
新增示例代码HandleBaseExtension
2024-12-27 17:34:22 +08:00
何冠峰
7f566e5388 update extension sample
重新整理目录结构
2024-12-27 17:29:00 +08:00
何冠峰
fe352ceb84 update operation system
新增字段PackageName
2024-12-27 17:23:55 +08:00
何冠峰
10750a0123 update space shooter 2024-12-27 17:08:59 +08:00
何冠峰
f2e6da649b update resource package
重构了下载器的委托方法
2024-12-27 17:08:39 +08:00
何冠峰
9737cd06dd Merge pull request #392 from absences/newv
upgrade deprecated event in newer version
2024-12-27 16:06:24 +08:00
何冠峰
df8cf4d9ca update extension sample 2024-12-27 16:04:01 +08:00
何冠峰
36b4cbb8c2 Update DefaultAddressRule.cs 2024-12-27 16:03:47 +08:00
何冠峰
bae84f65da Merge pull request #370 from BoysheO/patch-1
append an addressRule
2024-12-27 15:50:14 +08:00
何冠峰
313ec2d100 Merge pull request #418 from GodChouyu/dev
Fix a bug when initializing DefaultWebRemoteFileSystem.
2024-12-27 15:16:38 +08:00
GodChouyu
25c5683a09 Fix a bug when initializing DefaultWebRemoteFileSystem. 2024-12-27 10:16:57 +08:00
unknown
02250c3352 upgrade deprecated method in newer version 2024-11-12 14:40:49 +08:00
BoysheO
9e2030c83d Update DefaultAddressRule.cs
添加一个寻址规则,效果极好
2024-09-10 11:36:46 +08:00
Pro-Ly
be3fa0b688 fix url path special cases 2024-07-31 23:28:47 +08:00
489 changed files with 7130 additions and 5091 deletions

View File

@@ -2,6 +2,113 @@
All notable changes to this package will be documented in this file.
## [2.2.8-preview] - 2025-01-03
新增了单元测试用例。
### Improvements
- EditorSimulateModeHelper.SimulateBuild()方法提供指定自定义构建类
```csharp
public class EditorSimulateBuildParam
{
/// <summary>
/// 模拟构建类所属程序集名称
/// </summary>
public string InvokeAssmeblyName = "YooAsset.Editor";
/// <summary>
/// 模拟构建执行的类名全称
/// 注意:类名必须包含命名空间!
/// </summary>
public string InvokeClassFullName = "YooAsset.Editor.AssetBundleSimulateBuilder";
/// <summary>
/// 模拟构建执行的方法名称
/// 注意:执行方法必须满足 BindingFlags.Public | BindingFlags.Static
/// </summary>
public string InvokeMethodName = "SimulateBuild";
}
```
- 文件清理方式新增清理缓存清单。
```csharp
/// <summary>
/// 文件清理方式
/// </summary>
public enum EFileClearMode
{
/// <summary>
/// 清理所有清单
/// </summary>
ClearAllManifestFiles,
/// <summary>
/// 清理未在使用的清单
/// </summary>
ClearUnusedManifestFiles,
}
```
### Fixed
- (#426) 修复了鸿蒙next平台加载内置文件路径报错的问题。
- (#428) 修复了鸿蒙next平台加载内置文件路径报错的问题。
- (#434) 修复了2.2版本 catalog文件对Json格式原生文件不记录的问题。
- (#435) 修复了WebGL平台调用MD5算法触发异常的问题。
### Added
- 新增了视频打包规则。
```csharp
/// <summary>
/// 打包视频文件
/// </summary>
[DisplayName("打包视频文件")]
public class PackVideoFile : IPackRule
```
### Changed
- 重命名FileSystemParameters.RootDirectory字段为PackageRoot
- 重命名ResourcePackage.ClearCacheBundleFilesAsync()方法为ClearCacheFilesAsync()
## [2.2.7-preview] - 2024-12-30
### Improvements
- 重构了下载器的委托方法。
- YooAssetSettings配置文件新增Package Manifest Prefix参数。
```csharp
/// <summary>
/// 资源清单前缀名称(默认为空)
/// </summary>
public string PackageManifestPrefix = string.Empty;
```
### Fixed
- (#422) 修复了同步加载场景的NotImplementedException异常报错。
- (#418) 修复了web远程文件系统初始化不正确的问题
- (#392) 修复了引擎版本代码兼容相关的警告。
- (#332) 修复了当用户的设备中有特殊字符时URL路径无法被正确识别的问题。
### Added
- 新增代码字段AsyncOperationBase.PackageName
### Changed
- 重命名DownloaderOperation.OnDownloadOver()方法为DownloaderFinish()
- 重命名DownloaderOperation.OnDownloadProgress()方法为DownloadUpdate()
- 重命名DownloaderOperation.OnDownloadError()方法为DownloadError()
- 重命名DownloaderOperation.OnStartDownloadFile()方法为DownloadFileBegin()
## [2.2.6-preview] - 2024-12-27
### Improvements

View File

@@ -68,7 +68,7 @@ namespace YooAsset.Editor
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToBinary(filePath, manifest);
packageHash = HashUtility.FileMD5(filePath);
packageHash = HashUtility.FileCRC32(filePath);
BuildLogger.Log($"Create package manifest file: {filePath}");
ManifestContext manifestContext = new ManifestContext();

View File

@@ -116,7 +116,7 @@ namespace YooAsset.Editor
buildReport.IndependAssets = new List<ReportIndependAsset>(buildMapContext.IndependAssets);
// 序列化文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string fileName = YooAssetSettingsData.GetBuildReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
BuildReport.Serialize(filePath, buildReport);
BuildLogger.Log($"Create build report file: {filePath}");

View File

@@ -201,7 +201,6 @@ namespace YooAsset.Editor
public static void ClearAll()
{
Setting.ClearAll();
SaveFile();
}
public static List<RuleDisplayName> GetActiveRuleNames()

View File

@@ -205,7 +205,9 @@ namespace YooAsset.Editor
_packageListView = root.Q<ListView>("PackageListView");
_packageListView.makeItem = MakePackageListViewItem;
_packageListView.bindItem = BindPackageListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_packageListView.selectionChanged += PackageListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_packageListView.onSelectionChange += PackageListView_onSelectionChange;
#else
_packageListView.onSelectionChanged += PackageListView_onSelectionChange;
@@ -250,7 +252,9 @@ namespace YooAsset.Editor
_groupListView = root.Q<ListView>("GroupListView");
_groupListView.makeItem = MakeGroupListViewItem;
_groupListView.bindItem = BindGroupListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_groupListView.selectionChanged += GroupListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_groupListView.onSelectionChange += GroupListView_onSelectionChange;
#else
_groupListView.onSelectionChanged += GroupListView_onSelectionChange;

View File

@@ -10,246 +10,23 @@ namespace YooAsset.Editor
{
public class AssetDependencyCache
{
/// <summary>
/// 资源依赖缓存数据库
/// </summary>
private class CacheDatabase
{
private class CacheInfo
{
/// <summary>
/// 此哈希函数会聚合了以下内容:源资源路径、源资源、元文件、目标平台以及导入器版本。
/// 如果此哈希值发送变化,则说明导入资源可能已更改,因此应重新搜集依赖关系。
/// </summary>
public string DependHash;
/// <summary>
/// 直接依赖资源的GUID列表
/// </summary>
public List<string> DependGUIDs = new List<string>();
}
private string _databaseFilePath;
private readonly Dictionary<string, CacheInfo> _database = new Dictionary<string, CacheInfo>(100000);
/// <summary>
/// 创建数据库
/// </summary>
public void CreateDatabase(string databaseFilePath, bool useCacheDatabase)
{
_databaseFilePath = databaseFilePath;
_database.Clear();
try
{
if (useCacheDatabase && File.Exists(databaseFilePath))
{
// 解析缓存文件
using var stream = File.OpenRead(databaseFilePath);
using var reader = new BinaryReader(stream);
var count = reader.ReadInt32();
for (int i = 0; i < count; i++)
{
var assetPath = reader.ReadString();
var cacheInfo = new CacheInfo
{
DependHash = reader.ReadString(),
DependGUIDs = ReadStringList(reader),
};
_database.Add(assetPath, cacheInfo);
}
// 移除无效资源
List<string> removeList = new List<string>(10000);
foreach (var cacheInfoPair in _database)
{
var assetPath = cacheInfoPair.Key;
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
if (string.IsNullOrEmpty(assetGUID))
{
removeList.Add(assetPath);
}
}
foreach (var assetPath in removeList)
{
_database.Remove(assetPath);
}
}
}
catch (Exception ex)
{
ClearCache(true);
Debug.LogError($"Failed to load cache database : {ex.Message}");
}
// 查找新增或变动资源
var allAssetPaths = AssetDatabase.GetAllAssetPaths();
foreach (var assetPath in allAssetPaths)
{
if (_database.TryGetValue(assetPath, out CacheInfo cacheInfo))
{
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
if (dependHash.ToString() != cacheInfo.DependHash)
{
_database[assetPath] = CreateCacheInfo(assetPath);
}
}
else
{
var newCacheInfo = CreateCacheInfo(assetPath);
_database.Add(assetPath, newCacheInfo);
}
}
}
/// <summary>
/// 保存缓存文件
/// </summary>
public void SaveCacheFile()
{
if (File.Exists(_databaseFilePath))
File.Delete(_databaseFilePath);
try
{
using var stream = File.Create(_databaseFilePath);
using var writer = new BinaryWriter(stream);
writer.Write(_database.Count);
foreach (var assetPair in _database)
{
string assetPath = assetPair.Key;
var assetInfo = assetPair.Value;
writer.Write(assetPath);
writer.Write(assetInfo.DependHash);
WriteStringList(writer, assetInfo.DependGUIDs);
}
writer.Flush();
}
catch (Exception ex)
{
Debug.LogError($"Failed to save cache database : {ex.Message}");
}
}
/// <summary>
/// 清理缓存数据
/// </summary>
public void ClearCache(bool clearDatabaseFile)
{
if (clearDatabaseFile)
{
if (File.Exists(_databaseFilePath))
File.Delete(_databaseFilePath);
}
_database.Clear();
}
/// <summary>
/// 获取资源的依赖列表
/// </summary>
public string[] GetDependencies(string assetPath, bool recursive)
{
// 注意AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
// 注意AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
// 注意:机制上不允许存在未收录的资源
if (_database.ContainsKey(assetPath) == false)
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
}
var result = new HashSet<string> { assetPath };
CollectDependencies(assetPath, result, recursive);
// 注意AssetDatabase.GetDependencies保持一致将主资源添加到依赖列表最前面
return result.ToArray();
}
private void CollectDependencies(string assetPath, HashSet<string> result, bool recursive)
{
if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
}
foreach (var dependGUID in cacheInfo.DependGUIDs)
{
string dependAssetPath = AssetDatabase.GUIDToAssetPath(dependGUID);
if (string.IsNullOrEmpty(dependAssetPath))
continue;
// 如果是文件夹资源
if (AssetDatabase.IsValidFolder(dependAssetPath))
continue;
// 如果已经收集过
if (result.Contains(dependAssetPath))
continue;
result.Add(dependAssetPath);
// 递归收集依赖
if (recursive)
CollectDependencies(dependAssetPath, result, recursive);
}
}
private List<string> ReadStringList(BinaryReader reader)
{
var count = reader.ReadInt32();
var values = new List<string>(count);
for (int i = 0; i < count; i++)
{
values.Add(reader.ReadString());
}
return values;
}
private void WriteStringList(BinaryWriter writer, List<string> values)
{
writer.Write(values.Count);
foreach (var value in values)
{
writer.Write(value);
}
}
private CacheInfo CreateCacheInfo(string assetPath)
{
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
var dependGUIDs = new List<string>();
foreach (var dependAssetPath in dependAssetPaths)
{
string guid = AssetDatabase.AssetPathToGUID(dependAssetPath);
if (string.IsNullOrEmpty(guid) == false)
{
dependGUIDs.Add(guid);
}
}
var cacheInfo = new CacheInfo();
cacheInfo.DependHash = dependHash.ToString();
cacheInfo.DependGUIDs = dependGUIDs;
return cacheInfo;
}
}
private readonly CacheDatabase _database;
private readonly AssetDependencyDatabase _database;
/// <summary>
/// 初始化资源依赖缓存系统
/// </summary>
public AssetDependencyCache(bool useCacheDatabase)
public AssetDependencyCache(bool useAssetDependencyDB)
{
if (useCacheDatabase)
if (useAssetDependencyDB)
Debug.Log("Use asset dependency database !");
string databaseFilePath = "Library/AssetDependencyDB";
_database = new CacheDatabase();
_database.CreateDatabase(databaseFilePath, useCacheDatabase);
_database = new AssetDependencyDatabase();
_database.CreateDatabase(useAssetDependencyDB, databaseFilePath);
if (useCacheDatabase)
if (useAssetDependencyDB)
{
_database.SaveCacheFile();
_database.SaveDatabase();
}
}

View File

@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
/// <summary>
/// 资源依赖数据库
/// </summary>
public class AssetDependencyDatabase
{
private const string FILE_VERSION = "1.0";
private class DependencyInfo
{
/// <summary>
/// 此哈希函数会聚合了以下内容:源资源路径、源资源、元文件、目标平台以及导入器版本。
/// 如果此哈希值发送变化,则说明导入资源可能已更改,因此应重新搜集依赖关系。
/// </summary>
public string DependHash;
/// <summary>
/// 直接依赖资源的GUID列表
/// </summary>
public List<string> DependGUIDs = new List<string>();
}
private string _databaseFilePath;
private readonly Dictionary<string, DependencyInfo> _database = new Dictionary<string, DependencyInfo>(100000);
/// <summary>
/// 创建缓存数据库
/// </summary>
public void CreateDatabase(bool readCacheDatabaseFile, string databaseFilePath)
{
_databaseFilePath = databaseFilePath;
_database.Clear();
try
{
if (readCacheDatabaseFile && File.Exists(databaseFilePath))
{
// 解析缓存文件
using var stream = File.OpenRead(databaseFilePath);
using var reader = new BinaryReader(stream);
string fileVersion = reader.ReadString();
if (fileVersion != FILE_VERSION)
throw new Exception("The database file version not match !");
var count = reader.ReadInt32();
for (int i = 0; i < count; i++)
{
var assetPath = reader.ReadString();
var cacheInfo = new DependencyInfo
{
DependHash = reader.ReadString(),
DependGUIDs = ReadStringList(reader),
};
_database.Add(assetPath, cacheInfo);
}
// 移除无效资源
List<string> removeList = new List<string>(10000);
foreach (var cacheInfoPair in _database)
{
var assetPath = cacheInfoPair.Key;
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
if (string.IsNullOrEmpty(assetGUID))
{
removeList.Add(assetPath);
}
}
foreach (var assetPath in removeList)
{
_database.Remove(assetPath);
}
}
}
catch (Exception ex)
{
ClearDatabase(true);
Debug.LogError($"Failed to load cache database : {ex.Message}");
}
// 查找新增或变动资源
var allAssetPaths = AssetDatabase.GetAllAssetPaths();
foreach (var assetPath in allAssetPaths)
{
if (_database.TryGetValue(assetPath, out DependencyInfo cacheInfo))
{
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
if (dependHash.ToString() != cacheInfo.DependHash)
{
_database[assetPath] = CreateDependencyInfo(assetPath);
}
}
else
{
var newCacheInfo = CreateDependencyInfo(assetPath);
_database.Add(assetPath, newCacheInfo);
}
}
}
/// <summary>
/// 保存缓存数据库
/// </summary>
public void SaveDatabase()
{
if (File.Exists(_databaseFilePath))
File.Delete(_databaseFilePath);
try
{
using var stream = File.Create(_databaseFilePath);
using var writer = new BinaryWriter(stream);
writer.Write(FILE_VERSION);
writer.Write(_database.Count);
foreach (var assetPair in _database)
{
string assetPath = assetPair.Key;
var assetInfo = assetPair.Value;
writer.Write(assetPath);
writer.Write(assetInfo.DependHash);
WriteStringList(writer, assetInfo.DependGUIDs);
}
writer.Flush();
}
catch (Exception ex)
{
Debug.LogError($"Failed to save cache database : {ex.Message}");
}
}
/// <summary>
/// 清理缓存数据库
/// </summary>
public void ClearDatabase(bool deleteDatabaseFile)
{
if (deleteDatabaseFile)
{
if (File.Exists(_databaseFilePath))
File.Delete(_databaseFilePath);
}
_database.Clear();
}
/// <summary>
/// 获取资源的依赖列表
/// </summary>
public string[] GetDependencies(string assetPath, bool recursive)
{
// 注意AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
// 注意AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
// 注意:机制上不允许存在未收录的资源
if (_database.ContainsKey(assetPath) == false)
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
}
var result = new HashSet<string> { assetPath };
CollectDependencies(assetPath, result, recursive);
// 注意AssetDatabase.GetDependencies保持一致将主资源添加到依赖列表最前面
return result.ToArray();
}
private void CollectDependencies(string assetPath, HashSet<string> result, bool recursive)
{
if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
}
foreach (var dependGUID in cacheInfo.DependGUIDs)
{
string dependAssetPath = AssetDatabase.GUIDToAssetPath(dependGUID);
if (string.IsNullOrEmpty(dependAssetPath))
continue;
// 如果是文件夹资源
if (AssetDatabase.IsValidFolder(dependAssetPath))
continue;
// 如果已经收集过
if (result.Contains(dependAssetPath))
continue;
result.Add(dependAssetPath);
// 递归收集依赖
if (recursive)
CollectDependencies(dependAssetPath, result, recursive);
}
}
private List<string> ReadStringList(BinaryReader reader)
{
var count = reader.ReadInt32();
var values = new List<string>(count);
for (int i = 0; i < count; i++)
{
values.Add(reader.ReadString());
}
return values;
}
private void WriteStringList(BinaryWriter writer, List<string> values)
{
writer.Write(values.Count);
foreach (var value in values)
{
writer.Write(value);
}
}
private DependencyInfo CreateDependencyInfo(string assetPath)
{
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
var dependGUIDs = new List<string>();
foreach (var dependAssetPath in dependAssetPaths)
{
string guid = AssetDatabase.AssetPathToGUID(dependAssetPath);
if (string.IsNullOrEmpty(guid) == false)
{
dependGUIDs.Add(guid);
}
}
var cacheInfo = new DependencyInfo();
cacheInfo.DependHash = dependHash.ToString();
cacheInfo.DependGUIDs = dependGUIDs;
return cacheInfo;
}
}
}

View File

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

View File

@@ -147,6 +147,22 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 打包视频文件
/// </summary>
[DisplayName("打包视频文件")]
public class PackVideoFile : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName = data.AssetPath;
string fileExtension = Path.GetExtension(data.AssetPath);
fileExtension = fileExtension.Remove(0, 1);
PackRuleResult result = new PackRuleResult(bundleName, fileExtension);
return result;
}
}
/// <summary>
/// 打包着色器
/// </summary>

View File

@@ -35,7 +35,9 @@ namespace YooAsset.Editor
_assetListView = _root.Q<ListView>("TopListView");
_assetListView.makeItem = MakeAssetListViewItem;
_assetListView.bindItem = BindAssetListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_assetListView.selectionChanged += AssetListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_assetListView.onSelectionChange += AssetListView_onSelectionChange;
#else
_assetListView.onSelectionChanged += AssetListView_onSelectionChange;

View File

@@ -35,7 +35,9 @@ namespace YooAsset.Editor
_bundleListView = _root.Q<ListView>("TopListView");
_bundleListView.makeItem = MakeBundleListViewItem;
_bundleListView.bindItem = BindBundleListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_bundleListView.selectionChanged += BundleListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_bundleListView.onSelectionChange += BundleListView_onSelectionChange;
#else
_bundleListView.onSelectionChanged += BundleListView_onSelectionChange;

View File

@@ -58,7 +58,9 @@ namespace YooAsset.Editor
_assetListView = _root.Q<ListView>("TopListView");
_assetListView.makeItem = MakeAssetListViewItem;
_assetListView.bindItem = BindAssetListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_assetListView.selectionChanged += AssetListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_assetListView.onSelectionChange += AssetListView_onSelectionChange;
#else
_assetListView.onSelectionChanged += AssetListView_onSelectionChange;

View File

@@ -66,7 +66,9 @@ namespace YooAsset.Editor
_bundleListView = _root.Q<ListView>("TopListView");
_bundleListView.makeItem = MakeBundleListViewItem;
_bundleListView.bindItem = BindBundleListViewItem;
#if UNITY_2020_1_OR_NEWER
#if UNITY_2022_3_OR_NEWER
_bundleListView.selectionChanged += BundleListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
_bundleListView.onSelectionChange += BundleListView_onSelectionChange;
#else
_bundleListView.onSelectionChanged += BundleListView_onSelectionChange;

View File

@@ -3,4 +3,5 @@
[assembly: InternalsVisibleTo("YooAsset.Editor")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]

View File

@@ -0,0 +1,97 @@

namespace YooAsset
{
/// <summary>
/// 下载器结束
/// </summary>
public struct DownloaderFinishData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 是否成功
/// </summary>
public bool Succeed;
}
/// <summary>
/// 下载器相关的更新数据
/// </summary>
public struct DownloadUpdateData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载进度 (0-1f)
/// </summary>
public float Progress;
/// <summary>
/// 下载文件总数
/// </summary>
public int TotalDownloadCount;
/// <summary>
/// 当前完成的下载文件数量
/// </summary>
public int CurrentDownloadCount;
/// <summary>
/// 下载数据总大小(单位:字节)
/// </summary>
public long TotalDownloadBytes;
/// <summary>
/// 当前完成的下载数据大小(单位:字节)
/// </summary>
public long CurrentDownloadBytes;
}
/// <summary>
/// 下载器相关的错误数据
/// </summary>
public struct DownloadErrorData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载失败的文件名称
/// </summary>
public string FileName;
/// <summary>
/// 错误信息
/// </summary>
public string ErrorInfo;
}
/// <summary>
/// 下载器相关的文件数据
/// </summary>
public struct DownloadFileData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载的文件名称
/// </summary>
public string FileName;
/// <summary>
/// 下载的文件大小
/// </summary>
public long FileSize;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1c8ce2c52a3e9964fa50a9c031e4e593
guid: 6602c4be2ef295546b7bbb328de8fb0c
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -25,26 +25,35 @@ namespace YooAsset
/// </summary>
public static string ConvertToWWWPath(string path)
{
string url;
// 获取对应平台的URL地址
#if UNITY_EDITOR
return StringUtility.Format("file:///{0}", path);
url = StringUtility.Format("file:///{0}", path);
#elif UNITY_WEBGL
return path;
url = path;
#elif UNITY_IPHONE
return StringUtility.Format("file://{0}", path);
url = StringUtility.Format("file://{0}", path);
#elif UNITY_ANDROID
if (path.StartsWith("jar:file://"))
return path;
url = path;
else
return StringUtility.Format("jar:file://{0}", path);
#elif UNITY_STANDALONE_OSX
return new System.Uri(path).ToString();
#elif UNITY_STANDALONE
return StringUtility.Format("file:///{0}", path);
url = StringUtility.Format("jar:file://{0}", path);
#elif UNITY_OPENHARMONY
return StringUtility.Format("file://{0}", path);
if (path.StartsWith("jar:file://"))
url = path;
else
url = StringUtility.Format("jar:file://{0}", path);
#elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE
url = StringUtility.Format("file:///{0}", path);
#else
throw new System.NotImplementedException();
throw new System.NotImplementedException();
#endif
// For some special cases when users have special characters in their devices, url paths can not be identified correctly.
return url.Replace("+", "%2B").Replace("#", "%23").Replace("?", "%3F");
}
/// <summary>
@@ -52,7 +61,7 @@ namespace YooAsset
/// </summary>
public static bool IsRequestLocalFile(string url)
{
//TODO : UNITY_STANDALONE_OSX平台目前无法确定
//TODO UNITY_STANDALONE_OSX平台目前无法确定
if (url.StartsWith("file:"))
return true;
if (url.StartsWith("jar:file:"))

View File

@@ -71,7 +71,7 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
// 场景加载无法强制异步转同步
//注意:场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn !");
}
else
@@ -104,6 +104,11 @@ namespace YooAsset
}
}
}
internal override void InternalWaitForAsyncComplete()
{
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalOnUpdate();
}
public override void UnSuspendLoad()
{
_suspendLoad = false;

View File

@@ -76,7 +76,7 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
// 场景加载无法强制异步转同步
// 注意:场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn !");
}
else
@@ -110,6 +110,11 @@ namespace YooAsset
}
#endif
}
internal override void InternalWaitForAsyncComplete()
{
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalOnUpdate();
}
public override void UnSuspendLoad()
{
_suspendLoad = false;

View File

@@ -1,67 +0,0 @@
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,38 +0,0 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Threading;
namespace YooAsset
{
/// <summary>
/// 同步其它线程里的回调到主线程里
/// 注意Unity3D中需要设置Scripting Runtime Version为.NET4.6
/// </summary>
internal sealed class ThreadSyncContext : SynchronizationContext
{
private readonly ConcurrentQueue<Action> _safeQueue = new ConcurrentQueue<Action>();
/// <summary>
/// 更新同步队列
/// </summary>
public void Update()
{
while (true)
{
if (_safeQueue.TryDequeue(out Action action) == false)
return;
action.Invoke();
}
}
/// <summary>
/// 向同步队列里投递一个回调方法
/// </summary>
public override void Post(SendOrPostCallback callback, object state)
{
Action action = new Action(() => { callback(state); });
_safeQueue.Enqueue(action);
}
}
}

View File

@@ -96,9 +96,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
return _unpackFileSystem.ClearCacheBundleFilesAsync(manifest, clearMode, clearParam);
return _unpackFileSystem.ClearCacheFilesAsync(manifest, clearMode, clearParam);
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{
@@ -156,14 +156,14 @@ namespace YooAsset
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
rootDirectory = GetDefaultBuildinRoot();
_packageRoot = PathUtility.Combine(rootDirectory, packageName);
if (string.IsNullOrEmpty(packageRoot))
_packageRoot = GetDefaultBuildinPackageRoot(packageName);
else
_packageRoot = packageRoot;
// 创建解压文件系统
var remoteServices = new DefaultUnpackRemoteServices(_packageRoot);
@@ -282,9 +282,10 @@ namespace YooAsset
}
#region
protected string GetDefaultBuildinRoot()
protected string GetDefaultBuildinPackageRoot(string packageName)
{
return YooAssetSettingsData.GetYooMobileBuildinRoot();
string rootDirectory = YooAssetSettingsData.GetYooMobileBuildinRoot();
return PathUtility.Combine(rootDirectory, packageName);
}
public string GetBuildinFileLoadPath(PackageBundle bundle)
{

View File

@@ -26,7 +26,8 @@ namespace YooAsset
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists == false)
{
throw new System.Exception($"Can not found StreamingAssets root directory : {rootPath}");
UnityEngine.Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}");
return;
}
// 搜索所有Package目录
@@ -88,9 +89,20 @@ namespace YooAsset
FileInfo[] fileInfos = rootDirectory.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Extension == ".meta" || fileInfo.Extension == ".version" ||
fileInfo.Extension == ".hash" || fileInfo.Extension == ".bytes" ||
fileInfo.Extension == ".json")
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")
continue;
string fileName = fileInfo.Name;

View File

@@ -73,8 +73,7 @@ namespace YooAsset
#if UNITY_EDITOR
// 兼容性初始化
// 说明:内置文件系统在编辑器下运行时需要动态生成
string buildinRoot = YooAssetSettingsData.GetYooEditorBuildinRoot();
string packageRoot = PathUtility.Combine(buildinRoot, _fileSystem.PackageName);
string packageRoot = _fileSystem.FileRoot;
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot);
#endif

View File

@@ -67,7 +67,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;

View File

@@ -100,13 +100,13 @@ namespace YooAsset
DefaultDownloadFileOperation newDownloader;
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
{
newDownloader = new DownloadResumeFileOperation(_fileSystem, _fileSystem, bundle, param, _fileSystem.ResumeDownloadResponseCodes);
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, param);
newDownloader.Reference();
_downloaders.Add(bundle.BundleGUID, newDownloader);
}
else
{
newDownloader = new DownloadNormalFileOperation(_fileSystem, _fileSystem, bundle, param);
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, param);
newDownloader.Reference();
_downloaders.Add(bundle.BundleGUID, newDownloader);
}

View File

@@ -2,7 +2,6 @@
using System.IO;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace YooAsset
{
@@ -10,18 +9,18 @@ namespace YooAsset
/// 缓存文件系统
/// 说明正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作
/// </summary>
internal class DefaultCacheFileSystem : IFileSystem, ICacheSystem
internal class DefaultCacheFileSystem : IFileSystem
{
protected readonly Dictionary<string, CacheWrapper> _wrappers = new Dictionary<string, CacheWrapper>(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, RecordFileElement> _wrappers = new Dictionary<string, RecordFileElement>(10000);
protected readonly Dictionary<string, string> _bundleDataFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _bundleInfoFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _tempFilePaths = new Dictionary<string, string>(10000);
protected DefaultCacheDownloadCenter _downloadCenter;
protected string _packageRoot;
protected string _cacheFileRoot;
protected string _tempFileRoot;
protected string _manifestFileRoot;
protected string _tempFilesRoot;
protected string _cacheBundleFilesRoot;
protected string _cacheManifestFilesRoot;
/// <summary>
/// 包裹名称
@@ -114,30 +113,42 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
if (clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{
var operation = new ClearAllCacheFilesOperation(this);
var operation = new ClearAllCacheBundleFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{
var operation = new ClearUnusedCacheFilesOperation(this, manifest);
var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if (clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
var operation = new ClearCacheFilesByTagsOperaiton(this, manifest, clearParam);
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if (clearMode == EFileClearMode.ClearAllManifestFiles.ToString())
{
var operation = new ClearAllCacheManifestFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
{
var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else
{
string error = $"Invalid clear mode : {clearMode}";
var operation = new FSClearCacheBundleFilesCompleteOperation(error);
var operation = new FSClearCacheFilesCompleteOperation(error);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@@ -208,17 +219,18 @@ namespace YooAsset
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
rootDirectory = GetDefaultCacheRoot();
if (string.IsNullOrEmpty(packageRoot))
_packageRoot = GetDefaultCachePackageRoot(packageName);
else
_packageRoot = packageRoot;
_packageRoot = PathUtility.Combine(rootDirectory, packageName);
_cacheFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName);
_tempFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_manifestFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_downloadCenter = new DefaultCacheDownloadCenter(this);
}
public virtual void OnUpdate()
@@ -256,7 +268,7 @@ namespace YooAsset
public virtual string GetBundleFilePath(PackageBundle bundle)
{
return GetCacheFileLoadPath(bundle);
return GetCacheBundleFileLoadPath(bundle);
}
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
{
@@ -271,7 +283,7 @@ namespace YooAsset
return null;
}
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo()
{
BundleName = bundle.BundleName,
@@ -282,7 +294,7 @@ namespace YooAsset
}
else
{
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
return FileUtility.ReadAllBytes(filePath);
}
}
@@ -299,7 +311,7 @@ namespace YooAsset
return null;
}
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo()
{
BundleName = bundle.BundleName,
@@ -310,85 +322,82 @@ namespace YooAsset
}
else
{
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
return FileUtility.ReadAllText(filePath);
}
}
#region
public string GetCacheFileRoot()
{
return _cacheFileRoot;
}
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;
}
#region
public List<string> GetAllCachedBundleGUIDs()
{
return _wrappers.Keys.ToList();
}
public bool IsRecordFile(string bundleGUID)
public string GetTempFilePath(PackageBundle bundle)
{
if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_tempFilesRoot, bundle.BundleGUID);
_tempFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleDataFilePath(PackageBundle bundle)
{
if (_bundleDataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheBundleFilesRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.BundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_bundleDataFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleInfoFilePath(PackageBundle bundle)
{
if (_bundleInfoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheBundleFilesRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.BundleInfoFileName);
_bundleInfoFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public bool IsRecordBundleFile(string bundleGUID)
{
return _wrappers.ContainsKey(bundleGUID);
}
public bool RecordFile(string bundleGUID, CacheWrapper wrapper)
public bool RecordBundleFile(string bundleGUID, RecordFileElement element)
{
if (_wrappers.ContainsKey(bundleGUID))
{
YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}");
YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has record file element : {bundleGUID}");
return false;
}
_wrappers.Add(bundleGUID, wrapper);
_wrappers.Add(bundleGUID, element);
return true;
}
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
{
if (_wrappers.TryGetValue(bundle.BundleGUID, out CacheWrapper wrapper) == false)
if (_wrappers.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
return EFileVerifyResult.CacheNotFound;
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
return result;
}
public bool WriteCacheFile(PackageBundle bundle, string copyPath)
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
{
if (_wrappers.ContainsKey(bundle.BundleGUID))
{
throw new Exception("Should never get here !");
}
string infoFilePath = GetInfoFilePath(bundle);
string dataFilePath = GetDataFilePath(bundle);
string infoFilePath = GetBundleInfoFilePath(bundle);
string dataFilePath = GetBundleDataFilePath(bundle);
try
{
@@ -404,7 +413,7 @@ namespace YooAsset
fileInfo.CopyTo(dataFilePath);
// 写入文件信息
WriteInfoFile(infoFilePath, bundle.FileCRC, bundle.FileSize);
WriteBundleInfoFile(infoFilePath, bundle.FileCRC, bundle.FileSize);
}
catch (Exception e)
{
@@ -412,12 +421,12 @@ namespace YooAsset
return false;
}
var wrapper = new CacheWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
return RecordFile(bundle.BundleGUID, wrapper);
var recordFileElement = new RecordFileElement(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
return RecordBundleFile(bundle.BundleGUID, recordFileElement);
}
public bool DeleteCacheFile(string bundleGUID)
public bool DeleteCacheBundleFile(string bundleGUID)
{
if (_wrappers.TryGetValue(bundleGUID, out CacheWrapper wrapper))
if (_wrappers.TryGetValue(bundleGUID, out RecordFileElement wrapper))
{
try
{
@@ -441,7 +450,7 @@ namespace YooAsset
}
private readonly BufferWriter _sharedBuffer = new BufferWriter(1024);
public void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize)
public void WriteBundleInfoFile(string filePath, string dataFileCRC, long dataFileSize)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
@@ -452,7 +461,7 @@ namespace YooAsset
fs.Flush();
}
}
public void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize)
public void ReadBundleInfoFile(string filePath, out string dataFileCRC, out long dataFileSize)
{
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData);
@@ -462,33 +471,45 @@ namespace YooAsset
#endregion
#region
public string GetDefaultCacheRoot()
public string GetDefaultCachePackageRoot(string packageName)
{
string rootDirectory;
#if UNITY_EDITOR
return YooAssetSettingsData.GetYooEditorCacheRoot();
rootDirectory = YooAssetSettingsData.GetYooEditorCacheRoot();
#elif UNITY_STANDALONE
return YooAssetSettingsData.GetYooStandaloneCacheRoot();
rootDirectory = YooAssetSettingsData.GetYooStandaloneCacheRoot();
#else
return YooAssetSettingsData.GetYooMobileCacheRoot();
rootDirectory = YooAssetSettingsData.GetYooMobileCacheRoot();
#endif
return PathUtility.Combine(rootDirectory, packageName);
}
public string GetCacheFileLoadPath(PackageBundle bundle)
public string GetCacheBundleFileLoadPath(PackageBundle bundle)
{
return GetDataFilePath(bundle);
return GetBundleDataFilePath(bundle);
}
public string GetCachePackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
return PathUtility.Combine(_cacheManifestFilesRoot, fileName);
}
public string GetCachePackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(_manifestFileRoot, fileName);
return PathUtility.Combine(_cacheManifestFilesRoot, fileName);
}
public string GetSandboxAppFootPrintFilePath()
{
return PathUtility.Combine(_manifestFileRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
return PathUtility.Combine(_cacheManifestFilesRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
}
public string GetCacheBundleFilesRoot()
{
return _cacheBundleFilesRoot;
}
public string GetCacheManifestFilesRoot()
{
return _cacheManifestFilesRoot;
}
/// <summary>
@@ -496,9 +517,9 @@ namespace YooAsset
/// </summary>
public void DeleteAllManifestFiles()
{
if (Directory.Exists(_manifestFileRoot))
if (Directory.Exists(_cacheManifestFilesRoot))
{
Directory.Delete(_manifestFileRoot, true);
Directory.Delete(_cacheManifestFilesRoot, true);
}
}
@@ -507,7 +528,7 @@ namespace YooAsset
/// </summary>
public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo()
{
BundleName = bundle.BundleName,
@@ -522,7 +543,7 @@ namespace YooAsset
/// </summary>
public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo()
{
BundleName = bundle.BundleName,

View File

@@ -4,27 +4,27 @@ namespace YooAsset
internal class DefaultCacheFileSystemDefine
{
/// <summary>
/// 保存的数据文件名称
/// 数据文件名称
/// </summary>
public const string SaveBundleDataFileName = "__data";
public const string BundleDataFileName = "__data";
/// <summary>
/// 保存的信息文件名称
/// 信息文件名称
/// </summary>
public const string SaveBundleInfoFileName = "__info";
public const string BundleInfoFileName = "__info";
/// <summary>
/// 保存的资源文件的文件夹名称
/// 资源文件的文件夹名称
/// </summary>
public const string SaveFilesFolderName = "CacheFiles";
public const string BundleFilesFolderName = "BundleFiles";
/// <summary>
/// 下载的临时文件的文件夹名称
/// 临时文件的文件夹名称
/// </summary>
public const string TempFilesFolderName = "CacheTempFiles";
public const string TempFilesFolderName = "TempFiles";
/// <summary>
/// 保存的清单文件的文件夹名称
/// 清单文件的文件夹名称
/// </summary>
public const string ManifestFilesFolderName = "ManifestFiles";

View File

@@ -1,14 +1,14 @@

namespace YooAsset
{
internal class CacheWrapper
internal class RecordFileElement
{
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)
public RecordFileElement(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;

View File

@@ -10,7 +10,7 @@ namespace YooAsset
/// <summary>
/// 注意:原子操作对象
/// </summary>
public int Result = 0;
public volatile int Result = 0;
public TempFileElement(string filePath, string fileCRC, long fileSize)
{

View File

@@ -2,7 +2,7 @@
namespace YooAsset
{
internal class CacheFileElement
internal class VerifyFileElement
{
public string PackageName { private set; get; }
public string BundleGUID { private set; get; }
@@ -10,11 +10,15 @@ namespace YooAsset
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)
/// <summary>
/// 注意:原子操作对象
/// </summary>
public volatile int Result = 0;
public VerifyFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath)
{
PackageName = packageName;
BundleGUID = bundleGUID;

View File

@@ -57,7 +57,7 @@ namespace YooAsset
{
if (_searchCacheFilesOp == null)
{
_searchCacheFilesOp = new SearchCacheFilesOperation(_fileSystem, _fileSystem.PackageName, _fileSystem.AppendFileExtension);
_searchCacheFilesOp = new SearchCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _searchCacheFilesOp);
}
@@ -72,7 +72,7 @@ namespace YooAsset
{
if (_verifyCacheFilesOp == null)
{
_verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSystem, _fileSystem.FileVerifyLevel, _searchCacheFilesOp.Result);
_verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSystem, _searchCacheFilesOp.Result);
OperationSystem.StartOperation(_fileSystem.PackageName, _verifyCacheFilesOp);
}

View File

@@ -104,7 +104,7 @@ namespace YooAsset
}
else
{
string filePath = _fileSystem.GetCacheFileLoadPath(_bundle);
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
_assetBundle = AssetBundle.LoadFromFile(filePath);
}
}
@@ -118,7 +118,7 @@ namespace YooAsset
}
else
{
string filePath = _fileSystem.GetCacheFileLoadPath(_bundle);
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
_createRequest = AssetBundle.LoadFromFileAsync(filePath);
}
}
@@ -168,7 +168,7 @@ namespace YooAsset
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
// 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
string filePath = _fileSystem.GetCacheFileLoadPath(_bundle);
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
byte[] fileData = FileUtility.ReadAllBytes(filePath);
if (fileData != null && fileData.Length > 0)
{
@@ -198,7 +198,7 @@ namespace YooAsset
else
{
_steps = ESteps.Done;
_fileSystem.DeleteCacheFile(_bundle.BundleGUID);
_fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID);
Status = EOperationStatus.Failed;
Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}";
YooLogger.Error(Error);
@@ -304,7 +304,7 @@ namespace YooAsset
if (_steps == ESteps.LoadCacheRawBundle)
{
string filePath = _fileSystem.GetCacheFileLoadPath(_bundle);
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
if (File.Exists(filePath))
{
_steps = ESteps.Done;

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace YooAsset
{
internal sealed class ClearAllCacheFilesOperation : FSClearCacheBundleFilesOperation
internal sealed class ClearAllCacheBundleFilesOperation : FSClearCacheFilesOperation
{
private enum ESteps
{
@@ -13,15 +13,15 @@ namespace YooAsset
Done,
}
private readonly ICacheSystem _cacheSystem;
private readonly DefaultCacheFileSystem _fileSystem;
private List<string> _allBundleGUIDs;
private int _fileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearAllCacheFilesOperation(ICacheSystem cacheSystem)
internal ClearAllCacheBundleFilesOperation(DefaultCacheFileSystem fileSystem)
{
_cacheSystem = cacheSystem;
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
@@ -34,7 +34,7 @@ namespace YooAsset
if (_steps == ESteps.GetAllCacheFiles)
{
_allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
_allBundleGUIDs = _fileSystem.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];
_cacheSystem.DeleteCacheFile(bundleGUID);
_fileSystem.DeleteCacheBundleFile(bundleGUID);
_allBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;

View File

@@ -0,0 +1,63 @@
using System;
using System.IO;
namespace YooAsset
{
internal sealed class ClearAllCacheManifestFilesOperation : FSClearCacheFilesOperation
{
private enum ESteps
{
None,
ClearAllCacheFiles,
Done,
}
private readonly DefaultCacheFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
internal ClearAllCacheManifestFilesOperation(DefaultCacheFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.ClearAllCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.ClearAllCacheFiles)
{
try
{
// 注意:如果正在下载资源清单,会有几率触发异常!
string directoryRoot = _fileSystem.GetCacheManifestFilesRoot();
DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot);
if (directoryInfo.Exists)
{
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
string fileName = fileInfo.Name;
if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName)
continue;
fileInfo.Delete();
}
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
catch (Exception ex)
{
_steps = ESteps.Done;
Error = ex.Message;
Status = EOperationStatus.Failed;
}
}
}
}
}

View File

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

View File

@@ -2,7 +2,7 @@
namespace YooAsset
{
internal class ClearCacheFilesByTagsOperaiton : FSClearCacheBundleFilesOperation
internal class ClearCacheBundleFilesByTagsOperaiton : FSClearCacheFilesOperation
{
private enum ESteps
{
@@ -13,7 +13,7 @@ namespace YooAsset
Done,
}
private readonly ICacheSystem _cacheSystem;
private readonly DefaultCacheFileSystem _fileSystem;
private readonly PackageManifest _manifest;
private readonly object _clearParam;
private string[] _tags;
@@ -21,9 +21,9 @@ namespace YooAsset
private int _clearFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearCacheFilesByTagsOperaiton(ICacheSystem cacheSystem, PackageManifest manifest, object clearParam)
internal ClearCacheBundleFilesByTagsOperaiton(DefaultCacheFileSystem fileSystem, PackageManifest manifest, object clearParam)
{
_cacheSystem = cacheSystem;
_fileSystem = fileSystem;
_manifest = manifest;
_clearParam = clearParam;
}
@@ -82,7 +82,7 @@ namespace YooAsset
for (int i = _clearBundleGUIDs.Count - 1; i >= 0; i--)
{
string bundleGUID = _clearBundleGUIDs[i];
_cacheSystem.DeleteCacheFile(bundleGUID);
_fileSystem.DeleteCacheBundleFile(bundleGUID);
_clearBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
@@ -102,7 +102,7 @@ namespace YooAsset
}
private List<string> GetTagsBundleGUIDs()
{
var allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
var allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
List<string> result = new List<string>(allBundleGUIDs.Count);
foreach (var bundleGUID in allBundleGUIDs)
{

View File

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

View File

@@ -0,0 +1,70 @@
using System;
using System.IO;
namespace YooAsset
{
internal sealed class ClearUnusedCacheManifestFilesOperation : FSClearCacheFilesOperation
{
private enum ESteps
{
None,
ClearUnusedCacheFiles,
Done,
}
private readonly DefaultCacheFileSystem _fileSystem;
private readonly PackageManifest _manifest;
private ESteps _steps = ESteps.None;
internal ClearUnusedCacheManifestFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest)
{
_fileSystem = fileSystem;
_manifest = manifest;
}
internal override void InternalOnStart()
{
_steps = ESteps.ClearUnusedCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.ClearUnusedCacheFiles)
{
try
{
string activeManifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(_manifest.PackageName, _manifest.PackageVersion);
string activeHashFileName = YooAssetSettingsData.GetPackageHashFileName(_manifest.PackageName, _manifest.PackageVersion);
// 注意:如果正在下载资源清单,会有几率触发异常!
string directoryRoot = _fileSystem.GetCacheManifestFilesRoot();
DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot);
if (directoryInfo.Exists)
{
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
string fileName = fileInfo.Name;
if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName)
continue;
if (fileName == activeManifestFileName || fileName == activeHashFileName)
continue;
fileInfo.Delete();
}
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
catch (Exception ex)
{
_steps = ESteps.Done;
Error = ex.Message;
Status = EOperationStatus.Failed;
}
}
}
}
}

View File

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

View File

@@ -6,22 +6,20 @@ namespace YooAsset
{
internal sealed class DownloadNormalFileOperation : DefaultDownloadFileOperation
{
private readonly IFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly DefaultCacheFileSystem _fileSystem;
private VerifyTempFileOperation _verifyOperation;
private bool _isReuqestLocalFile;
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DownloadNormalFileOperation(IFileSystem fileSystem, ICacheSystem cacheSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
}
internal override void InternalOnStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_tempFilePath = _cacheSystem.GetTempFilePath(Bundle);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalOnUpdate()
@@ -106,7 +104,7 @@ namespace YooAsset
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_cacheSystem.WriteCacheFile(Bundle, _tempFilePath))
if (_fileSystem.WriteCacheBundleFile(Bundle, _tempFilePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
@@ -133,7 +131,7 @@ namespace YooAsset
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
//TODO : 拷贝本地文件失败后不再尝试!
//TODO 拷贝本地文件失败后不再尝试!
if (_isReuqestLocalFile)
{
Status = EOperationStatus.Failed;
@@ -166,7 +164,7 @@ namespace YooAsset
}
internal override void InternalWaitForAsyncComplete()
{
//TODO : 防止下载器挂起陷入无限死循环!
//TODO 防止下载器挂起陷入无限死循环!
if (_steps == ESteps.None)
{
InternalOnStart();
@@ -174,7 +172,7 @@ namespace YooAsset
while (true)
{
//TODO : 如果是导入或解压本地文件,执行等待完毕
//TODO 如果是导入或解压本地文件,执行等待完毕
if (_isReuqestLocalFile)
{
InternalOnUpdate();

View File

@@ -7,9 +7,7 @@ namespace YooAsset
{
internal sealed class DownloadResumeFileOperation : DefaultDownloadFileOperation
{
private readonly IFileSystem _fileSystem;
private readonly ICacheSystem _cacheSystem;
private readonly List<long> _responseCodes;
private readonly DefaultCacheFileSystem _fileSystem;
private DownloadHandlerFileRange _downloadHandle;
private VerifyTempFileOperation _verifyOperation;
private bool _isReuqestLocalFile;
@@ -18,16 +16,14 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DownloadResumeFileOperation(IFileSystem fileSystem, ICacheSystem cacheSystem, PackageBundle bundle, DownloadParam param, List<long> responseCodes) : base(bundle, param)
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
_cacheSystem = cacheSystem;
_responseCodes = responseCodes;
}
internal override void InternalOnStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_tempFilePath = _cacheSystem.GetTempFilePath(Bundle);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalOnUpdate()
@@ -129,7 +125,7 @@ namespace YooAsset
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_cacheSystem.WriteCacheFile(Bundle, _tempFilePath))
if (_fileSystem.WriteCacheBundleFile(Bundle, _tempFilePath))
{
Status = EOperationStatus.Succeed;
_steps = ESteps.Done;
@@ -155,7 +151,7 @@ namespace YooAsset
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
//TODO : 拷贝本地文件失败后不再尝试!
//TODO 拷贝本地文件失败后不再尝试!
if (_isReuqestLocalFile)
{
Status = EOperationStatus.Failed;
@@ -188,7 +184,7 @@ namespace YooAsset
}
internal override void InternalWaitForAsyncComplete()
{
//TODO : 防止下载器挂起陷入无限死循环!
//TODO 防止下载器挂起陷入无限死循环!
if (_steps == ESteps.None)
{
InternalOnStart();
@@ -196,7 +192,7 @@ namespace YooAsset
while (true)
{
//TODO : 如果是导入或解压本地文件,执行等待完毕
//TODO 如果是导入或解压本地文件,执行等待完毕
if (_isReuqestLocalFile)
{
InternalOnUpdate();
@@ -247,11 +243,11 @@ namespace YooAsset
}
private void ClearTempFileWhenError()
{
if (_responseCodes == null)
if (_fileSystem.ResumeDownloadResponseCodes == null)
return;
//说明:如果遇到以下错误返回码,验证失败直接删除文件
if (_responseCodes.Contains(HttpCode))
if (_fileSystem.ResumeDownloadResponseCodes.Contains(HttpCode))
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);

View File

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

View File

@@ -15,9 +15,7 @@ namespace YooAsset
Done,
}
private readonly ICacheSystem _cacheSystem;
private readonly string _packageName;
private readonly bool _appendFileExtension;
private readonly DefaultCacheFileSystem _fileSystem;
private IEnumerator<DirectoryInfo> _filesEnumerator = null;
private float _verifyStartTime;
private ESteps _steps = ESteps.None;
@@ -25,14 +23,12 @@ namespace YooAsset
/// <summary>
/// 需要验证的元素
/// </summary>
public readonly List<CacheFileElement> Result = new List<CacheFileElement>(5000);
public readonly List<VerifyFileElement> Result = new List<VerifyFileElement>(5000);
internal SearchCacheFilesOperation(ICacheSystem cacheSystem, string packageName, bool appendFileExtension)
internal SearchCacheFilesOperation(DefaultCacheFileSystem fileSystem)
{
_cacheSystem = cacheSystem;
_packageName = packageName;
_appendFileExtension = appendFileExtension;
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
@@ -46,7 +42,7 @@ namespace YooAsset
if (_steps == ESteps.Prepare)
{
DirectoryInfo rootDirectory = new DirectoryInfo(_cacheSystem.GetCacheFileRoot());
DirectoryInfo rootDirectory = new DirectoryInfo(_fileSystem.GetCacheBundleFilesRoot());
if (rootDirectory.Exists)
{
var directorieInfos = rootDirectory.EnumerateDirectories();
@@ -84,23 +80,23 @@ namespace YooAsset
foreach (var chidDirectory in childDirectories)
{
string bundleGUID = chidDirectory.Name;
if (_cacheSystem.IsRecordFile(bundleGUID))
if (_fileSystem.IsRecordBundleFile(bundleGUID))
continue;
// 创建验证元素类
string fileRootPath = chidDirectory.FullName;
string dataFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleInfoFileName}";
string dataFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.BundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.BundleInfoFileName}";
// 存储的数据文件追加文件格式
if (_appendFileExtension)
if (_fileSystem.AppendFileExtension)
{
string dataFileExtension = FindDataFileExtension(chidDirectory);
if (string.IsNullOrEmpty(dataFileExtension) == false)
dataFilePath += dataFileExtension;
}
var element = new CacheFileElement(_packageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);
var element = new VerifyFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);
Result.Add(element);
}
@@ -116,7 +112,7 @@ namespace YooAsset
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Name.StartsWith(DefaultCacheFileSystemDefine.SaveBundleDataFileName))
if (fileInfo.Name.StartsWith(DefaultCacheFileSystemDefine.BundleDataFileName))
{
dataFileExtension = fileInfo.Extension;
break;

View File

@@ -19,11 +19,10 @@ namespace YooAsset
Done,
}
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
private readonly ICacheSystem _cacheSystem;
private readonly EFileVerifyLevel _verifyLevel;
private List<CacheFileElement> _waitingList;
private List<CacheFileElement> _verifyingList;
private readonly DefaultCacheFileSystem _fileSystem;
private readonly EFileVerifyLevel _fileVerifyLevel;
private List<VerifyFileElement> _waitingList;
private List<VerifyFileElement> _verifyingList;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
@@ -32,11 +31,11 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal VerifyCacheFilesOperation(ICacheSystem cacheSystem, EFileVerifyLevel verifyLevel, List<CacheFileElement> elements)
internal VerifyCacheFilesOperation(DefaultCacheFileSystem fileSystem, List<VerifyFileElement> elements)
{
_cacheSystem = cacheSystem;
_verifyLevel = verifyLevel;
_fileSystem = fileSystem;
_waitingList = elements;
_fileVerifyLevel = fileSystem.FileVerifyLevel;
}
internal override void InternalOnStart()
{
@@ -60,13 +59,23 @@ namespace YooAsset
if (_verifyMaxNum < 1)
_verifyMaxNum = 1;
_verifyingList = new List<CacheFileElement>(_verifyMaxNum);
_verifyingList = new List<VerifyFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}
if (_steps == ESteps.UpdateVerify)
{
_syncContext.Update();
// 检测校验结果
for (int i = _verifyingList.Count - 1; i >= 0; i--)
{
var verifyElement = _verifyingList[i];
int result = verifyElement.Result;
if (result != 0)
{
_verifyingList.RemoveAt(i);
RecordVerifyFile(verifyElement);
}
}
Progress = GetProgress();
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
@@ -86,7 +95,8 @@ namespace YooAsset
break;
var element = _waitingList[i];
if (BeginVerifyFileWithThread(element))
bool succeed = ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
if (succeed)
{
_waitingList.RemoveAt(i);
_verifyingList.Add(element);
@@ -106,31 +116,23 @@ namespace YooAsset
return 1f;
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
}
private bool BeginVerifyFileWithThread(CacheFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
CacheFileElement element = (CacheFileElement)obj;
element.Result = VerifyingCacheFile(element, _verifyLevel);
_syncContext.Post(VerifyCallback, element);
VerifyFileElement element = (VerifyFileElement)obj;
int verifyResult = (int)VerifyingCacheFile(element, _fileVerifyLevel);
element.Result = verifyResult;
}
private void VerifyCallback(object obj)
private void RecordVerifyFile(VerifyFileElement element)
{
CacheFileElement element = (CacheFileElement)obj;
_verifyingList.Remove(element);
if (element.Result == EFileVerifyResult.Succeed)
if (element.Result == (int)EFileVerifyResult.Succeed)
{
_succeedCount++;
var fileWrapper = new CacheWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cacheSystem.RecordFile(element.BundleGUID, fileWrapper);
var recordFileElement = new RecordFileElement(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_fileSystem.RecordBundleFile(element.BundleGUID, recordFileElement);
}
else
{
_failedCount++;
YooLogger.Warning($"Failed to verify file {element.Result} and delete files : {element.FileRootPath}");
element.DeleteFiles();
}
@@ -139,7 +141,7 @@ namespace YooAsset
/// <summary>
/// 验证缓存文件(子线程内操作)
/// </summary>
private EFileVerifyResult VerifyingCacheFile(CacheFileElement element, EFileVerifyLevel verifyLevel)
private EFileVerifyResult VerifyingCacheFile(VerifyFileElement element, EFileVerifyLevel verifyLevel)
{
try
{
@@ -157,7 +159,7 @@ namespace YooAsset
return EFileVerifyResult.InfoFileNotExisted;
// 解析信息文件获取验证数据
_cacheSystem.ReadInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
_fileSystem.ReadBundleInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
}
}
catch (Exception)

View File

@@ -40,7 +40,8 @@ namespace YooAsset
if (_steps == ESteps.VerifyFile)
{
if (BeginVerifyFileWithThread(_element))
bool succeed = ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), _element);
if (succeed)
{
_steps = ESteps.Waiting;
}
@@ -70,17 +71,13 @@ namespace YooAsset
{
while (true)
{
//TODO : 等待子线程验证文件完毕,该操作会挂起主线程
//TODO 等待子线程验证文件完毕,该操作会挂起主线程
InternalOnUpdate();
if (IsDone)
break;
}
}
private bool BeginVerifyFileWithThread(TempFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
TempFileElement element = (TempFileElement)obj;

View File

@@ -69,9 +69,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
var operation = new FSClearCacheFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@@ -111,15 +111,14 @@ namespace YooAsset
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
if (string.IsNullOrEmpty(packageRoot))
throw new Exception($"{nameof(DefaultEditorFileSystem)} root directory is null or empty !");
// 注意:基础目录即为包裹目录
_packageRoot = rootDirectory;
_packageRoot = packageRoot;
}
public virtual void OnUpdate()
{

View File

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

View File

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

View File

@@ -71,9 +71,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
var operation = new FSClearCacheFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@@ -113,7 +113,7 @@ namespace YooAsset
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
}

View File

@@ -70,7 +70,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;

View File

@@ -80,9 +80,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{
var operation = new FSClearCacheBundleFilesCompleteOperation(null);
var operation = new FSClearCacheFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@@ -118,14 +118,14 @@ namespace YooAsset
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
rootDirectory = GetDefaultWebRoot();
_webPackageRoot = PathUtility.Combine(rootDirectory, packageName);
if (string.IsNullOrEmpty(packageRoot))
_webPackageRoot = GetDefaultWebPackageRoot(packageName);
else
_webPackageRoot = packageRoot;
}
public virtual void OnUpdate()
{
@@ -166,9 +166,10 @@ namespace YooAsset
}
#region
protected string GetDefaultWebRoot()
protected string GetDefaultWebPackageRoot(string packageName)
{
return YooAssetSettingsData.GetYooWebBuildinRoot();
string rootDirectory = YooAssetSettingsData.GetYooWebBuildinRoot();
return PathUtility.Combine(rootDirectory, packageName);
}
public string GetWebFileLoadPath(PackageBundle bundle)
{

View File

@@ -67,7 +67,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;

View File

@@ -9,17 +9,28 @@ namespace YooAsset
/// <summary>
/// 清理所有文件
/// </summary>
ClearAllBundleFiles = 1,
ClearAllBundleFiles,
/// <summary>
/// 清理未在使用的文件
/// </summary>
ClearUnusedBundleFiles = 2,
ClearUnusedBundleFiles,
/// <summary>
/// 清理指定标签的文件
/// 说明需要指定参数可选string, string[], List<string>
/// </summary>
ClearBundleFilesByTags = 3,
ClearBundleFilesByTags,
/// <summary>
/// 清理所有清单
/// </summary>
ClearAllManifestFiles,
/// <summary>
/// 清理未在使用的清单
/// </summary>
ClearUnusedManifestFiles,
}
}

View File

@@ -20,13 +20,13 @@ namespace YooAsset
/// <summary>
/// 文件系统的根目录
/// </summary>
public string RootDirectory { private set; get; }
public string PackageRoot { private set; get; }
public FileSystemParameters(string fileSystemClass, string rootDirectory)
public FileSystemParameters(string fileSystemClass, string packageRoot)
{
FileSystemClass = fileSystemClass;
RootDirectory = rootDirectory;
PackageRoot = packageRoot;
}
/// <summary>
@@ -62,19 +62,19 @@ namespace YooAsset
{
instance.SetParameter(param.Key, param.Value);
}
instance.OnCreate(packageName, RootDirectory);
instance.OnCreate(packageName, PackageRoot);
return instance;
}
#region
/// <summary>
/// 创建默认的编辑器文件系统参数
/// <param name="simulateBuildResult">模拟构建结果</param>
/// <param name="packageRoot">文件系统的根目录</param>
/// </summary>
public static FileSystemParameters CreateDefaultEditorFileSystemParameters(EditorSimulateBuildResult simulateBuildResult)
public static FileSystemParameters CreateDefaultEditorFileSystemParameters(string packageRoot)
{
string fileSystemClass = typeof(DefaultEditorFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, simulateBuildResult.PackageRootDirectory);
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
return fileSystemParams;
}
@@ -82,14 +82,12 @@ namespace YooAsset
/// 创建默认的内置文件系统参数
/// </summary>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="verifyLevel">缓存文件的校验等级</param>
/// <param name="rootDirectory">内置文件的根路径</param>
public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IDecryptionServices decryptionServices = null, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
/// <param name="packageRoot">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IDecryptionServices decryptionServices = null, string packageRoot = null)
{
string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, verifyLevel);
return fileSystemParams;
}
@@ -98,15 +96,13 @@ namespace YooAsset
/// </summary>
/// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="verifyLevel">缓存文件的校验等级</param>
/// <param name="rootDirectory">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
/// <param name="packageRoot">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, string packageRoot = null)
{
string fileSystemClass = typeof(DefaultCacheFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, verifyLevel);
return fileSystemParams;
}
@@ -129,7 +125,7 @@ namespace YooAsset
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, bool disableUnityWebCache = false)
{
string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName;
string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);

View File

@@ -25,7 +25,7 @@ namespace YooAsset
// 再验证文件CRC
if (verifyLevel == EFileVerifyLevel.High)
{
string crc = HashUtility.FileCRC32Safely(filePath);
string crc = HashUtility.FileCRC32(filePath);
if (crc == fileCRC)
return EFileVerifyResult.Succeed;
else

View File

@@ -37,7 +37,7 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
/// <summary>
/// 下载远端文件
@@ -48,7 +48,7 @@ namespace YooAsset
/// 加载Bundle文件
/// </summary>
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
/// <summary>
/// 设置自定义参数
@@ -58,7 +58,7 @@ namespace YooAsset
/// <summary>
/// 创建缓存系统
/// </summary>
void OnCreate(string packageName, string rootDirectory);
void OnCreate(string packageName, string packageRoot);
/// <summary>
/// 更新文件系统

View File

@@ -1,15 +1,19 @@

namespace YooAsset
{
internal abstract class FSClearCacheBundleFilesOperation : AsyncOperationBase
internal abstract class FSClearCacheFilesOperation : AsyncOperationBase
{
}
internal sealed class FSClearCacheBundleFilesCompleteOperation : FSClearCacheBundleFilesOperation
internal sealed class FSClearCacheFilesCompleteOperation : FSClearCacheFilesOperation
{
private readonly string _error;
internal FSClearCacheBundleFilesCompleteOperation(string error)
internal FSClearCacheFilesCompleteOperation()
{
_error = null;
}
internal FSClearCacheFilesCompleteOperation(string error)
{
_error = error;
}

View File

@@ -42,6 +42,17 @@ namespace YooAsset
/// </summary>
public float Progress { get; protected set; }
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName
{
get
{
return _packageName;
}
}
/// <summary>
/// 是否已经完成
/// </summary>
@@ -98,10 +109,6 @@ namespace YooAsset
throw new System.NotImplementedException(this.GetType().Name);
}
internal string GetPackageName()
{
return _packageName;
}
internal void SetPackageName(string packageName)
{
_packageName = packageName;

View File

@@ -112,7 +112,7 @@ namespace YooAsset
// 终止临时队列里的任务
foreach (var operation in _newList)
{
if (operation.GetPackageName() == packageName)
if (operation.PackageName == packageName)
{
operation.SetAbort();
}
@@ -121,7 +121,7 @@ namespace YooAsset
// 终止正在进行的任务
foreach (var operation in _operations)
{
if (operation.GetPackageName() == packageName)
if (operation.PackageName == packageName)
{
operation.SetAbort();
}

View File

@@ -113,7 +113,8 @@ namespace YooAsset
}
/// <summary>
/// 异步卸载场景
/// 异步卸载场景对象
/// 注意场景卸载成功后会自动释放该handle的引用计数
/// </summary>
public UnloadSceneOperation UnloadAsync()
{

View File

@@ -74,7 +74,7 @@ namespace YooAsset
}
#if UNITY_2023_3_OR_NEWER
//TODO : 官方BUG
//TODO 官方BUG
// BUG环境Windows平台Unity2022.3.41f1版本,编辑器模式。
// BUG描述异步实例化Prefab预制体有概率丢失Mono脚本里序列化的数组里某个成员
//_steps = ESteps.CloneAsync;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 58462a7dcef164e43878a037395d4417
guid: dfb81dc2664ed4d4db4bd2b95caadae4
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -31,7 +31,7 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(string clearMode, object clearParam);
ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam);
// 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout);

View File

@@ -1,10 +1,10 @@

namespace YooAsset
{
public abstract class ClearCacheBundleFilesOperation : AsyncOperationBase
public abstract class ClearCacheFilesOperation : AsyncOperationBase
{
}
internal sealed class ClearCacheBundleFilesImplOperation : ClearCacheBundleFilesOperation
internal sealed class ClearCacheFilesImplOperation : ClearCacheFilesOperation
{
private enum ESteps
{
@@ -21,12 +21,12 @@ namespace YooAsset
private readonly IFileSystem _fileSystemC;
private readonly string _clearMode;
private readonly object _clearParam;
private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpA;
private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpB;
private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpC;
private FSClearCacheFilesOperation _clearCacheFilesOpA;
private FSClearCacheFilesOperation _clearCacheFilesOpB;
private FSClearCacheFilesOperation _clearCacheFilesOpC;
private ESteps _steps = ESteps.None;
internal ClearCacheBundleFilesImplOperation(IPlayMode impl, IFileSystem fileSystemA, IFileSystem fileSystemB, IFileSystem fileSystemC, string clearMode, object clearParam)
internal ClearCacheFilesImplOperation(IPlayMode impl, IFileSystem fileSystemA, IFileSystem fileSystemB, IFileSystem fileSystemC, string clearMode, object clearParam)
{
_impl = impl;
_fileSystemA = fileSystemA;
@@ -52,14 +52,14 @@ namespace YooAsset
return;
}
if (_clearCacheBundleFilesOpA == null)
_clearCacheBundleFilesOpA = _fileSystemA.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
if (_clearCacheFilesOpA == null)
_clearCacheFilesOpA = _fileSystemA.ClearCacheFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearCacheBundleFilesOpA.Progress;
if (_clearCacheBundleFilesOpA.IsDone == false)
Progress = _clearCacheFilesOpA.Progress;
if (_clearCacheFilesOpA.IsDone == false)
return;
if (_clearCacheBundleFilesOpA.Status == EOperationStatus.Succeed)
if (_clearCacheFilesOpA.Status == EOperationStatus.Succeed)
{
_steps = ESteps.ClearFileSystemB;
}
@@ -67,7 +67,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearCacheBundleFilesOpA.Error;
Error = _clearCacheFilesOpA.Error;
}
}
@@ -79,14 +79,14 @@ namespace YooAsset
return;
}
if (_clearCacheBundleFilesOpB == null)
_clearCacheBundleFilesOpB = _fileSystemB.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
if (_clearCacheFilesOpB == null)
_clearCacheFilesOpB = _fileSystemB.ClearCacheFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearCacheBundleFilesOpB.Progress;
if (_clearCacheBundleFilesOpB.IsDone == false)
Progress = _clearCacheFilesOpB.Progress;
if (_clearCacheFilesOpB.IsDone == false)
return;
if (_clearCacheBundleFilesOpB.Status == EOperationStatus.Succeed)
if (_clearCacheFilesOpB.Status == EOperationStatus.Succeed)
{
_steps = ESteps.ClearFileSystemC;
}
@@ -94,7 +94,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearCacheBundleFilesOpB.Error;
Error = _clearCacheFilesOpB.Error;
}
}
@@ -107,14 +107,14 @@ namespace YooAsset
return;
}
if (_clearCacheBundleFilesOpC == null)
_clearCacheBundleFilesOpC = _fileSystemC.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
if (_clearCacheFilesOpC == null)
_clearCacheFilesOpC = _fileSystemC.ClearCacheFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearCacheBundleFilesOpC.Progress;
if (_clearCacheBundleFilesOpC.IsDone == false)
Progress = _clearCacheFilesOpC.Progress;
if (_clearCacheFilesOpC.IsDone == false)
return;
if (_clearCacheBundleFilesOpC.Status == EOperationStatus.Succeed)
if (_clearCacheFilesOpC.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
@@ -123,7 +123,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearCacheBundleFilesOpC.Error;
Error = _clearCacheFilesOpC.Error;
}
}
}

View File

@@ -15,10 +15,27 @@ namespace YooAsset
private const int MAX_LOADER_COUNT = 64;
public delegate void OnDownloadOver(bool isSucceed);
public delegate void OnDownloadProgress(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes);
public delegate void OnDownloadError(string fileName, string error);
public delegate void OnStartDownloadFile(string fileName, long sizeBytes);
#region
/// <summary>
/// 下载器结束
/// </summary>
public delegate void DownloaderFinish(DownloaderFinishData data);
/// <summary>
/// 下载进度更新
/// </summary>
public delegate void DownloadUpdate(DownloadUpdateData data);
/// <summary>
/// 下载发生错误
/// </summary>
public delegate void DownloadError(DownloadErrorData data);
/// <summary>
/// 开始下载某个文件
/// </summary>
public delegate void DownloadFileBegin(DownloadFileData data);
#endregion
private readonly string _packageName;
private readonly int _downloadingMaxNumber;
@@ -67,23 +84,23 @@ namespace YooAsset
/// <summary>
/// 当下载器结束(无论成功或失败)
/// </summary>
public OnDownloadOver OnDownloadOverCallback { set; get; }
public DownloaderFinish DownloadFinishCallback { set; get; }
/// <summary>
/// 当下载进度发生变化
/// </summary>
public OnDownloadProgress OnDownloadProgressCallback { set; get; }
public DownloadUpdate DownloadUpdateCallback { set; get; }
/// <summary>
/// 当某个文件下载失败
/// 当下载器发生错误
/// </summary>
public OnDownloadError OnDownloadErrorCallback { set; get; }
public DownloadError DownloadErrorCallback { set; get; }
/// <summary>
/// 当开始下载某个文件
/// </summary>
public OnStartDownloadFile OnStartDownloadFileCallback { set; get; }
public DownloadFileBegin DownloadFileBeginCallback { set; get; }
internal DownloaderOperation(string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
@@ -160,7 +177,18 @@ namespace YooAsset
_lastDownloadBytes = downloadBytes;
_lastDownloadCount = _cachedDownloadCount;
Progress = (float)_lastDownloadBytes / TotalDownloadBytes;
OnDownloadProgressCallback?.Invoke(TotalDownloadCount, _lastDownloadCount, TotalDownloadBytes, _lastDownloadBytes);
if (DownloadUpdateCallback != null)
{
var data = new DownloadUpdateData();
data.PackageName = _packageName;
data.Progress = Progress;
data.TotalDownloadCount = TotalDownloadCount;
data.CurrentDownloadCount = _lastDownloadCount;
data.TotalDownloadBytes = TotalDownloadBytes;
data.CurrentDownloadBytes = _lastDownloadBytes;
DownloadUpdateCallback.Invoke(data);
}
}
// 动态创建新的下载器到最大数量限制
@@ -177,7 +205,15 @@ namespace YooAsset
var downloader = bundleInfo.CreateDownloader(_failedTryAgain, _timeout);
_downloaders.Add(downloader);
_bundleInfoList.RemoveAt(index);
OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize);
if (DownloadFileBeginCallback != null)
{
var data = new DownloadFileData();
data.PackageName = _packageName;
data.FileName = bundleInfo.Bundle.BundleName;
data.FileSize = bundleInfo.Bundle.FileSize;
DownloadFileBeginCallback.Invoke(data);
}
}
}
@@ -191,15 +227,37 @@ namespace YooAsset
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to download file : {bundleName}";
OnDownloadErrorCallback?.Invoke(bundleName, failedDownloader.Error);
OnDownloadOverCallback?.Invoke(false);
if (DownloadErrorCallback != null)
{
var data = new DownloadErrorData();
data.PackageName = _packageName;
data.FileName = bundleName;
data.ErrorInfo = failedDownloader.Error;
DownloadErrorCallback.Invoke(data);
}
if (DownloadFinishCallback != null)
{
var data = new DownloaderFinishData();
data.PackageName = _packageName;
data.Succeed = false;
DownloadFinishCallback.Invoke(data);
}
}
else
{
// 结算成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
OnDownloadOverCallback?.Invoke(true);
if (DownloadFinishCallback != null)
{
var data = new DownloaderFinishData();
data.PackageName = _packageName;
data.Succeed = true;
DownloadFinishCallback.Invoke(data);
}
}
}
}

View File

@@ -385,7 +385,7 @@ namespace YooAsset
if (_steps == ESteps.InitWebRemoteFileSystem)
{
if (_initWebRemoteFileSystemOp == null)
_initWebRemoteFileSystemOp = _impl.WebServerFileSystem.InitializeFileSystemAsync();
_initWebRemoteFileSystemOp = _impl.WebRemoteFileSystem.InitializeFileSystemAsync();
Progress = _initWebRemoteFileSystemOp.Progress;
if (_initWebRemoteFileSystemOp.IsDone == false)

View File

@@ -6,11 +6,33 @@ namespace YooAsset
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName;
public readonly string PackageName;
/// <summary>
/// 模拟构建管线名称
/// </summary>
public string BuildPipelineName = "EditorSimulateBuildPipeline";
/// <summary>
/// 模拟构建类所属程序集名称
/// </summary>
public string InvokeAssmeblyName = "YooAsset.Editor";
/// <summary>
/// 模拟构建执行的类名全称
/// 注意:类名必须包含命名空间!
/// </summary>
public string InvokeClassFullName = "YooAsset.Editor.AssetBundleSimulateBuilder";
/// <summary>
/// 模拟构建执行的方法名称
/// 注意:执行方法必须满足 BindingFlags.Public | BindingFlags.Static
/// </summary>
public string InvokeMethodName = "SimulateBuild";
public EditorSimulateBuildParam(string packageName)
{
PackageName = packageName;
}
}
}

View File

@@ -5,17 +5,16 @@ namespace YooAsset
{
public static class EditorSimulateModeHelper
{
private static System.Type _classType;
/// <summary>
/// 编辑器下模拟构建清单
/// </summary>
public static EditorSimulateBuildResult SimulateBuild(EditorSimulateBuildParam buildParam)
{
if (_classType == null)
_classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleSimulateBuilder");
return (EditorSimulateBuildResult)InvokePublicStaticMethod(_classType, "SimulateBuild", buildParam);
var assemblyName = buildParam.InvokeAssmeblyName;
var className = buildParam.InvokeClassFullName;
var methodName = buildParam.InvokeMethodName;
var classType = Assembly.Load(assemblyName).GetType(className);
return (EditorSimulateBuildResult)InvokePublicStaticMethod(classType, methodName, buildParam);
}
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)

View File

@@ -52,9 +52,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(string clearMode, object clearParam)
{
var operation = new ClearCacheBundleFilesImplOperation(this, EditorFileSystem, null, null, clearMode, clearParam);
var operation = new ClearCacheFilesImplOperation(this, EditorFileSystem, null, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

@@ -56,9 +56,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(string clearMode, object clearParam)
{
var operation = new ClearCacheBundleFilesImplOperation(this, BuildinFileSystem, CacheFileSystem, null, clearMode, clearParam);
var operation = new ClearCacheFilesImplOperation(this, BuildinFileSystem, CacheFileSystem, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

@@ -52,9 +52,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(string clearMode, object clearParam)
{
var operation = new ClearCacheBundleFilesImplOperation(this, BuildinFileSystem, null, null, clearMode, clearParam);
var operation = new ClearCacheFilesImplOperation(this, BuildinFileSystem, null, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

@@ -74,9 +74,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(string clearMode, object clearParam)
{
var operation = new ClearCacheBundleFilesImplOperation(this, WebServerFileSystem, WebRemoteFileSystem, null, clearMode, clearParam);
var operation = new ClearCacheFilesImplOperation(this, WebServerFileSystem, WebRemoteFileSystem, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

@@ -209,7 +209,7 @@ namespace YooAsset
}
/// <summary>
/// 向网络端请求最新的资源版本
/// 请求最新的资源版本
/// </summary>
/// <param name="appendTimeTicks">在URL末尾添加时间戳</param>
/// <param name="timeout">超时时间默认值60秒</param>
@@ -220,9 +220,9 @@ namespace YooAsset
}
/// <summary>
/// 向网络端请求并更新清单
/// 更新并加载指定版本的资源清单
/// </summary>
/// <param name="packageVersion">更新的包裹版本</param>
/// <param name="packageVersion">包裹版本</param>
/// <param name="timeout">超时时间默认值60秒</param>
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60)
{
@@ -240,7 +240,7 @@ namespace YooAsset
/// <summary>
/// 预下载指定版本的包裹资源
/// </summary>
/// <param name="packageVersion">下载的包裹版本</param>
/// <param name="packageVersion">包裹版本</param>
/// <param name="timeout">超时时间默认值60秒</param>
public PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout = 60)
{
@@ -253,26 +253,27 @@ namespace YooAsset
/// </summary>
/// <param name="clearMode">清理方式</param>
/// <param name="clearParam">执行参数</param>
public ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(EFileClearMode clearMode, object clearParam = null)
public ClearCacheFilesOperation ClearCacheFilesAsync(EFileClearMode clearMode, object clearParam = null)
{
DebugCheckInitialize();
return _playModeImpl.ClearCacheBundleFilesAsync(clearMode.ToString(), clearParam);
return _playModeImpl.ClearCacheFilesAsync(clearMode.ToString(), clearParam);
}
/// <summary>
/// 清理缓存文件
/// </summary>
/// <param name="clearMode">清理方式</param>
/// <param name="clearParam">执行参数</param>
public ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(string clearMode, object clearParam = null)
public ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam = null)
{
DebugCheckInitialize();
return _playModeImpl.ClearCacheBundleFilesAsync(clearMode, clearParam);
return _playModeImpl.ClearCacheFilesAsync(clearMode, clearParam);
}
#region
/// <summary>
/// 获取当前激活包裹的版本信息
/// 获取当前加载包裹的版本信息
/// </summary>
public string GetPackageVersion()
{
@@ -281,7 +282,7 @@ namespace YooAsset
}
/// <summary>
/// 获取当前激活包裹的备注信息
/// 获取当前加载包裹的备注信息
/// </summary>
public string GetPackageNote()
{
@@ -290,7 +291,7 @@ namespace YooAsset
}
/// <summary>
/// 获取当前激活包裹的详细信息
/// 获取当前加载包裹的详细信息
/// </summary>
public PackageDetails GetPackageDetails()
{

View File

@@ -6,10 +6,15 @@ namespace YooAsset
internal class YooAssetSettings : ScriptableObject
{
/// <summary>
/// 默认的YooAsset文件夹名称
/// YooAsset文件夹名称
/// </summary>
public string DefaultYooFolderName = "yoo";
/// <summary>
/// 资源清单前缀名称(默认为空)
/// </summary>
public string PackageManifestPrefix = string.Empty;
/// <summary>
/// 清单文件头标记

View File

@@ -36,9 +36,12 @@ namespace YooAsset
/// <summary>
/// 获取构建报告文件名
/// </summary>
public static string GetReportFileName(string packageName, string packageVersion)
public static string GetBuildReportFileName(string packageName, string packageVersion)
{
return $"{packageName}_{packageVersion}.report";
if (string.IsNullOrEmpty(Setting.PackageManifestPrefix))
return $"{packageName}_{packageVersion}.report";
else
return $"{Setting.PackageManifestPrefix}_{packageName}_{packageVersion}.report";
}
/// <summary>
@@ -46,7 +49,10 @@ namespace YooAsset
/// </summary>
public static string GetManifestBinaryFileName(string packageName, string packageVersion)
{
return $"{packageName}_{packageVersion}.bytes";
if (string.IsNullOrEmpty(Setting.PackageManifestPrefix))
return $"{packageName}_{packageVersion}.bytes";
else
return $"{Setting.PackageManifestPrefix}_{packageName}_{packageVersion}.bytes";
}
/// <summary>
@@ -54,7 +60,10 @@ namespace YooAsset
/// </summary>
public static string GetManifestJsonFileName(string packageName, string packageVersion)
{
return $"{packageName}_{packageVersion}.json";
if (string.IsNullOrEmpty(Setting.PackageManifestPrefix))
return $"{packageName}_{packageVersion}.json";
else
return $"{Setting.PackageManifestPrefix}_{packageName}_{packageVersion}.json";
}
/// <summary>
@@ -62,7 +71,10 @@ namespace YooAsset
/// </summary>
public static string GetPackageHashFileName(string packageName, string packageVersion)
{
return $"{packageName}_{packageVersion}.hash";
if (string.IsNullOrEmpty(Setting.PackageManifestPrefix))
return $"{packageName}_{packageVersion}.hash";
else
return $"{Setting.PackageManifestPrefix}_{packageName}_{packageVersion}.hash";
}
/// <summary>
@@ -70,7 +82,10 @@ namespace YooAsset
/// </summary>
public static string GetPackageVersionFileName(string packageName)
{
return $"{packageName}.version";
if (string.IsNullOrEmpty(Setting.PackageManifestPrefix))
return $"{packageName}.version";
else
return $"{Setting.PackageManifestPrefix}_{packageName}.version";
}
#region

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8cae5a51fced527429445b140b8a0843
guid: 73ef838ec60c36249ba05eaa3c96273e
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using YooAsset.Editor;
[DisplayName("定位地址: 文件名.智能尾缀")]
public class AddressByFileNameAndExt : IAddressRule
{
public string GetAssetAddress(AddressRuleData data)
{
var ext = Path.GetExtension(data.AssetPath);
if (ext == ".asset")
{
var a = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(data.AssetPath);
if (a == null) return ".errortype";
var type = a.GetType();
var dt = Path.GetFileNameWithoutExtension(data.AssetPath);
return dt + $".{type.Name.ToLowerInvariant()}";
}
return Path.GetFileName(data.AssetPath);
}
}

View File

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

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