Compare commits

...

39 Commits

Author SHA1 Message Date
何冠峰
dfa95b57b9 Update CHANGELOG.md 2025-02-14 10:03:39 +08:00
何冠峰
33a2cf66d0 Update CHANGELOG.md 2025-02-14 10:03:15 +08:00
何冠峰
5f52cf5b51 Update package.json 2025-02-14 10:03:09 +08:00
何冠峰
9d07905f2d fix #471 2025-02-13 20:14:33 +08:00
何冠峰
26dbe9dfdd update extension sample 2025-02-13 19:08:23 +08:00
何冠峰
98c5851071 update extension file system
解决微信小游戏预下载和正常下载冲突的问题
2025-02-13 18:57:39 +08:00
何冠峰
a6ee571d65 update file system 2025-02-13 18:56:24 +08:00
何冠峰
a138701afe update extension sample
抖音小游戏支持资源加密
2025-02-13 12:12:52 +08:00
何冠峰
e52bdea255 fix #467
微信小游戏资源加密
2025-02-13 12:02:09 +08:00
何冠峰
068a712a30 Merge pull request #470 from suxf/dev
fix: 微信加密资源解密错误
2025-02-13 10:13:28 +08:00
枫似锦
80a5300648 fix: 微信加密资源解密错误 2025-02-13 00:12:26 +08:00
何冠峰
0c36e458f7 update space shooter 2025-02-12 17:43:15 +08:00
何冠峰
b2fa52e4c4 update AssetArtScanner 2025-02-12 17:43:07 +08:00
何冠峰
151e978e5b update space shoot 2025-02-12 16:29:26 +08:00
何冠峰
9e806861ec update extension sample 2025-02-12 16:28:31 +08:00
何冠峰
a9a9368b9b update test sample 2025-02-12 16:27:51 +08:00
何冠峰
7936ba31ea update file system
WebGL网页平台支持资源加密。
2025-02-12 16:27:30 +08:00
何冠峰
afc456de9a Update UnloadAllAssetsOperation.cs 2025-02-12 14:44:02 +08:00
何冠峰
a98db0ba83 update extension sample 2025-02-12 14:43:51 +08:00
何冠峰
fb8720edd3 update extension sample
抖音小游戏支持文件加密。
2025-02-12 11:59:09 +08:00
何冠峰
2aa2a0ac3a update space shooter 2025-02-12 11:46:38 +08:00
何冠峰
0531b6ef3a update extension sample 2025-02-12 11:45:12 +08:00
何冠峰
24142de11f update extension sample
支持微信小游戏文件加密
2025-02-12 11:23:27 +08:00
何冠峰
7fad6eb70b update services
增加WebGL端解密接口
2025-02-12 11:22:09 +08:00
何冠峰
f60227abdf Merge pull request #469 from suxf/dev
优化微信小游戏文件系统逻辑
2025-02-12 10:10:32 +08:00
枫似锦
18d6a74c53 Merge branch 'dev' of https://github.com/suxf/YooAsset into dev 2025-02-12 00:30:22 +08:00
枫似锦
03d06ba657 优化微信小游戏文件系统逻辑 2025-02-12 00:29:10 +08:00
何冠峰
07086b68c8 update extension sample
优化了抖音小游戏文件系统缓存机制
2025-02-11 18:44:51 +08:00
何冠峰
0a85f3126f update extension sample
优化了微信小游戏文件系统缓存机制。
2025-02-11 18:18:29 +08:00
何冠峰
efa4180340 update resource manager
UnloadUnusedAssetsOperation逻辑里移除了Resources.UnloadUnusedAssets调用
2025-02-11 18:15:45 +08:00
何冠峰
fb06f2aa11 update resource manager
UnloadAllAssetsAsync新增UnloadAllAssetsOptions参数
2025-02-11 17:32:31 +08:00
何冠峰
ce023cedb8 update extension sample 2025-02-11 15:13:45 +08:00
何冠峰
3d1a28a50e update file system 2025-02-11 15:09:23 +08:00
何冠峰
5d2d0b4168 fix #341 2025-02-11 10:20:33 +08:00
何冠峰
fa985a5a93 Merge branch 'dev' of https://github.com/tuyoogame/YooAsset into dev 2025-02-11 09:55:38 +08:00
何冠峰
40f9937b60 update space shooter 2025-02-11 09:55:37 +08:00
何冠峰
c543c629c3 Merge pull request #466 from suxf/dev
fix:微信小游戏缓存文件系统查询机制不生效
2025-02-11 09:43:16 +08:00
枫似锦
0a96e583d3 Merge branch 'dev' of https://github.com/suxf/YooAsset into dev 2025-02-10 16:39:31 +08:00
枫似锦
c9d263c60d fix:微信小游戏缓存文件系统查询机制不生效 2025-02-10 16:38:23 +08:00
47 changed files with 1096 additions and 626 deletions

View File

