From f0ff9752480485c9ddb5f8bae1afbb67550fe47c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 Jul 2016 19:48:52 -0700 Subject: [PATCH] UI wiring --- interface/resources/qml/LoginDialog.qml | 23 +-- .../qml/LoginDialog/CompleteProfileBody.qml | 37 +++++ .../qml/LoginDialog/EmailSentBody.qml | 6 +- .../qml/LoginDialog/LinkAccountBody.qml | 81 +++++++++- .../qml/LoginDialog/RecoverPasswordBody.qml | 38 ++++- .../resources/qml/LoginDialog/SignInBody.qml | 18 +++ .../qml/LoginDialog/UsernameCollisionBody.qml | 149 ++++++++---------- .../resources/qml/LoginDialog/WelcomeBody.qml | 17 +- .../scripting/AccountScriptingInterface.cpp | 3 + .../src/scripting/AccountScriptingInterface.h | 5 + interface/src/ui/LoginDialog.cpp | 92 +++++++++++ interface/src/ui/LoginDialog.h | 24 ++- libraries/networking/src/AccountManager.cpp | 1 + .../src/steamworks-wrapper/SteamClient.cpp | 23 ++- .../src/steamworks-wrapper/SteamClient.h | 2 + 15 files changed, 394 insertions(+), 125 deletions(-) diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 3e8747c076..1f84024e15 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -33,34 +33,13 @@ ModalWindow { property string title: "" property int titleWidth: 0 - Component { - id: signInBody - SignInBody {} - } - Component { - id: welcomeBody - WelcomeBody {} - } - LoginDialog { id: loginDialog Loader { id: bodyLoader anchors.fill: parent - sourceComponent: signInBody - } - - Connections { - target: loginDialog - onHandleLoginCompleted: { - console.log("Login Succeeded") - bodyLoader.sourceComponent = welcomeBody - bodyLoader.active = true - } - onHandleLoginFailed: { - console.log("Login Failed") - } + source: loginDialog.isSteamRunning() ? "LoginDialog/SignInBody.qml" : "LoginDialog/LinkAccountBody.qml" } } diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml index b6ef012e2a..12d2cee73e 100644 --- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml +++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml @@ -54,6 +54,8 @@ Item { text: qsTr("Create your profile") color: hifi.buttons.blue + + onClicked: loginDialog.createAccountFromStream() } Button { @@ -83,6 +85,15 @@ Item { lineHeight: 2 lineHeightMode: Text.ProportionalHeight horizontalAlignment: Text.AlignHCenter + + MouseArea { + anchors.fill: parent + onClicked: { + bodyLoader.source = "LinkAccountBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } } Component.onCompleted: { @@ -90,4 +101,30 @@ Item { root.iconText = "<" d.resize(); } + + Connections { + target: loginDialog + onHandleCreateCompleted: { + console.log("Create Succeeded") + + loginDialog.loginThroughSteam() + } + onHandleCreateFailed: { + console.log("Create Failed: " + error) + + bodyLoader.source = "UsernameCollisionBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + onHandleLoginCompleted: { + console.log("Login Succeeded") + + bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + onHandleLoginFailed: { + console.log("Login Failed") + } + } } diff --git a/interface/resources/qml/LoginDialog/EmailSentBody.qml b/interface/resources/qml/LoginDialog/EmailSentBody.qml index eede996412..489385864b 100644 --- a/interface/resources/qml/LoginDialog/EmailSentBody.qml +++ b/interface/resources/qml/LoginDialog/EmailSentBody.qml @@ -17,10 +17,10 @@ import "../styles-uit" Item { id: emailSentBody clip: true - width: pane.width - height: pane.height + width: root.pane.width + height: root.pane.height - property string email: "clement@highfidelity.com" + property string email: "" QtObject { id: d diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index b7ff756fa3..da5f0f1a42 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -19,10 +19,14 @@ import "../styles-uit" Item { id: linkAccountBody clip: true - width: pane.width - height: pane.height + width: root.pane.width + height: root.pane.height - property bool existingEmail: true + property bool existingEmail: false + + function login() { + loginDialog.login(usernameField.text, passwordField.text) + } QtObject { id: d @@ -64,7 +68,7 @@ Item { Column { id: form anchors { - top: mainTextContainer.bottom + top: mainTextContainer.visible ? mainTextContainer.bottom : parent.top left: parent.left margins: 0 topMargin: 2 * hifi.dimensions.contentSpacing.y @@ -96,6 +100,15 @@ Item { verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + + MouseArea { + anchors.fill: parent + onClicked: { + bodyLoader.source = "RecoverPasswordBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } } } Row { @@ -124,6 +137,15 @@ Item { verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + + MouseArea { + anchors.fill: parent + onClicked: { + bodyLoader.source = "RecoverPasswordBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } } } @@ -141,11 +163,14 @@ Item { onHeightChanged: d.resize(); onWidthChanged: d.resize(); Button { + id: linkAccountButton anchors.verticalCenter: parent.verticalCenter width: 200 - text: qsTr("Link Account") + text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") color: hifi.buttons.blue + + onClicked: linkAccountBody.login() } Button { @@ -161,5 +186,51 @@ Item { root.title = qsTr("Sign Into High Fidelity") root.iconText = "<" d.resize(); + + usernameField.forceActiveFocus() + } + + Connections { + target: loginDialog + onHandleLoginCompleted: { + console.log("Login Succeeded, linking steam account") + + if (loginDialog.isSteamRunning()) { + loginDialog.linkSteam() + } else { + bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } + onHandleLoginFailed: { + console.log("Login Failed") + + } + onHandleLinkCompleted: { + console.log("Link Succeeded") + + bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + onHandleLinkFailed: { + console.log("Link Failed") + + } + } + + Keys.onPressed: { + if (!visible) { + return + } + + switch (event.key) { + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true + linkAccountBody.login() + break + } } } diff --git a/interface/resources/qml/LoginDialog/RecoverPasswordBody.qml b/interface/resources/qml/LoginDialog/RecoverPasswordBody.qml index 74dcb18054..3c6e101e2a 100644 --- a/interface/resources/qml/LoginDialog/RecoverPasswordBody.qml +++ b/interface/resources/qml/LoginDialog/RecoverPasswordBody.qml @@ -19,8 +19,16 @@ import "../styles-uit" Item { id: recoverPasswordBody clip: true - width: pane.width - height: pane.height + width: root.pane.width + height: root.pane.height + + function send() { + loginDialog.sendRecoveryEmail(emailField.text) + + bodyLoader.setSource("EmailSentBody.qml", { "email": emailField.text }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } QtObject { id: d @@ -70,6 +78,10 @@ Item { width: 350 label: "Email address" + + Component.onCompleted: { + emailField.forceActiveFocus() + } } Row { @@ -89,12 +101,20 @@ Item { text: qsTr("Send recovery email") color: hifi.buttons.blue + + onClicked: recoverPasswordBody.send() } Button { anchors.verticalCenter: parent.verticalCenter text: qsTr("Back") + + onClicked: { + bodyLoader.source = "LinkAccountBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } } @@ -103,4 +123,18 @@ Item { root.iconText = "<" d.resize(); } + + Keys.onPressed: { + if (!visible) { + return + } + + switch (event.key) { + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true + recoverPasswordBody.send() + break + } + } } diff --git a/interface/resources/qml/LoginDialog/SignInBody.qml b/interface/resources/qml/LoginDialog/SignInBody.qml index d3f6926bd2..2da0ea856d 100644 --- a/interface/resources/qml/LoginDialog/SignInBody.qml +++ b/interface/resources/qml/LoginDialog/SignInBody.qml @@ -107,4 +107,22 @@ Item { root.iconText = "" d.resize(); } + + Connections { + target: loginDialog + onHandleLoginCompleted: { + console.log("Login Succeeded") + + bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + onHandleLoginFailed: { + console.log("Login Failed") + + bodyLoader.source = "CompleteProfileBody.qml" + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } } diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index ea5a9bb614..f0663631a8 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -19,8 +19,8 @@ import "../styles-uit" Item { id: usernameCollisionBody clip: true - width: pane.width - height: pane.height + width: root.pane.width + height: root.pane.height QtObject { id: d @@ -30,26 +30,59 @@ Item { readonly property int maxHeight: 720 function resize() { - var targetWidth = Math.max(titleWidth, mainTextContainer.visible ? mainTextContainer.contentWidth : 0) - var targetHeight = (mainTextContainer.visible ? mainTextContainer.height : 0) + - 4 * hifi.dimensions.contentSpacing.y + form.height + - 4 * hifi.dimensions.contentSpacing.y + buttons.height + var targetWidth = Math.max(titleWidth, Math.max(mainTextContainer.contentWidth, + termsContainer.contentWidth)) + var targetHeight = mainTextContainer.height + + 2 * hifi.dimensions.contentSpacing.y + textField.height + + 5 * hifi.dimensions.contentSpacing.y + termsContainer.height + + 1 * hifi.dimensions.contentSpacing.y + buttons.height root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)) root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) } } - MenuItem { + ShortcutText { id: mainTextContainer anchors { top: parent.top - horizontalCenter: parent.horizontalCenter + left: parent.left margins: 0 topMargin: hifi.dimensions.contentSpacing.y } - text: qsTr("Choose your High Fidelity user name:") + text: qsTr("Your Steam username is not available.") + wrapMode: Text.WordWrap + color: hifi.colors.redAccent + lineHeight: 1 + lineHeightMode: Text.ProportionalHeight + horizontalAlignment: Text.AlignHCenter + } + + + TextField { + id: textField + anchors { + top: mainTextContainer.bottom + left: parent.left + margins: 0 + topMargin: 2 * hifi.dimensions.contentSpacing.y + } + width: 250 + + placeholderText: "Choose your own" + } + + MenuItem { + id: termsContainer + anchors { + top: textField.bottom + left: parent.left + margins: 0 + topMargin: 3 * hifi.dimensions.contentSpacing.y + } + + text: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") wrapMode: Text.WordWrap color: hifi.colors.baseGrayHighlight lineHeight: 1 @@ -57,82 +90,13 @@ Item { horizontalAlignment: Text.AlignHCenter } - - Column { - id: form - anchors { - top: mainTextContainer.bottom - left: parent.left - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: 2 * hifi.dimensions.contentSpacing.y - - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: usernameField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "User Name or Email" - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: "Need help?" - - color: hifi.colors.blueAccent - font.underline: true - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: passwordField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Password" - echoMode: TextInput.Password - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: "Need help?" - - color: hifi.colors.blueAccent - font.underline: true - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - - } - Row { id: buttons anchors { - top: form.bottom + top: termsContainer.bottom right: parent.right margins: 0 - topMargin: 3 * hifi.dimensions.contentSpacing.y + topMargin: 1 * hifi.dimensions.contentSpacing.y } spacing: hifi.dimensions.contentSpacing.x onHeightChanged: d.resize(); onWidthChanged: d.resize(); @@ -143,6 +107,10 @@ Item { text: qsTr("Create your profile") color: hifi.buttons.blue + + onClicked: { + loginDialog.createAccountFromStream(textField.text) + } } Button { @@ -159,4 +127,25 @@ Item { root.iconText = "<" d.resize(); } + Connections { + target: loginDialog + onHandleCreateCompleted: { + console.log("Create Succeeded") + + loginDialog.loginThroughSteam() + } + onHandleCreateFailed: { + console.log("Create Failed: " + error) + } + onHandleLoginCompleted: { + console.log("Login Succeeded") + + bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false }) + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + onHandleLoginFailed: { + console.log("Login Failed") + } + } } diff --git a/interface/resources/qml/LoginDialog/WelcomeBody.qml b/interface/resources/qml/LoginDialog/WelcomeBody.qml index 8b771eac1f..ecc848cdc0 100644 --- a/interface/resources/qml/LoginDialog/WelcomeBody.qml +++ b/interface/resources/qml/LoginDialog/WelcomeBody.qml @@ -20,7 +20,13 @@ Item { width: pane.width height: pane.height - property bool welcomeBack: true + property bool welcomeBack: false + + function setTitle() { + root.title = (welcomeBack ? qsTr("Welcome back ") : qsTr("Welcome ")) + Account.username + qsTr("!") + root.iconText = "" + d.resize(); + } QtObject { id: d @@ -75,9 +81,10 @@ Item { } } - Component.onCompleted: { - root.title = (welcomeBack ? qsTr("Welcome back ") : qsTr("Welcome ")) + Account.getUsername() + qsTr("!") - root.iconText = "" - d.resize(); + Component.onCompleted: welcomeBody.setTitle() + + Connections { + target: Account + onUsernameChanged: welcomeBody.setTitle() } } diff --git a/interface/src/scripting/AccountScriptingInterface.cpp b/interface/src/scripting/AccountScriptingInterface.cpp index 1328197195..4090c99ac8 100644 --- a/interface/src/scripting/AccountScriptingInterface.cpp +++ b/interface/src/scripting/AccountScriptingInterface.cpp @@ -15,6 +15,9 @@ AccountScriptingInterface* AccountScriptingInterface::getInstance() { static AccountScriptingInterface sharedInstance; + auto accountManager = DependencyManager::get(); + QObject::connect(accountManager.data(), &AccountManager::profileChanged, + &sharedInstance, &AccountScriptingInterface::usernameChanged); return &sharedInstance; } diff --git a/interface/src/scripting/AccountScriptingInterface.h b/interface/src/scripting/AccountScriptingInterface.h index 888149b836..49648781ce 100644 --- a/interface/src/scripting/AccountScriptingInterface.h +++ b/interface/src/scripting/AccountScriptingInterface.h @@ -17,6 +17,11 @@ class AccountScriptingInterface : public QObject { Q_OBJECT + Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged) + +signals: + void usernameChanged(); + public slots: static AccountScriptingInterface* getInstance(); QString getUsername(); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 15a277f394..b65e111b16 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -12,6 +12,8 @@ #include "LoginDialog.h" #include +#include +#include #include #include @@ -52,6 +54,10 @@ void LoginDialog::toggleAction() { } } +bool LoginDialog::isSteamRunning() { + return SteamClient::isRunning(); +} + void LoginDialog::login(const QString& username, const QString& password) { qDebug() << "Attempting to login " << username; DependencyManager::get()->requestAccessToken(username, password); @@ -69,6 +75,92 @@ void LoginDialog::loginThroughSteam() { }); } +void LoginDialog::linkSteam() { + qDebug() << "Attempting to link Steam account"; + SteamClient::requestTicket([this](Ticket ticket) { + if (ticket.isNull()) { + emit handleLoginFailed(); + return; + } + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "linkCompleted"; + callbackParams.errorCallbackReceiver = this; + callbackParams.errorCallbackMethod = "linkFailed"; + + const QString LINK_STEAM_PATH = "api/v1/user/link_steam"; + + QJsonObject payload; + payload.insert("ticket", QJsonValue::fromVariant(QVariant(ticket))); + + auto accountManager = DependencyManager::get(); + accountManager->sendRequest(LINK_STEAM_PATH, AccountManagerAuth::Required, + QNetworkAccessManager::PostOperation, callbackParams, + QJsonDocument(payload).toJson()); + }); +} + +void LoginDialog::createAccountFromStream(QString username) { + qDebug() << "Attempting to create account from Steam info"; + SteamClient::requestTicket([this, username](Ticket ticket) { + if (ticket.isNull()) { + emit handleLoginFailed(); + return; + } + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "createCompleted"; + callbackParams.errorCallbackReceiver = this; + callbackParams.errorCallbackMethod = "createFailed"; + + const QString CREATE_ACCOUNT_FROM_STEAM_PATH = "api/v1/user/create_from_steam"; + + QJsonObject payload; + payload.insert("ticket", QJsonValue::fromVariant(QVariant(ticket))); + if (!username.isEmpty()) { + payload.insert("username", QJsonValue::fromVariant(QVariant(username))); + } + + auto accountManager = DependencyManager::get(); + accountManager->sendRequest(CREATE_ACCOUNT_FROM_STEAM_PATH, AccountManagerAuth::None, + QNetworkAccessManager::PostOperation, callbackParams, + QJsonDocument(payload).toJson()); + }); + +} + void LoginDialog::openUrl(const QString& url) { QDesktopServices::openUrl(url); } + +void LoginDialog::sendRecoveryEmail(const QString& email) { + const QString PASSWORD_RESET_PATH = "/users/password"; + + QJsonObject payload; + payload.insert("user_email", QJsonValue::fromVariant(QVariant(email))); + + + auto accountManager = DependencyManager::get(); + accountManager->sendRequest(PASSWORD_RESET_PATH, AccountManagerAuth::None, + QNetworkAccessManager::PostOperation, JSONCallbackParameters(), + QJsonDocument(payload).toJson()); +} + +void LoginDialog::linkCompleted(QNetworkReply& reply) { + emit handleLinkCompleted(); +} + +void LoginDialog::linkFailed(QNetworkReply& reply) { + emit handleLinkFailed(reply.errorString()); +} + +void LoginDialog::createCompleted(QNetworkReply& reply) { + emit handleCreateCompleted(); +} + +void LoginDialog::createFailed(QNetworkReply& reply) { + emit handleCreateFailed(reply.errorString()); +} + diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index dcd0e04894..ef2c937201 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -16,6 +16,8 @@ #include +class QNetworkReply; + class LoginDialog : public OffscreenQmlDialog { Q_OBJECT HIFI_QML_DECL @@ -29,10 +31,30 @@ signals: void handleLoginCompleted(); void handleLoginFailed(); -protected: + void handleLinkCompleted(); + void handleLinkFailed(QString error); + + void handleCreateCompleted(); + void handleCreateFailed(QString error); + +public slots: + void linkCompleted(QNetworkReply& reply); + void linkFailed(QNetworkReply& reply); + + void createCompleted(QNetworkReply& reply); + void createFailed(QNetworkReply& reply); + +protected slots: + Q_INVOKABLE bool isSteamRunning(); + Q_INVOKABLE void login(const QString& username, const QString& password); Q_INVOKABLE void loginThroughSteam(); + Q_INVOKABLE void linkSteam(); + Q_INVOKABLE void createAccountFromStream(QString username = QString()); + Q_INVOKABLE void openUrl(const QString& url); + Q_INVOKABLE void sendRecoveryEmail(const QString& email); + }; #endif // hifi_LoginDialog_h diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 8c0fa5ed92..52d9e87636 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -568,6 +568,7 @@ void AccountManager::requestAccessTokenFinished() { void AccountManager::requestAccessTokenError(QNetworkReply::NetworkError error) { // TODO: error handling qCDebug(networking) << "AccountManager requestError - " << error; + emit loginFailed(); } void AccountManager::requestProfile() { diff --git a/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.cpp b/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.cpp index 1dbfc0ce00..a8a57064de 100644 --- a/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.cpp +++ b/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.cpp @@ -133,8 +133,16 @@ void SteamTicketRequests::onGetAuthSessionTicketResponse(GetAuthSessionTicketRes static std::atomic_bool initialized { false }; static std::unique_ptr steamTicketRequests; -bool SteamClient::init() { + +bool SteamClient::isRunning() { if (!initialized) { + init(); + } + return initialized; +} + +bool SteamClient::init() { + if (SteamAPI_IsSteamRunning() && !initialized) { initialized = SteamAPI_Init(); } @@ -157,11 +165,6 @@ void SteamClient::shutdown() { void SteamClient::runCallbacks() { if (!initialized) { - init(); - } - - if (!initialized) { - qDebug() << "Steam not initialized"; return; } @@ -176,7 +179,13 @@ void SteamClient::runCallbacks() { void SteamClient::requestTicket(TicketRequestCallback callback) { if (!initialized) { - init(); + if (SteamAPI_IsSteamRunning()) { + init(); + } else { + qWarning() << "Steam is not running"; + callback(INVALID_TICKET); + return; + } } if (!initialized) { diff --git a/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.h b/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.h index ac5c648ead..f7ca775829 100644 --- a/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.h +++ b/libraries/steamworks-wrapper/src/steamworks-wrapper/SteamClient.h @@ -22,6 +22,8 @@ using TicketRequestCallback = std::function; class SteamClient { public: + static bool isRunning(); + static bool init(); static void shutdown();