Files

90 lines
4.5 KiB
C#

using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.U2D;
/// <summary>检查真实 bundle 中是否重复包含未压缩的图集原图。</summary>
public static class AuditUiAtlasBundle
{
public static string RebuildProductionWarm()
{
string result = AOT.Editor.YooAssetTools.BuildAndStageArt.BuildAndStage();
if (!result.StartsWith("ok", StringComparison.Ordinal)) throw new Exception(result);
return result + " | " + Production();
}
public static string VerifyProductionGuard()
{
string oldDirectory = Path.GetFullPath(Path.Combine(Application.dataPath, "../Bundles/WebGL/Art/20261022.142050"));
string latestDirectory = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/cdn_root/wechat/1.0.0/Art"));
var oldChecks = AIGame.EditorTools.UiAtlasBuildValidation.Inspect(oldDirectory);
var newChecks = AIGame.EditorTools.UiAtlasBuildValidation.Inspect(latestDirectory);
if (!oldChecks.Any(c => c.SourceTextureCount > 0)) throw new Exception("Guard did not detect the known bad production bundle");
if (newChecks.Any(c => c.SourceTextureCount > 0)) throw new Exception("New production bundles still contain source textures");
string output = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/ui_atlas/size"));
Directory.CreateDirectory(output);
File.WriteAllText(Path.Combine(output, "production_guard.json"), JsonConvert.SerializeObject(new {
passed = true, knownBadDetected = true, oldChecks, newChecks
}, Formatting.Indented));
return "PASS: known bad Art detected; all " + newChecks.Length + " current Art atlas bundles have zero source textures.";
}
public static string RebuildProductionWithoutStaleCache()
{
UnityEditor.Build.Pipeline.Utilities.BuildCache.PurgeCache(false);
string result = AOT.Editor.YooAssetTools.BuildAndStageArt.BuildAndStage();
if (!result.StartsWith("ok", StringComparison.Ordinal)) throw new Exception(result);
return result + " | " + Production();
}
public static string Production()
{
string root = Path.Combine(Application.dataPath, "StreamingAssets/yoo/Art");
return Inspect(Directory.GetFiles(root, "assets_bundles_ui_atlas_ui_homeatlas_*.bundle").Single(), "production_latest");
}
public static string Original()
{
string path = Path.Combine(Application.dataPath,
"StreamingAssets/yoo/Art/assets_bundles_ui_atlas_ui_homeatlas_a6442d30c6c5d555575f90ae44067db5.bundle");
return Inspect(path, "production_before");
}
public static string Verification()
{
string output = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/ui_atlas"));
string root = JObject.Parse(File.ReadAllText(Path.Combine(output, "build.json"))).Value<string>("packageRoot");
return Inspect(Directory.GetFiles(root, "assets_bundles_ui_atlas_ui_homeatlas_*.bundle").OrderByDescending(File.GetLastWriteTimeUtc).First(),
"verification_after", true);
}
public static string Inspect(string path, string reportName, bool requireStripped = false)
{
var bundle = AssetBundle.LoadFromFile(path);
if (bundle == null) throw new Exception("Cannot read bundle: " + path);
try
{
string[] assets = bundle.GetAllAssetNames();
var sources = bundle.LoadAllAssets<Texture2D>();
var atlases = bundle.LoadAllAssets<SpriteAtlas>();
int spriteCount = atlases.Sum(a => a.spriteCount);
var report = new {
path, bytes = new FileInfo(path).Length, spriteCount, assets,
sourceTextures = sources.Select(t => new { t.name, t.width, t.height, format = t.format.ToString() }).ToArray()
};
string output = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/ui_atlas/size"));
Directory.CreateDirectory(output);
File.WriteAllText(Path.Combine(output, reportName + ".json"), JsonConvert.SerializeObject(report, Formatting.Indented));
if (requireStripped && sources.Length != 0) throw new Exception("Bundle still contains original Texture2D data: " + path);
return $"bytes={report.bytes}, sourceTextures={sources.Length}, sprites={spriteCount}";
}
finally
{
bundle.Unload(true);
}
}
}