Subversion Repositories spk

Rev

Rev 203 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#pragma once

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

enum {ERROR_NONE, ERROR_ACCESSDENIED};
namespace PluginManager {

        /// <summary>
        /// Summary for CheckUpdate
        ///
        /// WARNING: If you change the name of this class, you will need to change the
        ///          'Resource File Name' property for the managed resource compiler tool
        ///          associated with all .resx files this class depends on.  Otherwise,
        ///          the designers will not be able to interact properly with localized
        ///          resources associated with this form.
        /// </summary>
        public ref class CheckUpdate : public System::Windows::Forms::Form
        {
        public:
                CheckUpdate(CPackages *p, ImageList ^images)
                {
                        m_iStatus = 0;
                        InitializeComponent();

                        m_lInstall = gcnew ArrayList();
                        m_pPackages = p;
                        m_pPackage = NULL;
                        m_pImageList = images;
                        this->listView1->SmallImageList = m_pImageList;
                        this->listView1->LargeImageList = m_pImageList;

                        this->listView1->Groups->Add(gcnew ListViewGroup("Packages", HorizontalAlignment::Left));
                        this->listView1->Groups->Add(gcnew ListViewGroup("Ships", HorizontalAlignment::Left));
                        this->listView1->Groups->Add(gcnew ListViewGroup("Mods", HorizontalAlignment::Left));

                        m_pCurrentItem = nullptr;
                        _lAddress = new Utils::WStringList;

                        for ( CBaseFile *package = p->PackageList()->First(); package; package = p->PackageList()->Next() ) {
                                if ( !package->webAddress().empty() ) this->AddPackage(package);
                        }

                        this->UpdateList();
                }

                void SetDownloader()
                {
                        m_bDownloader = true;
                        this->Text = "Download Packages";

                        this->listView1->Items->Clear();

                        for ( const SAvailablePackage *package = m_pPackages->getAvailablePackageList()->First(); package; package = m_pPackages->getAvailablePackageList()->Next() )
                                this->AddPackage(package);

                        this->UpdateList();
                }

                ArrayList ^GetInstallList() { return m_lInstall; }

                void OnePackage(CBaseFile *p)
                {
                        this->listView1->Items->Clear();
                        this->listView1->Groups->Clear();
                        this->listView1->CheckBoxes = false;
                        m_pCurrentItem = this->AddPackage(p);
                        this->UpdateList();
                        this->button2->Visible = false;
                        m_pPackage = p;
                        this->Height = 250;
                }

                void OnePackage(const SAvailablePackage *p)
                {
                        m_bDownloader = true;
                        this->Text = "Download Package";
                        this->listView1->Items->Clear();
                        this->listView1->Groups->Clear();
                        this->listView1->CheckBoxes = false;
                        m_pCurrentItem = this->AddPackage(p);
                        this->UpdateList();
                        this->button2->Visible = false;
                        m_pDownloadPackage = p;
                        this->Height = 250;
                }

                ListViewItem ^AddPackage(const SAvailablePackage *p)
                {
                        ListViewItem ^item = gcnew ListViewItem(_US(p->sName));
                        item->SubItems->Add(_US(p->sAuthor));
                        item->SubItems->Add(_US(p->sVersion));
                        item->SubItems->Add("Waiting");
                        item->SubItems->Add(_US(p->sFilename));
                        item->Tag = _US(p->sFilename);

                        AddPackage(item, p->iType);

                        return item;
                }

                void AddPackage(ListViewItem ^item, int type)
                {
                        item->SubItems->Add("");
                        item->Checked = true;
                        item->SubItems->Add("");
                        this->listView1->Items->Add(item);

                        if ( this->listView1->Groups->Count )
                        {
                                if ( type == PACKAGETYPE_SHIP )
                                        item->Group = this->listView1->Groups[1];
                                else if ( type == PACKAGETYPE_MOD )
                                        item->Group = this->listView1->Groups[2];
                                else
                                        item->Group = this->listView1->Groups[0];
                        }

                        item->ImageIndex = -1;

                        if ( item->ImageIndex == -1 )
                        {
                                if ( type == PACKAGETYPE_SHIP )
                                        item->ImageKey = "ship.png";
                                else if ( type == PACKAGETYPE_LIBRARY )
                                        item->ImageKey = "library.png";
                                else if ( type == PACKAGETYPE_FAKEPATCH || type == PACKAGETYPE_MOD )
                                        item->ImageKey = "fake.png";
                                else
                                        item->ImageKey = "package.png";
                        }
                }

                ListViewItem ^AddPackage(CBaseFile *p)
                {
                        ListViewItem ^item = gcnew ListViewItem(_US(p->name(m_pPackages->GetLanguage())));
                        item->SubItems->Add(_US(p->author()));
                        item->SubItems->Add(_US(p->version()));
                        item->SubItems->Add("Waiting");
                        item->SubItems->Add(_US(p->getNameValidFile().removeChar(' ') + L"_" + p->author().remove(L' ') + L".dat"));
                        item->Tag = p->GetNum();

                        if ( p->GetType() == TYPE_XSP )
                                AddPackage(item, PACKAGETYPE_SHIP);
                        else if ( p->IsMod() )
                                AddPackage(item, PACKAGETYPE_MOD);
                        else if ( p->GetType() == TYPE_SPK && ((CSpkFile *)p)->IsLibrary() )
                                AddPackage(item, PACKAGETYPE_LIBRARY);
                        else if ( p->IsFakePatch() )
                                AddPackage(item, PACKAGETYPE_FAKEPATCH);
                        else
                                AddPackage(item, PACKAGETYPE_NORMAL);

                        if ( p->icon() )
                                PluginManager::DisplayListIcon(p, this->listView1, item);

                        return item;
                }

                void UpdateNextPackage()
                {
                        m_pPackage = NULL;
                        m_pDownloadPackage = NULL;
                        int pos = (m_pCurrentItem) ? this->listView1->Items->IndexOf(m_pCurrentItem) : -1;
                        m_pCurrentItem = nullptr;

                        ++pos;
                        if ( pos < this->listView1->Items->Count )
                        {
                                m_pCurrentItem = this->listView1->Items[pos];
                                if ( m_bDownloader )
                                        m_pDownloadPackage = m_pPackages->findAvailablePackage(_WS(Convert::ToString(m_pCurrentItem->Tag)));
                                else
                                        m_pPackage = m_pPackages->GetPackageAt(Convert::ToInt32(m_pCurrentItem->Tag));
                        }

                        if ( m_pCurrentItem && (m_pPackage || m_pDownloadPackage) )
                                this->StartUpdate();
                        else // end of the list
                        {
                                this->progressBar1->Style = Windows::Forms::ProgressBarStyle::Continuous;
                                this->listView1->UseWaitCursor = false;
                                if ( m_bDownloader )
                                        this->button2->Text = "Install Now";
                                else
                                        this->button2->Text = "Update Now";
                                this->button2->DialogResult = Windows::Forms::DialogResult::OK;
                                this->button1->Text = "Close";
                                this->button1->DialogResult = Windows::Forms::DialogResult::Cancel;
                                this->listView1->CheckBoxes = false;

                                m_iStatus = 2;
                                // check if theres any updates
                                this->CheckButton();
                        }
                }

                void CheckNextPackage()
                {
                        m_pPackage = NULL;
                        m_pDownloadPackage = NULL;
                        int pos = (m_pCurrentItem) ? this->listView1->Items->IndexOf(m_pCurrentItem) : -1;
                        m_pCurrentItem = nullptr;

                        ++pos;
                        if ( pos < this->listView1->Items->Count )
                        {
                                m_pCurrentItem = this->listView1->Items[pos];
                                if ( m_bDownloader )
                                        m_pDownloadPackage = m_pPackages->findAvailablePackage(_WS(Convert::ToString(m_pCurrentItem->Tag)));
                                else
                                        m_pPackage = m_pPackages->GetPackageAt(Convert::ToInt32(m_pCurrentItem->Tag));
                        }

                        if ( m_pCurrentItem && (m_pPackage || m_pDownloadPackage) )
                                this->StartCheck();
                        else // end of the list
                        {
                                this->progressBar1->Style = Windows::Forms::ProgressBarStyle::Continuous;
                                this->listView1->UseWaitCursor = false;
                                if ( m_bDownloader )
                                        this->button2->Text = "Start Download";
                                else
                                        this->button2->Text = "Start Update";
                                this->button1->Text = "Close";
                                this->button1->DialogResult = Windows::Forms::DialogResult::Cancel;

                                m_iStatus = 1;
                                // check if theres any updates
                                this->CheckButton();
                        }
                }

                void CheckButton()
                {
                        this->button2->Visible = false;

                        if ( m_pCurrentItem )
                                return;

                        for ( int i = 0; i < this->listView1->Items->Count; i++ )
                        {
                                if ( !this->listView1->CheckBoxes || this->listView1->Items[i]->Checked )
                                {
                                        // if we are updating, check for a valid server
                                        if ( m_iStatus == 0 || this->listView1->Items[i]->SubItems[5]->Text->Length )
                                        {
                                                this->button2->Visible = true;
                                                break;
                                        }
                                }
                        }
                }

                void StartCheck()
                {
                        this->CheckButton();
                        this->button1->Text = "Cancel";
                        this->button1->DialogResult = Windows::Forms::DialogResult::None;
                        this->progressBar1->Style = Windows::Forms::ProgressBarStyle::Marquee;
                        this->listView1->UseWaitCursor = true;
                        m_sStatus = "";
                        m_sBestServer = "";
                        m_pCurrentItem->Selected = true;
                        m_pCurrentItem->SubItems[3]->Text = "Checking";

                        this->UpdateList();

                        // add all address
                        if ( m_pDownloadPackage )
                                _lAddress->pushBack(m_pDownloadPackage->sFilename);
                        else if ( m_pPackage )
                        {
                                _lAddress->pushBack(m_pPackage->webAddress());
                                for ( int i = 0; i < m_pPackage->getMaxWebMirrors(); i++ )
                                        _lAddress->pushBack(m_pPackage->getWebMirror(i));
                        }
                        else
                                return;

                        // start the check
                        this->backgroundWorker1->RunWorkerAsync();
                }

                System::String^ GetDestiantion()
                {
                        return Environment::GetFolderPath(Environment::SpecialFolder::Personal) + "\\Egosoft\\PluginManager";
                }

                void StartUpdate()
                {
                        // create downloads directory
                        System::String^ dir = GetDestiantion();
                        if ( !IO::Directory::Exists(dir + "\\Downloads") )
                        {
                                try {
                                        IO::Directory::CreateDirectory(dir + "\\Downloads");
                                }
                                catch (System::UnauthorizedAccessException ^) {
                                        MessageBox::Show(this, "Unable to create directory for downloads\nAccess Denied\n(" + dir + "\\Downloads)", "Access Denied", MessageBoxButtons::OK, MessageBoxIcon::Error);
                                        this->Close();                                  
                                }
                        }

                        // start the update
                        this->CheckButton();
                        this->button1->Text = "Cancel";
                        this->button1->DialogResult = Windows::Forms::DialogResult::None;
                        this->progressBar1->Style = Windows::Forms::ProgressBarStyle::Marquee;

                        this->listView1->UseWaitCursor = true;
                        m_pCurrentItem->Selected = true;
                        m_pCurrentItem->SubItems[3]->Text = "Downloading";
                        this->UpdateList();

                        // start the update
                        this->backgroundWorker2->RunWorkerAsync();
                }

                void UpdateList()
                {
                        this->listView1->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
                }

                bool ReadData(String ^url)
                {
                        bool ret = false;
                        m_sData = "";
                        try 
                        {
                                System::Net::WebClient ^Client = gcnew System::Net::WebClient();
                                Client->Headers->Add( "user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)" );
                                System::IO::Stream ^strm = Client->OpenRead(url);
                                System::IO::StreamReader ^sr = gcnew System::IO::StreamReader(strm);
                                m_sData = sr->ReadToEnd();

                                strm->Close();
                                sr->Close();

                                ret = true;
                        }
                        catch (System::Net::WebException ^)
                        {
                                return false;
                        }

                        if ( m_sData->Length )
                                return ret;
                        return false;
                }
                int CheckFile(String ^url)
                {
                        int ret = CONNECTERROR_UNKNOWN;
                        try 
                        {
                                // check for the file
                                Net::WebRequest ^check = (Net::HttpWebRequest ^)Net::WebRequest::Create(url);
                                check->Credentials = Net::CredentialCache::DefaultCredentials;
                                Net::WebResponse ^response = (Net::HttpWebResponse ^)check->GetResponse();
                                // check the file size
                                __int64 fileSize = response->ContentLength;
                                if ( fileSize )
                                        ret = CONNECTERROR_NONE;

                                response->Close();

                        }
                        catch (System::Net::WebException ^ex)
                        {
                                if ( ex->Status == System::Net::WebExceptionStatus::ConnectFailure )
                                        ret = CONNECTERROR_FAILED;
                                else
                                {
                                        switch ( cli::safe_cast<Net::HttpWebResponse ^>(ex->Response)->StatusCode )
                                        {
                                                case Net::HttpStatusCode::NotFound:
                                                        ret = CONNECTERROR_NOFILE;
                                                        break;
                                                case Net::HttpStatusCode::RequestTimeout:
                                                        ret = CONNECTERROR_TIMEOUT;
                                                        break;
                                                default:
                                                        ret = CONNECTERROR_UNKNOWN;
                                        }
                                }
                        }

                        return ret;
                }

        protected:
                ImageList               ^m_pImageList;
                ArrayList               ^m_lInstall;
                String                  ^m_sData;
                String                  ^m_sStatus;
                String                  ^m_sBestServer;
                Utils::WStringList      *_lAddress;
                ListViewItem    ^m_pCurrentItem;
                CPackages               *m_pPackages;
                CBaseFile               *m_pPackage;
                int                              m_iStatus;
                bool                     m_bDownloader;
                const SAvailablePackage *m_pDownloadPackage;
                int                              m_iErrorState;                 
private: System::Windows::Forms::ColumnHeader^  columnHeader4;
private: System::ComponentModel::BackgroundWorker^  backgroundWorker2;
private: System::Windows::Forms::Button^  button2;
protected: 

                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~CheckUpdate()
                {
                        if (components)
                        {
                                delete components;
                        }
                        delete _lAddress;
                }

        private: System::Windows::Forms::ProgressBar^  progressBar1;
        private: System::ComponentModel::BackgroundWorker^  backgroundWorker1;
        private: System::Windows::Forms::ListView^  listView1;
        private: System::Windows::Forms::ColumnHeader^  columnHeader1;
        private: System::Windows::Forms::ColumnHeader^  columnHeader2;
        private: System::Windows::Forms::ColumnHeader^  columnHeader3;
        private: System::Windows::Forms::Panel^  panel4;
        private: System::Windows::Forms::Button^  button1;
        protected: 

        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
                /// <summary>
                /// Required method for Designer support - do not modify
                /// the contents of this method with the code editor.
                /// </summary>
                void InitializeComponent(void)
                {
                        this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
                        this->backgroundWorker1 = (gcnew System::ComponentModel::BackgroundWorker());
                        this->listView1 = (gcnew System::Windows::Forms::ListView());
                        this->columnHeader1 = (gcnew System::Windows::Forms::ColumnHeader());
                        this->columnHeader2 = (gcnew System::Windows::Forms::ColumnHeader());
                        this->columnHeader3 = (gcnew System::Windows::Forms::ColumnHeader());
                        this->columnHeader4 = (gcnew System::Windows::Forms::ColumnHeader());
                        this->panel4 = (gcnew System::Windows::Forms::Panel());
                        this->button2 = (gcnew System::Windows::Forms::Button());
                        this->button1 = (gcnew System::Windows::Forms::Button());
                        this->backgroundWorker2 = (gcnew System::ComponentModel::BackgroundWorker());
                        this->panel4->SuspendLayout();
                        this->SuspendLayout();
                        // 
                        // progressBar1
                        // 
                        this->progressBar1->Dock = System::Windows::Forms::DockStyle::Bottom;
                        this->progressBar1->Location = System::Drawing::Point(20, 192);
                        this->progressBar1->MarqueeAnimationSpeed = 10;
                        this->progressBar1->Name = L"progressBar1";
                        this->progressBar1->Size = System::Drawing::Size(593, 31);
                        this->progressBar1->Step = 1;
                        this->progressBar1->Style = System::Windows::Forms::ProgressBarStyle::Continuous;
                        this->progressBar1->TabIndex = 3;
                        // 
                        // backgroundWorker1
                        // 
                        this->backgroundWorker1->WorkerReportsProgress = true;
                        this->backgroundWorker1->WorkerSupportsCancellation = true;
                        this->backgroundWorker1->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &CheckUpdate::backgroundWorker1_DoWork);
                        this->backgroundWorker1->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &CheckUpdate::backgroundWorker1_RunWorkerCompleted);
                        // 
                        // listView1
                        // 
                        this->listView1->CheckBoxes = true;
                        this->listView1->Columns->AddRange(gcnew cli::array< System::Windows::Forms::ColumnHeader^  >(4) {this->columnHeader1, this->columnHeader2, 
                                this->columnHeader3, this->columnHeader4});
                        this->listView1->Dock = System::Windows::Forms::DockStyle::Fill;
                        this->listView1->FullRowSelect = true;
                        this->listView1->HideSelection = false;
                        this->listView1->Location = System::Drawing::Point(20, 20);
                        this->listView1->MultiSelect = false;
                        this->listView1->Name = L"listView1";
                        this->listView1->ShowItemToolTips = true;
                        this->listView1->Size = System::Drawing::Size(593, 172);
                        this->listView1->Sorting = System::Windows::Forms::SortOrder::Ascending;
                        this->listView1->TabIndex = 7;
                        this->listView1->UseCompatibleStateImageBehavior = false;
                        this->listView1->UseWaitCursor = true;
                        this->listView1->View = System::Windows::Forms::View::Details;
                        this->listView1->Click += gcnew System::EventHandler(this, &CheckUpdate::listView1_Click);
                        // 
                        // columnHeader1
                        // 
                        this->columnHeader1->Text = L"Package";
                        this->columnHeader1->Width = 200;
                        // 
                        // columnHeader2
                        // 
                        this->columnHeader2->Text = L"Author";
                        this->columnHeader2->Width = 50;
                        // 
                        // columnHeader3
                        // 
                        this->columnHeader3->Text = L"Version";
                        // 
                        // columnHeader4
                        // 
                        this->columnHeader4->Text = L"Status";
                        // 
                        // panel4
                        // 
                        this->panel4->Controls->Add(this->button2);
                        this->panel4->Controls->Add(this->button1);
                        this->panel4->Dock = System::Windows::Forms::DockStyle::Bottom;
                        this->panel4->Location = System::Drawing::Point(20, 223);
                        this->panel4->Name = L"panel4";
                        this->panel4->Padding = System::Windows::Forms::Padding(10);
                        this->panel4->Size = System::Drawing::Size(593, 55);
                        this->panel4->TabIndex = 8;
                        // 
                        // button2
                        // 
                        this->button2->Dock = System::Windows::Forms::DockStyle::Left;
                        this->button2->Location = System::Drawing::Point(10, 10);
                        this->button2->Name = L"button2";
                        this->button2->Size = System::Drawing::Size(132, 35);
                        this->button2->TabIndex = 1;
                        this->button2->Text = L"Start Check";
                        this->button2->UseVisualStyleBackColor = true;
                        this->button2->Click += gcnew System::EventHandler(this, &CheckUpdate::button2_Click);
                        // 
                        // button1
                        // 
                        this->button1->DialogResult = System::Windows::Forms::DialogResult::Cancel;
                        this->button1->Dock = System::Windows::Forms::DockStyle::Right;
                        this->button1->Location = System::Drawing::Point(486, 10);
                        this->button1->Name = L"button1";
                        this->button1->Size = System::Drawing::Size(97, 35);
                        this->button1->TabIndex = 0;
                        this->button1->Text = L"Cancel";
                        this->button1->UseVisualStyleBackColor = true;
                        this->button1->Click += gcnew System::EventHandler(this, &CheckUpdate::button1_Click);
                        // 
                        // backgroundWorker2
                        // 
                        this->backgroundWorker2->WorkerReportsProgress = true;
                        this->backgroundWorker2->WorkerSupportsCancellation = true;
                        this->backgroundWorker2->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &CheckUpdate::backgroundWorker2_DoWork);
                        this->backgroundWorker2->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &CheckUpdate::backgroundWorker2_RunWorkerCompleted);
                        this->backgroundWorker2->ProgressChanged += gcnew System::ComponentModel::ProgressChangedEventHandler(this, &CheckUpdate::backgroundWorker2_ProgressChanged);
                        // 
                        // CheckUpdate
                        // 
                        this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                        this->ClientSize = System::Drawing::Size(633, 298);
                        this->ControlBox = false;
                        this->Controls->Add(this->listView1);
                        this->Controls->Add(this->progressBar1);
                        this->Controls->Add(this->panel4);
                        this->Name = L"CheckUpdate";
                        this->Padding = System::Windows::Forms::Padding(20);
                        this->ShowInTaskbar = false;
                        this->StartPosition = System::Windows::Forms::FormStartPosition::CenterParent;
                        this->Text = L"Checking Updates";
                        this->Load += gcnew System::EventHandler(this, &CheckUpdate::CheckUpdate_Load);
                        this->panel4->ResumeLayout(false);
                        this->ResumeLayout(false);

                }
