unity3D熱更新——(2)Assetbundle資源更新部分

///
///通過tomcat服務器進行下載ab包

///

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class UpdateAssetBundles : MonoBehaviour
{
/// <summary>
/// 配表路徑
/// </summary>
List<string> mainPath;
/// <summary>
/// 配表信息
/// </summary>
Dictionary<string, List<string>> tablePath;
/// <summary>
/// 進入遊戲進行資產更新
/// </summary>
public void FirstUpdateAB()
{
StartCoroutine(IEFirstUpdateAB());
}
IEnumerator IEFirstUpdateAB()
{
//進入遊戲先檢測persistent目錄下是否有文件,沒有則表示爲第一次進遊戲,
//需要將streaming目錄下的文件拷貝到該目錄下。
if (!Directory.Exists(AssetPath.persistentPath))
{
Debug.Log("解壓本地文件!(該步驟不需要流量)");
//注意,在Android中,StreamingAssets中的文件包含在一個.jar壓縮文件(基本上與標準的zip爲統一格式)中,所以只能用
//WWW讀取,否則要使用第三方軟件來讀取,不能用C#的文件讀取方法。
List<string> streamList = new List<string>();
yield return StartCoroutine(IECStomcat(AssetPath.streamingPath + "/" + IP.preloadedPath, streamList));
string tableStr = "";
for (int i = 0; i < streamList.Count; i++)
{
tableStr += streamList[i];
tableStr += Environment.NewLine;
string relativePath = "/" + streamList[i].Split(';')[0];
yield return StartCoroutine(IEUpdateAssetBundle(Application.streamingAssetsPath + relativePath.Replace('\\','/'), Application.persistentDataPath + relativePath.Replace('\\', '/')));
}
Debug.Log("解壓完成!");
CreadTextFile(AssetPath.persistentPath + "/" + IP.preloadedPath, tableStr);
yield return new WaitForSeconds(0);
}
//獲取主配表
Debug.Log("獲取服務器列表!(建議在WiFi下更新)");
mainPath = new List<string>();
yield return StartCoroutine(IECStomcat(IP.ResoucelsIP + AssetPath._Android + "/" + IP.ResoucelsTablePath, mainPath));
Debug.Log("檢測是否需要更新!");
if (mainPath != null)
{
tablePath = new Dictionary<string, List<string>>();
for (int i = 0; i < mainPath.Count; i++)
{
List<string> list = new List<string>();
tablePath.Add(mainPath[i], list);
yield return StartCoroutine(IECStomcat(IP.ResoucelsIP + mainPath[i], list));
}
}
else
{
Debug.Log("服務器更新失敗!找不到主配置文件!");
}
List<string> updateTable = ContrastDetection(tablePath);
Debug.Log("檢測到有" + updateTable.Count + "個文件需要更新!");
yield return new WaitForSeconds(0.5f);
if (updateTable.Count > 0)
{
Debug.Log("開始更新資源文件!");
for (int i = 0; i < updateTable.Count; i++)
{
string serverPathAB = IP.ResoucelsIP + updateTable[i].Split(';')[0];
string localPathAB = Application.persistentDataPath + "/" + updateTable[i].Split(';')[0];
yield return StartCoroutine(IEUpdateAssetBundle(serverPathAB.Replace('\\', '/'), localPathAB.Replace('\\', '/')));
}
Debug.Log("資源文件已更新完畢!");
Debug.Log("開始更新配置文件!");
readText(tablePath);
yield return new WaitForSeconds(0.5f);
Debug.Log("配置文件已更新完成!");
}
Debug.Log("進入遊戲!");
}




/// <summary>
/// 在安卓平臺下判斷該條路徑是否爲 "jar:file"開頭(返回true爲是)
/// </summary>
/// <returns></returns>
public bool jarFilePath(string path)
{
if (Application.platform == RuntimePlatform.Android && path.Substring(0, AssetPath.jarHead.Length) == AssetPath.jarHead)
{
return true;
}
return false;
}
/// <summary>
/// 判斷該條路徑是否爲"http"開頭(返回true爲是)
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool httpPath(string path)
{
if (path.Substring(0, AssetPath.httpHead.Length) == AssetPath.httpHead)
{
return true;
}
return false;
}


/// <summary>
/// 獲取配表,並把每行的信息寫入列表中
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
IEnumerator IECStomcat(string path, List<string> mainPath)
{
string[] pathAll;
if (jarFilePath(path) || httpPath(path))
{
//這裏有個問題,加了時間戳只有第一個鏈接能訪問到
//if (httpPath(path))
//{
// string nn = DateTime.Now.Ticks.ToString();
// path = path + "?a=" + nn.Substring(nn.ToString().Length - 6);
//}
WWW www = new WWW(path);
yield return www;
if (www.error != null)
{
Debug.Log(www.error+" "+ path);
yield break;
}
pathAll = www.text.Split(Environment.NewLine.ToCharArray());
}
else
{
pathAll= File.ReadAllText(path).Split(Environment.NewLine.ToCharArray());
}
for (int i = 0; i < pathAll.Length; i++)
{
if (pathAll[i] != "")
{
mainPath.Add(pathAll[i]);
}
}
}
/// <summary>
/// 服務器配表與本地配表進行檢測比對
/// </summary>
/// <param name="d"></param>
public List<string> ContrastDetection(Dictionary<string, List<string>> d)
{
string path = "";
List<string> listPath = new List<string>();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
path = Application.dataPath + "/" + AssetPath.StreamingAssets;
}
else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
path = Application.persistentDataPath;
}
//遍歷配表
foreach (var item in d)
{
string file = "";
string localPath = path + "/" + item.Key;
//檢測本地配表是否存在
if (File.Exists(localPath))
{
//本地有該配表就將路徑進行比對添加到列表中
file = File.ReadAllText(localPath);
}
for (int i = 0; i < item.Value.Count; i++)
{
if (!file.Contains(item.Value[i]))
{
listPath.Add(item.Value[i]);
}
}
}
return listPath;
}
/// <summary>
/// 從服務器上下載ab包到本地,(注意斜槓,一定要把所有的反斜槓轉成斜槓)
/// </summary>
/// <param name="path">服務器路徑</param>
/// <param name="localPath">本地路徑</param>
/// <returns></returns>
IEnumerator IEUpdateAssetBundle(string path, string localPath)
{
if (httpPath(path))
{
string nn = DateTime.Now.Ticks.ToString();
path = path + "?" + nn.Substring(nn.ToString().Length - 6);
}
WWW www = new WWW(path);
yield return www;
if (www.error != null)
{
Debug.Log("錯誤信息:" + www.error);
yield break;
}
else
{
string headLocalPath = pathRoundOff(localPath);
if (!Directory.Exists(headLocalPath))
{
Directory.CreateDirectory(headLocalPath);
}
if (File.Exists(localPath))
{
File.Delete(localPath);
}
FileStream steam = File.Create(localPath);
steam.Close();
File.WriteAllBytes(localPath, www.bytes);
}
}
/// <summary>
/// 更新配表
/// </summary>
/// <param name="dateList"></param>
public void readText(Dictionary<string, List<string>> dateList)
{

string directoryPath = Application.persistentDataPath + "/" + AssetPath._Android + "/" + AssetPath.ConfigurationFilesName;
//清除所有配表
if (Directory.Exists(directoryPath))
Directory.Delete(directoryPath, true);
Directory.CreateDirectory(directoryPath);
//創建新的配表
foreach (var item in dateList)
{
string loaclPath = Application.persistentDataPath + "/" + item.Key;
string str = "";
for (int i = 0; i < item.Value.Count; i++)
{
str += item.Value[i];
str += Environment.NewLine;
}
CreadTextFile(loaclPath, str);
}
}
/// <summary>
/// 創建文檔文件
/// </summary>
/// <param name="path"></param>
/// <param name="str"></param>
public void CreadTextFile(string path, string str)
{
string headPath = pathRoundOff(path);
if (!Directory.Exists(headPath))
Directory.CreateDirectory(headPath);
File.WriteAllText(path, str);
}

