fengye/fk101/wb_unity_pro/Assets/Scripts/HotUpdate.cs

606 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections;
using System.Collections.Generic;
using System.IO;
using taurus.client;
using taurus.unity;
using UnityEngine;
using UnityEngine.Networking;
public class Version
{
int _max_version = -1;
int _min_version = -1;
int _pack_version = -1;
string _version = "0.0.0";
public static readonly Version DEFUALT = new Version("1.0.0");
public Version(string version)
{
var tem = ReadVersionArray(version);
if (tem != null)
{
_version = version;
_max_version = tem[0];
_min_version = tem[1];
_pack_version = tem[2];
}
}
public void FillData(Version version)
{
this.max_version = version.max_version;
this.min_version = version.min_version;
this.pack_version = version.pack_version;
this._version = version._version;
}
public bool ContainAll(Version version)
{
if (_max_version != version._max_version || _min_version != version._min_version || _pack_version != version._pack_version)
{
return true;
}
return false;
}
public int max_version
{
get { return _max_version; }
set
{
if (_max_version != value)
{
_max_version = value;
_version = string.Format("{0}.{1}.{2}", _max_version, _min_version, _pack_version);
}
}
}
public int min_version
{
get { return _min_version; }
set
{
if (_min_version != value)
{
_min_version = value;
_version = string.Format("{0}.{1}.{2}", _max_version, _min_version, _pack_version);
}
}
}
public int pack_version
{
get { return _pack_version; }
set
{
if (_pack_version != value)
{
_pack_version = value;
_version = string.Format("{0}.{1}.{2}", _max_version, _min_version, _pack_version);
}
}
}
public override string ToString()
{
return _version;
}
public static int ReadVersion(string text, int index = 2)
{
try
{
var tem = text.Split(new char[] { '.' });
return int.Parse(tem[index]);
}
catch
{
return -1;
}
}
public static int[] ReadVersionArray(string text)
{
if (string.IsNullOrEmpty(text)) return null;
try
{
var tem_arr = text.Split(new char[] { '.' });
if (tem_arr == null || tem_arr.Length != 3)
{
return null;
}
int[] tem = new int[tem_arr.Length];
for (int i = 0; i < tem_arr.Length; ++i)
{
tem[i] = int.Parse(tem_arr[i]);
}
return tem;
}
catch
{
return null;
}
}
}
public class Hotupdate {
const int LOCAL_PACK = 1;
const int SERVER_PACK = 2;
[LuaInterface.NoToLua]
/// <summary>
/// 热更新资源包下载地址
/// </summary>
public static string PackUrl = string.Empty;
static Dictionary<string, Version> localVersionMap = new Dictionary<string, Version>();
string _base_path;
Version _server_version;
Version _local_version;
int _with_pack;
float _stage;
public bool isBuild32lua=false;
public Hotupdate(string base_path, string local_version, string server_version):
this(base_path,new Version(local_version),new Version(server_version))
{
}
public Hotupdate(string base_path, Version local_version, Version server_version)
{
_base_path = base_path;
_server_version = server_version;
_local_version = local_version;
_with_pack = GameApplication.HideSdk ? LOCAL_PACK : SERVER_PACK;
// #if !NOT_WITH_PACK
// _with_pack = LOCAL_PACK;
// #endif
TextTip = "正在检查资源。。。";
HideDetail = false;
}
void __DeleteOldPack()
{
string dir = ResourcesManager.PACK_PATH + _base_path;
if (Directory.Exists(dir)) Directory.Delete(dir, true);
}
public static Version GetLocalVersion(string _base_path)
{
string dir = ResourcesManager.PACK_PATH + _base_path;
string rv = dir + "version.txt";
Version local_version1 = null;
if (localVersionMap.ContainsKey(rv))
{
local_version1 = localVersionMap[rv];
}
else if (File.Exists(rv))
{
try
{
local_version1 = new Version(File.ReadAllText(rv));
localVersionMap[rv] = local_version1;
}
catch
{
return local_version1;
}
}
return local_version1;
}
public void LoadAsset()
{
GameApplication.Instance.StartCoroutine(__LoadAsset());
}
IEnumerator __LoadAsset()
{
bool _decompression = true;
string dir = ResourcesManager.PACK_PATH + _base_path;
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
string rv = dir + "version.txt";
Version local_version1 = GetLocalVersion(_base_path);
if (local_version1!=null)
{
_local_version = local_version1;
_decompression = _local_version.ContainAll(_server_version);
}
//如果没有发现本地文件解压APP包
if ((_with_pack& LOCAL_PACK)!=0&& _decompression)
{
var path = Application.streamingAssetsPath + string.Format("/{0}/{1}asset_pack{2}.bytes", ResourcesManager.OS_Dir, _base_path,_server_version.ToString());
#if !UNITY_EDITOR && UNITY_ANDROID
var www = new WWW(path);
yield return www;
var data = www.bytes;
www.Dispose();
www = null;
#else
var data = File.ReadAllBytes(path);
#endif
var zip_path = ResourcesManager.PACK_PATH + "asset_pack.bytes";
File.WriteAllBytes(zip_path, data);
data = null;
System.GC.Collect();
var finsh = false;
var tem_state = 0;
VerCheck.Instance.StartCoroutine(__UnPack(_server_version, (state) =>
{
tem_state = state;
finsh = state == 0;
},0.3f));
while (!finsh)
{
if (tem_state > 10)
{
if (__ShowTip("解压资源包时出问题,请重新下载客户端!", () =>
{
__DeleteOldPack();
Application.Quit();
}))
{
__DeleteOldPack();
Application.Quit();
}
yield break;
}
yield return null;
}
local_version1 = _local_version;
_stage = 0.3f;
}
if((_with_pack & SERVER_PACK) != 0)
{
var update_pack2 = local_version1==null || local_version1.ContainAll(_server_version);
if (update_pack2)
{
if (HideDetail) {
TextTip = string.Format ("正在下载资源包。", "游戏公共基础");
//TextTip = string.Format("正在下载{0}更新包。。",AssetName);
} else {
TextTip = string.Format("正在下载资源包。");
}
var down = false;
var _ratio = 1 - _stage;
VerCheck.Instance.StartCoroutine(DownAsset(() =>
{
down = true;
}, _server_version, _ratio * 0.6f));
while (!down)
{
yield return null;
}
var finsh = false;
var tem_state = 0;
_stage = 0.7f;
VerCheck.Instance.StartCoroutine(__UnPack(_server_version, (state) =>
{
tem_state = state;
finsh = state == 0;
}, _ratio * 0.4f));
while (!finsh)
{
if (tem_state > 10)
{
if(!__ShowTip("解压资源包时出问题,请重新下载客户端!", () =>
{
__DeleteOldPack();
Application.Quit();
}))
{
__DeleteOldPack();
Application.Quit();
}
yield break;
}
yield return null;
}
}
}
Done = true;
Progress = 1;
}
public void LoadAssetSize()
{
GameApplication.Instance.StartCoroutine(__LoadAssetSize());
}
IEnumerator __LoadAssetSize()
{
Size = 0;
bool _decompression = true;
string dir = ResourcesManager.PACK_PATH + _base_path;
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
string rv = dir + "version.txt";
Version local_version1 = GetLocalVersion(_base_path);
if (local_version1 != null)
{
_local_version = local_version1;
_decompression = _local_version.ContainAll(_server_version);
}
//如果没有发现本地文件解压APP包
if ((_with_pack & LOCAL_PACK) != 0 && _decompression)
{
var path = Application.streamingAssetsPath + string.Format("/{0}/{1}asset_pack{2}.bytes", ResourcesManager.OS_Dir, _base_path, _server_version.ToString());
#if !UNITY_EDITOR && UNITY_ANDROID
var www = new WWW(path);
yield return www;
var data = www.bytes;
www.Dispose();
www = null;
#else
var data = File.ReadAllBytes(path);
#endif
var zip_path = ResourcesManager.PACK_PATH + "asset_pack.bytes";
File.WriteAllBytes(zip_path, data);
data = null;
System.GC.Collect();
var finsh = false;
var tem_state = 0;
VerCheck.Instance.StartCoroutine(__UnPack(_server_version, (state) =>
{
tem_state = state;
finsh = state == 0;
}, 0.3f));
while (!finsh)
{
if (tem_state > 10)
{
if (__ShowTip("解压资源包时出问题,请重新下载客户端!", () =>
{
__DeleteOldPack();
Application.Quit();
}))
{
__DeleteOldPack();
Application.Quit();
}
yield break;
}
yield return null;
}
local_version1 = _local_version;
_stage = 0.3f;
}
if ((_with_pack & SERVER_PACK) != 0)
{
var update_pack2 = local_version1 == null || local_version1.ContainAll(_server_version);
if (update_pack2)
{
var down = false;
var _ratio = 1 - _stage;
VerCheck.Instance.StartCoroutine(GetAssetSize((size) =>
{
Size = size;
down = true;
}, _server_version));
while (!down)
{
yield return null;
}
}
}
Done = true;
Progress = 1;
}
IEnumerator __UnPack(Version version,System.Action<int> onback, float ratio)
{
TextTip = "正在解压资源包不消耗流量,请耐心等待";
string dir = ResourcesManager.PACK_PATH;
var zip_path = dir + "asset_pack.bytes";
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
IFilePack zip = null;
zip = new FilePack20(zip_path,PackMode.Read);
zip.UnPackFileSyn(dir);
while (!zip.Complete)
{
Progress = _stage + zip.Progress* ratio;
yield return null;
}
File.Delete(zip_path);
if (!string.IsNullOrEmpty(zip.Error))
{
onback(11);
yield break;
}
var lua_pack_path = dir + "lua_pack";
if (File.Exists(lua_pack_path))
{
var lua_dir = dir + "lua/";
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
zip = new FilePack20(lua_pack_path, PackMode.Read);
zip.UnPackFile(lua_dir);
File.Delete(lua_pack_path);
if (!string.IsNullOrEmpty(zip.Error))
{
onback(11);
yield break;
}
}
string rv = ResourcesManager.PACK_PATH + _base_path + "version.txt";
File.WriteAllText(rv, version.ToString(), System.Text.Encoding.ASCII);
localVersionMap[rv] = version;
if (onback != null)
{
Progress = _stage + 1 * ratio;
onback(0);
}
}
IEnumerator DownAsset(System.Action downcall,Version version,float ratio)
{
var pack_path = string.Format("{0}asset_pack{1}.bytes", _base_path, version.ToString());
string osPath = ResourcesManager.OS_Dir;
#if UNITY_ANDROID && !UNITY_EDITOR
if (GameApplication.Instance.isAndroid64bit == false)
{
//if (isBuild32lua)
//{
// osPath=osPath+"32";
//}
osPath=osPath+"32";
}
#endif
var url ="";
if(VerCheck.Instance.isGFF==false && VerCheck.Instance.isDXYGFF == false)
url = string.Format("{0}/{1}/{2}", PackUrl, osPath, pack_path);
else
url = string.Format("{0}/{1}/{2}", "http://" + VerCheck.Instance.conn.ip + ":" + VerCheck.Instance.conn.port + "/NewFK", osPath, pack_path);
url = string.Format("{0}/{1}/{2}", PackUrl, osPath, pack_path);
if (Application.platform == RuntimePlatform.WindowsEditor)
Debugger.Log("url:" + url);
var request = new WWW(url);
while (!request.isDone)
{
Progress = _stage + request.progress * ratio;
yield return null;
}
if (string.IsNullOrEmpty(request.error))
{
var zip_path = ResourcesManager.PACK_PATH + "asset_pack.bytes";
File.WriteAllBytes(zip_path, request.bytes);
if (downcall != null) downcall();
}
else
{
if (!__ShowTip("资源包下载失败,请检查您的网络设置!", () =>
{
VerCheck.Instance.StartCoroutine(DownAsset(downcall, version, ratio));
}))
{
Application.Quit();
}
}
}
IEnumerator GetAssetSize(System.Action<long> downcall, Version version)
{
var pack_path = string.Format("{0}asset_pack{1}.bytes", _base_path, version.ToString());
string osPath = ResourcesManager.OS_Dir;
#if UNITY_ANDROID && !UNITY_EDITOR
if (GameApplication.Instance.isAndroid64bit == false)
{
//if (isBuild32lua)
//{
// osPath=osPath+"32";
//}
osPath=osPath+"32";
}
#endif
var url = "";
if (VerCheck.Instance.isGFF == false && VerCheck.Instance.isDXYGFF == false)
url = string.Format("{0}/{1}/{2}", Hotupdate.PackUrl, osPath, pack_path);
else
url = string.Format("{0}/{1}/{2}", "http://" + VerCheck.Instance.conn.ip + ":" + VerCheck.Instance.conn.port + "/NewFKN", osPath, pack_path);
url = string.Format("{0}/{1}/{2}", Hotupdate.PackUrl, osPath, pack_path);
if (Application.platform == RuntimePlatform.WindowsEditor)
Debug.Log("check_url:" + url);
using (UnityWebRequest head = UnityWebRequest.Head(url))
{
yield return head.SendWebRequest();
#if UNITY_2020_2_OR_NEWER
if (head.result == UnityWebRequest.Result.Success)
#else
if (!head.isNetworkError && !head.isHttpError)
#endif
{
string len = head.GetResponseHeader("Content-Length");
if (!string.IsNullOrEmpty(len) && long.TryParse(len, out long size))
{
if (downcall != null) downcall(size);
yield return null;
}
else
{
Debug.LogWarning($"无法获取文件大小: {url}");
yield return 0L;
}
}
else
{
Debug.LogError($"获取文件大小失败: {head.error}");
yield return 0L;
}
}
}
bool __ShowTip(string text,System.Action callback)
{
if (this._tip_callback != null)
{
this._tip_callback(text, callback);
return true;
}
return false;
}
public void SetTipCallback(System.Action<string, System.Action> callback)
{
this._tip_callback = callback;
}
public string TextTip { get; set; }
public string AssetName { get; set; }
public bool HideDetail { get; set; }
private System.Action<string, System.Action> _tip_callback;
public float Progress
{
get;set;
}
public bool Done
{
get;set;
}
public float Size
{
get; set;
}
}