Exemplo n.º 1
0
        /// <summary>
        /// Starts a downloader by parsing the received message from the irc server on information
        /// </summary>
        /// <param name="dccString">message from irc server</param>
        /// <param name="downloaddir">download directory</param>
        /// <param name="bot">bot where the file came from</param>
        /// <param name="pack">pack on bot where the file came from</param>
        /// <param name="client">irc client used the moment it received the dcc message, used for sending abort messages when download fails unexpectedly</param>
        public void StartDownloader(string dccString, string downloaddir, string bot, string pack, IrcClient client)
        {
            if ((dccString ?? downloaddir ?? bot ?? pack) != null && dccString.Contains("SEND") && !IsDownloading)
            {
                NewDccString    = dccString;
                _curDownloadDir = downloaddir;
                BotName         = bot;
                PackNum         = pack;
                _ircClient      = client;

                //parsing the data for downloader thread

                UpdateStatus("PARSING");
                bool isParsed = ParseData(dccString);

                //try to set the necesary information for the downloader
                if (isParsed)
                {
                    _shouldAbort = false;
                    //start the downloader thread
                    _downloader = new Thread(new ThreadStart(this.Downloader));
                    _downloader.IsBackground = true;
                    _downloader.Start();
                }
                else
                {
                    OnDccDebugMessage?.Invoke(this,
                                              new DCCDebugMessageArgs(
                                                  "Can't parse dcc string and start downloader, failed to parse data, removing from que\n", "DCC STARTER"));
                    _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
                    _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
                }
            }
            else
            {
                if (IsDownloading)
                {
                    OnDccDebugMessage?.Invoke(this,
                                              new DCCDebugMessageArgs("You are already downloading! Ignore SEND request\n", "DCC STARTER"));
                }
                else
                {
                    OnDccDebugMessage?.Invoke(this,
                                              new DCCDebugMessageArgs("DCC String does not contain SEND and/or invalid values for parsing! Ignore SEND request\n", "DCC STARTER"));
                }
            }
        }
Exemplo n.º 2
0
 /// <summary>
 ///send message to all channels
 /// </summary>
 /// <param name="message">message to send</param>
 /// <returns>true if succesfully send</returns>
 public bool SendMessageToAll(string message)
 {
     return(IrcClient.SendMessageToAll(message));
 }
