596 lines
20 KiB
C#
596 lines
20 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Collections;
|
||
using Thousandto.Update.Singleton;
|
||
using Thousandto.Update.Download;
|
||
using Thousandto.Update.Flow;
|
||
using Thousandto.Update.Data;
|
||
using Thousandto.Update.Log;
|
||
using Thousandto.Update.Delegate;
|
||
using DownloadSpeeder = UnityEngine.Gonbest.MagicCube.DownloadSpeeder;
|
||
|
||
namespace Thousandto.Update.Manager
|
||
{
|
||
/// <summary>
|
||
/// 管理后台更新
|
||
/// </summary>
|
||
public partial class UpdateManager : Singleton<UpdateManager>
|
||
{
|
||
//总的静默更新资源大小
|
||
private int _totalBaseResSize = 0;
|
||
|
||
#region //Instance
|
||
private Flow8ExCheckResource _instance;
|
||
private Flow8ExCheckResource InstanceFlow8Ex
|
||
{
|
||
get
|
||
{
|
||
if (_instance == null) _instance = FlowInstance<Flow8ExCheckResource>();
|
||
return _instance;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
//场景资源列表
|
||
private Dictionary<DataLevel, List<MapFileData>> _sceneResList = new Dictionary<DataLevel, List<MapFileData>>();
|
||
|
||
//存储下载完成的文件
|
||
private Dictionary<string, int> _downloadedFileDic = new Dictionary<string, int>();
|
||
|
||
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.PriorityLevel > (int)level)
|
||
{
|
||
mapFileData.PriorityLevel = (int)level;
|
||
}
|
||
BackDownload.AddDataToPool(mapFileData, level);
|
||
//添加到当前场景资源列表,用于统计大小,显示进度
|
||
AddToCurSceneResList(level, mapFileData);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <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);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <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="absPath"></param>
|
||
/// <returns></returns>
|
||
public bool IsFileValid(string absPath,out bool isExist)
|
||
{
|
||
string fixPath = absPath;
|
||
MapFileData data = null;
|
||
|
||
isExist = IsExistOrDownloaded(absPath, out data, out fixPath);
|
||
return (isExist || (data != null));
|
||
}
|
||
|
||
/// <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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置后台下载速度
|
||
/// </summary>
|
||
/// <param name="kbPerSecond">kb/s</param>
|
||
public void SetDownloadSpeed(int kbPerSecond)
|
||
{
|
||
BackDownload.SetDownloadSpeed(kbPerSecond);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 下载资源
|
||
/// </summary>
|
||
/// <param name="absolutPath"></param>
|
||
/// <param name="callback"></param>
|
||
/// <param name="obj"></param>
|
||
/// <returns></returns>
|
||
public bool DownloadResource(string absolutPath, UpdateAction<string, int, 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, CodeDefine.RET_BACKDOWNLOAD_SKIPBYPAUSE, obj);
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
data.DownloadCallBack = callback;
|
||
data.ArgObj = obj;
|
||
data.PriorityLevel = (int)DataLevel.High;
|
||
}
|
||
}
|
||
|
||
if (!data.Downloading)
|
||
{
|
||
//UpdateLog.DEBUG_LOG("start load file: " + fixPath);
|
||
BackDownload.AddDataToPool(data, DataLevel.High);
|
||
}
|
||
else
|
||
UpdateLog.WARN_LOG("resource is downloading: " + fixPath);
|
||
}
|
||
else
|
||
{
|
||
//UpdateLog.WARN_LOG("no map data found: " + absolutPath);
|
||
callback(absolutPath, CodeDefine.RET_BACKDOWNLOAD_INVALIDFILE, obj);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
callback(fixPath, CodeDefine.RET_BACKDOWNLOAD_ALREADYEXIST, obj);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前场景下载信息
|
||
/// </summary>
|
||
/// <param name="total"></param>
|
||
/// <param name="downloaded"></param>
|
||
public void GetCurSceneTotalResSize(out long total, out long downloaded)
|
||
{
|
||
downloaded = 0;
|
||
total = 0;
|
||
try
|
||
{
|
||
if (_sceneResList.ContainsKey(DataLevel.CurScene))
|
||
{
|
||
var resList = _sceneResList[DataLevel.CurScene];
|
||
for (int i = 0; i < resList.Count; ++i)
|
||
{
|
||
downloaded += BackDownload.GetMapDataDownloadedSize(resList[i]);
|
||
total += resList[i].FileSize;
|
||
}
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
UpdateLog.ERROR_LOG(ex.Message + "\n" + ex.StackTrace);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂停所有
|
||
/// </summary>
|
||
public void PauseAll()
|
||
{
|
||
BackDownload.PauseAll();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 恢复所有
|
||
/// </summary>
|
||
public void ResumeAll()
|
||
{
|
||
BackDownload.ResumeAll();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂停后台下载
|
||
/// </summary>
|
||
public void PauseBaseDownload()
|
||
{
|
||
BackDownload.PauseLevel(DataLevel.Low);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 恢复后台下载,与pause成对
|
||
/// </summary>
|
||
public void ResumeBaseDownload()
|
||
{
|
||
BackDownload.ResumeLevel(DataLevel.Low);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂停当前场景下载
|
||
/// </summary>
|
||
public void PauseCurSceneDownload()
|
||
{
|
||
BackDownload.PauseLevel(DataLevel.CurScene);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 恢复当前场景下载
|
||
/// </summary>
|
||
public void ResumeCurSceneDownload()
|
||
{
|
||
BackDownload.ResumeLevel(DataLevel.CurScene);
|
||
}
|
||
|
||
public bool IsPaused()
|
||
{
|
||
return BackDownload.IsPaused();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否暂停静默更新
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsBaseResPaused()
|
||
{
|
||
return BackDownload.IsBaseResPaused();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否暂停当前场景更新
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsCurScenePaused()
|
||
{
|
||
return BackDownload.IsCurScenePaused();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 当前场景资源是否下载完了
|
||
/// 需要判断队列中是否存在和是否正在下载
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsCurSceneDownloadFinish()
|
||
{
|
||
if(_sceneResList.ContainsKey(DataLevel.CurScene))
|
||
{
|
||
var curSceneResList = _sceneResList[DataLevel.CurScene];
|
||
for (int i = 0; i < curSceneResList.Count; ++i)
|
||
{
|
||
if (!File.Exists(curSceneResList[i].FullPath))
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否静默更新下载完了
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsBaseResDownloadFinish()
|
||
{
|
||
return BackDownload.GetDataCount(DataLevel.Low) == 0;
|
||
}
|
||
|
||
/// <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;
|
||
|
||
//1.检查是否在包体内
|
||
//1.1: 如果不在存储路径,并且包体内存在,那么就返回为true.这个判断一般对IOS有效,对于Android是无效的.
|
||
//1.2: 判断FileList中是否存在.
|
||
//2.检查是否下载
|
||
//2.1.如果已经下载完毕,那么就直接返回true
|
||
//2.2.判断是否在MapFile中是否存在.
|
||
//2.2.1.如果当前文件没有下载,并且文件存在,放到downloaded缓存中,那么就直接返回
|
||
//2.2.2.如果当前文件已经下载完成,那么直接使用.
|
||
//2.2.3.如果当前文件已经正在下载或者没有下载,那么就把当前文件放到最优先下载的队列中.
|
||
|
||
|
||
|
||
//如果是包内路径
|
||
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;
|
||
}
|
||
else
|
||
{
|
||
string relativePath = absolutPath.Replace(_storePath, "");
|
||
if (relativePath.StartsWith("/"))
|
||
{
|
||
relativePath = relativePath.Substring(1);
|
||
}
|
||
|
||
string md5 = null;
|
||
int size = 0;
|
||
if(TryGetInAppData(relativePath, out md5, out size))
|
||
{
|
||
ret = true;
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
{
|
||
//已经下载好了,直接返回
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 后台更新当前场景资源
|
||
/// </summary>
|
||
/// <param name="normalList"></param>
|
||
/// <param name="append"></param>
|
||
internal void BackDownloadCurSceneData(string[] normalList, bool append = false)
|
||
{
|
||
UpdateLog.WARN_LOG("Add cur scene resources");
|
||
AddDataList(normalList, DataLevel.CurScene, append);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 后台更新下一场景资源
|
||
/// </summary>
|
||
/// <param name="preLoadList"></param>
|
||
/// <param name="append"></param>
|
||
internal void BackDownloadNextSceneData(string[] preLoadList, bool append = false)
|
||
{
|
||
AddDataList(preLoadList, DataLevel.NextScene, append);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 下载场景资源
|
||
/// </summary>
|
||
/// <param name="mapID">要下载的场景ID</param>
|
||
/// <param name="current">是否当前场景</param>
|
||
public void BackDownloadSceneData(int mapID, bool current = false, bool append = false)
|
||
{
|
||
string str = string.Format("{1}/{0}.txt", mapID, _sceneConfigPath);
|
||
string path = _storePath + "/" + str;
|
||
if (!File.Exists(path))
|
||
path = _appPath + "/" + str;
|
||
|
||
if (File.Exists(path))
|
||
{
|
||
UpdateLog.WARN_LOG("download scene resource: " + str);
|
||
string[] normalList = File.ReadAllLines(path);
|
||
if (current)
|
||
{
|
||
BackDownloadCurSceneData(normalList, append);
|
||
}
|
||
else
|
||
{
|
||
BackDownloadNextSceneData(normalList, append);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UpdateLog.WARN_LOG("找不到文件: " + path);
|
||
}
|
||
}
|
||
|
||
public void BackDownloadSceneData(string[] preLoadList, bool append = false)
|
||
{
|
||
AddDataList(preLoadList, DataLevel.NextScene, append);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 静默后台更新所有资源
|
||
/// </summary>
|
||
public void BackDownloadTotalData()
|
||
{
|
||
DownloadSpeeder.Reset();
|
||
_totalBaseResSize = 0;
|
||
|
||
Flow8ExCheckResource resource = InstanceFlow8Ex;
|
||
if (resource.BackDownloadList != null)
|
||
{
|
||
for (int i = 0; i < resource.BackDownloadList.Count; i++)
|
||
{
|
||
BackDownload.AddDataToPool(resource.BackDownloadList[i], DataLevel.Low);
|
||
_totalBaseResSize += resource.BackDownloadList[i].FileSize;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 总的后台下载资源大小
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public int GetTotalBaseResSize()
|
||
{
|
||
return _totalBaseResSize;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 总的已下载大小
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public int GetTotalDownloadedSize()
|
||
{
|
||
return DownloadSpeeder.CurTotalSize;
|
||
//return BackDownload.TotalDownloadedSize;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取下载速度
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public int GetDownloadSpeed()
|
||
{
|
||
return DownloadSpeeder.CalcSpeed();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化后台更新
|
||
/// </summary>
|
||
internal void InitBackDownload(int halfCpuCoreCount = 4)
|
||
{
|
||
//初始化后台更新模块
|
||
Thousandto.Update.Download.BackDownload.InitPool(halfCpuCoreCount, convertMyActionCall(delegate(string arg1, int arg2, object arg3)
|
||
{
|
||
MapFileData data = arg3 as MapFileData;
|
||
if (arg2 < CodeDefine.RET_BACKDOWNLOAD_SUCCESS)
|
||
{
|
||
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 >= CodeDefine.RET_BACKDOWNLOAD_SUCCESS;
|
||
}));
|
||
}
|
||
|
||
private bool Exist(string path, out string fixPath)
|
||
{
|
||
if (path.IndexOf(_storePath) == 0)
|
||
{
|
||
fixPath = path;
|
||
}
|
||
else
|
||
{
|
||
fixPath = Path.Combine(_storePath, path).Replace(@"\", "/");
|
||
}
|
||
return File.Exists(fixPath);
|
||
}
|
||
}
|
||
}
|