Files
Main/Assets/Plugins/References/FuncellUpdate/UpdateModel/Flow/Flow8ExCheckResource.cs

325 lines
12 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
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;
}
}
}