#pragma endregion
        private: System::Void CheckUpdate_Load(System::Object^  sender, System::EventArgs^  e) {
                                 this->CheckButton();
                                 if ( m_pCurrentItem )
                                 {
                                        if ( m_pPackage )
                                                this->StartCheck();
                                        else if ( m_bDownloader && m_pDownloadPackage )
                                                this->StartCheck();
                                 }
                         }
private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
                         // for each server
                         String ^bestServer = "";
                         Utils::WString bestVersion = L"0.00";
                         String ^bestFile = "";

                         for(auto itr = _lAddress->begin(); itr != _lAddress->end(); itr++)
                         {
                                 if ( backgroundWorker1->CancellationPending )
                                         break;
                                 String ^address = _US((*itr)->str);
                                 m_sData = "";
                                 String ^url = address;
                                 
                                 if ( !m_bDownloader )
                                        url += "/" + m_pCurrentItem->SubItems[4]->Text;

                                 //int error = this->CheckFile(url);
                                 int error = CheckWebFileExists(url);

                                 if ( backgroundWorker1->CancellationPending )
                                         break;

                                 if ( m_bDownloader )
                                 {
                                         if ( error == CONNECTERROR_NONE )
                                         {
                                                 m_sBestServer = url;
                                                 m_sStatus = "Ready";
                                                 return;
                                         }
                                         switch(error)
                                         {
                                                case CONNECTERROR_NOFILE:
                                                        m_sStatus = "File Not Found";
                                                        break;
                                                case CONNECTERROR_TIMEOUT:
                                                        m_sStatus = "Connection Timedout";
                                                        break;
                                                case CONNECTERROR_FAILED:
                                                        m_sStatus = "Failed";
                                                        break;
                                         }
                                 }

                                 if ( error == CONNECTERROR_NONE )
                                 {
                                         // file exists, lets download and examine it
                                         if ( this->ReadData(url) )
                                         {
                                                 if ( backgroundWorker1->CancellationPending )
                                                         break;

                                                // we have the file, parse data
                                                cli::array<String ^> ^lines = m_sData->Split('\n');
                                                if ( lines )
                                                {
                                                         Utils::WString version;
                                                         Utils::WString file;
                                                         for ( int i = 0; i < lines->Length; i++ )
                                                         {
                                                                 Utils::WString l = _WS(lines[i]).remove(9).remove('\r');
                                                                 //if ( !l.IsIn(":") ) continue;
                                                                 Utils::WString first = l.token(L":", 1);
                                                                 if ( first.Compare(L"Version") )
                                                                         version = l.tokens(L":", 2).removeFirstSpace();
                                                                 else if ( first.Compare(L"File") )
                                                                         file = l.tokens(L":", 2).removeFirstSpace();
                                                         }

                                                         if ( !version.empty() && !file.empty() )
                                                         {
                                                                 int error = this->CheckFile(address + "/" + _US(file));
                                                                 if ( error == CONNECTERROR_NONE )
                                                                 {
                                                                         if ( bestVersion.compareVersion(version) == COMPARE_NEWER )
                                                                         {
                                                                                 bestServer = address + "/" + _US(file);
                                                                                 bestVersion = version;
                                                                         }
                                                                 }
                                                         }
                                                 }
                                        }
                                 }
                         }

                         if ( m_bDownloader )
                                 return;

                         // now check if we have found an update
                         if ( bestServer->Length )
                         {
                                 int v = m_pPackage->version().compareVersion(bestVersion);
                                 switch ( v )
                                 {
                                        case COMPARE_OLDER:
                                                m_sStatus = "Older";
                                                break;
                                        case COMPARE_SAME:
                                                m_sStatus = "Same";
                                                break;
                                        case COMPARE_NEWER:
                                                m_sStatus = "Newer (" + _US(bestVersion) + ")";
                                                m_sBestServer = bestServer;
                                                break;
                                 }
                         }
                         else
                         {
                                 if ( this->backgroundWorker1->CancellationPending )
                                        m_sStatus = "Cancelled";
                                 else
                                        m_sStatus = "No Update";
                         }
                 }
