Exemple #1
0
        private IEnumerator UpdateFiles()
        {
#if !UNITY_ANDROID
            string updateWwwPath = "file://" + Application.persistentDataPath;
            string localWwwPath  = "file://" + Application.streamingAssetsPath;
#else
            string updateWwwPath = Application.persistentDataPath;
            string localWwwPath  = Application.streamingAssetsPath;
#endif

            string serverMD5;

            // 获取http服务器上的版本MD5
            using (WWW www = new WWW(GenRandomURL("versionMD5")))
            {
                yield return(www);

                if (www == null || !string.IsNullOrEmpty(www.error))
                {
                    LogManager.Error("VersionManager::UpdateFiles => can't get versionMD5 form server");
                    yield break;
                }
                serverMD5 = www.text;
            }

            // 检验客户端安装包自带的版本MD5是否最新
            // 是则删除本地更新文件,并结束更新
            // 否则继续往下执行
            VersionInfo versionInfo = null;
            using (WWW www = new WWW(Path.Combine(localWwwPath, "version")))
            {
                yield return(www);

                if (www == null || !string.IsNullOrEmpty(www.error))
                {
                    LogManager.Error("VersionManager::UpdateFiles => can't get version file form client");
                    yield break;
                }

                if (CheckBytesMD5(www.bytes, serverMD5))
                {
                    _updated = true;
                    yield return(StartCoroutine(ClearUpdatedFiles(updateWwwPath)));

                    yield break;
                }

                versionInfo = JsonUtility.FromJson <VersionInfo>(www.text);
            }

            // 检验更新目录下的版本MD5是否最新
            // 是则结束更新
            // 否则继续往下执行
            VersionInfo oldInfo = null;
            if (File.Exists(Path.Combine(Application.persistentDataPath, "version")))
            {
                using (WWW www = new WWW(Path.Combine(updateWwwPath, "version")))
                {
                    yield return(www);

                    if (www == null || !string.IsNullOrEmpty(www.error))
                    {
                        LogManager.Error("VersionManager::UpdateFiles => can't get version file form update path");
                        yield break;
                    }

                    if (CheckBytesMD5(www.bytes, serverMD5))
                    {
                        _updated = true;
                        yield break;
                    }

                    oldInfo = JsonUtility.FromJson <VersionInfo>(www.text);
                }
            }

            // 从服务器获取最新的版本文件
            VersionInfo newInfo      = null;
            byte[]      newInfoBytes = null;
            using (WWW www = new WWW(GenRandomURL("version")))
            {
                yield return(www);

                if (www == null || !string.IsNullOrEmpty(www.error) || !CheckBytesMD5(www.bytes, serverMD5))
                {
                    LogManager.Error("VersionManager::UpdateFiles => can't get version file form server");
                    yield break;
                }

                newInfoBytes = www.bytes;
                newInfo      = JsonUtility.FromJson <VersionInfo>(www.text);
                if (newInfo == null)
                {
                    LogManager.Error("VersionManager::UpdateFiles => can't parse version file from server");
                    yield break;
                }
            }

            // 若本地存在更新内容,则删除其中非最新的内容
            if (oldInfo != null)
            {
                for (int i = oldInfo._folders.Count - 1; i >= 0; --i)
                {
                    FolderInfo oldFolderInfo = oldInfo._folders[i];
                    string     folder        = oldFolderInfo._name;
                    string     folderPath    = Path.Combine(Application.persistentDataPath, folder);

                    FolderInfo newFolderInfo = newInfo._folders.Find(obj => obj._name == folder);
                    if (newFolderInfo == null)
                    {
                        if (Directory.Exists(folder))
                        {
                            Directory.Delete(folder);
                        }
                        continue;
                    }

                    for (int j = oldFolderInfo._files.Count; j >= 0; --j)
                    {
                        FileInfo oldFileInfo = oldFolderInfo._files[j];
                        FileInfo newFileInfo = newFolderInfo._files.Find(obj => obj._name == oldFileInfo._name);
                        if (newFileInfo == null || newFileInfo._md5 != oldFileInfo._md5)
                        {
                            string filePath = Path.Combine(folderPath, oldFileInfo._name);
                            if (File.Exists(filePath))
                            {
                                File.Delete(filePath);
                            }
                        }
                    }
                }
            }

            // 计算安装包版与最新版之间的差异
            for (int i = 0; i < newInfo._folders.Count; ++i)
            {
                FolderInfo newFolder = newInfo._folders[i];
                FolderInfo oldFolder = versionInfo._folders.Find(obj => obj._name == newFolder._name);
                if (oldFolder == null)
                {
                    _diffFolders.Add(newFolder);
                    continue;
                }

                FolderInfo diffFolder = new FolderInfo();
                for (int j = 0; j < newFolder._files.Count; ++j)
                {
                    FileInfo newFile = newFolder._files[j];
                    FileInfo oldFile = oldFolder._files.Find(obj => obj._name == newFile._name);
                    if (oldFile == null || oldFile._md5 != newFile._md5)
                    {
                        diffFolder._files.Add(newFile);
                    }
                }

                if (diffFolder._files.Count > 0)
                {
                    diffFolder._name = newFolder._name;
                    _diffFolders.Add(diffFolder);
                }
            }

            // 下载差异内容
            for (int i = 0; i < _diffFolders.Count; ++i)
            {
                FolderInfo folderInfo = _diffFolders[i];
                string     folderPath = Path.Combine(Application.persistentDataPath, folderInfo._name);
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                for (int j = 0; j < folderInfo._files.Count; ++j)
                {
                    FileInfo fileInfo = folderInfo._files[j];
                    string   filePath = Path.Combine(folderPath, fileInfo._name);
                    if (File.Exists(filePath))
                    {
                        continue;
                    }

                    using (WWW www = new WWW(GenRandomURL("")))
                    {
                        yield return(www);

                        if (www == null || !string.IsNullOrEmpty(www.error) || !CheckBytesMD5(www.bytes, fileInfo._md5))
                        {
                            LogManager.Error(string.Format("VersionManager::UpdateFiles => can't download [{0}/{1}] from server", folderInfo._name, fileInfo._name));
                            yield break;
                        }

                        File.WriteAllBytes(filePath, www.bytes);
                    }
                }
            }

            // 覆盖版本文件
            File.WriteAllBytes(Path.Combine(Application.persistentDataPath, "version"), newInfoBytes);
        }
        public static void Pack(string folderName)
        {
            // 创建保存目录
            string savePath = Path.Combine(Path.Combine(Application.dataPath, ".."), folderName);

            if (Directory.Exists(savePath))
            {
                Directory.Delete(savePath, true);
            }

            Directory.CreateDirectory(savePath);

            // 收集文件MD5信息并复制文件到保存目录
            VersionInfo versionInfo = new VersionInfo();

            for (int i = 0; i < _updateFolders.Length; ++i)
            {
                FolderInfo folderInfo = new FolderInfo();
                folderInfo._name = _updateFolders[i];

                // 建立保存目录
                string saveFolderPath = Path.Combine(savePath, folderInfo._name);
                if (Directory.Exists(saveFolderPath))
                {
                    Directory.Delete(saveFolderPath, true);
                }
                Directory.CreateDirectory(saveFolderPath);

                string   folderPath = Path.Combine(Application.streamingAssetsPath, folderInfo._name);
                string[] filePaths  = Directory.GetFiles(folderPath);
                for (int j = 0; j < filePaths.Length; ++j)
                {
                    string filePath = filePaths[j];
                    if (filePath.EndsWith(".meta") || filePath.EndsWith(".manifest"))
                    {
                        continue;
                    }

                    FileInfo fileInfo = new FileInfo();
                    fileInfo._name = Path.GetFileName(filePath);

                    // 计算MD5
                    fileInfo._md5 = GenMD5(File.ReadAllBytes(filePath));

                    folderInfo._files.Add(fileInfo);

                    // 复制文件到保存目录
                    File.Copy(filePath, Path.Combine(saveFolderPath, fileInfo._name));
                }

                if (folderInfo._files.Count > 0)
                {
                    versionInfo._folders.Add(folderInfo);
                }
                else
                {
                    Directory.Delete(saveFolderPath, true);
                }
            }

            // 生成 version 和 versionMD5 文件
            File.WriteAllText(Path.Combine(savePath, "version"), JsonUtility.ToJson(versionInfo));
            string versionMD5 = GenMD5(File.ReadAllBytes(Path.Combine(savePath, "version")));

            File.WriteAllText(Path.Combine(savePath, "versionMD5"), versionMD5);
            Debug.Log(folderName + " pack successfully!");
        }