Пример #1
0
        public static string GetPathMD5(string path)
        {
            string md5;

            if (s_pathMD5Dic.ContainsKey(path))
            {
                s_pathMD5Dic.TryGetValue(path, out md5);
            }
            else
            {
                md5 = MD5Util.GetMD5(path);
                s_pathMD5Dic.Add(path, md5);
            }
            return(md5);
        }
Пример #2
0
        /// <summary>
        /// 重命名文件,加入文件MD5字符串。
        /// 写入路径的长度(一字节),写入路径,以及对应的文件MD5。
        /// </summary>
        /// <param name="filePath">File path.</param>
        /// <param name="replacePath">Replace path.</param>
        /// <param name="writer">Writer.</param>
        private static void RenameFileAndWriteMD5(string filePath, string replacePath, BinaryWriter writer)
        {
            string extName     = Path.GetExtension(filePath);
            string fileName    = Path.GetFileName(filePath);
            string fileMD5     = MD5Util.GetFileMD5(filePath);
            string outFileName = fileName.Replace(extName, "") + "_" + fileMD5;
            string outFilePath = Path.GetDirectoryName(filePath) + "/" + outFileName + extName;

            File.Move(filePath, outFilePath);                                  // 重命名文件

            filePath = filePath.Replace(replacePath, "").Replace(extName, ""); // 文件路径掐头去尾

            writer.Write((byte)filePath.Length);                               // 写入路径的长度(一字节)
            writer.Write(filePath.ToCharArray());                              // 写入路径
            writer.Write(fileMD5.ToCharArray());                               // 写入文件MD5
        }
Пример #3
0
        private static void CreateResInfo(UpdateResInfoType updateType = UpdateResInfoType.ALL)
        {
            byte[] luaBytes = null, sceneBytes = null, resBytes = null;
            if (updateType != UpdateResInfoType.ALL)
            {
                if (!File.Exists(resInfoFilePath))                   // ResInfo 文件不存在
                {
                    updateType = UpdateResInfoType.ALL;
                }
                else
                {
                    // 只用更新某部分资源信息,将资源信息分类读取出来
                    using (BinaryReader reader = new BinaryReader(File.Open(resInfoFilePath, FileMode.Open))) {
                        ushort ushort1, ushort2, i;
                        byte   byte1, byte2;
                        int    sceneBytesPos, resBytesPos;

                        // - lua bytes
                        ushort1 = reader.ReadUInt16();
                        for (i = 0; i < ushort1; i++)
                        {
                            byte2 = reader.ReadByte();
                            reader.BaseStream.Position += byte2 + 16;
                        }
                        sceneBytesPos = (int)reader.BaseStream.Position;
                        reader.BaseStream.Position = 0;
                        luaBytes = reader.ReadBytes(sceneBytesPos);

                        // - scene bytes
                        byte1 = reader.ReadByte();
                        for (i = 0; i < byte1; i++)
                        {
                            byte2 = reader.ReadByte();
                            reader.BaseStream.Position += byte2 + 16;
                        }
                        resBytesPos = (int)reader.BaseStream.Position;
                        reader.BaseStream.Position = sceneBytesPos;
                        sceneBytes = reader.ReadBytes(resBytesPos - sceneBytesPos);

                        // - res bytes
                        ushort1 = reader.ReadUInt16();
                        for (i = 0; i < ushort1; i++)
                        {
                            byte2 = reader.ReadByte();
                            reader.BaseStream.Position += byte2 + 16;

                            // 包含的资源文件
                            ushort2 = reader.ReadUInt16();
                            reader.BaseStream.Position += ushort2 * 16;

                            // 依赖的 AssetBundle
                            byte2 = reader.ReadByte();
                            reader.BaseStream.Position += byte2 * 16;
                        }
                        reader.BaseStream.Position = resBytesPos;
                        resBytes = reader.ReadBytes((int)reader.BaseStream.Length - resBytesPos);
                    }
                }
            }

            // 写入资源信息
            using (BinaryWriter writer = new BinaryWriter(File.Open(resInfoFilePath, FileMode.Create))) {
                // - lua
                if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.LUA)
                {
                    writer.Write((ushort)_luaList.Count);                     // 写入lua文件数量
                    foreach (string lua in _luaList)
                    {
                        RenameFileAndWriteMD5(lua, luaOutputPath, writer);
                    }
                }
                else
                {
                    writer.Write(luaBytes);
                }


                // - scene
                if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.SCENE)
                {
                    writer.Write((byte)_sceneList.Count);                     // 写入场景文件数量(一字节)
                    foreach (string scene in _sceneList)
                    {
                        RenameFileAndWriteMD5(scene, sceneOutputPath, writer);
                    }
                }
                else
                {
                    writer.Write(sceneBytes);
                }

                // - res
                if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.RES)
                {
                    // 加载 Assets/StreamingAssets/Res/Res 文件,读取包含所有ab包引用关系的 manifest
                    AssetBundle         ab       = AssetBundle.LoadFromFile(resOutputPath + "Res");
                    AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");
                    string[]            abList   = manifest.GetAllAssetBundles();
                    writer.Write((ushort)abList.Length);                     // 写入ab文件数量

                    AssetBundleInfo abi;
                    foreach (string abPath in abList)
                    {
                        RenameFileAndWriteMD5(resOutputPath + abPath, resOutputPath, writer);
                        _abiDic.TryGetValue(abPath, out abi);

                        writer.Write((ushort)abi.assetList.Count);                         // 写入包含的资源文件数量
                        foreach (string assetPath in abi.assetList)
                        {
                            writer.Write(MD5Util.GetMD5(assetPath.Replace(resInputPath, "")).ToCharArray());                                // 写入资源文件的路径MD5
                        }

                        string[] depList = manifest.GetAllDependencies(abPath);
                        writer.Write((byte)depList.Length);                         // 写入依赖的ab文件数量(一字节)
                        foreach (string depPath in depList)
                        {
                            writer.Write(MD5Util.GetMD5(depPath).ToCharArray());                               // 写入ab文件的路径MD5
                        }
                    }
                    ab.Unload(true);
                }
                else
                {
                    writer.Write(resBytes);
                }
            }

            if (updateType == UpdateResInfoType.ALL)
            {
                UnityEngine.Debug.Log("[Packager] Generates ResInfo Completed.");
            }
            else
            {
                UnityEngine.Debug.Log("[Packager] Update ResInfo Completed!");
            }
        }