using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; namespace BFEditor.Build { public class CompareAssetBundleWindow : EditorWindow { private string newestABPath = ""; private string lastABPath = ""; public bool IsAndroid = true; private List ABList = new List(); Vector2 resultScrollPos; public CompareAssetBundleWindow() { titleContent = new GUIContent("AssetBundle对比"); } private void OnEnable() { GetNewestABPath(); } void OnGUI() { GUILayout.Space(18); GUILayout.BeginHorizontal(); GUILayout.Label("当前版本AB路径"); GUILayout.TextField(newestABPath, GUILayout.Width(600)); if (GUILayout.Button("选择", GUILayout.Width(80))) { string openPath = EditorUtility.OpenFolderPanel("select ab path", newestABPath, ""); if (openPath.CompareTo("") != 0){ newestABPath = openPath; } } GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("上个版本AB路径"); GUILayout.TextField(lastABPath, GUILayout.Width(600)); if (GUILayout.Button("选择", GUILayout.Width(80))) { string openPath = EditorUtility.OpenFolderPanel("select ab path", lastABPath, ""); if (openPath.CompareTo("") != 0){ lastABPath = openPath; } } GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Space(150); if (GUILayout.Button("对比", GUILayout.Width(200), GUILayout.Height(40))) { CheckMD5AndAssetHash(); } GUILayout.Space(100); if (GUILayout.Button("使用上个版本的AB修复", GUILayout.Width(200), GUILayout.Height(40))) { UseLastABFix(); } GUILayout.EndHorizontal(); GUILayout.Space(30); DrawResult(); } private void DrawResult() { resultScrollPos = GUILayout.BeginScrollView(resultScrollPos, GUILayout.Width(800), GUILayout.Height(620)); for (int i = ABList.Count - 1; i >= 0; i--) { var path = ABList[i]; GUILayout.BeginHorizontal(); GUILayout.Space(20); EditorGUILayout.TextField(path); GUILayout.Space(10); GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } private void CheckMD5AndAssetHash() { if (string.IsNullOrEmpty(newestABPath)) { return; } if (string.IsNullOrEmpty(lastABPath)) { return; } ABList.Clear(); var manifestPath = System.IO.Path.Combine(newestABPath, "asset_bundle_manifest.ab"); var manifestAB = AssetBundle.LoadFromFile(manifestPath); var Manifest = manifestAB.LoadAsset("AssetBundleManifest"); manifestAB.Unload(false); var lastManifestPath = System.IO.Path.Combine(lastABPath, "asset_bundle_manifest.ab"); var lastManifestAB = AssetBundle.LoadFromFile(lastManifestPath); var lastManifest = lastManifestAB.LoadAsset("AssetBundleManifest"); lastManifestAB.Unload(false); var allAB = Manifest.GetAllAssetBundles(); foreach(var path in allAB) { if (path.Contains("ab_config.bytes") || path.Contains("asset_bundle_manifest.ab")) { continue; } var fullPathA = Path.Combine(newestABPath, path); var fullPathB = Path.Combine(lastABPath, path); if (File.Exists(fullPathB) && BF.GameLaunchUtils.GetFileMD5(fullPathA).CompareTo(BF.GameLaunchUtils.GetFileMD5(fullPathB)) != 0) { if (Manifest.GetAssetBundleHash(path) == lastManifest.GetAssetBundleHash(path)) { // md5 不一致但是AssetHash一致的情况 ABList.Add(path); } } } } private void UseLastABFix() { if (string.IsNullOrEmpty(newestABPath)) { return; } if (string.IsNullOrEmpty(lastABPath)) { return; } if (ABList.Count == 0) { return; } foreach(var path in ABList) { var fullPathA = Path.Combine(newestABPath, path); var fullPathB = Path.Combine(lastABPath, path); File.Copy(fullPathB, fullPathA, true); } var version = newestABPath.Substring(newestABPath.Replace("\\", "/").LastIndexOf("/") + 1); AssetBundleUtils.RegenerateABConfigMd5(newestABPath, version); ABList.Clear(); } public static void ShowWindow() { var window = GetWindow(); window.Show(); } private void GetNewestABPath() { var bundleCachePath = IsAndroid ? Application.dataPath + "/../HistoryAssetBundles" : Application.dataPath + "/../HistoryAssetBundles/IOS"; var dirInfo = new DirectoryInfo(bundleCachePath); var dirs = dirInfo.GetDirectories(); if (dirs.Length == 0) { newestABPath = ""; lastABPath = ""; } if (dirs.Length == 1) { newestABPath = dirs[0].FullName; lastABPath = ""; } var hightestIndex = 0; var secondIndex = 0; for (var i = 1; i < dirs.Length; i++) { if (dirs[i].FullName.CompareTo(dirs[hightestIndex].FullName) > 0) { secondIndex = hightestIndex; hightestIndex = i; } } newestABPath = dirs[hightestIndex].FullName; if (hightestIndex > 0) { lastABPath = dirs[secondIndex].FullName; } } } }