using System; using System.Collections; using System.Collections.Generic; using System.IO; namespace YooAsset { internal class HostPlayModeImpl : IBundleServices { // 补丁清单 internal PatchManifest LocalPatchManifest { private set; get; } // 参数相关 private bool _locationToLower; private string _defaultHostServer; private string _fallbackHostServer; private IQueryServices _queryServices; /// /// 异步初始化 /// public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices) { _locationToLower = locationToLower; _defaultHostServer = defaultHostServer; _fallbackHostServer = fallbackHostServer; _queryServices = queryServices; var operation = new HostPlayModeInitializationOperation(); OperationSystem.StartOperation(operation); return operation; } /// /// 异步更新资源版本号 /// public UpdateStaticVersionOperation UpdateStaticVersionAsync(string packageName, int timeout) { var operation = new HostPlayModeUpdateStaticVersionOperation(this, packageName, timeout); OperationSystem.StartOperation(operation); return operation; } /// /// 异步更新补丁清单 /// public UpdateManifestOperation UpdatePatchManifestAsync(string packageName, string packageCRC, int timeout) { var operation = new HostPlayModeUpdateManifestOperation(this, packageName, packageCRC, timeout); OperationSystem.StartOperation(operation); return operation; } /// /// 异步更新补丁清单(弱联网) /// public UpdateManifestOperation WeaklyUpdatePatchManifestAsync(string packageName, string packageCRC) { var operation = new HostPlayModeWeaklyUpdateManifestOperation(this, packageName, packageCRC); OperationSystem.StartOperation(operation); return operation; } /// /// 异步更新资源包裹 /// public UpdatePackageOperation UpdatePackageAsync(string packageName, string packageCRC, int timeout) { var operation = new HostPlayModeUpdatePackageOperation(this, packageName, packageCRC, timeout); OperationSystem.StartOperation(operation); return operation; } /// /// 创建下载器 /// public PatchDownloaderOperation CreatePatchDownloaderByAll(int fileLoadingMaxNumber, int failedTryAgain) { List downloadList = GetDownloadListByAll(); var operation = new PatchDownloaderOperation(downloadList, fileLoadingMaxNumber, failedTryAgain); return operation; } private List GetDownloadListByAll() { List downloadList = new List(1000); foreach (var patchBundle in LocalPatchManifest.BundleList) { // 忽略缓存文件 if (CacheSystem.IsCached(patchBundle)) continue; // 忽略APP资源 if (IsBuildinPatchBundle(patchBundle)) continue; downloadList.Add(patchBundle); } return ConvertToDownloadList(downloadList); } /// /// 创建下载器 /// public PatchDownloaderOperation CreatePatchDownloaderByTags(string[] tags, int fileLoadingMaxNumber, int failedTryAgain) { List downloadList = GetDownloadListByTags(tags); var operation = new PatchDownloaderOperation(downloadList, fileLoadingMaxNumber, failedTryAgain); return operation; } private List GetDownloadListByTags(string[] tags) { List downloadList = new List(1000); foreach (var patchBundle in LocalPatchManifest.BundleList) { // 忽略缓存文件 if (CacheSystem.IsCached(patchBundle)) continue; // 忽略APP资源 if (IsBuildinPatchBundle(patchBundle)) continue; // 如果未带任何标记,则统一下载 if (patchBundle.HasAnyTags() == false) { downloadList.Add(patchBundle); } else { // 查询DLC资源 if (patchBundle.HasTag(tags)) { downloadList.Add(patchBundle); } } } return ConvertToDownloadList(downloadList); } /// /// 创建下载器 /// public PatchDownloaderOperation CreatePatchDownloaderByPaths(AssetInfo[] assetInfos, int fileLoadingMaxNumber, int failedTryAgain) { List downloadList = GetDownloadListByPaths(assetInfos); var operation = new PatchDownloaderOperation(downloadList, fileLoadingMaxNumber, failedTryAgain); return operation; } private List GetDownloadListByPaths(AssetInfo[] assetInfos) { // 获取资源对象的资源包和所有依赖资源包 List checkList = new List(); foreach (var assetInfo in assetInfos) { if (assetInfo.IsInvalid) { YooLogger.Warning(assetInfo.Error); continue; } // 注意:如果补丁清单里未找到资源包会抛出异常! PatchBundle mainBundle = LocalPatchManifest.GetMainPatchBundle(assetInfo.AssetPath); if (checkList.Contains(mainBundle) == false) checkList.Add(mainBundle); // 注意:如果补丁清单里未找到资源包会抛出异常! PatchBundle[] dependBundles = LocalPatchManifest.GetAllDependencies(assetInfo.AssetPath); foreach (var dependBundle in dependBundles) { if (checkList.Contains(dependBundle) == false) checkList.Add(dependBundle); } } List downloadList = new List(1000); foreach (var patchBundle in checkList) { // 忽略缓存文件 if (CacheSystem.IsCached(patchBundle)) continue; // 忽略APP资源 if (IsBuildinPatchBundle(patchBundle)) continue; downloadList.Add(patchBundle); } return ConvertToDownloadList(downloadList); } /// /// 创建解压器 /// public PatchUnpackerOperation CreatePatchUnpackerByTags(string[] tags, int fileUpackingMaxNumber, int failedTryAgain) { List unpcakList = GetUnpackListByTags(tags); var operation = new PatchUnpackerOperation(unpcakList, fileUpackingMaxNumber, failedTryAgain); return operation; } private List GetUnpackListByTags(string[] tags) { List downloadList = new List(1000); foreach (var patchBundle in LocalPatchManifest.BundleList) { // 忽略缓存文件 if (CacheSystem.IsCached(patchBundle)) continue; // 查询DLC资源 if (IsBuildinPatchBundle(patchBundle)) { if (patchBundle.HasTag(tags)) { downloadList.Add(patchBundle); } } } return PatchHelper.ConvertToUnpackList(downloadList); } /// /// 创建解压器 /// public PatchUnpackerOperation CreatePatchUnpackerByAll(int fileUpackingMaxNumber, int failedTryAgain) { List unpcakList = GetUnpackListByAll(); var operation = new PatchUnpackerOperation(unpcakList, fileUpackingMaxNumber, failedTryAgain); return operation; } private List GetUnpackListByAll() { List downloadList = new List(1000); foreach (var patchBundle in LocalPatchManifest.BundleList) { // 忽略缓存文件 if (CacheSystem.IsCached(patchBundle)) continue; if (IsBuildinPatchBundle(patchBundle)) { downloadList.Add(patchBundle); } } return PatchHelper.ConvertToUnpackList(downloadList); } // WEB相关 public string GetPatchDownloadMainURL(string fileName) { return $"{_defaultHostServer}/{fileName}"; } public string GetPatchDownloadFallbackURL(string fileName) { return $"{_fallbackHostServer}/{fileName}"; } // 下载相关 public List ConvertToDownloadList(List downloadList) { List result = new List(downloadList.Count); foreach (var patchBundle in downloadList) { var bundleInfo = ConvertToDownloadInfo(patchBundle); result.Add(bundleInfo); } return result; } public BundleInfo ConvertToDownloadInfo(PatchBundle patchBundle) { string remoteMainURL = GetPatchDownloadMainURL(patchBundle.FileName); string remoteFallbackURL = GetPatchDownloadFallbackURL(patchBundle.FileName); BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL); return bundleInfo; } internal void SetLocalPatchManifest(PatchManifest patchManifest) { LocalPatchManifest = patchManifest; LocalPatchManifest.InitAssetPathMapping(_locationToLower); } internal bool IsBuildinPatchBundle(PatchBundle patchBundle) { return _queryServices.QueryStreamingAssets(patchBundle.FileName); } #region IBundleServices接口 private BundleInfo CreateBundleInfo(PatchBundle patchBundle) { if (patchBundle == null) throw new Exception("Should never get here !"); // 查询沙盒资源 if (CacheSystem.IsCached(patchBundle)) { BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache); return bundleInfo; } // 查询APP资源 if (IsBuildinPatchBundle(patchBundle)) { BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming); return bundleInfo; } // 从服务端下载 return ConvertToDownloadInfo(patchBundle); } BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) { if (assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果补丁清单里未找到资源包会抛出异常! var patchBundle = LocalPatchManifest.GetMainPatchBundle(assetInfo.AssetPath); return CreateBundleInfo(patchBundle); } BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo) { if (assetInfo.IsInvalid) throw new Exception("Should never get here !"); // 注意:如果补丁清单里未找到资源包会抛出异常! var depends = LocalPatchManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var patchBundle in depends) { BundleInfo bundleInfo = CreateBundleInfo(patchBundle); result.Add(bundleInfo); } return result.ToArray(); } AssetInfo[] IBundleServices.GetAssetInfos(string[] tags) { return PatchHelper.GetAssetsInfoByTags(LocalPatchManifest, tags); } PatchAsset IBundleServices.TryGetPatchAsset(string assetPath) { if (LocalPatchManifest.TryGetPatchAsset(assetPath, out PatchAsset patchAsset)) return patchAsset; else return null; } string IBundleServices.MappingToAssetPath(string location) { return LocalPatchManifest.MappingToAssetPath(location); } string IBundleServices.GetPackageName() { return LocalPatchManifest.PackageName; } #endregion } }