Merge branch 'qt-launcher' of github.com:danteruiz/hifi into qt-launcher

This commit is contained in:
danteruiz 2019-10-23 14:40:49 -07:00
commit 0c81f30a3c
20 changed files with 199 additions and 142 deletions

View file

@ -66,7 +66,12 @@ if (WIN32)
list(APPEND CMAKE_PREFIX_PATH ${SOURCE_DIR}/lib/cmake) list(APPEND CMAKE_PREFIX_PATH ${SOURCE_DIR}/lib/cmake)
set(SSL_DIR ${SOURCE_DIR}/ssl) set(SSL_DIR ${SOURCE_DIR}/ssl)
set(OPENSSL_ROOT_DIR ${SSL_DIR})
message("SSL dir is ${SSL_DIR}") message("SSL dir is ${SSL_DIR}")
set(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
message("-- Found OpenSSL Libs ${OPENSSL_LIBRARIES}")
endif () endif ()
@ -220,8 +225,9 @@ if (WIN32)
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
wsock32 ws2_32 Winmm version imm32 dwmapi wsock32 ws2_32 Winmm version imm32 dwmapi
Crypt32 Iphlpapi Crypt32 Iphlpapi
"${SSL_DIR}/lib/libeay32.lib" #"${SSL_DIR}/lib/libeay32.lib"
"${SSL_DIR}/lib/ssleay32.lib" #"${SSL_DIR}/lib/ssleay32.lib"
${OPENSSL_LIBRARIES}
"${_qt5Core_install_prefix}/qml/QtQuick.2/qtquick2plugin.lib" "${_qt5Core_install_prefix}/qml/QtQuick.2/qtquick2plugin.lib"
"${_qt5Core_install_prefix}/qml/QtQuick/Controls.2/qtquickcontrols2plugin.lib" "${_qt5Core_install_prefix}/qml/QtQuick/Controls.2/qtquickcontrols2plugin.lib"
"${_qt5Core_install_prefix}/qml/QtQuick/Templates.2/qtquicktemplates2plugin.lib") "${_qt5Core_install_prefix}/qml/QtQuick/Templates.2/qtquicktemplates2plugin.lib")

View file

