using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using System.IO;
using System.Net;
using Api;
using Extention;
namespace Helper
{
///
/// Content download engine.
///
public sealed class ContentDownloadEngine : SingletonMonoBehaviourFast
{
#region シリアライズ変数
[SerializeField]
private GameObject _progressObj;
[SerializeField]
private UISlider progressBar;
[SerializeField]
private UILabel progressLabel;
[SerializeField]
private UILabel _fileCheckLabel;
#endregion
#region Private Fields
public static bool _isLoadFin = false;
public static string _udid = "";
private List<ContentsEntity.Contents> _cacheContentsList;
private volatile int _currentDownloadCount = 0;
private volatile int _downloadListCount = 0;
private volatile bool _exeptionFlag = false;
private volatile bool _displayErrorPopupFlag = false;
private volatile bool _displayNetworkPopupFlag = false;
private int _setProgress;
private object _lockObj = new object();
private delegate void ThreadDownloadDelegate(List<Dictionary<string, string>> content, int threadId);
private List<IAsyncResult> _asyncResultList;
private volatile int _threadQueueCounter = 0;
private volatile int _threadCounter = 0;
private volatile int _tryCounter = 0;
private volatile int _autoRetry = 0;
private readonly int threadSplitCount = 5;
private readonly int mHttpRequestTimeout = 15 * 1000; // 15 Sec
private readonly string mHttpRequestUserAgent = "";
#endregion
#region Unity Events
// void OnApplicationPause (bool pauseStatus)
// {
// if (pauseStatus == true) {
// CacheAssetContentsPrefs.CacheAssetContentsFlush ();
// }
// }
void Start()
{
_currentDownloadCount = 0;
_tryCounter = 0;
_autoRetry = 0;
//Debug.Log ("ベンチマーク開始");
StartTime(); //ベンチマーク計測用
//ダウンロードの速度最適化用設定。
System.Net.ServicePointManager.UseNagleAlgorithm = false;
System.Net.ServicePointManager.DefaultConnectionLimit = 8;
//file save proccess init
CacheAssetContentsPrefs.Init ();
}
void Update ()
{
//例外が起きた場合の処理
if (_exeptionFlag == true)
{
if (_displayNetworkPopupFlag == false && _threadQueueCounter == 0) {
_displayNetworkPopupFlag = true;
HttpIoOrNetworkErrorPopup ();
} else {
if (_displayNetworkPopupFlag == false) {
Debug.Log ("displayNetworkPopupFlag : " + _displayNetworkPopupFlag);
Debug.Log ("Last Thread Counter : " + _threadQueueCounter);
}
}
lock (_lockObj){
_exeptionFlag = false;
}
return;
}
// ProgressBar
if (progressBar != null && _isLoadFin == false)
{
if (_currentDownloadCount != 0 && _cacheContentsList != null && _downloadListCount > 0)
{
progressBar.value = ((float)_currentDownloadCount / (float)_downloadListCount) * 2;
if (progressBar.value <= 0) {
_progressObj.SetActive (false);
} else {
_progressObj.SetActive (true);
}
// マイナスと100%越えは見栄えが悪いので範囲更新
_setProgress = ((int)(((float)_currentDownloadCount / (float)_downloadListCount) * 100) * 2);
if (0 <= _setProgress && _setProgress <= 100 ) {
if (_setProgress <= 0) {
progressLabel.text = "100%";
} else {
progressLabel.text = _setProgress.ToString () + "%";
}
_fileCheckLabel.gameObject.SetActive (false);
} else if (0 <= _setProgress && _setProgress <= (100 * 2)) {
//ファイルチェック中導入。
progressLabel.text = "100%";
progressBar.value = 1.0f;
_fileCheckLabel.gameObject.SetActive (true);
} else {
progressLabel.gameObject.SetActive (false);
}
} else {
_progressObj.SetActive (false); //ちらつき防止。
}
} else if (_isLoadFin == true) {
if (_progressObj != null) {
_progressObj.SetActive (false); //通信処理終わってたらFalse
}
}
}
#endregion
#region 外部用メソッド
public void MultipleDownload(object _list, bool _popupRetry = false)
{
_udid = UiidManager.GetUdid ();
if (NetworkCheck () == false) {
// _exeptionFlag = true;
// _displayNetworkPopupFlag = false;
_displayNetworkPopupFlag = true;
StartCoroutine(deferredInvoke(0.3f, ()=>{
HttpIoOrNetworkErrorPopup ();
}));
return;
}
if (_threadQueueCounter != 0) {
Debug.Log ("Async execute now : " + _threadQueueCounter);
_exeptionFlag = true;
return;
}
List<ContentsEntity.Contents> _contentsList = (List<ContentsEntity.Contents>)_list;
List<ContentsEntity.Contents> brushedUpList = new List<ContentsEntity.Contents> ();
_exeptionFlag = false;
if (_contentsList != null) {
foreach (var list in _contentsList) {
if (IsMultipleDownloadIgnore (list) == true)
continue;
string fullPath = string.Format ("{0}{1}{2}", StreamingAssetsHelper.GetDownLoadPath (), list.directory, list.file_name);
if (File.Exists (fullPath)) {
if (CacheAssetContentsPrefs.CacheAssetContentsGetString (list.file_path) != list.release_id) { //バージョン番号が一致しない場合。
brushedUpList.Add (list);
}
} else if (!File.Exists (fullPath)) { //ファイルが存在しない場合
brushedUpList.Add (list);
}
}
}
Debug.Log (brushedUpList.Count + " ダウンロード精査されたリスト数 ");
if (brushedUpList.Count <= 0)
{
Debug.Log (" 入ってる、次のシーンに飛ぶ。 ");
_isLoadFin = true;
return;
}
_cacheContentsList = brushedUpList;
_downloadListCount = _cacheContentsList.Count;
List<Dictionary<string,string>> dic = new List<Dictionary<string, string>> ();
//分散出来るように処理書く
Dictionary<int, List<ContentsEntity.Contents>> _pacialContentsList = new Dictionary<int, List<ContentsEntity.Contents>>();
List<ContentsEntity.Contents> tmpC = new List<ContentsEntity.Contents> ();
int count = 0;
int inCount = 1;
// 端末別に分割数を調整
int mThreadSplitCount = threadSplitCount;
#if UNITY_IPHONE && !UNITY_EDITOR
string deviceModel = SystemInfo.deviceModel;
Debug.Log (deviceModel);
if (deviceModel != null && deviceModel != "") {
if (deviceModel.IndexOf("iPhone3") != -1 || deviceModel.IndexOf("iPhone4") != -1) {
mThreadSplitCount = 2;
} else if (deviceModel.IndexOf("iPhone5") != -1 || deviceModel.IndexOf("iPhone6") != -1) {
mThreadSplitCount = 4;
} else if (deviceModel.IndexOf("iPad2") != -1) {
mThreadSplitCount = 2;
} else if (deviceModel.IndexOf("iPad3") != -1) {
mThreadSplitCount = 3;
} else if (deviceModel.IndexOf("iPad4") != -1) {
mThreadSplitCount = 4;
} else if (deviceModel.IndexOf("iPod") != -1) {
mThreadSplitCount = 1;
}
Debug.Log("DeviceModel : " + deviceModel + " ThreadCount : " + mThreadSplitCount);
}
#elif UNITY_ANDROID && !UNITY_EDITOR
var cls = new AndroidJavaClass("android.os.Build$VERSION");
int apiLevel = cls.GetStatic<int>("SDK_INT");
if (14 <= apiLevel && apiLevel < 17) {
mThreadSplitCount = 1;
} else if (17 <= apiLevel && apiLevel < 19) {
mThreadSplitCount = 3;
} else if (19 <= apiLevel && apiLevel < 21) {
mThreadSplitCount = 4;
}
Debug.Log("ApiLevel : " + apiLevel + " ThreadCount : " + mThreadSplitCount);
#endif
int splitCount = _cacheContentsList.Count / mThreadSplitCount;
if (splitCount == 0) {
splitCount = _cacheContentsList.Count;
}
foreach (var cList in _cacheContentsList)
{
count++;
tmpC.Add (cList);
if (splitCount <= count && count % splitCount == 0 && inCount != mThreadSplitCount) {
_pacialContentsList.Add (inCount, tmpC);
tmpC = new List<ContentsEntity.Contents> ();
//Debug.Log ("list add : " + inCount);
inCount++;
} else if (_cacheContentsList.Count == count) {
//Debug.Log ("mod all add");
_pacialContentsList.Add (inCount, tmpC);
}
}
_asyncResultList = new List<IAsyncResult>();
foreach (var pC in _pacialContentsList)
{
// Create Download List
foreach (var cList in pC.Value) {
dic.Add (new Dictionary<string, string> (){
{"_awsS3Url", string.Format ("{0}{1}", ApiData.GetContentsDataURL (ApiData.API_CONTENTS_REQUEST_URI), cList.file_path)},
{"dir", string.Format ("{0}{1}/", StreamingAssetsHelper.GetDownLoadPath (), cList.directory)},
{"file_name", cList.file_name},
{"releaseId", cList.release_id},
{"versionKey", cList.file_path},
{"hashFile", cList.file_hash}
});
}
List<Dictionary<string, string>> handOf = new List<Dictionary<string, string>> ();
handOf.AddRange (dic);
// Async Excute
_threadQueueCounter++;
ThreadDownloadDelegate tdDelegate = new ThreadDownloadDelegate (StreamLargeFile);
IAsyncResult asyncResult = tdDelegate.BeginInvoke (handOf, _threadQueueCounter, new AsyncCallback(DownloadThreadFinished), null);
_asyncResultList.Add (asyncResult);
// dic init
dic = new List<Dictionary<string, string>> ();
}
Debug.Log ("Total Thread Count : " + _threadQueueCounter);
}
#endregion
#region Private Helper Functions
/// <summary>
/// Streams the large file.
/// Calling this function again when the "DownloadProgress" key in the PlayerPrefs present will
/// continue the download
/// </summary>
/// <param name="_contentsList">Contents list.</param>
//private void StreamLargeFile(ContentsEntity.Contents _content)
private void StreamLargeFile (List<Dictionary<string, string>> _contents, int _threadId)
{
string _awsS3Url;
string dir;
string file_name;
string releaseId; //
string versionKey;//filePath
string hashFile; //ハッシュ値
string saveFileName;
HttpWebResponse tHttpWebResponse = null;
Stream tHttpWebResponseStream = null;
byte[] tResponseBytes = null;
Debug.Log ("StreamLargeFile Thread Start NO." + _threadId);
Debug.Log (_contents.Count);
foreach (var _content in _contents) {
if (_exeptionFlag == true) {
Debug.LogError ("ThreadId " + _threadId + " / Already Exception at Start");
break;
}
_awsS3Url = null;
dir = null;
file_name = null;
releaseId = null;
versionKey = null; //filePath
hashFile = null; //ハッシュ値
saveFileName = null;
if (_content.TryGetValue ("_awsS3Url", out _awsS3Url) == true &&
_content.TryGetValue ("dir", out dir) == true &&
_content.TryGetValue ("file_name", out file_name) == true &&
_content.TryGetValue ("releaseId", out releaseId) == true &&
_content.TryGetValue ("versionKey", out versionKey) == true &&
_content.TryGetValue ("hashFile", out hashFile) == true
) {
if (!File.Exists (dir))
System.IO.Directory.CreateDirectory (dir);
saveFileName = string.Format ("{0}", file_name);
tHttpWebResponse = null;
tHttpWebResponseStream = null;
tResponseBytes = null;
try
{
// get resource
//Debug.Log("取得URL : " + _awsS3Url + "?realse_id=" + releaseId);
sendHttpRequest (ref tHttpWebResponse, _awsS3Url + "?realse_id=" + releaseId);
if (tHttpWebResponse.StatusCode != null) {
if (tHttpWebResponse.StatusCode == HttpStatusCode.OK) {
FileStream fs = new FileStream (System.IO.Path.Combine(dir, saveFileName), FileMode.Create, FileAccess.Write);
tHttpWebResponseStream = tHttpWebResponse.GetResponseStream ();
BinaryReader tBinaryReader = new BinaryReader (tHttpWebResponseStream);
tResponseBytes = tBinaryReader.ReadBytes ((int)tHttpWebResponse.ContentLength);
WriteFromBytesToFile(fs, tResponseBytes, System.IO.Path.Combine(dir, saveFileName));
}
}
}
catch (Exception tException)
{
//Debug.LogError ("DownloadEngine.threadLoop: Exception: " + tException.ToString ());
Debug.LogError ("ThreadId " + _threadId + " / Exception");
_exeptionFlag = true;
break;
}
finally
{
if (tHttpWebResponseStream != null)
tHttpWebResponseStream.Close ();
if (tHttpWebResponse != null)
tHttpWebResponse.Close ();
}
if (_exeptionFlag == true) {
Debug.LogError ("ThreadId " + _threadId + " / Already Exception at Http After");
break;
}
if (File.Exists (System.IO.Path.Combine(dir, saveFileName)))
{
//ハッシュファイルが既存
if (CacheAssetContentsPrefs.CacheAssetContentsGetString (System.IO.Path.Combine(dir, saveFileName)) != null && CacheAssetContentsPrefs.CacheAssetContentsGetString (System.IO.Path.Combine(dir, saveFileName)) != "")
{
//既にユーザーがローカルにハッシュデータと正確なコンテンツファイルを持っている場合の処理。
//バージョンチェック
//Debug.Log (" リリースIDチェック " + releaseId + " == " + CacheAssetContentsPrefs.CacheAssetContentsGetString (versionKey));
if (releaseId != CacheAssetContentsPrefs.CacheAssetContentsGetString (versionKey) && CacheAssetContentsPrefs.CacheAssetContentsGetString (versionKey) != null && CacheAssetContentsPrefs.CacheAssetContentsGetString (versionKey) != "")
{
// バージョンが違えば再度、新しくローカルに保存されたファイルを直接ハッシュ値を見る処理を入れる。
// ハッシュファイルが違えばもう一度、再処理
if (calcMd5 (System.IO.Path.Combine(dir, saveFileName)) != hashFile)
{
Debug.Log ("不整合0");
Debug.LogError ("不整合0:" + calcMd5 (System.IO.Path.Combine(dir, saveFileName)) + " == " + hashFile);
// 失敗している
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), "");
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, "");
RetryMultipleDownloadCount ();
}
else
{
//成功している
//Debug.Log ("成功0: " + versionKey);
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), hashFile);
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, releaseId);
DownloadCountUp ();
}
}
else if (CacheAssetContentsPrefs.CacheAssetContentsGetString (System.IO.Path.Combine(dir, saveFileName)) != hashFile && releaseId == CacheAssetContentsPrefs.CacheAssetContentsGetString (versionKey))
{
//ハッシュファイルが違えばもう一度、再処理
Debug.Log ("不整合1");
Debug.LogError ("不整合1:" + CacheAssetContentsPrefs.CacheAssetContentsGetString (System.IO.Path.Combine(dir, saveFileName)) + " == " + hashFile);
// 失敗している
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), "");
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, "");
RetryMultipleDownloadCount ();
}
else
{
// 成功している
//Debug.Log ("成功1: " + versionKey);
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), hashFile);
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, releaseId);
DownloadCountUp ();
}
}
else
{
//新規ユーザーや、キャッシュ削除時に入っていく処理。
if (calcMd5 (System.IO.Path.Combine(dir, saveFileName)) != hashFile)
{
// ハッシュファイルが違えばもう一度、再処理
Debug.Log ("不整合2");
Debug.LogError (calcMd5 (System.IO.Path.Combine(dir, saveFileName)) + " == " + hashFile);
// 失敗している
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), "");
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, "");
RetryMultipleDownloadCount ();
}
else
{
//成功している
//Debug.Log ("成功2: " + versionKey);
CacheAssetContentsPrefs.CacheAssetContentsSetString (System.IO.Path.Combine(dir, saveFileName), hashFile);
CacheAssetContentsPrefs.CacheAssetContentsSetString (versionKey, releaseId);
DownloadCountUp ();
}
}
}
//Debug.Log ("ThreadId " + _threadId + " / " + _currentDownloadCount.ToString() + " FIX 実行ファイルカウント");
} else {
Debug.LogError ("データ渡せてない。");
_exeptionFlag = true;
break;
}
}
//System.GC.Collect ();
Debug.Log ("StreamLargeFile Thread Finish NO." + _threadId);
}
/// <summary>
/// Writes from bytes to file.
/// </summary>
/// <param name="pDestinationFileStream">P destination file stream.</param>
/// <param name="pSourceBuffer">P source buffer.</param>
/// <param name="saveFullPath">Save full path.</param>
public void WriteFromBytesToFile(FileStream pDestinationFileStream, byte[] pSourceBuffer, string saveFullPath)
{
try {
long tLength = pSourceBuffer.Length;
long tBeforeLength = pDestinationFileStream.Length;
pDestinationFileStream.Seek(0, SeekOrigin.Begin);
if (tLength <= 0) {
_exeptionFlag = true;
} else {
pDestinationFileStream.Write(pSourceBuffer, 0, (int)tLength);
if (tBeforeLength > tLength) {
pDestinationFileStream.SetLength(tLength);
}
}
} catch (IOException pException) {
Debug.LogError("IOException:" + pException.Message);
} finally {
pDestinationFileStream.Close ();
}
}
/// <summary>
/// Downloads the thread finished.
/// </summary>
/// <param name="dtAsynResult">Dt asyn result.</param>
private void DownloadThreadFinished(IAsyncResult dtAsynResult)
{
AsyncResult dtCastedAsyncResult = (AsyncResult)dtAsynResult;
ThreadDownloadDelegate tdDelegate = (ThreadDownloadDelegate)dtCastedAsyncResult.AsyncDelegate;
tdDelegate.EndInvoke (dtAsynResult);
//dtCastedAsyncResult.AsyncWaitHandle.WaitOne();
if (dtAsynResult.IsCompleted == true) {
_threadQueueCounter = _threadQueueCounter - 1;
// Debug.Log ("Thread Queue Counter : " + _threadQueueCounter);
// Debug.Log ("DownloadFinished Get Counter : " + GetDownloadCount ());
// Debug.Log ("Download Counter : " + _downloadListCount);
if (GetDownloadCount () == _downloadListCount) {
StopTime ();
Debug.Log (ElapsedTime + " >>> 経過時間 "); //どれくらいでダウンロード処理終わったか?
Debug.Log ("ALL FInished Downloaded > " + _currentDownloadCount);
Debug.Log ("ALL FInished File Check Error > " + _tryCounter);
_currentDownloadCount = 0;
_tryCounter = 0;
if (_tryCounter == 0) {
_isLoadFin = true; //完了通知用。
CacheAssetContentsPrefs.CacheAssetContentsFlush (); //データをダウンロードするかどうかの判定等をするためのローカル保存用データ。
} else {
Debug.Log ("Download fix broken");
CacheAssetContentsPrefs.CacheAssetContentsFlush ();
_exeptionFlag = true;
}
return;
} else {
if (_threadQueueCounter == 0) {
Debug.Log ("Counter not fix");
// Debug.Log ("DownloadFinished Get Counter : " + GetDownloadCount ());
// Debug.Log ("Download Counter : " + _downloadListCount);
// AutoRetry
if (_displayErrorPopupFlag == false && _exeptionFlag == false) {
Debug.Log ("Counter not fix Auto Retry");
//_currentDownloadCount = 0;
CacheAssetContentsPrefs.CacheAssetContentsFlush ();
_exeptionFlag = true;
}
}
}
}
}
private static IEnumerator deferredInvoke(float seconds, System.Action action)
{
yield return new WaitForSeconds(seconds);
action ();
}
#endregion
#region 簡易的なリクエスト処理。
/// <summary>
/// Sends the http request.
/// </summary>
/// <param name="pDestinationWebResponse">P destination web response.</param>
/// <param name="pSourceUrl">P source URL.</param>
public void sendHttpRequest(ref HttpWebResponse pDestinationWebResponse, string pSourceUrl)
{
int tTimeout = mHttpRequestTimeout;
string tUserAgent = mHttpRequestUserAgent;
HttpWebRequest tHttpWebRequest = null;
if (pDestinationWebResponse != null) {
pDestinationWebResponse.Close ();
pDestinationWebResponse = null;
}
try {
Uri tUrl = new Uri(pSourceUrl);
tHttpWebRequest = (HttpWebRequest)WebRequest.Create(tUrl);
tHttpWebRequest.Timeout = tTimeout;
tHttpWebRequest.UserAgent = tUserAgent;
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {
//Debug.Log ("Network conect status : " + System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable());
pDestinationWebResponse = (HttpWebResponse)tHttpWebRequest.GetResponse();
// Check response.
if (pDestinationWebResponse.StatusCode == HttpStatusCode.OK) {
return;
}
} else {
Debug.Log ("Network disconect");
_exeptionFlag = true;
return;
}
} catch (WebException tWebException) {
pDestinationWebResponse = (HttpWebResponse)tWebException.Response;
if (pDestinationWebResponse == null) {
_autoRetry++;
Debug.LogError ("sendHttpRequest : HttpWebResponse Error {" + tWebException.Message + "}");
if (_autoRetry <= 3) {
Debug.Log ("AutoRetry : " + _autoRetry);
sendHttpRequest (ref pDestinationWebResponse, pSourceUrl);
} else {
_exeptionFlag = true;
}
return;
} else {
if (tWebException.Status == System.Net.WebExceptionStatus.ProtocolError) {
System.Net.HttpWebResponse errorResponse = (System.Net.HttpWebResponse)tWebException.Response;
Debug.LogError ("DownloadEngine.sendHttpRequest: {" + tWebException.Message + "} pSourceUrl={" + pSourceUrl + "} StatusCode={" + errorResponse.StatusCode + "} StatusDescription={" + errorResponse.StatusDescription + "}");
} else {
Debug.LogError ("sendHttpRequest: {" + tWebException.Message + "} pSourceUrl={" + pSourceUrl + "} ExceptionStatus = {" + tWebException.Status.ToString () + "}");
}
_exeptionFlag = true;
return;
}
}
}
/// <summary>
/// Networks the check.
/// </summary>
/// <returns><c>true</c>, if check was networked, <c>false</c> otherwise.</returns>
private bool NetworkCheck() {
string host = "";
if (ApiData._env == "product") {
host = string.Format("http://{0}", ApiData.Instance.PRODUCT_DOMAIN);
} else if (ApiData._env == "staging") {
host = string.Format("http://{0}", ApiData.Instance.STG_DOMAIN);
} else {
host = string.Format("http://{0}", ApiData.Instance.DEV_DOMAIN);
}
HttpWebRequest webreq = null;
HttpWebResponse webres = null;
try
{
//HttpWebRequestの作成
webreq = (HttpWebRequest)WebRequest.Create(host);
//メソッドをHEADにする
webreq.Method = "HEAD";
//受信する
webres = (HttpWebResponse)webreq.GetResponse();
//応答ステータスコードを表示
Debug.Log ("NetworkCheck OK : " + webres.StatusCode);
return true;
}
catch (WebException tWebException)
{
Debug.Log ("NetworkCheck Error : " + tWebException.Message);
return false;
}
finally
{
if (webres != null)
webres.Close();
}
}
#endregion
#region 再処理
private void DownloadCountUp ()
{
lock (_lockObj){
_currentDownloadCount++;
}
}
private int GetDownloadCount ()
{
lock (_lockObj){
return _currentDownloadCount;
}
}
private void RetryMultipleDownloadCount ()
{
lock (_lockObj){
_tryCounter++;
}
}
#endregion
#region 共通ポップアップ
/// <summary>
/// Https the error popup.
/// </summary>
private void HttpIoOrNetworkErrorPopup ()
{
GameObject.FindGameObjectWithTag (CommonConstants.NGUI_CAMERA_TAG).GetComponent<UICamera> ().enabled = false;
new NguiPopupHelper ().CommonPopUpHelper
(
LocalMsgConst.CONECTION_ERROR_TITLE,
LocalMsgConst.CONECTION_ERROR_TEXT,
this.gameObject,
this.gameObject,
"ReDownload",
"CancelButton",
CommonConstants.NGUI_COMMON_POPUP_2CHOICE
);
}
/// <summary>
/// Res the download.
/// </summary>
public void ReDownload ()
{
/** SE再生 */
CriSoundManager.sePlayCue (SoundConstants.CRIADX2_SE_COM_CANCEL);
_displayNetworkPopupFlag = false;
_currentDownloadCount = 0;
CacheAssetContentsPrefs.CacheAssetContentsFlush ();
MultipleDownload (_cacheContentsList, true);
}
public void CancelButton ()
{
/** SE再生 */
CriSoundManager.sePlayCue(SoundConstants.CRIADX2_SE_COM_CANCEL);
Extention.CommonPlayerPrefs.CommonSetString (LocalConstants.SCENE_BEFORE_QUEUE_SAVE_KEY, Application.loadedLevelName);
Extention.CommonPlayerPrefs.CommonSetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY, CommonConstants.SCENE_START);
SceneManager.NextSceneRedirect (CommonConstants.SCENE_START);
}
#endregion
#region ベンチマーク計測用関数群
public DateTime mStartedDateTime; //時間計測用
/// <summary>
/// 計測された経過時間を返します
/// </summary>
public string ElapsedTime { get; private set; }
/// <summary>
/// 経過時間の計測を開始します
/// </summary>
public void StartTime()
{
mStartedDateTime = DateTime.Now;
}
/// <summary>
/// 経過時間の計測を停止します
/// </summary>
public void StopTime()
{
var ts = DateTime.Now - mStartedDateTime;
ElapsedTime = string.Format(
"{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours,
ts.Minutes,
ts.Seconds,
ts.Milliseconds / 10
);
}
#endregion
#region ファイルハッシュ値計算関数
/// <summary>
/// Calculates the File By md5.
/// </summary>
/// <returns>The md5.</returns>
/// <param name="filename">Filename.</param>
private string calcMd5 (string path)
{
string result;
using (var stream = new FileStream (path, FileMode.Open,
FileAccess.Read,
FileShare.Read))
{
byte[] bytehash = System.Security.Cryptography.MD5.Create ().ComputeHash (stream);
result = BitConverter.ToString (bytehash).Replace ("-", string.Empty);
stream.Close ();
}
return result;
}
#endregion
#region 試験的に試している箇所。
/// <summary>
/// Texures the load set.
/// ローディングシーンの負荷を減らすため
/// スポットでダウンロードして表示させる処理を入れる
/// 現在:[武器アイコン], [ユニットアイコン]、[ユニットDetail], [UnitNo_deck]のpng
/// </summary>
/// <param name="targetId">Target identifier.</param>
/// <param name="type">Type.</param>
/// <param name="_contents">Contents.</param>
/// <param name="targetObj">Target object.</param>
public void TexureLoadSet (string targetId, int type, List<ContentsEntity.Contents> _contents, GameObject targetObj, string option="")
{
ContentsEntity.Contents content = new ContentsEntity.Contents ();
string path = "";
if (option != "")
{
content = ContentsHandler.GetContentsList (targetId, type.ToString (), _contents, option);
} else {
content = ContentsHandler.GetContentsList (targetId, type.ToString (), _contents, targetId);
}
if (content != null ) {
path = string.Format ("{0}{1}{2}", StreamingAssetsHelper.GetDownLoadPath (), content.directory, content.file_name);
string dir = string.Format ("{0}{1}", StreamingAssetsHelper.GetDownLoadPath (), content.directory);
if (!File.Exists (dir))
Directory.CreateDirectory (dir);
//ファイルが存在する場合は、そのままレンダリング。
if (File.Exists (path) == true) {
if (CacheAssetContentsPrefs.CacheAssetContentsGetString (content.file_path) == content.release_id)
{
Texture2D tex = new Texture2D (4, 4, TextureFormat.ARGB32, false, false);
tex.LoadImage (GetBinaryLocalLoad (path));
tex.Apply (true, true);
targetObj.GetComponent<UITexture> ().mainTexture = tex;
} else {
StartCoroutine (SaveAndRendering (targetId, type, _contents, content, targetObj, path, option));
}
//ファイルが存在しない場合、データ保管して表示処理。
} else if (File.Exists (path) == false) {
StartCoroutine (SaveAndRendering (targetId, type, _contents, content, targetObj, path, option));
}
}
}
//Dictionary <string, GameObject>
/// <summary>
/// Saves to rendering.
/// </summary>
/// <param name="targetId">Target identifier.</param>
/// <param name="type">Type.</param>
/// <param name="_contents">Contents.</param>
/// <param name="content">Content.</param>
/// <param name="targetObj">Target object.</param>
/// <param name="path">Path.</param>
private GameObject loadObj;
private IEnumerator SaveAndRendering (string targetId, int type, List<ContentsEntity.Contents> _contents, ContentsEntity.Contents content, GameObject targetObj, string path, string option = "")
{
GameObject.FindGameObjectWithTag (CommonConstants.NGUI_CAMERA_TAG).GetComponent<UICamera> ().enabled = false;
//アニメションセット
if (loadObj == null) {
loadObj = Instantiate (Resources.Load (ResoucesLoadConst.API_LOADING), Vector3.zero, Quaternion.identity) as GameObject;
loadObj.transform.localPosition = new Vector3 (0.0f, -20.0f, 0.0f);
}
using (WWW www = new WWW(string.Format ("{0}{1}{2}", ApiData.GetContentsDataURL (ApiData.API_CONTENTS_REQUEST_URI), content.file_path, "?realse_id=" + content.release_id))) {
while (www == null)
yield return (www != null);
while (www.isDone == false)
yield return (www.isDone);
//non texture file
if (string.IsNullOrEmpty(www.error) == false) {
Destroy (loadObj);
GameObject.FindGameObjectWithTag (CommonConstants.NGUI_CAMERA_TAG).GetComponent<UICamera> ().enabled = true;
Debug.LogError (www.error);
yield break;
} else {
StartCoroutine (SavedLocalData(path, www.bytes, content));
}
while (targetObj == null)
yield return (targetObj != null);
targetObj.GetComponent<UITexture> ().mainTexture = www.texture;
}
//File.WriteAllBytes (path, www.bytes);
Debug.Log (string.Format ("{0}{1}{2}", ApiData.GetContentsDataURL (ApiData.API_CONTENTS_REQUEST_URI), content.file_path, "?realse_id=" + content.release_id));
}
/// <summary>
/// Saveds the local data.
/// </summary>
/// <returns>The local data.</returns>
/// <param name="path">Path.</param>
/// <param name="bytes">Bytes.</param>
private IEnumerator SavedLocalData (string path, byte[] bytes, ContentsEntity.Contents content)
{
yield return new WaitForSeconds(2.2f);
File.WriteAllBytes (path, bytes);
while (File.Exists (path) == false)
yield return (File.Exists (path) == true);
if (calcMd5(path) == content.file_hash) {
Debug.Log ("hash save file proccessing.......");
CacheAssetContentsPrefs.CacheAssetContentsSetString (path, content.file_hash);
CacheAssetContentsPrefs.CacheAssetContentsSetString (content.file_path, content.release_id);
CacheAssetContentsPrefs.CacheAssetContentsFlush ();
} else {
Debug.Log (" no hash file ....... ");
File.Delete (path);
CacheAssetContentsPrefs.CacheAssetContentsSetString (path, "");
CacheAssetContentsPrefs.CacheAssetContentsSetString (content.file_path, "");
CacheAssetContentsPrefs.CacheAssetContentsFlush ();
}
Debug.Log ("file save finished");
Destroy (loadObj);
GameObject.FindGameObjectWithTag (CommonConstants.NGUI_CAMERA_TAG).GetComponent ().enabled = true;
}
/// <summary>
/// Gets the binary locla load.
/// </summary>
/// <returns>The Binary Local Load.</returns>
private byte[] GetBinaryLocalLoad (string path)
{
FileStream fs = new FileStream(path, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] buf = br.ReadBytes((int)br.BaseStream.Length);
br.Close();
return buf;
}
/// <summary>
/// Ises the multiple download ignore.
/// Loadingシーンのコンテンダウンロードに含めない
/// </summary>
/// <returns><c>true</c>, if multiple download ignore was ised, <c>false</c> otherwise.</returns>
private bool IsMultipleDownloadIgnore (ContentsEntity.Contents contents)
{
bool isIgnore = false;
string exDir = "co/un/dt/0/";
List<string> ignoreStrList = new List<string> () {
"co/un/dt", //ユニットの詳細テキスチャー(ディレクトリ名)
//"co/un/ic", //ユニットアイコン(ディレクトリ名)
"co/wp" //weapon icon, texture
};
//Scent to Scene Filtering
if (CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_FRIDND
|| CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_STRENGTHENING
|| CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_USER_STATUS
|| CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_MAIN_QUEST
|| CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_DOMESTICAFFAIRS
// || CommonPlayerPrefs.CommonGetString (LocalConstants.SCENE_AFTER_QUEUE_SAVE_KEY) == CommonConstants.SCENE_RAID_BOSS
)
{
//Debug.Log ("scene jump koko koko ");
foreach (var list in ignoreStrList)
{
//Exeption
if (contents.directory.Contains (exDir))
{
isIgnore = false;
break;
}
if (contents.directory.Contains (list))
{
//Debug.Log (" マッチしました。 ");
isIgnore = true;
break;
}
else
{
//Debug.Log ("non match");
}
}
}
return isIgnore;
}
#endregion
}
}