using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; using Thousandto.Update.Xml; using Thousandto.Update.Log; using Thousandto.Update.Data; using Thousandto.Update.Delegate; using Thousandto.Update.Enum; namespace Thousandto.Update.Flow { /// /// /// public abstract class BaseFlow { public bool ConfirmAfterPause; //当前流程的结果 public int CurrentFlowResult; //是否使用了http下载,用于显示进度的时候转换下载速度 public bool UseDownload; /// /// 流程名字 /// public FlowEnum FlowType = FlowEnum.Flow1TransResource; //修复列表 public List RepairList; //暂停,等待确认 private bool _pause; //初始化 private bool _initialized; //最近一次流程结果 protected int _recentResult = CodeDefine.RET_INIT; #region 静态数据,版本、路径等 //正在使用的xml路径 protected static string _localXmlPath; //包内localXml路径, 主要是ios有释放资源和不释放资源的路径访问问题 protected static string _inAppLocalXmlPath; //本地localXml路径(释放出去的路径) protected static string _storedLocalXmlPath; //包内的app版本和分段版本 protected static string _inAppClientVersion; protected static string _inAppBaseVersion; //本地保存资源的根路径 protected static string _storeDir; protected static string _appDir; //是否支持提示下载 private static bool _enablePause = true; //调用下载提示,弹出提示框 private static DownloadNoticeCall _callDownloadNotice; //每个流程结束调用 private static ActionCall _perFlowActionCall; //已经转移过资源的标签值 protected const string _hasCopyTag = "yes"; #endregion #region //上一个流程传递到下一个流程的数据,没有值的就不传 //继续后的localXml数据 public LocalVersionXml LocalXml; //RemoteXml解析数据 public ResourceVersionXml RemoteXml; //正式流程或者测试流程,由UseTestFlow决定 public DataModel CurrentRemoteData; //客户端下载存放地址 public string ApkStorePath; //解析的map文件数据 public List MapFileDataListForDownload; //强制检查md5的文件列表 public List ForceCheckMd5List; //本地分段号 public string LocalBaseResVersion; //上一个流程的结果 public int LastFlowResult = CodeDefine.RET_SUCCESS; #endregion public BaseFlow() { Inititalize(); } /// /// 设置基础路径 /// /// 存储LocalVersion.xml的绝对路径 /// 包内LocalVersion.xml的绝对路径 /// 释放/存储资源的根路径 public static void SetPath(string storedLocalXmlPath, string inAppLocalXmlPath, string storedPath, string appPath) { _localXmlPath = storedLocalXmlPath; _storedLocalXmlPath = storedLocalXmlPath; _inAppLocalXmlPath = inAppLocalXmlPath; _storeDir = storedPath; _appDir = appPath; CreateDir(storedPath); } /// /// 设置包内保存的相关版本 /// /// 包内的客户端版本 /// 包内分段版本 public static void SetInAppVer(string inAppClientVer, string inAppBaseVer) { _inAppClientVersion = inAppClientVer; _inAppBaseVersion = inAppBaseVer; } /// /// 返回当前客户端版本 /// /// public static string GetClientAppVer() { return _inAppClientVersion; } /// /// 初始化 /// /// 存储在指定位置的LocalVersion.xml路径 /// 存储在app中的LocalVersion.xml路径 /// 指定存储资源的根路径 public virtual void Inititalize() { _initialized = true; } /// /// 做数据拷贝,将上一个流程的数据转到当前流程 /// /// public virtual void OnEnter(BaseFlow oldFlow) { if (!_initialized) { //Inititalize(); } if (_perFlowActionCall != null) { _perFlowActionCall(null); } if (oldFlow == null) { return; } //数据拷贝 if (oldFlow.LocalXml != null) LocalXml = oldFlow.LocalXml; if (oldFlow.RemoteXml != null) RemoteXml = oldFlow.RemoteXml; if (oldFlow.CurrentRemoteData != null) CurrentRemoteData = oldFlow.CurrentRemoteData; if (!string.IsNullOrEmpty(oldFlow.LocalBaseResVersion)) LocalBaseResVersion = oldFlow.LocalBaseResVersion; if (oldFlow.MapFileDataListForDownload != null) MapFileDataListForDownload = oldFlow.MapFileDataListForDownload; if (oldFlow.ForceCheckMd5List != null) ForceCheckMd5List = oldFlow.ForceCheckMd5List; LastFlowResult = oldFlow.CurrentFlowResult; } /// /// 执行当前流程 /// /// public virtual int Work() { return 0; } /// /// 当前流程结束,保存结果 /// /// public virtual void OnLeave(int ret) { CurrentFlowResult = ret; _recentResult = ret; } //获取下载信息,链接、大小、已下载 public virtual void GetCurDownInfo(out string url, out int total, out int downloaded) { url = ""; total = 0; downloaded = 0; } public virtual void Uninitialize() { } public virtual void Abort() { Resume(false); } public virtual bool Pause(int size = 0) { ConfirmAfterPause = false; _pause = true; if (!_enablePause) { return true; } if (_callDownloadNotice != null) { _callDownloadNotice(size); } //等待用户确认 while (_pause) { //UpdateLog.DEBUG_LOG("有下载,等待用户确认"); Thread.Sleep(1000); } return ConfirmAfterPause; } public virtual void Resume(bool continueFlow) { _pause = false; ConfirmAfterPause = continueFlow; } /// /// 检查上一个流程的结果 /// /// true: 继续执行 false: 跳过 public bool CheckLastFlowResult() { //失败或者跳过 if (LastFlowResult < CodeDefine.RET_SUCCESS || LastFlowResult == CodeDefine.RET_SKIP_BY_CANCEL) { UpdateLog.DEBUG_LOG("Skip flow: " + GetType().Name); return false; } return true; } //是否已经转移过资源了 public static bool HasTransedResource() { if (File.Exists(_storedLocalXmlPath)) { var localXml = new LocalVersionXml(); localXml.parseLocalVersionXml(_storedLocalXmlPath); return localXml.HasCopy.ToLower() == _hasCopyTag; } return false; } /// /// 切换xml的读取路径 /// /// 外部存储路径 public void ChangeLocalXmlPath(bool storedPath) { if (storedPath) { _localXmlPath = _storedLocalXmlPath; } else _localXmlPath = _inAppLocalXmlPath; } public string FlowName() { return GetType().Name; } public static void CreateDir(string dirPath) { if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } } /// /// 在有资源下载时,支持暂停更新流程,提示用户下载资源 /// 某些平台强制要求提示玩家有下载 /// /// public static void SetEnablePause(bool enable) { _enablePause = enable; } /// /// 有下载需要弹出提示框,在这里做处理 /// /// public static void SetDownloadNoticeCallback(DownloadNoticeCall func) { _callDownloadNotice = func; } /// /// 每个流程结束时调用 /// /// public static void SetPerFlowActionCallback(ActionCall func) { _perFlowActionCall = func; } public static string GetStorePath() { return _storeDir; } public static int CompareVersionFormat(string ver1, string ver2) { UpdateLog.DEBUG_LOG("CompareVersionFormat: " + ver1 + " -- " + ver2); bool useDotSplit = ver1.IndexOf(".") > 0; int ret = 0; if(useDotSplit) { string[] verArray1 = ver1.Split('.'); string[] verArray2 = ver2.Split('.'); int mixLen = Math.Min(verArray1.Length, verArray2.Length); for(int i = 0; i < mixLen; ++i) { ret = CompareString(verArray1[i], verArray2[i]); if (ret != 0) { return ret; } } if (verArray1.Length != verArray2.Length) return verArray1.Length - verArray2.Length; } ret = CompareString(ver1, ver2); UpdateLog.DEBUG_LOG("CompareVersionFormat: ret = " + ret); return ret; } private static int CompareString(string str1, string str2) { UpdateLog.DEBUG_LOG("CompareString: " + str1 + " -- " + str2); if (str1.Length != str2.Length) return str1.Length - str2.Length; return str1.CompareTo(str2); } } }