using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; using System.Linq; using GameEditor.Core; using GameEditor.GameEditor.PlayerBuilder; using GameEditor.Util; using GameLogic; using System.Diagnostics; using ResUpdate; using System.Threading; using System.Net; namespace GameEditor.FrameTool { public static class HotFixTool { //重新下载外部.unity3d文件 public static void RegetExternalFile(string resUrl, string outPath) { //获取下载文件链接 string url = resUrl + "/files.unity3d"; string dlPath = outPath + "/files.unity3d"; // 文件夹没有就创建 if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } //获取文件存放路径 if (File.Exists(dlPath)) { File.Delete(dlPath); } // 设置参数 UnityEngine.Debug.Log(url); HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); //创建本地文件写入流 Stream stream = new FileStream(dlPath, FileMode.Create, FileAccess.Write); byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { stream.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } stream.Close(); responseStream.Close(); } //遍历内部unity3d数据 public static List GetFilesList(string filesPath) { UnityEngine.AssetBundle bundle = UnityEngine.AssetBundle.LoadFromFile(filesPath + UpdateConfigs.FILES); ResourceFiles files = bundle.LoadAsset("game"); bundle.Unload(true); return files.files; } // 获取差异文件list public static List GetDiffList(List inDataList, List exDataList) { List diffList = new List(); Dictionary exDataDic = new Dictionary(); for (int i = 0; i < exDataList.Count; i++) { if (!exDataDic.ContainsKey(exDataList[i].fileName)) { exDataDic.Add(exDataList[i].fileName, exDataList[i]); } else { exDataDic[exDataList[i].fileName] = exDataList[i]; } } for (int i = 0; i < inDataList.Count; i++) { if (!exDataDic.ContainsKey(inDataList[i].fileName)) { diffList.Add(inDataList[i]); } else { if (!inDataList[i].crc.Equals(exDataDic[inDataList[i].fileName].crc)) { diffList.Add(inDataList[i]); } } } return diffList; } // 计算大小 public static decimal GetDiffSize(List diffList) { decimal size = 0; foreach(ResourceFile rf in diffList) { size += rf.size; } return size / 1048576; } } class HotFixConfig { public string desc; public string dir_name; public bool isCalSize = false; public bool isChoose = false; public List hotFixSettings; public decimal project_local_size = 0; public List project_local_list; public HotFixConfig(string _dir_name) { desc = _dir_name; dir_name = _dir_name; hotFixSettings = new List(); // isCalSize = false; } // 添加配置文件夹 public void AddSetting(string _desc, string _dir_name, string _dir_cdn_setting) { hotFixSettings.Add(new HotFixSetting(_desc, _dir_name, _dir_cdn_setting)); } // 计算本地到工程的大小 public void CalHotFixSize() { if (HotfixWindow._HotFixProjectPath.Equals("")) { UnityEngine.Debug.LogError("热更工程路径为空!"); return; } // 工程中的位置 string project_files_path = Application.dataPath + "/../BuildABs/" + HotfixWindow.Platform + "/"; // GIT位置 string local_files_path = HotfixWindow._HotFixProjectPath + "/Root/" + dir_name + "/" + HotfixWindow.Platform + "/"; // 计算差异文件 project_local_list = HotFixTool.GetDiffList(HotFixTool.GetFilesList(project_files_path), HotFixTool.GetFilesList(local_files_path)); // 计算大小 project_local_size = HotFixTool.GetDiffSize(project_local_list); // isCalSize = true; } } class HotFixSetting { public string desc; // 设置描述 public string dir_name; // 热更分支文件夹 public string dir_cdn_setting; // cdn设置文件夹 public string path_cdn_setting;// cdn设置文件夹全路径 public bool isCalSize = false; // 判断是否计算过大小了 public bool isChoose = false; // 是否被选中 public decimal local_cdn_size = 0; // git与cdn比较 热更文件的文件大小 public decimal project_cdn_size = 0; // 工程与cdn比较 热更文件的文件大小 public List local_cdn_list; // git与cdn比较 热更文件列表 public List project_cdn_list; // 工程与cdn比较 热更文件列表 public VersionTxt local_version; public HotFixSetting(string _desc, string _dir_name, string _dir_cdn_setting) { desc = _desc; dir_name = _dir_name; dir_cdn_setting = _dir_cdn_setting; path_cdn_setting = HotfixWindow._HotFixProjectPath + "/Root/" + dir_name + "/" + dir_cdn_setting + "/"; isCalSize = false; } public void CalHotFixSize() { if(HotfixWindow._HotFixProjectPath.Equals("")){ UnityEngine.Debug.LogError("热更工程路径为空!"); return; } // cdn上files文件保存的位置 string cdn_files_path = path_cdn_setting + "__Download/"; // 工程中的位置 string project_files_path = Application.dataPath + "/../BuildABs/" + HotfixWindow.Platform + "/"; // GIT位置 string local_files_path = HotfixWindow._HotFixProjectPath + "/Root/" + dir_name + "/" + HotfixWindow.Platform + "/"; // 读取version文件 string json = File.ReadAllText(path_cdn_setting + AppConst.GameVersionFile); local_version = JsonUtility.FromJson(json); // 下载cdn上的files文件 HotFixTool.RegetExternalFile(local_version.resUrl + HotfixWindow.Platform, cdn_files_path); // 计算差异文件 local_cdn_list = HotFixTool.GetDiffList(HotFixTool.GetFilesList(local_files_path), HotFixTool.GetFilesList(cdn_files_path)); project_cdn_list = HotFixTool.GetDiffList(HotFixTool.GetFilesList(project_files_path), HotFixTool.GetFilesList(cdn_files_path)); // 计算大小 local_cdn_size = HotFixTool.GetDiffSize(local_cdn_list); project_cdn_size = HotFixTool.GetDiffSize(project_cdn_list); // isCalSize = true; } } //看热更大小 public class HotfixWindow : EditorWindow { static string[][] _SettingConfig = new string[][]{ new string[]{ "C轮测试v2", "mht_china/local", "cdn_v2", "china/dev-c" }, new string[]{ "C轮测试v3", "mht_china/local", "cdn_v3", "china/dev-c" } }; static Dictionary _HotFixConfigDic = new Dictionary(); static string benchName = ""; public static string _HotFixProjectPath; #if UNITY_ANDROID public static string Platform = "Android"; #elif UNITY_IOS public static string Platform = "IOS"; #else public static string Platform = "Android"; #endif [MenuItem("Build/Hotfix")] static void Init() { benchName = GitUtil.GetCurBenchName(); UnityEngine.Debug.Log("当前分支:" + benchName); _HotFixProjectPath = EditorPrefs.GetString("_HotFixProjectPath", ""); InitData(); InitStyle(); // Get existing open window or if none, make a new one: HotfixWindow window = (HotfixWindow)EditorWindow.GetWindow(typeof(HotfixWindow)); window.titleContent = new GUIContent("热更大小"); window.Show(); } static void InitData() { _HotFixConfigDic.Clear(); foreach (string[] sc in _SettingConfig) { string desc = sc[0]; string folder = sc[1]; string setting = sc[2]; string bench = sc[3]; if (bench.Equals(benchName)) { HotFixConfig hfc; _HotFixConfigDic.TryGetValue(folder, out hfc); if (hfc == null) { hfc = new HotFixConfig(folder); _HotFixConfigDic.Add(folder, hfc); } hfc.AddSetting(desc, folder, setting); } } } // 自定义style static GUIStyle FStyle = new GUIStyle(); static GUIStyle SStyle = new GUIStyle(); static void InitStyle() { FStyle.fontSize = 30; FStyle.fontStyle = FontStyle.Bold; SStyle.fontSize = 25; } void OnGUI() { EditorGUILayout.BeginVertical(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("当前工程GIT分支:"+ benchName); EditorGUILayout.BeginHorizontal(); _HotFixProjectPath = EditorGUILayout.TextField("热更GIT工程地址:", _HotFixProjectPath); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { _HotFixProjectPath = EditorUtility.OpenFolderPanel("Resource path", _HotFixProjectPath, _HotFixProjectPath); EditorPrefs.SetString("_HotFixProjectPath", _HotFixProjectPath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("请选择要更新的CDN:"); foreach(string k in _HotFixConfigDic.Keys)// i = 0; i < _CurConfig.Length; i++) { HotFixConfig _CurConfig = _HotFixConfigDic[k]; _CurConfig.isChoose = EditorGUILayout.ToggleLeft(""+_CurConfig.desc+"", _CurConfig.isChoose, FStyle, GUILayout.Height(40)); if (_CurConfig.isChoose) { EditorGUILayout.LabelField("工程到Git:"+_CurConfig.project_local_size.ToString("0.00") + "M"); if (!_CurConfig.isCalSize) { _CurConfig.CalHotFixSize(); } //EditorGUILayout.LabelField("本地到CDN目录:"+_CurConfig[i].local_cdn_size.ToString("0.00") + "M"); //EditorGUILayout.LabelField("工程到CDN目录:"+_CurConfig[i].project_cdn_size.ToString("0.00") + "M"); //EditorGUILayout.BeginHorizontal(); //if (GUILayout.Button("编辑Config", GUILayout.Height(20f))) //{ //} //if (GUILayout.Button("编辑Version", GUILayout.Height(20f))) //{ //} //// 自动计算一遍大小 //if (!_CurConfig.isCalSize) //{ // _CurConfig.CalHotFixSize(); //} //EditorGUILayout.EndHorizontal(); foreach (HotFixSetting hfs in _CurConfig.hotFixSettings)// i = 0; i < _CurConfig.Length; i++) { hfs.isChoose = EditorGUILayout.ToggleLeft("" + hfs.desc + "", hfs.isChoose, SStyle, GUILayout.Height(30)); if (hfs.isChoose) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("GIT到CDN:" + hfs.local_cdn_size.ToString("0.00") + "M"); EditorGUILayout.LabelField("工程到CDN:" + hfs.project_cdn_size.ToString("0.00") + "M"); EditorGUILayout.EndVertical(); if (GUILayout.Button("编辑Config", GUILayout.Height(40f), GUILayout.Width(100f))) { string tpath = hfs.path_cdn_setting + AppConst.GameConfigFile; ProcessUtil.OpenText(tpath); } if (GUILayout.Button("编辑Version", GUILayout.Height(40f), GUILayout.Width(100f))) { string tpath = hfs.path_cdn_setting + AppConst.GameVersionFile; ProcessUtil.OpenText(tpath); } // 自动计算一遍大小 if (!hfs.isCalSize) { hfs.CalHotFixSize(); } EditorGUILayout.EndHorizontal(); } } } } EditorGUILayout.EndVertical(); } } }