@@ -2,6 +2,39 @@
All notable changes to this package will be documented in this file.
## [2.2.12] - 2025-02-14
### Improvements
- WebGL网页平台支持文件加密。
- 微信小游戏平台支持文件加密。
- 抖音小游戏平台支持文件加密。
### Fixed
- (#466) 修复了微信小游戏文件系统查询机制不生效!
- (#341) 修复了微信小游戏的下载进度异常问题。
- (#471) 修复了Unity2019,Unity2020平台上TableView视图无法显示的问题。
### Added
- 新增了ResourcePackage.UnloadAllAssetsAsync(UnloadAllAssetsOptions options)方法
```csharp
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = true;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = true;
}
```
## [2.2.11] - 2025-02-10
### Improvements

View File

@@ -6,7 +6,7 @@ namespace YooAsset.Editor
/// <summary>
/// 检视界面的UI元素容器UIElements元素
/// </summary>
public object Containner;
public object Containner { private set; get; }
/// <summary>
/// 检视界面宽度
@@ -22,5 +22,24 @@ namespace YooAsset.Editor
/// 检视界面最大宽度
/// </summary>
public int MaxWidth = 250;
public SchemaInspector(object containner)
{
Containner = containner;
}
public SchemaInspector(object containner, int width)
{
Containner = containner;
Width = width;
MinWidth = width;
MaxWidth = width;
}
public SchemaInspector(object containner, int width, int minWidth, int maxWidth)
{
Containner = containner;
Width = width;
MinWidth = minWidth;
MaxWidth = maxWidth;
}
}
}

View File

@@ -2,7 +2,7 @@
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="TopTableView" />
</ui:VisualElement>
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -1,8 +1,8 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="TopTableView" />
<YooAsset.Editor.TableView name="TopTableView" style="flex-grow: 1;" />
</ui:VisualElement>
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="BottomTableView" />
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -1,8 +1,8 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="TopTableView" />
<YooAsset.Editor.TableView name="TopTableView" style="flex-grow: 1;" />
</ui:VisualElement>
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="BottomTableView" />
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -90,10 +90,16 @@ namespace YooAsset.Editor
public TableView()
{
_toolbar = new Toolbar();
this.Add(_toolbar);
this.style.flexShrink = 1f;
this.style.flexGrow = 1f;
// 定义标题栏
_toolbar = new Toolbar();
// 定义列表视图
_listView = new ListView();
_listView.style.flexShrink = 1f;
_listView.style.flexGrow = 1f;
_listView.makeItem = MakeListViewElement;
_listView.bindItem = BindListViewElement;
_listView.selectionType = SelectionType.Multiple;
@@ -107,6 +113,7 @@ namespace YooAsset.Editor
_listView.onSelectionChanged += OnSelectionChanged;
#endif
this.Add(_toolbar);
this.Add(_listView);
}

View File

@@ -21,7 +21,7 @@ namespace YooAsset
}
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, string> _buildinFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _buildinFilePathMapping = new Dictionary<string, string>(10000);
protected IFileSystem _unpackFileSystem;
protected string _packageRoot;
@@ -309,10 +309,10 @@ namespace YooAsset
}
public string GetBuildinFileLoadPath(PackageBundle bundle)
{
if (_buildinFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_buildinFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_packageRoot, bundle.FileName);
_buildinFilePaths.Add(bundle.BundleGUID, filePath);
_buildinFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}

View File

@@ -11,10 +11,10 @@ namespace YooAsset
/// </summary>
internal class DefaultCacheFileSystem : IFileSystem
{
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 readonly Dictionary<string, RecordFileElement> _records = new Dictionary<string, RecordFileElement>(10000);
protected readonly Dictionary<string, string> _bundleDataFilePathMapping = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _bundleInfoFilePathMapping = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _tempFilePathMapping = new Dictionary<string, string>(10000);
protected DefaultCacheDownloadCenter _downloadCenter;
protected string _packageRoot;
@@ -45,7 +45,7 @@ namespace YooAsset
{
get
{
return _wrappers.Count;
return _records.Count;
}
}
@@ -245,7 +245,7 @@ namespace YooAsset
}
public virtual bool Exists(PackageBundle bundle)
{
return _wrappers.ContainsKey(bundle.BundleGUID);
return _records.ContainsKey(bundle.BundleGUID);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -330,60 +330,60 @@ namespace YooAsset
#region
public List<string> GetAllCachedBundleGUIDs()
{
return _wrappers.Keys.ToList();
return _records.Keys.ToList();
}
public string GetTempFilePath(PackageBundle bundle)
{
if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_tempFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_tempFilesRoot, bundle.BundleGUID);
_tempFilePaths.Add(bundle.BundleGUID, filePath);
_tempFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleDataFilePath(PackageBundle bundle)
{
if (_bundleDataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_bundleDataFilePathMapping.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);
_bundleDataFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleInfoFilePath(PackageBundle bundle)
{
if (_bundleInfoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_bundleInfoFilePathMapping.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);
_bundleInfoFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public bool IsRecordBundleFile(string bundleGUID)
{
return _wrappers.ContainsKey(bundleGUID);
return _records.ContainsKey(bundleGUID);
}
public bool RecordBundleFile(string bundleGUID, RecordFileElement element)
{
if (_wrappers.ContainsKey(bundleGUID))
if (_records.ContainsKey(bundleGUID))
{
YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}");
return false;
}
_wrappers.Add(bundleGUID, element);
_records.Add(bundleGUID, element);
return true;
}
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
{
if (_wrappers.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
return EFileVerifyResult.CacheNotFound;
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
@@ -391,7 +391,7 @@ namespace YooAsset
}
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
{
if (_wrappers.ContainsKey(bundle.BundleGUID))
if (_records.ContainsKey(bundle.BundleGUID))
{
throw new Exception("Should never get here !");
}
@@ -426,7 +426,7 @@ namespace YooAsset
}
public bool DeleteCacheBundleFile(string bundleGUID)
{
if (_wrappers.TryGetValue(bundleGUID, out RecordFileElement wrapper))
if (_records.TryGetValue(bundleGUID, out RecordFileElement wrapper))
{
try
{
@@ -434,7 +434,7 @@ namespace YooAsset
FileInfo fileInfo = new FileInfo(dataFilePath);
if (fileInfo.Exists)
fileInfo.Directory.Delete(true);
_wrappers.Remove(bundleGUID);
_records.Remove(bundleGUID);
return true;
}
catch (Exception e)

View File

@@ -47,6 +47,11 @@ namespace YooAsset
/// 自定义参数:跨域下载服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -108,6 +113,10 @@ namespace YooAsset
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");

View File

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

using UnityEngine;
namespace YooAsset
{
internal class DWRFSLoadAssetBundleOperation : FSLoadBundleOperation
@@ -8,13 +6,13 @@ namespace YooAsset
private enum ESteps
{
None,
DownloadFile,
DownloadAssetBundle,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
@@ -25,38 +23,47 @@ namespace YooAsset
}
internal override void InternalOnStart()
{
_steps = ESteps.DownloadFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp == null)
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _downloadhanlderAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadhanlderAssetBundleOp.DownloadedBytes;
Progress = _downloadhanlderAssetBundleOp.Progress;
if (_downloadhanlderAssetBundleOp.IsDone == false)
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadAssetBundleOp.DownloadedBytes;
Progress = _downloadAssetBundleOp.Progress;
if (_downloadAssetBundleOp.IsDone == false)
return;
if (_downloadhanlderAssetBundleOp.Status == EOperationStatus.Succeed)
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadhanlderAssetBundleOp.Result;
if(assetBundle == null)
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadHandlerAssetBundleOperation)} loaded asset bundle is null !";
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
@@ -69,7 +76,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadhanlderAssetBundleOp.Error;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -85,10 +92,10 @@ namespace YooAsset
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp != null)
_downloadhanlderAssetBundleOp.SetAbort();
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
}
}

View File

@@ -21,7 +21,7 @@ namespace YooAsset
}
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, string> _webFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _webFilePathMapping = new Dictionary<string, string>(10000);
protected string _webPackageRoot = string.Empty;
/// <summary>
@@ -56,6 +56,11 @@ namespace YooAsset
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { private set; get; } = false;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -113,6 +118,10 @@ namespace YooAsset
{
DisableUnityWebCache = (bool)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
@@ -173,10 +182,10 @@ namespace YooAsset
}
public string GetWebFileLoadPath(PackageBundle bundle)
{
if (_webFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_webFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName);
_webFilePaths.Add(bundle.BundleGUID, filePath);
_webFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}

