void read_dict(Dictionary <string, object> dict) { _version = dict["version"] as string; try { _firstVersion = dict["firstVersion"] as string; } catch (Exception) { _firstVersion = _version; } _info.Clear(); Dictionary <string, object> infoDict = dict["info"] as Dictionary <string, object>; foreach (var info in infoDict) { Dictionary <string, object> asInfoDict = info.Value as Dictionary <string, object>; XBundleInfo assetInfo = new XBundleInfo(); assetInfo.read_dict(asInfoDict); _info[info.Key] = assetInfo; } callDependAllSize(); }
public void parseManifest(AssetBundleManifest manifest, string packDir) { clear(); string[] abs = manifest.GetAllAssetBundles(); // 这里已经是小写了,所以没有大小写问题 for (int i = 0; i < abs.Length; i++) { bool isDirectory = false; string res = getResName(abs[i], out isDirectory); XBundleInfo ainfo = new XBundleInfo(); ainfo.res = res; ainfo.isDirectory = isDirectory; ainfo.persistentData = false; ainfo.hash = manifest.GetAssetBundleHash(abs[i]); ainfo.dependList = new List <string>(manifest.GetAllDependencies(abs[i])); // 获取文件大小 ainfo.fileSize = XUtil.getFileSize(packDir + abs[i]); for (int j = 0; j < ainfo.dependList.Count; j++) { ainfo.dependList[j] = getResName(ainfo.dependList[j], out isDirectory); } _info.Add(ainfo.res, ainfo); } this.callDependAllSize(); }
bool read_dict(Dictionary <string, object> dict) { oldver = readString(dict, "oldver"); if (oldver == "") { XDebug.LogError("配置文件oldver错误"); return(false); } newver = readString(dict, "newver"); if (newver == "") { XDebug.LogError("配置文件newver错误"); return(false); } alreadyDownloadDict.Clear(); Dictionary <string, object> infoDict = dict["downloadDict"] as Dictionary <string, object>; foreach (var info in infoDict) { Dictionary <string, object> asInfoDict = info.Value as Dictionary <string, object>; XBundleInfo assetInfo = new XBundleInfo(); assetInfo.read_dict(asInfoDict); alreadyDownloadDict[info.Key] = assetInfo; } return(true); }
public void calAffectChild(XBundleInfo bundle) { foreach (var af in bundle.affect) { calAffectChild(af); } affectAll.Add(bundle); }
public void calDependChild(XBundleInfo bundle) { foreach (var dp in bundle.depend) { calDependChild(dp); } dependAll.Add(bundle); }
string getRelPathName(string res, XBundleInfo bundle) { if (bundle.isDirectory) { return(_info.getRelName(res, bundle.res)); } else { return(Path.GetFileNameWithoutExtension(res)); } }
string getPath(XBundleInfo bundle) { // 确定下在什么位置 if (bundle.persistentData) { return(getABDataPath(bundle.res, bundle.isDirectory)); } else { return(getABPath(bundle.res, bundle.isDirectory)); } }
// 添加一个bundle,如果有则修改 public void addBundle(string res, XBundleInfo bundleInfo) { XBundleInfo localBundle; if (_info.ContainsKey(res)) { localBundle = _info[res]; } else { localBundle = new XBundleInfo(); _info[res] = localBundle; } localBundle.res = res; localBundle.isDirectory = bundleInfo.isDirectory; localBundle.fileSize = bundleInfo.fileSize; localBundle.hash = bundleInfo.hash; localBundle.dependList = bundleInfo.dependList; localBundle.persistentData = true; }
public XAssetInfo getAssetInfo(XLoadRes res) { // 如果有了则直接返回 if (res.asset != null) { return(res.asset); } XAssetKey key = new XAssetKey { res = res.res, all = res.all, tp = res.tp }; if (string.IsNullOrEmpty(res.res)) { res.asset = getAssetInfoFromCache(key, XLoadStatus.FAIL); return(res.asset); } // 从AB里面获取一个 if (isLoadFromAB) { // 从AB包里面获取 XBundleInfo info = getAssetBundle(res.res); if (info != null) { // 是否一定要在这里取?--1方便info做引用计数 res.asset = info.getAssetInfo(key); } else { res.asset = getAssetInfoFromCache(key, XLoadStatus.FAIL); } } else { // 直接在上面在上面进行装载 res.asset = getAssetInfoFromCache(key, XLoadStatus.NONE); } return(res.asset); }
// 优化协程版本,不开启更多的协程 IEnumerator coLoad(XLoadDesc desc, Action <XLoadDesc> cb, bool check) { // asset desc!= null if (check) { fillDesc(desc); if (desc.isComplete) { if (cb != null) { cb(desc); } yield break; } } // 一个一个的装载 for (int i = 0; i < desc.reses.Count; i++) { XLoadRes res = desc.reses[i]; desc.cursor = res; XAssetInfo asset = res.asset; if (asset.status == XLoadStatus.NONE) { asset.status = XLoadStatus.LOADING; XBundleInfo bundle = res.asset.bundle; #region bundle 装载流程 // 没装载好 if (bundle.status == XLoadStatus.NONE) { bundle.status = XLoadStatus.LOADING; bool childOK = true; // 拍平了的依赖 for (int j = 0; j < bundle.dependAll.Count; j++) { XBundleInfo dpab = bundle.dependAll[j]; if (dpab.status == XLoadStatus.NONE) { dpab.status = XLoadStatus.LOADING; // 真正装载的路径 dpab.www = new WWW(getPath(dpab)); // XDebug.LogError("装载依赖"+ getPath(dpab)); yield return(dpab.www); if (!string.IsNullOrEmpty(dpab.www.error) || dpab.www.assetBundle == null) { dpab.status = XLoadStatus.FAIL; } else { dpab.ab = dpab.www.assetBundle; dpab.status = XLoadStatus.SUCESS; } dpab.www.Dispose(); dpab.www = null; } if (!dpab.isComplete) { yield return(dpab); } if (dpab.isFail) { bundle.status = XLoadStatus.FAIL; childOK = false; break; } } // 装载自己 if (childOK) { bundle.www = new WWW(getPath(bundle)); // XDebug.LogError("装载自己" + getPath(bundle)); yield return(bundle.www); if (!string.IsNullOrEmpty(bundle.www.error) || bundle.www.assetBundle == null) { bundle.status = XLoadStatus.FAIL; } else { bundle.ab = bundle.www.assetBundle; bundle.status = XLoadStatus.SUCESS; } bundle.www.Dispose(); bundle.www = null; } } #endregion if (!bundle.isComplete) { yield return(bundle); } #region 装载asset // 失败了 if (bundle.isFail) { asset.status = XLoadStatus.FAIL; } else { // bundle成功了 if (asset.all) { asset.rq = bundle.ab.LoadAllAssetsAsync(asset.tp); yield return(asset.rq); if (asset.rq.isDone && asset.rq.allAssets != null) { asset.status = XLoadStatus.SUCESS; asset.obs = asset.rq.allAssets; if (asset.obs != null) { asset.obDict = new Dictionary <string, UnityEngine.Object>(); string[] assetNames = bundle.ab.GetAllAssetNames(); if (assetNames.Length == asset.obs.Length) { for (int k = 0; k < asset.obs.Length; k++) { asset.obDict[assetNames[k]] = asset.obs[k]; } } else { // 如果只有一项,本来名称需要相同的 if (assetNames.Length >= 1) { for (int k = 0; k < asset.obs.Length; k++) { asset.obDict[assetNames[0]] = asset.obs[k]; } } } } } else { asset.status = XLoadStatus.FAIL; } asset.rq = null; } else { string relname = getRelPathName(asset.res, bundle); asset.rq = bundle.ab.LoadAssetAsync(relname, asset.tp); yield return(asset.rq); if (asset.rq.isDone && asset.rq.asset != null) { asset.status = XLoadStatus.SUCESS; asset.ob = asset.rq.asset; } else { asset.status = XLoadStatus.FAIL; } asset.rq = null; } } #endregion } // 可以让自己直接返回 if (!asset.isComplete) { yield return(asset); } } desc._isComplete = true; if (cb != null) { cb(desc); } }
// 更新流程 public IEnumerator updateVersion(string publishUrl) { // 转化下平台接口 publishUrl = getPlatformPublishUrl(publishUrl); // 切换进度条 XLoading.instance.beginShow(0, this); string urlver = XUtil.getUrl(publishUrl, "ver.json"); WWW wwwver = new WWW(urlver); _www = wwwver; _wwwinfo = "获取" + urlver + "中"; yield return(wwwver); XVer ver = new XVer(); if (!string.IsNullOrEmpty(wwwver.error) || !ver.load(wwwver.text)) { XDebug.LogError("远程版本文件" + urlver + wwwver.error); wwwver.Dispose(); _www = null; _status = XUpdateStatus.FAIL; yield break; } wwwver.Dispose(); XDebug.Log("更新开始远程版本号:v" + ver.ver + "当前版本号:v" + XLoad.instance.localver); if (ver.ver != XLoad.instance.localver) { string urlversion = XUtil.getUrl(ver.ab, "v" + ver.ver + "/assets/version.json"); WWW wwwWebInfo = new WWW(urlversion); _www = wwwWebInfo; _wwwinfo = "获取" + urlversion + "中"; yield return(wwwWebInfo); XPackInfo webInfo = new XPackInfo(); if (!string.IsNullOrEmpty(wwwWebInfo.error) || !webInfo.load(wwwWebInfo.text)) { XDebug.LogError("远程版本文件" + urlver + wwwWebInfo.error); wwwWebInfo.Dispose(); _www = null; _status = XUpdateStatus.FAIL; yield break; } wwwWebInfo.Dispose(); Dictionary <string, XBundleInfo> modify = XLoad.instance._info.compareWebList(webInfo); uint allsize = 0; int filecount = modify.Count; foreach (var bd in modify) { allsize += (uint)(bd.Value.fileSize); } if (filecount <= 0) { XDebug.Log("文件一样无需更新修改版本号"); XLoad.instance._info._version = ver.ver; // 保存文件 XLoad.instance._info.saveFile(XLoad.getABDataWritePath("assets/version.json")); _status = XUpdateStatus.SUCESS; // todo 修改版本号 yield break; } XDebug.Log(string.Format("一共{0}个文件,大小需要更新{1}", filecount, XUtil.getSizeString(allsize))); // 更新目录 this.oldver = XLoad.instance.localver; this.newver = ver.ver; string updateDirName = getUpdateDirName(); string updateFileName = getUpdateFileName("update.json"); if (XUtil.isExistDirectory(updateDirName) && XUtil.isExistFile(updateFileName)) { if (!loadFile(updateFileName)) { alreadyDownloadDict.Clear(); XUtil.clearDirectory(updateDirName); } } int fileno = 0; foreach (var bd in modify) { fileno++; string ufilename = getUpdateFileName(bd.Key, bd.Value.isDirectory); if (alreadyDownloadDict.ContainsKey(bd.Key)) { XBundleInfo bundleInfo = alreadyDownloadDict[bd.Key]; if (bundleInfo.fileSize == bd.Value.fileSize && bundleInfo.hash == bd.Value.hash && XUtil.isExistFile(ufilename)) { XDebug.Log("文件已下载完毕,跳过" + ufilename); continue; } } if (XUtil.isExistFile(ufilename)) { XUtil.deleteFile(ufilename); } string webufile = getUpdateWebName(ver.ab, "v" + ver.ver + "/" + bd.Key, bd.Value.isDirectory); WWW wwwufile = new WWW(webufile); _www = wwwufile; _wwwinfo = string.Format("下载({0}/{1}){2}", fileno, filecount, bd.Key); yield return(wwwufile); if (!string.IsNullOrEmpty(wwwufile.error)) { XDebug.LogError("远程文件" + webufile + wwwufile.error); wwwufile.Dispose(); _www = null; _status = XUpdateStatus.FAIL; yield break; } if (!XUtil.writeFileAllBytes(ufilename, wwwufile.bytes)) { XDebug.LogError("写入文件失败" + ufilename); wwwufile.Dispose(); _www = null; _status = XUpdateStatus.FAIL; yield break; } alreadyDownloadDict[bd.Key] = bd.Value; // 保存一下记录 saveFile(updateFileName); wwwufile.Dispose(); _www = null; } // 已经成功了,拷贝文件到目标文件 _wwwinfo = "拷贝文件中"; foreach (var bd in modify) { string ufilename = getUpdateFileName(bd.Key, bd.Value.isDirectory); string dfilename = XLoad.getABDataWritePath(bd.Key, bd.Value.isDirectory); if (!XUtil.copyFile(ufilename, dfilename)) { XDebug.LogError("拷贝文件失败" + ufilename); _status = XUpdateStatus.FAIL; break; } XLoad.instance._info.addBundle(bd.Key, bd.Value); } _wwwinfo = "重新生成版本文件"; XLoad.instance._info.callDependAllSize(); // 变更版本 XLoad.instance._info._version = ver.ver; // 保存文件 if (!XLoad.instance._info.saveFile(XLoad.getABDataWritePath("assets/version.json"))) { _status = XUpdateStatus.FAIL; yield break; } _status = XUpdateStatus.SUCESS; } else { // XDebug.Log("版本一致没有什么不同无需更新"); _status = XUpdateStatus.SUCESS; } }