private: System::Void backgroundWorker1_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e) {
                         // update the status display
                         m_pCurrentItem->SubItems[3]->Text = m_sStatus;
                         if ( m_sBestServer && m_sBestServer->Length )
                                 m_pCurrentItem->SubItems[5]->Text = m_sBestServer;
                         this->UpdateList();

                         // next package
                         this->CheckNextPackage();
                 }
private: System::Void listView1_Click(System::Object^  sender, System::EventArgs^  e) {
                         this->CheckButton();
                 }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
                         if ( m_iStatus == 0 ) // start check
                         {
                                 // remove all items that are not checked
                                 for ( int i = this->listView1->Items->Count - 1; i >= 0; i-- )
                                 {
                                         if ( this->listView1->Items[i]->Checked )
                                                 continue;
                                         this->listView1->Items->RemoveAt(i);
                                 }

                                 this->CheckNextPackage();
                         }
                         else if ( m_iStatus == 1 ) // start downloading
                         {
                                 for ( int i = this->listView1->Items->Count - 1; i >= 0; i-- )
                                 {
                                         if ( this->listView1->Items[i]->SubItems[5]->Text->Length && this->listView1->Items[i]->Checked )
                                                 continue;
                                         this->listView1->Items->RemoveAt(i);
                                 }

                                 this->UpdateNextPackage();
                         }
                         else if ( m_iStatus == 2 ) // start installing
                         {
                                 //this->button2 
                         }
                 }
