123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- namespace YooAsset
- {
- internal static class ManifestTools
- {
- #if UNITY_EDITOR
- /// <summary>
- /// 序列化(JSON文件)
- /// </summary>
- public static void SerializeToJson(string savePath, PackageManifest manifest)
- {
- string json = JsonUtility.ToJson(manifest, true);
- FileUtility.WriteAllText(savePath, json);
- }
- /// <summary>
- /// 序列化(二进制文件)
- /// </summary>
- public static void SerializeToBinary(string savePath, PackageManifest manifest)
- {
- using (FileStream fs = new FileStream(savePath, FileMode.Create))
- {
- // 创建缓存器
- BufferWriter buffer = new BufferWriter(YooAssetSettings.ManifestFileMaxSize);
- // 写入文件标记
- buffer.WriteUInt32(YooAssetSettings.ManifestFileSign);
- // 写入文件版本
- buffer.WriteUTF8(manifest.FileVersion);
- // 写入文件头信息
- buffer.WriteBool(manifest.EnableAddressable);
- buffer.WriteBool(manifest.LocationToLower);
- buffer.WriteBool(manifest.IncludeAssetGUID);
- buffer.WriteInt32(manifest.OutputNameStyle);
- buffer.WriteUTF8(manifest.PackageName);
- buffer.WriteUTF8(manifest.PackageVersion);
- // 写入资源列表
- buffer.WriteInt32(manifest.AssetList.Count);
- for (int i = 0; i < manifest.AssetList.Count; i++)
- {
- var packageAsset = manifest.AssetList[i];
- buffer.WriteUTF8(packageAsset.Address);
- buffer.WriteUTF8(packageAsset.AssetPath);
- buffer.WriteUTF8(packageAsset.AssetGUID);
- buffer.WriteUTF8Array(packageAsset.AssetTags);
- buffer.WriteInt32(packageAsset.BundleID);
- buffer.WriteInt32Array(packageAsset.DependIDs);
- }
- // 写入资源包列表
- buffer.WriteInt32(manifest.BundleList.Count);
- for (int i = 0; i < manifest.BundleList.Count; i++)
- {
- var packageBundle = manifest.BundleList[i];
- buffer.WriteUTF8(packageBundle.BundleName);
- buffer.WriteUTF8(packageBundle.FileHash);
- buffer.WriteUTF8(packageBundle.FileCRC);
- buffer.WriteInt64(packageBundle.FileSize);
- buffer.WriteBool(packageBundle.IsRawFile);
- buffer.WriteByte(packageBundle.LoadMethod);
- buffer.WriteUTF8Array(packageBundle.Tags);
- buffer.WriteInt32Array(packageBundle.ReferenceIDs);
- }
- // 写入文件流
- buffer.WriteToStream(fs);
- fs.Flush();
- }
- }
- /// <summary>
- /// 反序列化(JSON文件)
- /// </summary>
- public static PackageManifest DeserializeFromJson(string jsonContent)
- {
- return JsonUtility.FromJson<PackageManifest>(jsonContent);
- }
- /// <summary>
- /// 反序列化(二进制文件)
- /// </summary>
- public static PackageManifest DeserializeFromBinary(byte[] binaryData)
- {
- // 创建缓存器
- BufferReader buffer = new BufferReader(binaryData);
- // 读取文件标记
- uint fileSign = buffer.ReadUInt32();
- if (fileSign != YooAssetSettings.ManifestFileSign)
- throw new Exception("Invalid manifest file !");
- // 读取文件版本
- string fileVersion = buffer.ReadUTF8();
- if (fileVersion != YooAssetSettings.ManifestFileVersion)
- throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}");
- PackageManifest 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 Exception("Addressable not support location to lower !");
- // 读取资源列表
- int packageAssetCount = buffer.ReadInt32();
- manifest.AssetList = new List<PackageAsset>(packageAssetCount);
- for (int i = 0; i < packageAssetCount; i++)
- {
- 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);
- }
- // 读取资源包列表
- int packageBundleCount = buffer.ReadInt32();
- manifest.BundleList = new List<PackageBundle>(packageBundleCount);
- for (int i = 0; i < packageBundleCount; i++)
- {
- 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);
- }
- }
- // 填充BundleDic
- manifest.BundleDic = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
- foreach (var packageBundle in manifest.BundleList)
- {
- packageBundle.ParseBundle(manifest.PackageName, manifest.OutputNameStyle);
- manifest.BundleDic.Add(packageBundle.BundleName, packageBundle);
- }
- // 填充AssetDic
- manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
- foreach (var packageAsset in manifest.AssetList)
- {
- // 注意:我们不允许原始路径存在重名
- string assetPath = packageAsset.AssetPath;
- if (manifest.AssetDic.ContainsKey(assetPath))
- throw new Exception($"AssetPath have existed : {assetPath}");
- else
- manifest.AssetDic.Add(assetPath, packageAsset);
- }
- return manifest;
- }
- #endif
- public static string GetRemoteBundleFileExtension(string bundleName)
- {
- string fileExtension = Path.GetExtension(bundleName);
- return fileExtension;
- }
- public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash)
- {
- if (nameStyle == 1) //HashName
- {
- return StringUtility.Format("{0}{1}", fileHash, fileExtension);
- }
- else if (nameStyle == 4) //BundleName_HashName
- {
- string fileName = bundleName.Remove(bundleName.LastIndexOf('.'));
- return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension);
- }
- else
- {
- throw new NotImplementedException($"Invalid name style : {nameStyle}");
- }
- }
- /// <summary>
- /// 转换为解压BundleInfo
- /// </summary>
- public static BundleInfo ConvertToUnpackInfo(PackageBundle packageBundle)
- {
- // 注意:我们把流加载路径指定为远端下载地址
- string streamingPath = PersistentTools.ConvertToWWWPath(packageBundle.StreamingFilePath);
- BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
- return bundleInfo;
- }
- /// <summary>
- /// 批量转换解压为BundleInfo
- /// </summary>
- public static List<BundleInfo> ConvertToUnpackInfos(List<PackageBundle> unpackList)
- {
- List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
- foreach (var packageBundle in unpackList)
- {
- var bundleInfo = ConvertToUnpackInfo(packageBundle);
- result.Add(bundleInfo);
- }
- return result;
- }
- }
- }
|