示例#1
0
    /// <summary>
    /// Gens the patch files.
    /// </summary>
    /// <returns>The patch files.</returns>
    /// <param name="patchPatch">Patch patch.</param>
    /// <param name="versionItemSize">Version item size.</param>
    /// <param name="abPatchDic">Ab patch dic.</param>
    private static Dictionary <string, string> GenPatchFiles(string patchPath, string abPath,
                                                             Dictionary <string, List <object> > versionItemInfo, ref Dictionary <string, string> abPatchDic)
    {
        Dictionary <string, string> patchVersionDic = new Dictionary <string, string>();

        List <string> filterAB = new List <string>();

        foreach (KeyValuePair <string, List <string> > item in AssetBundleNameTools.patchAbDict)
        {
            filterAB.Clear();

            string md5Str = string.Empty;

            foreach (string reg in item.Value)
            {
                List <string> bundles = versionItemInfo.Keys.Where(bundle => (Regex.IsMatch(bundle, reg))).ToList <string>();

                if (bundles.Count == 0)
                {
                    NIDebug.LogError("生成patch时 {0} 筛选出来的文件个数为0,请检查!", reg);
                    continue;
                }

                // 对文件按文件名称进行排序
                bundles.Sort(delegate(string b1, string b2)
                {
                    return(b1.CompareTo(b2));
                });

                foreach (string bundle in bundles)
                {
                    filterAB.Add(string.Format("{0}{1}", abPath, bundle));

                    md5Str += versionItemInfo[bundle][0];

                    if (abPatchDic.ContainsKey(bundle))
                    {
                        NIDebug.LogError(string.Format("{0}重复放在了{1}和{2}中,请检查!", bundle, abPatchDic[bundle], item.Key));
                        continue;
                    }

                    abPatchDic.Add(bundle, item.Key);
                }
            }

            string md5 = NIEditorUtility.GetStrMD5(md5Str);

            NIEditorUtility.Zip(filterAB.ToArray(), string.Format("{0}{1}_{2}.zip", patchPath, item.Key, md5));

            patchVersionDic.Add(item.Key, md5);
        }

        return(patchVersionDic);
    }
