public static void Patch(string platform) { var p = Application.dataPath + DevCacheDirectory + platform + AssetBundlePath.kSlash + AssetBundlePath.kPackCfg; var jsonData = File.ReadAllText(p); var cfg = new PackageCfg(); EditorJsonUtility.FromJsonOverwrite(jsonData, cfg); var tmpDir = Application.dataPath + "/tempDir"; if (Directory.Exists(tmpDir)) { Directory.Delete(tmpDir, true); } var patchCfg = new PackageCfg(); patchCfg.PatchVersion = PackEditorWin.GetCfg().PatchVersion; var parentPath = Application.dataPath + DevCacheDirectory + platform; var codePatchFile = parentPath + AssetBundlePath.kSlash + AssetBundlePath.kCodePatchFile; if (File.Exists(codePatchFile)) { cfg.Files.Add(new FileCfg(CommonTool.CalFileMD5(codePatchFile), AssetBundlePath.kCodePatchFile)); } for (int i = 0; i < cfg.Files.Count; ++i) { var f = cfg.Files[i]; var md5 = CommonTool.CalFileMD5(parentPath + AssetBundlePath.kSlash + f.Path); if (Path.GetExtension(f.Path) == AssetBundleMgr.instance.kPatchFileExt || md5 != f.MD5 && Path.GetExtension(f.Path) != AssetBundlePath.kPackCfgSuffix) { patchCfg.Files.Add(new FileCfg(md5, f.Path)); var t = tmpDir + AssetBundlePath.kSlash + f.Path; if (!Directory.Exists(Path.GetDirectoryName(t))) { Directory.CreateDirectory(Path.GetDirectoryName(t)); } File.Copy(parentPath + AssetBundlePath.kSlash + f.Path, t); } } if (patchCfg.Files.Count != 0) { using (var sw = File.CreateText(tmpDir + AssetBundlePath.kSlash + AssetBundlePath.kPatchCfg)) { sw.Write(EditorJsonUtility.ToJson(patchCfg)); } ZipHelper.ZipDirectoryDirect(tmpDir, Application.dataPath + DiffPatchDirectory + platform + AssetBundlePath.kPatchZipRes); TimeLogger.LogYellow(platform + "差异包生成成功"); if (Directory.Exists(tmpDir)) { Directory.Delete(tmpDir, true); } } else { Debug.LogError("no different patch"); } }
public static void GeneratePackageCfg(string directoryPath) { var root = Path.GetFileNameWithoutExtension(directoryPath).ToLower(); var packEditorCfg = PackEditorWin.GetCfg(); var packCfg = new PackageCfg(); packCfg.CurVersion = packEditorCfg.CurVersion; packCfg.PatchVersion = packEditorCfg.PatchVersion; packCfg.ForceUpdateVersion = packEditorCfg.ForceUpdateVersion; TraverseDirectory(directoryPath, packCfg, root); var filePath = directoryPath + AssetBundlePath.kSlash + AssetBundlePath.kPackCfg; if (File.Exists(filePath)) { File.Delete(filePath); } using (var sw = File.CreateText(filePath)) { sw.Write(EditorJsonUtility.ToJson(packCfg)); } }
public static PackageCfg GetCfg() { var cfg = new PackageCfg(); var d = EditorPrefs.GetString(SaveKey, ""); if (!string.IsNullOrEmpty(d)) { EditorJsonUtility.FromJsonOverwrite(d, cfg); } return(cfg); }
public static void TraverseDirectory(string dirPath, PackageCfg pcfg, string root) { var files = Directory.GetFiles(dirPath); foreach (var file in files) { var correctFileName = file.Replace(@"\", @"/").ToLower(); var ext = Path.GetExtension(correctFileName); var ret = AssetBundleMgr.instance.CompressExts.FirstOrDefault(c => c == ext); if (!string.IsNullOrEmpty(ret)) { pcfg.Files.Add(new FileCfg(CommonTool.CalFileMD5(correctFileName), GetRelativePath(correctFileName, root))); } } var dirs = Directory.GetDirectories(dirPath); foreach (var dir in dirs) { TraverseDirectory(dir, pcfg, root); } }
IEnumerator PackCoroutineEnter() { EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0f); yield return StartCoroutine(UncompressPackRes(false)); var mainPackCfg = new PackageCfg(); var mainPackCfgPath = Application.persistentDataPath + AssetBundlePath.kSlash + AssetBundleMgr.instance.ZipFolder + AssetBundlePath.kSlash + AssetBundlePath.kPackCfg; var jsonData = File.ReadAllText(mainPackCfgPath); JsonUtility.FromJsonOverwrite(jsonData, mainPackCfg); EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.05f); //覆盖安装检测(之前已经有了缓存文件) var InternalCfg = Resources.Load<VersionCfg>(Path.GetFileNameWithoutExtension(AssetBundlePath.kVersionCfg)); if (mainPackCfg.CurVersion != InternalCfg.CurVersion) { yield return StartCoroutine(UncompressPackRes(true)); jsonData = File.ReadAllText(mainPackCfgPath); JsonUtility.FromJsonOverwrite(jsonData, mainPackCfg); } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.2f); //todo: 向服务器请求版本更新信息 var updateUri = "192.168.1.79/" + "UpdateJson"; var patchUri = "file://" + Application.dataPath + "/DiffPatch/" + AssetBundleMgr.instance.PatchZip; using (var updateReq = UnityWebRequest.Get(updateUri)) { EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.3f); yield return updateReq.SendWebRequest(); if (updateReq.isHttpError || updateReq.isNetworkError) { Debug.LogError(updateReq.error); yield break; } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.4f); var serverCfg = new PackageCfg(); jsonData = System.Text.Encoding.UTF8.GetString(updateReq.downloadHandler.data); JsonUtility.FromJsonOverwrite(jsonData, serverCfg); if (mainPackCfg.CurVersion < serverCfg.ForceUpdateVersion) { //todo:展示强更界面 yield break; } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.5f); //处理补丁包 var mainRoot = Application.persistentDataPath + AssetBundlePath.kSlash + AssetBundleMgr.instance.ZipFolder + AssetBundlePath.kSlash; if (mainPackCfg.PatchVersion < serverCfg.PatchVersion) { if (mainPackCfg.PatchVersion != 0) { yield return StartCoroutine(UncompressPackRes(true)); } using (var patchReq = UnityWebRequest.Get(patchUri)) { EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.6f); yield return patchReq.SendWebRequest(); if (patchReq.isNetworkError || patchReq.isHttpError) { Debug.LogError(updateReq.error); yield break; } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.7f); var patchZipPath = Application.persistentDataPath + AssetBundlePath.kSlash + AssetBundleMgr.instance.PatchZip; if (File.Exists(patchZipPath)) { File.Delete(patchZipPath); } File.WriteAllBytes(patchZipPath, patchReq.downloadHandler.data); ForceUncompressLocalRes(patchZipPath, Application.persistentDataPath + AssetBundlePath.kSlash + AssetBundlePath.kPatchDir); } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.8f); //合并主包与补丁包配置 var mainPackDict = new Dictionary<string, FileCfg>(); foreach (var mf in mainPackCfg.Files) { mainPackDict[mf.Path] = mf; } var patchRoot = Application.persistentDataPath + AssetBundlePath.kSlash + AssetBundlePath.kPatchDir + AssetBundlePath.kSlash; var patchCfg = new PackageCfg(); var patchJsonData = File.ReadAllText(patchRoot + AssetBundlePath.kPatchCfg); JsonUtility.FromJsonOverwrite(patchJsonData, patchCfg); foreach (var f in patchCfg.Files) { var isPatchFile = Path.GetExtension(f.Path) == AssetBundleMgr.instance.kPatchFileExt; if (!isPatchFile) { if (!mainPackDict.ContainsKey(f.Path)) { Debug.LogError("patch file no mainPack file:" + f.Path); yield break; } if (mainPackDict[f.Path].MD5 == f.MD5) { Debug.LogError("patchfile same as mainPack file:" + f.Path); yield break; } } if (File.Exists(mainRoot + f.Path)) { File.Delete(mainRoot + f.Path); } File.Copy(patchRoot + f.Path, mainRoot + f.Path); mainPackDict[f.Path] = f; } mainPackCfg.PatchVersion = patchCfg.PatchVersion; mainPackCfg.Files = mainPackDict.Values.ToList(); var mergeCfgJsonData = JsonUtility.ToJson(mainPackCfg); if (File.Exists(mainPackCfgPath)) { File.Delete(mainPackCfgPath); } File.WriteAllText(mainPackCfgPath, mergeCfgJsonData); Directory.Delete(patchRoot, true); } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 0.9f); //进行文件完整性校验 var md5 = ""; foreach(var f in mainPackCfg.Files) { if (!File.Exists(mainRoot + f.Path)) { Debug.LogError("mainPack file not exist " + f.Path); yield break; } if (Path.GetExtension(f.Path) == AssetBundlePath.kPackCfgSuffix) { continue; } md5 = CommonTool.CalFileMD5(mainRoot + f.Path); if (md5 != f.MD5) { Debug.LogError(string.Format("mainPack file MD5 check error! cfg md5:{0} real md5:{1}", f.MD5, md5)); yield break; } } //如果存在代码补丁就加载 var codePatchFile = mainRoot + AssetBundlePath.kCodePatchFile; if (File.Exists(codePatchFile)) { PatchManager.Load(new MemoryStream(File.ReadAllBytes(codePatchFile))); } EventMgr.instance.SendEvent<float>(EventDefine.UpdateProgress, 1f); } EventMgr.instance.SendEvent(EventDefine.UpdateFinish); }