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();
}
}
}