Example #1
0
        internal Object Load(string path, Type type)
        {
            Object obj = null;

            if (CachedObjects.TryGetValue(path, out obj))              // 尝试在缓存中查找
            {
                return(obj);
            }
            else                                             // 尝试从外部文件中加载asset bundle
            {
                var fileName = path.Replace("/", DIR_SPLIT); //替换目录分隔符
                if (DownloadedFiles.ContainsKey(fileName))
                {
                    FileInfo file       = DownloadedFiles[fileName];
                    var      bytes      = File.ReadAllBytes(file.FullName);
                    var      ab         = AssetBundle.LoadFromMemory(bytes);
                    string   objectName = Path.GetFileName(path);
                    obj = ab.LoadAsset(objectName, type);
                    ab.Unload(false);                    //一旦加载完毕,立即释放assetbundle,但不释放bundle中的物体,物体会在场景切换时释放
                    if (obj == null)
                    {
                        UpdaterLog.LogError(string.Format("the resource {0} load from ab is null", path));
                        return(null);
                    }
                    CachedObjects.Add(path, obj);
                }
                else
                {
                    obj = Resources.Load(path, type);
                }
            }
            return(obj);
        }
Example #2
0
 internal bool ReqScene(string path)
 {
     if (!CachedSceneBundles.ContainsKey(path))
     {
         if (DownloadedFiles.ContainsKey(path))
         {
             FileInfo file  = DownloadedFiles[path];
             var      bytes = File.ReadAllBytes(file.FullName);
             var      ab    = AssetBundle.LoadFromMemory(bytes);
             if (ab != null)                        //判断AB中是否有该场景
             {
                 var scenePaths = ab.GetAllScenePaths();
                 foreach (var scenePath in scenePaths)
                 {
                     if (Path.GetFileNameWithoutExtension(scenePath) == path)
                     {
                         UpdaterLog.Log("find scene in assetbundle:" + path);
                         CachedSceneBundles.Add(path, ab);
                         break;
                     }
                 }
             }
         }
     }
     return(Application.CanStreamedLevelBeLoaded(path));
 }
Example #3
0
        public void Init(int versionCode)
        {
            this.VersionCode = versionCode;
            //检查是否有patchIndex文件,并读取内容
            var indexFile = UResources.ReqFile(INDEX_FILE_NAME);

            if (indexFile != null)
            {
                string fileJson = DESFileUtil.ReadAllText(indexFile.FullName, DESKey.DefaultKey, DESKey.DefaultIV);
                _patchIndexLocal = new PatchIndex(this.VersionCode, JObject.Parse(fileJson));
                if (_patchIndexLocal.Version != this.VersionCode)
                {
                    UpdaterLog.Log("发现patchIndex中的主版本不等于目前的主版本,说明刚经历过主包更新,清空补丁");
                    foreach (var file in ResManager.Ins.DownloadedFiles.Values)
                    {
                        File.Delete(file.FullName);
                    }
                    ResManager.Ins.ReadDownloadDir();
                    _patchIndexLocal = new PatchIndex();
                }
            }
            else
            {
                _patchIndexLocal = new PatchIndex();
            }
        }
Example #4
0
        /// <summary>
        /// 读取下载目录,将下载目录中的文件缓存起来
        /// </summary>
        internal void ReadDownloadDir()
        {
            DownloadedFiles.Clear();
            CachedObjects.Clear();
            CachedSceneBundles.Clear();
            AsyncLoadingQueue.Clear();
            AsyncLoadingSceneQueue.Clear();

            if (Directory.Exists(FullDownloadDir))
            {
                // 找到所有的已下载文件
                var files = Directory.GetFiles(FullDownloadDir);
                foreach (var file in files)
                {
                    FileInfo info = new FileInfo(file);
                    UpdaterLog.Log("find downloaded file:" + info);
                    var fileName = Path.GetFileName(file);
                    DownloadedFiles.Add(fileName, info);
                }
            }
            else
            {
                UpdaterLog.Log("create directory:" + FullDownloadDir);
                Directory.CreateDirectory(FullDownloadDir);
            }
        }
