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));
}
}
}