mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 04:43:31 +02:00
Add signup to qt launcher, and cleanup
This commit is contained in:
parent
6db88dae3c
commit
e81deff4e9
15 changed files with 575 additions and 153 deletions
|
@ -127,8 +127,14 @@ set(src_files
|
||||||
src/LauncherState.cpp
|
src/LauncherState.cpp
|
||||||
src/LauncherWindow.h
|
src/LauncherWindow.h
|
||||||
src/LauncherWindow.cpp
|
src/LauncherWindow.cpp
|
||||||
src/PathUtils.cpp
|
src/LoginRequest.h
|
||||||
|
src/LoginRequest.cpp
|
||||||
|
src/SignupRequest.h
|
||||||
|
src/SignupRequest.cpp
|
||||||
|
src/UserSettingsRequest.h
|
||||||
|
src/UserSettingsRequest.cpp
|
||||||
src/PathUtils.h
|
src/PathUtils.h
|
||||||
|
src/PathUtils.cpp
|
||||||
src/Unzipper.h
|
src/Unzipper.h
|
||||||
src/Unzipper.cpp
|
src/Unzipper.cpp
|
||||||
src/Helper.h
|
src/Helper.h
|
||||||
|
@ -159,7 +165,7 @@ set(TARGET_NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
set_packaging_parameters()
|
set_packaging_parameters()
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_executable(${PROJECT_NAME} ${src_files} build/resources.qrc)
|
add_executable(${PROJECT_NAME} ${src_files} ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
set_target_properties(${this_target} PROPERTIES
|
set_target_properties(${this_target} PROPERTIES
|
||||||
MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in)
|
MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in)
|
||||||
|
|
|
@ -47,7 +47,7 @@ Item {
|
||||||
font.family: "Graphik"
|
font.family: "Graphik"
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
color: "#C4C4C4"
|
color: "#C4C4C4"
|
||||||
text: "Use the email address that you regisetered with."
|
text: "Use the email address that you regisetered with. " + LauncherState.lastSignupError
|
||||||
anchors {
|
anchors {
|
||||||
left: root.left
|
left: root.left
|
||||||
leftMargin: root.marginLeft
|
leftMargin: root.marginLeft
|
||||||
|
@ -57,7 +57,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
HFTextField {
|
HFTextField {
|
||||||
id: organization
|
id: email
|
||||||
width: 430
|
width: 430
|
||||||
height: 50
|
height: 50
|
||||||
font.family: "Graphik"
|
font.family: "Graphik"
|
||||||
|
@ -83,7 +83,7 @@ Item {
|
||||||
color: "#7e8c81"
|
color: "#7e8c81"
|
||||||
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
|
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
|
||||||
anchors {
|
anchors {
|
||||||
top: organization.bottom
|
top: email.bottom
|
||||||
left: root.left
|
left: root.left
|
||||||
leftMargin: root.marginLeft
|
leftMargin: root.marginLeft
|
||||||
topMargin: 18
|
topMargin: 18
|
||||||
|
@ -157,7 +157,7 @@ Item {
|
||||||
topMargin: 21
|
topMargin: 21
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: LauncherState.login(username.text, passwordField.text)
|
onClicked: LauncherState.signup(email.text, username.text, passwordField.text, displayName.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ Item {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("clicked");
|
console.log("clicked");
|
||||||
root.parent.source = PathUtils.resourcePath("qml/Login.qml");
|
LauncherState.gotoLogin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,6 @@ Item {
|
||||||
placeholderText: "Display name"
|
placeholderText: "Display name"
|
||||||
color: "#7E8C81"
|
color: "#7E8C81"
|
||||||
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
|
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
|
||||||
echoMode: TextInput.Password
|
|
||||||
anchors {
|
anchors {
|
||||||
top: displayText.bottom
|
top: displayText.bottom
|
||||||
horizontalCenter: instruction.horizontalCenter
|
horizontalCenter: instruction.horizontalCenter
|
||||||
|
@ -132,7 +131,7 @@ Item {
|
||||||
topMargin: 25
|
topMargin: 25
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: LauncherState.login(username.text, password.text)
|
onClicked: LauncherState.login(username.text, password.text, displayName.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@ -155,7 +154,7 @@ Item {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("clicked");
|
console.log("clicked");
|
||||||
root.parent.source = PathUtils.resourcePath("qml/Login.qml");
|
LauncherState.gotoSignup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,3 +25,47 @@ void swapLaunchers(const QString& oldLauncherPath, const QString& newLauncherPat
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString getHTTPUserAgent() {
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
return "HQLauncher/fixme (Windows)";
|
||||||
|
#elif defined(Q_OS_MACOS)
|
||||||
|
return "HQLauncher/fixme (MacOS)";
|
||||||
|
#else
|
||||||
|
#error Unsupported platform
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& getInterfaceSharedMemoryName() {
|
||||||
|
static const QString applicationName = "High Fidelity Interface - " + qgetenv("USERNAME");
|
||||||
|
return applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#ifdef Q_OS_WIN
|
||||||
|
//#include <Windows.h>
|
||||||
|
//#include <tlhelp32.h>
|
||||||
|
//#include <wincrypt.h>
|
||||||
|
//#include <tlhelp32.h>
|
||||||
|
//#include <strsafe.h>
|
||||||
|
//#include <winhttp.h>
|
||||||
|
//
|
||||||
|
//bool isProcessRunning(const wchar_t *processName, int& processID) {
|
||||||
|
// bool exists = false;
|
||||||
|
// PROCESSENTRY32 entry;
|
||||||
|
// entry.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
//
|
||||||
|
// HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||||
|
//
|
||||||
|
// if (Process32First(snapshot, &entry)) {
|
||||||
|
// while (Process32Next(snapshot, &entry)) {
|
||||||
|
// if (!_wcsicmp(entry.szExeFile, processName)) {
|
||||||
|
// exists = true;
|
||||||
|
// processID = entry.th32ProcessID;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// CloseHandle(snapshot);
|
||||||
|
// return exists;
|
||||||
|
//}
|
||||||
|
//#endif
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
//#define USE_STAGING
|
||||||
|
|
||||||
|
#ifdef USE_STAGING
|
||||||
|
const QString METAVERSE_API_DOMAIN{ "https://staging.highfidelity.com" };
|
||||||
|
#else
|
||||||
|
const QString METAVERSE_API_DOMAIN{ "https://metaverse.highfidelity.com" };
|
||||||
|
#endif
|
||||||
|
|
||||||
void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptOverride,
|
void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptOverride,
|
||||||
const QString& displayName, const QString& contentCachePath, QString loginResponseToken = QString());
|
const QString& displayName, const QString& contentCachePath, QString loginResponseToken = QString());
|
||||||
|
|
||||||
|
@ -11,3 +19,11 @@ void swapLaunchers(const QString& oldLauncherPath = QString(), const QString& ne
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory);
|
bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString getHTTPUserAgent();
|
||||||
|
|
||||||
|
const QString& getInterfaceSharedMemoryName();
|
||||||
|
|
||||||
|
//#ifdef Q_OS_WIN
|
||||||
|
//bool isProcessRunning(const wchar_t *processName, int& processID) {
|
||||||
|
//#endif
|
||||||
|
|
|
@ -9,7 +9,7 @@ void launchClient(const QString& clientPath, const QString& homePath, const QStr
|
||||||
// TODO Fix parameters
|
// TODO Fix parameters
|
||||||
QString params = "--url \"" + homePath + "\""
|
QString params = "--url \"" + homePath + "\""
|
||||||
+ " --setBookmark \"hqhome=" + homePath + "\""
|
+ " --setBookmark \"hqhome=" + homePath + "\""
|
||||||
+ " --defaultScriptsOverride \"" + defaultScriptsPath + "\""
|
+ " --defaultScriptsOverride \"file:///" + defaultScriptsPath + "\""
|
||||||
+ " --displayName \"" + displayName + "\""
|
+ " --displayName \"" + displayName + "\""
|
||||||
+ " --cache \"" + contentCachePath + "\"";
|
+ " --cache \"" + contentCachePath + "\"";
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
#include <qregularexpression.h>
|
#include <qregularexpression.h>
|
||||||
|
|
||||||
const QString METAVERSE_API_URL{ "https://metaverse.highfidelity.com" };
|
|
||||||
const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization";
|
|
||||||
|
|
||||||
QString LauncherState::getContentCachePath() const {
|
QString LauncherState::getContentCachePath() const {
|
||||||
return _launcherDirectory.filePath("cache");
|
return _launcherDirectory.filePath("cache");
|
||||||
|
@ -70,7 +68,7 @@ bool LatestBuilds::getBuild(QString tag, Build* outBuild) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::array<QString, LauncherState::UIState::UI_STATE_NUM> QML_FILE_FOR_UI_STATE =
|
static const std::array<QString, LauncherState::UIState::UI_STATE_NUM> QML_FILE_FOR_UI_STATE =
|
||||||
{ { "SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "DisplayName.qml",
|
{ { "SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "qml/HFBase/LoginBase.qml", "DisplayName.qml",
|
||||||
"qml/Download.qml", "qml/DownloadFinished.qml", "qml/HFBase/Error.qml" } };
|
"qml/Download.qml", "qml/DownloadFinished.qml", "qml/HFBase/Error.qml" } };
|
||||||
|
|
||||||
void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) {
|
void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) {
|
||||||
|
@ -82,7 +80,7 @@ void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherState::ASSERT_STATE(std::vector<LauncherState::ApplicationState> states) {
|
void LauncherState::ASSERT_STATE(const std::vector<LauncherState::ApplicationState>& states) {
|
||||||
for (auto state : states) {
|
for (auto state : states) {
|
||||||
if (_applicationState == state) {
|
if (_applicationState == state) {
|
||||||
return;
|
return;
|
||||||
|
@ -120,6 +118,9 @@ LauncherState::UIState LauncherState::getUIState() const {
|
||||||
case ApplicationState::WaitingForLogin:
|
case ApplicationState::WaitingForLogin:
|
||||||
case ApplicationState::RequestingLogin:
|
case ApplicationState::RequestingLogin:
|
||||||
return LOGIN_SCREEN;
|
return LOGIN_SCREEN;
|
||||||
|
case ApplicationState::WaitingForSignup:
|
||||||
|
case ApplicationState::RequestingSignup:
|
||||||
|
return SIGNUP_SCREEN;
|
||||||
case ApplicationState::DownloadingClient:
|
case ApplicationState::DownloadingClient:
|
||||||
case ApplicationState::InstallingClient:
|
case ApplicationState::InstallingClient:
|
||||||
case ApplicationState::DownloadingContentCache:
|
case ApplicationState::DownloadingContentCache:
|
||||||
|
@ -240,33 +241,11 @@ void LauncherState::getCurrentClientVersion() {
|
||||||
QProcess client;
|
QProcess client;
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
|
|
||||||
//connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit);
|
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);
|
connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit, Qt::QueuedConnection);
|
||||||
/*
|
|
||||||
connect(&client, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [&]() {
|
|
||||||
qDebug() << "Finished";
|
|
||||||
});
|
|
||||||
connect(&client, &QProcess::errorOccurred, [&](QProcess::ProcessError err) {
|
|
||||||
qDebug() << "Error occurred" << err << client.error();
|
|
||||||
});
|
|
||||||
connect(&client, &QProcess::started, [&]() {
|
|
||||||
qDebug() << "Started";
|
|
||||||
});
|
|
||||||
connect(&client, &QProcess::stateChanged, [&]() {
|
|
||||||
qDebug() << "State changed " << client.state();
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
//qDebug() << "Starting client";
|
|
||||||
client.start(getClientExecutablePath(), { "--version" });
|
client.start(getClientExecutablePath(), { "--version" });
|
||||||
//qDebug() << "Started" << client.error();
|
loop.exec();
|
||||||
|
|
||||||
if (client.state() != QProcess::NotRunning) {
|
|
||||||
//qDebug() << "Starting loop";
|
|
||||||
loop.exec();
|
|
||||||
} else {
|
|
||||||
qDebug() << "Not waiting for client, there was an error starting it: " << client.error();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Handle errors
|
// TODO Handle errors
|
||||||
auto output = client.readAllStandardOutput();
|
auto output = client.readAllStandardOutput();
|
||||||
|
@ -282,132 +261,140 @@ void LauncherState::getCurrentClientVersion() {
|
||||||
}
|
}
|
||||||
qDebug() << "Current client version is: " << _currentClientVersion;
|
qDebug() << "Current client version is: " << _currentClientVersion;
|
||||||
|
|
||||||
setApplicationState(ApplicationState::WaitingForLogin);
|
setApplicationState(ApplicationState::WaitingForSignup);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getUserAgent() {
|
|
||||||
#if defined(Q_OS_WIN)
|
void LauncherState::gotoSignup() {
|
||||||
return "HQLauncher/fixme (Windows)";
|
if (_applicationState == ApplicationState::WaitingForLogin) {
|
||||||
#elif defined(Q_OS_MACOS)
|
setApplicationState(ApplicationState::WaitingForSignup);
|
||||||
return "HQLauncher/fixme (MacOS)";
|
} else {
|
||||||
#else
|
qDebug() << "Error, can't switch to signup page, current state is: " << _applicationState;
|
||||||
#error Unsupported platform
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherState::login(QString username, QString password) {
|
void LauncherState::gotoLogin() {
|
||||||
|
if (_applicationState == ApplicationState::WaitingForSignup) {
|
||||||
|
setApplicationState(ApplicationState::WaitingForLogin);
|
||||||
|
} else {
|
||||||
|
qDebug() << "Error, can't switch to signup page, current state is: " << _applicationState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherState::signup(QString email, QString username, QString password, QString displayName) {
|
||||||
|
ASSERT_STATE(ApplicationState::WaitingForSignup);
|
||||||
|
|
||||||
|
_username = username;
|
||||||
|
_password = password;
|
||||||
|
|
||||||
|
setApplicationState(ApplicationState::RequestingSignup);
|
||||||
|
|
||||||
|
auto signupRequest = new SignupRequest();
|
||||||
|
|
||||||
|
_displayName = displayName;
|
||||||
|
|
||||||
|
{
|
||||||
|
_lastSignupError = SignupRequest::Error::None;
|
||||||
|
emit lastSignupErrorChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(signupRequest, &SignupRequest::finished, this, [this, signupRequest] {
|
||||||
|
signupRequest->deleteLater();
|
||||||
|
|
||||||
|
|
||||||
|
_lastSignupError = signupRequest->getError();
|
||||||
|
emit lastSignupErrorChanged();
|
||||||
|
|
||||||
|
if (_lastSignupError != SignupRequest::Error::None) {
|
||||||
|
setApplicationStateError("Failed to sign up");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setApplicationState(ApplicationState::RequestingLoginAfterSignup);
|
||||||
|
|
||||||
|
// After successfully signing up, attempt to login
|
||||||
|
auto loginRequest = new LoginRequest();
|
||||||
|
|
||||||
|
connect(loginRequest, &LoginRequest::finished, this, [this, loginRequest]() {
|
||||||
|
ASSERT_STATE(ApplicationState::RequestingLoginAfterSignup);
|
||||||
|
|
||||||
|
loginRequest->deleteLater();
|
||||||
|
|
||||||
|
auto err = loginRequest->getError();
|
||||||
|
if (err != LoginRequest::Error::None) {
|
||||||
|
setApplicationStateError("Failed to login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_loginResponse = loginRequest->getToken();
|
||||||
|
_loginTokenResponse = loginRequest->getRawToken();
|
||||||
|
|
||||||
|
requestSettings();
|
||||||
|
});
|
||||||
|
|
||||||
|
setApplicationState(ApplicationState::RequestingLoginAfterSignup);
|
||||||
|
loginRequest->send(_networkAccessManager, _username, _password);
|
||||||
|
});
|
||||||
|
signupRequest->send(_networkAccessManager, email, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LauncherState::login(QString username, QString password, QString displayName) {
|
||||||
ASSERT_STATE(ApplicationState::WaitingForLogin);
|
ASSERT_STATE(ApplicationState::WaitingForLogin);
|
||||||
|
|
||||||
setApplicationState(ApplicationState::RequestingLogin);
|
setApplicationState(ApplicationState::RequestingLogin);
|
||||||
|
|
||||||
|
_displayName = displayName;
|
||||||
|
|
||||||
qDebug() << "Got login: " << username << password;
|
qDebug() << "Got login: " << username << password;
|
||||||
|
|
||||||
auto request = new QNetworkRequest(QUrl(METAVERSE_API_URL + "/oauth/token"));
|
auto request = new LoginRequest();
|
||||||
|
|
||||||
request->setHeader(QNetworkRequest::UserAgentHeader, getUserAgent());
|
connect(request, &LoginRequest::finished, this, [this, request]() {
|
||||||
request->setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
ASSERT_STATE(ApplicationState::RequestingLogin);
|
||||||
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());
|
request->deleteLater();
|
||||||
QObject::connect(reply, &QNetworkReply::finished, this, &LauncherState::receivedLoginReply);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_INVOKABLE void LauncherState::receivedLoginReply() {
|
auto err = request->getError();
|
||||||
ASSERT_STATE(ApplicationState::RequestingLogin);
|
if (err != LoginRequest::Error::None) {
|
||||||
|
setApplicationStateError("Failed to login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Check for errors
|
_loginResponse = request->getToken();
|
||||||
auto reply = static_cast<QNetworkReply*>(sender());
|
_loginTokenResponse = request->getRawToken();
|
||||||
|
|
||||||
if (reply->error()) {
|
requestSettings();
|
||||||
setApplicationState(ApplicationState::UnexpectedError);
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = reply->readAll();
|
request->send(_networkAccessManager, username, password);
|
||||||
QJsonParseError parseError;
|
|
||||||
auto doc = QJsonDocument::fromJson(data, &parseError);
|
|
||||||
auto root = doc.object();
|
|
||||||
|
|
||||||
if (!root.contains("access_token")
|
|
||||||
|| !root.contains("token_type")
|
|
||||||
|| !root.contains("expires_in")
|
|
||||||
|| !root.contains("refresh_token")
|
|
||||||
|| !root.contains("scope")
|
|
||||||
|| !root.contains("created_at")) {
|
|
||||||
|
|
||||||
setApplicationState(ApplicationState::UnexpectedError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_loginResponse.accessToken = root["access_token"].toString();
|
|
||||||
_loginResponse.refreshToken = root["refresh_token"].toString();
|
|
||||||
_loginResponse.tokenType = root["token_type"].toString();
|
|
||||||
|
|
||||||
qDebug() << "Got response for login: " << data;
|
|
||||||
_loginTokenResponse = data;
|
|
||||||
|
|
||||||
requestSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherState::requestSettings() {
|
void LauncherState::requestSettings() {
|
||||||
// TODO Request settings if already logged in
|
// TODO Request settings if already logged in
|
||||||
|
qDebug() << "Requesting settings";
|
||||||
|
|
||||||
QUrl lockerURL = METAVERSE_API_URL;
|
auto request = new UserSettingsRequest();
|
||||||
lockerURL.setPath("/api/v1/user/locker");
|
|
||||||
|
|
||||||
auto lockerRequest = new QNetworkRequest(lockerURL);
|
connect(request, &UserSettingsRequest::finished, this, [this, request]() {
|
||||||
lockerRequest->setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
auto userSettings = request->getUserSettings();
|
||||||
lockerRequest->setHeader(QNetworkRequest::UserAgentHeader, getUserAgent());
|
if (userSettings.homeLocation.isEmpty()) {
|
||||||
lockerRequest->setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, QString("Bearer %1").arg(_loginResponse.accessToken).toUtf8());
|
_homeLocation = "hifi://hq";
|
||||||
|
_contentCacheURL = "";
|
||||||
QNetworkReply* lockerReply = _networkAccessManager.get(*lockerRequest);
|
} else {
|
||||||
connect(lockerReply, &QNetworkReply::finished, this, &LauncherState::receivedSettingsReply);
|
_homeLocation = userSettings.homeLocation;
|
||||||
}
|
|
||||||
|
|
||||||
void LauncherState::receivedSettingsReply() {
|
|
||||||
auto reply = static_cast<QNetworkReply*>(sender());
|
|
||||||
qDebug() << "Got reply: " << reply->error();
|
|
||||||
if (reply->error()) {
|
|
||||||
setApplicationState(ApplicationState::UnexpectedError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto data = reply->readAll();
|
|
||||||
qDebug() << "Settings: " << data;
|
|
||||||
QJsonParseError parseError;
|
|
||||||
auto doc = QJsonDocument::fromJson(data, &parseError);
|
|
||||||
|
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
|
||||||
qDebug() << "Error parsing settings";
|
|
||||||
setApplicationStateError("Error retreiving settings");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto root = doc.object();
|
|
||||||
if (root["status"] != "success") {
|
|
||||||
qDebug() << "Status is not \"success\"";
|
|
||||||
setApplicationStateError("Error retreiving settings");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_homeLocation = "hifi://hq";
|
|
||||||
if (root["data"].toObject().contains("home_location")) {
|
|
||||||
auto homeLocation = root["data"].toObject()["home_location"];
|
|
||||||
if (homeLocation.isString()) {
|
|
||||||
_homeLocation = homeLocation.toString();
|
|
||||||
auto host = QUrl(_homeLocation).host();
|
auto host = QUrl(_homeLocation).host();
|
||||||
_contentCacheURL = "http://orgs.highfidelity.com/host-content-cache/" + host + ".zip";
|
_contentCacheURL = "http://orgs.highfidelity.com/host-content-cache/" + host + ".zip";
|
||||||
qDebug() << "Home location is: " << _homeLocation;
|
|
||||||
qDebug() << "Content cache url is: " << _contentCacheURL;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "Home:" << _homeLocation << QUrl(_homeLocation).host();
|
qDebug() << "Home location is: " << _homeLocation;
|
||||||
|
qDebug() << "Content cache url is: " << _contentCacheURL;
|
||||||
|
|
||||||
downloadClient();
|
downloadClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
request->send(_networkAccessManager, _loginResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherState::downloadClient() {
|
void LauncherState::downloadClient() {
|
||||||
|
@ -683,10 +670,9 @@ void LauncherState::launchClient() {
|
||||||
defaultScriptsPath = installDirectory.filePath("interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js");
|
defaultScriptsPath = installDirectory.filePath("interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString displayName = "fixMe";
|
|
||||||
QString contentCachePath = _launcherDirectory.filePath("cache");
|
QString contentCachePath = _launcherDirectory.filePath("cache");
|
||||||
|
|
||||||
::launchClient(clientPath, _homeLocation, QDir::toNativeSeparators(defaultScriptsPath), displayName, contentCachePath, _loginTokenResponse);
|
::launchClient(clientPath, _homeLocation, defaultScriptsPath, _displayName, contentCachePath, _loginTokenResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherState::setApplicationStateError(QString errorMessage) {
|
void LauncherState::setApplicationStateError(QString errorMessage) {
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
|
#include "LoginRequest.h"
|
||||||
|
#include "SignupRequest.h"
|
||||||
|
#include "UserSettingsRequest.h"
|
||||||
|
|
||||||
struct Build {
|
struct Build {
|
||||||
QString tag;
|
QString tag;
|
||||||
int latestVersion;
|
int latestVersion;
|
||||||
|
@ -22,18 +26,13 @@ struct LatestBuilds {
|
||||||
Build launcherBuild;
|
Build launcherBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginResponse {
|
|
||||||
QString accessToken;
|
|
||||||
QString tokenType;
|
|
||||||
QString refreshToken;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LauncherState : public QObject {
|
class LauncherState : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(UIState uiState READ getUIState NOTIFY uiStateChanged);
|
Q_PROPERTY(UIState uiState READ getUIState NOTIFY uiStateChanged);
|
||||||
Q_PROPERTY(ApplicationState applicationState READ getApplicationState NOTIFY applicationStateChanged);
|
Q_PROPERTY(ApplicationState applicationState READ getApplicationState NOTIFY applicationStateChanged);
|
||||||
Q_PROPERTY(float downloadProgress READ getDownloadProgress NOTIFY downloadProgressChanged);
|
Q_PROPERTY(float downloadProgress READ getDownloadProgress NOTIFY downloadProgressChanged);
|
||||||
|
Q_PROPERTY(SignupRequest::Error lastSignupError MEMBER _lastSignupError NOTIFY lastSignupErrorChanged);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LauncherState();
|
LauncherState();
|
||||||
|
@ -41,6 +40,7 @@ public:
|
||||||
|
|
||||||
enum UIState {
|
enum UIState {
|
||||||
SPLASH_SCREEN = 0,
|
SPLASH_SCREEN = 0,
|
||||||
|
SIGNUP_SCREEN,
|
||||||
LOGIN_SCREEN,
|
LOGIN_SCREEN,
|
||||||
DISPLAY_NAME_SCREEN,
|
DISPLAY_NAME_SCREEN,
|
||||||
DOWNLOAD_SCREEN,
|
DOWNLOAD_SCREEN,
|
||||||
|
@ -60,6 +60,10 @@ public:
|
||||||
WaitingForLogin,
|
WaitingForLogin,
|
||||||
RequestingLogin,
|
RequestingLogin,
|
||||||
|
|
||||||
|
WaitingForSignup,
|
||||||
|
RequestingSignup,
|
||||||
|
RequestingLoginAfterSignup,
|
||||||
|
|
||||||
DownloadingClient,
|
DownloadingClient,
|
||||||
DownloadingLauncher,
|
DownloadingLauncher,
|
||||||
DownloadingContentCache,
|
DownloadingContentCache,
|
||||||
|
@ -85,7 +89,7 @@ public:
|
||||||
Q_INVOKABLE QString getCurrentUISource() const;
|
Q_INVOKABLE QString getCurrentUISource() const;
|
||||||
|
|
||||||
void ASSERT_STATE(LauncherState::ApplicationState state);
|
void ASSERT_STATE(LauncherState::ApplicationState state);
|
||||||
void ASSERT_STATE(std::vector<LauncherState::ApplicationState> states);
|
void ASSERT_STATE(const std::vector<LauncherState::ApplicationState>& states);
|
||||||
|
|
||||||
static void declareQML();
|
static void declareQML();
|
||||||
|
|
||||||
|
@ -98,17 +102,21 @@ public:
|
||||||
void setApplicationState(ApplicationState state);
|
void setApplicationState(ApplicationState state);
|
||||||
ApplicationState getApplicationState() const;
|
ApplicationState getApplicationState() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void gotoSignup();
|
||||||
|
Q_INVOKABLE void gotoLogin();
|
||||||
|
|
||||||
// Request builds
|
// Request builds
|
||||||
void requestBuilds();
|
void requestBuilds();
|
||||||
Q_INVOKABLE void receivedBuildsReply();
|
Q_INVOKABLE void receivedBuildsReply();
|
||||||
|
|
||||||
|
// Signup
|
||||||
|
Q_INVOKABLE void signup(QString email, QString username, QString password, QString displayName);
|
||||||
|
|
||||||
// Login
|
// Login
|
||||||
Q_INVOKABLE void login(QString username, QString password);
|
Q_INVOKABLE void login(QString username, QString password, QString displayName);
|
||||||
Q_INVOKABLE void receivedLoginReply();
|
|
||||||
|
|
||||||
|
// Request Settings
|
||||||
void requestSettings();
|
void requestSettings();
|
||||||
Q_INVOKABLE void receivedSettingsReply();
|
|
||||||
|
|
||||||
// Launcher
|
// Launcher
|
||||||
void downloadLauncher();
|
void downloadLauncher();
|
||||||
|
@ -132,6 +140,7 @@ signals:
|
||||||
void uiStateChanged();
|
void uiStateChanged();
|
||||||
void applicationStateChanged();
|
void applicationStateChanged();
|
||||||
void downloadProgressChanged();
|
void downloadProgressChanged();
|
||||||
|
void lastSignupErrorChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void clientDownloadComplete();
|
void clientDownloadComplete();
|
||||||
|
@ -154,8 +163,10 @@ private:
|
||||||
|
|
||||||
// Application State
|
// Application State
|
||||||
ApplicationState _applicationState { ApplicationState::Init };
|
ApplicationState _applicationState { ApplicationState::Init };
|
||||||
LoginResponse _loginResponse;
|
LoginToken _loginResponse;
|
||||||
LastLoginError _lastLoginError { NONE };
|
LastLoginError _lastLoginError { NONE };
|
||||||
|
SignupRequest::Error _lastSignupError{ SignupRequest::Error::None };
|
||||||
|
QString _displayName;
|
||||||
QString _applicationErrorMessage;
|
QString _applicationErrorMessage;
|
||||||
QString _currentClientVersion;
|
QString _currentClientVersion;
|
||||||
QString _buildTag { QString::null };
|
QString _buildTag { QString::null };
|
||||||
|
@ -166,5 +177,8 @@ private:
|
||||||
QFile _launcherZipFile;
|
QFile _launcherZipFile;
|
||||||
QFile _contentZipFile;
|
QFile _contentZipFile;
|
||||||
|
|
||||||
|
QString _username;
|
||||||
|
QString _password;
|
||||||
|
|
||||||
float _downloadProgress { 0 };
|
float _downloadProgress { 0 };
|
||||||
};
|
};
|
||||||
|
|
73
launchers/qt/src/LoginRequest.cpp
Normal file
73
launchers/qt/src/LoginRequest.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include "LoginRequest.h"
|
||||||
|
|
||||||
|
#include "Helper.h"
|
||||||
|
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
void LoginRequest::send(QNetworkAccessManager& nam, QString username, QString password) {
|
||||||
|
QNetworkRequest request(QUrl(METAVERSE_API_DOMAIN + "/oauth/token"));
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::UserAgentHeader, getHTTPUserAgent());
|
||||||
|
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 = nam.post(request, query.toString().toUtf8());
|
||||||
|
QObject::connect(reply, &QNetworkReply::finished, this, &LoginRequest::receivedResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginRequest::receivedResponse() {
|
||||||
|
_state = State::Finished;
|
||||||
|
|
||||||
|
auto reply = static_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
if (reply->error()) {
|
||||||
|
qDebug() << "Error logging in: " << reply->readAll();
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
//setApplicationState(ApplicationState::UnexpectedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = reply->readAll();
|
||||||
|
QJsonParseError parseError;
|
||||||
|
auto doc = QJsonDocument::fromJson(data, &parseError);
|
||||||
|
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qDebug() << "Error parsing response for login" << data;
|
||||||
|
_error = Error::BadResponse;
|
||||||
|
emit finished();
|
||||||
|
//setApplicationStateError("Failed to login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto root = doc.object();
|
||||||
|
|
||||||
|
if (!root.contains("access_token")
|
||||||
|
|| !root.contains("token_type")
|
||||||
|
|| !root.contains("expires_in")
|
||||||
|
|| !root.contains("refresh_token")
|
||||||
|
|| !root.contains("scope")
|
||||||
|
|| !root.contains("created_at")) {
|
||||||
|
|
||||||
|
_error = Error::BadUsernameOrPassword;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_token.accessToken = root["access_token"].toString();
|
||||||
|
_token.refreshToken = root["refresh_token"].toString();
|
||||||
|
_token.tokenType = root["token_type"].toString();
|
||||||
|
|
||||||
|
qDebug() << "Got response for login: " << data;
|
||||||
|
_rawLoginToken = data;
|
||||||
|
|
||||||
|
emit finished();
|
||||||
|
}
|
49
launchers/qt/src/LoginRequest.h
Normal file
49
launchers/qt/src/LoginRequest.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
struct LoginToken {
|
||||||
|
QString accessToken;
|
||||||
|
QString tokenType;
|
||||||
|
QString refreshToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoginRequest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class State {
|
||||||
|
Unsent,
|
||||||
|
Sending,
|
||||||
|
Finished
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Error {
|
||||||
|
None = 0,
|
||||||
|
Unknown,
|
||||||
|
BadResponse,
|
||||||
|
BadUsernameOrPassword
|
||||||
|
};
|
||||||
|
Q_ENUM(Error)
|
||||||
|
|
||||||
|
void send(QNetworkAccessManager& nam, QString username, QString password);
|
||||||
|
Error getError() const { return _error; }
|
||||||
|
|
||||||
|
// The token is only valid if the request has finished without error
|
||||||
|
QString getRawToken() const { return _rawLoginToken; }
|
||||||
|
LoginToken getToken() const { return _token; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void receivedResponse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
State _state { State::Unsent };
|
||||||
|
Error _error { Error::None };
|
||||||
|
|
||||||
|
QString _rawLoginToken;
|
||||||
|
LoginToken _token;
|
||||||
|
};
|
||||||
|
|
79
launchers/qt/src/SignupRequest.cpp
Normal file
79
launchers/qt/src/SignupRequest.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "SignupRequest.h"
|
||||||
|
|
||||||
|
#include "Helper.h"
|
||||||
|
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
void SignupRequest::send(QNetworkAccessManager& nam, QString email, QString username, QString password) {
|
||||||
|
if (_state != State::Unsent) {
|
||||||
|
qDebug() << "Error: Trying to send signuprequest, but not unsent";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = State::Sending;
|
||||||
|
|
||||||
|
QUrl signupURL { METAVERSE_API_DOMAIN };
|
||||||
|
signupURL.setPath("/api/v1/user/channel_user");
|
||||||
|
QNetworkRequest request(signupURL);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::UserAgentHeader, getHTTPUserAgent());
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
QUrlQuery query;
|
||||||
|
query.addQueryItem("email", email);
|
||||||
|
query.addQueryItem("username", username);
|
||||||
|
query.addQueryItem("password", password);
|
||||||
|
|
||||||
|
auto reply = nam.post(request, query.toString().toUtf8());
|
||||||
|
QObject::connect(reply, &QNetworkReply::finished, this, &SignupRequest::receivedResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignupRequest::receivedResponse() {
|
||||||
|
_state = State::Finished;
|
||||||
|
|
||||||
|
auto reply = static_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
if (reply->error() && reply->size() == 0) {
|
||||||
|
qDebug() << "Error signing up: " << reply->error() << reply->readAll();
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = reply->readAll();
|
||||||
|
QJsonParseError parseError;
|
||||||
|
auto doc = QJsonDocument::fromJson(data, &parseError);
|
||||||
|
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qDebug() << "Error parsing response for signup " << data;
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto root = doc.object();
|
||||||
|
|
||||||
|
auto status = root["status"];
|
||||||
|
if (status.isString() && status.toString() != "success") {
|
||||||
|
auto error = root["data"].toString();
|
||||||
|
|
||||||
|
_error = Error::Unknown;
|
||||||
|
|
||||||
|
if (error == "no_such_email") {
|
||||||
|
_error = Error::NoSuchEmail;
|
||||||
|
} else if (error == "user_profile_already_completed") {
|
||||||
|
_error = Error::UserProfileAlreadyCompleted;
|
||||||
|
} else if (error == "bad_username") {
|
||||||
|
_error = Error::BadUsername;
|
||||||
|
} else if (error == "existing_username") {
|
||||||
|
_error = Error::ExistingUsername;
|
||||||
|
} else if (error == "bad_password") {
|
||||||
|
_error = Error::BadPassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit finished();
|
||||||
|
}
|
38
launchers/qt/src/SignupRequest.h
Normal file
38
launchers/qt/src/SignupRequest.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
class SignupRequest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class State {
|
||||||
|
Unsent,
|
||||||
|
Sending,
|
||||||
|
Finished
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Error {
|
||||||
|
None = 0,
|
||||||
|
Unknown,
|
||||||
|
NoSuchEmail,
|
||||||
|
UserProfileAlreadyCompleted,
|
||||||
|
BadUsername,
|
||||||
|
ExistingUsername,
|
||||||
|
BadPassword,
|
||||||
|
};
|
||||||
|
Q_ENUM(Error)
|
||||||
|
|
||||||
|
void send(QNetworkAccessManager& nam, QString email, QString username, QString password);
|
||||||
|
Error getError() const { return _error; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void receivedResponse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
State _state { State::Unsent };
|
||||||
|
Error _error { Error::None };
|
||||||
|
};
|
67
launchers/qt/src/UserSettingsRequest.cpp
Normal file
67
launchers/qt/src/UserSettingsRequest.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "UserSettingsRequest.h"
|
||||||
|
|
||||||
|
#include "Helper.h"
|
||||||
|
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
|
||||||
|
void UserSettingsRequest::send(QNetworkAccessManager& nam, const LoginToken& token) {
|
||||||
|
_state = State::Sending;
|
||||||
|
|
||||||
|
QUrl lockerURL = METAVERSE_API_DOMAIN;
|
||||||
|
lockerURL.setPath("/api/v1/user/locker");
|
||||||
|
|
||||||
|
QNetworkRequest lockerRequest(lockerURL);
|
||||||
|
lockerRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
|
lockerRequest.setHeader(QNetworkRequest::UserAgentHeader, getHTTPUserAgent());
|
||||||
|
lockerRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, QString("Bearer %1").arg(token.accessToken).toUtf8());
|
||||||
|
|
||||||
|
QNetworkReply* lockerReply = nam.get(lockerRequest);
|
||||||
|
connect(lockerReply, &QNetworkReply::finished, this, &UserSettingsRequest::receivedResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserSettingsRequest::receivedResponse() {
|
||||||
|
_state = State::Finished;
|
||||||
|
|
||||||
|
auto reply = static_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
qDebug() << "Got reply: " << reply->error();
|
||||||
|
if (reply->error()) {
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = reply->readAll();
|
||||||
|
qDebug() << "Settings: " << data;
|
||||||
|
QJsonParseError parseError;
|
||||||
|
auto doc = QJsonDocument::fromJson(data, &parseError);
|
||||||
|
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qDebug() << "Error parsing settings";
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto root = doc.object();
|
||||||
|
if (root["status"] != "success") {
|
||||||
|
qDebug() << "Status is not \"success\"";
|
||||||
|
_error = Error::Unknown;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root["data"].toObject().contains("home_location")) {
|
||||||
|
auto homeLocation = root["data"].toObject()["home_location"];
|
||||||
|
if (homeLocation.isString()) {
|
||||||
|
_userSettings.homeLocation = homeLocation.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit finished();
|
||||||
|
}
|
43
launchers/qt/src/UserSettingsRequest.h
Normal file
43
launchers/qt/src/UserSettingsRequest.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
#include "LoginRequest.h"
|
||||||
|
|
||||||
|
struct UserSettings {
|
||||||
|
QString homeLocation{ QString::null };
|
||||||
|
};
|
||||||
|
|
||||||
|
class UserSettingsRequest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class State {
|
||||||
|
Unsent,
|
||||||
|
Sending,
|
||||||
|
Finished
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Error {
|
||||||
|
None = 0,
|
||||||
|
Unknown,
|
||||||
|
};
|
||||||
|
Q_ENUM(Error)
|
||||||
|
|
||||||
|
void send(QNetworkAccessManager& nam, const LoginToken& token);
|
||||||
|
Error getError() const { return _error; }
|
||||||
|
|
||||||
|
UserSettings getUserSettings() const { return _userSettings; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void receivedResponse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
State _state { State::Unsent };
|
||||||
|
Error _error { Error::None };
|
||||||
|
|
||||||
|
UserSettings _userSettings;
|
||||||
|
};
|
|
@ -1,5 +1,7 @@
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
|
|
||||||
|
#include <qsharedmemory.h>
|
||||||
|
|
||||||
#include "LauncherWindow.h"
|
#include "LauncherWindow.h"
|
||||||
#include "Launcher.h"
|
#include "Launcher.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -19,7 +21,7 @@ Q_IMPORT_PLUGIN(QtQuickTemplates2Plugin);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool hasSuffix(const std::string path, const std::string suffix) {
|
bool hasSuffix(const std::string& path, const std::string& suffix) {
|
||||||
if (path.substr(path.find_last_of(".") + 1) == suffix) {
|
if (path.substr(path.find_last_of(".") + 1) == suffix) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +63,12 @@ int main(int argc, char *argv[]) {
|
||||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QCoreApplication::setOrganizationName(name);
|
QCoreApplication::setOrganizationName(name);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
//QSharedMemory sharedMemory{ applicationName };
|
||||||
|
//instanceMightBeRunning = !sharedMemory.create(1, QSharedMemory::ReadOnly);
|
||||||
|
#endif
|
||||||
|
|
||||||
Launcher launcher(argc, argv);
|
Launcher launcher(argc, argv);
|
||||||
|
|
||||||
return launcher.exec();
|
return launcher.exec();
|
||||||
|
|
Loading…
Reference in a new issue