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

This commit is contained in:
danteruiz 2019-08-30 09:00:46 -07:00
commit 255c3e4334
7 changed files with 154 additions and 8 deletions

View file

@ -30,12 +30,14 @@ endif ()
# CMAKE_CURRENT_SOURCE_DIR is the parent folder here
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
set(HF_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(HF_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")
set(MACRO_DIR "${HF_CMAKE_DIR}/macros")
set(EXTERNAL_PROJECT_DIR "${HF_CMAKE_DIR}/externals")
file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake")
file(GLOB HIFI_CUSTOM_MACROS "${HF_CMAKE_DIR}/macros/*.cmake")
message("CMAKE FILEs: ${CMAKE_CURRENT_LIST_DIR} ${MACRO_DIR} ||")
foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS})
message("CMAKE FILE: ${CUSTOM_MACRO}")
include(${CUSTOM_MACRO})
endforeach()
unset(HIFI_CUSTOM_MACROS)

View file

@ -1,14 +1,50 @@
cmake_minimum_required(VERSION 3.11)
project(HQLauncher)
set(CMAKE_CXX_STANDARD_REQUIRED_ON)
include("cmake/init.cmake")
find_package(Qt5 COMPONENTS Core Gui Qml Quick QuickControls2 Network REQUIRED)
find_package(OpenGL)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
#set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include("cmake/init.cmake")
include(ExternalProject)
if (WIN32)
ExternalProject_Add(
qtlite
URL "https://hifi-public.s3.amazonaws.com/huffman/launcher/qt-lite-ssl.zip"
URL_HASH MD5=83eeba1565e5727aef11655acf893c15
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
)
ExternalProject_Get_Property(qtlite SOURCE_DIR)
ExternalProject_Get_Property(qtlite STAMP_DIR)
include("${STAMP_DIR}/download-qtlite.cmake")
include("${STAMP_DIR}/extract-qtlite.cmake")
include("${STAMP_DIR}/verify-qtlite.cmake")
message("${SOURCE_DIR}/lib/cmake")
list(APPEND CMAKE_PREFIX_PATH ${SOURCE_DIR}/lib/cmake)
set(SSL_DIR ${SOURCE_DIR}/ssl)
message("SSL dir is ${SSL_DIR}")
endif ()
find_package(Qt5 COMPONENTS Core Gui Qml Quick QuickControls2 Network REQUIRED)
find_package(OpenGL)
set(CUSTOM_LAUNCHER_QRC_PATHS "")
set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
set(RESOURCES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/resources.rcc)
@ -38,9 +74,12 @@ set(src_files
src/LauncherWindow.h
src/LauncherWindow.cpp)
set(TARGET_NAME ${PROJECT_NAME})
add_executable(${PROJECT_NAME} ${src_files})
target_link_libraries(${PROJECT_NAME} PUBLIC
#target_openssl()
target_link_libraries(${PROJECT_NAME}
Qt5::Core
Qt5::Quick
Qt5::QuickControls2
@ -51,6 +90,9 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
${OPENGL_LIBRARIES}
${plugin_libs}
wsock32 ws2_32 Winmm version imm32 dwmapi
Crypt32 Iphlpapi
"${SSL_DIR}/lib/libeay32.lib"
"${SSL_DIR}/lib/ssleay32.lib"
"${_qt5Core_install_prefix}/lib/qtpcre2.lib"
"${_qt5Core_install_prefix}/lib/qtlibpng.lib"
"${_qt5Core_install_prefix}/lib/qtfreetype.lib"

View file

@ -105,5 +105,7 @@ Item {
horizontalCenter: instruction.horizontalCenter
topMargin: 48
}
onClicked: LauncherState.login(username.text, password.text)
}
}

View file

