Update logic code

优化补丁清单格式为二进制。
pull/62/head
hevinci 2022-12-03 18:48:51 +08:00
parent 7aab610be5
commit 19cb239746
14 changed files with 193 additions and 62 deletions

View File

@ -23,7 +23,7 @@ namespace YooAsset.Editor
var buildResult = builder.Run(buildParameters); var buildResult = builder.Run(buildParameters);
if (buildResult.Success) if (buildResult.Success)
{ {
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion); string manifestFileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}"; string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
return manifestFilePath; return manifestFilePath;
} }

View File

@ -182,13 +182,14 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
internal PatchBundle CreatePatchBundle() internal PatchBundle CreatePatchBundle()
{ {
string fileHash = PatchInfo.PatchFileHash; PatchBundle patchBundle = new PatchBundle();
string fileCRC = PatchInfo.PatchFileCRC; patchBundle.BundleName = BundleName;
long fileSize = PatchInfo.PatchFileSize; patchBundle.FileHash = PatchInfo.PatchFileHash;
bool isRawFile = IsRawFile; patchBundle.FileCRC = PatchInfo.PatchFileCRC;
byte loadMethod = (byte)LoadMethod; patchBundle.FileSize = PatchInfo.PatchFileSize;
string[] tags = GetBundleTags(); patchBundle.IsRawFile = IsRawFile;
PatchBundle patchBundle = new PatchBundle(BundleName, fileHash, fileCRC, fileSize, isRawFile, loadMethod, tags); patchBundle.LoadMethod = (byte)LoadMethod;
patchBundle.Tags = GetBundleTags();
return patchBundle; return patchBundle;
} }
} }

View File

@ -45,7 +45,7 @@ namespace YooAsset.Editor
// 拷贝补丁清单文件 // 拷贝补丁清单文件
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, buildPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(buildPackageName, buildPackageVersion);
string sourcePath = $"{packageOutputDirectory}/{fileName}"; string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}"; string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);

View File

@ -51,18 +51,26 @@ namespace YooAsset.Editor
} }
} }
// 创建补丁清单文件 // 创建补丁清单文本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
PatchManifest.SerializeToJson(filePath, patchManifest);
BuildRunner.Log($"创建补丁清单文件:{filePath}");
}
// 创建补丁清单二进制文件
string packageHash; string packageHash;
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
PatchManifest.Serialize(filePath, patchManifest); PatchManifest.SerializeToBinary(filePath, patchManifest);
packageHash = HashUtility.FileMD5(filePath); packageHash = HashUtility.FileMD5(filePath);
BuildRunner.Log($"创建补丁清单文件:{filePath}"); BuildRunner.Log($"创建补丁清单文件:{filePath}");
var patchManifestContext = new PatchManifestContext(); PatchManifestContext patchManifestContext = new PatchManifestContext();
string jsonData = FileUtility.ReadFile(filePath); byte[] bytesData = FileUtility.ReadAllBytes(filePath);
patchManifestContext.Manifest = PatchManifest.Deserialize(jsonData); patchManifestContext.Manifest = PatchManifest.DeserializeFromBinary(bytesData);
context.SetContextObject(patchManifestContext); context.SetContextObject(patchManifestContext);
} }

View File

@ -109,7 +109,7 @@ namespace YooAsset.Editor
return; return;
_reportFilePath = selectFilePath; _reportFilePath = selectFilePath;
string jsonData = FileUtility.ReadFile(_reportFilePath); string jsonData = FileUtility.ReadAllText(_reportFilePath);
_buildReport = BuildReport.Deserialize(jsonData); _buildReport = BuildReport.Deserialize(jsonData);
_assetListViewer.FillViewData(_buildReport, _searchKeyWord); _assetListViewer.FillViewData(_buildReport, _searchKeyWord);
_bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord); _bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord);

View File

@ -105,7 +105,7 @@ namespace YooAsset
if (_steps == ESteps.LoadWebManifest) if (_steps == ESteps.LoadWebManifest)
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(_packageName, _packageVersion);
string webURL = GetPatchManifestRequestURL(fileName); string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}"); YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
@ -131,7 +131,8 @@ namespace YooAsset
// 解析补丁清单 // 解析补丁清单
try try
{ {
_remotePatchManifest = PatchManifest.Deserialize(_downloader.GetText()); byte[] bytesData = _downloader.GetData();
_remotePatchManifest = PatchManifest.DeserializeFromBinary(bytesData);
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
} }

View File

