Example #1
0
            /// <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);
            }
Example #2
0
            /// <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);
            }
Example #3
0
            /// <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 }
                };
            }
Example #4
0
        /// <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);
        }
Example #5
0
            /// <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);
            }
Example #6
0
            /// <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;
                    }
                }
Example #7
0
        /// <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);
        }
Example #8
0
            /// <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);
                }
            }
Example #9
0
        /// <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));
        }
Example #10
0
            /// <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);
            }
Example #11
0
        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);
        }