View File

@@ -6,13 +6,13 @@ namespace YooAsset
private enum ESteps
{
None,
DownloadFile,
DownloadAssetBundle,
Done,
}
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
@@ -23,39 +23,48 @@ namespace YooAsset
}
internal override void InternalOnStart()
{
_steps = ESteps.DownloadFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp == null)
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
downloadParam.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
downloadParam.FallbackURL = downloadParam.MainURL;
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _downloadhanlderAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadhanlderAssetBundleOp.DownloadedBytes;
Progress = _downloadhanlderAssetBundleOp.Progress;
if (_downloadhanlderAssetBundleOp.IsDone == false)
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadAssetBundleOp.DownloadedBytes;
Progress = _downloadAssetBundleOp.Progress;
if (_downloadAssetBundleOp.IsDone == false)
return;
if (_downloadhanlderAssetBundleOp.Status == EOperationStatus.Succeed)
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadhanlderAssetBundleOp.Result;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadHandlerAssetBundleOperation)} loaded asset bundle is null !";
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
@@ -68,7 +77,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadhanlderAssetBundleOp.Error;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -84,10 +93,10 @@ namespace YooAsset
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp != null)
_downloadhanlderAssetBundleOp.SetAbort();
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
}
}

View File

@@ -110,10 +110,11 @@ namespace YooAsset
/// 创建默认的WebServer文件系统参数
/// </summary>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache = false)
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{
string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams;
}
@@ -123,11 +124,12 @@ namespace YooAsset
/// </summary>
/// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, bool disableUnityWebCache = false)
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{
string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams;
}

View File

@@ -20,7 +20,7 @@ namespace YooAsset
/// <summary>
/// 初始化缓存系统
/// 初始化文件系统
/// </summary>
FSInitializeFileSystemOperation InitializeFileSystemAsync();
@@ -30,7 +30,7 @@ namespace YooAsset
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
/// <summary>
/// 查询最新的版本
/// 查询包裹版本
/// </summary>
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
@@ -40,7 +40,7 @@ namespace YooAsset
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
/// <summary>
/// 下载远端文件
/// 下载Bundle文件
/// </summary>
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param);

View File

@@ -0,0 +1,14 @@
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal abstract class DownloadAssetBundleOperation : DefaultDownloadFileOperation
{
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
public AssetBundle Result;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 640ec7bd883b8314db53b508278aea6e
guid: 0f65d2f6038b95246b7a09cec4055b3a
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,157 @@
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal class DownloadWebEncryptAssetBundleOperation : DownloadAssetBundleOperation
{
private readonly bool _checkTimeout;
private readonly IWebDecryptionServices _decryptionServices;
private DownloadHandlerBuffer _downloadhandler;
private ESteps _steps = ESteps.None;
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_checkTimeout = checkTimeout;
_decryptionServices = decryptionServices;
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
if (_checkTimeout)
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
if (_decryptionServices == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The {nameof(IWebDecryptionServices)} is null !";
YooLogger.Error(Error);
return;
}
var fileData = _downloadhandler.data;
if (fileData == null || fileData.Length == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The download handler data is null or empty !";
YooLogger.Error(Error);
return;
}
AssetBundle assetBundle = LoadEncryptedAssetBundle(fileData);
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_downloadhandler = new DownloadHandlerBuffer();
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
/// <summary>
/// 加载加密资源文件
/// </summary>
private AssetBundle LoadEncryptedAssetBundle(byte[] fileData)
{
var fileInfo = new WebDecryptFileInfo();
fileInfo.BundleName = Bundle.BundleName;
fileInfo.FileLoadCRC = Bundle.UnityCRC;
fileInfo.FileData = fileData;
var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo);
return decryptResult.Result;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e4420bd73f37dec468a9b23425be68f2
guid: 2f88823353464474faf7b020a76f9b2d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -3,16 +3,13 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal class DownloadHandlerAssetBundleOperation : DefaultDownloadFileOperation
internal class DownloadWebNormalAssetBundleOperation : DownloadAssetBundleOperation
{
private readonly bool _disableUnityWebCache;
private DownloadHandlerAssetBundle _downloadhandler;
private ESteps _steps = ESteps.None;
public AssetBundle Result { private set; get; }
internal DownloadHandlerAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadWebNormalAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_disableUnityWebCache = disableUnityWebCache;
}
@@ -55,12 +52,12 @@ namespace YooAsset
// 检查网络错误
if (CheckRequestResult())
{
var assetBundle = _downloadhandler.assetBundle;
AssetBundle assetBundle = _downloadhandler.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = "Download handler asset bundle object is null !";
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
@@ -106,7 +103,7 @@ namespace YooAsset
private void CreateWebRequest()
{
_downloadhandler = CreateDownloadHandler();
_downloadhandler = CreateWebDownloadHandler();
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
@@ -121,7 +118,7 @@ namespace YooAsset
_webRequest = null;
}
}
private DownloadHandlerAssetBundle CreateDownloadHandler()
private DownloadHandlerAssetBundle CreateWebDownloadHandler()
{
if (_disableUnityWebCache)
{

View File

@@ -3,38 +3,88 @@ using UnityEngine;
namespace YooAsset
{
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = false;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = false;
}
public sealed class UnloadAllAssetsOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckOptions,
ReleaseAll,
AbortDownload,
CheckLoading,
UnloadAll,
DestroyAll,
Done,
}
private readonly ResourceManager _resManager;
private readonly UnloadAllAssetsOptions _options;
private ESteps _steps = ESteps.None;
internal UnloadAllAssetsOperation(ResourceManager resourceManager)
internal UnloadAllAssetsOperation(ResourceManager resourceManager, UnloadAllAssetsOptions options)
{
_resManager = resourceManager;
_options = options;
}
internal override void InternalOnStart()
{
_steps = ESteps.AbortDownload;
_steps = ESteps.CheckOptions;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckOptions)
{
if (_options == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(UnloadAllAssetsOptions)} is null.";
return;
}
// 设置锁定状态
if (_options.LockLoadOperation)
_resManager.LockLoadOperation = true;
_steps = ESteps.ReleaseAll;
}
if (_steps == ESteps.ReleaseAll)
{
// 清空所有场景句柄
_resManager.SceneHandles.Clear();
// 释放所有资源句柄
if (_options.ReleaseAllHandles)
{
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.ReleaseAllHandles();
}
}
_steps = ESteps.AbortDownload;
}
if (_steps == ESteps.AbortDownload)
{
// 注意:终止所有下载任务
var loaderDic = _resManager._loaderDic;
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.AbortDownloadOperation();
}
@@ -44,44 +94,32 @@ namespace YooAsset
if (_steps == ESteps.CheckLoading)
{
// 注意:等待所有任务完成
var providerDic = _resManager._providerDic;
foreach (var provider in providerDic.Values)
foreach (var provider in _resManager.ProviderDic.Values)
{
if (provider.IsDone == false)
return;
}
_steps = ESteps.UnloadAll;
_steps = ESteps.DestroyAll;
}
if (_steps == ESteps.UnloadAll)
if (_steps == ESteps.DestroyAll)
{
var loaderDic = _resManager._loaderDic;
var providerDic = _resManager._providerDic;
// 清空所有场景句柄
_resManager._sceneHandles.Clear();
// 释放所有资源句柄
foreach (var provider in providerDic.Values)
{
provider.ReleaseAllHandles();
}
// 强制销毁资源提供者
foreach (var provider in providerDic.Values)
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.DestroyProvider();
}
// 强制销毁文件加载器
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.DestroyLoader();
}
// 清空数据
providerDic.Clear();
loaderDic.Clear();
_resManager.ProviderDic.Clear();
_resManager.LoaderDic.Clear();
_resManager.LockLoadOperation = false;
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();