Example #5
0
        IEnumerator AsyncCreateABReqScene(string path, byte[] bytes)
        {
            var abCreateReq = AssetBundle.LoadFromMemoryAsync(bytes);

            yield return(abCreateReq);

            var ab = abCreateReq.assetBundle;

            if (ab != null)                //判断AB中是否有该场景
            {
                var scenePaths = ab.GetAllScenePaths();
                foreach (var scenePath in scenePaths)
                {
                    if (Path.GetFileNameWithoutExtension(scenePath) == path)
                    {
                        UpdaterLog.Log("find scene in assetbundle:" + path);
                        CachedSceneBundles.Add(path, ab);
                        break;
                    }
                }
            }
            bool result = Application.CanStreamedLevelBeLoaded(path);
            //执行回调
            Queue <Action <bool> > onDoneQueue = AsyncLoadingSceneQueue[path];

            if (onDoneQueue == null)
            {
                UpdaterLog.LogException(new Exception("Internal error , the AsyncLoadingQueue have no queue named :" + path));
                yield break;
            }
            while (onDoneQueue.Count > 0)
            {
                onDoneQueue.Dequeue()(result);
            }
        }
Example #6
0
        IEnumerator ClearDelay()
        {
            yield return(0);

            //释放资源物体的引用
            CachedObjects.Clear();
            //释放场景bundle的引用
            CachedSceneBundles.Clear();
            UpdaterLog.Log("Clean LevelCached End");
        }
Example #7
0
 void OnSceneLoaded(Scene scene, LoadSceneMode mode)
 {
     UpdaterLog.Log("Clean LevelCached Start");
     //在切换关卡的时候将保留的Bundle释放
     foreach (var bundle in CachedSceneBundles.Values)
     {
         bundle.Unload(false);
     }
     StartCoroutine(ClearDelay());
 }
Example #8
0
        internal string GetUpdatedStreamingAssetPath(string path)
        {
            var fileName = Path.GetFileNameWithoutExtension(path);

            if (DownloadedFiles.ContainsKey(fileName))
            {
                path = "file://" + DownloadedFiles[fileName].FullName;
                UpdaterLog.Log("find streaming asset at update path : " + path);
            }
            else
            {
                path = Path.Combine(Application.streamingAssetsPath, path);
                if (!path.Contains("://"))
                {
                    path = "file://" + path;
                }
            }
            return(path);
        }
Example #9
0
        IEnumerator AsyncResourcesLoad(string path, Type type)
        {
            var req = Resources.LoadAsync(path, type);

            yield return(req);

            Object obj = req.asset;
            Queue <Action <Object> > onDoneQueue = AsyncLoadingQueue[path];

            if (onDoneQueue == null)
            {
                UpdaterLog.LogException(new Exception("internal error , the AsyncLoadingQueue have no queue named :" + path));
                yield break;
            }
            while (onDoneQueue.Count > 0)
            {
                onDoneQueue.Dequeue()(obj);
            }
            this.AsyncLoadingQueue.Remove(path);
        }
Example #10
0
        IEnumerator AsyncCreateABReqObj(string path, Type type, byte[] bytes)
        {
            var abCreateReq = AssetBundle.LoadFromMemoryAsync(bytes);            //异步创建ab

            yield return(abCreateReq);

            string objectName = Path.GetFileName(path);
            var    abReq      = abCreateReq.assetBundle.LoadAssetAsync(objectName, type);    //异步读取物体

            yield return(abReq);

            Object obj = abReq.asset;

            abCreateReq.assetBundle.Unload(false);            //一旦加载完毕,立即释放assetbundle,但不释放bundle中的物体,物体会在场景切换时释放
            if (obj == null)
            {
                UpdaterLog.LogError(string.Format("the resource {0} load async from ab is null", path));
            }
            else
            {
                UpdaterLog.Log(string.Format("load async the resource {0} from ab", path));
                if (!CachedObjects.ContainsKey(path))
                {
                    CachedObjects.Add(path, obj);
                }
            }
            Queue <Action <Object> > onDoneQueue = AsyncLoadingQueue[path];

            if (onDoneQueue == null)
            {
                UpdaterLog.LogException(new Exception("internal error , the AsyncLoadingQueue have no queue named :" + path));
                yield break;
            }
            while (onDoneQueue.Count > 0)
            {
                onDoneQueue.Dequeue()(obj);
            }
            this.AsyncLoadingQueue.Remove(path);
        }