Exemplo n.º 3
0
        /// <summary>
        /// Method ran within downloader thread, starts a connection to the file server, and receives the file accordingly, sends updates using event handler during the download.
        /// </summary>
        public void Downloader()
        {
            UpdateStatus("WAITING");

            //combining download directory path with filename

            if (_curDownloadDir != null)
            {
                if (_curDownloadDir != string.Empty)
                {
                    if (_curDownloadDir.Length > 0)
                    {
                        if (!Directory.Exists(_curDownloadDir))
                        {
                            Directory.CreateDirectory(_curDownloadDir);
                        }
                    }
                    else
                    {
                        _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
                        if (!Directory.Exists(_curDownloadDir))
                        {
                            Directory.CreateDirectory(_curDownloadDir);
                        }
                    }
                }
                else
                {
                    _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
                    if (!Directory.Exists(_curDownloadDir))
                    {
                        Directory.CreateDirectory(_curDownloadDir);
                    }
                }
            }
            else
            {
                _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
                if (!Directory.Exists(_curDownloadDir))
                {
                    Directory.CreateDirectory(_curDownloadDir);
                }
            }

            string dlDirAndFileName = Path.Combine(_curDownloadDir, NewFileName);

            CurrentFilePath = dlDirAndFileName;
            try
            {
                if (!File.Exists(dlDirAndFileName))
                {
                    OnDccDebugMessage?.Invoke(this,
                                              new DCCDebugMessageArgs("File does not exist yet, start connection with: " + NewIP + ":" + NewPortNum + Environment.NewLine, "DCC DOWNLOADER"));
                    Thread.Sleep(500);
                    //start connection with tcp server

                    IPAddress ip = IPAddress.Parse(NewIP);

                    using (TcpClient dltcp = new TcpClient(ip.AddressFamily))
                    {
                        dltcp.Connect(ip, NewPortNum);
                        using (NetworkStream dlstream = dltcp.GetStream())
                        {
                            //succesfully connected to tcp server, status is downloading
                            UpdateStatus("DOWNLOADING");

                            //values to keep track of progress
                            Int64    bytesReceived    = 0;
                            Int64    oldBytesReceived = 0;
                            Int64    oneprocent       = NewFileSize / 100;
                            DateTime start            = DateTime.Now;
                            bool     timedOut         = false;

                            //values to keep track of download position
                            int count;

                            //to me this buffer size seemed to be the most efficient.
                            byte[] buffer;
                            if (NewFileSize > 1048576)
                            {
                                OnDccDebugMessage?.Invoke(this,
                                                          new DCCDebugMessageArgs("Big file, big buffer (1 mb) \n ", "DCC DOWNLOADER"));
                                buffer = new byte[16384];
                            }
                            else if (NewFileSize < 1048576 && NewFileSize > 2048)
                            {
                                OnDccDebugMessage?.Invoke(this,
                                                          new DCCDebugMessageArgs("Smaller file (< 1 mb), smaller buffer (2 kb) \n ", "DCC DOWNLOADER"));
                                buffer = new byte[2048];
                            }
                            else if (NewFileSize < 2048 && NewFileSize > 128)
                            {
                                OnDccDebugMessage?.Invoke(this,
                                                          new DCCDebugMessageArgs("Small file (< 2kb mb), small buffer (128 b) \n ", "DCC DOWNLOADER"));
                                buffer = new byte[128];
                            }
                            else
                            {
                                OnDccDebugMessage?.Invoke(this,
                                                          new DCCDebugMessageArgs("Tiny file (< 128 b), tiny buffer (2 b) \n ", "DCC DOWNLOADER"));
                                buffer = new byte[2];
                            }


                            //create file to write to
                            using (FileStream writeStream = new FileStream(dlDirAndFileName, FileMode.Append, FileAccess.Write, FileShare.Read))
                            {
                                writeStream.SetLength(NewFileSize);
                                IsDownloading = true;
                                //download while connected and filesize is not reached
                                while (dltcp.Connected && bytesReceived < NewFileSize && !_shouldAbort)
                                {
                                    if (_shouldAbort)
                                    {
                                        dltcp.Close();
                                        dlstream.Dispose();
                                        writeStream.Close();
                                    }
                                    //keep track of progress
                                    DateTime end = DateTime.Now;
                                    if (end.Second != start.Second)
                                    {
                                        BytesPerSecond   = bytesReceived - oldBytesReceived;
                                        KBytesPerSecond  = (int)(BytesPerSecond / 1024);
                                        MBytesPerSecond  = (KBytesPerSecond / 1024);
                                        oldBytesReceived = bytesReceived;
                                        start            = DateTime.Now;
                                        UpdateStatus("DOWNLOADING");
                                    }

                                    //count bytes received
                                    count = dlstream.Read(buffer, 0, buffer.Length);

                                    //write to file
                                    writeStream.Write(buffer, 0, count);

                                    //count bytes received
                                    bytesReceived += count;

                                    Progress = (int)(bytesReceived / oneprocent);
                                }

                                //close all connections and streams (just to be save)
                                dltcp.Close();
                                dlstream.Dispose();
                                writeStream.Close();

                                IsDownloading = false;

                                if (_shouldAbort)
                                {
                                    try
                                    {
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("Downloader Stopped", "DCC DOWNLOADER"));
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("File " + CurrentFilePath + " will be deleted due to aborting", "DCC DOWNLOADER"));
                                        File.Delete(CurrentFilePath);
                                    }
                                    catch (Exception e)
                                    {
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("File " + CurrentFilePath + " probably doesn't exist :X", "DCC DOWNLOADER"));
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs(e.ToString(), "DCC DOWNLOADER"));
                                    }

                                    UpdateStatus("ABORTED");
                                }
                                else
                                {
                                    //consider 95% downloaded as done, files are sequentually downloaded, sometimes download stops early, but the file still is usable
                                    if (Progress < 95 && !_shouldAbort)
                                    {
                                        UpdateStatus("FAILED");
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("Download stopped at < 95 % finished, deleting file: " + NewFileName + " \n", "DCC DOWNLOADER"));
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("Download stopped at : " + bytesReceived + " bytes, a total of " + Progress + "%", "DCC DOWNLOADER"));
                                        File.Delete(dlDirAndFileName);
                                        timedOut = false;
                                    }
                                    else if (timedOut && Progress < 95 && !_shouldAbort)
                                    {
                                        UpdateStatus("FAILED: TIMED OUT");
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("Download timed out at < 95 % finished, deleting file: " + NewFileName + " \n", "DCC DOWNLOADER"));
                                        OnDccDebugMessage?.Invoke(this,
                                                                  new DCCDebugMessageArgs("Download stopped at : " + bytesReceived + " bytes, a total of " + Progress + "%", "DCC DOWNLOADER"));
                                        File.Delete(dlDirAndFileName);
                                        timedOut = false;
                                    }
                                    else if (!_shouldAbort)
                                    {
                                        //make sure that in the event something happens and the downloader calls delete after finishing, the file will remain where it is.
                                        dlDirAndFileName = "";
                                        UpdateStatus("COMPLETED");
                                    }
                                }
                                _shouldAbort = false;
                            }
                        }
                    }
                }
                else
                {
                    OnDccDebugMessage?.Invoke(this,
                                              new DCCDebugMessageArgs("File already exists, removing from xdcc que!\n", "DCC DOWNLOADER"));
                    _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
                    _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
                    UpdateStatus("FAILED: ALREADY EXISTS");
                }
                OnDccDebugMessage?.Invoke(this,
                                          new DCCDebugMessageArgs("File has been downloaded! \n File Location:" + CurrentFilePath, "DCC DOWNLOADER"));
            }
            catch (SocketException e)
            {
                OnDccDebugMessage?.Invoke(this,
                                          new DCCDebugMessageArgs("Something went wrong while downloading the file! Removing from xdcc que to be sure! Error:\n" + e.ToString(), "DCC DOWNLOADER"));
                _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
                _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
                UpdateStatus("FAILED: CONNECTING");
            }
            catch (Exception ex)
            {
                OnDccDebugMessage?.Invoke(this,
                                          new DCCDebugMessageArgs("Something went wrong while downloading the file! Removing from xdcc que to be sure! Error:\n" + ex.ToString(), "DCC DOWNLOADER"));
                _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
                _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
                UpdateStatus("FAILED: UNKNOWN");
            }
            IsDownloading = false;
        }