//---------------------------------------------------------------------------------- // SendReport: Send report on what happened with this patch. // (for automatic pruning of poor patch locations) //---------------------------------------------------------------------------------- void DownloadCtrl::SendReport(void) { CustomInfo* pCustInfo = GetCustomInfo(); CPatchData* pPatch = pCustInfo->GetSelectedPatch(); PatchCore* pCore = GetMainControl()->GetPatchCore(); ServerContext* pGamePatchServers = pCore->GetGamePatchServers(); if (pGamePatchServers == NULL) return; AsyncSocketPtr aSocketP = new AsyncSocket(AsyncSocket::UDP); aSocketP->Bind(0); AddrList GamePatchServerAddrList; pGamePatchServers->CopyAddresses(GamePatchServerAddrList); for (AddrList::iterator anItr = GamePatchServerAddrList.begin(); anItr != GamePatchServerAddrList.end(); ++anItr) { ReportPatchStatusOpPtr pOp = new ReportPatchStatusOp(*anItr); pOp->SetProductName(pCustInfo->GetProductName()); pOp->SetConfigName(pCustInfo->GetExtraConfig()); pOp->SetFromVersion(pPatch->GetFromVersion()); pOp->SetToVersion(pCustInfo->GetNewVersion()); pOp->SetNetAddress(pPatch->GetPatchUrl()); pOp->SetUDPSocket(aSocketP); if (m_bAborted) pOp->SetPatchStatus(1); // cancel type else if (m_bPatchIsValid && m_bPatchDownloadSucceeded) pOp->SetPatchStatus(0); // success type else pOp->SetPatchStatus(2); // failed type pOp->RunBlock(0); } }
//---------------------------------------------------------------------------------- // StartDownloads: Start the threads that will download the files. //---------------------------------------------------------------------------------- void DownloadCtrl::StartDownloads(void) { CustomInfo* pCustInfo = GetCustomInfo(); CPatchData* pPatch = pCustInfo->GetSelectedPatch(); if (pPatch) { #ifdef _DEBUG if (GetKeyState(VK_MENU) & GetKeyState(VK_CONTROL) & GetKeyState(VK_SHIFT) & 0x8000) pPatch->DebugBox(GetWindow()); #endif GUIString sPatchFile = pPatch->GetPatchUrl(); int nPos = sPatchFile.rFind('/'); if (nPos == -1) nPos = sPatchFile.rFind('\\'); if (nPos != -1) sPatchFile.erase(0, nPos + 1); else sPatchFile = TEXT("Update.exe"); std::string aHostGraphic = pPatch->GetHostBmp(); int aPos = aHostGraphic.find_last_of('.'); std::string aHostGraphicExtension; if(aPos != std::string::npos && aHostGraphic.length() > aPos + 1) aHostGraphicExtension = aHostGraphic.substr(aPos+1); else aHostGraphicExtension = "bmp"; m_sHostBitmapFile = GenerateTempFileName("FS", aHostGraphicExtension); CreateDirectoryRecursive(pCustInfo->GetPatchFolder()); GUIString sPatchExe = pCustInfo->GetPatchFolder(); sPatchExe.append(sPatchFile); pCustInfo->SetPatchFile(sPatchExe); mStartTime = time(NULL); mNumberCallbacks = 0; if (IsFtpAddress(pPatch->GetHostBmp())) { // Don't attempt to handle resumed downloads of bitmaps - not worth it. DeleteFile(std::string(m_sHostBitmapFile).c_str()); m_pFtpGetBitmap = new FTPGetOp(pPatch->GetHostBmp(), true); m_pFtpGetBitmap->SetLocalPath(m_sHostBitmapFile); m_pFtpGetBitmap->SetCompletion(new DownloadCompletion(FtpBitmapDoneCallback)); m_pFtpGetBitmap->RunAsync(static_cast<ULONG>(OP_TIMEOUT_INFINITE)); } else { m_pHttpGetBitmap = new HTTPGetOp(pPatch->GetHostBmp()); m_pHttpGetBitmap->SetLocalPath(m_sHostBitmapFile); m_pHttpGetBitmap->SetCompletion(new DownloadCompletion(HttpBitmapDoneCallback)); m_pHttpGetBitmap->RunAsync(static_cast<ULONG>(OP_TIMEOUT_INFINITE)); } // m_tDownloadStarted = GetTickCount(); m_nPrevDownloadedFtpBytes = 0; if (IsFtpAddress(pPatch->GetPatchUrl())) { // If the previous patch profile does not match this patch profile, nuke the file. if (! pCustInfo->MatchFtpDownloadTag(sPatchExe, pCustInfo->GetNewVersion(), pPatch->GetPatchSize(), pPatch->GetChecksum())) DeleteFile(std::string(sPatchExe).c_str()); else m_nPrevDownloadedFtpBytes = GetFileSize(sPatchExe); // Tag the patch's profile (so we can 'resume or not as appropriate later). pCustInfo->TagFtpDownload(sPatchExe, pCustInfo->GetNewVersion(), pPatch->GetPatchSize(), pPatch->GetChecksum()); m_pFtpGetPatch = new FTPGetOp(pPatch->GetPatchUrl(), true); m_pFtpGetPatch->SetDoResume(true); // Allow resuming of downloads. m_pFtpGetPatch->SetLocalPath(sPatchExe); m_pFtpGetPatch->SetRecvChunkCompletion(new DownloadCompletion(PatchProgressCallback), CHUNCK_SIZE); m_pFtpGetPatch->SetCompletion(new DownloadCompletion(FtpPatchDoneCallback)); m_pFtpGetPatch->RunAsync(static_cast<ULONG>(OP_TIMEOUT_INFINITE)); } else { m_pHttpGetPatch = new HTTPGetOp(pPatch->GetPatchUrl()); m_pHttpGetPatch->SetLocalPath(sPatchExe); m_pHttpGetPatch->SetRecvChunkCompletion(new DownloadCompletion(PatchProgressCallback), CHUNCK_SIZE); m_pHttpGetPatch->SetCompletion(new DownloadCompletion(HttpPatchDoneCallback)); m_pHttpGetPatch->RunAsync(static_cast<ULONG>(OP_TIMEOUT_INFINITE)); } m_bDownloadStarted = true; } }
//---------------------------------------------------------------------------------- // FtpPatchDownloadComplete: The ftp transfer has completed for the patch. Check // the status to see if it worked. //---------------------------------------------------------------------------------- void DownloadCtrl::FtpPatchDownloadComplete(FTPGetOp* pGetOp) { CustomInfo* pCustInfo = GetCustomInfo(); ResourceManager* pResMgr = pCustInfo->GetResourceManager(); // Turn off the timer. RequestTimer(false); WONStatus aStatus = pGetOp->GetStatus(); CPatchData* pPatch = pCustInfo->GetSelectedPatch(); if (aStatus == WS_Success) { if (pPatch) pCustInfo->SaveDefaultSelection(pPatch->GetHostName()); m_bPatchDownloadSucceeded = true; if (! m_bAborted) { // Set the progress bar to 100%. int nLower, nUpper; m_pProgressBar->GetRange(nLower, nUpper); UpdateProgressBar(nUpper, nUpper); ValidatePatch(); } } else { if (! m_bAborted) // If the user aborted don't pop up an error telling them they aborted... { // Clear the file name (so no one tries to use it), but don't deleted it, // we can resume the download later. pCustInfo->SetPatchFile(""); GUIString sTitle = pResMgr->GetFinishedString(Download_DownloadError_String); GUIString sMsg; if (pPatch) pPatch->SetDownloadFailures(pPatch->GetDownloadFailures() + 1); switch (aStatus) { case WS_FTP_StatusError: switch (pGetOp->GetFTPStatus()) { case 500: NamePasswordDialog(pGetOp, sTitle, pResMgr->GetFinishedString(Download_InvalidFtpUser_String)); return; case 530: NamePasswordDialog(pGetOp, sTitle, pResMgr->GetFinishedString(Download_InvalidFtpPassword_String)); return; case 550: MessageBox(GetWindow(), pResMgr->GetFinishedString(Download_InvalidFtpFile_String), sTitle, MD_OK); break; default: sMsg = pResMgr->GetFinishedString(Download_FtpError_String); ReplaceSubInt(sMsg, "%ERROR%", pGetOp->GetFTPStatus()); MessageBox(GetWindow(), sMsg, sTitle, MD_OK); } //lint !e788 break; case WS_FTP_InvalidResponse: MessageBox(GetWindow(), pResMgr->GetFinishedString(Download_InvalidFtpResp_String), sTitle, MD_OK); break; case WS_FTP_InvalidPasvResponse: MessageBox(GetWindow(), pResMgr->GetFinishedString(Download_InvalidFtpPasvResp_String), sTitle, MD_OK); break; case WS_WSAECONNREFUSED: MessageBox(GetWindow(), pResMgr->GetFinishedString(Download_ConnectionRefused_String), sTitle, MD_OK); break; default: sMsg = pResMgr->GetFinishedString(Download_UnknownFtpError_String); ReplaceSubString(sMsg, "%ERROR%", WONStatusToString(aStatus)); MessageBox(GetWindow(), sMsg, sTitle, MD_OK); } //lint !e788 FireBackButton(); } } m_bPatchDownloadComplete = true; SendReport(); EnableControls(); }