using UnityEngine; using UnityEngine.UI; using UnityEditor; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System; using System.Linq; using System.Security.Cryptography; /// /// 更新工具(安卓) /// By WJ 2020-04-27 11:24:14 /// public class UpdateTools_Android { /// /// 更新文件的路径 /// private static string mFilePath = Application.dataPath + @"/StreamingAssets/" + UpdateHelper.AndroidUpdateFileName; /// /// 更新的资源所在目录 /// private static string mResSavePath = Application.dataPath + @"/StreamingAssets/UpdateAndroid"; /// /// 更新信息 /// private static UpdateFileInfo mUpdateFileInfo = null; #if UNITY_ANDROID /// /// 创建资源更新版本 /// [MenuItem("Build/构建更新版本(Android)", false, 301)] private static void CreateUpdateResources() { // 读取Json文件 bool haveJson = ReadFile(); // 获取 UpdateResBackups/UpdateAndroid下面所有的.unity3d文件 string[] files = Directory.GetFiles("Assets/StreamingAssets/Res", "*.unity3d", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { string filePath = files[i]; filePath = filePath.Replace("\\", "/"); //编辑器进度条 EditorUtility.DisplayProgressBar("处理中>>>", filePath, (float)i / (float)files.Length); // 添加数据 AddData(filePath, GetFileMD5(filePath)); AssetDatabase.SaveAssets(); DoAssetReimport(filePath, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport); } // 保存更新的Json文件 SaveUpdateFile(); EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("成功", "处理完成!", "好的"); } /// /// 删除更新资源所在的文件夹 /// /// [MenuItem("Build/清空更新版本(Android)", false, 302)] private static void DeleteUpdateFile() { if (Directory.Exists(mResSavePath)) { Directory.Delete(mResSavePath, true); AssetDatabase.Refresh(); } } #endif /// /// 保存Json更新文件 /// private static void SaveUpdateFile() { // 保存文件 WriteFile(); AssetDatabase.Refresh(); } /// /// 添加数据 /// /// 名称 /// 大小信息 private static void AddData(string pathName, FileSizeInfo sizeInfo) { // 获取文件名字 string[] strs = pathName.Split('/'); string fileName = ""; if (strs.Length > 0) { fileName = strs[strs.Length - 1]; } else { fileName = pathName; } for (int i = 0; i < mUpdateFileInfo.Infos.Count; i++) { if (mUpdateFileInfo.Infos[i].Name == fileName) { if (mUpdateFileInfo.Infos[i].MD5 == sizeInfo.md5) { // 相同,什么也不做 Debug.Log(fileName + " MD5未变更,无需更新!"); } else { // md5不同,设置新md5 Debug.Log(fileName + " 原MD5:" + mUpdateFileInfo.Infos[i].MD5 + " 新MD5:" + sizeInfo.md5); mUpdateFileInfo.Infos[i].MD5 = sizeInfo.md5; mUpdateFileInfo.Infos[i].PackSizeB = sizeInfo.sizeB; mUpdateFileInfo.Infos[i].PackSizeM = sizeInfo.sizeM; mUpdateFileInfo.Infos[i].PackVersion = mUpdateFileInfo.Version + 1; // 拷贝需要更新的文件 CopyResources(pathName); } return; } } // 添加信息 FileMD5Info md5Info = new FileMD5Info(); md5Info.Name = fileName; md5Info.MD5 = sizeInfo.md5; md5Info.PackSizeB = sizeInfo.sizeB; md5Info.PackSizeM = sizeInfo.sizeM; md5Info.PackVersion = mUpdateFileInfo.Version + 1; mUpdateFileInfo.Infos.Add(md5Info); // 拷贝需要更新的文件 CopyResources(pathName); } /// /// 拷贝资源去更新文件夹 /// /// 路径 private static void CopyResources(string path) { string[] strs = path.Split('/'); string resName = ""; if (strs.Length > 0) { resName = strs[strs.Length - 1]; } if (resName == "") { return; } // 文件不存在,创建 if (Directory.Exists(mResSavePath) == false) { Directory.CreateDirectory(mResSavePath); AssetDatabase.Refresh(); } // 保存的路径 string savePath = mResSavePath + "/" + resName; // 复制 File.Copy(path, savePath); } /// /// 写文件 /// private static void WriteFile() { byte[] texts = new byte[] { }; try { // 版本叠加 mUpdateFileInfo.Version++; string AutoSaveJson = JsonUtility.ToJson(mUpdateFileInfo); byte[] curTexts = Encoding.UTF8.GetBytes(AutoSaveJson); texts = curTexts; } catch (Exception e) { Debug.LogError("Message:" + e.Message); } if (File.Exists(mFilePath)) { File.Delete(mFilePath); } using (FileStream fs = new FileStream(mFilePath, FileMode.OpenOrCreate, FileAccess.Write)) { if (fs != null) { fs.Write(texts, 0, texts.Length); fs.Flush(); fs.Dispose(); } } } /// /// 读文件 /// private static bool ReadFile() { try { string DecrypText = string.Empty; using (FileStream fs = new FileStream(mFilePath, FileMode.Open, FileAccess.Read)) { if (fs.Length > 0) { int fsLen = (int)fs.Length; byte[] heByte = new byte[fsLen]; int r = fs.Read(heByte, 0, heByte.Length); DecrypText = System.Text.Encoding.UTF8.GetString(heByte); fs.Dispose(); } } mUpdateFileInfo = JsonUtility.FromJson(DecrypText); } catch (Exception e) { mUpdateFileInfo = new UpdateFileInfo(); return false; } return true; } /// /// 获取文件的md5 /// /// 路径 /// md5 public static FileSizeInfo GetFileMD5(string filePath) { FileSizeInfo sizeInfo = new FileSizeInfo(); try { FileStream fs = new FileStream(filePath, FileMode.Open); int len = (int)fs.Length; byte[] data = new byte[len]; fs.Read(data, 0, len); fs.Close(); MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(data); string fileMD5 = ""; foreach (byte b in result) { fileMD5 += Convert.ToString(b, 16); } sizeInfo.md5 = fileMD5; sizeInfo.sizeB = len; // 1048576=1024 * 1024 sizeInfo.sizeM = len / 1048576; return sizeInfo; } catch (FileNotFoundException e) { Console.WriteLine(e.Message); return sizeInfo; } } /// /// 同步编辑器进度条 /// /// 路径 /// 选项 public static void DoAssetReimport(string path, ImportAssetOptions options) { try { AssetDatabase.StartAssetEditing(); AssetDatabase.ImportAsset(path, options); } finally { AssetDatabase.StopAssetEditing(); } } }