public string GetMappedFileName() { var name = string.Format("{0}{1}{2}", MD5Creater.MD5LongToHexStr(MapedFileName_MD51) , MD5Creater.MD5LongToHexStr(MapedFileName_MD52), FileExtension); return(name); }
/// <summary> /// 无论啥错误都会返回一个默认的 /// </summary> /// <param name="cfgBytes"></param> /// <returns></returns> public static FileMapGroupInfo ReadFromByteBuf(byte[] cfgBytes) { var group = new FileMapGroupInfo(); var byteBuf = ByteBuf.CreateFromBytes(cfgBytes); group.MD51 = byteBuf.ReadLong(); group.MD52 = byteBuf.ReadLong(); group.Ver = new Version() { Version_Major = byteBuf.ReadInt(), Version_Minor = byteBuf.ReadInt(), Version_Build = byteBuf.ReadInt(), }; var readedMd5 = MD5Creater.MD5Struct.CreateFromLong(group.MD51, group.MD52); var fileMD5 = MD5Creater.GenerateMd5Code(cfgBytes, 16); if (!readedMd5.Equals(fileMD5)) { CommonLog.Error("MD5校验不通过!"); return(null); } int FileNum = byteBuf.ReadInt(); group.AllFileMapInfo = new FileMapInfo[FileNum]; for (int i = 0; i < group.AllFileMapInfo.Length; i++) { group.AllFileMapInfo[i] = FileMapInfo.ReadFromByteBuf(byteBuf); } return(group); }
private (WebRequestError, string) CheckWebRequestError(SingleFileDownloadRequest sr, UnityWebRequest request) { var error = request.error; if (!string.IsNullOrEmpty(error)) { return(WebRequestError.Raw, error); } if (!File.Exists(sr.targetPath)) { error = $"download finish but {sr.targetPath} not exist"; return(WebRequestError.NoExist, error); } if (sr.md5 != null) { var bs = File.ReadAllBytes(sr.targetPath); var md5Struct = MD5Creater.GenerateMd5Code(bs); var bm = sr.md5.Value; if (md5Struct.MD51 != bm.MD51 || md5Struct.MD52 != bm.MD52) { error = $"download file {sr.targetPath} md5 error {md5Struct.GetMD5Str(false)}->{bm.GetMD5Str(false)}"; return(WebRequestError.Md5, error); } } return(WebRequestError.None, null); }
public MD5Creater.MD5Struct WriteToByteBuf(ByteBuf buf) { //标记MD5 int firstIndex = buf.WriterIndex; buf.WriteLong(0); buf.WriteLong(0); //写入Ver buf.WriteInt(Ver.Version_Major); buf.WriteInt(Ver.Version_Minor); buf.WriteInt(Ver.Version_Build); //data buf.WriteInt(AllFileMapInfo.Length); for (int i = 0; i < AllFileMapInfo.Length; i++) { var info = AllFileMapInfo[i]; info.WriteToByteBuf(buf); } int finalIndex = buf.WriterIndex; var bytelen = finalIndex - firstIndex; //计算MD5 var fileMD5 = MD5Creater.GenerateMd5Code(buf.GetRaw(), firstIndex + 16, bytelen - 16); buf.SetWriterIndex(firstIndex); buf.WriteLong(fileMD5.MD51); buf.WriteLong(fileMD5.MD52); buf.SetWriterIndex(finalIndex); return(fileMD5); }
/// <summary> /// 获取某目录下的所有文件路径的md5值 不包含meta文件 /// </summary> /// <param name="rootPath">查找的根目录</param> /// <param name="contain">路径包含的字符串</param> /// <param name="hasExt">是否有扩展名</param> /// <returns></returns> public static List <string> GetMD5FilesPath(string rootPath, string contain, bool hasExt, bool isShort) { List <string> md5FilePath = new List <string>(); List <string> filePathList = GetFilesPath(rootPath, contain, hasExt); foreach (var filePath in filePathList) { md5FilePath.Add(MD5Creater.Md5String(filePath, isShort)); } return(md5FilePath); }
private static void CleanAndGenMD5UpdateFileFileHelper( List <AssetBundleUpdateInfo.AssetBundleUpdateFileInfo> upfileList, string path, MD5Creater.MD5Struct md5, bool isComplex) { var fi = new AssetBundleUpdateInfo.AssetBundleUpdateFileInfo(); fi.FileName = md5; fi.IsComplexName = isComplex; fi.FileMD5 = MD5Creater.MD5FileShortLong(path + fi.FileName.GetMD5Str(!fi.IsComplexName)); fi.SizeKB = Mathf.Clamp((int)(FileUtils.FileSize(path + fi.FileName.GetMD5Str(!fi.IsComplexName)) / 1024), 1, int.MaxValue); upfileList.Add(fi); }
private void PrepareDownloads(FileMapSystem.FileMapSystem newMap, string versionStr) { if (_downloader != null) { _downloader.Release(); _downloader = null; } _downloader = new HttpFileDownloader(new Uri(GetDownloadBaseURL(versionStr)), AssetBundlePathResolver.BundleSaveDirName); var currentMap = AssetBundleManager.Instance.GetFileMapSystem(); var misses = currentMap.GetMissFileMaps(newMap); _currentDownloadingGroupDesc = misses; CommonLog.Log(MAuthor.WY, $"{misses.Count} files miss in current file map"); foreach (var fileMapGroupDescIter in misses) { var fileName = fileMapGroupDescIter.Key; var desc = fileMapGroupDescIter.Value; var fileSavePath = _savePath + fileName; if (File.Exists(fileSavePath)) { var bytes = FileUtils.ReadAllBytes(fileSavePath); if (bytes != null && bytes.Length > 0) { var md5 = MD5Creater.Md5Struct(bytes); if (md5.MD51 == desc.Md51 && md5.MD52 == desc.Md52) { CommonLog.Log(MAuthor.WY, $"file {fileSavePath} already exist, skip"); continue; } } } _downloader.AddDownLoad(new WWWFileDownloader.DownloadFileInfo { FileName = fileName, FileSize = desc.Len, MapedFileName_MD51 = desc.Md51, MapedFileName_MD52 = desc.Md52, }); } }
/// <summary> /// 计算MD5 /// </summary> /// <param name="path"></param> /// <returns></returns> public static string CalcMD5(string path) { try { if (string.IsNullOrEmpty(path)) { return(string.Empty); } if (md5Dict.TryGetValue(path, out var md5)) { return(md5); } md5 = MD5Creater.MD5File(path); md5Dict.Add(path, md5); return(md5); } catch (System.Exception e) { Debug.LogError(path + "\n " + e.ToString()); return(string.Empty); } }
private void CheckMd5AndReplaceTempFile(RequestState myRequestState) { var ms = new MemoryStream(); myRequestState.m_file_stream.Position = 0; myRequestState.m_file_stream.CopyTo(ms); var md5Struct = MD5Creater.GenerateMd5Code(ms.ToArray()); myRequestState.m_file_stream.Close(); ms.Dispose(); var pathRoot = UnityPersistFileHelper.GetPersistAssetFilePath(SavedDir, ""); if (md5Struct.MD51 == myRequestState.fileInfo.MapedFileName_MD51 && md5Struct.MD52 == myRequestState.fileInfo.MapedFileName_MD52) { CommonLog.Log($"complete download file {myRequestState.fileInfo.FileName}"); myRequestState.progress.RealCompletedSize -= myRequestState.downloadedSize; myRequestState.progress.RealCompletedSize += myRequestState.fileInfo.FileSize; //myRequestState.fileSize; myRequestState.progress.UpdateProgress(); FileUtils.RenameFile(pathRoot, myRequestState.fileInfo.FileName + TempExtension, myRequestState.fileInfo.FileName); } else { var tempFilePath = pathRoot + myRequestState.fileInfo.FileName + TempExtension; CommonLog.Error(MAuthor.WY, $"file {myRequestState.fileInfo.FileName} md5 error, delete file {tempFilePath}"); FileUtils.DeleteFile(tempFilePath); myRequestState.progress.SetException("md5 check failed", WWWFileDownloader.eWWWErrorType.WriteFileError); } }
public virtual void End(AssetBundleManifest manifest, bool addPacker = false) { //生成TableBundle信息 XMLTable = new AssetBundleTable(); XMLTable.GenBundleInfoFromRaw(AssetBundleRawInfoList); //刷新XML数据 RefreshXMLTableByManifest(manifest); var abMainifestName = System.IO.Path.GetFileName(BundleSavePath.Substring(0, BundleSavePath.Length - 1)); //删了主AB包 FileUtils.DeleteFile(BundleSavePath + abMainifestName); //删了无用的manifest //FileUtils.DeleteFiles(BundleSavePath(), SearchOption.TopDirectoryOnly, ".manifest"); //重命名所有Bundle //foreach (var info in XMLTable.BundleInfos) for (int index = 0; index < XMLTable.BundleInfos.Length; index++) { var bunldeInfo = XMLTable.BundleInfos[index]; for (int i = 0; i < bunldeInfo.bundleLanguages.Length; i++) { if (bunldeInfo.bundleLanguages[i]) { if (!FileUtils.IsFileExist(BundleSavePath + bunldeInfo.GetBundleNameWithLangExtension((eAssetLanguageVarType)i))) { CommonLog.Error("找不到打包后的资源:" + bunldeInfo.assets[0].assetFullName); continue; } //是否增量打Bundle if (addPacker) { string sourceFilePath = BundleSavePath + bunldeInfo.GetBundleNameWithLangExtension((eAssetLanguageVarType)i); string targetFilePath = BundleSavePath + bunldeInfo.GetBundleFileNameWithLangExtension((eAssetLanguageVarType)i); if (!sourceFilePath.Equals(targetFilePath)) { if (File.Exists(targetFilePath)) { File.Delete(targetFilePath); } File.Copy(BundleSavePath + bunldeInfo.GetBundleNameWithLangExtension((eAssetLanguageVarType)i), BundleSavePath + bunldeInfo.GetBundleFileNameWithLangExtension((eAssetLanguageVarType)i), true); } } else { FileUtils.RenameFile(BundleSavePath, bunldeInfo.GetBundleNameWithLangExtension((eAssetLanguageVarType)i), bunldeInfo.GetBundleFileNameWithLangExtension((eAssetLanguageVarType)i)); } } } //计算Bundle的MD5 var assetBundleBytes = FileUtils.ReadAllBytes($"{BundleSavePath}/{bunldeInfo.bundleFileName}"); if (assetBundleBytes != null && assetBundleBytes.Length > 0) { var md5Str = MD5Creater.Md5Struct(assetBundleBytes).GetMD5Str(false); bunldeInfo.bundleMD5 = md5Str; } } //TODO 写上版本号 string xml = XMLTable.ToXML(); File.WriteAllText(BundleSavePath + AssetBundlePathResolver.DependFileName, xml); EditorUtility.ClearProgressBar(); CommonLog.Warning(string.Format("热更新XML生成完成")); }
private static List <AssetBundleXMLRawData> RefreshNewNameAndGetAssetBundleList() { List <AssetBundleXMLRawData> list = new List <AssetBundleXMLRawData>(); //非Default的资源 List <AssetBundleXMLRawData> foreignlist = new List <AssetBundleXMLRawData>(); bool checkConfig = AssetBundleBuilderExtSetting.Instance.InitProjectSettingFromFile(); if (!checkConfig) { return(null); } var paths = AssetDatabase.GetAllAssetPaths(); bool isBreak = false; for (int i = 0; i < paths.Length; i++) { var path = paths[i]; if (!path.Contains(".")) { continue; } //不需要打包的文件类型 if (!CheckNeedPackFile(path)) { continue; } if (!path.Contains("/AssetBundles/") && !AssetBundleBuilderExtSetting.Instance.CheckIsInExtFolderAsset(path) && !AssetBundleBuilderExtSetting.Instance.CheckIsSpriteInTagAsset(path)) { continue; } //if (!path.Contains("/AssetBundles/")) continue; //不导文件夹 if (AssetDatabase.IsValidFolder(path)) { continue; } //是否取消打包 isBreak = EditorUtility.DisplayCancelableProgressBar("Loading", path, (float)i / paths.Length); if (isBreak) { CommonLog.Log("终止打包"); return(null); } AssetBundleXMLRawData xmlRawData = new AssetBundleXMLRawData(); var extensionName = Path.GetExtension(path); //path.Remove(0,path.LastIndexOf(".", StringComparison.Ordinal)); var withoutExtensionPath = path.Replace(extensionName, string.Empty); //path.Substring(0, path.LastIndexOf(".", StringComparison.Ordinal)); int abResourceStartIndex = withoutExtensionPath.LastIndexOf("AssetBundles", StringComparison.Ordinal); var resPath = AssetI8NHelper.GetDefaultPathLanguage(abResourceStartIndex >= 0 ? withoutExtensionPath.Substring(abResourceStartIndex) : withoutExtensionPath); //剔除 Assets/ if (resPath.StartsWith("Assets/")) { int startIndex = resPath.IndexOf("/", StringComparison.Ordinal) + 1; resPath = resPath.Substring(startIndex); } var langType = AssetI8NHelper.GetPathLanguage(path); xmlRawData.resPath = resPath; xmlRawData.resPathMD5Struct = MD5Creater.Md5Struct(xmlRawData.resPath); xmlRawData.Language = langType; string fileName = Path.GetFileNameWithoutExtension(resPath); string bundleName = Path.GetDirectoryName(resPath.Substring(0, resPath.LastIndexOf("/", StringComparison.Ordinal))); //设置bundleName,使用时,使用下面的MD5 xmlRawData.bundleName = AssetBundleBuilderExtSetting.Instance.GetGroupMappedBundlePath(xmlRawData.resPath, extensionName); xmlRawData.bundleMD5Struct = MD5Creater.Md5Struct( AssetBundleBuilderExtSetting.Instance.GetGroupMappedBundlePath(xmlRawData.resPath, extensionName)); //fullName带后缀名 //int assetStartIndex = path.IndexOf("Assets", StringComparison.Ordinal); xmlRawData.assetFullName = path; //path.Substring(assetStartIndex); //int resStartIndex = resPath.LastIndexOf("/", StringComparison.Ordinal) + 1; xmlRawData.resShortName = Path.GetFileName(resPath); //resPath.Substring(resStartIndex); xmlRawData.OtherLanguages[(int)langType] = true; list.Add(xmlRawData); foreignlist.Add(xmlRawData); } //第二遍开始计算asset的多语言信息 foreach (var xmlRaw in list) { if (xmlRaw.Language == eAssetLanguageVarType.Default) { foreach (var xmlForeign in foreignlist) { if (xmlForeign.bundleName == xmlRaw.bundleName) { xmlRaw.OtherLanguages[(int)xmlForeign.Language] = true; } } } } return(list); }