summaryrefslogtreecommitdiff
path: root/Assets/Scripts/ResManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts/ResManager.cs')
-rw-r--r--Assets/Scripts/ResManager.cs273
1 files changed, 273 insertions, 0 deletions
diff --git a/Assets/Scripts/ResManager.cs b/Assets/Scripts/ResManager.cs
new file mode 100644
index 0000000..ba47f8e
--- /dev/null
+++ b/Assets/Scripts/ResManager.cs
@@ -0,0 +1,273 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.IO;
+using UnityEngine;
+using UnityEngine.UI;
+using MEC;
+
+public class ResManager {
+
+ private struct BundleInfo{
+ public long size;
+ public string hash;
+ }
+
+ public static ResManager Instance
+ {
+ get
+ {
+ if (_instance == null)
+ _instance = new ResManager();
+ return _instance;
+ }
+ }
+ static ResManager _instance;
+
+ Test test;
+ string Content;
+
+ static string BundleRoot = "PackData";
+ static string ManifestBundleName = "PackData";
+ static string ManifestFileResName = "bundles"; // under Resources/bundles.manifest
+ static string ManifesteRemotePath = "bundles.manifest";
+#if UNITY_STANDALONE_WIN
+ static string cdnAddress = "http://localhost/bundles/"; // PC
+#elif UNITY_ANDROID
+ static string cdnAddress = "http://10.0.2.2/bundles/"; // AndroidEmu
+#endif
+
+ Dictionary<string, AssetBundle> CachedBundles = new Dictionary<string, AssetBundle>();
+ Dictionary<string, string> FileMapping = new Dictionary<string, string>();
+ AssetBundleManifest Manifest;
+
+#region 更新相关
+ // 本地streamingAssetsPath下的bundles数据,从固化的bundles.manifest中读取
+ Dictionary<string, BundleInfo> localBundles = new Dictionary<string, BundleInfo>();
+ // CDN上的bundles数据
+ Dictionary<string, BundleInfo> remoteBundles = new Dictionary<string, BundleInfo>();
+#endregion
+
+ public void Init(Test test)
+ {
+ this.test = test;
+ LoadLocalBundlesInfo();
+ Timing.Instance.RunCoroutineOnInstance(DownloadManifest());
+ }
+
+ void Print(string content , bool alert = false)
+ {
+ test.Print(content, alert);
+ }
+
+ public string ResContent(string path)
+ {
+ TextAsset text = Resources.Load(path) as TextAsset;
+ if (text == null)
+ return null;
+ return text.text;
+ }
+
+ public void ReadFileMapping()
+ {
+ AssetBundle bundle = LoadBundle("bundle00.ab"); // 不可以省略后缀
+ if (bundle == null)
+ {
+ string path = PathHelper.GetStreamingFullFilePath(BundleRoot + "/bundle00.ab");
+ Print("Bundle 为空, path = " + path, true);
+ return;
+ }
+ TextAsset text = bundle.LoadAsset<TextAsset>("fileMapping");
+ if (text == null)
+ return;
+ string content = text.text;
+ content = content.Replace("\r", string.Empty);
+ string[] lines = content.Split('\n');
+ Print("Load FileMapping:");
+ foreach (string line in lines)
+ {
+ string[] part = line.Split(',');
+ FileMapping.Add(part[0], part[1]);
+ Print(part[0] + " " + part[1]);
+ }
+ }
+
+ /// <summary>
+ /// 刚开始进入游戏的时候要写入.manifest,用来后续对比更新
+ /// </summary>
+ public void LoadManifest()
+ {
+ AssetBundle bundle = LoadBundle(ManifestBundleName);
+ if (bundle == null)
+ {
+ Print("没有Manifest", true);
+ return;
+ }
+ Manifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
+ if (Manifest == null)
+ {
+ Print("AssetBundleManifest", true);
+ return;
+ }
+ Print("All bundles:");
+ string[] bundleNames = Manifest.GetAllAssetBundles();
+ foreach (var bundleName in bundleNames)
+ {
+ Print(bundleName);
+ }
+ }
+
+ public AssetBundle LoadBundle(string name)
+ {
+ AssetBundle bundle;
+ if (CachedBundles.TryGetValue(name, out bundle))
+ {
+ return bundle;
+ }
+ string path = PathHelper.GetPersistentFullFilePath(BundleRoot + "/" + name);
+ Print(path);
+ if (!File.Exists(path))
+ {
+ Print("不在persistent里");
+ path = PathHelper.GetStreamingFullFilePath(BundleRoot + "/" + name);
+ }
+ bundle = AssetBundle.LoadFromFile(path);
+ if(bundle == null)
+ Print("是空的");
+ CachedBundles.Add(name, bundle);
+ return bundle;
+ }
+
+ public string GetBundleName(string assetName)
+ {
+ string bundleName;
+ FileMapping.TryGetValue(assetName, out bundleName);
+ return bundleName;
+ }
+
+ public string BundleContent(string resName)
+ {
+ string bundleName = GetBundleName(resName);
+ if (bundleName == null)
+ return null;
+ AssetBundle bundle = LoadBundle(bundleName);
+ if (bundle == null)
+ return null;
+ TextAsset text = bundle.LoadAsset<TextAsset>(resName);
+ if (text == null)
+ return null;
+ return text.text;
+ }
+
+ /// <summary>
+ /// 根据Resources/bundles.manifest读取本地bundle数据
+ /// </summary>
+ private void LoadLocalBundlesInfo()
+ {
+ TextAsset manifest = Resources.Load<TextAsset>(ManifestFileResName);
+ if(manifest == null)
+ {
+ Debug.LogError("本地Resources目录下没有bundles.manifest");
+ return;
+ }
+ string[] bundles = manifest.text.Replace("\r", string.Empty).Split('\n');
+ string[] info;
+ foreach(string bundle in bundles)
+ {
+ info = bundle.Split(',');
+ if (info.Length != 3)
+ continue;
+ BundleInfo bi = new BundleInfo();
+ bi.size = long.Parse(info[1]);
+ bi.hash = info[2];
+ localBundles.Add(info[0], bi);
+ }
+ }
+
+ IEnumerator<float> DownloadManifest()
+ {
+ WWW www = new WWW(cdnAddress + ManifesteRemotePath);
+ while(!www.isDone)
+ {
+ yield return Timing.WaitForSeconds(0.01f);
+ }
+ string content = www.text;
+ string[] bundles = content.Replace("\r", string.Empty).Split('\n');
+ string[] info;
+ foreach (string bundle in bundles)
+ {
+ info = bundle.Split(',');
+ if (info.Length != 3)
+ continue;
+ BundleInfo bi = new BundleInfo();
+ bi.size = long.Parse(info[1]);
+ bi.hash = info[2];
+ remoteBundles.Add(info[0], bi);
+ }
+ // Download bundles
+ Timing.Instance.RunCoroutineOnInstance(DownloadBundles());
+ }
+
+ IEnumerator<float> DownloadBundles()
+ {
+ List<string> downloadBundles = new List<string>();
+ foreach(var b in remoteBundles)
+ {
+ string bundleName = b.Key;
+ long size = b.Value.size;
+ string hash = b.Value.hash;
+ BundleInfo localInfo;
+ //1. 剔除首包中就有的
+ if (localBundles.TryGetValue(bundleName, out localInfo) && localInfo.hash == hash)
+ continue;
+ //2. 剔除上次小版本更新下载下来的
+ string persistentPath = PathHelper.GetPersistentFullFilePath(BundleRoot + "/" + bundleName);
+ if(File.Exists(persistentPath))
+ {
+ long lastsize = new FileInfo(persistentPath).Length;
+ if(lastsize == size)
+ {
+ string lasthash = FileUtil.GetMD5Hash(persistentPath);
+ if (lasthash == "")
+ {
+ Debug.LogError("计算md5出错");
+ }
+ else if (lasthash == hash)
+ continue;
+ }
+ }
+ downloadBundles.Add(bundleName);
+ }
+ //3. 下载
+ foreach (string bundle in downloadBundles)
+ {
+ WWW www = new WWW(cdnAddress + bundle);
+ while(!www.isDone)
+ {
+ yield return Timing.WaitForSeconds(0.01f);
+ }
+ // save to persistentDataPath
+ Print("->下载" + bundle + "完毕");
+ byte[] data = www.bytes;
+ string folder = PathHelper.GetPersistentFullFilePath(BundleRoot);
+ if (!Directory.Exists(folder))
+ Directory.CreateDirectory(folder);
+ File.WriteAllBytes(folder + "/" + bundle, data);
+ }
+
+ Print("Bundle 下载完毕,共下载" + downloadBundles.Count + "个");
+ Print("------------------------------------------------------------------------");
+ // test test
+ ResManager.Instance.ReadFileMapping();
+ ResManager.Instance.LoadManifest();
+ // Done
+ OnDownloaded();
+ }
+
+ void OnDownloaded()
+ {
+ if (test != null)
+ test.Testing();
+ }
+
+}