Example #11
0
        public Dictionary <string, Patch> VerifyPatches()
        {
            var ret = new Dictionary <string, Patch>();

            //验证本地补丁
            foreach (var patchKV in Patches)
            {
                var      name  = patchKV.Key;
                var      patch = patchKV.Value;
                FileInfo file  = UResources.ReqFile(name);
                if (patch.NeedDelete)                  //如果这个补丁是删除补丁,验证他是否真的被删除
                {
                    if (file != null)
                    {
                        UpdaterLog.LogError(string.Format("{0} 这个文件理应被删除,但验证发现没有被删除,将更新", name));
                        ret.Add(name, patch);
                    }
                }
                else                    //这是更新补丁,检测是否存在,并验证md5
                {
                    if (file == null)
                    {
                        UpdaterLog.LogError(string.Format("{0} 这个文件验证时发现应该存在,但实际不存在,将更新", name));
                        ret.Add(name, patch);
                    }
                    else
                    {
                        string fileMd5   = MD5Util.GetMD5ForFile(file.FullName);
                        string recordMd5 = patch.MD5;
                        if (!fileMd5.EqualIgnoreCase(recordMd5))
                        {
                            UpdaterLog.LogError(string.Format("{0} 这个文件验证的md5和记录的md5不一致{1}//{2},将更新", name, fileMd5, recordMd5));
                            ret.Add(name, patch);
                        }
                    }
                }
            }
            return(ret);
        }
Example #12
0
        IEnumerator AsyncResourcesLoad(string path, Type type)
        {
            var req = Resources.LoadAsync(path, type);

            yield return(req);

            Object obj = req.asset;
            //			if (obj != null) {//对于Resource.load的对象,由于Unity已经做过缓存,因此不加入缓存中,由Unity处理其缓存和释放。
            //				CachedObjects.Add(path, obj);
            //			}
            //执行所有回调
            Queue <Action <Object> > onDoneQueue = AsyncLoadingQueue[path];

            if (onDoneQueue == null)
            {
                UpdaterLog.LogException(new Exception("internal error , the AsyncLoadingQueue have no queue named :" + path));
                yield break;
            }
            while (onDoneQueue.Count > 0)
            {
                onDoneQueue.Dequeue()(obj);
            }
        }
Example #13
0
        void DownloadPatch(Dictionary <string, Patch> .Enumerator enumerator, int i, int totalToDownload)
        {
            if (!enumerator.MoveNext())
            {
                //下载完毕,将新版本号写入patchIndex,并保存
                _patchIndexLocal.Version      = VersionCode;
                _patchIndexLocal.PatchVersion = _patchIndexNew.PatchVersion;
                _patchIndexLocal.WriteToFile();
                ResManager.Ins.ReadDownloadDir();
                if (Listener != null)
                {
                    Listener.OnPatchDownloadFinish();
                }
                CheckUpdate();                //补丁更新结束后再次检查更新
                return;
            }
            i++;
            var patchKV = enumerator.Current;
            var name    = patchKV.Key;
            var patch   = patchKV.Value;

            if (patch.NeedDelete)              //如果这个补丁是删除更新,则删除
            {
                FileInfo file = UResources.ReqFile(name);
                if (file != null)
                {
                    File.Delete(file.FullName);
                }
                if (Listener != null)
                {
                    Listener.OnPatchDownloadProgress(name, 1, i, totalToDownload);
                }
                _patchIndexLocal.UpdatePatch(name, patch);
                _patchIndexLocal.WriteToFile();
                DownloadPatch(enumerator, i, totalToDownload);
                return;
            }
            //下载更新
            string url = String.Format(_patchIndexNew.PatchBaseURL, name, patch.Version);

            HttpManager.Get(url, (error, www) => {
                if (!string.IsNullOrEmpty(error))
                {
                    UpdaterLog.LogError("下载补丁包出错" + name + "  " + www.error + "  url:" + www.url);
                    if (Listener != null)
                    {
                        Listener.OnPatchDownloadFail(error);
                    }
                    return;
                }
                string filePath = ResManager.FullDownloadDir + name;
                File.WriteAllBytes(filePath, www.bytes);
                //下载完一个文件后立刻写入PatchIndex,这样中途断开网络后重新下载可以不下载该文件
                _patchIndexLocal.UpdatePatch(name, patch);
                _patchIndexLocal.WriteToFile();
                DownloadPatch(enumerator, i, totalToDownload);
                return;
            }, progress => {
                if (Listener != null)
                {
                    Listener.OnPatchDownloadProgress(name, progress, i, totalToDownload);
                }
            });
        }