View File

@@ -31,17 +31,16 @@ namespace YooAsset
if (_steps == ESteps.UnloadUnused)
{
var loaderDic = _resManager._loaderDic;
var removeList = new List<LoadBundleFileOperation>(loaderDic.Count);
var removeList = new List<LoadBundleFileOperation>(_resManager.LoaderDic.Count);
// 注意:优先销毁资源提供者
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.TryDestroyProviders();
}
// 获取销毁列表
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
if (loader.CanDestroyLoader())
{
@@ -54,13 +53,9 @@ namespace YooAsset
{
string bundleName = loader.LoadBundleInfo.Bundle.BundleName;
loader.DestroyLoader();
_resManager._loaderDic.Remove(bundleName);
_resManager.LoaderDic.Remove(bundleName);
}
// 注意:调用底层接口释放所有资源
if (removeList.Count > 0)
Resources.UnloadUnusedAssets();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}

View File

@@ -86,7 +86,7 @@ namespace YooAsset
// 依赖资源包加载器集合
var dependLoaders = manager.CreateDependBundleFileLoaders(assetInfo);
if(dependLoaders.Count > 0)
if (dependLoaders.Count > 0)
_bundleLoaders.AddRange(dependLoaders);
// 增加引用计数

View File

@@ -9,9 +9,9 @@ namespace YooAsset
{
internal class ResourceManager
{
internal readonly Dictionary<string, ProviderOperation> _providerDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> _loaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
internal readonly List<SceneHandle> _sceneHandles = new List<SceneHandle>(100);
internal readonly Dictionary<string, ProviderOperation> ProviderDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> LoaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100);
private long _sceneCreateIndex = 0;
private IBundleQuery _bundleQuery;
@@ -20,6 +20,11 @@ namespace YooAsset
/// </summary>
public readonly string PackageName;
/// <summary>
/// 锁定加载操作
/// </summary>
public bool LockLoadOperation = false;
public ResourceManager(string packageName)
{
@@ -64,7 +69,7 @@ namespace YooAsset
{
string bundleName = mainLoader.LoadBundleInfo.Bundle.BundleName;
mainLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
LoaderDic.Remove(bundleName);
}
}
@@ -79,7 +84,7 @@ namespace YooAsset
{
string bundleName = dependLoader.LoadBundleInfo.Bundle.BundleName;
dependLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
LoaderDic.Remove(bundleName);
}
}
}
@@ -92,6 +97,15 @@ namespace YooAsset
/// </summary>
public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<SceneHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
@@ -106,14 +120,14 @@ namespace YooAsset
{
provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
var handle = provider.CreateHandle<SceneHandle>();
handle.PackageName = PackageName;
_sceneHandles.Add(handle);
SceneHandles.Add(handle);
return handle;
}
@@ -122,6 +136,15 @@ namespace YooAsset
/// </summary>
public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<AssetHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
@@ -136,7 +159,7 @@ namespace YooAsset
{
provider = new AssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -149,6 +172,15 @@ namespace YooAsset
/// </summary>
public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<SubAssetsHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
@@ -163,7 +195,7 @@ namespace YooAsset
{
provider = new SubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -176,6 +208,15 @@ namespace YooAsset
/// </summary>
public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<AllAssetsHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
@@ -190,7 +231,7 @@ namespace YooAsset
{
provider = new AllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -203,6 +244,15 @@ namespace YooAsset
/// </summary>
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<RawFileHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
@@ -217,7 +267,7 @@ namespace YooAsset
{
provider = new RawFileProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -245,12 +295,12 @@ namespace YooAsset
{
foreach (var provider in removeList)
{
_providerDic.Remove(provider.ProviderGUID);
ProviderDic.Remove(provider.ProviderGUID);
}
}
internal bool HasAnyLoader()
{
return _loaderDic.Count > 0;
return LoaderDic.Count > 0;
}
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
@@ -264,19 +314,19 @@ namespace YooAsset
// 新增下载需求
loaderOperation = new LoadBundleFileOperation(this, bundleInfo);
OperationSystem.StartOperation(PackageName, loaderOperation);
_loaderDic.Add(bundleName, loaderOperation);
LoaderDic.Add(bundleName, loaderOperation);
return loaderOperation;
}
private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName)
{
if (_loaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
if (LoaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
return value;
else
return null;
}
private ProviderOperation TryGetAssetProvider(string providerGUID)
{
if (_providerDic.TryGetValue(providerGUID, out ProviderOperation value))
if (ProviderDic.TryGetValue(providerGUID, out ProviderOperation value))
return value;
else
return null;
@@ -284,7 +334,7 @@ namespace YooAsset
private void OnSceneUnloaded(Scene scene)
{
List<SceneHandle> removeList = new List<SceneHandle>();
foreach (var sceneHandle in _sceneHandles)
foreach (var sceneHandle in SceneHandles)
{
if (sceneHandle.IsValid)
{
@@ -297,15 +347,15 @@ namespace YooAsset
}
foreach (var sceneHandle in removeList)
{
_sceneHandles.Remove(sceneHandle);
SceneHandles.Remove(sceneHandle);
}
}
#region
internal List<DebugProviderInfo> GetDebugReportInfos()
{
List<DebugProviderInfo> result = new List<DebugProviderInfo>(_providerDic.Count);
foreach (var provider in _providerDic.Values)
List<DebugProviderInfo> result = new List<DebugProviderInfo>(ProviderDic.Count);
foreach (var provider in ProviderDic.Values)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;

View File

@@ -318,9 +318,19 @@ namespace YooAsset
/// 强制回收所有资源
/// </summary>
public UnloadAllAssetsOperation UnloadAllAssetsAsync()
{
var options = new UnloadAllAssetsOptions();
return UnloadAllAssetsAsync(options);
}
/// <summary>
/// 强制回收所有资源
/// </summary>
/// <param name="options">卸载选项</param>
public UnloadAllAssetsOperation UnloadAllAssetsAsync(UnloadAllAssetsOptions options)
{
DebugCheckInitialize();
var operation = new UnloadAllAssetsOperation(_resourceManager);
var operation = new UnloadAllAssetsOperation(_resourceManager, options);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

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

View File

@@ -7,7 +7,7 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
{
private TiktokFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
@@ -84,7 +84,7 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
private void CreateWebRequest()
{
//TODO : 抖音小游戏没有找到预下载方法
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_requestURL);
_webRequest = UnityWebRequest.Get(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}

View File

@@ -3,16 +3,7 @@ using YooAsset;
internal partial class TTFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
RecordCacheFiles,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private RecordTiktokCacheFilesOperation _recordTiktokCacheFilesOp;
private ESteps _steps = ESteps.None;
public TTFSInitializeOperation(TiktokFileSystem fileSystem)
{
@@ -20,36 +11,10 @@ internal partial class TTFSInitializeOperation : FSInitializeFileSystemOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
if (_recordTiktokCacheFilesOp == null)
{
_recordTiktokCacheFilesOp = new RecordTiktokCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _recordTiktokCacheFilesOp);
}
if (_recordTiktokCacheFilesOp.IsDone == false)
return;
if (_recordTiktokCacheFilesOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _recordTiktokCacheFilesOp.Error;
}
}
}
}
#endif

View File

@@ -2,20 +2,19 @@
using UnityEngine;
using UnityEngine.Networking;
using YooAsset;
using TTSDK;
internal class TTFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundleFile,
DownloadAssetBundle,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private UnityWebRequest _webRequest;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
internal TTFSLoadBundleOperation(TiktokFileSystem fileSystem, PackageBundle bundle)
@@ -25,36 +24,47 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBundleFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundleFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_webRequest == null)
if (_downloadAssetBundleOp == null)
{
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
_webRequest = TTAssetBundle.GetAssetBundle(mainURL);
_webRequest.SendWebRequest();
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadTiktokAssetBundleOperation(_bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
if (_downloadAssetBundleOp.IsDone == false)
return;
if (CheckRequestResult())
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = (_webRequest.downloadHandler as DownloadHandlerTTAssetBundle).assetBundle;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = $"{nameof(DownloadHandlerTTAssetBundle)} loaded asset bundle is null !";
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
@@ -67,6 +77,7 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -82,31 +93,11 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
}
public override void AbortDownloadOperation()
{
}
private bool CheckRequestResult()
{
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
if (_steps == ESteps.DownloadAssetBundle)
{
Error = _webRequest.error;
return false;
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
else
{
return true;
}
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
{
Error = _webRequest.error;
return false;
}
else
{
return true;
}
#endif
}
}
#endif

View File

@@ -0,0 +1,127 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using TTSDK;
namespace YooAsset
{
internal class DownloadTiktokAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadTiktokAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 需要验证抖音插件请求器的下载进度
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerTTAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 需要验证抖音插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = TTAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

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

View File

@@ -1,57 +0,0 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using YooAsset;
using TTSDK;
internal class RecordTiktokCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RecordCacheFiles,
WaitResponse,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
public RecordTiktokCacheFilesOperation(TiktokFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
_steps = ESteps.WaitResponse;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var getSavedFileListParam = new GetSavedFileListParam();
getSavedFileListParam.success = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
foreach (var fileInfo in response.fileList)
{
//TODO 需要确认存储文件为Bundle文件
_fileSystem.RecordBundleFile(fileInfo.filePath);
}
};
getSavedFileListParam.fail = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = response.errMsg;
};
fileSystemMgr.GetSavedFileList(getSavedFileListParam);
}
}
}
#endif

View File

@@ -8,11 +8,20 @@ using System;
public static class TiktokFileSystemCreater
{
public static FileSystemParameters CreateByteGameFileSystemParameters(IRemoteServices remoteServices, string packageRoot)
public static FileSystemParameters CreateByteGameFileSystemParameters(string packageRoot, IRemoteServices remoteServices)
{
string fileSystemClass = $"{nameof(TiktokFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
return fileSystemParams;
}
public static FileSystemParameters CreateByteGameFileSystemParameters(string packageRoot, IRemoteServices remoteServices, IWebDecryptionServices decryptionServices)
{
string fileSystemClass = $"{nameof(TiktokFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams;
}
}
@@ -53,8 +62,7 @@ internal class TiktokFileSystem : IFileSystem
}
}
private readonly HashSet<string> _recorders = new HashSet<string>();
private readonly Dictionary<string, string> _cacheFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cacheFilePathMapping = new Dictionary<string, string>(10000);
private TTFileSystemManager _fileSystemMgr;
private string _ttCacheRoot = string.Empty;
@@ -81,7 +89,7 @@ internal class TiktokFileSystem : IFileSystem
{
get
{
return _recorders.Count;
return 0;
}
}
@@ -90,6 +98,11 @@ internal class TiktokFileSystem : IFileSystem
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -147,10 +160,14 @@ internal class TiktokFileSystem : IFileSystem
public virtual void SetParameter(string name, object value)
{
if (name == "REMOTE_SERVICES")
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
@@ -185,8 +202,7 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual bool Exists(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
return _recorders.Contains(filePath);
return CheckCacheFileExist(bundle);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -210,19 +226,27 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath);
}
else
{
return Array.Empty<byte>();
}
}
public virtual string ReadBundleFileText(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath, "utf8");
}
else
{
return string.Empty;
}
}
#region
@@ -230,55 +254,32 @@ internal class TiktokFileSystem : IFileSystem
{
return _fileSystemMgr;
}
public bool CheckCacheFileExist(string filePath)
public bool CheckCacheFileExist(PackageBundle bundle)
{
return _fileSystemMgr.AccessSync(filePath);
string url = RemoteServices.GetRemoteMainURL(bundle.FileName);
return _fileSystemMgr.IsUrlCached(url);
}
private string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = _fileSystemMgr.GetLocalCachedPathForUrl(bundle.FileName);
_cacheFilePaths.Add(bundle.BundleGUID, filePath);
_cacheFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
#region
public List<string> GetAllRecords()
/// <summary>
/// 加载加密资源文件
/// </summary>
public AssetBundle LoadEncryptedAssetBundle(PackageBundle bundle, byte[] fileData)
{
return _recorders.ToList();
}
public bool RecordBundleFile(string filePath)
{
if (_recorders.Contains(filePath))
{
YooLogger.Error($"{nameof(TiktokFileSystem)} has element : {filePath}");
return false;
}
_recorders.Add(filePath);
return true;
}
public void TryRecordBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (_recorders.Contains(filePath) == false)
{
_recorders.Add(filePath);
}
}
public void ClearAllRecords()
{
_recorders.Clear();
}
public void ClearRecord(string filePath)
{
if (_recorders.Contains(filePath))
{
_recorders.Remove(filePath);
}
WebDecryptFileInfo fileInfo = new WebDecryptFileInfo();
fileInfo.BundleName = bundle.BundleName;
fileInfo.FileLoadCRC = bundle.UnityCRC;
fileInfo.FileData = fileData;
var decryptResult = DecryptionServices.LoadAssetBundle(fileInfo);
return decryptResult.Result;
}
#endregion
}

