using System; using System.Collections; using System.Collections.Generic; namespace YooAsset { internal class PlayModeImpl : IPlayMode, IBundleQuery { public readonly string PackageName; public readonly EPlayMode PlayMode; public readonly List FileSystems = new List(10); public PlayModeImpl(string packageName, EPlayMode playMode) { PackageName = packageName; PlayMode = playMode; } /// /// 异步初始化 /// public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameter) { var fileSystemParamList = new List(); if (fileSystemParameter != null) fileSystemParamList.Add(fileSystemParameter); return InitializeAsync(fileSystemParamList); } /// /// 异步初始化 /// public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB) { var fileSystemParamList = new List(); if (fileSystemParameterA != null) fileSystemParamList.Add(fileSystemParameterA); if (fileSystemParameterB != null) fileSystemParamList.Add(fileSystemParameterB); return InitializeAsync(fileSystemParamList); } /// /// 异步初始化 /// public InitializationOperation InitializeAsync(List fileSystemParameterList) { var operation = new InitializationOperation(this, fileSystemParameterList); return operation; } #region IPlayMode接口 /// /// 当前激活的清单 /// public PackageManifest ActiveManifest { set; get; } /// /// 销毁文件系统 /// void IPlayMode.DestroyFileSystem() { foreach (var fileSystem in FileSystems) { fileSystem.OnDestroy(); } FileSystems.Clear(); } /// /// 向网络端请求最新的资源版本 /// RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) { var operation = new RequestPackageVersionImplOperation(this, appendTimeTicks, timeout); return operation; } /// /// 向网络端请求并更新清单 /// UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) { var operation = new UpdatePackageManifestOperation(this, packageVersion, timeout); return operation; } /// /// 预下载指定版本的包裹内容 /// PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout) { var operation = new PreDownloadContentOperation(this, packageVersion, timeout); return operation; } /// /// 清理缓存文件 /// ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(ClearCacheFilesOptions options) { var operation = new ClearCacheFilesOperation(this, options); return operation; } // 下载相关 ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { List downloadList = GetDownloadListByAll(ActiveManifest); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) { List downloadList = GetDownloadListByTags(ActiveManifest, tags); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout) { List downloadList = GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } // 解压相关 ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) { List unpcakList = GetUnpackListByAll(ActiveManifest); var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) { List unpcakList = GetUnpackListByTags(ActiveManifest, tags); var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } // 导入相关 ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout) { List importerList = GetImporterListByFilePaths(ActiveManifest, filePaths); var operation = new ResourceImporterOperation(PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); return operation; } #endregion #region IBundleQuery接口 private BundleInfo CreateBundleInfo(PackageBundle packageBundle) { if (packageBundle == null) throw new Exception("Should never get here !"); var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem != null) { BundleInfo bundleInfo = new BundleInfo(fileSystem, packageBundle); return bundleInfo; } throw new Exception($"Can not found belong file system : {packageBundle.BundleName}"); } BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); return CreateBundleInfo(packageBundle); } BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! PackageBundle[] depends; if (assetInfo.LoadMethod == AssetInfo.ELoadMethod.LoadAllAssets) { var mainBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); depends = ActiveManifest.GetAllDependencies(mainBundle); } else { depends = ActiveManifest.GetAllDependencies(assetInfo.Asset); } List result = new List(depends.Length); foreach (var packageBundle in depends) { BundleInfo bundleInfo = CreateBundleInfo(packageBundle); result.Add(bundleInfo); } return result.ToArray(); } string IBundleQuery.GetMainBundleName(int bundleID) { // 注意:如果清单里未找到资源包会抛出异常! var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID); return packageBundle.BundleName; } string IBundleQuery.GetMainBundleName(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); return packageBundle.BundleName; } string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! var depends = ActiveManifest.GetAllDependencies(assetInfo.Asset); List result = new List(depends.Length); foreach (var packageBundle in depends) { result.Add(packageBundle.BundleName); } return result.ToArray(); } #endregion /// /// 获取主文件系统 /// 说明:文件系统列表里,最后一个属于主文件系统 /// public IFileSystem GetMainFileSystem() { int count = FileSystems.Count; if (count == 0) return null; return FileSystems[count - 1]; } /// /// 获取资源包所属文件系统 /// public IFileSystem GetBelongFileSystem(PackageBundle packageBundle) { for (int i = 0; i < FileSystems.Count; i++) { IFileSystem fileSystem = FileSystems[i]; if (fileSystem.Belong(packageBundle)) { return fileSystem; } } YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); return null; } public List GetDownloadListByAll(PackageManifest manifest) { if (manifest == null) return new List(); List result = new List(1000); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedDownload(packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } } return result; } public List GetDownloadListByTags(PackageManifest manifest, string[] tags) { if (manifest == null) return new List(); List result = new List(1000); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedDownload(packageBundle)) { // 如果未带任何标记,则统一下载 if (packageBundle.HasAnyTags() == false) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } else { // 查询DLC资源 if (packageBundle.HasTag(tags)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } } } } return result; } public List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload) { if (manifest == null) return new List(); // 获取资源对象的资源包和所有依赖资源包 List checkList = new List(); foreach (var assetInfo in assetInfos) { if (assetInfo.IsInvalid) { YooLogger.Warning(assetInfo.Error); continue; } // 注意:如果清单里未找到资源包会抛出异常! PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.Asset); if (checkList.Contains(mainBundle) == false) checkList.Add(mainBundle); // 注意:如果清单里未找到资源包会抛出异常! PackageBundle[] mainDependBundles = manifest.GetAllDependencies(assetInfo.Asset); foreach (var dependBundle in mainDependBundles) { if (checkList.Contains(dependBundle) == false) checkList.Add(dependBundle); } // 下载主资源包内所有资源对象依赖的资源包 if (recursiveDownload) { foreach (var otherMainAsset in mainBundle.IncludeMainAssets) { var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID); if (checkList.Contains(otherMainBundle) == false) checkList.Add(otherMainBundle); PackageBundle[] otherDependBundles = manifest.GetAllDependencies(otherMainAsset); foreach (var dependBundle in otherDependBundles) { if (checkList.Contains(dependBundle) == false) checkList.Add(dependBundle); } } } } List result = new List(1000); foreach (var packageBundle in checkList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedDownload(packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } } return result; } public List GetUnpackListByAll(PackageManifest manifest) { if (manifest == null) return new List(); List result = new List(1000); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedUnpack(packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } } return result; } public List GetUnpackListByTags(PackageManifest manifest, string[] tags) { if (manifest == null) return new List(); List result = new List(1000); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedUnpack(packageBundle)) { if (packageBundle.HasTag(tags)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); } } } return result; } public List GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths) { if (manifest == null) return new List(); List result = new List(); foreach (var filePath in filePaths) { string fileName = System.IO.Path.GetFileName(filePath); if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle)) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; if (fileSystem.NeedImport(packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle, filePath); result.Add(bundleInfo); } } else { YooLogger.Warning($"Not found package bundle, importer file path : {filePath}"); } } return result; } } }