/// <summary> /// 更新文件 /// </summary> /// <param name="output"></param> public static void BuildUpdateFile(string output, string cdn = null) { ManifestConfig newManifestConfig = GetManifest(output); ManifestConfig oldManifestConfig = newManifestConfig; if (!string.IsNullOrEmpty(cdn)) { string url = cdn + "/data/conf/manifestfile.json"; WWW www = new WWW(url); while (!www.isDone) { ; } if (string.IsNullOrEmpty(www.error) && www.progress == 1f) { TextAsset text = www.assetBundle.LoadAsset(Path.GetFileNameWithoutExtension(url)) as TextAsset; oldManifestConfig = JsonReader.Deserialize <ManifestConfig>(text.text); www.assetBundle.Unload(false); } www.Dispose(); } ManifestConfig manifestConfig = new ManifestConfig(); if (!string.IsNullOrEmpty(cdn)) { string url = cdn + "/data/conf/updatefile.json"; WWW www = new WWW(url); while (!www.isDone) { ; } if (string.IsNullOrEmpty(www.error) && www.progress == 1f) { TextAsset text = www.assetBundle.LoadAsset(Path.GetFileNameWithoutExtension(url)) as TextAsset; manifestConfig = JsonReader.Deserialize <ManifestConfig>(text.text); www.assetBundle.Unload(false); } www.Dispose(); } // 写入Manifest if (newManifestConfig != null && oldManifestConfig != null) { foreach (var data in newManifestConfig.data.Values) { if (oldManifestConfig.Contains(data.name) && oldManifestConfig.Get(data.name).MD5 == data.MD5) { continue; } manifestConfig.Add(data); } // 写入到文件 File.WriteAllText(assetPath + "/data/conf/updatefile.json", JsonWriter.Serialize(manifestConfig)); // 刷新 AssetDatabase.Refresh(); // Build清单文件 AssetBundleBuild[] builds = new AssetBundleBuild[1]; builds[0].assetBundleName = "data/conf/updatefile"; builds[0].assetBundleVariant = null; builds[0].assetNames = new string[1] { assetPath + "/data/conf/updatefile.json" }; BuildPipeline.BuildAssetBundles(output, builds, BuildAssetBundleOptions.ChunkBasedCompression, buildTarget); } }
/// <summary> /// 拷贝更新资源包 /// </summary> public static void CopyUpdateAssetBundles(string output, string dest, string version, string cdn = null) { ManifestConfig remote = new ManifestConfig(); if (!string.IsNullOrEmpty(cdn)) { string url = cdn + "/data/conf/updatefile.json"; WWW www = new WWW(url); while (!www.isDone) { ; } if (string.IsNullOrEmpty(www.error) && www.progress == 1f) { TextAsset text = www.assetBundle.LoadAsset(Path.GetFileNameWithoutExtension(url)) as TextAsset; remote = JsonReader.Deserialize <ManifestConfig>(text.text); www.assetBundle.Unload(true); } www.Dispose(); } ManifestConfig local = JsonReader.Deserialize <ManifestConfig>(File.ReadAllText(assetPath + "/data/conf/updatefile.json")); if (local != null) { ManifestConfig manifestConfig = new ManifestConfig(); foreach (var data in local.data.Values) { if (remote.Contains(data.name) && remote.Get(data.name).MD5 == data.MD5) { continue; } manifestConfig.Add(data); } if (!Directory.Exists(dest)) { Directory.CreateDirectory(dest); } string updateFilePath = dest + "/updatefile.json"; string updateFileValue = JsonWriter.Serialize(manifestConfig); File.WriteAllText(updateFilePath, updateFileValue); AssetDatabase.Refresh(); manifestConfig.Add(new Manifest() { name = "data/conf/manifestfile.json" }); manifestConfig.Add(new Manifest() { name = "data/conf/updatefile.json" }); using (MemoryStream stream = new MemoryStream()) { using (ZipOutputStream zip = new ZipOutputStream(stream)) { zip.SetComment(version); foreach (var data in manifestConfig.data.Values) { ZipEntry entry = new ZipEntry(data.name); entry.DateTime = new DateTime(); entry.DosTime = 0; zip.PutNextEntry(entry); string filepPth = output + "/" + data.name; var bytes = File.ReadAllBytes(filepPth); zip.Write(bytes, 0, bytes.Length); } zip.Finish(); zip.Flush(); var fileBytes = new byte[stream.Length]; Array.Copy(stream.GetBuffer(), fileBytes, fileBytes.Length); string platform = "PC"; #if UNITY_ANDROID platform = "Android"; #elif UNITY_IOS platform = "iOS"; #endif DateTime dt = DateTime.Now; string date = string.Format("{0}.{1}.{2}_{3}.{4}.{5}", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second); string md5 = Util.GetMD5(fileBytes); File.WriteAllBytes(string.Format("{0}/{1}_{2}_{3}_{4}.zip", dest, platform, version, date, md5), fileBytes); } } File.Delete(updateFilePath); AssetDatabase.Refresh(); } }
/// <summary> /// 开始资源更新 /// </summary> private void StartAssetUpdate() { bool hasAssetUpdate = false; // 更新 m_async.Clear(); if (m_remoteUpdateManifest.data.Count > 0) { // 最后一个更新清单文件是否下载 hasAssetUpdate = !m_localUpdateManifestMD5.Equals(m_remoteUpdateManifestMD5); if (hasAssetUpdate) { Action sure = () => { // 更新清单文件 AsyncAsset async = AssetManager.instance.AssetBundleAsyncLoad(Path.Combine(Path.Combine(App.cdn + App.platform, string.Format(Const.REMOTE_DIRECTORY, App.version)), Const.MANIFESTFILE), (bResult, asset) => { if (bResult) { Util.WriteAllBytes(App.assetPath + Const.MANIFESTFILE, asset.bytes); m_currentSize += (float)asset.userData; m_async.Remove(asset); } else { Debugger.LogError(asset.error); } }, dependence: false); async.userData = 0.5F; m_size += (float)async.userData; m_async.Add(async); // 更新其它文件 foreach (var data in m_remoteUpdateManifest.data.Values) { if (m_localUpdateManifest.Contains(data.name)) { if (m_localUpdateManifest.Get(data.name).MD5.Equals(data.MD5)) { continue; } else if (data.MD5.Equals(Util.GetMD5(App.assetPath + data.name))) { continue; } } async = AssetManager.instance.AssetBundleAsyncLoad(Path.Combine(Path.Combine(App.cdn + App.platform, string.Format(Const.REMOTE_DIRECTORY, App.version)), data.name), (bResult, asset) => { if (bResult) { Util.WriteAllBytes(App.assetPath + data.name, asset.bytes); m_currentSize += (float)asset.userData; m_async.Remove(asset); } else { Debugger.LogError(asset.error); } }, dependence: false); async.userData = data.size / 1024F; m_size += (float)async.userData; m_async.Add(async); } // 更新更新文件 async = AssetManager.instance.AssetBundleAsyncLoad(Path.Combine(Path.Combine(App.cdn + App.platform, string.Format(Const.REMOTE_DIRECTORY, App.version)), Const.UPDATE_FILE), (bResult, asset) => { if (bResult) { Util.WriteAllBytes(App.assetPath + Const.UPDATE_FILE, asset.bytes); m_currentSize += (float)asset.userData; m_async.Remove(asset); } else { Debugger.LogError(asset.error); } }, dependence: false); async.userData = 0.1F; m_size += (float)async.userData; m_async.Add(async); // 记录是否资源更新中 m_assetUpdating = true; m_time = Time.realtimeSinceStartup; }; Action close = () => { Application.Quit(); }; UIManager.instance.OpenUI(Const.UI_NORMAL_TIPS_BOX, Param.Create(new object[] { UINormalTipsBox.ACTION_SURE, sure, UINormalTipsBox.TEXT_CONTENT, ConfigManager.GetLang("Network_Invalid"), UINormalTipsBox.ACTION_CLOSE, close })); } } // 如果没有资源更新,就直接认为更新完成 if (!hasAssetUpdate) { AssetUpdateComplete(); } }