示例#2
0
    /// <summary>
    /// 发布资源
    /// </summary>
    private static void DoBuildPublish(BuildTarget target, string resVersion, bool isNewAssets, string channel)
    {
        string rootPath    = GetABRootPath(target, channel);
        string publishPath = string.Format("{0}/PublishAssetBundles/", rootPath);
        string abPath      = string.Format("{0}/AssetBundles/", rootPath);
        string patchPath   = string.Format("{0}/PatchAssetBundles/", rootPath);
        string encryptPath = string.Format("{0}/EncryptAssetBundles/", rootPath);

        // 如果需要重新打包资源则删除原来的版本文件
        if (isNewAssets)
        {
            FileMgr.DeleteDirectory(abPath);
        }

        // ab路径是否存在,不存在则创建一个
        DirectoryInfo abInfo = new DirectoryInfo(abPath);

        if (!abInfo.Exists)
        {
            abInfo.Create();
        }

        // 确保目录存在
        FileMgr.DeleteDirectory(encryptPath);
        FileMgr.CreateDirectory(encryptPath);
        FileMgr.DeleteDirectory(publishPath);
        FileMgr.CreateDirectory(publishPath);
        FileMgr.DeleteDirectory(patchPath);
        FileMgr.CreateDirectory(patchPath);

        BuildAssetBundleOptions opt =
            BuildAssetBundleOptions.DeterministicAssetBundle |      // 保证同样的资源多次打包出的assetbundle相同
            BuildAssetBundleOptions.UncompressedAssetBundle;        // 不压缩资源,我们会压缩,然后在目标平台解压缩,最后使用的是没有压缩的资源,保证资源快速加载

        // AssetBundle打包,Unity5.x之后都是用这个方法打包,而且还会自动生成依赖关系
        AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(abPath, opt, target);

        // 载入旧版本树
        CsvFile oldVersionCsv = LoadVersion(abPath);

        // 生成资源映射表
        GenResourceDictFile(abPath, manifest);

        //// 加密ab资源包
        DoEncryptAssetBundle(encryptPath, abPath, manifest);

        // 收集需要发布的ab资源包
        Dictionary <string, string> newABVersion = DoCollectNewABVersion(encryptPath, manifest);

        // 资源大小映射表
        Dictionary <string, List <object> > versionItemInfo = new Dictionary <string, List <object> >();

        // 是否需要更新标识
        bool isABChanged = false;

        byte[] unzipBuf;
        byte[] buf;

        // 发布资源
        foreach (string abName in newABVersion.Keys)
        {
            // 获取旧版本信息
            CsvRow data = oldVersionCsv.FindByKey(abName);

            if ((data != null) && string.Equals(data.Query <string>("md5"), newABVersion[abName]))
            {
                // 添加到列表中
                versionItemInfo.Add(abName, new List <object>()
                {
                    newABVersion[abName], data.Query <int>("unzip_size"), data.Query <int>("zip_size")
                });
                continue;
            }

            // 标识数据已经变化了
            isABChanged = true;

            // 取得未压缩大小
            unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, abName));
            if (unzipBuf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, abName));
                continue;
            }

            NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, abName) }, string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName]));

            // 读取文件
            buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName]));
            if (buf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, abName));
                continue;
            }

            // 添加到列表中
            versionItemInfo.Add(abName, new List <object>()
            {
                newABVersion[abName], unzipBuf.Length, buf.Length
            });
        }

        // 如果ab资源没有变化, 不处理
        if (isABChanged)
        {
            string resourceDictPath = string.Format("{0}{1}", encryptPath, "resource_dict.bytes");

            // 发布资源到发布资源目录
            string md5 = NIEditorUtility.GetFileMD5(resourceDictPath);

            // 取得未压缩大小
            unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, "resource_dict.bytes"));
            if (unzipBuf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, "resource_dict.bytes"));
                return;
            }

            NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, "resource_dict.bytes") }, string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5));

            // 读取文件
            buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5));
            if (buf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, "resource_dict.bytes"));
                return;
            }

            // 添加到列表中
            versionItemInfo.Add("resource_dict.bytes", new List <object>()
            {
                md5, unzipBuf.Length, buf.Length
            });
        }

        bool isPatchChanged = false;

        Dictionary <string, string> abPatchDic = new Dictionary <string, string>();

        // 生成压缩patch文件
        Dictionary <string, string> newPatchVersion = GenPatchFiles(patchPath, encryptPath, versionItemInfo, ref abPatchDic);

        // 发布资源
        foreach (string patchName in newPatchVersion.Keys)
        {
            // 获取旧版本信息
            CsvRow data = oldVersionCsv.FindByKey(patchName);

            if ((data != null) && string.Equals(data.Query <string>("md5"), newPatchVersion[patchName]))
            {
                versionItemInfo.Add(patchName, new List <object>()
                {
                    data.Query <string>("md5"), 0, data.Query <int>("zip_size")
                });
                continue;
            }

            // 标识数据已经变化了
            isPatchChanged = true;

            string filePath = string.Format("{0}{1}_{2}.zip", patchPath, patchName, newPatchVersion[patchName]);

            // 读取文件
            buf = File.ReadAllBytes(filePath);
            if (buf.Length == 0)
            {
                NIDebug.LogError(string.Format("读取{0}失败!", filePath));
                continue;
            }

            versionItemInfo.Add(patchName, new List <object>()
            {
                newPatchVersion[patchName], 0, buf.Length
            });

            File.Copy(filePath, string.Format("{0}{1}_{2}.zip", publishPath, patchName, newPatchVersion[patchName]), true);
        }

        // 有变化重新生成版本文件
        if (isABChanged || isPatchChanged)
        {
            // 将资源版本添加到列表中
            versionItemInfo.Add("res_version", new List <object>()
            {
                resVersion, 0, 0
            });

            // 生成某个目录下的版本控制文件
            GenVersionFile(abPath, publishPath, versionItemInfo, abPatchDic);
        }

        // 标识Build AssetBundle OK
        NIDebug.Log("生成AssetBundle完成");

        // 刷新编辑器
        AssetDatabase.Refresh();
    }