/// <summary> /// 根据字节数组获取资源包版本信息 /// </summary> /// <param name="buffer">字节数组</param> /// <param name="version">版本号</param> /// <returns></returns> public static Dictionary <string, AssetBundleInfoEntity> GetAssetBundleVersionList(byte[] buffer, ref string version) { buffer = ZlibHelper.DeCompressBytes(buffer); Dictionary <string, AssetBundleInfoEntity> dic = new Dictionary <string, AssetBundleInfoEntity>(); MMO_MemoryStream ms = new MMO_MemoryStream(buffer); int len = ms.ReadInt(); for (int i = 0; i < len; i++) { if (i == 0) { version = ms.ReadUTF8String().Trim(); } else { AssetBundleInfoEntity entity = new AssetBundleInfoEntity(); entity.AssetBundleName = ms.ReadUTF8String(); entity.MD5 = ms.ReadUTF8String(); entity.Size = ms.ReadULong(); entity.IsFirstData = ms.ReadByte() == 1; entity.IsEncrypt = ms.ReadByte() == 1; dic[entity.AssetBundleName] = entity; } } return(dic); }
/// <summary> /// 将只读取区版本文件初始化到可写区 /// </summary> private void InitVersionFileStreamingAssetBundleToLocal() { GameEntry.Log(LogCategory.Resource, "InitVersionFileStreamingAssetBundleToLocal"); m_LocalAssetsVersionDic = new Dictionary <string, AssetBundleInfoEntity>(); var enumerator = m_LocalAssetsVersionDic.GetEnumerator(); while (enumerator.MoveNext()) { AssetBundleInfoEntity entity = enumerator.Current.Value; m_LocalAssetsVersionDic[enumerator.Current.Key] = new AssetBundleInfoEntity() { AssetBundleName = entity.AssetBundleName, MD5 = entity.MD5, Size = entity.Size, IsFirstData = entity.IsFirstData, IsEncrypt = entity.IsEncrypt }; } //保存版本文件 LocalAssetsManager.SaveVersionFile(m_LocalAssetsVersionDic); //保存版本号 m_LocalAssetsVersion = m_StreamingAssetsVersion; LocalAssetsManager.SetResourceVersion(m_LocalAssetsVersion); }
/// <summary> /// 获取资源包信息 这个方法一定要能返回资源信息 /// </summary> /// <param name="assetbundlePath"></param> /// <returns></returns> public AssetBundleInfoEntity GetAssetBundleInfo(string assetbundlePath) { AssetBundleInfoEntity entity = null; m_CDNVersionDic.TryGetValue(assetbundlePath, out entity); return(entity); }
/// <summary> /// 保存版本信息 /// </summary> /// <param name="entity"></param> public void SaveVersion(AssetBundleInfoEntity entity) { if (m_LocalAssetsVersionDic == null) { m_LocalAssetsVersionDic = new Dictionary <string, AssetBundleInfoEntity>(); } m_LocalAssetsVersionDic[entity.AssetBundleName] = entity; //保存版本文件 LocalAssetsManager.SaveVersionFile(m_LocalAssetsVersionDic); }
/// <summary> /// 下载多个文件 /// </summary> /// <param name="lstUrl"></param> /// <param name="onDownloadMulitUpdate"></param> /// <param name="onDownloadMulitComplete"></param> public void BeginDownloadMulit(LinkedList <string> lstUrl, BaseAction <int, int, ulong, ulong> onDownloadMulitUpdate, BaseAction onDownloadMulitComplete) { m_OnDownloadMulitUpdate = onDownloadMulitUpdate; m_OnDownloadMulitComplete = onDownloadMulitComplete; m_NeedDownloadList.Clear(); m_DownloadMulitCurrSizeDic.Clear(); m_DownloadMulitNeedCount = 0; m_DownloadMulitCurrCount = 0; m_DownloadMulitTotalSize = 0; m_DownloadMulitCurrSize = 0; //m_DownloadMulitNeedCount = lstUrl.Count; //m_DownloadMulitCurrCount = 0; //1.把需要下载的加入下载列表 for (LinkedListNode <string> item = lstUrl.First; item != null; item = item.Next) { string url = item.Value; Debug.Log("要下载的资源" + url); AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url); if (entity != null) { m_DownloadMulitTotalSize += entity.Size; m_DownloadMulitNeedCount++; m_NeedDownloadList.AddLast(url); m_DownloadMulitCurrSizeDic[url] = 0; } else { GameEntry.LogError("无效资源包=》" + url); } } //2.下载器数量 最多五个 int routineCount = Mathf.Min(GameEntry.Download.DownloadRoutineCount, m_NeedDownloadList.Count); for (int i = 0; i < routineCount; i++) { DownloadRoutine routine = GameEntry.Pool.DequeueClassObject <DownloadRoutine>(); string url = m_NeedDownloadList.First.Value; m_NeedDownloadList.RemoveFirst(); AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url); routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete); m_DownloadRoutineList.AddLast(routine); } }
public void BeginDownload(string url, AssetBundleInfoEntity assetBundleInfo, BaseAction <string, ulong, float> onUpadte = null, BaseAction <string, DownloadRoutine> onComplete = null) { m_CurrFileUrl = url; m_CurrAssetBundleInfo = assetBundleInfo; m_OnUpdate = onUpadte; m_OnComplete = onComplete; m_DownloadLocalFilePath = string.Format("{0}/{1}", GameEntry.Resource.LocalFilePath, m_CurrFileUrl); if (File.Exists(m_DownloadLocalFilePath)) { File.Delete(m_DownloadLocalFilePath); } m_DownloadLocalFilePath = m_DownloadLocalFilePath + ".temp"; if (File.Exists(m_DownloadLocalFilePath)) { Debug.LogError("验证md5 避免版本更新时出现问题"); if (PlayerPrefs.HasKey(m_DownloadLocalFilePath)) { //验证 if (!PlayerPrefs.GetString(m_CurrFileUrl).Equals(assetBundleInfo.MD5, System.StringComparison.CurrentCultureIgnoreCase)) { Debug.LogError("如果不一致 就删除本地临时文件"); File.Delete(m_DownloadLocalFilePath); BeginDownload(); } else { Debug.LogError("一致 继续下载"); m_FileStream = File.OpenWrite(m_DownloadLocalFilePath); m_FileStream.Seek(0, SeekOrigin.End); m_BeginPos = (uint)m_FileStream.Length; Download(string.Format("{0}{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, m_CurrFileUrl), m_BeginPos); } } else { Debug.LogError("如果不一致 就删除本地临时文件"); File.Delete(m_DownloadLocalFilePath); BeginDownload(); } } else { Debug.LogError("本地没有md5记录 重新下载"); BeginDownload(); } }
/// <summary> /// 加载资源包 /// </summary> /// <param name="assetbundlePath"></param> public void LoadAssetBundle(string assetbundlePath) { //获取资源包信息 m_CurrAssetBundleInfo = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(assetbundlePath); //检查文件是否在可写区 bool isExistsInLocal = GameEntry.Resource.ResourceManager.LocalAssetsManager.CheckeFileExists(assetbundlePath); if (isExistsInLocal && !m_CurrAssetBundleInfo.IsEncrypt) { //如果资源包存在于可写区 并没有加加密 m_CurrAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(string.Format("{0}/{1}", Application.persistentDataPath, assetbundlePath)); } else { //先从资源目录加载 byte[] buffer = GameEntry.Resource.ResourceManager.LocalAssetsManager.GetFileBuffer(assetbundlePath); if (buffer == null) { //没有就到只读区 GameEntry.Resource.ResourceManager.StreamingAssetsManager.ReadAssetBundle(assetbundlePath, (byte[] buff) => { if (buff == null) { //只读区没有 就到cdn下载 Debug.LogError("资源需要加载:" + assetbundlePath); GameEntry.Download.BeginDownloadSingle(assetbundlePath, onComplete: (string fileUrl) => { Debug.LogError("下载完毕fileUrl:" + fileUrl); buffer = GameEntry.Resource.ResourceManager.LocalAssetsManager.GetFileBuffer(fileUrl); Debug.LogError("准备加载资源:" + buffer); LoadAssetBundleAsync(buffer); }); } else { LoadAssetBundleAsync(buff); } }); } else { LoadAssetBundleAsync(buffer); } } }
/// <summary> /// 下载初始化资源 /// </summary> private void DownloadInitResourse() { GameEntry.Event.CommonEvent.Dispatch(SysEventId.CheckVersionBeginDownload); m_DownloadingParams = GameEntry.Pool.DequeueClassObject <BaseParams>(); m_NeedDownloadList.Clear(); var enumerator = m_CDNVersionDic.GetEnumerator(); while (enumerator.MoveNext()) { AssetBundleInfoEntity entity = enumerator.Current.Value; if (entity.IsFirstData) { m_NeedDownloadList.AddLast(entity.AssetBundleName); } } GameEntry.Download.BeginDownloadMulit(m_NeedDownloadList, OnDownloadMulitUpdate, OnDownloadMulitComplete); }
/// <summary> /// 多文件下载完毕回调 /// </summary> /// <param name="fileUrl"></param> /// <param name="routine"></param> private void OnDownloadMulitComplete(string fileUrl, DownloadRoutine routine) { Debug.LogError("下载完毕=" + fileUrl); //检查队列中是否有要下载的数据 if (m_NeedDownloadList.Count > 0) { //让下载器继续工作 string url = m_NeedDownloadList.First.Value; m_NeedDownloadList.RemoveFirst(); AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url); routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete); } else { m_DownloadRoutineList.Remove(routine); Debug.LogError("下载器回池"); GameEntry.Pool.EnqueueClassObject(routine); } m_DownloadMulitCurrCount++; if (m_OnDownloadMulitUpdate != null) { m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize); } if (m_DownloadMulitCurrCount == m_DownloadMulitNeedCount) { Debug.LogError("资源下载完成"); m_DownloadMulitCurrSize = m_DownloadMulitTotalSize; if (m_OnDownloadMulitUpdate != null) { m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize); } if (m_OnDownloadMulitComplete != null) { m_OnDownloadMulitComplete(); } } }
/// <summary> /// 下载文件 /// </summary> /// <param name="url"></param> /// <param name="onUpdate"></param> /// <param name="onComplete"></param> public void BeginDownloadSingle(string url, BaseAction <string, ulong, float> onUpdate = null, BaseAction <string> onComplete = null) { AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url); if (entity == null) { GameEntry.LogError("无效资源包=》" + url); return; } DownloadRoutine routine = GameEntry.Pool.DequeueClassObject <DownloadRoutine>(); routine.BeginDownload(url, entity, onUpdate, onComplete: (string fileUrl, DownloadRoutine r) => { m_DownloadRoutineList.Remove(r); GameEntry.Pool.EnqueueClassObject(routine); if (onComplete != null) { onComplete(fileUrl); } }); m_DownloadRoutineList.AddLast(routine); }
/// <summary> /// 开始检查版本更新 /// </summary> private void BeginCheckVersionChange() { m_DownloadingParams = GameEntry.Pool.DequeueClassObject <BaseParams>(); m_DownloadingParams.Reset(); //需要删除的文件 LinkedList <string> delList = new LinkedList <string>(); //可写区资源md5和cdn资源md5不一致 LinkedList <string> inconformtyList = new LinkedList <string>(); LinkedList <string> needDownloadList = new LinkedList <string>(); #region 找出需要删除的文件 删除 var enumerator = m_LocalAssetsVersionDic.GetEnumerator(); while (enumerator.MoveNext()) { string assetBundleName = enumerator.Current.Key; //去cdn对比 AssetBundleInfoEntity cdnAssetBundleInfo = null; if (m_CDNVersionDic.TryGetValue(assetBundleName, out cdnAssetBundleInfo)) { //可写区有 cdn也有 if (!cdnAssetBundleInfo.MD5.Equals(enumerator.Current.Value.MD5, StringComparison.CurrentCultureIgnoreCase)) { //如果md5不一致 加入不一致列表 inconformtyList.AddLast(assetBundleName); } } else { //可写区有 cdn上没有 加入删除列表 delList.AddLast(assetBundleName); } } //循环判断这个文件在只读区的md5和cdn是否一致 一致的进行删除 不一致的进行重新下载 LinkedListNode <string> currInconformity = inconformtyList.First; while (currInconformity != null) { AssetBundleInfoEntity cdnAssetBundleInfo = null; m_CDNVersionDic.TryGetValue(currInconformity.Value, out cdnAssetBundleInfo); AssetBundleInfoEntity streamingAssetAssetBundleInfo = null; if (m_StreamingAssetsVersionDic != null) { m_StreamingAssetsVersionDic.TryGetValue(currInconformity.Value, out streamingAssetAssetBundleInfo); } if (streamingAssetAssetBundleInfo == null) { //如果只读区 没有 needDownloadList.AddLast(currInconformity.Value); } else { //判断 是否一致 if (cdnAssetBundleInfo.MD5.Equals(streamingAssetAssetBundleInfo.MD5, StringComparison.CurrentCultureIgnoreCase)) { //一致 delList.AddLast(currInconformity.Value); } else { //不一致 needDownloadList.AddLast(currInconformity.Value); } } currInconformity = currInconformity.Next; } #endregion #region LinkedListNode <string> currDel = delList.First; while (currDel != null) { string filePath = string.Format("{0}/{1}", GameEntry.Resource.LocalFilePath, currDel.Value); if (File.Exists(filePath)) { File.Delete(filePath); } LinkedListNode <string> next = currDel.Next; delList.Remove(currDel); currDel = next; } #endregion #region 检查需要下载的 enumerator = m_CDNVersionDic.GetEnumerator(); while (enumerator.MoveNext()) { AssetBundleInfoEntity cdnAssetBundleInfo = enumerator.Current.Value; if (cdnAssetBundleInfo.IsFirstData) { //检查初始资源 if (!m_LocalAssetsVersionDic.ContainsKey(cdnAssetBundleInfo.AssetBundleName)) { //如果可写区没有 就去只读区判断一次 AssetBundleInfoEntity streamingAssetsAssetBundleInfo = null; if (m_StreamingAssetsVersionDic != null) { m_StreamingAssetsVersionDic.TryGetValue(cdnAssetBundleInfo.AssetBundleName, out streamingAssetsAssetBundleInfo); } if (streamingAssetsAssetBundleInfo == null) { //只读区 不存在 needDownloadList.AddLast(cdnAssetBundleInfo.AssetBundleName); } else { //只读区存在 验证md5 if (!cdnAssetBundleInfo.MD5.Equals(streamingAssetsAssetBundleInfo.MD5, StringComparison.CurrentCultureIgnoreCase)) { //md5不一致 needDownloadList.AddLast(cdnAssetBundleInfo.AssetBundleName); } } } } } #endregion GameEntry.Event.CommonEvent.Dispatch(SysEventId.CheckVersionBeginDownload); //进行下载 GameEntry.Download.BeginDownloadMulit(needDownloadList, OnDownloadMulitUpdate, OnDownloadMulitComplete); }