using UnityEngine;
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using GameCore;
namespace ResUpdate
{
///
/// 下载进度
///
public class DownLoadProgress
{
///
/// 已经下载的大小:Byte
///
public long Size
{
get;
private set;
}
///
/// 已经下载的大小:KB
///
public float SizeKB
{
get
{
return 1f * Size / 1024;
}
}
///
/// 已经下载的大小:MB
///
public float SizeMB {
get {
return 1f * Size / 1024/1024;
}
}
///
/// 需要下载的大小:Byte
///
public long TotalSize
{
get;
private set;
}
///
/// 需要下载的大小:KB
///
public float TotalSizeKB {
get {
return 1f * TotalSize / 1024;
}
}
///
/// 需要下载的大小:MB
///
public float TotalSizeMB
{
get {
return 1f * TotalSize / 1024/1024;
}
}
///
/// 进度
///
public float Progress {
get {
if (TotalSize == 0) return 1f;
return Mathf.Clamp01(1f * Size / TotalSize);
}
}
///
/// 下载速度
///
public float LoadSpeed
{
get;
private set;
}
///
/// 更新进度
///
/// 已经下载的大小
/// 需要下载的大小
internal void UpdateProgress(long size, long totalSize,float speed)
{
this.Size = size;
this.TotalSize = totalSize;
this.LoadSpeed = speed;
}
///
/// 重置
///
internal void Reset() {
this.Size = 0;
this.TotalSize = 0;
}
}
///
/// 资源下载器
///
public class ResourceDownloadManager : UnitySingleton
{
///
/// 下载更新间隔
///
const float DOWNLOAD_UPDATE_INTERVAL = 0.05f;
///
/// 下载线程数量
///
const int MAX_DOWNLOAD_THREADS_COUNT = 3;
///
/// 线程下载器池
///
ObjectPool downloadRequestPool = new ObjectPool(l=>l.Init(), l => l.Reset());
///
/// 线程下载器
///
List downloadRequestList = new List();
///
/// 下载完成的数据
///
Dictionary finishedRequest = new Dictionary();
///
/// 当前正在下载的数量
///
int curDownloadingCount;
///
/// 当前网络状态
///
NetworkReachability curNetworkStatus = NetworkReachability.NotReachable;
///
/// 下载URL
///
public string downloadURL
{
get;
set;
}
///
/// 是否允许从数据流量下载
///
public bool allowDowloadFromWWAN
{
get;
set;
}
void Update()
{
UpdateDownLoadList();
}
///
/// 更新下载列表
///
void UpdateDownLoadList()
{
if (downloadRequestList.Count == 0)return;
UpdateCurNetworkStatus();
ProcessDownloadList();
}
///
/// 处理下载列表
///
void ProcessDownloadList()
{
var count = Mathf.Min(MAX_DOWNLOAD_THREADS_COUNT, downloadRequestList.Count);
var i = curDownloadingCount;
for (; i < count; ++i)
{
downloadRequestList[i].Start();
curDownloadingCount++;
}
for (i = 0; i < curDownloadingCount; )
{
var downloadRequest = downloadRequestList[i];
if (downloadRequest.downLoadState == DownloadState.Finished)
{
finishedRequest.Add(downloadRequest.fileName, downloadRequest.isSuccess);
downloadRequestList.RemoveAt(i);
curDownloadingCount--;
downloadRequest.UpdateCallBack();
downloadRequest.FinishCallback();
downloadRequestPool.Release(downloadRequest);
}
else
{
downloadRequest.UpdateCallBack();
++i;
}
}
}
///
/// 校验结果
///
///
///
///
///
///
public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
bool isOk = true;
// If there are errors in the certificate chain,
// look at each error to determine the cause.
if (errors != SslPolicyErrors.None)
{
for (int i = 0; i < chain.ChainStatus.Length; i++)
{
if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown)
{
continue;
}
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
bool chainIsValid = chain.Build((X509Certificate2)certificate);
if (!chainIsValid)
{
isOk = false;
break;
}
}
}
return isOk;
}
///
/// 开始下载文件
///
/// 文件名
/// 下载地址
/// 保存的文件夹
/// 文件大小
/// 文件CRC
/// 完成回调
/// 请求参数
public void StartDownload(string file, string url, string saveDirectory, long size, string crc,Action progressAction=null , Action finishAction = null, string postContent = "")
{
if (FindInDownLoadList(file) != -1)
{
return;
}
if (finishedRequest.ContainsKey(file))
{
if (BaseLogger.isDebug) Debug.Log(string.Format("Re download file: {0}.", file));
finishedRequest.Remove(file);
}
var downloadRequest = downloadRequestPool.Get();
var stringBuilder = new StringBuilder();
var savePath = stringBuilder.Append(UpdateConfigs.PersistentDataPath).Append(saveDirectory).Append(file).ToString();
downloadRequest.Init(file, url, savePath, size, crc,progressAction, finishAction, postContent);
downloadRequestList.Add(downloadRequest);
}
///
/// 开始下载文件
///
///
///
///
///
///
public void StartDownload(string file, string url, string saveDirectory, Action progressAction = null, Action finishAction = null, string postContent = "")
{
if (FindInDownLoadList(file) != -1)
{
return;
}
if (finishedRequest.ContainsKey(file))
{
if (BaseLogger.isDebug) Debug.Log(string.Format("Re download file: {0}.", file));
finishedRequest.Remove(file);
}
var downloadRequest = downloadRequestPool.Get();
var stringBuilder = new StringBuilder();
var savePath = stringBuilder.Append(UpdateConfigs.PersistentDataPath).Append(saveDirectory).Append(file).ToString();
downloadRequest.Init(file, url, savePath,progressAction,finishAction, postContent);
downloadRequestList.Add(downloadRequest);
}
///
/// 是否下载完成
///
/// 文件名
///
public bool IsFinishDownload(string file)
{
return finishedRequest.ContainsKey(file);
}
///
/// 是否下载成功
///
/// 文件名
///
public bool IsDownloadSuccess(string file)
{
bool isSuccess = false;
finishedRequest.TryGetValue(file, out isSuccess);
return isSuccess;
}
///
/// 是否在下载中
///
/// 文件名
///
public int FindInDownLoadList(string file)
{
var count = downloadRequestList.Count;
for (var i = 0; i < count; ++i)
{
if (downloadRequestList[i].fileName == file)
{
return i;
}
}
return -1;
}
///
/// 网络是否可用
///
public bool IsNetworkReachable
{
get
{
return ((allowDowloadFromWWAN && curNetworkStatus == UnityEngine.NetworkReachability.ReachableViaCarrierDataNetwork)
|| curNetworkStatus == UnityEngine.NetworkReachability.ReachableViaLocalAreaNetwork);
}
}
///
/// 更新网络状态
///
void UpdateCurNetworkStatus()
{
NetworkReachability state = Application.internetReachability;
if (curNetworkStatus != state)
{
curNetworkStatus = state;
if (BaseLogger.isDebug) Debug.Log(string.Format("curNetworkStatus changed:{0}", curNetworkStatus));
if (!IsNetworkReachable)
{
ClearDownloadRequestList();
}
}
}
///
/// 清理下载列表
///
void ClearDownloadRequestList()
{
var count = downloadRequestList.Count;
for (var i = curDownloadingCount; i < count; i++)
{
var downloadRequest = downloadRequestList[i];
downloadRequest.FinishCallback();
downloadRequestPool.Release(downloadRequest);
}
downloadRequestList.RemoveRange(curDownloadingCount, count - curDownloadingCount);
if (BaseLogger.isDebug) BaseLogger.Log("Remove all waiting download file");
}
}
}