| 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;			}		}	}}
 |