325 lines
12 KiB
C#
325 lines
12 KiB
C#
|
namespace Thousandto.Update.Flow
|
|||
|
{
|
|||
|
using Thousandto.Update.Data;
|
|||
|
using Thousandto.Update.Log;
|
|||
|
using Thousandto.Update.Xml;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using MD5Utils = UnityEngine.Gonbest.MagicCube.MD5Utils;
|
|||
|
|
|||
|
public class Flow8ExCheckResource : BaseFlow
|
|||
|
{
|
|||
|
private int _checkedCount;
|
|||
|
private DataModel _currentData;
|
|||
|
private List<string> _forceCheckMd5List;
|
|||
|
private List<MapFileData> _parsedMapDataList;
|
|||
|
private Dictionary<string, MapFileData> _backDownloadDict;
|
|||
|
private RepairRecordFileData _repairRecords=null;
|
|||
|
//本地不存在的文件,需要加入到静默更新列表中
|
|||
|
internal List<MapFileData> BackDownloadList;
|
|||
|
|
|||
|
//忽略的文件
|
|||
|
private static string[] _ignoreFiles = new string[] {
|
|||
|
"localversion.xml",
|
|||
|
"filelist.txt",
|
|||
|
//"thousandtoupdate.bytes",
|
|||
|
//"ThousandtoBase.bytes",
|
|||
|
//"ThousandtoCore.bytes",
|
|||
|
//"ThousandtoDeclare.bytes",
|
|||
|
//"ThousandtoLogic.bytes",
|
|||
|
//"ThousandtoSDK.bytes",
|
|||
|
//"ThousandtoUIForm.bytes",
|
|||
|
//"ThousandtoUpdate.bytes",
|
|||
|
//"ThousandtoUpdateForm.bytes",
|
|||
|
//"Lua.bytes",
|
|||
|
};
|
|||
|
|
|||
|
// 必须进行修复检查的资源,这些文件有一个特征,就是通过FileStream读取,并且都不大
|
|||
|
private static string[] _needRepairDirs = new string[]
|
|||
|
{
|
|||
|
"resources/config/",
|
|||
|
"resources/mapInfo/"
|
|||
|
};
|
|||
|
|
|||
|
//判断是否忽略
|
|||
|
private bool IsCheckIgnoreFile(string filePath)
|
|||
|
{
|
|||
|
var tmp = filePath.ToLower();
|
|||
|
for (int i = 0; i < _ignoreFiles.Length; i++)
|
|||
|
{
|
|||
|
if (tmp.IndexOf(_ignoreFiles[i])>=0)
|
|||
|
{
|
|||
|
UpdateLog.DEBUG_LOG("忽略文件:" + filePath);
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
//判断必须进行修复检查的文件
|
|||
|
private bool IsNeedCheckRepair(string filePath)
|
|||
|
{
|
|||
|
var tmp = filePath.ToLower();
|
|||
|
for (int i = 0; i < _needRepairDirs.Length; i++)
|
|||
|
{
|
|||
|
if (tmp.IndexOf(_needRepairDirs[i]) >= 0)
|
|||
|
{
|
|||
|
UpdateLog.DEBUG_LOG("必须进行修复检查的文件:" + filePath);
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private int checkLocalFile(bool useMd5 = true)
|
|||
|
{
|
|||
|
UpdateLog.DEBUG_LOG("检查本地文件md5+++ , useMd5=" + useMd5);
|
|||
|
_repairRecords.Read();
|
|||
|
int count = this._parsedMapDataList.Count;
|
|||
|
this._checkedCount = 0;
|
|||
|
int insertSceneIndex = 0;
|
|||
|
for (int i = 0; i < this._parsedMapDataList.Count; i++)
|
|||
|
{
|
|||
|
this._checkedCount++;
|
|||
|
MapFileData item = this._parsedMapDataList[i];
|
|||
|
if (!IsCheckIgnoreFile(item.Name))
|
|||
|
{
|
|||
|
bool needRepair = false;
|
|||
|
var isBytes = item.Name.EndsWith(".bytes");
|
|||
|
if (IsExists(item, useMd5 || isBytes, out needRepair))
|
|||
|
{
|
|||
|
if (needRepair)
|
|||
|
{
|
|||
|
RepairList.Add(item);
|
|||
|
_repairRecords.IncRepairCount(item.Dir + item.Name);
|
|||
|
//UpdateLog.ERROR_LOG("need repaire: " + item.Dir + item.Name);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string path = BaseFlow._storeDir + "/" + item.Dir + item.Name;
|
|||
|
_backDownloadDict.Add(path, item);
|
|||
|
if (item.Dir.IndexOf("/Scene/") > 0)
|
|||
|
{
|
|||
|
this.BackDownloadList.Insert(insertSceneIndex++, item);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//UpdateLog.ERROR_LOG("back download: " + item.Dir + item.Name);
|
|||
|
this.BackDownloadList.Add(item);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (RepairList.Count > 0)
|
|||
|
{
|
|||
|
_repairRecords.Write();
|
|||
|
}
|
|||
|
|
|||
|
MapFileDataListForDownload = RepairList;
|
|||
|
|
|||
|
UpdateLog.DEBUG_LOG("检查本地文件md5--- ,需要静默下载的文件数:"+ BackDownloadList.Count+";;需要修补的文件数:" + RepairList.Count);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
public override void GetCurDownInfo(out string url, out int total, out int downloaded)
|
|||
|
{
|
|||
|
url = "";
|
|||
|
total = (this._parsedMapDataList == null) ? 0 : this._parsedMapDataList.Count;
|
|||
|
downloaded = this._checkedCount;
|
|||
|
}
|
|||
|
|
|||
|
public bool IsExists(MapFileData item, bool useMd5, out bool needRepair)
|
|||
|
{
|
|||
|
needRepair = false;
|
|||
|
string relativePath = item.Dir + item.Name;
|
|||
|
string storePath = BaseFlow._storeDir + "/" + relativePath;
|
|||
|
string inAppPath = BaseFlow._appDir + "/" + relativePath;
|
|||
|
string existPath = null;
|
|||
|
//1.首先判断外部目录中是否存在这个文件
|
|||
|
//先直接通过拼接路径判断是否存在
|
|||
|
if (File.Exists(storePath))
|
|||
|
existPath = storePath;
|
|||
|
|
|||
|
//2.判断是否修复
|
|||
|
if (!string.IsNullOrEmpty(existPath))
|
|||
|
{//2.1 如果外部文件存在,就判断外部文件
|
|||
|
//UpdateLog.ERROR_LOG("Updatefile: " + existPath);
|
|||
|
if(useMd5)
|
|||
|
needRepair = !CompareFileMd5(existPath, item);
|
|||
|
else
|
|||
|
needRepair = !CompareFileSize(existPath, item);
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{//2.2如果外部文件不存在
|
|||
|
|
|||
|
if (IsNeedCheckRepair(relativePath))
|
|||
|
{//2.2.1 处理外部必须存在的文件
|
|||
|
|
|||
|
needRepair = true;
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{//2.2.2 处理那些包体内存在的文件
|
|||
|
string md5 = null;
|
|||
|
int size = 0;
|
|||
|
//在尝试读取包内文件配置信息
|
|||
|
if (Manager.UpdateManager.Instance.TryGetInAppData(relativePath, out md5, out size))
|
|||
|
{
|
|||
|
//包内文件,直接MD5和size一起比较,因为没有计算消耗
|
|||
|
needRepair = (item.Md5 != md5) || (item.FileSize != size);
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public MapFileData GetMapFileDataByPath(string path)
|
|||
|
{
|
|||
|
MapFileData data = null;
|
|||
|
string str = Path.GetDirectoryName(path).Replace(@"\", "/") + "/";
|
|||
|
string fileName = Path.GetFileName(path);
|
|||
|
// for (int i = 0; i < this._parsedMapDataList.Count; i++)
|
|||
|
// {
|
|||
|
// if (((this._parsedMapDataList[i].Dir != null) && (str.IndexOf(this._parsedMapDataList[i].Dir) >= 0)) && ((fileName != null) && fileName.Equals(this._parsedMapDataList[i].Name, StringComparison.OrdinalIgnoreCase)))
|
|||
|
// {
|
|||
|
// data = this._parsedMapDataList[i];
|
|||
|
// data.FullPath = path;
|
|||
|
// return data;
|
|||
|
// }
|
|||
|
// }
|
|||
|
|
|||
|
//绝对路径
|
|||
|
if (path.IndexOf(_storeDir) == -1)
|
|||
|
{
|
|||
|
path = _storeDir + "/" + path;
|
|||
|
}
|
|||
|
_backDownloadDict.TryGetValue(path, out data);
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
public List<MapFileData> GetMapListDataToDownload()
|
|||
|
{
|
|||
|
return RepairList;
|
|||
|
}
|
|||
|
|
|||
|
public override void Inititalize()
|
|||
|
{
|
|||
|
base.Inititalize();
|
|||
|
RepairList = new List<MapFileData>();
|
|||
|
this._parsedMapDataList = new List<MapFileData>();
|
|||
|
this.BackDownloadList = new List<MapFileData>();
|
|||
|
_backDownloadDict = new Dictionary<string, MapFileData>();
|
|||
|
}
|
|||
|
|
|||
|
public override void OnEnter(BaseFlow oldFlow)
|
|||
|
{
|
|||
|
base.OnEnter(oldFlow);
|
|||
|
this._currentData = base.CurrentRemoteData;
|
|||
|
_repairRecords = new RepairRecordFileData();
|
|||
|
}
|
|||
|
|
|||
|
private int parseMapFiles()
|
|||
|
{
|
|||
|
UpdateLog.DEBUG_LOG("解析map文件+++");
|
|||
|
int num = 1;
|
|||
|
RepairList.Clear();
|
|||
|
this.BackDownloadList.Clear();
|
|||
|
_backDownloadDict.Clear();
|
|||
|
this._parsedMapDataList.Clear();
|
|||
|
string resourceUrl = "";
|
|||
|
for (int i = 0; i < this._currentData.VersionModelBaseList.Count; i++)
|
|||
|
{
|
|||
|
VersionModel model = this._currentData.VersionModelBaseList[i];
|
|||
|
string str2 = model.Map_url.Replace(@"\", "/");
|
|||
|
string str3 = str2.Substring(str2.LastIndexOf("/") + 1);
|
|||
|
string mapFile = Path.Combine(BaseFlow._storeDir, str3);
|
|||
|
resourceUrl = model.ResourceUrl;
|
|||
|
MapFileManage manage = new MapFileManage();
|
|||
|
num = manage.parseMapFile(mapFile, model.ResourceUrl, BaseFlow._storeDir);
|
|||
|
if (num <= -1)
|
|||
|
{
|
|||
|
return num;
|
|||
|
}
|
|||
|
this._parsedMapDataList.AddRange(manage.GetMapFileDataList());
|
|||
|
}
|
|||
|
UpdateLog.DEBUG_LOG("解析map文件---");
|
|||
|
return num;
|
|||
|
}
|
|||
|
|
|||
|
public void SetExternalData(List<string> forceCheckList)
|
|||
|
{
|
|||
|
this._forceCheckMd5List = forceCheckList;
|
|||
|
}
|
|||
|
|
|||
|
public override void Uninitialize()
|
|||
|
{
|
|||
|
if (RepairList != null)
|
|||
|
{
|
|||
|
RepairList.Clear();
|
|||
|
}
|
|||
|
if (this._parsedMapDataList != null)
|
|||
|
{
|
|||
|
this._parsedMapDataList.Clear();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override int Work()
|
|||
|
{
|
|||
|
if (!base.CheckLastFlowResult())
|
|||
|
{
|
|||
|
return base.LastFlowResult;
|
|||
|
}
|
|||
|
|
|||
|
int num = this.parseMapFiles();
|
|||
|
if (num >= 1)
|
|||
|
{
|
|||
|
Recorder.StepRecorder.AddStep(Recorder.StepType.DownloadAndParseMapFile);
|
|||
|
num = this.checkLocalFile(NeedPatch());
|
|||
|
|
|||
|
var success = num >= CodeDefine.RET_SUCCESS;
|
|||
|
Recorder.StepRecorder.AddStep(Recorder.StepType.CheckNeedUpdateFiles, success ? 0: 1, success.ToString());
|
|||
|
}
|
|||
|
else
|
|||
|
Recorder.StepRecorder.AddStep(Recorder.StepType.DownloadAndParseMapFile, 3, "下载成功但是解析失败");
|
|||
|
|
|||
|
return num;
|
|||
|
}
|
|||
|
|
|||
|
//是否有补丁版本升级, 有升级,则需要比对md5
|
|||
|
private bool NeedPatch()
|
|||
|
{
|
|||
|
string localPathVersion = LocalXml.PatchResVersion;
|
|||
|
string latestPathVersion = localPathVersion;
|
|||
|
if (_currentData.LastVersionPatch != null)
|
|||
|
{
|
|||
|
latestPathVersion = _currentData.LastVersionPatch.ToVersion;
|
|||
|
}
|
|||
|
|
|||
|
return CompareVersionFormat(latestPathVersion, localPathVersion) > 0;
|
|||
|
}
|
|||
|
|
|||
|
private bool CompareFileSize(string sourceFile, MapFileData mapData)
|
|||
|
{
|
|||
|
if (!File.Exists(sourceFile)) return false;
|
|||
|
|
|||
|
FileInfo info = new FileInfo(sourceFile);
|
|||
|
return info.Length == mapData.FileSize;
|
|||
|
}
|
|||
|
|
|||
|
private bool CompareFileMd5(string sourceFile, MapFileData mapData)
|
|||
|
{
|
|||
|
if (!File.Exists(sourceFile)) return false;
|
|||
|
|
|||
|
string md5 = MD5Utils.GetFileMD5(sourceFile);
|
|||
|
return md5 == mapData.Md5;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|