public void Initialize() { foldout = true; resources = new List <ResourceConfig>(); ResourceConfig res = new ResourceConfig(); res.Initialize(); resources.Add(res); }
private IEnumerator StartUnzipAsset() { ResourceConfig resourceConfig = new ResourceConfig(); using (WWW www = new WWW(verfilePath)) { yield return(www); if (null != www.error) { Logger.LogError("load verfile failed"); yield break; } TextAsset verfileText = www.assetBundle.LoadAsset <TextAsset>("verfile"); resourceConfig.Initialize(verfileText.text); www.assetBundle.Unload(false); } List <KeyValuePair <string, string> > downLoadList = new List <KeyValuePair <string, string> >(); for (int index = 0; index < resourceConfig.resource.patchLst.Count; ++index) { ConfResourceItem item = resourceConfig.resource.patchLst[index]; downLoadList.Add(new KeyValuePair <string, string>(GameConstant.AssetBundleBasePath + item.file, GameConstant.PersistentDataPath + item.file)); } int fileCount = 0; for (int index = 0; index < downLoadList.Count; ++index) { KeyValuePair <string, string> item = downLoadList[index]; AssetBundleManager.Instance.DownloadAssetAsync(item.Key, item.Value, (abInfo) => { ++fileCount; //Logger.LogError("unzip progress = " + (float)fileCount / downLoadList.Count); }); } while (fileCount < downLoadList.Count) { yield return(null); } Logger.LogError("unzip complete"); yield return(StartCoroutine(CheckAssetUpdate())); }
private IEnumerator CheckAssetUpdate() { #region load local update list config string clientList = null; AssetBundleInfo bundleInfo = null; AssetBundleManager.Instance.LoadAssetAsync("updatelist.conf", (abInfo) => { waiteString = GetAssetBundleText(abInfo); bundleInfo = abInfo; }); yield return(StartCoroutine(WaiteRequest())); if (null != bundleInfo) { AssetBundleManager.Instance.RemoveAssetBundle(bundleInfo); } clientList = waiteString; if (string.IsNullOrEmpty(clientList)) { Logger.LogError("load client update list failed!!!"); yield break; } clientResourceConfig.Initialize(clientList); #endregion #region load server update list config string serverList = null; byte[] serverBytes = null; AssetBundleManager.Instance.DownloadAssetAsync(GameConstant.RemoteResourcePath + GameResourceDefine.ASSET_UPDATE_FILE, null, (abInfo) => { waiteString = GetAssetBundleText(abInfo); serverBytes = abInfo.bytes; }); yield return(StartCoroutine(WaiteRequest())); serverList = waiteString; #endregion if (!string.IsNullOrEmpty(serverList)) { serverResourceConfig.Initialize(serverList); List <ConfResourceItem> updateList = new List <ConfResourceItem>(); int totalSize = 0; if (!clientResourceConfig.resource.Equals(serverResourceConfig.resource)) { for (int index = 0; index < serverResourceConfig.resource.patchLst.Count; ++index) { var item = serverResourceConfig.resource.patchLst[index]; var clientItem = clientResourceConfig.GetResourceItem(item.file); if (null == clientItem || clientItem.md5 != item.md5) { if (Utils.FileToMd5(GameConstant.PersistentDataPath + item.file) != item.md5) { totalSize += item.size; updateList.Add(item); } } Logger.LogError("check resource is valid"); } if (updateList.Count > 0 && totalSize > 0) { yield return(StartCoroutine(DownloadAsset(updateList, serverBytes))); } } } yield return(StartCoroutine(PreloadNeedAsset())); }
private void DrawContent() { float keyWidth = (position.width - 85) / 6; float pathWidth = (position.width - 85) / 6 * 4; float objWidth = (position.width - 85) / 6; _pos = EditorGUILayout.BeginScrollView(_pos); { EditorGUILayout.BeginVertical(); { for (int i = 0; i < _groups.Count; i++) { GroupConfig config = _groups[i]; config.foldout = EditorGUILayout.Foldout(config.foldout, GetGroupInfo(config.id)); { if (config.foldout) { EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("+", EditorStyles.miniButtonLeft, GUILayout.Width(25))) //Add group { GroupConfig group = new GroupConfig(); group.Initialize(); _groups.Insert(i + 1, group); return; } if (GUILayout.Button("-", EditorStyles.miniButtonRight, GUILayout.Width(25))) //remove group { if (_groups.Count <= 1) { return; } _groups.RemoveAt(i); return; } config.id = EditorGUILayout.Popup(config.id, _selections.Select(s => s.name).ToArray(), GUILayout.Width(100)); } EditorGUILayout.EndHorizontal(); for (int j = 0; j < config.resources.Count; j++) { EditorResourceConfig resource = new EditorResourceConfig(config.resources[j]); bool legal = CheckKey(config.resources[j]); _nameLegal = _nameLegal && legal; EditorGUILayout.BeginHorizontal(); { resource.key = EditorGUILayout.TextField(resource.key, legal ? EditorStyles.textField : _errorStyle, GUILayout.Width(keyWidth)); resource.path = EditorGUILayout.TextField(resource.path, GUILayout.Width(pathWidth)); if (!string.IsNullOrEmpty(resource.path)) { resource.obj = AssetDatabase.LoadAssetAtPath(resource.path, typeof(Object)); } resource.obj = EditorGUILayout.ObjectField(resource.obj, typeof(Object), false, GUILayout.Width(objWidth)); if (resource.obj != null) { resource.path = AssetDatabase.GetAssetPath(resource.obj); } else if (!string.IsNullOrEmpty(resource.path)) { resource.obj = AssetDatabase.LoadAssetAtPath(resource.path, typeof(Object)); } if (GUILayout.Button("+", EditorStyles.miniButtonLeft, GUILayout.Width(25))) //add resource { ResourceConfig res = new ResourceConfig(); res.Initialize(); config.resources.Insert(j + 1, res); return; } if (GUILayout.Button("-", EditorStyles.miniButtonRight, GUILayout.Width(25))) //remove resource { if (config.resources.Count <= 1) { return; } config.resources.RemoveAt(j); return; } config.resources[j] = resource.ToResourceConfig(); } EditorGUILayout.EndHorizontal(); } } } } } EditorGUILayout.EndVertical(); } EditorGUILayout.EndScrollView(); }
private static void GenerateUpdatePackages(BuildAssetConfig assetConfig) { ResourceConfig oldConfig = LoadFileFromPackage(assetConfig.packagePath, VERFILE_CONF_PATH); ResourceConfig oldUpdateConfig = null; if (string.IsNullOrEmpty(assetConfig.updatePackagePath)) { oldUpdateConfig = new ResourceConfig(); } else { oldUpdateConfig = LoadFileFromPackage(assetConfig.updatePackagePath, UPDATELIST_CONF_PATH); } // old files md5 Dictionary <string, string> oldFileMd5 = new Dictionary <string, string>(); foreach (var item in oldConfig.resource.patchLst) { oldFileMd5[item.file] = item.md5; } foreach (var item in oldUpdateConfig.resource.patchLst) { oldFileMd5[item.file] = item.md5; } // load new verfile and caculate new verfile md5 AssetBundle newVerfileBundle = null; ResourceConfig verfileConfig = new ResourceConfig(); string verfileHashValue = string.Empty; try { byte[] verfileBytes = File.ReadAllBytes(Path.Combine(BuildOutputPath, VERFILE_CONF_PATH)); newVerfileBundle = AssetBundle.LoadFromMemory(verfileBytes); string verfileText = newVerfileBundle.LoadAsset <TextAsset>(newVerfileBundle.GetAllAssetNames()[0]).text; verfileConfig.Initialize(verfileText); ResourceConfig tempVersionJson = new ResourceConfig(); tempVersionJson.Initialize(verfileText); tempVersionJson.resource.patchLst.RemoveAll((item) => { return(item.file.Contains("verfile") || item.file.Contains("updatelist")); }); verfileHashValue = Utils.HashToMd5(Pathfinding.Serialization.JsonFx.JsonWriter.Serialize(tempVersionJson.resource)); } finally { if (null != newVerfileBundle) { newVerfileBundle.Unload(false); newVerfileBundle = null; } } ResourceConfig updateConfig = new ResourceConfig(); updateConfig.resource.hashValue = verfileHashValue; ConfResourceItem verfileItem = null; foreach (var newItem in verfileConfig.resource.patchLst) { if (newItem.file.Contains("updatelist")) { continue; } if (newItem.file.Contains("verfile")) { newItem.md5 = Utils.FileToMd5(Path.Combine(BuildOutputPath, VERFILE_CONF_PATH)); verfileItem = newItem; continue; } var oldItemMd5 = string.Empty; oldFileMd5.TryGetValue(newItem.file, out oldItemMd5); // add or modify if (string.IsNullOrEmpty(oldItemMd5) || oldItemMd5 != newItem.md5) { updateConfig.resource.patchLst.Add(newItem); } } if (updateConfig.resource.patchLst.Count <= 0) { updateConfig.resource.hashValue = oldUpdateConfig.resource.hashValue; } else { updateConfig.resource.patchLst.Add(verfileItem); } // set need copy asset map Dictionary <string, string> needCopyMap = new Dictionary <string, string>(); foreach (var item in updateConfig.resource.patchLst) { needCopyMap.Add(item.file, Path.Combine(BuildOutputPath, item.file)); } needCopyMap[UPDATELIST_CONF_PATH] = Path.Combine(BuildOutputPath, UPDATELIST_CONF_PATH); // add old update list to new, but don't need to copy foreach (var item in oldUpdateConfig.resource.patchLst) { // this is the old update list if (item.file.Contains("updatelist")) { continue; } if (updateConfig.resource.patchLst.FindAll(fileItem => { return(fileItem.file == item.file); }).Count <= 0) { updateConfig.resource.patchLst.Add(item); } } string updateListConfigText = SerializeJsonFile(updateConfig.resource, UPDATELIST_JSON_PATH); string tempDirectory = Path.Combine(Application.dataPath, "../" + FileUtil.GetUniqueTempPathInProject()); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } AssetBundleBuild[] buildMap = new AssetBundleBuild[] { new AssetBundleBuild() { assetBundleName = UPDATELIST_CONF_PATH, assetNames = new string[] { "Assets/data/conf/updatelist.json" } }, }; BuildPipeline.BuildAssetBundles(tempDirectory, buildMap, BuildAssetBundleOptions.ChunkBasedCompression, CurrentBuildTarget); CopyFileEx(Path.Combine(tempDirectory, UPDATELIST_CONF_PATH), Path.Combine(BuildOutputPath, UPDATELIST_CONF_PATH)); using (MemoryStream compressed = new MemoryStream()) { using (ZipOutputStream compressor = new ZipOutputStream(compressed)) { int count = 0; try { compressor.SetComment(updateListConfigText); } catch { compressor.SetComment(string.Format("hash:{0}", updateConfig.resource.hashValue)); } foreach (var fileKV in needCopyMap) { string file = fileKV.Value; ZipEntry entry = new ZipEntry(fileKV.Key); entry.DateTime = new System.DateTime(); entry.DosTime = 0; compressor.PutNextEntry(entry); if (Directory.Exists(file)) { continue; } byte[] bytes = File.ReadAllBytes(file); int offset = 0; compressor.Write(bytes, offset, bytes.Length - offset); EditorUtility.DisplayProgressBar("Generate update files", string.Format("Add:\t{0}", file), (++count % needCopyMap.Count)); } compressor.Finish(); compressor.Flush(); byte[] fileBytes = new byte[compressed.Length]; Array.Copy(compressed.GetBuffer(), fileBytes, compressed.Length); string fileName = string.Format("{0}_{1}_{2}_{3}.zip", Path.GetFileNameWithoutExtension(assetConfig.packagePath), DateTime.Now.ToString("yyyy.MM.dd_HH.mm.s"), Utils.HashToMd5(fileBytes), updateConfig.resource.hashValue); string filePath = Path.Combine(UpdateBuildPath, fileName); File.WriteAllBytes(filePath, fileBytes); if (null != assetConfig.successCallback) { assetConfig.successCallback(filePath); } } } EditorUtility.ClearProgressBar(); }
private static ResourceConfig LoadFileFromPackage(string packagePath, string fileName, HashSet <string> files = null) { if (string.IsNullOrEmpty(packagePath) || !File.Exists(packagePath)) { Logger.LogError("the package path is invalid"); return(null); } ResourceConfig result = null; byte[] fileData = null; if (!packagePath.EndsWith(".conf")) { using (FileStream fileStream = File.Open(packagePath, FileMode.Open)) { fileStream.Seek(0, SeekOrigin.Begin); using (ZipInputStream zipStream = new ZipInputStream(fileStream)) { ZipEntry zipEntry = null; while (null != (zipEntry = zipStream.GetNextEntry())) { if (null != files && zipEntry.IsFile) { files.Add(zipEntry.Name); } if (zipEntry.Name.EndsWith(fileName)) { fileData = new byte[zipEntry.Size]; zipStream.Read(fileData, (int)zipEntry.Offset, (int)zipEntry.Size); if (null == files) { break; } } } } } } else { fileData = File.ReadAllBytes(packagePath); } AssetBundle bundle = null; try { bundle = AssetBundle.LoadFromMemory(fileData); string fileText = bundle.LoadAsset <TextAsset>(bundle.GetAllAssetNames()[0]).text; result = new ResourceConfig(); result.Initialize(fileText); } finally { if (null != bundle) { bundle.Unload(false); bundle = null; } } return(result); }