/// <summary> /// Release 资源剪裁 /// </summary> /// <param name="buildTarget"></param> /// <param name="bundleMapPath"></param> /// <returns></returns> private static bool StrippingResourcesForRelease(BuildTarget buildTarget, string bundleMapPath) { BundleIndicesMap fullBundleIndexMap = new BundleIndicesMap($"{PathConfig.CODE_STREAMINGASSET_PATH}/bundlemap.bytes"); List <BundleIndexItemInfo> allBundleInfoList = fullBundleIndexMap.GetAllBundleIndexItemList(); fullBundleIndexMap.Dispose(); Dictionary <string, BundleIndexItemInfo> allBundleDict = allBundleInfoList.ToDictionary(bundleIndexItem => bundleIndexItem.BundleName); List <string> allBundleKeyList = allBundleDict.Keys.ToList(); Dictionary <string, object> existStripSet = ReleaseStripping.GetStrippingAssets(); HashSet <string> appendSet = new HashSet <string>(); string strippintReportPath = GetStrippingReportPath(buildTarget); for (int i = 0; i < allBundleKeyList.Count; ++i) { string bundleName = allBundleKeyList[i]; if (existStripSet.ContainsKey(bundleName)) { existStripSet.Remove(bundleName); } else { appendSet.Add(bundleName); } } if (appendSet.Count == 0 && existStripSet.Count == 0) { Dictionary <string, object> strippingDict = ReleaseStripping.GetStrippingAssets(); string buildOutputPath = GetBuildBundleMapPath(buildTarget); BundleIndicesMap bundlemapDb = new BundleIndicesMap($"{buildOutputPath}/bundlemap.bytes"); Dictionary <string, BundleIndexItemInfo> allBundleMapDict = bundlemapDb.GetAllBundleIndexItemList().ToDictionary(item => item.BundleName); bundlemapDb.BundleIndicesMapConn.BeginTransaction(); foreach (var pair in strippingDict) { ReleaseStrippingForTheChief.AssetManifestConfig assetManifestConfig = (ReleaseStrippingForTheChief.AssetManifestConfig)pair.Value; if ((ReleaseStrippingForTheChief.AssetLevel)assetManifestConfig.AssetLevel != ReleaseStrippingForTheChief.AssetLevel.BUILDIN) { string strippingBundlePath = Path.Combine(buildOutputPath, allBundleMapDict[pair.Key].BundleHashName); File.Delete(strippingBundlePath); bundlemapDb.RemoveBundleIndices(pair.Key); } } bundlemapDb.Dispose(); File.Delete(strippintReportPath); return(true); } else { List <string> obsoluteBundleList = existStripSet.Keys.ToList(); List <string> appendBundleList = appendSet.ToList(); StrippingReport report = new StrippingReport(); report.ObsoluteAssets.AddRange(obsoluteBundleList); report.NotIncludeAssets.AddRange(appendBundleList); using (FileStream fs = new FileStream(strippintReportPath, FileMode.Create)) { byte[] writeBuffer = Encoding.Default.GetBytes(JsonMapper.ToJson(report)); fs.Write(writeBuffer, 0, writeBuffer.Length); } return(false); } }
/// <summary> /// 构建基于SQLite的bundlemap /// </summary> /// <param name="buildTarget"></param> /// <param name="builtAssetBundleManifest"></param> /// <param name="bundleIndexMapPath"></param> /// <param name="fileNameCaseSensitive"></param> public static bool DoSqliteBundleIndexMap(string bundleIndexMapPath, BuildTarget buildTarget, AssetBundleManifest builtAssetBundleManifest = null, bool fileNameCaseSensitive = true) { try { FileUtil.ClearOrCreateEmptyFolder(bundleIndexMapPath); string assetsBuildPath = GOEPackUIHelperV5.GetBundleOutputPath(buildTarget); if (!builtAssetBundleManifest) { string buildManifestBundlePath = Path.Combine(assetsBuildPath, PathConfig.BUILD_MANIFEST_BUNDLE); //manifest实际上在AssetBundle里,.manifest是给外面看的(只有build出来的manifest有信息,别的都没有) AssetBundle buildManifestBundle = AssetBundle.LoadFromFile(buildManifestBundlePath); builtAssetBundleManifest = buildManifestBundle.LoadAsset <AssetBundleManifest>("assetbundlemanifest"); buildManifestBundle.Unload(false); } string currentBuildBundleMapDbPath = Path.Combine(assetsBuildPath, PathConfig.SQLITE_BUNDLE_MAP_NAME); BundleIndicesMap bundleIndexMap = new BundleIndicesMap(currentBuildBundleMapDbPath); bundleIndexMap.ClearBundleIndicesData(); string[] allAssetBundleNames = builtAssetBundleManifest.GetAllAssetBundles(); for (int i = 0; i < allAssetBundleNames.Length; ++i) { string originBundlePath = Path.Combine(assetsBuildPath, allAssetBundleNames[i]); AssetBundle buildBundle = AssetBundle.LoadFromFile(originBundlePath); if (buildBundle == null) { throw new Exception($"no bundle:{Path.Combine(assetsBuildPath, allAssetBundleNames[i])}"); } string bundleHash = builtAssetBundleManifest.GetAssetBundleHash(allAssetBundleNames[i]).ToString(); string[] bundleIncludeAssets = buildBundle.GetAllAssetNames(); string[] bundleIncludeScenes = buildBundle.GetAllScenePaths(); buildBundle.Unload(true); int bundleFileSize = (int)FileUtil.GetFileLength(Path.Combine(assetsBuildPath, allAssetBundleNames[i])); string[] bundleAssets = new string[bundleIncludeAssets.Length + bundleIncludeScenes.Length]; int assetIndex = 0; for (int j = 0; j < bundleIncludeAssets.Length; ++j) { bundleAssets[assetIndex++] = fileNameCaseSensitive ? Path.GetFileName(FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(bundleIncludeAssets[j])) : Path.GetFileName(bundleIncludeAssets[j]); } for (int j = 0; j < bundleIncludeScenes.Length; ++j) { bundleAssets[assetIndex++] = fileNameCaseSensitive ? Path.GetFileName(FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(bundleIncludeScenes[j])) : Path.GetFileName(bundleIncludeScenes[j]); } string[] bundleDependencies = builtAssetBundleManifest.GetAllDependencies(allAssetBundleNames[i]); for (int j = 0; j < bundleDependencies.Length; ++j) { string dependencyFullPath = Path.Combine(assetsBuildPath, bundleDependencies[j]); dependencyFullPath = fileNameCaseSensitive ? FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(dependencyFullPath) : dependencyFullPath; bundleDependencies[j] = Path.GetFileName(dependencyFullPath); } bundleIndexMap.AddBundleIndicesByTransaction(allAssetBundleNames[i], bundleHash, bundleDependencies, bundleAssets, bundleFileSize); //AssetBundle HashName string bundleHashName = Path.Combine(bundleIndexMapPath, $"{bundleHash}{PathConfig.BUNDLE_POSTFIX}"); File.Copy(originBundlePath, bundleHashName); } AssetBundle.UnloadAllAssetBundles(true); bundleIndexMap.ForceCommit(); string bundleMapDbDstPath = Path.Combine(bundleIndexMapPath, PathConfig.SQLITE_BUNDLE_MAP_NAME); File.Copy(currentBuildBundleMapDbPath, bundleMapDbDstPath); using (FileStream fs = new FileStream(bundleMapDbDstPath, FileMode.Open)) { System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create(); byte[] bundleMapHash = sha.ComputeHash(fs); string bundlemapHashFilePath = Path.Combine(bundleIndexMapPath, PathConfig.SQLITE_BUNDLE_MAP_HASH); using (FileStream fs2 = new FileStream(bundlemapHashFilePath, FileMode.CreateNew)) fs2.Write(bundleMapHash, 0, bundleMapHash.Length); bundleIndexMap.SetBundleMapInfo(BundleIndicesMap.BundleMapKey.BUNDLEMAP_IDENTIFY, Encoding.UTF8.GetString(bundleMapHash)); bundleIndexMap.Dispose(); } //Copy To StreamingAssets if (Directory.Exists(PathConfig.CODE_STREAMINGASSET_PATH)) { File.Copy(currentBuildBundleMapDbPath, Path.Combine(PathConfig.CODE_STREAMINGASSET_PATH, PathConfig.SQLITE_BUNDLE_MAP_NAME), true); } //只有Windows的Bundle需要拷贝 //if (buildTarget == BuildTarget.StandaloneWindows64 || buildTarget == BuildTarget.StandaloneWindows || buildTarget == BuildTarget.StandaloneOSX) // CopyGOEBundleToPath(bundleIndexMapPath); //else //{ //Copy RawAssets string rawAssetDirPath = Path.Combine(assetsBuildPath, PathConfig.RAW_ASSET_PATH); DirectoryInfo rawAssetDir = new DirectoryInfo(rawAssetDirPath); if (rawAssetDir.Exists) { FileInfo[] rawAssetFileInfoList = rawAssetDir.GetFiles(); foreach (FileInfo rawAssetFile in rawAssetFileInfoList) { string dstPath = Path.Combine(bundleIndexMapPath, rawAssetFile.Name); rawAssetFile.CopyTo(dstPath); } } //} return(true); } catch (Exception ex) { throw ex; } }