ManifestTools.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. namespace YooAsset
  7. {
  8. internal static class ManifestTools
  9. {
  10. #if UNITY_EDITOR
  11. /// <summary>
  12. /// 序列化(JSON文件)
  13. /// </summary>
  14. public static void SerializeToJson(string savePath, PackageManifest manifest)
  15. {
  16. string json = JsonUtility.ToJson(manifest, true);
  17. FileUtility.WriteAllText(savePath, json);
  18. }
  19. /// <summary>
  20. /// 序列化(二进制文件)
  21. /// </summary>
  22. public static void SerializeToBinary(string savePath, PackageManifest manifest)
  23. {
  24. using (FileStream fs = new FileStream(savePath, FileMode.Create))
  25. {
  26. // 创建缓存器
  27. BufferWriter buffer = new BufferWriter(YooAssetSettings.ManifestFileMaxSize);
  28. // 写入文件标记
  29. buffer.WriteUInt32(YooAssetSettings.ManifestFileSign);
  30. // 写入文件版本
  31. buffer.WriteUTF8(manifest.FileVersion);
  32. // 写入文件头信息
  33. buffer.WriteBool(manifest.EnableAddressable);
  34. buffer.WriteBool(manifest.LocationToLower);
  35. buffer.WriteBool(manifest.IncludeAssetGUID);
  36. buffer.WriteInt32(manifest.OutputNameStyle);
  37. buffer.WriteUTF8(manifest.PackageName);
  38. buffer.WriteUTF8(manifest.PackageVersion);
  39. // 写入资源列表
  40. buffer.WriteInt32(manifest.AssetList.Count);
  41. for (int i = 0; i < manifest.AssetList.Count; i++)
  42. {
  43. var packageAsset = manifest.AssetList[i];
  44. buffer.WriteUTF8(packageAsset.Address);
  45. buffer.WriteUTF8(packageAsset.AssetPath);
  46. buffer.WriteUTF8(packageAsset.AssetGUID);
  47. buffer.WriteUTF8Array(packageAsset.AssetTags);
  48. buffer.WriteInt32(packageAsset.BundleID);
  49. buffer.WriteInt32Array(packageAsset.DependIDs);
  50. }
  51. // 写入资源包列表
  52. buffer.WriteInt32(manifest.BundleList.Count);
  53. for (int i = 0; i < manifest.BundleList.Count; i++)
  54. {
  55. var packageBundle = manifest.BundleList[i];
  56. buffer.WriteUTF8(packageBundle.BundleName);
  57. buffer.WriteUTF8(packageBundle.FileHash);
  58. buffer.WriteUTF8(packageBundle.FileCRC);
  59. buffer.WriteInt64(packageBundle.FileSize);
  60. buffer.WriteBool(packageBundle.IsRawFile);
  61. buffer.WriteByte(packageBundle.LoadMethod);
  62. buffer.WriteUTF8Array(packageBundle.Tags);
  63. buffer.WriteInt32Array(packageBundle.ReferenceIDs);
  64. }
  65. // 写入文件流
  66. buffer.WriteToStream(fs);
  67. fs.Flush();
  68. }
  69. }
  70. /// <summary>
  71. /// 反序列化(JSON文件)
  72. /// </summary>
  73. public static PackageManifest DeserializeFromJson(string jsonContent)
  74. {
  75. return JsonUtility.FromJson<PackageManifest>(jsonContent);
  76. }
  77. /// <summary>
  78. /// 反序列化(二进制文件)
  79. /// </summary>
  80. public static PackageManifest DeserializeFromBinary(byte[] binaryData)
  81. {
  82. // 创建缓存器
  83. BufferReader buffer = new BufferReader(binaryData);
  84. // 读取文件标记
  85. uint fileSign = buffer.ReadUInt32();
  86. if (fileSign != YooAssetSettings.ManifestFileSign)
  87. throw new Exception("Invalid manifest file !");
  88. // 读取文件版本
  89. string fileVersion = buffer.ReadUTF8();
  90. if (fileVersion != YooAssetSettings.ManifestFileVersion)
  91. throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}");
  92. PackageManifest manifest = new PackageManifest();
  93. {
  94. // 读取文件头信息
  95. manifest.FileVersion = fileVersion;
  96. manifest.EnableAddressable = buffer.ReadBool();
  97. manifest.LocationToLower = buffer.ReadBool();
  98. manifest.IncludeAssetGUID = buffer.ReadBool();
  99. manifest.OutputNameStyle = buffer.ReadInt32();
  100. manifest.PackageName = buffer.ReadUTF8();
  101. manifest.PackageVersion = buffer.ReadUTF8();
  102. // 检测配置
  103. if (manifest.EnableAddressable && manifest.LocationToLower)
  104. throw new Exception("Addressable not support location to lower !");
  105. // 读取资源列表
  106. int packageAssetCount = buffer.ReadInt32();
  107. manifest.AssetList = new List<PackageAsset>(packageAssetCount);
  108. for (int i = 0; i < packageAssetCount; i++)
  109. {
  110. var packageAsset = new PackageAsset();
  111. packageAsset.Address = buffer.ReadUTF8();
  112. packageAsset.AssetPath = buffer.ReadUTF8();
  113. packageAsset.AssetGUID = buffer.ReadUTF8();
  114. packageAsset.AssetTags = buffer.ReadUTF8Array();
  115. packageAsset.BundleID = buffer.ReadInt32();
  116. packageAsset.DependIDs = buffer.ReadInt32Array();
  117. manifest.AssetList.Add(packageAsset);
  118. }
  119. // 读取资源包列表
  120. int packageBundleCount = buffer.ReadInt32();
  121. manifest.BundleList = new List<PackageBundle>(packageBundleCount);
  122. for (int i = 0; i < packageBundleCount; i++)
  123. {
  124. var packageBundle = new PackageBundle();
  125. packageBundle.BundleName = buffer.ReadUTF8();
  126. packageBundle.FileHash = buffer.ReadUTF8();
  127. packageBundle.FileCRC = buffer.ReadUTF8();
  128. packageBundle.FileSize = buffer.ReadInt64();
  129. packageBundle.IsRawFile = buffer.ReadBool();
  130. packageBundle.LoadMethod = buffer.ReadByte();
  131. packageBundle.Tags = buffer.ReadUTF8Array();
  132. packageBundle.ReferenceIDs = buffer.ReadInt32Array();
  133. manifest.BundleList.Add(packageBundle);
  134. }
  135. }
  136. // 填充BundleDic
  137. manifest.BundleDic = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
  138. foreach (var packageBundle in manifest.BundleList)
  139. {
  140. packageBundle.ParseBundle(manifest.PackageName, manifest.OutputNameStyle);
  141. manifest.BundleDic.Add(packageBundle.BundleName, packageBundle);
  142. }
  143. // 填充AssetDic
  144. manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
  145. foreach (var packageAsset in manifest.AssetList)
  146. {
  147. // 注意:我们不允许原始路径存在重名
  148. string assetPath = packageAsset.AssetPath;
  149. if (manifest.AssetDic.ContainsKey(assetPath))
  150. throw new Exception($"AssetPath have existed : {assetPath}");
  151. else
  152. manifest.AssetDic.Add(assetPath, packageAsset);
  153. }
  154. return manifest;
  155. }
  156. #endif
  157. public static string GetRemoteBundleFileExtension(string bundleName)
  158. {
  159. string fileExtension = Path.GetExtension(bundleName);
  160. return fileExtension;
  161. }
  162. public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash)
  163. {
  164. if (nameStyle == 1) //HashName
  165. {
  166. return StringUtility.Format("{0}{1}", fileHash, fileExtension);
  167. }
  168. else if (nameStyle == 4) //BundleName_HashName
  169. {
  170. string fileName = bundleName.Remove(bundleName.LastIndexOf('.'));
  171. return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension);
  172. }
  173. else
  174. {
  175. throw new NotImplementedException($"Invalid name style : {nameStyle}");
  176. }
  177. }
  178. /// <summary>
  179. /// 转换为解压BundleInfo
  180. /// </summary>
  181. public static BundleInfo ConvertToUnpackInfo(PackageBundle packageBundle)
  182. {
  183. // 注意:我们把流加载路径指定为远端下载地址
  184. string streamingPath = PersistentTools.ConvertToWWWPath(packageBundle.StreamingFilePath);
  185. BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
  186. return bundleInfo;
  187. }
  188. /// <summary>
  189. /// 批量转换解压为BundleInfo
  190. /// </summary>
  191. public static List<BundleInfo> ConvertToUnpackInfos(List<PackageBundle> unpackList)
  192. {
  193. List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
  194. foreach (var packageBundle in unpackList)
  195. {
  196. var bundleInfo = ConvertToUnpackInfo(packageBundle);
  197. result.Add(bundleInfo);
  198. }
  199. return result;
  200. }
  201. }
  202. }