private: System::Void backgroundWorker2_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {

                                m_iErrorState = ERROR_NONE;

                                Threading::Thread::Sleep(1000);
                                System::Net::WebResponse ^res = nullptr;
                                System::Net::WebRequest ^req = nullptr;
                                try {
                                        req = System::Net::WebRequest::Create(m_pCurrentItem->SubItems[5]->Text);
                                        req->Timeout = 25000;
                                        res = req->GetResponse();
                                }
                                catch (System::Net::WebException ^) {
                                        return;
                                }

                                if ( backgroundWorker2->CancellationPending )
                                        return;

                                System::String ^dir = GetDestiantion();
                                dir += "\\Downloads";
                                String ^file = dir + "\\" + _US(CFileIO(_WS(m_pCurrentItem->SubItems[5]->Text)).filename().remove('\r').remove(9));

                                __int64 maxSize = res->ContentLength;
                                __int64 curSize = 0;

                                System::IO::FileStream ^writeStream = nullptr;
                                try {
                                        writeStream = gcnew System::IO::FileStream(file, System::IO::FileMode::OpenOrCreate);
                                }
                                catch (System::UnauthorizedAccessException ^) {
                                        m_iErrorState = ERROR_ACCESSDENIED;
                                        return;
                                }
                                catch (System::IO::IOException ^)
                                {
                                        return;
                                }
                                catch (System::Exception ^e)
                                {
                                        MessageBox::Show("Error: " + e->ToString(), "Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
                                        return;
                                }

                                do
                                {
                                        if ( backgroundWorker2->CancellationPending )
                                                break;

                                        Threading::Thread::Sleep(20);

                                        array<unsigned char> ^readBytes = gcnew array<unsigned char>(4096);
                                        int read = res->GetResponseStream()->Read(readBytes, 0, 4096);

                                        curSize += (__int64)read;

                                        int percent = (int)((curSize * 100) / maxSize);
                                        backgroundWorker2->ReportProgress(percent);

                                        if ( read <= 0 )
                                                break;

                                        writeStream->Write(readBytes, 0, read);
                                }
                                while(1);

                                res->GetResponseStream()->Close();
                                writeStream->Close();

                                Threading::Thread::Sleep(1000);

                                if ( backgroundWorker2->CancellationPending )
                                {
                                        try {
                                                System::IO::File::Delete(file);
                                        }
                                        catch (System::IO::IOException ^)
                                        {
                                        }
                                        catch (System::Exception ^)
                                        {
                                        }
                                }
                 }
private: System::Void backgroundWorker2_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e) {
                        this->progressBar1->Style = Windows::Forms::ProgressBarStyle::Continuous;
                        this->progressBar1->Value = e->ProgressPercentage;
                 }
