From 4d9557dfc115ff42aba4d568301620cbff5faa2c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 24 Jul 2019 17:16:22 -0700 Subject: [PATCH 1/3] Display version and autoupdate --- launchers/win32/CMakeLists.txt | 5 +- launchers/win32/Launcher.rc | 5 +- launchers/win32/LauncherDlg.cpp | 40 ++++++- launchers/win32/LauncherDlg.h | 2 + launchers/win32/LauncherManager.cpp | 104 +++++++++++++----- launchers/win32/LauncherManager.h | 20 +++- .../cmake/macros/SetPackagingParameters.cmake | 45 ++++++++ launchers/win32/resource.h | 1 + 8 files changed, 181 insertions(+), 41 deletions(-) create mode 100644 launchers/win32/cmake/macros/SetPackagingParameters.cmake diff --git a/launchers/win32/CMakeLists.txt b/launchers/win32/CMakeLists.txt index a472c68688..e42e3eb743 100644 --- a/launchers/win32/CMakeLists.txt +++ b/launchers/win32/CMakeLists.txt @@ -10,6 +10,7 @@ set(CMAKE_MFC_FLAG 1) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +include("cmake/macros/SetPackagingParameters.cmake") add_executable(HQLauncher WIN32 @@ -49,6 +50,8 @@ function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE) endif() endfunction() +set_packaging_parameters() + set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "") if (LAUNCHER_HMAC_SECRET STREQUAL "") @@ -56,7 +59,7 @@ if (LAUNCHER_HMAC_SECRET STREQUAL "") endif() target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_HMAC_SECRET="${LAUNCHER_HMAC_SECRET}") - +target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_BUILD_VERSION="${BUILD_VERSION}") # Preprocessor definitions target_compile_definitions(HQLauncher PRIVATE diff --git a/launchers/win32/Launcher.rc b/launchers/win32/Launcher.rc index eb72dced4c..b3225d5a4a 100644 --- a/launchers/win32/Launcher.rc +++ b/launchers/win32/Launcher.rc @@ -92,8 +92,8 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION EXSTYLE WS_EX_APPWINDOW FONT 10, "MS Shell Dlg", 400, 0, 0x0 BEGIN - CONTROL "",IDC_VOXEL,"Static",SS_BLACKRECT,65,3,174,123, NOT WS_VISIBLE - CONTROL "", IDC_PROGRESS, "Static", SS_BLACKRECT, 35, 170, 239, 4, NOT WS_VISIBLE + CONTROL "",IDC_VOXEL,"Static",SS_BLACKRECT,65,3,174,123 + CONTROL "",IDC_PROGRESS,"Static",SS_BLACKRECT,35,170,239,4 EDITTEXT IDC_ORGNAME,44,68,219,12,ES_AUTOHSCROLL | NOT WS_VISIBLE | NOT WS_BORDER EDITTEXT IDC_USERNAME,44,95,219,12,ES_AUTOHSCROLL | NOT WS_VISIBLE | NOT WS_BORDER EDITTEXT IDC_PASSWORD,44,122,219,12,ES_PASSWORD | ES_AUTOHSCROLL | NOT WS_VISIBLE | NOT WS_BORDER @@ -107,6 +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 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/LauncherDlg.cpp b/launchers/win32/LauncherDlg.cpp index 2e5d568839..a2128b4389 100644 --- a/launchers/win32/LauncherDlg.cpp +++ b/launchers/win32/LauncherDlg.cpp @@ -40,6 +40,8 @@ static CString GRAPHIK_SEMIBOLD = _T("Graphik-Semibold"); static CString TROUBLE_URL = _T("https://www.highfidelity.com/hq-support"); static CString TERMS_URL = _T("https://www.highfidelity.com/termsofservice"); +static int SPLASH_DURATION = 100; + CLauncherDlg::CLauncherDlg(CWnd* pParent) : CDialog(IDD_LAUNCHER_DIALOG, pParent) @@ -112,6 +114,11 @@ BOOL CLauncherDlg::OnInitDialog() { m_voxel = (CStatic *)GetDlgItem(IDC_VOXEL); m_progress = (CStatic *)GetDlgItem(IDC_PROGRESS); + m_version = (CStatic *)GetDlgItem(IDC_VERSION); + CString version; + version.Format(_T("V.%s"), theApp._manager.getLauncherVersion()); + m_version->SetWindowTextW(version); + m_voxel->EnableD2DSupport(); m_progress->EnableD2DSupport(); @@ -230,7 +237,6 @@ void CLauncherDlg::startProcess() { theApp._manager.setFailed(true); } }); - } BOOL CLauncherDlg::getHQInfo(const CString& orgname) { @@ -322,11 +328,12 @@ void CLauncherDlg::drawLogo(CHwndRenderTarget* pRenderTarget) { void CLauncherDlg::drawSmallLogo(CHwndRenderTarget* pRenderTarget) { CD2DBitmap m_pBitmamLogo(pRenderTarget, IDB_PNG5, _T("PNG")); auto size = pRenderTarget->GetSize(); - int padding = 6; + int xPadding = 6; + int yPadding = 22; int logoWidth = 100; int logoHeight = 18; - float logoPosX = size.width - logoWidth - padding; - float logoPosY = size.height - logoHeight - padding; + float logoPosX = size.width - logoWidth - xPadding; + float logoPosY = size.height - logoHeight - yPadding; CD2DRectF logoRec(logoPosX, logoPosY, logoPosX + logoWidth, logoPosY + logoHeight); pRenderTarget->DrawBitmap(&m_pBitmamLogo, logoRec); } @@ -521,6 +528,7 @@ BOOL CLauncherDlg::getTextFormat(int resID, TextFormat& formatOut) { formatOut.size = FIELDS_FONT_SIZE; formatOut.color = COLOR_GREY; break; + case IDC_VERSION: case IDC_TERMS: formatOut.size = TERMS_FONT_SIZE; break; @@ -663,6 +671,24 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { // Refresh setDrawDialog(_drawStep, true); } + + if (theApp._manager.needsSelfUpdate()) { + if (theApp._manager.needsSelfDownload()) { + theApp._manager.downloadNewLauncher(); + } else { + if (_splashStep > SPLASH_DURATION && _splashStep < 2 * SPLASH_DURATION) { + theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, (float)(_splashStep - SPLASH_DURATION) / SPLASH_DURATION); + _splashStep++; + } + if (theApp._manager.needsRestartNewLauncher()) { + if (_splashStep >= 2 * SPLASH_DURATION) { + theApp._manager.restartNewLauncher(); + exit(0); + } + } + } + } + if (_showSplash) { if (_splashStep == 0) { if (theApp._manager.needsUninstall()) { @@ -672,7 +698,7 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { theApp._manager.addToLog(_T("Start splash screen")); setDrawDialog(DrawStep::DrawLogo); } - } else if (_splashStep > 100 && !theApp._manager.needsToWait()) { + } else if (_splashStep > SPLASH_DURATION && !theApp._manager.needsToWait()) { _showSplash = false; if (theApp._manager.shouldShutDown()) { if (_applicationWND != NULL) { @@ -692,12 +718,14 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { theApp._manager.addToLog(_T("HQ failed to uninstall.")); theApp._manager.setFailed(true); } + } else if (theApp._manager.needsSelfUpdate()) { + setDrawDialog(DrawStep::DrawProcessUpdate); } else { theApp._manager.addToLog(_T("Starting login")); setDrawDialog(DrawStep::DrawLoginLogin); } } else if (theApp._manager.needsUninstall()) { - theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, (float)_splashStep/100); + theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, (float)_splashStep / SPLASH_DURATION); } _splashStep++; } else if (theApp._manager.shouldShutDown()) { diff --git a/launchers/win32/LauncherDlg.h b/launchers/win32/LauncherDlg.h index faebc8a822..d25618c554 100644 --- a/launchers/win32/LauncherDlg.h +++ b/launchers/win32/LauncherDlg.h @@ -94,6 +94,8 @@ protected: CStatic* m_username_banner; CStatic* m_password_banner; + CStatic* m_version; + HWND _applicationWND { 0 }; void drawBackground(CHwndRenderTarget* pRenderTarget); diff --git a/launchers/win32/LauncherManager.cpp b/launchers/win32/LauncherManager.cpp index 294c9742f5..d584e56ad1 100644 --- a/launchers/win32/LauncherManager.cpp +++ b/launchers/win32/LauncherManager.cpp @@ -23,8 +23,11 @@ LauncherManager::~LauncherManager() { void LauncherManager::init() { initLog(); - addToLog(_T("Getting most recent build")); - getMostRecentBuild(_latestApplicationURL, _latestVersion); + int tokenPos = 0; + _launcherVersion = CString(LAUNCHER_BUILD_VERSION).Tokenize(_T("-"), tokenPos); + addToLog(_T("Launcher is running version: " + _launcherVersion)); + addToLog(_T("Getting most recent builds")); + getMostRecentBuilds(_latestLauncherURL, _latestLauncherVersion, _latestApplicationURL, _latestVersion); } BOOL LauncherManager::initLog() { @@ -124,6 +127,8 @@ BOOL LauncherManager::restartLauncher() { void LauncherManager::updateProgress(ProcessType processType, float progress) { switch (processType) { + case ProcessType::DownloadLauncher: + break; case ProcessType::Uninstall: _progress = progress; break; @@ -359,14 +364,23 @@ LauncherUtils::ResponseError LauncherManager::readOrganizationJSON(const CString return LauncherUtils::ResponseError::ParsingJSON; } -void LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut) { +void LauncherManager::getMostRecentBuilds(CString& launcherUrlOut, CString& launcherVersionOut, + CString& interfaceUrlOut, CString& interfaceVersionOut) { CString contentTypeJson = L"content-type:application/json"; std::function httpCallback = [&](CString response, int err) { LauncherUtils::ResponseError error = LauncherUtils::ResponseError(err); if (error == LauncherUtils::ResponseError::NoError) { Json::Value json; - error = LauncherUtils::ResponseError::ParsingJSON; if (LauncherUtils::parseJSON(response, json)) { + if (json["launcher"].isObject()) { + if (json["launcher"]["windows"].isObject() && json["launcher"]["windows"]["url"].isString()) { + launcherUrlOut = json["launcher"]["windows"]["url"].asCString(); + } + if (json["launcher"]["version"].isInt()) { + std::string version = std::to_string(json["launcher"]["version"].asInt()); + launcherVersionOut = CString(version.c_str()); + } + } int count = json["count"].isInt() ? json["count"].asInt() : 0; if (count > 0 && json["results"].isArray()) { for (int i = 0; i < count; i++) { @@ -374,19 +388,21 @@ void LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut) { Json::Value result = json["results"][i]; if (result["latest_version"].isInt()) { std::string version = std::to_string(result["latest_version"].asInt()); - versionOut = CString(version.c_str()); + interfaceVersionOut = CString(version.c_str()); } if (result["installers"].isObject() && result["installers"]["windows"].isObject() && result["installers"]["windows"]["zip_url"].isString()) { - urlOut = result["installers"]["windows"]["zip_url"].asCString(); - error = LauncherUtils::ResponseError::NoError; + interfaceUrlOut = result["installers"]["windows"]["zip_url"].asCString(); } } } } + if (launcherUrlOut.IsEmpty() || launcherVersionOut.IsEmpty() || interfaceUrlOut.IsEmpty() || interfaceVersionOut.IsEmpty()) { + error = LauncherUtils::ResponseError::ParsingJSON; + } } - onMostRecentBuildReceived(response, error); + onMostRecentBuildsReceived(response, error); } }; LauncherUtils::httpCallOnThread(L"HQ Launcher", @@ -395,31 +411,46 @@ void LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut) { contentTypeJson, CStringA(), false, httpCallback); } -void LauncherManager::onMostRecentBuildReceived(const CString& response, LauncherUtils::ResponseError error) { +void LauncherManager::onMostRecentBuildsReceived(const CString& response, LauncherUtils::ResponseError error) { if (error == LauncherUtils::ResponseError::NoError) { - addToLog(_T("Latest version: ") + _latestVersion); - CString currentVersion; - if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) { - addToLog(_T("Installed version: ") + currentVersion); - if (_latestVersion.Compare(currentVersion) == 0) { - addToLog(_T("Already running most recent build. Launching interface.exe")); - _shouldLaunch = TRUE; - _shouldShutdown = TRUE; - } else { - addToLog(_T("New build found. Updating")); - _shouldUpdate = TRUE; - } - } else if (_loggedIn) { - addToLog(_T("Interface not found but logged in. Reinstalling")); - _shouldUpdate = TRUE; + addToLog(_T("Latest launcher version: ") + _latestLauncherVersion); + + if (_updateLauncherAllowed && _latestLauncherVersion.Compare(_launcherVersion) != 0) { + CString updatingMsg; + updatingMsg.Format(_T("Updating Launcher from version: %s to version: %s"), _launcherVersion, _latestLauncherVersion); + addToLog(updatingMsg); + _shouldUpdateLauncher = TRUE; + _shouldDownloadLauncher = TRUE; } else { - _shouldInstall = TRUE; + 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) { + addToLog(_T("Installed version: ") + currentVersion); + if (_latestVersion.Compare(currentVersion) == 0) { + addToLog(_T("Already running most recent build. Launching interface.exe")); + _shouldLaunch = TRUE; + _shouldShutdown = TRUE; + } else { + addToLog(_T("New build found. Updating")); + _shouldUpdate = TRUE; + } + } else if (_loggedIn) { + addToLog(_T("Interface not found but logged in. Reinstalling")); + _shouldUpdate = TRUE; + } else { + _shouldInstall = TRUE; + } } _shouldWait = FALSE; + } else { _hasFailed = true; CString msg; - msg.Format(_T("Getting most recent build has failed with error: %d"), error); + msg.Format(_T("Getting most recent builds has failed with error: %d"), error); addToLog(msg); msg.Format(_T("Response: %s"), response); addToLog(msg); @@ -563,9 +594,15 @@ void LauncherManager::onFileDownloaded(ProcessType type) { setFailed(true); } }); + } else if (type == ProcessType::DownloadLauncher) { + _shouldRestartNewLauncher = true; } } +void LauncherManager::restartNewLauncher() { + LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart")); +} + BOOL LauncherManager::installContent() { std::string contentZipFile = LauncherUtils::cStringToStd(_contentZipPath); @@ -610,18 +647,18 @@ BOOL LauncherManager::downloadFile(ProcessType type, const CString& url, CString } else { if (type == ProcessType::DownloadApplication) { addToLog(_T("Error downloading content.")); + } else if (type == ProcessType::DownloadLauncher) { + addToLog(_T("Error downloading launcher.")); } else { addToLog(_T("Error downloading application.")); } _hasFailed = true; } }; - std::function onProgress = [&](float progress) { + std::function onProgress = [&, type](float progress) { updateProgress(_currentProcess, progress); }; - if (!LauncherUtils::downloadFileOnThread(type, url, outPath, onDownloadFinished, onProgress)) { - success = FALSE; - } + success = LauncherUtils::downloadFileOnThread(type, url, outPath, onDownloadFinished, onProgress); } return success; } @@ -637,6 +674,13 @@ BOOL LauncherManager::downloadApplication() { return downloadFile(ProcessType::DownloadApplication, applicationURL, _applicationZipPath); } +BOOL LauncherManager::downloadNewLauncher() { + _shouldDownloadLauncher = FALSE; + getAndCreatePaths(PathType::Temp_Directory, _tempLauncherPath); + _tempLauncherPath += _T("/") + LAUNCHER_EXE_FILENAME; + return downloadFile(ProcessType::DownloadLauncher, _latestLauncherURL, _tempLauncherPath); +} + void LauncherManager::onCancel() { if (_currentProcess == ProcessType::UnzipApplication) { _latestVersion = _T(""); diff --git a/launchers/win32/LauncherManager.h b/launchers/win32/LauncherManager.h index 6ebebc5fc3..3fd8fdba07 100644 --- a/launchers/win32/LauncherManager.h +++ b/launchers/win32/LauncherManager.h @@ -49,6 +49,7 @@ public: ErrorIOFiles }; enum ProcessType { + DownloadLauncher = 0, DownloadContent, DownloadApplication, UnzipContent, @@ -67,7 +68,8 @@ public: BOOL isApplicationInstalled(CString& version, CString& domain, CString& content, bool& loggedIn); LauncherUtils::ResponseError getAccessTokenForCredentials(const CString& username, const CString& password); - void getMostRecentBuild(CString& urlOut, CString& versionOut); + void getMostRecentBuilds(CString& launcherUrlOut, CString& launcherVersionOut, + CString& interfaceUrlOut, CString& interfaceVersionOut); LauncherUtils::ResponseError readOrganizationJSON(const CString& hash); LauncherUtils::ResponseError readConfigJSON(CString& version, CString& domain, CString& content, bool& loggedIn); @@ -88,9 +90,12 @@ public: BOOL shouldShutDown() const { return _shouldShutdown; } BOOL shouldLaunch() const { return _shouldLaunch; } BOOL needsUpdate() { return _shouldUpdate; } + BOOL needsSelfUpdate() { return _shouldUpdateLauncher; } + BOOL needsSelfDownload() { return _shouldDownloadLauncher; } BOOL needsUninstall() { return _shouldUninstall; } BOOL needsInstall() { return _shouldInstall; } BOOL needsToWait() { return _shouldWait; } + BOOL needsRestartNewLauncher() { return _shouldRestartNewLauncher; } void setDisplayName(const CString& displayName) { _displayName = displayName; } bool isLoggedIn() { return _loggedIn; } bool hasFailed() { return _hasFailed; } @@ -101,19 +106,24 @@ public: BOOL downloadFile(ProcessType type, const CString& url, CString& localPath); BOOL downloadContent(); BOOL downloadApplication(); + BOOL downloadNewLauncher(); BOOL installContent(); BOOL extractApplication(); + void restartNewLauncher(); void onZipExtracted(ProcessType type, int size); void onFileDownloaded(ProcessType type); float getProgress() { return _progress; } void updateProgress(ProcessType processType, float progress); void onCancel(); + const CString& getLauncherVersion() const { return _launcherVersion; } private: ProcessType _currentProcess { ProcessType::DownloadApplication }; - void onMostRecentBuildReceived(const CString& response, LauncherUtils::ResponseError error); + void onMostRecentBuildsReceived(const CString& response, LauncherUtils::ResponseError error); CString _latestApplicationURL; CString _latestVersion; + CString _latestLauncherURL; + CString _latestLauncherVersion; CString _contentURL; CString _domainURL; CString _version; @@ -121,6 +131,8 @@ private: CString _tokensJSON; CString _applicationZipPath; CString _contentZipPath; + CString _launcherVersion; + CString _tempLauncherPath; bool _loggedIn { false }; bool _hasFailed { false }; BOOL _shouldUpdate { FALSE }; @@ -129,6 +141,10 @@ private: BOOL _shouldShutdown { FALSE }; BOOL _shouldLaunch { FALSE }; BOOL _shouldWait { TRUE }; + BOOL _shouldUpdateLauncher { FALSE }; + BOOL _shouldDownloadLauncher{ FALSE }; + BOOL _updateLauncherAllowed { TRUE }; + BOOL _shouldRestartNewLauncher { FALSE }; float _progress { 0.0f }; CStdioFile _logFile; }; diff --git a/launchers/win32/cmake/macros/SetPackagingParameters.cmake b/launchers/win32/cmake/macros/SetPackagingParameters.cmake new file mode 100644 index 0000000000..ed24b3bd6b --- /dev/null +++ b/launchers/win32/cmake/macros/SetPackagingParameters.cmake @@ -0,0 +1,45 @@ +# +# SetPackagingParameters.cmake +# cmake/macros +# +# Created by Leonardo Murillo on 07/14/2015. +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +# This macro checks some Jenkins defined environment variables to determine the origin of this build +# and decides how targets should be packaged. + +macro(SET_PACKAGING_PARAMETERS) + set(PR_BUILD 0) + set(PRODUCTION_BUILD 0) + set(DEV_BUILD 0) + set(BUILD_NUMBER 0) + + set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV") + set_from_env(RELEASE_NUMBER RELEASE_NUMBER "") + set_from_env(STABLE_BUILD STABLE_BUILD 0) + + message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}") + set(BUILD_NUMBER ${RELEASE_NUMBER}) + + if (RELEASE_TYPE STREQUAL "PRODUCTION") + set(PRODUCTION_BUILD 1) + set(BUILD_VERSION ${RELEASE_NUMBER}) + + # add definition for this release type + add_definitions(-DPRODUCTION_BUILD) + + elseif (RELEASE_TYPE STREQUAL "PR") + set(PR_BUILD 1) + set(BUILD_VERSION "PR${RELEASE_NUMBER}") + + # add definition for this release type + add_definitions(-DPR_BUILD) + else () + set(DEV_BUILD 1) + set(BUILD_VERSION "dev") + endif () + +endmacro(SET_PACKAGING_PARAMETERS) diff --git a/launchers/win32/resource.h b/launchers/win32/resource.h index 74c62b75cb..ffe1b1431b 100644 --- a/launchers/win32/resource.h +++ b/launchers/win32/resource.h @@ -27,6 +27,7 @@ #define IDC_TROUBLE 1023 #define IDC_VOXEL 1024 #define IDC_PROGRESS 1025 +#define IDC_VERSION 1026 #define IDC_TROUBLE_LINK 1027 // Next default values for new objects From 13952bf27e72c3a76d576b3424b659a77c688c29 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 25 Jul 2019 10:51:18 -0700 Subject: [PATCH 2/3] 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; }; From c3ad65f62890b499e1e0e0ae378bae1d6957f996 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 25 Jul 2019 11:22:20 -0700 Subject: [PATCH 3/3] add --skipSplash param --- launchers/win32/LauncherApp.cpp | 5 ++++- launchers/win32/LauncherDlg.cpp | 11 ++++++---- launchers/win32/LauncherManager.cpp | 6 +++-- launchers/win32/LauncherManager.h | 34 +++++++++++++++-------------- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/launchers/win32/LauncherApp.cpp b/launchers/win32/LauncherApp.cpp index 5aae2f312b..841a0bee3b 100644 --- a/launchers/win32/LauncherApp.cpp +++ b/launchers/win32/LauncherApp.cpp @@ -43,6 +43,7 @@ BOOL CLauncherApp::InitInstance() { bool restarting = false; bool noUpdate = false; bool continueUpdating = false; + bool skipSplash = false; if (iNumOfArgs > 1) { for (int i = 1; i < iNumOfArgs; i++) { CString curArg = CString(pArgs[i]); @@ -54,6 +55,8 @@ BOOL CLauncherApp::InitInstance() { noUpdate = true; } else if (curArg.Compare(_T("--continueUpdating")) == 0) { continueUpdating = true; + } else if (curArg.Compare(_T("--skipSplash")) == 0) { + skipSplash = true; } } } @@ -68,7 +71,7 @@ BOOL CLauncherApp::InitInstance() { if (uninstalling) { _manager.uninstall(); } else { - _manager.init(!noUpdate, continueUpdating); + _manager.init(!noUpdate, continueUpdating, skipSplash); } if (!_manager.hasFailed() && !_manager.installLauncher()) { return FALSE; diff --git a/launchers/win32/LauncherDlg.cpp b/launchers/win32/LauncherDlg.cpp index fb64555a69..d7d214842d 100644 --- a/launchers/win32/LauncherDlg.cpp +++ b/launchers/win32/LauncherDlg.cpp @@ -693,7 +693,6 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { } } } - BOOL needsToWait = theApp._manager.needsToWait(); if (_showSplash) { if (_splashStep == 0) { if (theApp._manager.needsUninstall()) { @@ -704,10 +703,14 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { setDrawDialog(DrawStep::DrawProcessUpdate); theApp._manager.updateProgress(LauncherManager::ProcessType::Uninstall, 0.0f); } else { - theApp._manager.addToLog(_T("Start splash screen")); - setDrawDialog(DrawStep::DrawLogo); + if (theApp._manager.shouldSkipSplashScreen()) { + _splashStep = SPLASH_DURATION; + } else { + theApp._manager.addToLog(_T("Start splash screen")); + setDrawDialog(DrawStep::DrawLogo); + } } - } else if (_splashStep > SPLASH_DURATION && !needsToWait) { + } else if (_splashStep > SPLASH_DURATION && !theApp._manager.needsToWait()) { _showSplash = false; if (theApp._manager.shouldShutDown()) { if (_applicationWND != NULL) { diff --git a/launchers/win32/LauncherManager.cpp b/launchers/win32/LauncherManager.cpp index a431672f2e..26ad95f7d2 100644 --- a/launchers/win32/LauncherManager.cpp +++ b/launchers/win32/LauncherManager.cpp @@ -21,11 +21,13 @@ LauncherManager::LauncherManager() { LauncherManager::~LauncherManager() { } -void LauncherManager::init(BOOL allowUpdate, BOOL continueUpdating) { +void LauncherManager::init(BOOL allowUpdate, BOOL continueUpdating, BOOL skipSplashScreen) { initLog(); int tokenPos = 0; _updateLauncherAllowed = allowUpdate; _continueUpdating = continueUpdating; + _skipSplashScreen = skipSplashScreen; + _shouldWait = !skipSplashScreen; if (_continueUpdating) { _progressOffset = CONTINUE_UPDATING_GLOBAL_OFFSET; } @@ -613,7 +615,7 @@ void LauncherManager::restartNewLauncher() { if (_willContinueUpdating) { LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart --noUpdate --continueUpdating")); } else { - LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart --noUpdate")); + LauncherUtils::launchApplication(_tempLauncherPath, _T(" --restart --noUpdate --skipSplash")); } Sleep(500); } diff --git a/launchers/win32/LauncherManager.h b/launchers/win32/LauncherManager.h index 29dd05b4e0..108327469d 100644 --- a/launchers/win32/LauncherManager.h +++ b/launchers/win32/LauncherManager.h @@ -59,7 +59,7 @@ public: }; LauncherManager(); ~LauncherManager(); - void init(BOOL allowUpdate, BOOL continueUpdating); + void init(BOOL allowUpdate, BOOL continueUpdating, BOOL skipSplashScreen); BOOL initLog(); BOOL addToLog(const CString& line); void closeLog(); @@ -90,18 +90,19 @@ public: const CString& getVersion() const { return _version; } BOOL shouldShutDown() const { return _shouldShutdown; } BOOL shouldLaunch() const { return _shouldLaunch; } - BOOL needsUpdate() { return _shouldUpdate; } - BOOL needsSelfUpdate() { return _shouldUpdateLauncher; } - BOOL needsSelfDownload() { return _shouldDownloadLauncher; } - BOOL needsUninstall() { return _shouldUninstall; } - BOOL needsInstall() { return _shouldInstall; } - BOOL needsToWait() { return _shouldWait; } - BOOL needsRestartNewLauncher() { return _shouldRestartNewLauncher; } - BOOL shouldContinueUpdating() { return _continueUpdating; } - BOOL willContinueUpdating() { return _willContinueUpdating; } + BOOL shouldSkipSplashScreen() const { return _skipSplashScreen; } + BOOL needsUpdate() const { return _shouldUpdate; } + BOOL needsSelfUpdate() const { return _shouldUpdateLauncher; } + BOOL needsSelfDownload() const { return _shouldDownloadLauncher; } + BOOL needsUninstall() const { return _shouldUninstall; } + BOOL needsInstall() const { return _shouldInstall; } + BOOL needsToWait() const { return _shouldWait; } + BOOL needsRestartNewLauncher() const { return _shouldRestartNewLauncher; } + BOOL shouldContinueUpdating() const { return _continueUpdating; } + BOOL willContinueUpdating() const { return _willContinueUpdating; } void setDisplayName(const CString& displayName) { _displayName = displayName; } - bool isLoggedIn() { return _loggedIn; } - bool hasFailed() { return _hasFailed; } + bool isLoggedIn() const { return _loggedIn; } + bool hasFailed() const { return _hasFailed; } void setFailed(bool hasFailed) { _hasFailed = hasFailed; } const CString& getLatestInterfaceURL() const { return _latestApplicationURL; } void uninstall() { _shouldUninstall = true; _shouldWait = false; }; @@ -115,7 +116,7 @@ public: void restartNewLauncher(); void onZipExtracted(ProcessType type, int size); void onFileDownloaded(ProcessType type); - float getProgress() { return _progress; } + float getProgress() const { return _progress; } void updateProgress(ProcessType processType, float progress); void onCancel(); const CString& getLauncherVersion() const { return _launcherVersion; } @@ -145,11 +146,12 @@ private: BOOL _shouldLaunch { FALSE }; BOOL _shouldWait { TRUE }; BOOL _shouldUpdateLauncher { FALSE }; - BOOL _shouldDownloadLauncher{ FALSE }; + BOOL _shouldDownloadLauncher { FALSE }; BOOL _updateLauncherAllowed { TRUE }; BOOL _shouldRestartNewLauncher { FALSE }; - BOOL _continueUpdating{ FALSE }; - BOOL _willContinueUpdating{ FALSE }; + BOOL _continueUpdating { FALSE }; + BOOL _willContinueUpdating { FALSE }; + BOOL _skipSplashScreen { FALSE }; float _progressOffset { 0.0f }; float _progress { 0.0f }; CStdioFile _logFile;