仿LOL项目开发第三天
仿LOL项目开发第二天
by草帽
昨个我们已经实现了下载功能,但是发现没有,下载的包是压缩的,没有解压开,那么Unity是识别不了的。
所以今个我们来讲讲如何实现解压文件。
还记得吗,我们在DownloadTask里面添加了一个完成下载后的一个解压委托,我们还没有实现,那么,我们就去解决他。
回到VersionManager的DownloadPackageList方法里面,在OnDownloadFinished委托里面,添加解压缩的代码。
之前讲过类的单一职责,所以不可能在VersionManager里面完成解压缩功能吧。
所以呢,我们新建一个文件管理类:FileAccessManager.cs:
using UnityEngine; using System.Collections; using System.IO; using System.Linq; using System.Text.RegularExpressions; using ICSharpCode.SharpZipLib.Zip; /// <summary> /// 文件管理器 /// </summary> public static class FileAccessManager { /// <summary> /// 解压文件到资源文件目录 /// </summary> /// <param name="filePath"></param> public static void DecompressFile(string filePath) { DecompressToDirectory(SystemConfig.ResourceFolder, filePath); } /// <summary> /// 解压文件到指定文件路径 /// </summary> /// <param name="targetPath"></param> /// <param name="zipFilePath"></param> public static void DecompressToDirectory(string targetPath,string zipFilePath) { if (File.Exists(zipFilePath)) { Stream compressed = File.OpenRead(zipFilePath); compressed.DecompressToDirectory(targetPath); } else { Debug.LogError("解压文件不存在"); } } private static void DecompressToDirectory(this Stream source, string targetPath) { targetPath = Path.GetFullPath(targetPath); using (ZipInputStream decompressor = new ZipInputStream(source)) { ZipEntry entry; while ((entry = decompressor.GetNextEntry()) != null) { string name = entry.Name; if (entry.IsDirectory && entry.Name.StartsWith("\\")) name = entry.Name.ReplaceFirst("\\", ""); //name = ReplaceFirst(entry.Name, "\\", ""); string filePath = Path.Combine(targetPath, name); string directoryPath = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); if (entry.IsDirectory) continue; byte[] data = new byte[2048]; using (FileStream streamWriter = File.Create(filePath)) { int bytesRead; while ((bytesRead = decompressor.Read(data, 0, data.Length)) > 0) { streamWriter.Write(data, 0, bytesRead); } } } } } public static string ReplaceFirst(this string source, string oldString, string newString) { Regex regEx = new Regex(oldString, RegexOptions.Multiline); return regEx.Replace(source, newString == null ? "" : newString, 1); } }
不懂解压缩文件的童鞋可以看我另一篇博客:通用工具类解压缩文件篇
这里我就不详细介绍了,我们继续回到VersionManager的DownloadPackageList:
Action OnDownloadFinished =()=> { //进行解压,以后再来 if (File.Exists(localFile)) { //开始解压文件 FileAccessManager.DecompressFile(localFile); } if (File.Exists(localFile)) { File.Delete(localFile); } //更新本地版本信息 LocalVersion.ResourceVersionCodeInfo = new VersionCodeInfo(kvp.Key); //保存版本信息 SaveVersion(LocalVersion); };
SaveVersion():更新本地版本信息xml
/// <summary> /// 保存版本信息到xml文件中 /// </summary> /// <param name="version"></param> private void SaveVersion(VersionManagerInfo version) { var props = typeof(VersionManagerInfo).GetProperties(); XmlDocument doc = new XmlDocument(); XmlDeclaration newChild = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(newChild); XmlElement root = doc.CreateElement("root"); doc.AppendChild(root); foreach (var prop in props) { XmlElement e = doc.CreateElement(prop.Name); string value = prop.GetGetMethod().Invoke(version,null) as string; e.InnerText = value; root.AppendChild(e); } UnityTools.SaveText(SystemConfig.VersionPath, doc.InnerXml); }
Ok,我们来运行一下程序,哎,发现有错误,和之前一样的错误。
也就是说获取Application.dataPath不能在其他线程获取,我们看看那些弄了线程。
找到了,也就是在DownloadMrg的CheckDownloadList的时候new 一个下载线程:
所以解决方法还是,去DownloadTask类里面,找到OnFinished方法,修改下:
public void OnFinished() { if (Finished != null) LOLGameDriver.Invoke(Finished); //Finished(); }
然后回到DownloadFinishedWithMd5()里面,找到task.Finished()改成task.OnFinished();
再次运行程序:
可以看到原先的压缩文件已经自动解压开了(看不到的童鞋请刷新下Project的资源),因为我们已经修改了版本信息,所以再次运行看看:
可以看到不需要更新了,说明版本已经迭代了。Ok,基本上版本更新已经搞一个段落,现在只差和界面交互,所以下一节,我们专门来讲讲界面UI的框架。