/// <summary>
/// 截取文件的文件夾路徑
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string pathRoundOff(string path)
{
string[] newPath = path.Split('\\');
if (newPath.Length <= 1)
{
newPath = path.Split('/');
}
return path.Substring(0, path.Length - newPath[newPath.Length - 1].Length - 1);
}
}

public class AssetPath
{
/// <summary>
/// 需要打包的文件夾路徑
/// </summary>
public static string OriginalPath = Application.dataPath + "/AssetBundleResources/Resources";
/// <summary>
/// 打包出來的文件夾路徑
/// </summary>
public const string StreamingAssetsPath = @"Assets/StreamingAssets";
/// <summary>
/// 配置文件夾
/// </summary>
public const string ConfigurationFilesName = "configuration";
/// <summary>
/// 資源文件夾
/// </summary>
public const string ResourcesFilesName = "resources";
/// <summary>
/// 資源文件後綴名
/// </summary>
public const string unity3dSuffix = ".unity3d";
/// <summary>
/// .meta後綴名
/// </summary>
public const string metaSuffix = ".meta";
/// <summary>
/// 打包目錄
/// </summary>
public const string StreamingAssets = "StreamingAssets";
/// <summary>
/// Android
/// </summary>
public const string _Android = "Android";
/// <summary>
/// IPhonePlayer
/// </summary>
public const string _IPhonePlayer = "IPhonePlayer";
/// <summary>
/// 移動端本地壓縮包路徑
/// </summary>
public static string streamingPath = Application.streamingAssetsPath + "/" + Application.platform;
/// <summary>
/// 移動端資產放置路徑
/// </summary>
public static string persistentPath = Application.persistentDataPath + "/" + Application.platform;
/// <summary>
/// 預留物配表相對路徑
/// </summary>
public const string scheduledFileName = "/"+ConfigurationFilesName+"/prefad/scheduled.txt";
/// <summary>
/// "jar:file"
/// </summary>
public const string jarHead = "jar:file";
/// <summary>
/// "http"
/// </summary>
public const string httpHead = "http";

/// <summary>
/// 配置物
/// </summary>
public const string source = "source";

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章