123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- namespace YooAsset
- {
- internal class DeserializeManifestOperation : AsyncOperationBase
- {
- private enum ESteps
- {
- None,
- DeserializeFileHeader,
- PrepareAssetList,
- DeserializeAssetList,
- PrepareBundleList,
- DeserializeBundleList,
- Done,
- }
- private readonly BufferReader _buffer;
- private int _packageAssetCount;
- private int _packageBundleCount;
- private int _progressTotalValue;
- private ESteps _steps = ESteps.None;
- /// <summary>
- /// 解析的清单实例
- /// </summary>
- public PackageManifest Manifest { private set; get; }
- public DeserializeManifestOperation(byte[] binaryData)
- {
- _buffer = new BufferReader(binaryData);
- }
- internal override void Start()
- {
- _steps = ESteps.DeserializeFileHeader;
- }
- internal override void Update()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
- try
- {
- if (_steps == ESteps.DeserializeFileHeader)
- {
- if (_buffer.IsValid == false)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = "Buffer is invalid !";
- return;
- }
- // 读取文件标记
- uint fileSign = _buffer.ReadUInt32();
- if (fileSign != YooAssetSettings.ManifestFileSign)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = "The manifest file format is invalid !";
- return;
- }
- // 读取文件版本
- string fileVersion = _buffer.ReadUTF8();
- if (fileVersion != YooAssetSettings.ManifestFileVersion)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}";
- return;
- }
- // 读取文件头信息
- Manifest = new PackageManifest();
- Manifest.FileVersion = fileVersion;
- Manifest.EnableAddressable = _buffer.ReadBool();
- Manifest.LocationToLower = _buffer.ReadBool();
- Manifest.IncludeAssetGUID = _buffer.ReadBool();
- Manifest.OutputNameStyle = _buffer.ReadInt32();
- Manifest.PackageName = _buffer.ReadUTF8();
- Manifest.PackageVersion = _buffer.ReadUTF8();
- // 检测配置
- if (Manifest.EnableAddressable && Manifest.LocationToLower)
- throw new System.Exception("Addressable not support location to lower !");
- _steps = ESteps.PrepareAssetList;
- }
- if (_steps == ESteps.PrepareAssetList)
- {
- _packageAssetCount = _buffer.ReadInt32();
- Manifest.AssetList = new List<PackageAsset>(_packageAssetCount);
- Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount);
- if (Manifest.EnableAddressable)
- Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount);
- else
- Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 2);
- if (Manifest.IncludeAssetGUID)
- Manifest.AssetPathMapping2 = new Dictionary<string, string>(_packageAssetCount);
- else
- Manifest.AssetPathMapping2 = new Dictionary<string, string>();
- _progressTotalValue = _packageAssetCount;
- _steps = ESteps.DeserializeAssetList;
- }
- if (_steps == ESteps.DeserializeAssetList)
- {
- while (_packageAssetCount > 0)
- {
- var packageAsset = new PackageAsset();
- packageAsset.Address = _buffer.ReadUTF8();
- packageAsset.AssetPath = _buffer.ReadUTF8();
- packageAsset.AssetGUID = _buffer.ReadUTF8();
- packageAsset.AssetTags = _buffer.ReadUTF8Array();
- packageAsset.BundleID = _buffer.ReadInt32();
- packageAsset.DependIDs = _buffer.ReadInt32Array();
- Manifest.AssetList.Add(packageAsset);
- // 注意:我们不允许原始路径存在重名
- string assetPath = packageAsset.AssetPath;
- if (Manifest.AssetDic.ContainsKey(assetPath))
- throw new System.Exception($"AssetPath have existed : {assetPath}");
- else
- Manifest.AssetDic.Add(assetPath, packageAsset);
- // 填充AssetPathMapping1
- if (Manifest.EnableAddressable)
- {
- string location = packageAsset.Address;
- if (Manifest.AssetPathMapping1.ContainsKey(location))
- throw new System.Exception($"Address have existed : {location}");
- else
- Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
- }
- else
- {
- string location = packageAsset.AssetPath;
- if (Manifest.LocationToLower)
- location = location.ToLower();
- // 添加原生路径的映射
- if (Manifest.AssetPathMapping1.ContainsKey(location))
- throw new System.Exception($"AssetPath have existed : {location}");
- else
- Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
- // 添加无后缀名路径的映射
- //if (Path.HasExtension(location))
- //{
- // string locationWithoutExtension = PathUtility.RemoveExtension(location);
- // if (Manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
- // YooLogger.Warning($"AssetPath have existed : {locationWithoutExtension}");
- // else
- // Manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
- //}
- }
- // 填充AssetPathMapping2
- if (Manifest.IncludeAssetGUID)
- {
- if (Manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
- throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
- else
- Manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
- }
- _packageAssetCount--;
- Progress = 1f - _packageAssetCount / _progressTotalValue;
- if (OperationSystem.IsBusy)
- break;
- }
- if (_packageAssetCount <= 0)
- {
- _steps = ESteps.PrepareBundleList;
- }
- }
- if (_steps == ESteps.PrepareBundleList)
- {
- _packageBundleCount = _buffer.ReadInt32();
- Manifest.BundleList = new List<PackageBundle>(_packageBundleCount);
- Manifest.BundleDic = new Dictionary<string, PackageBundle>(_packageBundleCount);
- _progressTotalValue = _packageBundleCount;
- _steps = ESteps.DeserializeBundleList;
- }
- if (_steps == ESteps.DeserializeBundleList)
- {
- while (_packageBundleCount > 0)
- {
- var packageBundle = new PackageBundle();
- packageBundle.BundleName = _buffer.ReadUTF8();
- packageBundle.FileHash = _buffer.ReadUTF8();
- packageBundle.FileCRC = _buffer.ReadUTF8();
- packageBundle.FileSize = _buffer.ReadInt64();
- packageBundle.IsRawFile = _buffer.ReadBool();
- packageBundle.LoadMethod = _buffer.ReadByte();
- packageBundle.Tags = _buffer.ReadUTF8Array();
- packageBundle.ReferenceIDs = _buffer.ReadInt32Array();
- Manifest.BundleList.Add(packageBundle);
- packageBundle.ParseBundle(Manifest.PackageName, Manifest.OutputNameStyle);
- Manifest.BundleDic.Add(packageBundle.BundleName, packageBundle);
- _packageBundleCount--;
- Progress = 1f - _packageBundleCount / _progressTotalValue;
- if (OperationSystem.IsBusy)
- break;
- }
- if (_packageBundleCount <= 0)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- }
- }
- catch (System.Exception e)
- {
- Manifest = null;
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = e.Message;
- }
- }
- }
- }
|