//<summary>セーブデータからワールドを作成</summary> static public MapWorld createFromSave(string aFilePath, MyMap aMap) { MapSaveFileData tSaveData = new MapSaveFileData(aFilePath); //マップデータを記憶 mData = tSaveData; mWorld = initWorld(new Vector3Int(mData.mStratums[0].mFeild[0].Count, mData.mStratums.Count, mData.mStratums[0].mFeild.Count)); mWorld.mMap = aMap; mWorld.mMapName = mData.mMapName; mWorld.mFileData = mData; mWorld.mSaveData = tSaveData; //マップファイルへのパス mWorld.mMapPath = tSaveData.mFilePath; //生成 createFromFileData(); //生成完了 foreach (MapBehaviour tBehaviour in mWorld.GetComponentsInChildren <MapBehaviour>()) { tBehaviour.placed(); } MapWorld tCreatedWorld = mWorld; mWorld = null; mData = null; return(tCreatedWorld); }
//根据解析出来的map文件,比较本地文件的md5,如果不同,则需要重新下载 private int checkLocalFileMD5() { UpdateLog.DEBUG_LOG("检查本地文件md5+++"); int ret = CodeDefine.RET_SUCCESS; int total = _parsedMapDataList.Count; _checkedCount = 0; for (int i = 0; i < _parsedMapDataList.Count; i++) { MapFileData fileData = _parsedMapDataList[i]; if (fileData.Name.ToLower().Contains("localversion.xml") || fileData.Name.ToLower().Contains("resourceassetbundles")) { continue; } string localFile = (_storeDir + "/" + fileData.Dir + fileData.Name).Replace("\\", "/").Replace("//", "/"); string localFileMD5 = MD5.MD5File(localFile); if (localFileMD5.Equals("") || fileData.Md5.Equals(localFileMD5) == false) { MapFileDataListForDownload.Add(fileData); } _checkedCount++; } if (_checkedCount > 0) { UpdateLog.WARN_LOG("需要下载文件"); } UpdateLog.DEBUG_LOG("检查本地文件md5---"); return(ret); }
/// <summary> /// 游戏内调用,用于判断某场景是否存在 /// 如果不存在,则需要提示4G玩家等待 /// </summary> /// <param name="absolutPath"></param> /// <returns></returns> public bool IsExist(string absolutPath) { string fixPath = absolutPath; MapFileData data = null; return(IsExistOrDownloaded(absolutPath, out data, out fixPath)); }
/// <summary> /// 本地存在或者map中存在,都视为有效 /// </summary> /// <param name="absolutPath"></param> /// <returns></returns> public bool IsValid(string absolutPath) { string fixPath = absolutPath; MapFileData data = null; bool localExist = IsExistOrDownloaded(absolutPath, out data, out fixPath); return(localExist || data != null); }
public void Refresh(MapFileData fileData) { DataToDisplay = fileData; NameField.text = fileData.FileName; DateModifiedField.text = fileData.LastModified.ToString("M/d/yy"); TimeModifiedField.text = fileData.LastModified.ToString("h:m tt"); }
private static int DownloadFile(MapFileData data, string url, string saveFilePath, long begin = 0L, long end = 0L) { int num = 0; FileStream outFile = new FileStream(saveFilePath, FileMode.Create); UpdateSystem.Download.Download ins = new UpdateSystem.Download.Download(); ins.MapFileData = data; AddIns(ins); num = ins.HttpDownload(url, outFile, begin, end); RemoveIns(ins); return(num); }
public void Read(byte[] data) { using BinaryReader reader = new(new MemoryStream(data)); for (var x = 0; x < 64; ++x) { MapFileDataIDs[x] = new MapFileData[64]; for (var y = 0; y < 64; ++y) { MapFileDataIDs[x][y] = reader.Read <MapFileData>(); } } }
/// <summary> /// 下载资源 /// </summary> /// <param name="absolutPath"></param> /// <param name="callback"></param> /// <param name="obj"></param> /// <returns></returns> public bool DownloadResource(string absolutPath, UpdateAction <string, bool, object> callback, object obj) { string fixPath = absolutPath; MapFileData data = null; if (!IsExistOrDownloaded(absolutPath, out data, out fixPath)) { if (data != null) { lock (BackDownload.GetLocker()) { //暂停中,则不接受请求,原样返回 if (IsPaused()) { UpdateLog.WARN_LOG("当前是暂停状态,直接返回请求:" + absolutPath); data.DownloadCallBack = null; data.ArgObj = null; callback(fixPath, false, obj); return(true); } else { data.DownloadCallBack = callback; data.ArgObj = obj; data.DataLevel = DataLevel.High; } } if (!data.Downloading) { BackDownload.AddDataToPool(data, DataLevel.High); } else { UpdateLog.WARN_LOG("resource is downloading: " + fixPath); } } else { //UpdateLog.WARN_LOG("no map data found: " + absolutPath); callback(absolutPath, false, obj); return(true); } } else { callback(fixPath, true, obj); } return(false); }
/// <summary> /// 判断是否正在下载中,如果是,则不做提示 /// </summary> /// <param name="absolutPath"></param> /// <returns></returns> public bool IsExist(string absolutPath, out bool downloading) { downloading = false; string fixPath = absolutPath; MapFileData data = null; bool ret = IsExistOrDownloaded(absolutPath, out data, out fixPath); if (data != null) { downloading = data.Downloading; } return(ret); }
public MapFileData GetMapFileDataByPath(string path) { MapFileData data = null; string str = Path.GetDirectoryName(path).Replace(@"\", "/") + "/"; string fileName = Path.GetFileName(path); //绝对路径 if (path.IndexOf(_storeDir) == -1) { path = _storeDir + "/" + path; } _backDownloadDict.TryGetValue(path, out data); return(data); }
private int checkLocalFileMD5() { UpdateLog.DEBUG_LOG("检查本地文件md5+++"); int count = this._parsedMapDataList.Count; this._checkedCount = 0; for (int i = 0; i < this._parsedMapDataList.Count; i++) { this._checkedCount++; MapFileData item = this._parsedMapDataList[i]; string path = BaseFlow._storeDir + "/" + item.Dir + item.Name; if (item.Name.ToLower().IndexOf("localversion.xml") == -1 || item.Name.ToLower().IndexOf("resourceassetbundles") == -1) { string str2 = BaseFlow._appDir + "/" + item.Dir + item.Name; if (File.Exists(path) || File.Exists(str2)) { string str3 = MD5.MD5File(path); if (string.IsNullOrEmpty(str3)) { str3 = MD5.MD5File(str2); } if (!(!str3.Equals("") && item.Md5.Equals(str3))) { RepairList.Add(item); } } else { if (item.Name.ToLower().IndexOf("resourceassetbundles") == -1) { RepairList.Add(item); continue; //后台下载(是否后台下载) _backDownloadDict.Add(path, item); this.BackDownloadList.Add(item); } } } } if (this._checkedCount > 0) { UpdateLog.WARN_LOG("需要下载文件"); } MapFileDataListForDownload = RepairList; UpdateLog.DEBUG_LOG("检查本地文件md5---"); return(1); }
/// <summary> /// 添加失败的数据到下载队列, 如果是因为中断操作造成的,则添加到之前的下载队列中 /// 如果是正常失败,则添加到失败队列,在所有资源下载完成后在重新下载 /// </summary> /// <param name="data"></param> /// <param name="byAbort"></param> internal static void AddFailDataToPool(MapFileData data) { if (data.ErrorCode == CodeDefine.RET_SKIP_BY_ABORT) { //只有静默更新的资源才放回失败列表 if (data.DataLevel == DataLevel.Low) { _threadPool.AddData(data, data.DataLevel, true); } } else { //_threadPool.AddFailData(data); } }
private static void DownloadAction(MapFileData state) { MapFileData fileData = state; fileData.ErrorCode = CodeDefine.RET_INIT; string saveFilePath = fileData.SaveDir + "/" + fileData.Dir + fileData.Name; int num = DownloadMapData(fileData, saveFilePath); string str2 = MD5.MD5File(saveFilePath); bool success = (num >= CodeDefine.RET_SUCCESS) && fileData.Md5.Equals(str2); if (!success) { UpdateLog.ERROR_LOG("download fail: " + saveFilePath); //下载失败,删除已下载文件 File.Delete(saveFilePath); //重置下载状态 state.Downloading = false; //将失败data放回下载队列 AddFailDataToPool(fileData); //如果是因为中止操作造成下载失败,则把文件加入到当前场景下载队列,继续下载 if (num == CodeDefine.RET_SKIP_BY_ABORT) { UpdateLog.ERROR_LOG("download fail because of stop action: " + saveFilePath); //return; } } else { //累加下载大小 TotalDownloadedSize += state.FileSize; } lock (m_downloadedLocker) { fileData.Downloaded = success; if (fileData.DownloadCallBack == null) { return; } } if (_finishDownloadCallback != null) { _finishDownloadCallback(saveFilePath, success, state); } }
/// <summary> /// 添加到当前场景资源 /// </summary> /// <param name="level"></param> /// <param name="data"></param> private void AddToCurSceneResList(DataLevel level, MapFileData data) { if (level == DataLevel.CurScene) { if (!_sceneResList.ContainsKey(level)) { var dataList = new List <MapFileData>(); dataList.Add(data); _sceneResList.Add(level, dataList); } else { _sceneResList[level].Add(data); } } }
//线程回调方法,用来做具体的下载动作 public void ThreadCallBack(object state) { if (_abort) { return; } MapFileData fileData = (MapFileData)state; string saveFilePath = fileData.SaveDir + "/" + fileData.Dir + fileData.Name; //如果下载的文件失败个数超过10个,那么后面的文件就没有必要再下载了,需要检查网络 lock (this._failDownloadFile) { if (_failDownloadFile.Count >= _MAX_ERROR_LIMIT) { _failDownloadFile.Add(fileData); return; } } int ret = downloadMapData(fileData, saveFilePath); lock (m_locker) { _currentDownloadFileCount++; if (ret == CodeDefine.RET_SKIP_BY_ABORT) { UpdateLog.DEBUG_LOG("abort download: " + Thread.CurrentThread.Name); return; } //当前文件下载失败,放到失败列表中 if (ret <= CodeDefine.RET_FAIL) { _failDownloadFile.Add(fileData); return; } //文件下载成功后,对比md5是否正确,不正确也放到失败队列中 string downloadFileMD5 = MD5.MD5File(saveFilePath); if (string.IsNullOrEmpty(downloadFileMD5) || !fileData.Md5.Equals(downloadFileMD5)) { _failDownloadFile.Add(fileData); } } }
private static int DownloadUseBackCdn(MapFileData data, string url, string saveFilePath, long begin = 0L, long end = 0L) { int num = 0; if (UpdateSystem.Download.Download.UseBackupCdn(url, UpdateSystem.Download.Download.BackupCdn)) { for (int i = 0; ((num <= 0)) && (i < UpdateSystem.Download.Download.BackupCdn.Length); i++) { num = DownloadFile(data, url.Replace(Download.BackupCdn[0], Download.BackupCdn[i]), saveFilePath, begin, end); if (num == CodeDefine.RET_SKIP_BY_ABORT) { break; } } return(num); } return(DownloadFile(data, url, saveFilePath, begin, end)); }
private static int DownloadMapData(MapFileData fileData, string saveFilePath) { int code = CodeDefine.RET_INIT; try { lock (m_locker) { if (!Directory.Exists(fileData.SaveDir + "/" + fileData.Dir)) { Directory.CreateDirectory(fileData.SaveDir + "/" + fileData.Dir); } } long begin = fileData.Begin + 4 * 32 + fileData.DirLen + fileData.NameLen + fileData.Md5Len; long end = fileData.End - 1; int retryTimes = _RETRAY_TIMES; while ((retryTimes > 0) && (code <= CodeDefine.RET_INIT)) { retryTimes--; if (fileData.Name.Contains("RemoteVersion.xml") || fileData.Name.ToLower().Contains("localversion.xml")) { return(CodeDefine.RET_SUCCESS); } code = DownloadUseBackCdn(fileData, fileData.ResUrl, saveFilePath, begin, end); if (code == CodeDefine.RET_SKIP_BY_ABORT) { break; } } } catch (Exception exception) { if (saveFilePath.Contains("ClassesResources.xml")) { code = CodeDefine.RET_SUCCESS; } UpdateLog.ERROR_LOG(_TAG + "ThreadCallBack(object state) download fail: file= " + saveFilePath + "\n error" + exception.Message + "\n" + exception.StackTrace); UpdateLog.EXCEPTION_LOG(exception); } return(code); }
private void AddDataList(IEnumerable dataList, DataLevel level, bool append = false) { if (dataList != null && !append) { BackDownload.ClearData(level); if (_sceneResList.ContainsKey(level) && _sceneResList[level] != null) { _sceneResList[level].Clear(); } } Flow8ExCheckResource resource = InstanceFlow8Ex; string fixPath = ""; IEnumerator enumerator = dataList.GetEnumerator(); while (enumerator.MoveNext()) { //不存在的文件才加入到下载队列 if (!Exist(enumerator.Current as string, out fixPath)) { lock (BackDownload.GetLocker()) { MapFileData mapFileData = resource.GetMapFileDataByPath(fixPath); if (((mapFileData == null) || mapFileData.Downloading) || mapFileData.Downloaded) { UpdateLog.WARN_LOG("no map data: " + fixPath); } else { mapFileData.FullPath = fixPath; if (mapFileData.DataLevel > level) { mapFileData.DataLevel = level; } BackDownload.AddDataToPool(mapFileData, level); //添加到当前场景资源列表,用于统计大小,显示进度 AddToCurSceneResList(level, mapFileData); } } } } }
/// <summary> /// 初始化后台更新 /// </summary> internal void InitBackDownload(int halfCpuCoreCount = 4) { //初始化后台更新模块 Download.BackDownload.InitPool(halfCpuCoreCount, convertMyActionCall(delegate(string arg1, bool arg2, object arg3) { MapFileData data = arg3 as MapFileData; if (!arg2) { UpdateLog.ERROR_LOG("下载失败: " + arg1); } var func = data.DownloadCallBack; //需要设置为null,不然重复下载的文件会出问题 data.DownloadCallBack = null; if (func != null) { func(arg1, arg2, data.ArgObj); } data.Downloading = false; data.Downloaded = arg2; })); }
/// <summary> /// 多线程下载文件 /// </summary> /// <param name="mapFileDataList">文件列表</param> /// <returns>小于0失败</returns> public int DownloadFileByMultiThread(List <MapFileData> mapFileDataList) { int ret = CodeDefine.RET_FAIL; int allRetryTimes = _RETRAY_TIMES; Download.MutiDownloadedSize = 0; _abort = false; if (mapFileDataList == null) { ret = CodeDefine.RET_FAIL; return(ret); } while (_failDownloadFile.Count <= _MAX_ERROR_LIMIT && allRetryTimes > 0) { _currentDownloadFileCount = 0; _failDownloadFile.Clear(); _totalDownloadFileCount = mapFileDataList.Count; _threadPool = new HttpThreadPool <MapFileData>(_MAX_THREAD_COUNT, ThreadCallBack); for (int i = 0; i < mapFileDataList.Count; i++) { MapFileData fileData = mapFileDataList[i]; _threadPool.addTask(fileData); } //等待所有文件下载完 _threadPool.waitWhileWorking(); if (_abort) { UpdateLog.DEBUG_LOG("abort repaire download!!!"); _abort = false; return(CodeDefine.RET_SKIP_BY_ABORT); } //当失败文件数小于_MAX_ERROR_LIMIT,则这些文件重新加到下载队列里面 if (_failDownloadFile.Count != 0) { for (int i = 0; i < _failDownloadFile.Count; i++) { UpdateLog.DEBUG_LOG("有文件下载失败" + _failDownloadFile[i].Name); } mapFileDataList.Clear(); mapFileDataList.AddRange(_failDownloadFile); //_failDownloadFile.Clear(); ret = CodeDefine.RET_FAIL; } else { mapFileDataList.Clear(); _failDownloadFile.Clear(); ret = CodeDefine.RET_SUCCESS; break; } allRetryTimes--; } //到这里还有文件没有下载成功,则表示下载失败了 if (mapFileDataList.Count > 0) { UpdateLog.DEBUG_LOG("更新失败,有" + mapFileDataList.Count + "个文件下载失败"); } return(ret); }
private int downloadMapData(MapFileData fileData, string saveFilePath) { int ret = CodeDefine.RET_FAIL; try { lock (m_locker) { if (!Directory.Exists(fileData.SaveDir + "/" + fileData.Dir)) { Directory.CreateDirectory(fileData.SaveDir + "/" + fileData.Dir); } } //计算下载点,在资源包中,每个文件都有4个32字节的数据头加上文件名、md5长度,要跳过 long begin = fileData.Begin + 32 * 4 + fileData.DirLen + fileData.NameLen + fileData.Md5Len; //http的AddRange方法是闭包的,所以减一。([from, to]) long end = fileData.End - 1; //每个文件有3次下载机会 int i = _RETRAY_TIMES; while (i > 0) { i--; if (fileData.Name.Contains("RemoteVersion.xml") || fileData.Name.ToLower().Contains("localversion.xml")) { ret = CodeDefine.RET_SUCCESS; return(ret); } if (Download.UseBackupCdn(fileData.ResUrl, Download.BackupCdn)) { //使用台湾备份cdn地址 for (int cdnIndex = 0; cdnIndex < Download.BackupCdn.Length; ++cdnIndex) { string backupUrl = fileData.ResUrl.Replace(Download.BackupCdn[0], Download.BackupCdn[cdnIndex]); using (FileStream outFile = new FileStream(saveFilePath, FileMode.Create)) { ret = httpDownload(backupUrl, outFile, begin, end); if (ret >= CodeDefine.RET_SUCCESS) { break; } if (ret == CodeDefine.RET_SKIP_BY_ABORT) { return(ret); } } } if (ret >= CodeDefine.RET_SUCCESS) { break; } } else { using (FileStream outFile = new FileStream(saveFilePath, FileMode.Create)) { //UpdateLog.INFO_LOG(_TAG + " download: " + saveFilePath); ret = httpDownload(fileData.ResUrl, outFile, begin, end); if (ret >= CodeDefine.RET_SUCCESS) { break; } if (ret == CodeDefine.RET_SKIP_BY_ABORT) { return(ret); } UpdateLog.WARN_LOG(_TAG + " try download i = " + i); Thread.Sleep(_SLEEP_TIME); } } } } catch (System.Exception ex) { if (saveFilePath.Contains("ClassesResources.xml")) { ret = CodeDefine.RET_SUCCESS; } UpdateLog.ERROR_LOG(_TAG + "ThreadCallBack(object state) download fail: file= " + saveFilePath + "\n error" + ex.Message + "\n" + ex.StackTrace); UpdateLog.EXCEPTION_LOG(ex); } return(ret); }
/// <summary> /// 添加数据到下载队列, level:队列类型 /// </summary> /// <param name="data"></param> /// <param name="level"></param> internal static void AddDataToPool(MapFileData data, DataLevel level) { _threadPool.AddData(data, level); }
/// <summary> /// 本身存在或者下载完成的文件 /// </summary> /// <param name="absolutPath"></param> /// <param name="data"></param> /// <param name="fixPath"></param> /// <returns></returns> internal bool IsExistOrDownloaded(string absolutPath, out MapFileData data, out string fixPath) { bool ret = false; fixPath = absolutPath; data = null; //如果是包内路径 if (!string.IsNullOrEmpty(_appPath) && (absolutPath.IndexOf(_appPath) >= 0)) { //拼接存储路径 string path = absolutPath.Replace(_appPath, _storePath); //包内存在文件,存储路径不存在文件,直接返回 if (!File.Exists(path) && File.Exists(absolutPath)) { ret = true; return(ret); } //将路径转换成存储路径 fixPath = path; absolutPath = fixPath; } { //已经下载好了,直接返回 if (_downloadedFileDic.ContainsKey(absolutPath)) { ret = true; } else { //获取对应的MapData数据 MapFileData mapFileDataByPath = InstanceFlow8Ex.GetMapFileDataByPath(absolutPath); if (mapFileDataByPath != null) { bool skipDownload = false; //lock (BackDownload.GetLocker()) { //没有在下载中,并且存在这个文件,直接返回 if (!mapFileDataByPath.Downloading && File.Exists(absolutPath)) { _downloadedFileDic.Add(absolutPath, 0); skipDownload = true; } //下载完成状态,直接返回 else if (mapFileDataByPath.Downloaded) { _downloadedFileDic.Add(absolutPath, 0); skipDownload = true; } else { //没下载或下载中状态,添加到高优先级的下载队列 data = mapFileDataByPath; } } ret = skipDownload; } else if (File.Exists(absolutPath)) { //没有找到MapData数据,但是文件存在,依然返回true ret = true; } } } return(ret); }
private void OnSelectedFileChanged(MapFileData fileData) { CurrentlySelectedFile = fileData; FileNameField.text = CurrentlySelectedFile.FileName; }
private void OnMapDataSelected(MapFileData mapData) { NewFileNameInput.text = Path.GetFileNameWithoutExtension(mapData.FileName); }