@ -54,7 +54,7 @@ Item {
HFTextRegular { HFTextRegular {
id: secondText id: secondText
text: "We're getting everything setup for you." text: "We're getting everything set up for you."
anchors { anchors {
top: firstText.bottom top: firstText.bottom

View file

@ -8,7 +8,7 @@ import HQLauncher 1.0
Item { Item {
id: root id: root
anchors.centerIn: parent anchors.centerIn: parent
property string titleText: "Sign-in and pick a password" property string titleText: "Sign in and pick a password"
property string usernamePlaceholder: "Username" property string usernamePlaceholder: "Username"
property string passwordPlaceholder: "Set a password (must be at least 6 characters)" property string passwordPlaceholder: "Set a password (must be at least 6 characters)"
property int marginLeft: root.width * 0.15 property int marginLeft: root.width * 0.15
@ -30,7 +30,7 @@ Item {
width: 481 width: 481
lineHeight: 35 lineHeight: 35
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
text: LauncherState.lastSignupErrorMessage.length == 0 ? root.titleText : "Uh oh." text: LauncherState.lastSignupErrorMessage.length == 0 ? root.titleText : "Uh oh"
anchors { anchors {
top: root.top top: root.top
topMargin: 29 topMargin: 29
@ -43,7 +43,7 @@ Item {
id: instruction id: instruction
width: 425 width: 425
text: "Use the email address you applied for access with." text: "Use the email address you applied for access with"
visible: LauncherState.lastSignupErrorMessage.length == 0 visible: LauncherState.lastSignupErrorMessage.length == 0
anchors { anchors {
@ -136,7 +136,7 @@ Item {
HFTextRegular { HFTextRegular {
id: displayNameText id: displayNameText
text: "This is the display name other people see in world, it can be changed at anytime, from your profile." text: "This is the display name other people see in High Fidelity. It can be changed at any time from your profile."
wrapMode: Text.Wrap wrapMode: Text.Wrap
width: 430 width: 430
@ -164,7 +164,11 @@ Item {
topMargin: 4 topMargin: 4
} }
onAccepted: LauncherState.signup(email.text, username.text, password.text, displayName.text) onAccepted: {
if (root.enabled && email.text.length > 0 && username.text.length > 0 && password.text.length > 0 && displayName.text.length > 0) {
LauncherState.signup(email.text, username.text, password.text, displayName.text);
}
}
} }
HFButton { HFButton {
@ -214,7 +218,6 @@ Item {
bottom: root.bottom bottom: root.bottom
bottomMargin: 46 bottomMargin: 46
right: displayName.right right: displayName.right
rightMargin: 30
} }
} }

View file

@ -33,10 +33,6 @@ Item {
HFTextHeader { HFTextHeader {
id: header id: header
width: 87
height: 31
text: "Uh oh." text: "Uh oh."
anchors { anchors {
@ -49,10 +45,7 @@ Item {
HFTextRegular { HFTextRegular {
id: description id: description
text: "We seem to have a problem.\nPlease restart Launcher" text: "We seem to have a problem.\n Please restart Launcher."
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors { anchors {
top: header.bottom top: header.bottom

View file

@ -21,7 +21,7 @@ Item {
} }
Item { Item {
width: 353 width: 430
height: root.height height: root.height
@ -32,9 +32,8 @@ Item {
HFTextHeader { HFTextHeader {
id: title id: title
lineHeight: 35
font.bold: true lineHeightMode: Text.FixedHeight
text: "Please Log in" text: "Please Log in"
anchors { anchors {
@ -75,6 +74,7 @@ Item {
id: username id: username
enabled: root.enabled enabled: root.enabled
width: 430
text: LauncherState.lastUsedUsername text: LauncherState.lastUsedUsername
placeholderText: "Username" placeholderText: "Username"
@ -91,7 +91,7 @@ Item {
HFTextField { HFTextField {
id: password id: password
width: 430
enabled: root.enabled enabled: root.enabled
placeholderText: "Password" placeholderText: "Password"
@ -111,7 +111,8 @@ Item {
HFTextRegular { HFTextRegular {
id: displayText id: displayText
text: "You can change this at anytime from your profile." text: "This is the display name other people see in High Fidelity. It can be changed at any time from your profile."
wrapMode: Text.Wrap
anchors { anchors {
top: password.bottom top: password.bottom
@ -124,7 +125,7 @@ Item {
HFTextField { HFTextField {
id: displayName id: displayName
width: 430
enabled: root.enabled enabled: root.enabled
placeholderText: "Display name" placeholderText: "Display name"
@ -136,12 +137,16 @@ Item {
left: parent.left left: parent.left
right: parent.right; right: parent.right;
} }
onAccepted: LauncherState.login(username.text, password.text, displayName.text) onAccepted: {
if (root.enabled && username.text.length > 0 && password.text.length > 0 && displayName.text.length > 0) {
LauncherState.login(username.text, password.text, displayName.text);
}
}
} }
HFButton { HFButton {
id: button id: button
width: 110 width: 134
enabled: root.enabled && username.text.length > 0 && password.text.length > 0 && displayName.text.length > 0 enabled: root.enabled && username.text.length > 0 && password.text.length > 0 && displayName.text.length > 0
@ -160,7 +165,7 @@ Item {
Text { Text {
id: createAccountLink id: createAccountLink
text: "Create New Account" text: "Sign up"
font.family: "Graphik" font.family: "Graphik"
font.pixelSize: 14 font.pixelSize: 14
color: "#009EE0" color: "#009EE0"
@ -190,8 +195,8 @@ Item {
right: parent.right right: parent.right
} }
} }
}
}
Component.onCompleted: { Component.onCompleted: {
root.parent.setBuildInfoState("right"); root.parent.setBuildInfoState("right");
} }

View file

@ -14,7 +14,7 @@ Button {
property int backgroundWidth: 2 property int backgroundWidth: 2
font.family: "Graphik Semibold" font.family: "Graphik Semibold"
font.pointSize: 12 font.pixelSize: 15
background: Rectangle { background: Rectangle {
implicitWidth: 100 implicitWidth: 100

View file

@ -7,7 +7,7 @@ TextField {
height: 50 height: 50
font.family: "Graphik Regular" font.family: "Graphik Regular"
font.pointSize: 10.5 font.pixelSize: 14
color: (text.length == 0 || !enabled) ? "#7e8c81" : "#000000" color: (text.length == 0 || !enabled) ? "#7e8c81" : "#000000"
property bool togglePasswordField: false property bool togglePasswordField: false

View file

@ -3,6 +3,6 @@ import QtQuick 2.1
Text { Text {
font.family: "Graphik Semibold" font.family: "Graphik Semibold"
font.pointSize: 24 font.pixelSize: 32
color: "#ffffff" color: "#ffffff"
} }

View file

@ -5,7 +5,7 @@ Text {
text: "High Fidelity" text: "High Fidelity"
font.bold: true font.bold: true
font.family: "Graphik Semibold" font.family: "Graphik Semibold"
font.pointSize: 14 font.pixelSize: 17
font.letterSpacing: -1 font.letterSpacing: -1
color: "#FFFFFF" color: "#FFFFFF"
} }

View file

@ -5,7 +5,7 @@ Text {
id: root id: root
font.family: "Graphik Regular" font.family: "Graphik Regular"
font.pointSize: 10.5 font.pixelSize: 14
color: "#C4C4C4" color: "#C4C4C4"
linkColor: color linkColor: color

View file

@ -7,8 +7,6 @@ import "HFControls"
Item { Item {
id: root id: root
width: 627
height: 540
Loader { Loader {
anchors.fill: parent anchors.fill: parent
id: loader id: loader
@ -34,8 +32,6 @@ Item {
HFTextRegular { HFTextRegular {
id: buildInfo id: buildInfo
font.pixelSize: 12
anchors { anchors {
leftMargin: 10 leftMargin: 10
rightMargin: 10 rightMargin: 10

View file

@ -20,14 +20,12 @@ void CommandlineOptions::parse(const int argc, char** argv) {
for (int index = 1; index < argc; index++) { for (int index = 1; index < argc; index++) {
std::string option = argv[index]; std::string option = argv[index];
if (isCommandlineOption(option)) { if (isCommandlineOption(option)) {
qDebug() << "adding commandline option: " << QString::fromStdString(option);
_commandlineOptions.push_back(option); _commandlineOptions.push_back(option);
} }
} }
} }
void CommandlineOptions::append(const std::string& command) { void CommandlineOptions::append(const std::string& command) {
qDebug() << "appending option: " << QString::fromStdString(command);
_commandlineOptions.push_back(command); _commandlineOptions.push_back(command);
} }

View file

@ -1,5 +1,7 @@
#include "Helper.h" #include "Helper.h"
#include "PathUtils.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QFileInfo> #include <QFileInfo>
@ -47,9 +49,9 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
break; break;
} }
QDir launcherDirectory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QDir logsDir = PathUtils::getLogsDirectory();
launcherDirectory.mkpath(launcherDirectory.absolutePath()); logsDir.mkpath(logsDir.absolutePath());
QString filename = launcherDirectory.absoluteFilePath("Log.txt"); QString filename = logsDir.absoluteFilePath("Log.txt");
QFile outFile(filename); QFile outFile(filename);
outFile.open(QIODevice::WriteOnly | QIODevice::Append); outFile.open(QIODevice::WriteOnly | QIODevice::Append);

View file

@ -33,6 +33,8 @@ Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) {
QFontDatabase::addApplicationFont(PathUtils::fontPath("Graphik-Semibold.ttf")); QFontDatabase::addApplicationFont(PathUtils::fontPath("Graphik-Semibold.ttf"));
_launcherWindow->setSource(QUrl(PathUtils::resourcePath("qml/root.qml"))); _launcherWindow->setSource(QUrl(PathUtils::resourcePath("qml/root.qml")));
_launcherWindow->setHeight(540);
_launcherWindow->setWidth(627);
_launcherWindow->setResizeMode(QQuickView::SizeRootObjectToView); _launcherWindow->setResizeMode(QQuickView::SizeRootObjectToView);
_launcherWindow->show(); _launcherWindow->show();
} }

View file

@ -2,6 +2,7 @@
#include "CommandlineOptions.h" #include "CommandlineOptions.h"
#include "Helper.h" #include "Helper.h"
#include "PathUtils.h"
#include <string> #include <string>
#include <chrono> #include <chrono>
@ -15,10 +16,11 @@
#include <QDebug> #include <QDebug>
LauncherInstaller::LauncherInstaller(const QString& applicationFilePath) { LauncherInstaller::LauncherInstaller(const QString& applicationFilePath) {
_launcherInstallDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); _launcherInstallDir = PathUtils::getLauncherDirectory();
_launcherApplicationsDir = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Launcher"; _launcherApplicationsDir = PathUtils::getApplicationsDirectory();
qDebug() << "Launcher install dir: " << _launcherInstallDir.absolutePath(); qDebug() << "Launcher install dir: " << _launcherInstallDir.absolutePath();
qDebug() << "Launcher Application dir: " << _launcherApplicationsDir.absolutePath(); qDebug() << "Launcher Application dir: " << _launcherApplicationsDir.absolutePath();
_launcherInstallDir.mkpath(_launcherInstallDir.absolutePath()); _launcherInstallDir.mkpath(_launcherInstallDir.absolutePath());
_launcherApplicationsDir.mkpath(_launcherApplicationsDir.absolutePath()); _launcherApplicationsDir.mkpath(_launcherApplicationsDir.absolutePath());
QFileInfo fileInfo(applicationFilePath); QFileInfo fileInfo(applicationFilePath);
@ -36,7 +38,7 @@ void LauncherInstaller::install() {
if (runningOutsideOfInstallDir()) { if (runningOutsideOfInstallDir()) {
qDebug() << "Installing HQ Launcher...."; qDebug() << "Installing HQ Launcher....";
uninstallOldLauncher(); uninstallOldLauncher();
QString oldLauncherPath = _launcherInstallDir.absolutePath() + "/HQ Launcher.exe"; QString oldLauncherPath = PathUtils::getLauncherFilePath();
if (QFile::exists(oldLauncherPath)) { if (QFile::exists(oldLauncherPath)) {
bool didRemove = QFile::remove(oldLauncherPath); bool didRemove = QFile::remove(oldLauncherPath);
@ -59,15 +61,15 @@ void LauncherInstaller::install() {
} }
void LauncherInstaller::createShortcuts() { void LauncherInstaller::createShortcuts() {
QString launcherPath = _launcherInstallDir.absolutePath() + "/HQ Launcher.exe"; QString launcherPath = PathUtils::getLauncherFilePath();
QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.lnk"; QString uninstallLinkPath = _launcherInstallDir.absoluteFilePath("Uninstall HQ.lnk");
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString applicationPath = _launcherApplicationsDir.absolutePath();
QString appStartLinkPath = applicationPath + "/HQ Launcher.lnk"; QDir desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString uninstallAppStartLinkPath = applicationPath + "/Uninstall HQ.lnk";
QString desktopAppLinkPath = desktopPath + "/HQ Launcher.lnk"; QString appStartLinkPath = _launcherApplicationsDir.absoluteFilePath("HQ Launcher.lnk");
QString uninstallAppStartLinkPath = _launcherApplicationsDir.absoluteFilePath("Uninstall HQ.lnk");
QString desktopAppLinkPath = desktopDir.absoluteFilePath("HQ Launcher.lnk");
createSymbolicLink((LPCSTR)launcherPath.toStdString().c_str(), (LPCSTR)uninstallLinkPath.toStdString().c_str(), createSymbolicLink((LPCSTR)launcherPath.toStdString().c_str(), (LPCSTR)uninstallLinkPath.toStdString().c_str(),
@ -136,7 +138,7 @@ void LauncherInstaller::uninstall() {
} }
return; return;
} }
QString launcherPath = _launcherInstallDir.absolutePath() + "/HQ Launcher.exe"; QString launcherPath = _launcherInstallDir.absoluteFilePath("HQ Launcher.exe");
if (QFile::exists(launcherPath)) { if (QFile::exists(launcherPath)) {
bool removed = QFile::remove(launcherPath); bool removed = QFile::remove(launcherPath);
qDebug() << "Successfully removed " << launcherPath << ": " << removed; qDebug() << "Successfully removed " << launcherPath << ": " << removed;
@ -145,58 +147,58 @@ void LauncherInstaller::uninstall() {
} }
void LauncherInstaller::deleteShortcuts() { void LauncherInstaller::deleteShortcuts() {
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QDir desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString applicationPath = _launcherApplicationsDir.absolutePath(); QString applicationPath = _launcherApplicationsDir.absolutePath();
QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.lnk"; QString uninstallLinkPath = _launcherInstallDir.absoluteFilePath("Uninstall HQ.lnk");
if (QFile::exists(uninstallLinkPath)) { if (QFile::exists(uninstallLinkPath)) {
QFile::remove(uninstallLinkPath); QFile::remove(uninstallLinkPath);
} }
QString appStartLinkPath = applicationPath + "/HQ Launcher.lnk"; QString appStartLinkPath = _launcherApplicationsDir.absoluteFilePath("HQ Launcher.lnk");
if (QFile::exists(appStartLinkPath)) { if (QFile::exists(appStartLinkPath)) {
QFile::remove(appStartLinkPath); QFile::remove(appStartLinkPath);
} }
QString uninstallAppStartLinkPath = applicationPath + "/Uninstall HQ.lnk"; QString uninstallAppStartLinkPath = _launcherApplicationsDir.absoluteFilePath("Uninstall HQ.lnk");
if (QFile::exists(uninstallAppStartLinkPath)) { if (QFile::exists(uninstallAppStartLinkPath)) {
QFile::remove(uninstallAppStartLinkPath); QFile::remove(uninstallAppStartLinkPath);
} }
QString desktopAppLinkPath = desktopPath + "/HQ Launcher.lnk"; QString desktopAppLinkPath = desktopDir.absoluteFilePath("HQ Launcher.lnk");
if (QFile::exists(desktopAppLinkPath)) { if (QFile::exists(desktopAppLinkPath)) {
QFile::remove(desktopAppLinkPath); QFile::remove(desktopAppLinkPath);
} }
} }
void LauncherInstaller::uninstallOldLauncher() { void LauncherInstaller::uninstallOldLauncher() {
QDir localAppPath = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation).value(0) + "/../../HQ"; QDir localAppDir = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation).value(0) + "/../../HQ";
QDir startAppPath = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0) + "/HQ"; QDir startAppDir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0) + "/HQ";
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QDir desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
qDebug() << localAppPath.absolutePath(); qDebug() << localAppDir.absolutePath();
qDebug() << startAppPath.absolutePath(); qDebug() << startAppDir.absolutePath();
QString desktopAppLinkPath = desktopPath + "/HQ Launcher.lnk"; QString desktopAppLinkPath = desktopDir.absoluteFilePath("HQ Launcher.lnk");
if (QFile::exists(desktopAppLinkPath)) { if (QFile::exists(desktopAppLinkPath)) {
QFile::remove(desktopAppLinkPath); QFile::remove(desktopAppLinkPath);
} }
QString uninstallLinkPath = localAppPath.absolutePath() + "/Uninstall HQ.lnk"; QString uninstallLinkPath = localAppDir.absoluteFilePath("Uninstall HQ.lnk");
if (QFile::exists(uninstallLinkPath)) { if (QFile::exists(uninstallLinkPath)) {
QFile::remove(uninstallLinkPath); QFile::remove(uninstallLinkPath);
} }
QString applicationPath = localAppPath.absolutePath() + "/HQ Launcher.exe"; QString applicationPath = localAppDir.absoluteFilePath("HQ Launcher.exe");
if (QFile::exists(applicationPath)) { if (QFile::exists(applicationPath)) {
QFile::remove(applicationPath); QFile::remove(applicationPath);
} }
QString appStartLinkPath = startAppPath.absolutePath() + "/HQ Launcher.lnk"; QString appStartLinkPath = startAppDir.absoluteFilePath("HQ Launcher.lnk");
if (QFile::exists(appStartLinkPath)) { if (QFile::exists(appStartLinkPath)) {
QFile::remove(appStartLinkPath); QFile::remove(appStartLinkPath);
} }
QString uninstallAppStartLinkPath = startAppPath.absolutePath() + "/Uninstall HQ.lnk"; QString uninstallAppStartLinkPath = startAppDir.absoluteFilePath("Uninstall HQ.lnk");
if (QFile::exists(uninstallAppStartLinkPath)) { if (QFile::exists(uninstallAppStartLinkPath)) {
QFile::remove(uninstallAppStartLinkPath); QFile::remove(uninstallAppStartLinkPath);
} }

View file

@ -23,7 +23,6 @@
#include <QThreadPool> #include <QThreadPool>
#include <QStandardPaths>
#include <QEventLoop> #include <QEventLoop>
#include <qregularexpression.h> #include <qregularexpression.h>
@ -33,6 +32,7 @@
#endif #endif
//#define BREAK_ON_ERROR //#define BREAK_ON_ERROR
//#define DEBUG_UI
const QString configHomeLocationKey { "homeLocation" }; const QString configHomeLocationKey { "homeLocation" };
const QString configLastLoginKey { "lastLogin" }; const QString configLastLoginKey { "lastLogin" };
@ -48,6 +48,7 @@ Q_INVOKABLE void LauncherState::openURLInBrowser(QString url) {
} }
void LauncherState::toggleDebugState() { void LauncherState::toggleDebugState() {
#ifdef DEBUG_UI
_isDebuggingScreens = !_isDebuggingScreens; _isDebuggingScreens = !_isDebuggingScreens;
UIState updatedUIState = getUIState(); UIState updatedUIState = getUIState();
@ -56,8 +57,10 @@ void LauncherState::toggleDebugState() {
emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource())); emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource()));
_uiState = getUIState(); _uiState = getUIState();
} }
#endif
} }
void LauncherState::gotoNextDebugScreen() { void LauncherState::gotoNextDebugScreen() {
#ifdef DEBUG_UI
if (_currentDebugScreen < (UIState::UI_STATE_NUM - 1)) { if (_currentDebugScreen < (UIState::UI_STATE_NUM - 1)) {
_currentDebugScreen = (UIState)(_currentDebugScreen + 1); _currentDebugScreen = (UIState)(_currentDebugScreen + 1);
//UIState updatedUIState = getUIState(); //UIState updatedUIState = getUIState();
@ -65,48 +68,21 @@ void LauncherState::gotoNextDebugScreen() {
emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource())); emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource()));
_uiState = getUIState(); _uiState = getUIState();
} }
#endif
} }
void LauncherState::gotoPreviousDebugScreen() { void LauncherState::gotoPreviousDebugScreen() {
#ifdef DEBUG_UI
if (_currentDebugScreen > 0) { if (_currentDebugScreen > 0) {
_currentDebugScreen = (UIState)(_currentDebugScreen - 1); _currentDebugScreen = (UIState)(_currentDebugScreen - 1);
emit uiStateChanged(); emit uiStateChanged();
emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource())); emit updateSourceUrl(PathUtils::resourcePath(getCurrentUISource()));
_uiState = getUIState(); _uiState = getUIState();
} }
}
QString LauncherState::getContentCachePath() const {
return _launcherDirectory.filePath("cache");
}
QString LauncherState::getClientDirectory() const {
return _launcherDirectory.filePath("interface_install");
}
QString LauncherState::getClientExecutablePath() const {
QDir clientDirectory = getClientDirectory();
#if defined(Q_OS_WIN)
return clientDirectory.absoluteFilePath("interface.exe");
#elif defined(Q_OS_MACOS)
return clientDirectory.absoluteFilePath("interface.app/Contents/MacOS/interface");
#endif
}
QString LauncherState::getConfigFilePath() const {
QDir clientDirectory = getClientDirectory();
return clientDirectory.absoluteFilePath("config.json");
}
QString LauncherState::getLauncherFilePath() const {
#if defined(Q_OS_WIN)
return _launcherDirectory.absoluteFilePath("launcher.exe");
#elif defined(Q_OS_MACOS)
return getBundlePath() + "/Contents/MacOS/HQ Launcher";
#endif #endif
} }
bool LauncherState::shouldDownloadContentCache() const { bool LauncherState::shouldDownloadContentCache() const {
return !_contentCacheURL.isEmpty() && !QFile::exists(getContentCachePath()); return !_contentCacheURL.isEmpty() && !QFile::exists(PathUtils::getContentCachePath());
} }
void LauncherState::setLastSignupErrorMessage(const QString& msg) { void LauncherState::setLastSignupErrorMessage(const QString& msg) {
@ -146,10 +122,10 @@ void LauncherState::ASSERT_STATE(const std::vector<ApplicationState>& states) {
} }
LauncherState::LauncherState() { LauncherState::LauncherState() {
_launcherDirectory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); _launcherDirectory = PathUtils::getLauncherDirectory();
// TODO Fix launcher directory
qDebug() << "Launcher directory: " << _launcherDirectory.absolutePath(); qDebug() << "Launcher directory: " << _launcherDirectory.absolutePath();
_launcherDirectory.mkpath(_launcherDirectory.absolutePath()); _launcherDirectory.mkpath(_launcherDirectory.absolutePath());
_launcherDirectory.mkpath(PathUtils::getDownloadDirectory().absolutePath());
requestBuilds(); requestBuilds();
} }
@ -255,7 +231,7 @@ void LauncherState::getCurrentClientVersion() {
connect(&client, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), &loop, &QEventLoop::exit, Qt::QueuedConnection); connect(&client, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), &loop, &QEventLoop::exit, Qt::QueuedConnection);
connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit, Qt::QueuedConnection); connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit, Qt::QueuedConnection);
client.start(getClientExecutablePath(), { "--version" }); client.start(PathUtils::getClientExecutablePath(), { "--version" });
loop.exec(); loop.exec();
// TODO Handle errors // TODO Handle errors
@ -273,14 +249,14 @@ void LauncherState::getCurrentClientVersion() {
qDebug() << "Current client version is: " << _currentClientVersion; qDebug() << "Current client version is: " << _currentClientVersion;
{ {
auto path = getConfigFilePath(); auto path = PathUtils::getConfigFilePath();
QFile configFile{ path }; QFile configFile{ path };
if (configFile.open(QIODevice::ReadOnly)) { if (configFile.open(QIODevice::ReadOnly)) {
QJsonDocument doc = QJsonDocument::fromJson(configFile.readAll()); QJsonDocument doc = QJsonDocument::fromJson(configFile.readAll());
auto root = doc.object(); auto root = doc.object();
_config.launcherPath = getLauncherFilePath(); _config.launcherPath = PathUtils::getLauncherFilePath();
_config.loggedIn = false; _config.loggedIn = false;
if (root.contains(configLoggedInKey)) { if (root.contains(configLoggedInKey)) {
_config.loggedIn = root[configLoggedInKey].toBool(); _config.loggedIn = root[configLoggedInKey].toBool();
@ -358,27 +334,27 @@ void LauncherState::signup(QString email, QString username, QString password, QS
auto err = signupRequest->getError(); auto err = signupRequest->getError();
if (err == SignupRequest::Error::ExistingUsername) { if (err == SignupRequest::Error::ExistingUsername) {
setLastSignupErrorMessage(_username + " is already taken - please try a different username."); setLastSignupErrorMessage(_username + " is already taken. Please try a different username.");
setApplicationState(ApplicationState::WaitingForSignup); setApplicationState(ApplicationState::WaitingForSignup);
return; return;
} else if (err == SignupRequest::Error::BadPassword) { } else if (err == SignupRequest::Error::BadPassword) {
setLastSignupErrorMessage("That's an invalid password - must be at least 6 characters."); setLastSignupErrorMessage("That's an invalid password. Must be at least 6 characters.");
setApplicationState(ApplicationState::WaitingForSignup); setApplicationState(ApplicationState::WaitingForSignup);
return; return;
} else if (err == SignupRequest::Error::BadUsername) { } else if (err == SignupRequest::Error::BadUsername) {
setLastSignupErrorMessage("That's an invalid username - please try another username."); setLastSignupErrorMessage("That's an invalid username. Please try another username.");
setApplicationState(ApplicationState::WaitingForSignup); setApplicationState(ApplicationState::WaitingForSignup);
return; return;
} else if (err == SignupRequest::Error::UserProfileAlreadyCompleted) { } else if (err == SignupRequest::Error::UserProfileAlreadyCompleted) {
setLastSignupErrorMessage("This email exists, if it's yours please <b><a href='login'>login</a></b>."); setLastSignupErrorMessage("An account with this email already exists. Please <b><a href='login'>log in</a></b>.");
setApplicationState(ApplicationState::WaitingForSignup); setApplicationState(ApplicationState::WaitingForSignup);
return; return;
} else if (err == SignupRequest::Error::NoSuchEmail) { } else if (err == SignupRequest::Error::NoSuchEmail) {
setLastSignupErrorMessage("That email isn't setup yet. <a href='https://www.highfidelity.com/hq-support'>Request Access</a>."); setLastSignupErrorMessage("That email isn't setup yet. <a href='https://www.highfidelity.com/hq-support'>Request access</a>.");
setApplicationState(ApplicationState::WaitingForSignup); setApplicationState(ApplicationState::WaitingForSignup);
return; return;
} else if (err != SignupRequest::Error::None) { } else if (err != SignupRequest::Error::None) {
setApplicationStateError("Failed to sign up"); setApplicationStateError("Failed to sign up. Please try again.");
return; return;
} }
@ -397,11 +373,11 @@ void LauncherState::signup(QString email, QString username, QString password, QS
auto err = loginRequest->getError(); auto err = loginRequest->getError();
if (err == LoginRequest::Error::BadUsernameOrPassword) { if (err == LoginRequest::Error::BadUsernameOrPassword) {
setLastLoginErrorMessage("Bad username or password"); setLastLoginErrorMessage("Invalid username or password.");
setApplicationState(ApplicationState::WaitingForLogin); setApplicationState(ApplicationState::WaitingForLogin);
return; return;
} else if (err != LoginRequest::Error::None) { } else if (err != LoginRequest::Error::None) {
setApplicationStateError("Failed to login"); setApplicationStateError("Failed to login. Please try again.");
return; return;
} }
@ -436,11 +412,11 @@ void LauncherState::login(QString username, QString password, QString displayNam
auto err = request->getError(); auto err = request->getError();
if (err == LoginRequest::Error::BadUsernameOrPassword) { if (err == LoginRequest::Error::BadUsernameOrPassword) {
setLastLoginErrorMessage("Bad username or password"); setLastLoginErrorMessage("Invalid username or password");
setApplicationState(ApplicationState::WaitingForLogin); setApplicationState(ApplicationState::WaitingForLogin);
return; return;
} else if (err != LoginRequest::Error::None) { } else if (err != LoginRequest::Error::None) {
setApplicationStateError("Failed to login"); setApplicationStateError("Failed to login. Please try again.");
return; return;
} }
@ -509,7 +485,8 @@ void LauncherState::downloadClient() {
auto request = new QNetworkRequest(QUrl(build.installerZipURL)); auto request = new QNetworkRequest(QUrl(build.installerZipURL));
auto reply = _networkAccessManager.get(*request); auto reply = _networkAccessManager.get(*request);
_clientZipFile.setFileName(_launcherDirectory.absoluteFilePath("client.zip")); QDir downloadDir{ PathUtils::getDownloadDirectory() };
_clientZipFile.setFileName(downloadDir.absoluteFilePath("client.zip"));
qDebug() << "Opening " << _clientZipFile.fileName(); qDebug() << "Opening " << _clientZipFile.fileName();
if (!_clientZipFile.open(QIODevice::WriteOnly)) { if (!_clientZipFile.open(QIODevice::WriteOnly)) {
@ -566,15 +543,18 @@ void LauncherState::installClient() {
ASSERT_STATE(ApplicationState::DownloadingClient); ASSERT_STATE(ApplicationState::DownloadingClient);
setApplicationState(ApplicationState::InstallingClient); setApplicationState(ApplicationState::InstallingClient);
_launcherDirectory.rmpath("interface_install");
_launcherDirectory.mkpath("interface_install"); auto clientDir = PathUtils::getClientDirectory();
auto installDir = _launcherDirectory.absoluteFilePath("interface_install");
auto clientPath = clientDir.absolutePath();
_launcherDirectory.rmpath(clientPath);
_launcherDirectory.mkpath(clientPath);
_interfaceInstallProgress = 0; _interfaceInstallProgress = 0;
qDebug() << "Unzipping " << _clientZipFile.fileName() << " to " << installDir; qDebug() << "Unzipping " << _clientZipFile.fileName() << " to " << clientDir.absolutePath();
auto unzipper = new Unzipper(_clientZipFile.fileName(), QDir(installDir)); auto unzipper = new Unzipper(_clientZipFile.fileName(), clientDir);
unzipper->setAutoDelete(true); unzipper->setAutoDelete(true);
connect(unzipper, &Unzipper::progress, this, [this](float progress) { connect(unzipper, &Unzipper::progress, this, [this](float progress) {
_interfaceInstallProgress = progress; _interfaceInstallProgress = progress;
@ -666,7 +646,8 @@ void LauncherState::downloadContentCache() {
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
auto reply = _networkAccessManager.get(request); auto reply = _networkAccessManager.get(request);
_contentZipFile.setFileName(_launcherDirectory.absoluteFilePath("content_cache.zip")); QDir downloadDir{ PathUtils::getDownloadDirectory() };
_contentZipFile.setFileName(downloadDir.absoluteFilePath("content_cache.zip"));
qDebug() << "Opening " << _contentZipFile.fileName(); qDebug() << "Opening " << _contentZipFile.fileName();
if (!_contentZipFile.open(QIODevice::WriteOnly)) { if (!_contentZipFile.open(QIODevice::WriteOnly)) {
@ -692,6 +673,8 @@ void LauncherState::contentCacheDownloadComplete() {
if (reply->error()) { if (reply->error()) {
qDebug() << "Error downloading content cache: " << reply->error() << reply->readAll(); qDebug() << "Error downloading content cache: " << reply->error() << reply->readAll();
qDebug() << "Continuing to launch client"; qDebug() << "Continuing to launch client";
_contentDownloadProgress = 100.0f;
_contentInstallProgress = 100.0f;
launchClient(); launchClient();
return; return;
} }
@ -713,7 +696,7 @@ void LauncherState::installContentCache() {
ASSERT_STATE(ApplicationState::DownloadingContentCache); ASSERT_STATE(ApplicationState::DownloadingContentCache);
setApplicationState(ApplicationState::InstallingContentCache); setApplicationState(ApplicationState::InstallingContentCache);
auto installDir = getContentCachePath(); auto installDir = PathUtils::getContentCachePath();
qDebug() << "Unzipping " << _contentZipFile.fileName() << " to " << installDir; qDebug() << "Unzipping " << _contentZipFile.fileName() << " to " << installDir;
@ -750,15 +733,10 @@ void LauncherState::launchClient() {
setApplicationState(ApplicationState::LaunchingHighFidelity); setApplicationState(ApplicationState::LaunchingHighFidelity);
QDir installDirectory = _launcherDirectory.filePath("interface_install"); QDir installDirectory = PathUtils::getClientDirectory();
QString clientPath; QString clientPath = PathUtils::getClientExecutablePath();
#if defined(Q_OS_WIN)
clientPath = installDirectory.absoluteFilePath("interface.exe");
#elif defined(Q_OS_MACOS)
clientPath = installDirectory.absoluteFilePath("interface.app/Contents/MacOS/interface");
#endif
auto path = getConfigFilePath(); auto path = PathUtils::getConfigFilePath();
QFile configFile{ path }; QFile configFile{ path };
if (configFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) { if (configFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
QJsonDocument doc = QJsonDocument::fromJson(configFile.readAll()); QJsonDocument doc = QJsonDocument::fromJson(configFile.readAll());
@ -766,7 +744,7 @@ void LauncherState::launchClient() {
{ configHomeLocationKey, _config.homeLocation }, { configHomeLocationKey, _config.homeLocation },
{ configLastLoginKey, _config.lastLogin }, { configLastLoginKey, _config.lastLogin },
{ configLoggedInKey, _config.loggedIn }, { configLoggedInKey, _config.loggedIn },
{ configLauncherPathKey, getLauncherFilePath() }, { configLauncherPathKey, PathUtils::getLauncherFilePath() },
}); });
qint64 result = configFile.write(doc.toJson()); qint64 result = configFile.write(doc.toJson());
configFile.close(); configFile.close();

View file

@ -155,12 +155,6 @@ private:
bool shouldDownloadContentCache() const; bool shouldDownloadContentCache() const;
void getCurrentClientVersion(); void getCurrentClientVersion();
QString getContentCachePath() const;
QString getClientDirectory() const;
QString getClientExecutablePath() const;
QString getConfigFilePath() const;
QString getLauncherFilePath() const;
float calculateDownloadProgress() const; float calculateDownloadProgress() const;
bool shouldDownloadLauncher(); bool shouldDownloadLauncher();

View file

@ -1,6 +1,10 @@
#include "PathUtils.h" #include "PathUtils.h"
#include "Helper.h"
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QStandardPaths>
QUrl PathUtils::resourcePath(const QString& source) { QUrl PathUtils::resourcePath(const QString& source) {
QString filePath = RESOURCE_PREFIX_URL + source; QString filePath = RESOURCE_PREFIX_URL + source;
@ -18,3 +22,56 @@ QString PathUtils::fontPath(const QString& fontName) {
return ":/fonts/" + fontName; return ":/fonts/" + fontName;
#endif #endif
} }
QDir PathUtils::getLauncherDirectory() {
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
}
QDir PathUtils::getApplicationsDirectory() {
return QDir(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)).absoluteFilePath("Launcher");
}
// The client directory is where interface is installed to.
QDir PathUtils::getClientDirectory() {
return getLauncherDirectory().filePath("client");
}
QDir PathUtils::getLogsDirectory() {
return getLauncherDirectory().filePath("logs");
}
// The download directory is used to store files downloaded during installation.
QDir PathUtils::getDownloadDirectory() {
return getLauncherDirectory().filePath("downloads");
}
// The content cache path is the directory interface uses for caching data.
// It is pre-populated on startup with domain content.
QString PathUtils::getContentCachePath() {
return getLauncherDirectory().filePath("contentcache");
}
// The path to the interface binary.
QString PathUtils::getClientExecutablePath() {
QDir clientDirectory = getClientDirectory();
#if defined(Q_OS_WIN)
return clientDirectory.absoluteFilePath("interface.exe");
#elif defined(Q_OS_MACOS)
return clientDirectory.absoluteFilePath("interface.app/Contents/MacOS/interface");
#endif
}
// The path to the config.json file that the launcher uses to store information like
// the last user that logged in.
QString PathUtils::getConfigFilePath() {
return getClientDirectory().absoluteFilePath("config.json");
}
// The path to the launcher binary.
QString PathUtils::getLauncherFilePath() {
#if defined(Q_OS_WIN)
return getLauncherDirectory().absoluteFilePath("HQ Launcher.exe");
#elif defined(Q_OS_MACOS)
return getBundlePath() + "/Contents/MacOS/HQ Launcher";
#endif
}

View file

@ -1,14 +1,28 @@
#pragma once #pragma once
#include <QDir>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QFile> #include <QFile>
#include <QUrl> #include <QUrl>
class PathUtils : public QObject { class PathUtils : public QObject {
Q_OBJECT Q_OBJECT
public: public:
PathUtils() = default; PathUtils() = default;
~PathUtils() = default; ~PathUtils() = default;
Q_INVOKABLE static QUrl resourcePath(const QString& source); Q_INVOKABLE static QUrl resourcePath(const QString& source);
QString static fontPath(const QString& fontName);
static QString fontPath(const QString& fontName);
static QDir getLauncherDirectory();
static QDir getApplicationsDirectory();
static QDir getDownloadDirectory();
static QDir getClientDirectory();
static QDir getLogsDirectory();
static QString getContentCachePath();
static QString getClientExecutablePath();
static QString getConfigFilePath();
static QString getLauncherFilePath();
}; };

View file

@ -30,16 +30,17 @@ bool hasSuffix(const std::string& path, const std::string& suffix) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QString name { "High Fidelity" };
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setOrganizationName(name); QCoreApplication::setOrganizationName("High Fidelity");
QCoreApplication::setApplicationName("Launcher"); QCoreApplication::setApplicationName("Launcher");
Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(resources);
cleanLogFile(); cleanLogFile();
qInstallMessageHandler(messageHandler); qInstallMessageHandler(messageHandler);
CommandlineOptions* options = CommandlineOptions::getInstance(); CommandlineOptions* options = CommandlineOptions::getInstance();
options->parse(argc, argv); options->parse(argc, argv);
bool didUpdate = false; bool didUpdate = false;
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
if (isLauncherAlreadyRunning()) { if (isLauncherAlreadyRunning()) {
return 0; return 0;
@ -48,7 +49,7 @@ int main(int argc, char *argv[]) {
if (argc == 3) { if (argc == 3) {
if (hasSuffix(argv[1], "app") && hasSuffix(argv[2], "app")) { if (hasSuffix(argv[1], "app") && hasSuffix(argv[2], "app")) {
bool success = swapLaunchers(argv[1], argv[2]); bool success = swapLaunchers(argv[1], argv[2]);
qDebug() << "Launcher install success: " << success; qDebug() << "Successfully installed Launcher: " << success;
if (!success) { if (!success) {
options->append("--noUpdate"); options->append("--noUpdate");
} }
@ -56,6 +57,12 @@ int main(int argc, char *argv[]) {
} }
} }
#endif #endif
if (options->contains("--version")) {
std::cout << LAUNCHER_BUILD_VERSION << std::endl;
return 0;
}
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
LauncherInstaller launcherInstaller(argv[0]); LauncherInstaller launcherInstaller(argv[0]);
if (options->contains("--uninstall") || options->contains("--resumeUninstall")) { if (options->contains("--uninstall") || options->contains("--resumeUninstall")) {
@ -69,7 +76,6 @@ int main(int argc, char *argv[]) {
if (isProcessRunning("interface.exe", interfacePID)) { if (isProcessRunning("interface.exe", interfacePID)) {
shutdownProcess(interfacePID, 0); shutdownProcess(interfacePID, 0);
} }
#endif #endif
QProcessEnvironment processEnvironment = QProcessEnvironment::systemEnvironment(); QProcessEnvironment processEnvironment = QProcessEnvironment::systemEnvironment();
@ -78,6 +84,7 @@ int main(int argc, char *argv[]) {
options->append("--noUpdate"); options->append("--noUpdate");
} }
} }
Launcher launcher(argc, argv); Launcher launcher(argc, argv);
return launcher.exec(); return launcher.exec();
} }