View File

@@ -42,7 +42,6 @@ internal class WXFSClearAllBundleFilesOperation : FSClearCacheFilesOperation
YooLogger.Log("微信缓存清理成功!");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
_fileSystem.ClearAllRecords();
}
else
{

View File

@@ -4,6 +4,7 @@ using System.IO;
using UnityEngine;
using YooAsset;
using WeChatWASM;
using static UnityEngine.Networking.UnityWebRequest;
internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
@@ -11,6 +12,7 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
None,
GetUnusedCacheFiles,
WaitingSearch,
ClearUnusedCacheFiles,
Done,
}
@@ -37,20 +39,46 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
if (_steps == ESteps.GetUnusedCacheFiles)
{
_unusedCacheFiles = GetUnusedCacheFiles();
_unusedFileTotalCount = _unusedCacheFiles.Count;
_steps = ESteps.ClearUnusedCacheFiles;
YooLogger.Log($"Found unused cache files count : {_unusedFileTotalCount}");
_steps = ESteps.WaitingSearch;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var statOption = new WXStatOption();
statOption.path = _fileSystem.FileRoot;
statOption.recursive = true;
statOption.success = (WXStatResponse response) =>
{
foreach (var fileStat in response.stats)
{
// 注意存储文件必须按照Bundle文件哈希值存储
string bundleGUID = Path.GetFileNameWithoutExtension(fileStat.path);
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false)
{
string fullPath = WX.GetCachePath(fileStat.path);
if (_unusedCacheFiles.Contains(fullPath) == false)
_unusedCacheFiles.Add(fullPath);
}
}
_steps = ESteps.ClearUnusedCacheFiles;
_unusedFileTotalCount = _unusedCacheFiles.Count;
YooLogger.Log($"Found unused cache files count : {_unusedFileTotalCount}");
};
statOption.fail = (WXStatResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = response.errMsg;
};
fileSystemMgr.Stat(statOption);
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
for (int i = _unusedCacheFiles.Count - 1; i >= 0; i--)
{
string clearFilePath = _unusedCacheFiles[i];
string filePath = _unusedCacheFiles[i];
_unusedCacheFiles.RemoveAt(i);
_fileSystem.ClearRecord(clearFilePath);
WX.RemoveFile(clearFilePath, null);
WX.RemoveFile(filePath, null);
if (OperationSystem.IsBusy)
break;
@@ -68,30 +96,5 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
}
}
}
private List<string> GetUnusedCacheFiles()
{
var allRecords = _fileSystem.GetAllRecords();
List<string> result = new List<string>(allRecords.Count);
foreach (var filePath in allRecords)
{
// 如果存储文件名是按照Bundle文件哈希值存储
string bundleGUID = Path.GetFileNameWithoutExtension(filePath);
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false)
{
result.Add(filePath);
}
// 如果存储文件名是按照Bundle文件名称存储
/*
string bundleName = Path.GetFileNameWithoutExtension(filePath);
if (_manifest.TryGetPackageBundleByBundleName(bundleName, out PackageBundle value) == false)
{
result.Add(filePath);
}
*/
}
return result;
}
}
#endif

