using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.IO;
//using System.Diagnostics;
//using System.Net;
using System;
using UnityEngine;
using XLua;
using LitJson;
public class ThreadEvent {
public string Key;
public List<object> evParams = new List<object>();
}
public class HasLoadFile {
public string Key;
public string KeyValue;
public string FileVersionPath;
public string FilePath;
public LuaFunction onFinish;
}
public class NotiData {
public string evName;
public object evParam;
public NotiData(string name, object param) {
this.evName = name;
this.evParam = param;
}
}
namespace LuaFramework {
[LuaCallCSharp]
public class DownloadManager : Manager {
private Thread thread;
private Action func;
private LuaFunction luaFinishCall;
//private Stopwatch sw = new Stopwatch();
private string currDownFile = string.Empty;
private ThreadEvent currentEvent;
static readonly object m_lockObj = new object();
static Queue<ThreadEvent> events = new Queue<ThreadEvent>();
static Queue<HasLoadFile> hasLoadFile = new Queue<HasLoadFile>();
private bool UIisDownloading = false; //下载大厅
private bool GameisDownloading = false; //下载游戏
private bool isDownloadGameFailure = false;//下载失败
private bool isNowUnZipFile = false; //正在解压文件
private bool isNowUnZipFileComplise = false; //解压完成
public LuaFunction onUnZipFinishCall; //解压完成回调
private int tryDownloadTimes = 0; //当前已经尝试下载的次数
private int totalDownFileNum = 0;//总需下载的文件数
private int waitUnZipFileNum = 0;//总下载的文件数
private int hasUnZipFileNum = 0;//已解压的文件数
HttpDownLoader downloader;
private Action<float> onProgressAction;
private Action<string> onFileProgressAction;
private Action<string> onUnZipFileCall;
private LuaFunction onProgressLuaFunc;
private static DownloadManager _instance;
//private GameObject messagePanel;
//private UILabel messageTxt;
private Dictionary<string, string> m_localFileVersion;
private string m_localFileVersionPath;
public static DownloadManager Instance
{
get
{
return _instance;
}
}
void Awake() {
_instance = this;
}
// Use this for initialization
void Start() {
}
public void checkUpdate(LuaFunction callBack)
{
StartCoroutine(_checkUpdate(callBack));
}
public void SaveLocalVersion()
{
string output = "";
foreach (KeyValuePair<string, string> kv in m_localFileVersion)
{
output += kv.Key + "|" + kv.Value + "\n";
}
StreamWriter sw = new StreamWriter(m_localFileVersionPath);
sw.Write(output);
sw.Close();
}
IEnumerator _checkUpdate(LuaFunction callBack)
{
string uiV = "gameui" + AppConst.UIVersion;
string VersionUrl;//下载版本信息
if (AppConst.EOSType == 3)
{
VersionUrl = AppConst.ResUrl + "/android/"+ uiV + "/files.txt";
}else if (AppConst.EOSType == 5)
{
VersionUrl = AppConst.ResUrl + "/ios/" + uiV +"/files.txt";
}
else
{
VersionUrl = AppConst.ResUrl + "/pc/" + uiV +"/files.txt";
}
WWW www = new WWW(VersionUrl);
yield return www;
if (www.error == null)
{
string filesText = System.Text.Encoding.Default.GetString(www.bytes);
string[] files = filesText.Split('\n');
for (int i = 0; i < files.Length; i++)
{
string[] keyValue = files[i].Split('|');
string f = keyValue[0].Replace(".zip", "");
string vers = keyValue[1].Replace("\r", "");
string direc = AppConst.FrameworkRoot + "/" + uiV + "/" + f;
if (!Directory.Exists(direc)) //如果游戏没存在则不理
{
//callBack.Call("f",false);
}
else
{
string version = "";
string localFilesPath = AppConst.FrameworkRoot + "/" + uiV + "/" + f + "/version.txt";
if (File.Exists(localFilesPath))
{
StreamReader sr = new StreamReader(localFilesPath);
version = sr.ReadToEnd();
sr.Close();
if (version == vers)
{
callBack.Call(f,true);
}
else
{
callBack.Call(f,false);
}
}
else
{
callBack.Call(f,false);
}
}
}
}
www.Dispose();
}
public void downloadFiles(string filesText, Action<string> onProgress,Action<string> OnUnZipFile)
{
onUnZipFileCall = OnUnZipFile;
onFileProgressAction = onProgress;
_downloadFiles(filesText);
//StartCoroutine(_downloadFiles(filesText));
}
public void downLoadGame(string gameId, LuaFunction onProgress, LuaFunction onFinish, LuaFunction onFail)
{
_downLoadGame(gameId, onProgress, onFinish, onFail);
}
void _downLoadGame(string gameId, LuaFunction onProgress, LuaFunction onFinish, LuaFunction onFail)
{
string uiV = "gameui" + AppConst.UIVersion;
string osType;
if (AppConst.EOSType == 3)
{
osType = "/android";
}else if (AppConst.EOSType == 5)
{
osType = "/ios";
}else
{
osType = "/pc";
}
string uidirec = AppConst.FrameworkRoot + "/"+ uiV;
if (!Directory.Exists(uidirec))
{
Directory.CreateDirectory(uidirec);
}
string direc = AppConst.FrameworkRoot + "/"+ uiV +"/" + gameId;
if (Directory.Exists(direc))
{
Directory.Delete(direc, true);
}
string fileUrl = AppConst.ResUrl + osType + "/"+ uiV+ "/" + gameId.Trim() + ".zip";
string localfile = AppConst.FrameworkRoot + "/" + uiV + "/" + gameId.Trim() + ".zip";
object[] param = new object[5] { fileUrl, localfile , onProgress , onFinish , onFail };
ThreadEvent ev = new ThreadEvent();
ev.Key = NotiConst.UPDATE_DOWNLOAD;
ev.evParams.AddRange(param);
DownloadManager.AddEvent(ev);
StartDownloadGame();
}
public void downloadFilesLuaCall(string filesUrlDir, string localFilesDir, LuaFunction onProgress)
{
//onProgressLuaFunc = onProgress;
//StartCoroutine(_downloadFiles(filesUrlDir, localFilesDir));
}
private ConfigInfo _gamecode;
private Action<float> _onProgress;
private Action<string> _onFinish;
public void downloadGamecode(ConfigInfo gamecode, Action<float> onProgress, Action<string> onFinish)
{
_gamecode = gamecode;
_onProgress = onProgress;
_onFinish = onFinish;
downloader = HttpDownLoader.newHttpDownLoader();
string osType;
string fileUrl;
string localFile = "";
if (AppConst.EOSType == 3)
{
osType = "android";
fileUrl = gamecode.Android_DownLoadurl;
localFile = AppConst.FrameworkRoot + "Dating" + AppConst.GameCode + ".apk";
}
else if (AppConst.EOSType == 5)
{
osType = "ios";
fileUrl = gamecode.Ios_DownLoadurl;
Application.OpenURL(fileUrl);
return;
}
else
{//暂未发布PC
osType = "pc";
fileUrl = gamecode.PC_DownLoadurl;
}
downloader.Init(fileUrl, localFile, (float percent) => { onProgress(percent); }, (string savePath) =>
{
onFinish(savePath);
_onProgress = null;
_onFinish = null;
}, OnDownloadGameVersionFailed);
}
//IEnumerator _downloadFiles(string filesText)
void _downloadFiles(string filesText)
{
//string VersionUrl = AppConst.ResUrl + filesUrlDir + "/files2.txt";
//WWW www = new WWW(VersionUrl);
//yield return www;
//if (www.error == null)
//{
totalDownFileNum = 0;
string localFilesText = string.Empty;
//string localFilesPath = AppConst.FrameworkRoot + localFilesDir + "/files2.txt";
string localFilesPath = AppConst.FrameworkRoot + "/files2.txt";
Dictionary<string, string> filesVersionDic = new Dictionary<string, string>();
//本地是否有版本文件
if (File.Exists(localFilesPath))
{
StreamReader sr = new StreamReader(localFilesPath);
localFilesText = sr.ReadToEnd();
localFilesText = localFilesText.Replace("\r", "");
sr.Close();
string[] _files = localFilesText.Split('\n');
if (_files.Length > 1)
{
for (int i = 0; i < _files.Length; i++)
{
string[] _keyValue = _files[i].Split('|');
if(_keyValue.Length >= 2)
{
if (!filesVersionDic.ContainsKey(_keyValue[0]))
{
filesVersionDic.Add(_keyValue[0], _keyValue[1]);
}
}
}
}
}else//创建版本文件
{
var file = File.Create(localFilesPath);
file.Close();
}
m_localFileVersionPath = localFilesPath;
m_localFileVersion = filesVersionDic;
//string filesText = System.Text.Encoding.Default.GetString(www.bytes);
var js = JsonMapper.ToObject(filesText);
foreach(var key in js.Keys)
{
bool canUpdate = true;
string versionStr;
string dicKey = key;
if (key == "FishAudio")
{
#if UNITY_ANDROID
versionStr = js[key]["android"][AppConst.UIVersion].ToString();
dicKey = "android/" + key + "_" + AppConst.UIVersion;
#elif UNITY_IPHONE
versionStr = js[key]["ios"][AppConst.UIVersion].ToString();
dicKey = "ios/" + key + "_" + AppConst.UIVersion;
#endif
}
else if (key == "datingui")
{
#if UNITY_ANDROID
versionStr = js[key]["android"][AppConst.UIVersion].ToString();
dicKey = "android/" + key + "_" + AppConst.UIVersion;
#elif UNITY_IPHONE
versionStr = js[key]["ios"][AppConst.UIVersion].ToString();
dicKey = "ios/" + key + "_" + AppConst.UIVersion;
#endif
}
else
{
versionStr = js[key].ToString();
}
if (filesVersionDic.ContainsKey(dicKey) && versionStr == filesVersionDic[dicKey])
{
canUpdate = false;
}
if (canUpdate)
{
totalDownFileNum = totalDownFileNum + 1;
string path = AppConst.FrameworkRoot + "/" + dicKey;
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
string fileUrl = AppConst.ResUrl + "/" + dicKey + ".zip";
string localfile = AppConst.FrameworkRoot + "/" + key + ".zip";// + "_" + AppConst.UIVersion
object[] param = new object[4] { fileUrl, localfile, dicKey, versionStr};
ThreadEvent ev = new ThreadEvent();
ev.Key = NotiConst.UPDATE_DOWNLOAD;
ev.evParams.AddRange(param);
DownloadManager.AddEvent(ev);
}
}
//}
StartDownloadUI();
}
public void getWWW(string url, LuaFunction callBack = null)
{
StartCoroutine(_getWWW(url, callBack));
}
IEnumerator _getWWW(string url, LuaFunction callBack = null)
{
if (url.Equals(string.Empty))
{
yield return null;
}
WWW www = new WWW(url);
yield return www;
if (callBack != null)
callBack.Call(www);
www.Dispose();
}
/// <summary>
/// 添加到事件队列
/// </summary>
public void AddEvent(ThreadEvent ev)
{
events.Enqueue(ev);
}
public void OnFinish(Action func)
{
this.func = func;
}
public void StartDownloadUI()
{
if (AppConst.EOSType == 3 || AppConst.EOSType == 5 )
{
//友盟统计
UnityCallAndroid.Instance.CallAndroid("umenRecord","140");
}
UIisDownloading = true;
}
public void StartDownloadGame()
{
GameisDownloading = true;
}
// Update is called once per frame
void Update()
{
if (UIisDownloading)
{
if (isNowUnZipFile)
{
if (onUnZipFileCall != null)
{
string str = "正在解压文件:"+ hasUnZipFileNum.ToString() + "/" + waitUnZipFileNum.ToString();
onUnZipFileCall(str);
}
return;
}
if (!currDownFile.Equals(string.Empty))
{
return;
}
if (events.Count == 0)
{
//下载完成先安装
if (hasLoadFile.Count > 0)
{
isNowUnZipFile = true;
System.GC.Collect();
UnZipFile();
return;
}
else
{
if (thread != null)
{
thread.Abort();
thread.Join();
thread = null;
}
}
if (this.func != null)
{
this.func();
this.func = null;
if (AppConst.EOSType == 3 || AppConst.EOSType == 5 )
{
//友盟统计
UnityCallAndroid.Instance.CallAndroid("umenRecord","141");
}
}
if (luaFinishCall != null)
{
luaFinishCall.Call();
luaFinishCall = null;
}
onProgressLuaFunc = null;
onProgressAction = null;
onFileProgressAction = null;
onUnZipFileCall = null;
UIisDownloading = false;
currentEvent = null;
isNowUnZipFile = false;
waitUnZipFileNum = 0;
hasUnZipFileNum = 0;
System.GC.Collect();
return;
}
System.GC.Collect();
tryDownloadTimes = 0;
currentEvent = events.Dequeue();
OnDownloadFile(currentEvent.evParams);
}
if (GameisDownloading)
{
if (isNowUnZipFile)
{
if (isNowUnZipFileComplise)
{
if (onUnZipFinishCall != null)
{
onUnZipFinishCall.Call();
}
isNowUnZipFileComplise = false;
}
return;
}
if (!currDownFile.Equals(string.Empty))
{
return;
}
if (Application.internetReachability == NetworkReachability.NotReachable)
{
return;
}
else
{
}
//下载一个安装一个
if (hasLoadFile.Count > 0)
{
isNowUnZipFile = true;
System.GC.Collect();
InstantceGame();
return;
}
else
{
if (thread != null)
{
thread.Abort();
thread.Join();
thread = null;
}
}
if (events.Count == 0 )
{
GameisDownloading = false;
currentEvent = null;
System.GC.Collect();
return;
}
System.GC.Collect();
tryDownloadTimes = 0;
currentEvent = events.Dequeue();
OnDownloadGame();
}
}
IEnumerator tryDownloadGames()
{
System.GC.Collect();
yield return new WaitForSeconds(1.0f);
downloader = null;
OnDownloadGame();
}
/// <summary>
///下载游戏
/// <summary>
void OnDownloadGame()
{
string url = currentEvent.evParams[0].ToString();
currDownFile = currentEvent.evParams[1].ToString();
LuaFunction onProgress = (LuaFunction)currentEvent.evParams[2];
LuaFunction onFinish = (LuaFunction)currentEvent.evParams[3];
LuaFunction onFail = (LuaFunction)currentEvent.evParams[4];
downloader = HttpDownLoader.newHttpDownLoader();
downloader.Init(url, currDownFile, (float percent) => { onProgress.Call(percent); },
(string savePath) => {
HasLoadFile ev = new HasLoadFile();
ev.Key = "";
ev.KeyValue = "";
ev.FileVersionPath = "";
ev.FilePath = savePath;
ev.onFinish = onFinish;
hasLoadFile.Enqueue(ev);
currDownFile = string.Empty;
},
() => {
tryDownloadTimes = tryDownloadTimes + 1;
if (tryDownloadTimes < 20)
{
StartCoroutine(tryDownloadGames());
//OnDownloadGame();
}
else
{
onFail.Call();
//GameObject msgBox = Instantiate(Resources.Load<GameObject>("MessageBox"));
//msgBox.transform.SetParent(GameObject.Find("UI Root").transform);
//msgBox.transform.localPosition = Vector3.zero;
//msgBox.transform.localScale = Vector3.one;
//msgBox.transform.Find("beijing/text").GetComponent<UILabel>().text = "下载游戏失败,是否重新下载?";
//msgBox.transform.Find("queren").GetComponent<UIButton>().onClick.Add(new EventDelegate(() => {
// GameObject.Destroy(msgBox);
// OnDownloadGame();
//}));
//msgBox.transform.Find("quxiao").GetComponent<UIButton>().onClick.Add(new EventDelegate(() => {
// GameObject.Destroy(msgBox);
// currDownFile = string.Empty;
//}));
}
}
);
}
/// <summary>
/// 下载文件
/// </summary>
void OnDownloadFile(List<object> evParams) {
string url = evParams[0].ToString();
currDownFile = evParams[1].ToString();
if(evParams.Count == 4)
{
string key = evParams[2].ToString();
string keyValue = evParams[3].ToString();
downloader = HttpDownLoader.newHttpDownLoader();
downloader.Init(url, currDownFile, ProgressChanged,
(string savePath) => {
m_localFileVersion[key] = keyValue;
HasLoadFile ev = new HasLoadFile();
ev.Key = key;
ev.KeyValue = keyValue;
ev.FileVersionPath = m_localFileVersionPath;
ev.FilePath = savePath;
hasLoadFile.Enqueue(ev);
waitUnZipFileNum = waitUnZipFileNum + 1;
currDownFile = string.Empty;
},
OnDownloadFailed);
}else
{
downloader = HttpDownLoader.newHttpDownLoader();
downloader.Init(url, currDownFile, ProgressChanged, OnDownLoadFinish, OnDownloadFailed);
}
}
void OnDownloadGameVersionFailed()
{
string message = "更新失败!>" + currDownFile;
GameObject msgBox = Instantiate(Resources.Load<GameObject>("MessageBox"));
msgBox.transform.SetParent(GameObject.Find("UI Root").transform);
msgBox.transform.localPosition = Vector3.zero;
msgBox.transform.localScale = Vector3.one;
msgBox.transform.Find("beijing/text").GetComponent<UILabel>().text = "下载失败,是否重新下载?";
msgBox.transform.Find("queren").GetComponent<UIButton>().onClick.Add(new EventDelegate(() => {
downloadGamecode(_gamecode, _onProgress, _onFinish);
GameObject.Destroy(msgBox);
}));
msgBox.transform.Find("quxiao").GetComponent<UIButton>().onClick.Add(new EventDelegate(() => {
Application.Quit();
}));
}
IEnumerator tryDownloads()
{
System.GC.Collect();
yield return new WaitForSeconds(1.0f);
downloader = null;
OnDownloadFile(currentEvent.evParams);
}
void OnDownloadFailed()
{
tryDownloadTimes = tryDownloadTimes + 1;
if (tryDownloadTimes < 10)
{
StartCoroutine(tryDownloads());
}
else
{
string message = "更新失败!>" + currDownFile;
GameObject msgBox = Instantiate(Resources.Load<GameObject>("MessageBox"));
msgBox.transform.SetParent(GameObject.Find("UI Root").transform);
msgBox.transform.localPosition = Vector3.zero;
msgBox.transform.localScale = Vector3.one;
msgBox.transform.Find("beijing/text").GetComponent<UILabel>().text = "网络异常,是否重试?";
msgBox.transform.Find("queren").GetComponent<UIButton>().onClick.Add(new EventDelegate(() =>
{
GameObject.Destroy(msgBox);
OnDownloadFile(currentEvent.evParams);
}));
msgBox.transform.Find("quxiao").GetComponent<UIButton>().onClick.Add(new EventDelegate(() =>
{
Application.Quit();
}));
}
}
private void ProgressChanged(float percent) {
//UnityEngine.Debug.Log("正在下载" + currDownFile + percent);
if (onProgressAction != null)
{
onProgressAction(percent);
}
if (onProgressLuaFunc != null)
{
onProgressLuaFunc.Call(percent);
}
if (onFileProgressAction != null)
{
int num = waitUnZipFileNum + 1;
string str = string.Format("正在下载文件{0}/{2}:{1:P1},首次更新可能需要等待一些时间",num,percent,totalDownFileNum);
onFileProgressAction(str);
}
//messagePanel.SetActive(true);
//messageTxt.text = "正在下载更新文件";
}
/// <summary>
/// 下载单个文件完成
/// </summary>
void OnDownLoadFinish(string savePath) {
//小游戏下载完成直接安装
if (savePath.IndexOf(".zip") != -1)
{
if (ZipFileC.UnZipFile(savePath))
{
currDownFile = string.Empty;
}
else
{
if (File.Exists(savePath))
{
File.Delete(savePath);
}
currDownFile = string.Empty;
}
}else
{
if (File.Exists(savePath))
{
File.Delete(savePath);
}
currDownFile = string.Empty;
}
}
/// <summary>
/// 解压文件
/// </summary>
void UnZipFile()
{
thread = new Thread(ThreadRun);
thread.Start();
}
void ThreadRun()
{
while (true)
{
if (hasLoadFile.Count > 0)
{
HasLoadFile ev = hasLoadFile.Dequeue();
if (ev.FilePath.IndexOf(".zip") != -1)
{
hasUnZipFileNum = hasUnZipFileNum + 1;
//if (onUnZipFileCall != null)
//{
// string str = "正在解压文件:"+ hasUnZipFileNum.ToString() + "/" + waitUnZipFileNum.ToString();
// onUnZipFileCall(str);
//}
if (ZipFileC.UnZipFile(ev.FilePath))
{
SaveLocalVersion();
}
else
{
if (File.Exists(ev.FilePath))
{
File.Delete(ev.FilePath);
}
}
}else
{
if (File.Exists(ev.FilePath))
{
File.Delete(ev.FilePath);
}
}
}
else
{
isNowUnZipFile = false;
break;
}
Thread.Sleep(1);
}
}
void InstantceGame()
{
//安装游戏
thread = new Thread(InstanceThreadRun);
thread.Start();
}
void InstanceThreadRun()
{
while (true)
{
if (isNowUnZipFileComplise == false)
{
if (hasLoadFile.Count > 0)
{
HasLoadFile ev = hasLoadFile.Dequeue();
if (ev.FilePath.IndexOf(".zip") != -1)
{
hasUnZipFileNum = hasUnZipFileNum + 1;
if (ZipFileC.UnZipFile(ev.FilePath))
{
onUnZipFinishCall = null;
onUnZipFinishCall = ev.onFinish;
isNowUnZipFileComplise = true;
//ev.onFinish.Call();
}
else
{
if (File.Exists(ev.FilePath))
{
File.Delete(ev.FilePath);
}
}
}else
{
if (File.Exists(ev.FilePath))
{
File.Delete(ev.FilePath);
}
}
}
else
{
isNowUnZipFile = false;
break;
}
}
Thread.Sleep(1);
}
}
public void dispose()
{
//GameObject.Destroy(messagePanel);
GameObject.Destroy(gameObject);
}
/// <summary>
/// 应用程序退出
/// </summary>
void OnDestroy() {
}
}
}警告 1 变量“osType”已赋值,但其值从未使用过 D:\Lua_Dating546\Assets\Scripts\Manager\DownloadManager.cs 241 20 Assembly-CSharp
错误 2 使用了未赋值的局部变量“versionStr” D:\Lua_Dating546\Assets\Scripts\Manager\DownloadManager.cs 350 64 Assembly-CSharp