306 lines
11 KiB
C#
306 lines
11 KiB
C#
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////断点续存的方式下载网络资源/////////////////////////////////////////
|
||
/////////////////////////TODO:UI显示下载进度///暂时使用打印替代(平板不需要)//////////////////////
|
||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using UnityEngine;
|
||
using UnityEngine.Events;
|
||
using UnityEngine.Networking;
|
||
|
||
public class DownloadAssets : MonoBehaviour
|
||
{
|
||
public static DownloadAssets Instance;
|
||
//五亿字节为一段 0.1G 100mb
|
||
double loadedBytes = 100000000;
|
||
|
||
/// <summary>
|
||
/// 存放正在下载资源的UWR事件
|
||
/// </summary>
|
||
internal Dictionary<string, UnityWebRequest> AssetsUWR = new Dictionary<string, UnityWebRequest>();
|
||
/// <summary>
|
||
/// 创建新的资源图标
|
||
/// </summary>
|
||
internal UnityEvent<Assets,string> CreateAssetcell = new UnityEvent<Assets, string>();
|
||
/// <summary>
|
||
/// 更新资源图标
|
||
/// </summary>
|
||
internal UnityEvent<Assets, string> UpdateAssetcell = new UnityEvent<Assets, string>();
|
||
/// <summary>
|
||
/// 删除资源图标
|
||
/// </summary>
|
||
internal UnityEvent<Assets, string> DeleteAssetcell = new UnityEvent<Assets, string>();
|
||
|
||
void Awake()
|
||
{
|
||
if (Instance == null)
|
||
Instance = this;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 下载资源
|
||
/// </summary>
|
||
/// <param name="fullUrl">资源url</param>
|
||
/// <param name="savePath">本地存放位置</param>
|
||
/// <param name="assets">资源信息</param>
|
||
/// <param name="isAdded">是否是新增资源</param>
|
||
/// <param name="isIcon">是否是封面</param>
|
||
public void DownLoad(string fullUrl, string savePath, Assets assets, bool isAdded, bool isIcon)
|
||
{
|
||
//完整的接口
|
||
fullUrl = WebNet.DownAssetsUrl + fullUrl;
|
||
//Debug.Log(fullUrl);
|
||
StartCoroutine(RenewDownLoad(fullUrl, savePath, assets, isAdded, isIcon));
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 断点续存
|
||
/// </summary>
|
||
/// <param name="fullUrl">资源url</param>
|
||
/// <param name="savePath">本地存放位置</param>
|
||
IEnumerator RenewDownLoad(string fullUrl, string savePath, Assets assets, bool isAdded, bool isIcon)
|
||
{
|
||
long countLength;
|
||
using (UnityWebRequest uwrGetCount = UnityWebRequest.Head(fullUrl))
|
||
{
|
||
yield return uwrGetCount.SendWebRequest();
|
||
//获取资源字节长度
|
||
long.TryParse(uwrGetCount.GetResponseHeader("Content-Length"), out countLength);
|
||
//Debug.Log($"{savePath}:{countLength}");
|
||
}
|
||
//long countLength = assets.file_size;
|
||
////Debug.LogError(fullUrl);
|
||
//if (assets.file_size > 1000000)
|
||
//{
|
||
// using (UnityWebRequest uwrGetCount = UnityWebRequest.Head(fullUrl))
|
||
// {
|
||
// yield return uwrGetCount.SendWebRequest();
|
||
// //获取资源字节长度
|
||
// countLength = long.Parse(uwrGetCount.GetResponseHeader("Content-Length"));
|
||
// //Debug.Log($"{savePath}:{countLength}");
|
||
// }
|
||
//}
|
||
|
||
using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(fullUrl))
|
||
{
|
||
//append设置为true文件写入方式为接续写入,不覆盖原文件。
|
||
unityWebRequest.downloadHandler = new DownloadHandlerFile(savePath, true);
|
||
//创建文件
|
||
FileInfo file = new FileInfo(savePath);
|
||
string filename = Path.GetFileName(savePath);//资源名字
|
||
if (!AssetsUWR.ContainsKey(filename))
|
||
AssetsUWR.Add(filename, unityWebRequest);
|
||
//当前下载的文件长度
|
||
long fileLength = file.Length;
|
||
//请求网络数据从第fileLength到最后的字节
|
||
unityWebRequest.SetRequestHeader("Range", $"bytes={fileLength}-");//设置Range值
|
||
|
||
if (!string.IsNullOrEmpty(unityWebRequest.error))
|
||
{
|
||
Debug.LogError($"下载失败{unityWebRequest.error}");
|
||
}
|
||
|
||
string jsonPath = $"{Path.GetDirectoryName(savePath)}/{assets.resource_name}.json";
|
||
//Debug.Log(jsonPath);
|
||
double currProgress = 0;
|
||
if (fileLength < countLength)
|
||
{
|
||
unityWebRequest.SendWebRequest();
|
||
while (!unityWebRequest.isDone)
|
||
{
|
||
if (File.Exists(jsonPath))
|
||
{
|
||
File.Delete(jsonPath);
|
||
}
|
||
|
||
double lastProgress = (double)fileLength / countLength;//上次下载的进度
|
||
//Debug.Log($"{savePath}上次下载:{(lastProgress * 100).ToString("0.00")}% ");
|
||
double newProgress = unityWebRequest.downloadProgress;
|
||
currProgress = lastProgress + newProgress * (1 - lastProgress);
|
||
//Debug.Log($"{savePath}已经下载:{(currProgress * 100).ToString("0.00")}% ");
|
||
|
||
if (savePath.Contains("mp4"))
|
||
{
|
||
//更新进度条
|
||
//UpdateVideoProgressUIEvent.Invoke(filename, currProgress);
|
||
}
|
||
else if (savePath.Contains("apk"))
|
||
{
|
||
//更新进度条
|
||
//UpdateAppProgressUIEvent.Invoke(filename, currProgress);
|
||
}
|
||
else
|
||
{
|
||
//其他资源更新进度条
|
||
}
|
||
|
||
//超过一定的字节关闭现在的协程,开启新的协程,将资源分段下载
|
||
if (unityWebRequest.downloadedBytes >= loadedBytes)
|
||
{
|
||
Coroutine coroutine = StartCoroutine(RenewDownLoad(fullUrl, savePath, assets, isAdded, isIcon));
|
||
StopCoroutine(coroutine);
|
||
//如果 UnityWebRequest 在进行中,就停止。
|
||
unityWebRequest.Abort();
|
||
AssetsUWR.Remove(filename);
|
||
if (!string.IsNullOrEmpty(unityWebRequest.error))
|
||
{
|
||
Debug.LogError($"{filename}下载失败:{unityWebRequest.error}");
|
||
}
|
||
Debug.Log($"开启新的携程继续下载{filename}");
|
||
yield return StartCoroutine(RenewDownLoad(fullUrl, savePath, assets, isAdded, isIcon));
|
||
}
|
||
|
||
yield return null;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//资源是完整的
|
||
DoneRecordInfo(savePath, assets, isIcon);
|
||
}
|
||
|
||
if (unityWebRequest.downloadHandler.isDone)
|
||
{
|
||
DoneRecordInfo(savePath, assets, isAdded, isIcon);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 资源是完整的,直接记录下载完成信息
|
||
/// </summary>
|
||
void DoneRecordInfo(string savePath, Assets assets, bool isIcon)
|
||
{
|
||
AssetsUWR.Remove(Path.GetFileName(savePath));
|
||
if (isIcon)
|
||
return;//如果下载的是封面,则不记录
|
||
RecordDownloaddoneAssetsinfo(assets);
|
||
}
|
||
/// <summary>
|
||
/// 下载完成记录信息
|
||
/// </summary>
|
||
void DoneRecordInfo(string savePath, Assets assets, bool isAdded, bool isIcon)
|
||
{
|
||
AssetsUWR.Remove(Path.GetFileName(savePath));
|
||
|
||
string extension = Path.GetExtension(savePath).ToLower();
|
||
|
||
switch (assets.type)//1:apk 2:video 3:image 4:file 5:maps 6:pc应用
|
||
{
|
||
case 1:
|
||
if (isIcon)
|
||
{
|
||
//Debug.Log($"封面图片:{assets.resource_name}下载完成");
|
||
if (isAdded)//资源是新增
|
||
{
|
||
Debug.Log("创建资源封面");
|
||
CreateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
else//资源是更新
|
||
{
|
||
Debug.Log("更改资源封面");
|
||
UpdateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
Debug.Log($"app资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
PicoAPI._Instance.UnInstallApp(assets.brief);
|
||
GameTools.Share.Delay(5f, () =>
|
||
{
|
||
PicoAPI._Instance.InstallApk(savePath);
|
||
});
|
||
}
|
||
break;
|
||
case 2:
|
||
if (isIcon)
|
||
{
|
||
//Debug.Log($"封面图片:{assets.resource_name}下载完成");
|
||
if (isAdded)//资源是新增
|
||
{
|
||
Debug.Log("创建资源封面");
|
||
CreateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
else//资源是更新
|
||
{
|
||
Debug.Log("更改资源封面");
|
||
UpdateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
Debug.Log($"mp4资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
}
|
||
break;
|
||
case 3:
|
||
Debug.Log($"图片资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
break;
|
||
case 4:
|
||
Debug.Log($"文件资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
break;
|
||
case 5:
|
||
Debug.Log($"地图资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
break;
|
||
case 6:
|
||
if (isIcon)
|
||
{
|
||
//Debug.Log($"封面图片:{assets.resource_name}下载完成");
|
||
if (isAdded)//资源是新增
|
||
{
|
||
Debug.Log("创建资源封面");
|
||
CreateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
else//资源是更新
|
||
{
|
||
Debug.Log("更改资源封面");
|
||
UpdateAssetcell.Invoke(assets, savePath);
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
Debug.Log($"pc应用资源:{assets.resource_name}下载完成");
|
||
//关闭下载进度条
|
||
}
|
||
break;
|
||
default:
|
||
//其他未知资源
|
||
Debug.Log($"其他资源:{assets.resource_name}下载完成");
|
||
break;
|
||
}
|
||
RecordDownloaddoneAssetsinfo(assets);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 记录下载完成的资源信息
|
||
/// </summary>
|
||
public void RecordDownloaddoneAssetsinfo(Assets assets)
|
||
{
|
||
string json = JsonUtility.ToJson(assets);
|
||
byte[] bytes = Encoding.UTF8.GetBytes(json);
|
||
string path = $"{Config.AssetsInfoPath}/{assets.resource_name}.json";
|
||
GameTools.WriteFile(path, bytes);
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
foreach (var item in AssetsUWR.Values)
|
||
{
|
||
item.Abort();
|
||
}
|
||
}
|
||
}
|