/// <summary> /// Creates new torrent with specified file. /// </summary> /// <param name="path">Path to shared torrent</param> /// <returns>The newly created torrent</returns> public static Torrent CreateFromPath(string path) { Torrent t = new Torrent(); t.File = PartFile.FromPath(path); t.Name = t.FileName; t.Status = EStatus.Seeding; return(t); }
/// <summary> /// Creates new PartFile from existing file. /// </summary> /// <param name="filePath">Path of the file</param> /// <returns>Returns new PartFile</returns> public static PartFile FromPath(string filePath) { PartFile file = new PartFile(filePath); for (int i = 0; i < file.PartStatus.Length; ++i) { file.PartStatus[i] = EPartStatus.Available; } return(file); }
/// <inheritdoc /> /// <summary> /// Constructs new ProgressViewer for visualisation of specified PartFile /// </summary> /// <param name="file">The PartFile which progress to visualize</param> public ProgressViewer(PartFile file) { InitializeComponent(); DoubleBuffered = true; Paint += ProgressViewer_Paint; this.file = file; penChoice = new Dictionary <PartFile.EPartStatus, Pen> { { PartFile.EPartStatus.Available, availablePen }, { PartFile.EPartStatus.Missing, missingPen }, { PartFile.EPartStatus.Processing, processingPen } }; }
/// <summary> /// 初始化分片上传 /// </summary> /// <param name="key">上传至Bucket后的文件名.</param> /// <param name="filePath">文件路径.</param> /// <param name="bucket">Bucket.</param> /// <returns>返回对象<see cref="UCloudSDK.Models.InitiateMultipartUploadResponse"/></returns> /// <exception cref="System.ApplicationException"></exception> public InitiateMultipartUploadResponse InitiateMultipartUpload(string filePath, string key = "", string bucket = "") { if (!File.Exists(filePath)) { throw new Exception(string.Format("文件{0}不存在", filePath)); } if (bucket.IsNullOrWhiteSpace()) { bucket = Bucket; } if (key.IsNullOrWhiteSpace()) { key = Path.GetFileName(filePath); } var url = string.Format(FileUrl, bucket); Client.BaseUrl = new Uri(url); var request = new RestRequest("{key}?uploads", Method.POST); request.AddUrlSegment("key", key); request.AddHeader("Authorization", SignRequest(request, bucket, key)); var response = Client.Execute <InitiateMultipartUploadResponse>(request); Client.BaseUrl = new Uri(BaseUrl); if (response.ErrorException != null) { const string message = "响应错误,请检查."; throw new ApplicationException(message, response.ErrorException); } var entity = response.Data; PartFile = new PartFile() { BlkSize = entity.BlkSize, Bucket = entity.Bucket, Key = entity.Key, UploadId = entity.UploadId, FilePath = filePath, Etags = new SortedDictionary <int, string>(), IsLast = false, PartNumber = 0 }; return(entity); }
/// <summary> /// Creates new file with specified path with info from xml /// </summary> /// <param name="elem">XmlElement to load from</param> /// <param name="filePath">Path to new file</param> /// <returns>The nrw PartFile</returns> public static PartFile FromXmlShare(XmlElement elem, string filePath) { PartFile file = new PartFile(filePath); file.NumberOfParts = int.Parse(elem["numberofparts"].InnerText); file.PartStatus = new EPartStatus[file.NumberOfParts]; file.FileName = elem["filename"].InnerText; file.Hash = elem["hash"].InnerText; file.Size = long.Parse(elem["size"].InnerText); //file.setLength(file.Size); return(file); }
/// <summary> /// Deserializes new torrent from xml - whole torrent is loaded /// </summary> /// <param name="elem">XmlElement with the torrent</param> /// <returns>The newly created torrent.</returns> public static Torrent CreateFromXml(XmlElement elem) { Torrent t = new Torrent(elem["id"].InnerText); t.Name = elem["name"].InnerText; t.Status = (EStatus)Enum.Parse(typeof(EStatus), elem["status"].InnerText); if (t.Status != EStatus.Error) { try { t.File = PartFile.FromXml(elem[PartFile.XmlName], t.Status == EStatus.Seeding); //check hash only if the the file is already downloaded - otherwise the hash must be different } catch (WrongFileException) { t.Status = EStatus.Error; } }
/// <summary> /// 完成分片上传 /// </summary> /// <param name="newKey">新文件名.</param> /// <param name="eTags">分片ETags使用,连接后的字符串.</param> /// <param name="key">在Bucket中名称.</param> /// <param name="uploadId">本次分片上传的ID.</param> /// <param name="bucket">Bucket.</param> /// <returns>返回对象<see cref="UCloudSDK.Models.FinishMultipartUploadResponse"/></returns> /// <exception cref="System.ApplicationException"></exception> /// <exception cref="System.Exception"></exception> public FinishMultipartUploadResponse FinishMultipartUpload(string newKey, string eTags, string key, string uploadId, string bucket = "") { PartFile = new PartFile(); if (bucket.IsNullOrWhiteSpace()) { bucket = Bucket; } var url = string.Format(FileUrl, bucket); Client.BaseUrl = new Uri(url); var request = new RestRequest("{key}?uploadId={uploadId}&newKey={newKey}", Method.POST); request.AddHeader("Authorization", SignRequest(request, bucket, key)); request.AddUrlSegment("key", key); request.AddUrlSegment("newKey", newKey); request.AddUrlSegment("uploadId", uploadId); request.AddParameter("", Encoding.Default.GetBytes(eTags), ParameterType.RequestBody); var response = Client.Execute <FinishMultipartUploadResponse>(request); Client.BaseUrl = new Uri(BaseUrl); if (response.StatusCode == HttpStatusCode.OK) { response.Data.RetCode = 0; response.Data.ErrMsg = "Success"; response.Data.ETag = response.Headers.GetHeader("ETag"); } else { if (response.ErrorException != null) { const string message = "响应错误,请检查."; throw new ApplicationException(message, response.ErrorException); } response.Data.XSessionId = response.Headers.GetHeader("X-SessionId"); response.Data.ContentType = response.Headers.GetHeader("Content-Type"); response.Data.ContentLength = Convert.ToInt32(response.Headers.GetHeader("Content-Length")); } return(response.Data); }
/// <summary> /// Downloads one part from connected client and writes it into specified file /// </summary> /// <param name="file">PartFile into which will be the part written</param> /// <param name="part">Number of downloaded part</param> /// <returns>Returns eRequestPartResponse, which indicates whether process went well or the part was not available</returns> public async Task <ERequestPartResponse> DownloadPartAsync(PartFile file, long part) { try { Logger.WriteLine("Sending request for part"); await SendByteAsync((byte)EMessage.Part); Logger.WriteLine("Sending part number: " + part); await SendLongAsync(part); byte resp = await ReadByteAsync(); ERequestPartResponse response = (ERequestPartResponse)Enum.Parse(typeof(ERequestPartResponse), resp.ToString()); if (response != ERequestPartResponse.OK) { Logger.WriteLine("Part " + response.ToString()); return(response); } int count = file.GetPartLength(part); Logger.WriteLine("Reading content content of part:" + part); byte[] buffer = await ReadBytesAsync(count); //writes part into the file Logger.WriteLine("Writing part " + part + "of file " + file.FileName); await file.WritePartAsync(buffer, part); return(ERequestPartResponse.OK); } catch (IOException exception) { Logger.WriteLine("Closing connection. Exception caught: " + exception.Message); Close(); return(ERequestPartResponse.NeverAvailable); } catch (SocketException exception) { Logger.WriteLine("Closing connection. Exception caught: " + exception.Message); Close(); return(ERequestPartResponse.NeverAvailable); } }
/// <summary> /// 放弃分片上传 /// </summary> /// <param name="key">Bucket中文件名.</param> /// <param name="uploadId">本次分片上传的上传Id.</param> /// <param name="bucket">Bucket.</param> /// <returns>返回对象<see cref="UCloudSDK.Models.FileResponse"/></returns> /// <exception cref="System.Exception"></exception> public FileResponse AbortMultipartUpload(string key, string uploadId, string bucket = "") { PartFile = new PartFile(); if (bucket.IsNullOrWhiteSpace()) { bucket = Bucket; } var url = string.Format(FileUrl, bucket); Client.BaseUrl = new Uri(url); var request = new RestRequest("{key}?uploadId={uploadId}", Method.DELETE); request.AddHeader("Authorization", SignRequest(request, bucket, key)); request.AddUrlSegment("key", key); request.AddUrlSegment("uploadId", uploadId); return(FileExecute(request)); }
/// <summary> /// Deserializes file from xml and opens it. /// </summary> /// <param name="elem">XmlElement with serializet filePart</param> /// <param name="checkHash"></param> /// <returns>The loaded PartFile</returns> public static PartFile FromXml(XmlElement elem, bool checkHash) { PartFile file = new PartFile(elem["filepath"].InnerText); /*if (checkHash && file.Hash != elem["hash"].InnerText) * throw new WrongFileException("File has changed");*/ file.FileName = elem["filename"].InnerText; file.NumberOfParts = long.Parse(elem["numberofparts"].InnerText); file.PartStatus = new EPartStatus[file.NumberOfParts]; string partstatus = elem["partstatus"].InnerText; for (int i = 0; i < partstatus.Length; ++i) { file.PartStatus[i] = (EPartStatus)Enum.Parse(typeof(EPartStatus), partstatus[i].ToString()); } return(file); }
private bool ProcessPacket(byte[] buffer, int offset, int size, uint opcode, uint nIP, ushort nUDPPort) { try { MuleApplication.Instance.Statistics.AddDownDataOverheadServer((uint)size); ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(nIP, nUDPPort, true); if (pServer != null) { pServer.ResetFailedCount(); } switch ((OperationCodeEnum)opcode) { case OperationCodeEnum.OP_GLOBSEARCHRES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all search result packets int iLeft; do { uint uResultCount = MuleApplication.Instance.SearchList.ProcessUDPSearchAnswer(data, true /*pServer.GetUnicodeSupport()*/, nIP, nUDPPort - 4); // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBSEARCHRES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBFOUNDSOURCES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all source packets int iLeft; do { byte[] fileid = new byte[16]; data.ReadHash16(fileid); PartFile file = MuleApplication.Instance.DownloadQueue.GetFileByID(fileid); if (file != null) { file.AddSources(data, nIP, (ushort)(nUDPPort - 4), false); } else { // skip sources for that file uint count = data.ReadUInt8(); data.Seek(count * (4 + 2), System.IO.SeekOrigin.Current); } // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBSERVSTATRES: { if (size < 12 || pServer == null) { return(true); } uint challenge = BitConverter.ToUInt32(buffer, 0); if (challenge != pServer.Challenge) { return(true); } if (pServer != null) { pServer.Challenge = 0; pServer.CryptPingReplyPending = false; uint tNow = MpdUtilities.Time(); Random rand = new Random(); // if we used Obfuscated ping, we still need to reset the time properly pServer.LastPingedTime = Convert.ToUInt32(tNow - (rand.Next() % MuleConstants.ONE_HOUR_SEC)); } uint cur_user = BitConverter.ToUInt32(buffer, 4); uint cur_files = BitConverter.ToUInt32(buffer, 8); uint cur_maxusers = 0; uint cur_softfiles = 0; uint cur_hardfiles = 0; uint uUDPFlags = 0; uint uLowIDUsers = 0; uint dwServerUDPKey = 0; ushort nTCPObfuscationPort = 0; ushort nUDPObfuscationPort = 0; if (size >= 16) { cur_maxusers = BitConverter.ToUInt32(buffer, 12); } if (size >= 24) { cur_softfiles = BitConverter.ToUInt32(buffer, 16); cur_hardfiles = BitConverter.ToUInt32(buffer, 20); } if (size >= 28) { uUDPFlags = BitConverter.ToUInt32(buffer, 24); } if (size >= 32) { uLowIDUsers = BitConverter.ToUInt32(buffer, 28); } if (size >= 40) { // TODO debug check if this packet was encrypted if it has a key nUDPObfuscationPort = BitConverter.ToUInt16(buffer, 32); nTCPObfuscationPort = BitConverter.ToUInt16(buffer, 34);; dwServerUDPKey = BitConverter.ToUInt32(buffer, 36); } if (pServer != null) { pServer.Ping = MpdUtilities.GetTickCount() - pServer.LastPinged; pServer.UserCount = cur_user; pServer.FileCount = cur_files; pServer.MaxUsers = cur_maxusers; pServer.SoftFiles = cur_softfiles; pServer.HardFiles = cur_hardfiles; pServer.ServerKeyUDP = dwServerUDPKey; pServer.ObfuscationPortTCP = nTCPObfuscationPort; pServer.ObfuscationPortUDP = nUDPObfuscationPort; // if the received UDP flags do not match any already stored UDP flags, // reset the server version string because the version (which was determined by last connecting to // that server) is most likely not accurat any longer. // this may also give 'false' results because we don't know the UDP flags when connecting to a server // with TCP. //if (pServer.GetUDPFlags() != uUDPFlags) // pServer.Version(_T = ""); pServer.UDPFlags = (ED2KServerUdpFlagsEnum)uUDPFlags; pServer.LowIDUsers = uLowIDUsers; pServer.SetLastDescPingedCount(false); if (pServer.LastDescPingedCount < 2) { // eserver 16.45+ supports a new OP_SERVER_DESC_RES answer, if the OP_SERVER_DESC_REQ contains a uint // challenge, the server returns additional info with OP_SERVER_DESC_RES. To properly distinguish the // old and new OP_SERVER_DESC_RES answer, the challenge has to be selected carefully. The first 2 bytes // of the challenge (in network byte order) MUST NOT be a valid string-len-int16! Packet packet1 = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_SERVER_DESC_REQ, 4); uint uDescReqChallenge = ((uint)MpdUtilities.GetRandomUInt16() << 16) + MuleConstants.INV_SERV_DESC_LEN; // 0xF0FF = an 'invalid' string length. pServer.DescReqChallenge = uDescReqChallenge; Array.Copy(BitConverter.GetBytes(uDescReqChallenge), packet1.Buffer, 4); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet1.Size); MuleApplication.Instance.ServerConnect.SendUDPPacket(packet1, pServer, true); } else { pServer.SetLastDescPingedCount(true); } } break; } case OperationCodeEnum.OP_SERVER_DESC_RES: { if (pServer == null) { return(true); } // old packet: <name_len 2><name name_len><desc_len 2 desc_en> // new packet: <challenge 4><taglist> // // NOTE: To properly distinguish between the two packets which are both useing the same opcode... // the first two bytes of <challenge> (in network byte order) have to be an invalid <name_len> at least. SafeMemFile srvinfo = MpdObjectManager.CreateSafeMemFile(buffer, size); if (size >= 8 && BitConverter.ToUInt16(buffer, 0) == MuleConstants.INV_SERV_DESC_LEN) { if (pServer.DescReqChallenge != 0 && BitConverter.ToUInt32(buffer, 0) == pServer.DescReqChallenge) { pServer.DescReqChallenge = 0; srvinfo.ReadUInt32(); // skip challenge uint uTags = srvinfo.ReadUInt32(); for (uint i = 0; i < uTags; i++) { Tag tag = MpdObjectManager.CreateTag(srvinfo, true /*pServer.GetUnicodeSupport()*/); if (tag.NameID == MuleConstants.ST_SERVERNAME && tag.IsStr) { pServer.ServerName = tag.Str; } else if (tag.NameID == MuleConstants.ST_DESCRIPTION && tag.IsStr) { pServer.Description = tag.Str; } else if (tag.NameID == MuleConstants.ST_DYNIP && tag.IsStr) { // Verify that we really received a DN. IPAddress address; if (!IPAddress.TryParse(tag.Str, out address) || address == IPAddress.None) { string strOldDynIP = pServer.DynIP; pServer.DynIP = tag.Str; // If a dynIP-server changed its address or, if this is the // first time we get the dynIP-address for a server which we // already have as non-dynIP in our list, we need to remove // an already available server with the same 'dynIP:port'. if (string.Compare(strOldDynIP, pServer.DynIP, true) != 0) { MuleApplication.Instance.ServerList.RemoveDuplicatesByAddress(pServer); } } } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsStr) { pServer.Version = tag.Str; } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsInt) { pServer.Version = string.Format("{0}.{1}", tag.Int >> 16, tag.Int & 0xFFFF); } } } else { // A server sent us a new server description packet (including a challenge) although we did not // ask for it. This may happen, if there are multiple servers running on the same machine with // multiple IPs. If such a server is asked for a description, the server will answer 2 times, // but with the same IP. } } else { string strName = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); string strDesc = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); pServer.Description = strDesc; pServer.ServerName = strName; } break; } default: return(false); } return(true); } catch (Exception error) { ProcessPacketError((uint)size, (uint)opcode, nIP, nUDPPort, error); if (opcode == (byte)OperationCodeEnum.OP_GLOBSEARCHRES || opcode == (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { return(true); } } return(false); }