// 检查本地 bundle 是否有效 public static bool IsBundleFileValid(string fullPath, Manifest.BundleInfo bundleInfo) { try { var metaPath = fullPath + Metadata.Ext; if (File.Exists(fullPath)) { if (File.Exists(metaPath)) { var json = File.ReadAllText(metaPath); var metadata = JsonUtility.FromJson <Metadata>(json); // quick but unsafe if (metadata != null && metadata.checksum == bundleInfo.checksum && metadata.size == bundleInfo.size) { return(true); } File.Delete(metaPath); } } } catch (Exception exception) { Debug.LogError(exception); } return(false); }
public static Stream GetDecryptStream(Stream fin, Manifest.BundleInfo bundleInfo, string password) { if (bundleInfo.encrypted) { //TODO: 内存问题 var buffer = new byte[bundleInfo.size]; var phrase = password + bundleInfo.name; var key = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(phrase)); var iv = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(phrase + Manifest.EncryptionSalt)); using (var algo = Rijndael.Create()) { algo.Padding = PaddingMode.Zeros; var decryptor = algo.CreateDecryptor(key, iv); using (var cstream = new CryptoStream(fin, decryptor, CryptoStreamMode.Read)) { cstream.Read(buffer, 0, buffer.Length); } } fin.Close(); var seekableStream = new MemoryStream(buffer, 0, bundleInfo.rsize, false); return(seekableStream); } return(fin); }
public static Stream GetDecryptStream(Stream fin, Manifest.BundleInfo bundleInfo, string password) { if (bundleInfo.encrypted) { return(GetDecryptStream(fin, bundleInfo.name, bundleInfo.size, bundleInfo.rsize, password)); } return(fin); }
public Entry CreateEntry(Manifest.BundleInfo bundle) { Entry entry = new Entry(bundle); foreach (var assetPath in bundle.assets) { entry.Add(assetPath); } _entries.Add(bundle.name, entry); return(entry); }
public static FileStream GetBundleStream(string fullPath, Manifest.BundleInfo bundleInfo) { try { if (IsBundleFileValid(fullPath, bundleInfo)) { var fileStream = System.IO.File.OpenRead(fullPath); return(fileStream); } } catch (Exception exception) { Debug.LogError(exception); } return(null); }
// 检查本地 bundle 是否有效 public static bool IsBundleFileValid(string fullPath, Manifest.BundleInfo bundleInfo) { return(IsFileValid(fullPath, bundleInfo.checksum, bundleInfo.size)); }
public Entry(Manifest.BundleInfo bundle) { _bundle = bundle; }
// 生成清单 public static void BuildManifest(BundleBuilderData data, string outputPath, AssetBundleManifest assetBundleManifest, ZipArchiveManifest zipArchiveManifest) { var manifest = new Manifest(); if (assetBundleManifest != null) { var assetBundles = assetBundleManifest.GetAllAssetBundles(); foreach (var assetBundle in assetBundles) { BundleBuilderData.BundleInfo bundleInfo; BundleBuilderData.BundleSplit bundleSplit; if (TryGetBundleSplit(data, assetBundle, out bundleInfo, out bundleSplit)) { // Debug.Log(bundleInfo.name); var assetBundlePath = Path.Combine(outputPath, assetBundle); using (var stream = File.OpenRead(assetBundlePath)) { var fileInfo = new FileInfo(assetBundlePath); var checksum = new Utils.Crc16(); checksum.Update(stream); var bundle = new Manifest.BundleInfo(); bundle.type = Manifest.BundleType.AssetBundle; bundle.name = bundleSplit.name; bundle.checksum = checksum.hex; bundle.size = (int)fileInfo.Length; bundle.startup = bundleInfo.load == BundleLoad.Startup; bundle.priority = bundleInfo.priority; foreach (var asset in bundleSplit.assets) { var assetPath = AssetDatabase.GetAssetPath(asset); bundle.assets.Add(assetPath); } bundle.dependencies = assetBundleManifest.GetAllDependencies(assetBundle); manifest.bundles.Add(bundle); } } } } if (zipArchiveManifest != null) { foreach (var zipArchive in zipArchiveManifest.archives) { var bundleInfo = GetBundleInfo(data, zipArchive.name); var zipArchivePath = Path.Combine(outputPath, zipArchive.name); using (var stream = File.OpenRead(zipArchivePath)) { var fileInfo = new FileInfo(zipArchivePath); var checksum = new Utils.Crc16(); checksum.Update(stream); var bundle = new Manifest.BundleInfo(); bundle.type = Manifest.BundleType.ZipArchive; bundle.name = zipArchive.name; bundle.checksum = checksum.hex; bundle.size = (int)fileInfo.Length; bundle.startup = bundleInfo.load == BundleLoad.Startup; bundle.priority = bundleInfo.priority; foreach (var assetPath in zipArchive.assets) { // var assetPath = AssetDatabase.GetAssetPath(asset.target); bundle.assets.Add(assetPath); } // bundle.dependencies = null; manifest.bundles.Add(bundle); } } } if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } var json = JsonUtility.ToJson(manifest); var jsonChecksum = Utils.Crc16.ToString(Utils.Crc16.ComputeChecksum(System.Text.Encoding.UTF8.GetBytes(json))); var manifestPath = Path.Combine(outputPath, "manifest.json"); var manifestChecksumPath = Path.Combine(outputPath, "checksum.txt"); File.WriteAllText(manifestPath, json); File.WriteAllText(manifestChecksumPath, jsonChecksum); }
// 生成清单 public static void BuildManifest(BundleBuilderData data, string outputPath, AssetBundleManifest assetBundleManifest, ZipArchiveManifest zipArchiveManifest, out EmbeddedManifest embeddedManifest) { var manifest = new Manifest(); embeddedManifest = new EmbeddedManifest(); if (assetBundleManifest != null) { var assetBundles = assetBundleManifest.GetAllAssetBundles(); foreach (var assetBundle in assetBundles) { BundleBuilderData.BundleInfo bundleInfo; BundleBuilderData.BundleSplit bundleSplit; if (TryGetBundleSplit(data, assetBundle, out bundleInfo, out bundleSplit)) { // Debug.Log(bundleInfo.name); var assetBundlePath = Path.Combine(outputPath, assetBundle); using (var stream = File.OpenRead(assetBundlePath)) { var fileInfo = new FileInfo(assetBundlePath); var checksum = new Utils.Crc16(); checksum.Update(stream); var bundle = new Manifest.BundleInfo(); bundle.type = Manifest.BundleType.AssetBundle; bundle.name = bundleSplit.name; bundle.checksum = checksum.hex; bundle.size = (int)fileInfo.Length; bundle.load = bundleInfo.load; bundle.priority = bundleInfo.priority; foreach (var asset in bundleSplit.assets) { var assetPath = AssetDatabase.GetAssetPath(asset); bundle.assets.Add(assetPath); } bundle.dependencies = assetBundleManifest.GetAllDependencies(assetBundle); manifest.bundles.Add(bundle); if (bundleInfo.streamingAssets) { embeddedManifest.bundles.Add(new EmbeddedManifest.BundleInfo() { name = bundle.name, checksum = bundle.checksum, size = bundle.size, }); } } } } } if (zipArchiveManifest != null) { foreach (var zipArchive in zipArchiveManifest.archives) { var bundleInfo = GetBundleInfo(data, zipArchive.name); var zipArchivePath = Path.Combine(outputPath, zipArchive.name); using (var stream = File.OpenRead(zipArchivePath)) { var fileInfo = new FileInfo(zipArchivePath); var checksum = new Utils.Crc16(); checksum.Update(stream); var bundle = new Manifest.BundleInfo(); bundle.type = Manifest.BundleType.ZipArchive; bundle.name = zipArchive.name; bundle.checksum = checksum.hex; bundle.size = (int)fileInfo.Length; bundle.load = bundleInfo.load; bundle.priority = bundleInfo.priority; foreach (var assetPath in zipArchive.assets) { // var assetPath = AssetDatabase.GetAssetPath(asset.target); bundle.assets.Add(assetPath); } // bundle.dependencies = null; manifest.bundles.Add(bundle); if (bundleInfo.streamingAssets) { embeddedManifest.bundles.Add(new EmbeddedManifest.BundleInfo() { name = bundle.name, checksum = bundle.checksum, size = bundle.size, }); } } } } if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } OutputManifest(manifest, outputPath); OutputEmbeddedManifest(embeddedManifest, outputPath); }
// 生成最终包文件, 生成最终清单 public static EmbeddedManifest BuildFinalPackages(PackageBuildInfo buildInfo, AssetBundleManifest assetBundleManifest, ZipArchiveManifest zipArchiveManifest, FileListManifest fileListManifest, RawFileManifest rawFileManifest) { var data = buildInfo.data; var manifest = new Manifest(); manifest.chunkSize = data.chunkSize; manifest.build = buildInfo.data.build; manifest.timestamp = (int)(DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds; manifest.tag = buildInfo.sharedBuildInfo.tag; var embeddedManifest = new EmbeddedManifest(); if (assetBundleManifest != null) { var assetBundles = assetBundleManifest.GetAllAssetBundles(); foreach (var assetBundle in assetBundles) { BundleBuilderData.BundleInfo bundleInfo; BundleBuilderData.BundleSplit bundleSplit; BundleBuilderData.BundleSlice bundleSlice; if (TryGetBundleSlice(data, assetBundle, out bundleInfo, out bundleSplit, out bundleSlice)) { // Debug.Log(bundleInfo.name); var fileEntry = EncryptFileEntry(data, buildInfo, bundleSplit.encrypted, bundleSlice.name, buildInfo.assetBundlePath); var bundle = new Manifest.BundleInfo(); bundle.comment = bundleInfo.note; bundle.tag = bundleInfo.tag; bundle.encrypted = bundleSplit.encrypted; bundle.rsize = fileEntry.rsize; bundle.type = Manifest.BundleType.AssetBundle; bundle.name = fileEntry.name; bundle.checksum = fileEntry.checksum; bundle.size = fileEntry.size; bundle.load = bundleInfo.load; bundle.priority = GetPriority(buildInfo, bundleInfo, bundleSlice); if (bundleSlice.lastBuildSize != fileEntry.size) { bundleSlice.lastBuildSize = fileEntry.size; data.MarkAsDirty(); } for (int assetIndex = 0, assetCount = bundleSlice.GetAssetCount(); assetIndex < assetCount; assetIndex++) { var assetPath = bundleSlice.GetAssetPath(assetIndex); bundle.assets.Add(assetPath); } bundle.dependencies = assetBundleManifest.GetAllDependencies(assetBundle); buildInfo.CreateEntry(bundle); manifest.bundles.Add(bundle); if (bundleSlice.streamingAssets || data.streamingAssetsAnyway) { embeddedManifest.bundles.Add(fileEntry); } } } } if (zipArchiveManifest != null) { foreach (var zipArchive in zipArchiveManifest.archives) { BundleBuilderData.BundleInfo bundleInfo; BundleBuilderData.BundleSplit bundleSplit; BundleBuilderData.BundleSlice bundleSlice; if (TryGetBundleSlice(data, zipArchive.name, out bundleInfo, out bundleSplit, out bundleSlice)) { var fileEntry = EncryptFileEntry(data, buildInfo, bundleSplit.encrypted, zipArchive.name, buildInfo.zipArchivePath); var bundle = new Manifest.BundleInfo(); bundle.comment = bundleInfo.note; bundle.tag = bundleInfo.tag; bundle.encrypted = bundleSplit.encrypted; bundle.rsize = fileEntry.rsize; bundle.type = Manifest.BundleType.ZipArchive; bundle.name = fileEntry.name; bundle.checksum = fileEntry.checksum; bundle.size = fileEntry.size; bundle.load = bundleInfo.load; bundle.priority = GetPriority(buildInfo, bundleInfo, bundleSlice); foreach (var assetPath in zipArchive.assets) { bundle.assets.Add(assetPath); } manifest.bundles.Add(bundle); if (bundleSlice.streamingAssets || data.streamingAssetsAnyway) { embeddedManifest.bundles.Add(fileEntry); } } } } if (fileListManifest != null) { foreach (var fileList in fileListManifest.fileLists) { var bundleInfo = GetBundleInfo(data, fileList.name); var fileListPath = Path.Combine(buildInfo.packagePath, fileList.name); var fileEntry = GenFileEntry(fileList.name, fileListPath); var bundle = new Manifest.BundleInfo(); bundle.comment = bundleInfo.note; bundle.tag = bundleInfo.tag; bundle.type = Manifest.BundleType.FileList; bundle.name = fileList.name; bundle.checksum = fileEntry.checksum; bundle.size = fileEntry.size; bundle.load = bundleInfo.load; bundle.priority = bundleInfo.priority; buildInfo.filelist.Add(fileList.name); foreach (var bundleTargets in bundleInfo.targets) { var targetPath = bundleTargets.targetPath; bundle.assets.Add(targetPath); } manifest.bundles.Add(bundle); if (bundleInfo.streamingAssets || data.streamingAssetsAnyway) { embeddedManifest.bundles.Add(fileEntry); } } } WriteManifest(buildInfo, manifest); WriteEmbeddedManifest(buildInfo, embeddedManifest); if (buildInfo.buildTarget == EditorUserBuildSettings.activeBuildTarget) { BuildStreamingAssets(buildInfo, fileListManifest); } return(embeddedManifest); }