View File

@@ -42,7 +42,9 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return;
}
@@ -51,7 +53,12 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
_fileSystem.TryRecordBundle(Bundle); //记录下载文件
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
else
{
@@ -85,7 +92,7 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest = UnityWebRequest.Get(_requestURL);
_webRequest.SetRequestHeader("wechatminigame-preload", "1");
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();

View File

@@ -3,16 +3,7 @@ using YooAsset;
internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
RecordCacheFiles,
Done,
}
private readonly WechatFileSystem _fileSystem;
private RecordWechatCacheFilesOperation _recordWechatCacheFilesOp;
private ESteps _steps = ESteps.None;
public WXFSInitializeOperation(WechatFileSystem fileSystem)
{
@@ -20,36 +11,10 @@ internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
if (_recordWechatCacheFilesOp == null)
{
_recordWechatCacheFilesOp = new RecordWechatCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _recordWechatCacheFilesOp);
}
if (_recordWechatCacheFilesOp.IsDone == false)
return;
if (_recordWechatCacheFilesOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _recordWechatCacheFilesOp.Error;
}
}
}
}
#endif

View File

@@ -1,21 +1,18 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using YooAsset;
using WeChatWASM;
internal class WXFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundleFile,
DownloadAssetBundle,
Done,
}
private readonly WechatFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private UnityWebRequest _webRequest;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
internal WXFSLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle)
@@ -25,49 +22,60 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBundleFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundleFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_webRequest == null)
if (_downloadAssetBundleOp == null)
{
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
_webRequest = WXAssetBundle.GetAssetBundle(mainURL);
_webRequest.SendWebRequest();
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWechatAssetBundleOperation(_bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
if (_downloadAssetBundleOp.IsDone == false)
return;
if (CheckRequestResult())
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = (_webRequest.downloadHandler as DownloadHandlerWXAssetBundle).assetBundle;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = $"{nameof(DownloadHandlerWXAssetBundle)} loaded asset bundle is null !";
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
_steps = ESteps.Done;
Result = new WXAssetBundleResult(_fileSystem, _bundle, assetBundle);
Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null);
Status = EOperationStatus.Succeed;
_fileSystem.TryRecordBundle(_bundle); //记录下载文件
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -83,31 +91,11 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
}
public override void AbortDownloadOperation()
{
}
private bool CheckRequestResult()
{
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
if (_steps == ESteps.DownloadAssetBundle)
{
Error = _webRequest.error;
return false;
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
else
{
return true;
}
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
{
Error = _webRequest.error;
return false;
}
else
{
return true;
}
#endif
}
}
#endif