private: System::Void backgroundWorker2_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e) {
                        if ( this->backgroundWorker2->CancellationPending )
                        {
                                 m_pCurrentItem->SubItems[3]->Text = "Cancelled";
                                 m_pCurrentItem->SubItems[5]->Text = "";
                        }
                        else
                        {
                                System::String ^dir = GetDestiantion();
                                dir += "\\Downloads";
                                String ^file = dir + "\\" + _US(CFileIO(_WS(m_pCurrentItem->SubItems[5]->Text)).filename().remove('\r').remove(9));

                                 if ( IO::File::Exists(file) )
                                 {
                                         m_pCurrentItem->SubItems[3]->Text = "Ready to Install";
                                         m_pCurrentItem->SubItems[5]->Text = file;
                                         m_lInstall->Add(file);
                                 }
                                 else
                                 {
                                         switch ( m_iErrorState ) {
                                                 case ERROR_ACCESSDENIED:
                                                         m_pCurrentItem->SubItems[3]->Text = "Access Denied";
                                                         break;
                                                 default:
                                                         m_pCurrentItem->SubItems[3]->Text = "Failed";
                                         }
                                         m_pCurrentItem->SubItems[5]->Text = "";
                                 }
                                 this->UpdateList();
                                 this->UpdateNextPackage();
                        }
                 }
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
                         this->backgroundWorker1->CancelAsync();
                         this->backgroundWorker2->CancelAsync();
                 }
};
}