using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using Game.Config; using System; using System.Reflection; using System.IO; using System.Text; public class CheckHotUpdateRes : EditorWindow { public class VersionInfoData:GameData { public string FullName; public string MD5; public ulong Size; public VersionInfoData() { FullName = ""; MD5 = ""; Size = 0; } private static void OnCsvLoad(CsvReader csvReader) { VersionInfoData.Onload(csvReader); } } [MenuItem("AssetBundle/热更相关")] public static void OpenCheckHotUpdateWindow() { CheckHotUpdateRes window = GetWindow("热更相关"); window.maxSize = new Vector2(800, 600); window.minSize = new Vector2(600, 400); window.Show(); window.Init(); } private string oldPath = ""; private string newPath = ""; private CheckResWindowInfo info; private List needResList; private GameDataFormatInfo downloadFormatInfo; public void Init() { string path = "Assets/Editor/AssetBundle/CheckHotResWindownInfo.asset"; //Debug.Log(); info = AssetDatabase.LoadAssetAtPath(path); needResList = new List(); } private void OnGUI() { DrowSelectFolder("旧版本文件", "选择文件路径", "选择旧版本资源MD5文件路径", ref info.OldPath); DrowSelectFolder("新版本文件", "选择文件路径", "选择新版本资源MD5文件路径", ref info.NewPath); DrowSelectFolder("需跟新文件输出路径", "选择文件路径", "选择需跟新文件输出路径", ref info.OutputPath); DrawInfo(); DrawCheckBtn(); } private void DrowSelectFolder(string name, string btnName, string savepath, ref string path) { GUILayout.Box("", GUILayout.Width(790)); GUILayout.BeginHorizontal(); GUILayout.Space(10); GUILayout.Label(name, GUILayout.Width(120)); GUILayout.Space(10); path = GUILayout.TextField(path, GUILayout.Width(360)); if (GUILayout.Button(btnName, GUILayout.Width(100))) { string getstr = EditorUtility.SaveFolderPanel(savepath, path, ""); if(!string.IsNullOrEmpty(getstr)) { path = getstr; } } GUILayout.Space(10); GUILayout.EndHorizontal(); } private void DrawInfo() { GUILayout.Box("", GUILayout.Width(790)); GUILayout.BeginHorizontal(); GUILayout.Space(10); GUILayout.Label("版本文件名:", GUILayout.Width(65)); GUILayout.Space(10); info.VersionFileName = GUILayout.TextField(info.VersionFileName, GUILayout.Width(160)); GUILayout.Space(60); GUILayout.Label("版本文件信息文件名:", GUILayout.Width(120)); GUILayout.Space(10); info.mainfestFileName = GUILayout.TextField(info.mainfestFileName, GUILayout.Width(160)); GUILayout.EndHorizontal(); GUILayout.Box("", GUILayout.Width(790)); GUILayout.BeginHorizontal(); GUILayout.Space(10); GUILayout.Label("资源版本:", GUILayout.Width(65)); GUILayout.Space(10); info.ResVersion = GUILayout.TextField(info.ResVersion, GUILayout.Width(160)); GUILayout.Space(10); if (GUILayout.Button("读取版本", GUILayout.Width(100))) { info.ResVersion = File.ReadAllText($"{info.OldPath}/{info.VersionFileName}"); } GUILayout.Space(10); if (GUILayout.Button("版本+1", GUILayout.Width(100))) { VersionCode lVersionCode = info.ResVersion; lVersionCode.patch += 1; info.ResVersion = lVersionCode.ToString(); } GUILayout.Space(10); GUILayout.EndHorizontal(); } private void DrawCheckBtn() { GUILayout.Box("", GUILayout.Width(790)); GUILayout.BeginHorizontal(); GUILayout.Space(10); if (GUILayout.Button("生成MD5资源版本文件")) { BundleBuilderZ.CreateMD5File(info.ResVersion); } GUILayout.Space(60); if (GUILayout.Button("对比新旧资源")) { CheckRes(); } GUILayout.EndHorizontal(); GUILayout.Box("", GUILayout.Width(790)); if (GUILayout.Button("复制所以资源到输出路径")) { CopyFiles(); } if (GUILayout.Button("复制图片资源到输出路径")) { CopyTexture(); } if (GUILayout.Button("复制PSD资源到输出路径")) { CopyPsd(); } GUILayout.Box("", GUILayout.Width(790)); GUILayout.BeginHorizontal(); GUILayout.Space(60); info.IsIgnore =GUILayout.Toggle(info.IsIgnore, "是否开启忽略某些文件") ; GUILayout.EndHorizontal(); } private List SerizlizeResList(byte[] data) { CsvReader csvReader = new CsvReader(info.mainfestFileName, data); if (downloadFormatInfo == null) { downloadFormatInfo = new GameDataFormatInfo(csvReader.Fields(), csvReader.Types()); } Type type = typeof(VersionInfoData); MethodInfo methodInfo = type.GetMethod("OnCsvLoad", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); methodInfo?.Invoke(null, new object[] { csvReader }); List resList = VersionInfoData.AllData(); VersionInfoData.Clear(); return resList; } private void CheckRes() { needResList.Clear(); oldPath = $"{info.OldPath}/{ info.mainfestFileName}"; List Oldlist = GetInfoDatas(oldPath); newPath = $"{info.NewPath}/{ info.mainfestFileName}"; List newlist = GetInfoDatas(newPath); ChangeResMD5(newlist); if (Oldlist != null && newlist != null) { int size = newlist.Count; for (int i = 0; i < size; i++) { if (newlist[i].FullName == info.mainfestFileName || newlist[i].FullName == info.VersionFileName) { continue; } bool isignore = false; if (info.IsIgnore) { string igstr = info.IgnoreFiles.FindFirst(it => it == newlist[i].FullName); if (!string.IsNullOrEmpty(igstr)) { isignore = true; Debug.Log("======================" + newlist[i].FullName); } } VersionInfoData ores = Oldlist.FindFirst(it=> it.FullName == newlist[i].FullName); if (ores != null ) { if (isignore) { newlist[i].MD5 = ores.MD5; newlist[i].Size = ores.Size; } else if (newlist[i].MD5 != ores.MD5) { needResList.Add(newlist[i]); } } else { needResList.Add(newlist[i]); } } } CsvWriter csvWriter = new CsvWriter(newPath, "", newlist, downloadFormatInfo); csvWriter.Write(); CopyFile(); needResList.Clear(); Debug.Log($"资源检查完成 输出路径 : 【{info.OutputPath}】"); } private void CopyFile() { if (needResList == null) { return; } int size = needResList.Count; string datapath = $"{info.NewPath}/"; StringBuilder ChangedataUrls = new StringBuilder(); for (int i = 0; i < size; i++) { ChangedataUrls.Append($"http://weix.vvfyj.cn/res/WDAndroidRes/{ needResList[i].FullName}\n\r"); byte[] fdatas = File.ReadAllBytes(datapath + needResList[i].FullName); FileHelper.WirteToFile( $"{info.OutputPath}/{needResList[i].FullName}" ,fdatas); } FileHelper.WirteStringToFile($"{info.OutputPath}/{info.VersionFileName}",info.ResVersion); byte[] mdatas = File.ReadAllBytes(datapath + info.mainfestFileName); ChangedataUrls.Append($"http://weix.vvfyj.cn/res/WDAndroidRes/{ info.mainfestFileName}\n\r"); ChangedataUrls.Append($"http://weix.vvfyj.cn/res/WDAndroidRes/{ info.VersionFileName}\n\r"); FileHelper.WirteToFile($"{info.OutputPath}/{info.mainfestFileName}", mdatas); FileHelper.WirteToFile($"{info.OutputPath}/ChangeFileUrls.txt", Encoding.UTF8.GetBytes(ChangedataUrls.ToString())); } private List GetInfoDatas(string path) { List list = null; byte[] datas = null; if (FileSystem.Exists(path)) { datas = File.ReadAllBytes(path); } if (datas != null) { list = SerizlizeResList(datas); } else { Debug.LogError($"请选择正确路径;[{path}]文件不存在!!!!"); } return list; } private void ChangeResMD5(List datas) { int[] ids = GenerateRandomArray(info.ChangeNum, 1, datas.Count); for (int i = 0; i < ids.Length; i++) { Debug.Log($"{ datas[ids[i]].FullName} 改===={ datas[ids[i]].MD5}====="); datas[ids[i]].MD5 = datas[ids[i]].MD5.Substring(0,6); //Debug.Log($"{ datas[ids[i]].FullName} 改===={ datas[ids[i]].MD5}=====eeee"); } } int[] GenerateRandomArray(int size, int min, int max) { List array = new List(size); if (size >= max - min) { for (int i = min; i < max; i++) { array.Add(i); } } else { while (size > 0) { int a = UnityEngine.Random.Range(min, max); if (!array.Contains(a)) { array.Add(a); size--; } } } return array.ToArray(); } private void CopyFiles() { string[] files1 = FileHelper.GetAllFileNmae(info.NewPath, "meta"); int size = files1.Length; string datapath = $"{info.NewPath}/"; for (int i = 0; i < size; i++) { byte[] fdatas = File.ReadAllBytes(datapath + files1[i]); FileHelper.WirteToFile($"{info.OutputPath}/{files1[i]}", fdatas); } } private void CopyTexture() { string datapath = $"{Application.dataPath}/Content/Icons/"; FileHelper.CopyDir(datapath, info.OutputPath, "meta"); } private void CopyPsd() { string datapath = $"{Application.dataPath}/"; FileHelper.CopyDir_Only(datapath, info.OutputPath, ".psd"); } }