/// <summary> /// 把文件的名称与对应的MD5编码,写入校验文件 /// </summary> /// <param name="verifyFileOutPath">写入校验文件的路径</param> /// <param name="abOutPath">AssetBundle 的输出路径</param> /// <param name="fileLists">存储所有合法文件的相对路径信息集合</param> private static void WriteVerifyFile(string verifyFileOutPath, string abOutPath, List <string> fileLists) { using (FileStream fs = new FileStream(verifyFileOutPath, FileMode.CreateNew)) { using (StreamWriter sw = new StreamWriter(fs)) { for (int i = 0; i < fileLists.Count; i++) { //获取文件的名称 string strFile = fileLists[i]; //测试 //Debug.Log(strFile); //生成此文件的对应MD5编码数值 //string strFileMD5 = "MD5 编码xxxxxxyyyyyzzzzz 临时测试使用"; //??? 本表达式没有写完,需要定义一个生成MD5 的方法。 string strFileMD5 = Helps.GetMD5Vlues(strFile); //把文件中的全路径信息去除,保留相对路径。 string strTrueFileName = strFile.Replace(abOutPath + "/", string.Empty); //做参数检查,写入文件前。 //。。。。 //写入文件 sw.WriteLine(strTrueFileName + "|" + strFileMD5); }//for_end } } //提示用户生成操作完毕 Debug.Log("CreateVerifyFiles.cs/WriteVerifyFile()/创建校验文件成功!"); //刷新Unity 编辑器 AssetDatabase.Refresh(); } //WriteVerifyFile_end
/// <summary> /// 检测资源进行对比更新 /// </summary> /// <param name="serverUrl">服务器下载URL</param> /// <returns></returns> IEnumerator DownloadResourceAndCheckUpdate(string serverUrl) { /* 步骤1: 下载“校验文件”到客户端 */ //参数检查 if (string.IsNullOrEmpty(serverUrl)) { Debug.LogError(GetType() + "/DownloadResourceAndCheckUpdate()/协程的方法参数不能为null, 请检查重试! "); yield break; //相当于C#方法 return null; } //服务端校验文件 //string fileURL = serverUrl +ABDefine.ProjectVerifyFile;//Original string fileURL = serverUrl + HotUpdateProcess.HotUpdatePathTool.PROJECT_VERIFY_FILE; //WWW请求,下载服务端的校验文件 WWW www = new WWW(fileURL); //等待www 加载完成,再往下运行。 yield return(www); //网络错误检查 if ((www.error != null) && (!string.IsNullOrEmpty(www.error))) { Debug.LogError("fileURL" + fileURL); Debug.LogError("### ERROR ! 发生网络错误,请检查服务器是否开启、URL是否正确、网络是否正常链接。 详细错误: www.error: " + www.error); yield break; } //判断客户端本地是否有此目录(下载目录) if (!Directory.Exists(_DownloadPath)) { Directory.CreateDirectory(_DownloadPath); } //开始下载校验文件,且写入本地 //File.WriteAllBytes(_DownloadPath + ABDefine.ProjectVerifyFile,www.bytes); File.WriteAllBytes(_DownloadPath + HotUpdateProcess.HotUpdatePathTool.PROJECT_VERIFY_FILE, www.bytes); /* 步骤2: 根据“校验文件”,客户端逐条读取资源文件,然后与本客户端相同的资源文件,进行MD5编码对比。 */ //读取资源文件里面的内容 string strServerFileText = www.text; string[] lines = strServerFileText.Split('\n');//按照换行进行截取 //遍历每一行 for (int i = 0; i < lines.Length; i++) { //如果校验文件出现“空行”,则不予处理 if (string.IsNullOrEmpty(lines[i])) { continue; } //得到校验文件每行的“文件名”与“MD5”编码 string[] fileAndMD5 = lines[i].Split('|'); string strServerFileName = fileAndMD5[0].Trim(); //(服务端)文件名称 string strServerMD5 = fileAndMD5[1].Trim(); //(服务端) 文件所对应的MD5编码 //得到本地这个文件 string strLocalFile = _DownloadPath + "/" + strServerFileName; /* 步骤3: 如果客户端没有服务器(增加的)文件,直接下载服务器端文件即可。 */ if (!File.Exists(strLocalFile)) { Debug.Log(GetType() + "/DownloadResourceAndCheckUpdate()/strLocalFile: " + strLocalFile + " 不存在,需要从服务器下载。"); //对于文件本地不存在的文件夹,需要进行创建 string dir = Path.GetDirectoryName(strLocalFile); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } //通过WWW,开始正式下载服务端的文件,且写入本地指定路径 yield return(StartCoroutine(DownLoadFileByWWW(serverUrl + "/" + strServerFileName, strLocalFile))); } /* 步骤4: 客户端存在与服务端相同的文件名,但是MD5编码对比不一致,说明服务器端对应的资源文件发生的更新,则客户端 * 下载最新的资源文件。 */ else { //根据客户端本地文件名称,得到本地的MD5编码 string strLocalMD5 = Helps.GetMD5Vlues(strLocalFile); //服务器端MD5编码,与本地生成的MD5编码,做比较 if (!strLocalMD5.Equals(strServerMD5)) { //如果比较不一致,删除本地对应文件。 File.Delete(strLocalFile); //从服务器下载新的对应文件 yield return(StartCoroutine(DownLoadFileByWWW(serverUrl + "/" + strServerFileName, strLocalFile))); //提示 Debug.Log(GetType() + "/DownloadResourceAndCheckUpdate()/MD5 服务端与客户端比较不一致,从服务器更新这个资源文件。 (服务器)资源文件名称:" + strServerFileName); } } }//for_end yield return(new WaitForEndOfFrame()); //提示完成 Debug.Log(GetType() + "/DownloadResourceAndCheckUpdate()/更新完成! 可以开始游戏主逻辑!"); //向下广播,通知游戏启动主逻辑开始 BroadcastMessage(HotUpdateProcess.HotUpdatePathTool.RECEIVE_INFO_START_RUNING, SendMessageOptions.DontRequireReceiver); }//DownloadResourceAndCheckUpdate_end