MPQDirver.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. 
  2. using CommonLang;
  3. using CommonLang.Concurrent;
  4. using CommonLang.Property;
  5. using MPQ.Updater;
  6. using System.IO;
  7. using System;
  8. using CommonNetwork.Http;
  9. using CommonLang.Log;
  10. namespace MPQ
  11. {
  12. public class MPQDirver
  13. {
  14. private Logger log = LoggerFactory.GetLogger("MPQDirver");
  15. /// <summary>
  16. /// 获取存储空间可用容量
  17. /// </summary>
  18. /// <param name="path"></param>
  19. /// <returns></returns>
  20. public virtual long GetAvaliableSpace(string path)
  21. {
  22. DriveInfo drive = new DriveInfo(Directory.GetDirectoryRoot(path));
  23. return drive.AvailableFreeSpace;
  24. }
  25. /// <summary>
  26. /// 获取存储空间总容量
  27. /// </summary>
  28. /// <param name="path"></param>
  29. /// <returns></returns>
  30. public virtual long GetTotalSpace(string path)
  31. {
  32. DriveInfo drive = new DriveInfo(Directory.GetDirectoryRoot(path));
  33. return drive.TotalSize;
  34. }
  35. /// <summary>
  36. /// 自定义获取文件MD5方法.
  37. /// </summary>
  38. /// <param name="fullname"></param>
  39. /// <param name="md5"></param>
  40. /// <returns></returns>
  41. public virtual bool RunGetFileMD5(string fullname, out string md5)
  42. {
  43. using (FileStream fs = new FileStream(fullname, FileMode.Open, FileAccess.Read))
  44. {
  45. md5 = CMD5.CalculateMD5(fs);
  46. }
  47. return true;
  48. }
  49. /// <summary>
  50. /// 自定义解压缩方法
  51. /// </summary>
  52. /// <param name="updater"></param>
  53. /// <param name="zip">压缩文件</param>
  54. /// <param name="mpq">解压缩文件</param>
  55. /// <param name="process">解压进度,process+=readed</param>
  56. /// <returns></returns>
  57. public virtual bool RunUnzipSingle(MPQUpdater updater, MPQUpdater.RemoteFileInfo zip, MPQUpdater.RemoteFileInfo mpq, AtomicLong process)
  58. {
  59. var type = ReflectionUtil.GetType("CommonMPQ.SharpZipLib.Unzip");
  60. var method = type.GetMethod("SharpZipLib_RunUnzipMPQ");
  61. return (bool)method.Invoke(null, new object[] { updater, zip, mpq, process });
  62. }
  63. /// <summary>
  64. /// 自定义下载方法
  65. /// </summary>
  66. /// <param name="updater"></param>
  67. /// <param name="inf">要下载的文件</param>
  68. /// <param name="exist_size">已下载大小</param>
  69. /// <param name="need_bytes">需要的大小</param>
  70. /// <param name="process">下载进度,process+=readed</param>
  71. /// <returns></returns>
  72. public virtual bool RunDownloadSingle(MPQUpdater updater, MPQUpdater.RemoteFileInfo inf, long exist_size, long need_bytes, AtomicLong process)
  73. {
  74. byte[] io_buffer = new byte[1024 * 1024];
  75. using (FileStream fos = new FileStream(inf.file.FullName, FileMode.Append, FileAccess.Write))
  76. {
  77. Stream input;
  78. using (WebClient www = connect_url(updater, inf.key, exist_size, need_bytes, out input))
  79. {
  80. try
  81. {
  82. long total_readed = 0;
  83. while (total_readed < need_bytes)
  84. {
  85. if (updater.IsDisposing) return false;
  86. int readed = input.Read(io_buffer, 0, (int)Math.Min(io_buffer.Length, need_bytes - total_readed));
  87. total_readed += readed;
  88. process += readed;
  89. fos.Write(io_buffer, 0, readed);
  90. }
  91. fos.Flush();
  92. }
  93. finally
  94. {
  95. fos.Close();
  96. }
  97. }
  98. }
  99. return true;
  100. }
  101. protected virtual WebClient connect_url(MPQUpdater updater, string key, long exist_size, long expect_length, out Stream input)
  102. {
  103. for (int i = 0; i < updater.UrlRoots.Length; i++)
  104. {
  105. string path = updater.UrlRoots[i % updater.UrlRoots.Length] + key;
  106. path = path.Replace('\\', '/');
  107. Uri url = new Uri(path);
  108. WebClient http = new WebClient(url);
  109. http.TimeoutMS = updater.DownloadTimeoutSEC * 1000;
  110. if (exist_size > 0)
  111. {
  112. http.Request.Params["Range"] = ("bytes=" + exist_size + "-");
  113. }
  114. try
  115. {
  116. input = http.Connect();
  117. if ((http.Response.ContentLength != expect_length))
  118. {
  119. throw new Exception("下载HTTP.ContentLength尺寸不匹配 : "
  120. + http.Response.ContentLength + "\n"
  121. + url.ToString() + "\n"
  122. + http.Response.Status );
  123. }
  124. }
  125. catch (Exception err)
  126. {
  127. log.Error("下载出错 : " + url + "\n " + err.Message, err);
  128. try
  129. {
  130. http.Dispose();
  131. }
  132. catch (Exception err2)
  133. {
  134. log.Error(err2.Message, err2);
  135. }
  136. continue;
  137. }
  138. return http;
  139. }
  140. throw new Exception("Can not connect to download root : " + CUtils.ArrayToString(updater.UrlRoots));
  141. }
  142. }
  143. }