Example #14
0
        private void CheckUpdate()
        {
            //检查是否有patchIndex文件,并读取内容
            Init(this.VersionCode);

            //构建检查更新需要的表单
            JObject json = new JObject();

            json["version"]      = this.VersionCode;
            json["patchVersion"] = _patchIndexLocal.PatchVersion;
            if (CustomData != null)
            {
                foreach (var kv in CustomData)
                {
                    json[kv.Name] = kv;
                }
            }
            WWWForm form = new WWWForm();

            form.AddField("P", json.ToString());

            HttpManager.Post(CheckUpdateUrl, form, (error, www) => {
                if (!string.IsNullOrEmpty(error))
                {
                    Listener.OnError(error);
                    return;
                }
                UpdaterLog.Log(www.text);

                JObject responseJObj = JObject.Parse(www.text);
                if (responseJObj["E"].GetString() != null)
                {
                    Listener?.OnError(responseJObj["E"].AsString());
                    return;
                }
                responseJObj = responseJObj["P"].OptObject();
                _updateType  = (UpdateType)(responseJObj["Type"].OptInt(0));

                switch (_updateType)
                {
                case UpdateType.NoUpdate:
                    _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                    //没有找到更新,验证文件
                    Listener.OnVerifyStart();
                    if (VerifyPatches())
                    {
                        Listener.OnVerifySuccess();
                        Listener.OnPassUpdate();
                    }
                    else
                    {
                        Listener.OnVerifyFail();
                    }
                    break;

                case UpdateType.MainPak:
                    _mainPakIndexFromServer = new MainPakIndex(this.VersionCode, responseJObj);
                    Listener.OnFindMainUpdate(_mainPakIndexFromServer.Info);
                    break;

                case UpdateType.Patch:
                    _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                    if (Listener != null)
                    {
                        Listener.OnFindPatchUpdate(_patchIndexNew.PatchInfo, _patchIndexNew.TotalPatchSize);
                    }
                    break;
                }
            });
        }
Example #15
0
        private void CheckUpdate()
        {
            //检查是否有patchIndex文件,并读取内容
            var indexFile = UResources.ReqFile(INDEX_FILE_NAME);

            if (indexFile != null)
            {
                string fileJson = DESFileUtil.ReadAllText(indexFile.FullName, DESKey.DefaultKey, DESKey.DefaultIV);
                _patchIndexLocal = new PatchIndex(this.VersionCode, JObject.Parse(fileJson));
                if (_patchIndexLocal.Version != this.VersionCode)
                {
                    UpdaterLog.Log("发现patchIndex中的主版本不等于目前的主版本,说明刚经历过主包更新,清空补丁");
                    foreach (var file in ResManager.Ins.DownloadedFiles.Values)
                    {
                        File.Delete(file.FullName);
                    }
                    ResManager.Ins.ReadDownloadDir();
                    _patchIndexLocal = new PatchIndex();
                }
            }
            else
            {
                _patchIndexLocal = new PatchIndex();
                try {
                    //清空下载目录
                    Directory.Delete(ResManager.FullDownloadDir, true);
                } catch { }

                try {
                    // 重新创建目录,并写回PatchIndex
                    Directory.CreateDirectory(ResManager.FullDownloadDir);
                    _patchIndexLocal.WriteToFile();
                } catch (Exception e) {
                    Debug.LogException(e);
                }
            }

            //构建检查更新需要的表单
            JObject json = new JObject();

            json["Version"]      = this.VersionCode;
            json["PatchVersion"] = _patchIndexLocal.PatchVersion;
            if (CustomData != null)
            {
                foreach (var kv in CustomData)
                {
                    json[kv.Key.ToString()] = kv.Value.ToString();
                }
            }
            UpdaterLog.Log(json.ToFormatString());
            WWWForm form = new WWWForm();

            form.AddField("Data", json.ToString());

            HttpManager.Post(CheckUpdateUrl, form, (error, www) => {
                if (!string.IsNullOrEmpty(error))
                {
                    Listener.OnError(ErrorCode.NET_CONNECT_ERROR);
                    return;
                }
                UpdaterLog.Log(www.text);

                JObject responseJObj = JObject.Parse(www.text);
                int code             = responseJObj["code"].OptInt(ErrorCode.DEFAULT.Code);
                if (code == ErrorCode.SUCCESS.Code)
                {
                    _updateType = responseJObj["Type"].OptEnum <UpdateType>(UpdateType.NoUpdate);
                    switch (_updateType)
                    {
                    case UpdateType.NoUpdate:
                        _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                        //没有找到更新,验证文件
                        Listener.OnVerifyStart();
                        if (VerifyPatches())
                        {
                            Listener.OnVerifySuccess();
                            Listener.OnPassUpdate(responseJObj);
                        }
                        else
                        {
                            Listener.OnVerifyFail();
                        }
                        break;

                    case UpdateType.MainPak:
                        _mainPakIndexFromServer = new MainPakIndex(this.VersionCode, responseJObj);
                        Listener.OnFindMainUpdate(_mainPakIndexFromServer.Info);
                        break;

                    case UpdateType.Patch:
                        _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                        if (Listener != null)
                        {
                            Listener.OnFindPatchUpdate(_patchIndexNew.PatchInfo, _patchIndexNew.TotalPatchSize);
                        }
                        break;
                    }
                }
                else
                {
                    Listener.OnError(new ErrorCode(code, responseJObj["error"].OptObject()));
                }
            }, null, 15);
        }
