using CommonLang; using CommonLang.Concurrent; using CommonLang.Property; using MPQ.Updater; using System.IO; using System; using CommonNetwork.Http; using CommonLang.Log; namespace MPQ { public class MPQDirver { private Logger log = LoggerFactory.GetLogger("MPQDirver"); /// /// 获取存储空间可用容量 /// /// /// public virtual long GetAvaliableSpace(string path) { DriveInfo drive = new DriveInfo(Directory.GetDirectoryRoot(path)); return drive.AvailableFreeSpace; } /// /// 获取存储空间总容量 /// /// /// public virtual long GetTotalSpace(string path) { DriveInfo drive = new DriveInfo(Directory.GetDirectoryRoot(path)); return drive.TotalSize; } /// /// 自定义获取文件MD5方法. /// /// /// /// public virtual bool RunGetFileMD5(string fullname, out string md5) { using (FileStream fs = new FileStream(fullname, FileMode.Open, FileAccess.Read)) { md5 = CMD5.CalculateMD5(fs); } return true; } /// /// 自定义解压缩方法 /// /// /// 压缩文件 /// 解压缩文件 /// 解压进度,process+=readed /// public virtual bool RunUnzipSingle(MPQUpdater updater, MPQUpdater.RemoteFileInfo zip, MPQUpdater.RemoteFileInfo mpq, AtomicLong process) { var type = ReflectionUtil.GetType("CommonMPQ.SharpZipLib.Unzip"); var method = type.GetMethod("SharpZipLib_RunUnzipMPQ"); return (bool)method.Invoke(null, new object[] { updater, zip, mpq, process }); } /// /// 自定义下载方法 /// /// /// 要下载的文件 /// 已下载大小 /// 需要的大小 /// 下载进度,process+=readed /// public virtual bool RunDownloadSingle(MPQUpdater updater, MPQUpdater.RemoteFileInfo inf, long exist_size, long need_bytes, AtomicLong process) { byte[] io_buffer = new byte[1024 * 1024]; using (FileStream fos = new FileStream(inf.file.FullName, FileMode.Append, FileAccess.Write)) { Stream input; using (WebClient www = connect_url(updater, inf.key, exist_size, need_bytes, out input)) { try { long total_readed = 0; while (total_readed < need_bytes) { if (updater.IsDisposing) return false; int readed = input.Read(io_buffer, 0, (int)Math.Min(io_buffer.Length, need_bytes - total_readed)); total_readed += readed; process += readed; fos.Write(io_buffer, 0, readed); } fos.Flush(); } finally { fos.Close(); } } } return true; } protected virtual WebClient connect_url(MPQUpdater updater, string key, long exist_size, long expect_length, out Stream input) { for (int i = 0; i < updater.UrlRoots.Length; i++) { string path = updater.UrlRoots[i % updater.UrlRoots.Length] + key; path = path.Replace('\\', '/'); Uri url = new Uri(path); WebClient http = new WebClient(url); http.TimeoutMS = updater.DownloadTimeoutSEC * 1000; if (exist_size > 0) { http.Request.Params["Range"] = ("bytes=" + exist_size + "-"); } try { input = http.Connect(); if ((http.Response.ContentLength != expect_length)) { throw new Exception("下载HTTP.ContentLength尺寸不匹配 : " + http.Response.ContentLength + "\n" + url.ToString() + "\n" + http.Response.Status ); } } catch (Exception err) { log.Error("下载出错 : " + url + "\n " + err.Message, err); try { http.Dispose(); } catch (Exception err2) { log.Error(err2.Message, err2); } continue; } return http; } throw new Exception("Can not connect to download root : " + CUtils.ArrayToString(updater.UrlRoots)); } } }