From 13952bf27e72c3a76d576b3424b659a77c688c29 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 25 Jul 2019 10:51:18 -0700 Subject: [PATCH] Fixes and seamless self update --- launchers/win32/Launcher.rc | 2 +- launchers/win32/LauncherApp.cpp | 27 ++++++++++----- launchers/win32/LauncherDlg.cpp | 22 +++++++++--- launchers/win32/LauncherManager.cpp | 53 ++++++++++++++++++++--------- launchers/win32/LauncherManager.h | 8 ++++- 5 files changed, 80 insertions(+), 32 deletions(-) diff --git a/launchers/win32/Launcher.rc b/launchers/win32/Launcher.rc index b3225d5a4a..80d5f74404 100644 --- a/launchers/win32/Launcher.rc +++ b/launchers/win32/Launcher.rc @@ -107,7 +107,7 @@ BEGIN RTEXT "",IDC_TERMS,15,172,180,15,NOT WS_VISIBLE CONTROL "",IDC_TERMS_LINK,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,197,172,80,15 CTEXT "",IDC_TROUBLE,65,203,174,15,NOT WS_VISIBLE - RTEXT "THIS IS THE VERSION",IDC_VERSION,0,205,305,10 + RTEXT "",IDC_VERSION,100,205,205,10 CONTROL "NEXT",IDC_BUTTON_NEXT,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,107,158,94,16 CONTROL "Having Trouble?",IDC_TROUBLE_LINK,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,126,203,56,11 END diff --git a/launchers/win32/LauncherApp.cpp b/launchers/win32/LauncherApp.cpp index c15ba75a9b..5aae2f312b 100644 --- a/launchers/win32/LauncherApp.cpp +++ b/launchers/win32/LauncherApp.cpp @@ -39,16 +39,25 @@ BOOL CLauncherApp::InitInstance() { } int iNumOfArgs; LPWSTR* pArgs = CommandLineToArgvW(GetCommandLine(), &iNumOfArgs); - bool isUninstalling = false; - bool isRestarting = false; + bool uninstalling = false; + bool restarting = false; + bool noUpdate = false; + bool continueUpdating = false; if (iNumOfArgs > 1) { - if (CString(pArgs[1]).Compare(_T("--uninstall")) == 0) { - isUninstalling = true; - } else if (CString(pArgs[1]).Compare(_T("--restart")) == 0) { - isRestarting = true; + for (int i = 1; i < iNumOfArgs; i++) { + CString curArg = CString(pArgs[i]); + if (curArg.Compare(_T("--uninstall")) == 0) { + uninstalling = true; + } else if (curArg.Compare(_T("--restart")) == 0) { + restarting = true; + } else if (curArg.Compare(_T("--noUpdate")) == 0) { + noUpdate = true; + } else if (curArg.Compare(_T("--continueUpdating")) == 0) { + continueUpdating = true; + } } } - if (!isRestarting) { + if (!restarting) { // don't launch if already running CreateMutex(NULL, TRUE, _T("HQ_Launcher_Mutex")); if (GetLastError() == ERROR_ALREADY_EXISTS) { @@ -56,10 +65,10 @@ BOOL CLauncherApp::InitInstance() { } } - if (isUninstalling) { + if (uninstalling) { _manager.uninstall(); } else { - _manager.init(); + _manager.init(!noUpdate, continueUpdating); } if (!_manager.hasFailed() && !_manager.installLauncher()) { return FALSE; diff --git a/launchers/win32/LauncherDlg.cpp b/launchers/win32/LauncherDlg.cpp index a2128b4389..fb64555a69 100644 --- a/launchers/win32/LauncherDlg.cpp +++ b/launchers/win32/LauncherDlg.cpp @@ -677,7 +677,12 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { theApp._manager.downloadNewLauncher(); } else { if (_splashStep > SPLASH_DURATION && _splashStep < 2 * SPLASH_DURATION) { - theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, (float)(_splashStep - SPLASH_DURATION) / SPLASH_DURATION); + float progress = (float)(_splashStep - SPLASH_DURATION) / SPLASH_DURATION; + if (theApp._manager.willContinueUpdating()) { + progress = CONTINUE_UPDATING_GLOBAL_OFFSET * progress; + progress = min(progress, CONTINUE_UPDATING_GLOBAL_OFFSET); + } + theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, progress); _splashStep++; } if (theApp._manager.needsRestartNewLauncher()) { @@ -688,17 +693,21 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { } } } - + BOOL needsToWait = theApp._manager.needsToWait(); if (_showSplash) { if (_splashStep == 0) { if (theApp._manager.needsUninstall()) { theApp._manager.addToLog(_T("Waiting to uninstall")); setDrawDialog(DrawStep::DrawProcessUninstall); + } else if (theApp._manager.shouldContinueUpdating()) { + _splashStep = SPLASH_DURATION; + setDrawDialog(DrawStep::DrawProcessUpdate); + theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, 0.0f); } else { theApp._manager.addToLog(_T("Start splash screen")); setDrawDialog(DrawStep::DrawLogo); } - } else if (_splashStep > SPLASH_DURATION && !theApp._manager.needsToWait()) { + } else if (_splashStep > SPLASH_DURATION && !needsToWait) { _showSplash = false; if (theApp._manager.shouldShutDown()) { if (_applicationWND != NULL) { @@ -769,12 +778,17 @@ void CLauncherDlg::setDrawDialog(DrawStep step, BOOL isUpdate) { auto m_voxelRenderTarget = m_voxel->GetRenderTarget(); auto m_progressRenderTarget = m_progress->GetRenderTarget(); switch (_drawStep) { - case DrawStep::DrawLogo: + case DrawStep::DrawLogo: { m_pRenderTarget->BeginDraw(); drawBackground(m_pRenderTarget); drawLogo(m_pRenderTarget); m_pRenderTarget->EndDraw(); + CRect redrawRec; + GetClientRect(redrawRec); + redrawRec.top = redrawRec.bottom - 30; + RedrawWindow(redrawRec); break; + } case DrawStep::DrawLoginLogin: case DrawStep::DrawLoginErrorOrg: case DrawStep::DrawLoginErrorCred: diff --git a/launchers/win32/LauncherManager.cpp b/launchers/win32/LauncherManager.cpp index d584e56ad1..a431672f2e 100644 --- a/launchers/win32/LauncherManager.cpp +++ b/launchers/win32/LauncherManager.cpp @@ -21,9 +21,14 @@ LauncherManager::LauncherManager() { LauncherManager::~LauncherManager() { } -void LauncherManager::init() { +void LauncherManager::init(BOOL allowUpdate, BOOL continueUpdating) { initLog(); int tokenPos = 0; + _updateLauncherAllowed = allowUpdate; + _continueUpdating = continueUpdating; + if (_continueUpdating) { + _progressOffset = CONTINUE_UPDATING_GLOBAL_OFFSET; + } _launcherVersion = CString(LAUNCHER_BUILD_VERSION).Tokenize(_T("-"), tokenPos); addToLog(_T("Launcher is running version: " + _launcherVersion)); addToLog(_T("Getting most recent builds")); @@ -158,6 +163,7 @@ void LauncherManager::updateProgress(ProcessType processType, float progress) { default: break; } + _progress = _progressOffset + (1.0f - _progressOffset) * _progress; TRACE("progress = %f\n", _progress); } @@ -205,11 +211,11 @@ BOOL LauncherManager::isApplicationInstalled(CString& version, CString& domain, CString applicationDir; getAndCreatePaths(PathType::Launcher_Directory, applicationDir); CString applicationPath = applicationDir + "interface\\interface.exe"; - BOOL isApplicationInstalled = PathFileExistsW(applicationPath); + BOOL isInstalled = PathFileExistsW(applicationPath); BOOL configFileExist = PathFileExistsW(applicationDir + _T("interface\\config.json")); if (configFileExist) { LauncherUtils::ResponseError status = readConfigJSON(version, domain, content, loggedIn); - return isApplicationInstalled && status == LauncherUtils::ResponseError::NoError; + return isInstalled && status == LauncherUtils::ResponseError::NoError; } return FALSE; } @@ -414,23 +420,26 @@ void LauncherManager::getMostRecentBuilds(CString& launcherUrlOut, CString& laun void LauncherManager::onMostRecentBuildsReceived(const CString& response, LauncherUtils::ResponseError error) { if (error == LauncherUtils::ResponseError::NoError) { addToLog(_T("Latest launcher version: ") + _latestLauncherVersion); - - if (_updateLauncherAllowed && _latestLauncherVersion.Compare(_launcherVersion) != 0) { + CString currentVersion; + BOOL isInstalled = (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn); + bool newInterfaceVersion = _latestVersion.Compare(currentVersion) != 0; + bool newLauncherVersion = _latestLauncherVersion.Compare(_launcherVersion) != 0 && _updateLauncherAllowed; + if (newLauncherVersion) { CString updatingMsg; updatingMsg.Format(_T("Updating Launcher from version: %s to version: %s"), _launcherVersion, _latestLauncherVersion); addToLog(updatingMsg); _shouldUpdateLauncher = TRUE; _shouldDownloadLauncher = TRUE; + _willContinueUpdating = isInstalled && newInterfaceVersion; } else { if (_updateLauncherAllowed) { addToLog(_T("Already running most recent build. Launching interface.exe")); } else { addToLog(_T("Updating the launcher was not allowed --noUpdate")); } - CString currentVersion; - if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) { + if (isInstalled) { addToLog(_T("Installed version: ") + currentVersion); - if (_latestVersion.Compare(currentVersion) == 0) { + if (!newInterfaceVersion) { addToLog(_T("Already running most recent build. Launching interface.exe")); _shouldLaunch = TRUE; _shouldShutdown = TRUE; @@ -552,7 +561,7 @@ BOOL LauncherManager::extractApplication() { } }; std::function onProgress = [&](float progress) { - updateProgress(ProcessType::UnzipApplication, progress); + updateProgress(ProcessType::UnzipApplication, max(progress, 0.0f)); }; _currentProcess = ProcessType::UnzipApplication; BOOL success = LauncherUtils::unzipFileOnThread(ProcessType::UnzipApplication, @@ -600,7 +609,13 @@ void LauncherManager::onFileDownloaded(ProcessType type) { } void LauncherManager::restartNewLauncher() { - LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart")); + closeLog(); + if (_willContinueUpdating) { + LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart --noUpdate --continueUpdating")); + } else { + LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart --noUpdate")); + } + Sleep(500); } @@ -619,7 +634,7 @@ BOOL LauncherManager::installContent() { } }; std::function onProgress = [&](float progress) { - updateProgress(ProcessType::UnzipContent, progress); + updateProgress(ProcessType::UnzipContent, max(progress, 0.0f)); }; _currentProcess = ProcessType::UnzipContent; BOOL success = LauncherUtils::unzipFileOnThread(ProcessType::UnzipContent, contentZipFile, @@ -634,10 +649,13 @@ BOOL LauncherManager::installContent() { BOOL LauncherManager::downloadFile(ProcessType type, const CString& url, CString& outPath) { - CString fileName = url.Mid(url.ReverseFind('/') + 1); - CString downloadDirectory; - BOOL success = getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDirectory); - outPath = downloadDirectory + fileName; + BOOL success = TRUE; + if (outPath.IsEmpty()) { + CString fileName = url.Mid(url.ReverseFind('/') + 1); + CString downloadDirectory; + BOOL success = getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDirectory); + outPath = downloadDirectory + fileName; + } _currentProcess = type; if (success) { addToLog(_T("Downloading: ") + url); @@ -656,7 +674,7 @@ BOOL LauncherManager::downloadFile(ProcessType type, const CString& url, CString } }; std::function onProgress = [&, type](float progress) { - updateProgress(_currentProcess, progress); + updateProgress(_currentProcess, max(progress, 0.0f)); }; success = LauncherUtils::downloadFileOnThread(type, url, outPath, onDownloadFinished, onProgress); } @@ -677,7 +695,8 @@ BOOL LauncherManager::downloadApplication() { BOOL LauncherManager::downloadNewLauncher() { _shouldDownloadLauncher = FALSE; getAndCreatePaths(PathType::Temp_Directory, _tempLauncherPath); - _tempLauncherPath += _T("/") + LAUNCHER_EXE_FILENAME; + CString tempName = _T("HQLauncher") + _launcherVersion + _T(".exe"); + _tempLauncherPath += tempName; return downloadFile(ProcessType::DownloadLauncher, _latestLauncherURL, _tempLauncherPath); } diff --git a/launchers/win32/LauncherManager.h b/launchers/win32/LauncherManager.h index 3fd8fdba07..29dd05b4e0 100644 --- a/launchers/win32/LauncherManager.h +++ b/launchers/win32/LauncherManager.h @@ -25,6 +25,7 @@ const float DOWNLOAD_APPLICATION_INSTALL_WEIGHT = 0.5f; const float EXTRACT_APPLICATION_INSTALL_WEIGHT = 0.2f; const float DOWNLOAD_APPLICATION_UPDATE_WEIGHT = 0.75f; const float EXTRACT_APPLICATION_UPDATE_WEIGHT = 0.25f; +const float CONTINUE_UPDATING_GLOBAL_OFFSET = 0.2f; class LauncherManager { @@ -58,7 +59,7 @@ public: }; LauncherManager(); ~LauncherManager(); - void init(); + void init(BOOL allowUpdate, BOOL continueUpdating); BOOL initLog(); BOOL addToLog(const CString& line); void closeLog(); @@ -96,6 +97,8 @@ public: BOOL needsInstall() { return _shouldInstall; } BOOL needsToWait() { return _shouldWait; } BOOL needsRestartNewLauncher() { return _shouldRestartNewLauncher; } + BOOL shouldContinueUpdating() { return _continueUpdating; } + BOOL willContinueUpdating() { return _willContinueUpdating; } void setDisplayName(const CString& displayName) { _displayName = displayName; } bool isLoggedIn() { return _loggedIn; } bool hasFailed() { return _hasFailed; } @@ -145,6 +148,9 @@ private: BOOL _shouldDownloadLauncher{ FALSE }; BOOL _updateLauncherAllowed { TRUE }; BOOL _shouldRestartNewLauncher { FALSE }; + BOOL _continueUpdating{ FALSE }; + BOOL _willContinueUpdating{ FALSE }; + float _progressOffset { 0.0f }; float _progress { 0.0f }; CStdioFile _logFile; };