Example #16
0
        private void CheckUpdate()
        {
            //检查是否有patchIndex文件,并读取内容
            var indexFile = UResources.ReqFile(INDEX_FILE_NAME);

            if (indexFile != null)
            {
                string fileJson = DESFileUtil.ReadAllText(indexFile.FullName, DESKey.DefaultKey, DESKey.DefaultIV);
                _patchIndexLocal = new PatchIndex(this.VersionCode, JObject.Parse(fileJson));
                if (_patchIndexLocal.Version != this.VersionCode)
                {
                    UpdaterLog.Log("发现patchIndex中的主版本不等于目前的主版本,说明刚经历过主包更新,清空补丁");
                    foreach (var file in ResManager.Ins.DownloadedFiles.Values)
                    {
                        File.Delete(file.FullName);
                    }
                    ResManager.Ins.ReadDownloadDir();
                    _patchIndexLocal = new PatchIndex();
                }
            }
            else
            {
                _patchIndexLocal = new PatchIndex();
            }

            //构建检查更新需要的表单
            JObject json = new JObject();

            json["Version"]      = this.VersionCode;
            json["PatchVersion"] = _patchIndexLocal.PatchVersion;
            if (CustomData != null)
            {
                foreach (var kv in CustomData)
                {
                    json[kv.Key.ToString()] = kv.Value.ToString();
                }
            }
            WWWForm form = new WWWForm();

            form.AddField("Data", json.ToString());

            HttpManager.Post(CheckUpdateUrl, form, (error, www) => {
                if (!string.IsNullOrEmpty(error))
                {
                    Listener.OnError(error);
                    return;
                }
                UpdaterLog.Log(www.text);

                JObject responseJObj = JObject.Parse(www.text);
                _updateType          = (UpdateType)(responseJObj["Type"].OptInt(0));

                switch (_updateType)
                {
                case UpdateType.NoUpdate:
                    _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                    //没有找到更新,验证文件
                    Listener.OnVerifyStart();
                    if (VerifyPatches())
                    {
                        Listener.OnVerifySuccess();
                        Listener.OnPassUpdate();
                    }
                    else
                    {
                        Listener.OnVerifyFail();
                    }
                    break;

                case UpdateType.MainPak:
                    _mainPakIndexFromServer = new MainPakIndex(this.VersionCode, responseJObj);
                    Listener.OnFindMainUpdate(_mainPakIndexFromServer.Info);
                    break;

                case UpdateType.Patch:
                    _patchIndexNew = new PatchIndex(this.VersionCode, responseJObj);
                    if (Listener != null)
                    {
                        Listener.OnFindPatchUpdate(_patchIndexNew.PatchInfo, _patchIndexNew.TotalPatchSize);
                    }
                    break;
                }
            });
        }