mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-06-09 20:23:42 +00:00
Compare commits
10 Commits
3.0.1-beta
...
2.3.19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5df594f7dc | ||
|
|
5151bb555f | ||
|
|
c331dc9b58 | ||
|
|
9d5f1b3aa4 | ||
|
|
93a9167100 | ||
|
|
54d1593dd2 | ||
|
|
a5f4b555e7 | ||
|
|
20ae423bbe | ||
|
|
d712a00458 | ||
|
|
c14244b2cf |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -15,7 +15,9 @@
|
|||||||
/Bundles/
|
/Bundles/
|
||||||
/ProjectSettings/
|
/ProjectSettings/
|
||||||
/App/
|
/App/
|
||||||
/yoo/
|
/yoo/
|
||||||
|
/Assets/Docs
|
||||||
|
/Assets/Docs.meta
|
||||||
/Assets/StreamingAssets
|
/Assets/StreamingAssets
|
||||||
/Assets/StreamingAssets.meta
|
/Assets/StreamingAssets.meta
|
||||||
/Assets/Samples
|
/Assets/Samples
|
||||||
@@ -70,6 +72,7 @@ sysinfo.txt
|
|||||||
# Builds
|
# Builds
|
||||||
*.apk
|
*.apk
|
||||||
*.unitypackage
|
*.unitypackage
|
||||||
|
*.zip
|
||||||
|
|
||||||
# Crashlytics generated file
|
# Crashlytics generated file
|
||||||
crashlytics-build.properties
|
crashlytics-build.properties
|
||||||
|
|||||||
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
All notable changes to this package will be documented in this file.
|
All notable changes to this package will be documented in this file.
|
||||||
|
|
||||||
|
## [2.3.19] - 2026-06-02
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- (#734) 修复了强制回收所有资源与自动卸载Bundle冲突。
|
||||||
|
- (#712) 修复了在禁用边玩边下的时候,加载原生文件流程未处理的问题。
|
||||||
|
- (#702) 修复了解压行为在包体内文件被篡改后,会无限尝试的问题。
|
||||||
|
- 修复了释放零引用待处理 Provider 时 UnloadAllAssetsOperation 死锁的问题。
|
||||||
|
- 修复了缓存文件校验改用清单的 FileCRC/FileSize,而非来自 .info 文件的自记录值。
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- 优化了资源清单重名键校验仅在 UNITY_EDITOR || DEBUG 下执行。
|
||||||
|
|
||||||
## [2.3.18] - 2025-12-04
|
## [2.3.18] - 2025-12-04
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -469,7 +469,9 @@ namespace YooAsset
|
|||||||
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element) == false)
|
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element) == false)
|
||||||
return EFileVerifyResult.CacheNotFound;
|
return EFileVerifyResult.CacheNotFound;
|
||||||
|
|
||||||
EFileVerifyResult result = FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, EFileVerifyLevel.High);
|
// 注意:使用清单里的权威校验值(与下载/解压时的校验基准一致),而不是缓存记录里来源于本地 .info 文件的自描述值,
|
||||||
|
// 否则数据文件与 .info 文件被一并篡改时仍会校验通过。
|
||||||
|
EFileVerifyResult result = FileVerifyHelper.FileVerify(element.DataFilePath, bundle.FileSize, bundle.FileCRC, EFileVerifyLevel.High);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
|
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
|
||||||
|
|||||||
@@ -336,7 +336,17 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.DownloadFile;
|
if (_fileSystem.DisableOnDemandDownload)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"The bundle not cached : {_bundle.BundleName}";
|
||||||
|
YooLogger.Warning(Error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.DownloadFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (IsWaitForAsyncComplete == false && _failedTryAgain > 0)
|
// 注意:本地文件(解压/导入)校验失败属于确定性失败,重试只会重复读取同一文件,直接判定失败防止无限重试。
|
||||||
|
if (IsWaitForAsyncComplete == false && _failedTryAgain > 0 && _unityDownloadFileOp.VerifyFailed == false)
|
||||||
{
|
{
|
||||||
_steps = ESteps.TryAgain;
|
_steps = ESteps.TryAgain;
|
||||||
YooLogger.Warning($"Failed download : {_unityDownloadFileOp.URL} Try again !");
|
YooLogger.Warning($"Failed download : {_unityDownloadFileOp.URL} Try again !");
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int RefCount { private set; get; }
|
public int RefCount { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件校验是否失败
|
||||||
|
/// 注意:本地文件(解压/导入)校验失败属于确定性失败,重试无意义,上层不应重试。
|
||||||
|
/// </summary>
|
||||||
|
public bool VerifyFailed { protected set; get; } = false;
|
||||||
|
|
||||||
internal UnityDownloadFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
internal UnityDownloadFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 注意:本地内置文件被篡改或损坏时校验会失败,重试只会重复读取同一文件,因此标记为不可重试。
|
||||||
|
VerifyFailed = true;
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = _verifyOperation.Error;
|
Error = _verifyOperation.Error;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
@@ -24,6 +25,7 @@ namespace YooAsset
|
|||||||
CheckOptions,
|
CheckOptions,
|
||||||
ReleaseAll,
|
ReleaseAll,
|
||||||
TryAbortLoader,
|
TryAbortLoader,
|
||||||
|
RequestForceDestroy,
|
||||||
CheckLoading,
|
CheckLoading,
|
||||||
DestroyAll,
|
DestroyAll,
|
||||||
Done,
|
Done,
|
||||||
@@ -72,7 +74,10 @@ namespace YooAsset
|
|||||||
// 释放所有资源句柄
|
// 释放所有资源句柄
|
||||||
if (_options.ReleaseAllHandles)
|
if (_options.ReleaseAllHandles)
|
||||||
{
|
{
|
||||||
foreach (var provider in _resManager.ProviderDic.Values)
|
// 注意:创建快照,因为释放句柄可能触发自动卸载逻辑(AutoUnloadBundleWhenUnused),
|
||||||
|
// 进而修改 ProviderDic 容器,导致遍历时抛出 InvalidOperationException。
|
||||||
|
var snapshot = new List<ProviderOperation>(_resManager.ProviderDic.Values);
|
||||||
|
foreach (var provider in snapshot)
|
||||||
{
|
{
|
||||||
provider.ReleaseAllHandles();
|
provider.ReleaseAllHandles();
|
||||||
}
|
}
|
||||||
@@ -89,6 +94,17 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
loader.TryAbortLoader();
|
loader.TryAbortLoader();
|
||||||
}
|
}
|
||||||
|
_steps = ESteps.RequestForceDestroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.RequestForceDestroy)
|
||||||
|
{
|
||||||
|
// 向所有资源提供者下发强制销毁请求
|
||||||
|
// 注意:防止零引用且尚未进入加载阶段的任务被无限挂起,从而导致 CheckLoading 死锁。
|
||||||
|
foreach (var provider in _resManager.ProviderDic.Values)
|
||||||
|
{
|
||||||
|
provider.RequestForceDestroy();
|
||||||
|
}
|
||||||
_steps = ESteps.CheckLoading;
|
_steps = ESteps.CheckLoading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDestroyed { private set; get; } = false;
|
public bool IsDestroyed { private set; get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已收到强制销毁请求
|
||||||
|
/// </summary>
|
||||||
|
public bool ForceDestroyRequested { private set; get; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载任务是否进行中
|
/// 加载任务是否进行中
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -119,6 +124,18 @@ namespace YooAsset
|
|||||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 注意:收到强制销毁请求时,未在加载中的任务立即结束,防止零引用任务被无限挂起导致卸载流程死锁!
|
||||||
|
if (ForceDestroyRequested)
|
||||||
|
{
|
||||||
|
if (IsLoading == false)
|
||||||
|
{
|
||||||
|
InvokeCompletion("Provider force destroyed during unload all assets !", EOperationStatus.Failed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注意:已进入加载阶段则继续等待自然完成
|
||||||
|
}
|
||||||
|
|
||||||
// 注意:未在加载中的任务可以挂起!
|
// 注意:未在加载中的任务可以挂起!
|
||||||
if (IsLoading == false)
|
if (IsLoading == false)
|
||||||
{
|
{
|
||||||
@@ -199,11 +216,24 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
protected abstract void ProcessBundleResult();
|
protected abstract void ProcessBundleResult();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求强制销毁
|
||||||
|
/// 注意:用于卸载流程,标记后未在加载中的任务会在下一次更新时立即结束。
|
||||||
|
/// </summary>
|
||||||
|
public void RequestForceDestroy()
|
||||||
|
{
|
||||||
|
ForceDestroyRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 销毁资源提供者
|
/// 销毁资源提供者
|
||||||
|
/// 注意:该方法是幂等的,重复调用不会重复释放资源。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void DestroyProvider()
|
public void DestroyProvider()
|
||||||
{
|
{
|
||||||
|
if (IsDestroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
IsDestroyed = true;
|
IsDestroyed = true;
|
||||||
|
|
||||||
// 检测是否为正常销毁
|
// 检测是否为正常销毁
|
||||||
|
|||||||
@@ -264,23 +264,27 @@ namespace YooAsset
|
|||||||
manifest.AssetList.Add(packageAsset);
|
manifest.AssetList.Add(packageAsset);
|
||||||
|
|
||||||
// 注意:我们不允许原始路径存在重名
|
// 注意:我们不允许原始路径存在重名
|
||||||
|
// 说明:清单是构建期生成的可信数据,重名只会因构建错误产生,仅在开发期校验即可,发行版省去一次哈希查找。
|
||||||
string assetPath = packageAsset.AssetPath;
|
string assetPath = packageAsset.AssetPath;
|
||||||
|
#if UNITY_EDITOR || DEBUG
|
||||||
if (manifest.AssetDic.ContainsKey(assetPath))
|
if (manifest.AssetDic.ContainsKey(assetPath))
|
||||||
throw new System.Exception($"AssetPath have existed : {assetPath}");
|
throw new System.Exception($"AssetPath have existed : {assetPath}");
|
||||||
else
|
#endif
|
||||||
manifest.AssetDic.Add(assetPath, packageAsset);
|
manifest.AssetDic.Add(assetPath, packageAsset);
|
||||||
|
|
||||||
// 填充AssetPathMapping1
|
// 填充AssetPathMapping1
|
||||||
{
|
{
|
||||||
string location = packageAsset.AssetPath;
|
string location = packageAsset.AssetPath;
|
||||||
|
|
||||||
// 添加原生路径的映射
|
// 添加原生路径的映射
|
||||||
|
#if UNITY_EDITOR || DEBUG
|
||||||
if (manifest.AssetPathMapping1.ContainsKey(location))
|
if (manifest.AssetPathMapping1.ContainsKey(location))
|
||||||
throw new System.Exception($"Location have existed : {location}");
|
throw new System.Exception($"Location have existed : {location}");
|
||||||
else
|
#endif
|
||||||
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
|
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
|
||||||
|
|
||||||
// 添加无后缀名路径的映射
|
// 添加无后缀名路径的映射
|
||||||
|
// 注意:无后缀名重名属于合法运行时情况(仅警告并跳过),因此该校验必须在发行版也执行。
|
||||||
if (manifest.SupportExtensionless)
|
if (manifest.SupportExtensionless)
|
||||||
{
|
{
|
||||||
string locationWithoutExtension = Path.ChangeExtension(location, null);
|
string locationWithoutExtension = Path.ChangeExtension(location, null);
|
||||||
@@ -297,10 +301,11 @@ namespace YooAsset
|
|||||||
// 填充AssetPathMapping2
|
// 填充AssetPathMapping2
|
||||||
if (manifest.IncludeAssetGUID)
|
if (manifest.IncludeAssetGUID)
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR || DEBUG
|
||||||
if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
|
if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
|
||||||
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
|
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
|
||||||
else
|
#endif
|
||||||
manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
|
manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加可寻址地址
|
// 添加可寻址地址
|
||||||
@@ -309,10 +314,11 @@ namespace YooAsset
|
|||||||
string location = packageAsset.Address;
|
string location = packageAsset.Address;
|
||||||
if (string.IsNullOrEmpty(location) == false)
|
if (string.IsNullOrEmpty(location) == false)
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR || DEBUG
|
||||||
if (manifest.AssetPathMapping1.ContainsKey(location))
|
if (manifest.AssetPathMapping1.ContainsKey(location))
|
||||||
throw new System.Exception($"Location have existed : {location}");
|
throw new System.Exception($"Location have existed : {location}");
|
||||||
else
|
#endif
|
||||||
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
|
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.tuyoogame.yooasset",
|
"name": "com.tuyoogame.yooasset",
|
||||||
"displayName": "YooAsset",
|
"displayName": "YooAsset",
|
||||||
"version": "2.3.18",
|
"version": "2.3.19",
|
||||||
"unity": "2019.4",
|
"unity": "2019.4",
|
||||||
"description": "unity3d resources management system.",
|
"description": "unity3d resources management system.",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -187,7 +187,7 @@
|
|||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2018-2021 何冠峰
|
Copyright 2018-2021 何冠峰
|
||||||
Copyright 2021-2025 TuYoo Games
|
Copyright 2021-2026 TuYoo Games
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
Reference in New Issue
Block a user