View File

@@ -0,0 +1,129 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using WeChatWASM;
namespace YooAsset
{
internal class DownloadWechatAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadWechatAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerWXAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

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

View File

@@ -1,58 +0,0 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using YooAsset;
using WeChatWASM;
using System.IO;
internal class RecordWechatCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RecordCacheFiles,
WaitResponse,
Done,
}
private readonly WechatFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
public RecordWechatCacheFilesOperation(WechatFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
_steps = ESteps.WaitResponse;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var getSavedFileListOption = new GetSavedFileListOption();
getSavedFileListOption.success = (GetSavedFileListSuccessCallbackResult response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
foreach (var fileInfo in response.fileList)
{
//TODO 需要确认存储文件为Bundle文件
_fileSystem.RecordBundleFile(fileInfo.filePath);
}
};
getSavedFileListOption.fail = (FileError fileError) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = fileError.errMsg;
};
fileSystemMgr.GetSavedFileList(getSavedFileListOption);
}
}
}
#endif

View File

@@ -8,11 +8,19 @@ using WeChatWASM;
public static class WechatFileSystemCreater
{
public static FileSystemParameters CreateWechatFileSystemParameters(IRemoteServices remoteServices, string packageRoot)
public static FileSystemParameters CreateWechatFileSystemParameters(string packageRoot, IRemoteServices remoteServices)
{
string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
return fileSystemParams;
}
public static FileSystemParameters CreateWechatFileSystemParameters(string packageRoot, IRemoteServices remoteServices, IWebDecryptionServices decryptionServices)
{
string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams;
}
}
@@ -53,8 +61,7 @@ internal class WechatFileSystem : IFileSystem
}
}
private readonly HashSet<string> _recorders = new HashSet<string>();
private readonly Dictionary<string, string> _cacheFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cacheFilePathMapping = new Dictionary<string, string>(10000);
private WXFileSystemManager _fileSystemMgr;
private string _wxCacheRoot = string.Empty;
@@ -63,6 +70,8 @@ internal class WechatFileSystem : IFileSystem
/// </summary>
public string PackageName { private set; get; }
private readonly string _packageRoot = YooAssetSettingsData.Setting.DefaultYooFolderName;
/// <summary>
/// 文件根目录
/// </summary>
@@ -81,7 +90,7 @@ internal class WechatFileSystem : IFileSystem
{
get
{
return _recorders.Count;
return 0;
}
}
@@ -90,6 +99,11 @@ internal class WechatFileSystem : IFileSystem
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -163,25 +177,34 @@ internal class WechatFileSystem : IFileSystem
public virtual void SetParameter(string name, object value)
{
if (name == "REMOTE_SERVICES")
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
_wxCacheRoot = rootDirectory;
_wxCacheRoot = packageRoot;
if (string.IsNullOrEmpty(_wxCacheRoot))
{
throw new System.Exception("请配置微信小游戏缓存根目录!");
}
if (_wxCacheRoot.StartsWith(WX.PluginCachePath) == false)
{
_wxCacheRoot = PathUtility.Combine(WX.PluginCachePath, _wxCacheRoot);
}
// 注意CDN服务未启用的情况下使用微信WEB服务器
if (RemoteServices == null)
{
@@ -202,7 +225,7 @@ internal class WechatFileSystem : IFileSystem
public virtual bool Exists(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
return _recorders.Contains(filePath);
return CheckCacheFileExist(filePath);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -248,54 +271,33 @@ internal class WechatFileSystem : IFileSystem
}
public bool CheckCacheFileExist(string filePath)
{
string result = _fileSystemMgr.AccessSync(filePath);
return result.Equals("access:ok");
string result = WX.GetCachePath(filePath);
if (string.IsNullOrEmpty(result))
return false;
else
return true;
}
public string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_wxCacheRoot, bundle.FileName);
_cacheFilePaths.Add(bundle.BundleGUID, filePath);
_cacheFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
#region
public List<string> GetAllRecords()
/// <summary>
/// 加载加密资源文件
/// </summary>
public AssetBundle LoadEncryptedAssetBundle(PackageBundle bundle, byte[] fileData)
{
return _recorders.ToList();
}
public bool RecordBundleFile(string filePath)
{
if (_recorders.Contains(filePath))
{
YooLogger.Error($"{nameof(WechatFileSystem)} has element : {filePath}");
return false;
}
_recorders.Add(filePath);
return true;
}
public void TryRecordBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (_recorders.Contains(filePath) == false)
{
_recorders.Add(filePath);
}
}
public void ClearAllRecords()
{
_recorders.Clear();
}
public void ClearRecord(string filePath)
{
if (_recorders.Contains(filePath))
{
_recorders.Remove(filePath);
}
WebDecryptFileInfo fileInfo = new WebDecryptFileInfo();
fileInfo.BundleName = bundle.BundleName;
fileInfo.FileLoadCRC = bundle.UnityCRC;
fileInfo.FileData = fileData;
var decryptResult = DecryptionServices.LoadAssetBundle(fileInfo);
return decryptResult.Result;
}
#endregion
}