@ -11,7 +11,7 @@ Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) {
QString resourceBinaryLocation = QGuiApplication::applicationDirPath() + "/resources.rcc";
QResource::registerResource(resourceBinaryLocation);
_launcherState = std::make_shared<LauncherState>();
_launcherState->setUIState(LauncherState::DOWNLOAD_SCREEN);
_launcherState->setUIState(LauncherState::LOGIN_SCREEN);
_launcherWindow = std::make_unique<LauncherWindow>();
_launcherWindow->rootContext()->setContextProperty("LauncherState", _launcherState.get());
_launcherWindow->setFlags(Qt::FramelessWindowHint);

View file

@ -2,12 +2,68 @@
#include <array>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QUrlQuery>
#include <QDebug>
#include <QQmlEngine>
static const std::array<QString, LauncherState::UIState::UI_STATE_NUM> QML_FILE_FOR_UI_STATE =
{ { "qrc:/qml/SplashScreen.qml", "qrc:/qml/Login.qml", "qrc:/qml/DisplayName.qml",
"qrc:/qml/Download.qml", "qrc:/qml/DownloadFinshed.qml", "qrc:/qml/Error.qml" } };
LauncherState::LauncherState() {
// TODO Show splash screen until this request is complete
auto request = new QNetworkRequest(QUrl("https://thunder.highfidelity.com/builds/api/tags/latest/?format=json"));
auto reply = _networkAccessManager.get(*request);
QObject::connect(reply, &QNetworkReply::finished, [reply, this]() {
if (reply->error()) {
qDebug() << "Error getting builds from thunder: " << reply->errorString();
} else {
qDebug() << "Builds reply has been received";
auto data = reply->readAll();
QJsonParseError parseError;
auto doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error) {
qDebug() << "Error parsing response from thunder: " << data;
} else {
auto root = doc.object();
if (!root.contains("default_tag")) {
return;
}
_latestBuilds.defaultTag = root["default_tag"].toString();
auto results = root["results"];
if (!results.isArray()) {
return;
}
for (auto result : results.toArray()) {
auto entry = result.toObject();
Build build;
build.tag = entry["name"].toString();
build.latestVersion = entry["latest_version"].toInt();
build.buildNumber = entry["build_number"].toInt();
#ifdef Q_OS_WIN
build.installerZipURL = entry["installers"].toObject()["windows"].toObject()["zip_url"].toString();
#elif defined(Q_OS_MACOS)
build.installerZipURL = entry["installers"].toObject()["mac"].toObject()["zip_url"].toString();
#else
#error "Launcher is only supported on Windows and Mac OS"
#endif
_latestBuilds.builds.push_back(build);
}
}
}
});
}
QString LauncherState::getCurrentUISource() const {
return QML_FILE_FOR_UI_STATE[getUIState()];
}
@ -31,3 +87,22 @@ void LauncherState::setLastLoginError(LastLoginError lastLoginError) {
LauncherState::LastLoginError LauncherState::getLastLoginError() const {
return _lastLoginError;
}
void LauncherState::login(QString username, QString password) {
qDebug() << "Got login: " << username << password;
auto request = new QNetworkRequest(QUrl("https://metaverse.highfidelity.com/oauth/token"));
request->setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QUrlQuery query;
query.addQueryItem("grant_type", "password");
query.addQueryItem("username", username);
query.addQueryItem("password", password);
query.addQueryItem("scope", "owner");
auto reply = _networkAccessManager.post(*request, query.toString().toUtf8());
QObject::connect(reply, &QNetworkReply::finished, [reply, this]() {
qDebug() << "Got response for login: " << reply->readAll();
});
}

View file

@ -1,11 +1,24 @@
#include <QObject>
#include <QString>
#include <QNetworkAccessManager>
struct Build {
QString tag;
int latestVersion;
int buildNumber;
QString installerZipURL;
};
struct LatestBuilds {
QString defaultTag;
std::vector<Build> builds;
};
class LauncherState : public QObject {
Q_OBJECT
public:
LauncherState() = default;
LauncherState();
~LauncherState() = default;
enum UIState {
@ -36,10 +49,18 @@ public:
void setLastLoginError(LastLoginError lastLoginError);
LastLoginError getLastLoginError() const;
// LOGIN
Q_INVOKABLE void login(QString username, QString password);
signals:
void updateSourceUrl(QString sourceUrl);
private:
QNetworkAccessManager _networkAccessManager;
LatestBuilds _latestBuilds;
UIState _uiState { SPLASH_SCREEN };
LastLoginError _lastLoginError { NONE };
};

View file

@ -2,11 +2,13 @@
#include "LauncherWindow.h"
#include "Launcher.h"
//Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
Q_IMPORT_PLUGIN(QtQuick2Plugin);
Q_IMPORT_PLUGIN(QtQuickControls2Plugin);
Q_IMPORT_PLUGIN(QtQuickTemplates2Plugin);
int main(int argc, char *argv[])
{
QString name { "HQLauncher" };
@ -14,5 +16,7 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationName(name);
Launcher launcher(argc, argv);
return launcher.exec();
}