@ -56,8 +56,8 @@ namespace YooAsset
try try
{ {
YooLogger.Log($"Load simulation manifest file : {_simulatePatchManifestPath}"); YooLogger.Log($"Load simulation manifest file : {_simulatePatchManifestPath}");
string jsonContent = FileUtility.ReadFile(_simulatePatchManifestPath); byte[] bytesData = FileUtility.ReadAllBytes(_simulatePatchManifestPath);
var manifest = PatchManifest.Deserialize(jsonContent); var manifest = PatchManifest.DeserializeFromBinary(bytesData);
InitializedPackageVersion = manifest.PackageVersion; InitializedPackageVersion = manifest.PackageVersion;
_impl.SetSimulatePatchManifest(manifest); _impl.SetSimulatePatchManifest(manifest);
_steps = ESteps.Done; _steps = ESteps.Done;
@ -491,7 +491,7 @@ namespace YooAsset
if (_steps == ESteps.LoadAppManifest) if (_steps == ESteps.LoadAppManifest)
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(_buildinPackageName, _buildinPackageVersion);
string filePath = PathHelper.MakeStreamingLoadPath(fileName); string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath); string url = PathHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
@ -513,7 +513,8 @@ namespace YooAsset
// 解析APP里的补丁清单 // 解析APP里的补丁清单
try try
{ {
Manifest = PatchManifest.Deserialize(_downloader.GetText()); byte[] bytesData = _downloader.GetData();
Manifest = PatchManifest.DeserializeFromBinary(bytesData);
} }
catch (System.Exception e) catch (System.Exception e)
{ {
@ -590,7 +591,7 @@ namespace YooAsset
if (_steps == ESteps.CopyAppManifest) if (_steps == ESteps.CopyAppManifest)
{ {
string savePath = PersistentHelper.GetCacheManifestFilePath(_buildinPackageName); string savePath = PersistentHelper.GetCacheManifestFilePath(_buildinPackageName);
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(_buildinPackageName, _buildinPackageVersion);
string filePath = PathHelper.MakeStreamingLoadPath(fileName); string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath); string url = PathHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebFileRequester(); _downloader = new UnityWebFileRequester();

View File

@ -171,7 +171,7 @@ namespace YooAsset
if (_steps == ESteps.LoadWebManifest) if (_steps == ESteps.LoadWebManifest)
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageVersion); string fileName = YooAssetSettingsData.GetPatchManifestBinaryFileName(_packageName, _packageVersion);
string webURL = GetPatchManifestRequestURL(fileName); string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}"); YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader2 = new UnityWebDataRequester(); _downloader2 = new UnityWebDataRequester();
@ -194,8 +194,8 @@ namespace YooAsset
{ {
try try
{ {
string content = _downloader2.GetText(); byte[] bytesData = _downloader2.GetData();
var manifest = PersistentHelper.SaveCacheManifestFile(_packageName, content); var manifest = PersistentHelper.SaveCacheManifestFile(_packageName, bytesData);
_impl.SetLocalPatchManifest(manifest); _impl.SetLocalPatchManifest(manifest);
FoundNewManifest = true; FoundNewManifest = true;
_steps = ESteps.InitVerifyingCache; _steps = ESteps.InitVerifyingCache;

View File

@ -109,15 +109,8 @@ namespace YooAsset
} }
public PatchBundle(string bundleName, string fileHash, string fileCRC, long fileSize, bool isRawFile, byte loadMethod, string[] tags) public PatchBundle()
{ {
BundleName = bundleName;
FileHash = fileHash;
FileCRC = fileCRC;
FileSize = fileSize;
IsRawFile = isRawFile;
LoadMethod = loadMethod;
Tags = tags;
} }
/// <summary> /// <summary>

View File

@ -266,48 +266,147 @@ namespace YooAsset
/// <summary> /// <summary>
/// 序列化 /// 序列化JSON文件
/// </summary> /// </summary>
public static void Serialize(string savePath, PatchManifest patchManifest) public static void SerializeToJson(string savePath, PatchManifest manifest)
{ {
string json = JsonUtility.ToJson(patchManifest); string json = JsonUtility.ToJson(manifest, true);
FileUtility.CreateFile(savePath, json); FileUtility.CreateFile(savePath, json);
} }
/// <summary> /// <summary>
/// 序列化 /// 序列化(二进制文件)
/// </summary> /// </summary>
public static PatchManifest Deserialize(string jsonData) public static void SerializeToBinary(string savePath, PatchManifest patchManifest)
{ {
PatchManifest patchManifest = JsonUtility.FromJson<PatchManifest>(jsonData); using (FileStream fs = new FileStream(savePath, FileMode.Create))
if (patchManifest == null) {
throw new System.Exception($"{nameof(PatchManifest)} deserialize object is null !"); // 创建缓存器
BufferWriter buffer = new BufferWriter(YooAssetSettings.PatchManifestFileMaxSize);
// 检测文件版本 // 写入文件标记
if (patchManifest.FileVersion != YooAssetSettings.PatchManifestFileVersion) buffer.WriteUInt32(YooAssetSettings.PatchManifestFileSign);
throw new Exception($"The manifest file version are not compatible : {patchManifest.FileVersion} != {YooAssetSettings.PatchManifestFileVersion}");
// 写入文件版本
buffer.WriteUTF8(patchManifest.FileVersion);
// 写入文件头信息
buffer.WriteBool(patchManifest.EnableAddressable);
buffer.WriteInt32(patchManifest.OutputNameStyle);
buffer.WriteUTF8(patchManifest.PackageName);
buffer.WriteUTF8(patchManifest.PackageVersion);
// 写入资源列表
buffer.WriteInt32(patchManifest.AssetList.Count);
for (int i = 0; i < patchManifest.AssetList.Count; i++)
{
var patchAsset = patchManifest.AssetList[i];
buffer.WriteUTF8(patchAsset.Address);
buffer.WriteUTF8(patchAsset.AssetPath);
buffer.WriteUTF8Array(patchAsset.AssetTags);
buffer.WriteInt32(patchAsset.BundleID);
buffer.WriteInt32Array(patchAsset.DependIDs);
}
// 写入资源包列表
buffer.WriteInt32(patchManifest.BundleList.Count);
for (int i = 0; i < patchManifest.BundleList.Count; i++)
{
var patchBundle = patchManifest.BundleList[i];
buffer.WriteUTF8(patchBundle.BundleName);
buffer.WriteUTF8(patchBundle.FileHash);
buffer.WriteUTF8(patchBundle.FileCRC);
buffer.WriteInt64(patchBundle.FileSize);
buffer.WriteBool(patchBundle.IsRawFile);
buffer.WriteByte(patchBundle.LoadMethod);
buffer.WriteUTF8Array(patchBundle.Tags);
}
// 写入文件流
buffer.WriteToStream(fs);
fs.Flush();
}
}
/// <summary>
/// 反序列化(二进制文件)
/// </summary>
public static PatchManifest DeserializeFromBinary(byte[] binaryData)
{
// 创建缓存器
BufferReader buffer = new BufferReader(binaryData);
// 读取文件标记
uint fileSign = buffer.ReadUInt32();
if (fileSign != YooAssetSettings.PatchManifestFileSign)
throw new Exception("Invalid manifest file !");
PatchManifest manifest = new PatchManifest();
{
// 读取文件版本
manifest.FileVersion = buffer.ReadUTF8();
if (manifest.FileVersion != YooAssetSettings.PatchManifestFileVersion)
throw new Exception($"The manifest file version are not compatible : {manifest.FileVersion} != {YooAssetSettings.PatchManifestFileVersion}");
// 读取文件头信息
manifest.EnableAddressable = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32();
manifest.PackageName = buffer.ReadUTF8();
manifest.PackageVersion = buffer.ReadUTF8();
// 读取资源列表
int patchAssetCount = buffer.ReadInt32();
manifest.AssetList = new List<PatchAsset>(patchAssetCount);
for (int i = 0; i < patchAssetCount; i++)
{
var patchAsset = new PatchAsset();
patchAsset.Address = buffer.ReadUTF8();
patchAsset.AssetPath = buffer.ReadUTF8();
patchAsset.AssetTags = buffer.ReadUTF8Array();
patchAsset.BundleID = buffer.ReadInt32();
patchAsset.DependIDs = buffer.ReadInt32Array();
manifest.AssetList.Add(patchAsset);
}
// 读取资源包列表
int patchBundleCount = buffer.ReadInt32();
manifest.BundleList = new List<PatchBundle>(patchBundleCount);
for (int i = 0; i < patchBundleCount; i++)
{
var patchBundle = new PatchBundle();
patchBundle.BundleName = buffer.ReadUTF8();
patchBundle.FileHash = buffer.ReadUTF8();
patchBundle.FileCRC = buffer.ReadUTF8();
patchBundle.FileSize = buffer.ReadInt64();
patchBundle.IsRawFile = buffer.ReadBool();
patchBundle.LoadMethod = buffer.ReadByte();
patchBundle.Tags = buffer.ReadUTF8Array();
manifest.BundleList.Add(patchBundle);
}
}
// BundleList // BundleList
foreach (var patchBundle in patchManifest.BundleList) foreach (var patchBundle in manifest.BundleList)
{ {
patchBundle.ParseBundle(patchManifest.PackageName, patchManifest.OutputNameStyle); patchBundle.ParseBundle(manifest.PackageName, manifest.OutputNameStyle);
patchManifest.BundleDic.Add(patchBundle.BundleName, patchBundle); manifest.BundleDic.Add(patchBundle.BundleName, patchBundle);
} }
// AssetList // AssetList
foreach (var patchAsset in patchManifest.AssetList) foreach (var patchAsset in manifest.AssetList)
{ {
// 注意:我们不允许原始路径存在重名 // 注意:我们不允许原始路径存在重名
string assetPath = patchAsset.AssetPath; string assetPath = patchAsset.AssetPath;
if (patchManifest.AssetDic.ContainsKey(assetPath)) if (manifest.AssetDic.ContainsKey(assetPath))
throw new Exception($"AssetPath have existed : {assetPath}"); throw new Exception($"AssetPath have existed : {assetPath}");
else else
patchManifest.AssetDic.Add(assetPath, patchAsset); manifest.AssetDic.Add(assetPath, patchAsset);
} }
return patchManifest; return manifest;
} }
/// <summary> /// <summary>
/// 生成Bundle文件的正式名称 /// 生成Bundle文件的正式名称
/// </summary> /// </summary>

View File

@ -16,13 +16,23 @@ namespace YooAsset
public string RawFileVariant = "rawfile"; public string RawFileVariant = "rawfile";
/// <summary> /// <summary>
/// 补丁清单文件名称 /// 清单文件名称
/// </summary> /// </summary>
public string PatchManifestFileName = "PatchManifest"; public string PatchManifestFileName = "PatchManifest";
/// <summary> /// <summary>
/// 补丁清单文件格式版本 /// 清单文件头标记
/// </summary>
public const uint PatchManifestFileSign = 0x594F4F;
/// <summary>
/// 清单文件极限大小100MB
/// </summary>
public const int PatchManifestFileMaxSize = 104857600;
/// <summary>
/// 清单文件格式版本
/// </summary> /// </summary>
public const string PatchManifestFileVersion = "1.3.4"; public const string PatchManifestFileVersion = "1.3.4";

View File

@ -51,11 +51,19 @@ namespace YooAsset
/// <summary> /// <summary>
/// 获取补丁清单文件完整名称 /// 获取补丁清单文件完整名称
/// </summary> /// </summary>
public static string GetPatchManifestFileName(string packageName, string packageVersion) public static string GetPatchManifestBinaryFileName(string packageName, string packageVersion)
{ {
return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.bytes"; return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.bytes";
} }
/// <summary>
/// 获取补丁清单文件完整名称
/// </summary>
public static string GetPatchManifestJsonFileName(string packageName, string packageVersion)
{
return $"{Setting.PatchManifestFileName}_{packageName}_{packageVersion}.json";
}
/// <summary> /// <summary>
/// 获取补丁清单哈希文件完整名称 /// 获取补丁清单哈希文件完整名称
/// </summary> /// </summary>

View File

@ -128,19 +128,19 @@ namespace YooAsset
{ {
YooLogger.Log($"Load sandbox patch manifest file : {packageName}"); YooLogger.Log($"Load sandbox patch manifest file : {packageName}");
string filePath = GetCacheManifestFilePath(packageName); string filePath = GetCacheManifestFilePath(packageName);
string jsonData = File.ReadAllText(filePath); byte[] bytesData = File.ReadAllBytes(filePath);
return PatchManifest.Deserialize(jsonData); return PatchManifest.DeserializeFromBinary(bytesData);
} }
/// <summary> /// <summary>
/// 存储沙盒内清单文件 /// 存储沙盒内清单文件
/// </summary> /// </summary>
public static PatchManifest SaveCacheManifestFile(string packageName, string fileContent) public static PatchManifest SaveCacheManifestFile(string packageName, byte[] fileBytesData)
{ {
YooLogger.Log($"Save sandbox patch manifest file : {packageName}"); YooLogger.Log($"Save sandbox patch manifest file : {packageName}");
var manifest = PatchManifest.Deserialize(fileContent); var manifest = PatchManifest.DeserializeFromBinary(fileBytesData);
string savePath = GetCacheManifestFilePath(packageName); string savePath = GetCacheManifestFilePath(packageName);
FileUtility.CreateFile(savePath, fileContent); FileUtility.CreateFile(savePath, fileBytesData);
return manifest; return manifest;
} }

View File

@ -117,15 +117,25 @@ namespace YooAsset
internal static class FileUtility internal static class FileUtility
{ {
/// <summary> /// <summary>
/// 读取文件 /// 读取文件的文本数据
/// </summary> /// </summary>
public static string ReadFile(string filePath) public static string ReadAllText(string filePath)
{ {
if (File.Exists(filePath) == false) if (File.Exists(filePath) == false)
return string.Empty; return string.Empty;
return File.ReadAllText(filePath, Encoding.UTF8); return File.ReadAllText(filePath, Encoding.UTF8);
} }
/// <summary>
/// 读取文件的字节数据
/// </summary>
public static byte[] ReadAllBytes(string filePath)
{
if (File.Exists(filePath) == false)
return null;
return File.ReadAllBytes(filePath);
}
/// <summary> /// <summary>
/// 创建文件(如果已经存在则删除旧文件) /// 创建文件(如果已经存在则删除旧文件)
/// </summary> /// </summary>