View File

@@ -1,14 +1,12 @@
using System.Collections;
#if UNITY_2019_4_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using YooAsset.Editor;
#if UNITY_2019_4_OR_NEWER
using UnityEditor.UIElements;
using UnityEngine.UIElements;
#endif
[CreateAssetMenu(fileName = "TextureSchema", menuName = "YooAssetArt/Create TextureSchema")]
public class TextureSchema : ScannerSchema
@@ -37,9 +35,9 @@ public class TextureSchema : ScannerSchema
public override ScanReport RunScanner(AssetArtScanner scanner)
{
// 创建扫描报告
string title = "扫描所有纹理资产";
string name = "扫描所有纹理资产";
string desc = GetUserGuide();
var report = new ScanReport(title, desc);
var report = new ScanReport(name, desc);
report.AddHeader("资源路径", 600, 500, 1000).SetStretchable().SetSearchable().SetSortable().SetHeaderType(EHeaderType.AssetPath);
report.AddHeader("图片宽度", 100).SetSortable().SetHeaderType(EHeaderType.LongValue);
report.AddHeader("图片高度", 100).SetSortable().SetHeaderType(EHeaderType.LongValue);
@@ -105,9 +103,9 @@ public class TextureSchema : ScannerSchema
// 添加扫描信息
ReportElement result = new ReportElement(assetGUID);
result.AddScanInfo("资源路径", assetPath);
result.AddScanInfo("图片宽度", texture.width.ToString());
result.AddScanInfo("图片高度", texture.height.ToString());
result.AddScanInfo("内存大小", memorySize.ToString());
result.AddScanInfo("图片宽度", texture.width);
result.AddScanInfo("图片高度", texture.height);
result.AddScanInfo("内存大小", memorySize);
result.AddScanInfo("苹果格式", iosFormat.ToString());
result.AddScanInfo("安卓格式", androidFormat.ToString());
result.AddScanInfo("错误信息", errorInfo);
@@ -157,7 +155,6 @@ public class TextureSchema : ScannerSchema
/// </summary>
public override SchemaInspector CreateInspector()
{
#if UNITY_2019_4_OR_NEWER
var container = new VisualElement();
// 图片最大宽度
@@ -180,11 +177,8 @@ public class TextureSchema : ScannerSchema
});
container.Add(maxHeightField);
SchemaInspector inspector = new SchemaInspector();
inspector.Containner = container;
SchemaInspector inspector = new SchemaInspector(container);
return inspector;
#else
return null;
#endif
}
}
}
#endif

View File

@@ -74,10 +74,11 @@ internal class FsmInitializePackage : IStateNode
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
string defaultHostServer = GetHostServerURL();
string fallbackHostServer = GetHostServerURL();
string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE"; //注意:如果有子目录,请修改此处!
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateWechatFileSystemParameters(remoteServices);
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateWechatFileSystemParameters(packageRoot, remoteServices);
#else
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(new WebDecryption());
#endif
initializationOperation = package.InitializeAsync(createParameters);
}
@@ -148,4 +149,24 @@ internal class FsmInitializePackage : IStateNode
return $"{_fallbackHostServer}/{fileName}";
}
}
private class WebDecryption : IWebDecryptionServices
{
public const byte KEY = 64;
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
{
byte[] copyData = new byte[fileInfo.FileData.Length];
Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length);
for (int i = 0; i < copyData.Length; i++)
{
copyData[i] ^= KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(copyData);
return decryptResult;
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Text;
using UnityEngine;
using YooAsset;
#region
/// <summary>
/// 资源文件解密流
/// </summary>
@@ -29,6 +30,35 @@ public class BundleStream : FileStream
}
}
/// <summary>
/// 文件流加密方式
/// </summary>
public class FileStreamEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件流加载解密类
/// </summary>
@@ -81,6 +111,37 @@ public class FileStreamDecryption : IDecryptionServices
return 1024;
}
}
#endregion
#region
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class FileOffsetEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 注意:只对音频资源包加密
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件偏移加载解密类
@@ -132,61 +193,4 @@ public class FileOffsetDecryption : IDecryptionServices
return 32;
}
}
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class FileOffsetEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 注意:只对音频资源包加密
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 文件流加密方式
/// </summary>
public class FileStreamEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
#endregion

View File

@@ -1,7 +1,7 @@
{
"name": "com.tuyoogame.yooasset",
"displayName": "YooAsset",
"version": "2.2.11",
"version": "2.2.12",
"unity": "2019.4",
"description": "unity3d resources management system.",
"author": {