mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 07:56:55 +02:00
Interface login through steam
This commit is contained in:
parent
45921a5c8d
commit
cea0e182c0
10 changed files with 275 additions and 17 deletions
BIN
interface/resources/images/steam-sign-in.png
Normal file
BIN
interface/resources/images/steam-sign-in.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
|
@ -203,24 +203,48 @@ ScrollingWindow {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Row {
|
||||
width: loginDialog.inputWidth
|
||||
height: loginDialog.inputHeight
|
||||
radius: height / 2
|
||||
color: "#353535"
|
||||
|
||||
TextInput {
|
||||
anchors.fill: parent
|
||||
text: "Login"
|
||||
color: "white"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Rectangle {
|
||||
width: loginDialog.inputWidth / 3
|
||||
height: loginDialog.inputHeight
|
||||
radius: height / 2
|
||||
color: "#353535"
|
||||
|
||||
TextInput {
|
||||
anchors.fill: parent
|
||||
text: "Login"
|
||||
color: "white"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
loginDialog.login(username.text, password.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
loginDialog.login(username.text, password.text)
|
||||
Image {
|
||||
source: "../images/steam-sign-in.png"
|
||||
width: loginDialog.inputWidth / 3
|
||||
height: loginDialog.inputHeight
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
leftMargin: loginDialog.inputHeight / 4
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
loginDialog.loginThroughSteam()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,15 +86,16 @@
|
|||
#include <PhysicsHelpers.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include <RecordingScriptingInterface.h>
|
||||
#include <RenderableWebEntityItem.h>
|
||||
#include <RenderShadowTask.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <SceneScriptingInterface.h>
|
||||
#include <RecordingScriptingInterface.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <SoundCache.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <steamworks-wrapper/SteamClient.h>
|
||||
#include <Tooltip.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UserActivityLogger.h>
|
||||
|
@ -2910,6 +2911,8 @@ void Application::idle(float nsecsElapsed) {
|
|||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
SteamClient::runCallbacks();
|
||||
|
||||
float secondsSinceLastUpdate = nsecsElapsed / NSECS_PER_MSEC / MSECS_PER_SECOND;
|
||||
|
||||
// If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
@ -20,12 +22,13 @@
|
|||
#include <gl/OpenGLVersionChecker.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include <steamworks-wrapper/SteamClient.h>
|
||||
|
||||
#include "AddressManager.h"
|
||||
#include "Application.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "UserActivityLogger.h"
|
||||
#include "MainWindow.h"
|
||||
#include <thread>
|
||||
|
||||
#ifdef HAS_BUGSPLAT
|
||||
#include <BuildInfo.h>
|
||||
|
@ -137,6 +140,8 @@ int main(int argc, const char* argv[]) {
|
|||
// or in the main window ctor, before GL startup.
|
||||
Application::initPlugins(arguments);
|
||||
|
||||
SteamClient::init();
|
||||
|
||||
int exitCode;
|
||||
{
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
@ -202,6 +207,8 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
Application::shutdownPlugins();
|
||||
|
||||
SteamClient::shutdown();
|
||||
|
||||
qCDebug(interfaceapp, "Normal exit.");
|
||||
#if !defined(DEBUG) && !defined(Q_OS_LINUX)
|
||||
// HACK: exit immediately (don't handle shutdown callbacks) for Release build
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QDesktopServices>
|
||||
|
||||
#include <NetworkingConstants.h>
|
||||
#include <steamworks-wrapper/SteamClient.h>
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "DependencyManager.h"
|
||||
|
@ -82,6 +83,20 @@ void LoginDialog::login(const QString& username, const QString& password) {
|
|||
DependencyManager::get<AccountManager>()->requestAccessToken(username, password);
|
||||
}
|
||||
|
||||
void LoginDialog::loginThroughSteam() {
|
||||
qDebug() << "Attempting to login through Steam";
|
||||
setStatusText("Logging in...");
|
||||
|
||||
SteamClient::requestTicket([this](Ticket ticket) {
|
||||
if (ticket.isNull()) {
|
||||
setStatusText("Steam client not logged into an account");
|
||||
return;
|
||||
}
|
||||
|
||||
DependencyManager::get<AccountManager>()->requestAccessTokenWithSteam(ticket);
|
||||
});
|
||||
}
|
||||
|
||||
void LoginDialog::openUrl(const QString& url) {
|
||||
qDebug() << url;
|
||||
QDesktopServices::openUrl(url);
|
||||
|
|
|
@ -41,6 +41,7 @@ protected:
|
|||
void handleLoginFailed();
|
||||
|
||||
Q_INVOKABLE void login(const QString& username, const QString& password);
|
||||
Q_INVOKABLE void loginThroughSteam();
|
||||
Q_INVOKABLE void openUrl(const QString& url);
|
||||
private:
|
||||
QString _statusText;
|
||||
|
|
|
@ -505,6 +505,29 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
|
|||
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
||||
|
||||
QUrl grantURL = _authURL;
|
||||
grantURL.setPath("/oauth/token");
|
||||
|
||||
const QString ACCOUNT_MANAGER_REQUESTED_SCOPE = "owner";
|
||||
|
||||
QByteArray postData;
|
||||
postData.append("grant_type=password&");
|
||||
postData.append("ticket=" + QUrl::toPercentEncoding(authSessionTicket) + "&");
|
||||
postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
|
||||
|
||||
request.setUrl(grantURL);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
|
||||
QNetworkReply* requestReply = networkAccessManager.post(request, postData);
|
||||
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished);
|
||||
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
void AccountManager::requestAccessTokenFinished() {
|
||||
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
|
||||
public slots:
|
||||
void requestAccessToken(const QString& login, const QString& password);
|
||||
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
|
||||
|
||||
void requestAccessTokenFinished();
|
||||
void requestProfileFinished();
|
||||
|
|
|
@ -11,9 +11,180 @@
|
|||
|
||||
#include "SteamClient.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
|
||||
#endif
|
||||
|
||||
#include <steam/steam_api.h>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
static const Ticket INVALID_TICKET = Ticket();
|
||||
|
||||
class SteamTicketRequests {
|
||||
public:
|
||||
SteamTicketRequests();
|
||||
~SteamTicketRequests();
|
||||
|
||||
HAuthTicket startRequest(TicketRequestCallback callback);
|
||||
void stopRequest(HAuthTicket authTicket);
|
||||
|
||||
STEAM_CALLBACK(SteamTicketRequests, onGetAuthSessionTicketResponse,
|
||||
GetAuthSessionTicketResponse_t, _getAuthSessionTicketResponse);
|
||||
|
||||
private:
|
||||
void stopAll();
|
||||
|
||||
struct PendingTicket {
|
||||
HAuthTicket authTicket;
|
||||
Ticket ticket;
|
||||
TicketRequestCallback callback;
|
||||
};
|
||||
|
||||
std::vector<PendingTicket> _pendingTickets;
|
||||
};
|
||||
|
||||
SteamTicketRequests::SteamTicketRequests() :
|
||||
_getAuthSessionTicketResponse(this, &SteamTicketRequests::onGetAuthSessionTicketResponse)
|
||||
{
|
||||
}
|
||||
|
||||
SteamTicketRequests::~SteamTicketRequests() {
|
||||
stopAll();
|
||||
}
|
||||
|
||||
HAuthTicket SteamTicketRequests::startRequest(TicketRequestCallback callback) {
|
||||
static const uint32 MAX_TICKET_SIZE { 1024 };
|
||||
uint32 ticketSize { 0 };
|
||||
char ticket[MAX_TICKET_SIZE];
|
||||
|
||||
auto authTicket = SteamUser()->GetAuthSessionTicket(ticket, MAX_TICKET_SIZE, &ticketSize);
|
||||
qDebug() << "Got Steam auth session ticket:" << authTicket;
|
||||
|
||||
if (authTicket == k_HAuthTicketInvalid) {
|
||||
qWarning() << "Auth session ticket is invalid.";
|
||||
callback(INVALID_TICKET);
|
||||
} else {
|
||||
PendingTicket pendingTicket{ authTicket, QByteArray(ticket, ticketSize).toHex(), callback };
|
||||
_pendingTickets.push_back(pendingTicket);
|
||||
}
|
||||
|
||||
return authTicket;
|
||||
}
|
||||
|
||||
void SteamTicketRequests::stopRequest(HAuthTicket authTicket) {
|
||||
auto it = std::find_if(_pendingTickets.begin(), _pendingTickets.end(), [&authTicket](const PendingTicket& pendingTicket) {
|
||||
return pendingTicket.authTicket == authTicket;
|
||||
});
|
||||
|
||||
if (it != _pendingTickets.end()) {
|
||||
SteamUser()->CancelAuthTicket(it->authTicket);
|
||||
it->callback(INVALID_TICKET);
|
||||
_pendingTickets.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void SteamTicketRequests::stopAll() {
|
||||
auto steamUser = SteamUser();
|
||||
if (steamUser) {
|
||||
for (const auto& pendingTicket : _pendingTickets) {
|
||||
steamUser->CancelAuthTicket(pendingTicket.authTicket);
|
||||
pendingTicket.callback(INVALID_TICKET);
|
||||
}
|
||||
}
|
||||
_pendingTickets.clear();
|
||||
}
|
||||
|
||||
void SteamTicketRequests::onGetAuthSessionTicketResponse(GetAuthSessionTicketResponse_t* pCallback) {
|
||||
auto authTicket = pCallback->m_hAuthTicket;
|
||||
|
||||
auto it = std::find_if(_pendingTickets.begin(), _pendingTickets.end(), [&authTicket](const PendingTicket& pendingTicket) {
|
||||
return pendingTicket.authTicket == authTicket;
|
||||
});
|
||||
|
||||
|
||||
if (it != _pendingTickets.end()) {
|
||||
|
||||
if (pCallback->m_eResult == k_EResultOK) {
|
||||
qDebug() << "Got steam callback, auth session ticket is valid. Send it." << authTicket;
|
||||
it->callback(it->ticket);
|
||||
} else {
|
||||
qWarning() << "Steam auth session ticket callback encountered an error:" << pCallback->m_eResult;
|
||||
it->callback(INVALID_TICKET);
|
||||
}
|
||||
|
||||
_pendingTickets.erase(it);
|
||||
} else {
|
||||
qWarning() << "Could not find steam auth session ticket in list of pending tickets:" << authTicket;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::atomic_bool initialized { false };
|
||||
static std::unique_ptr<SteamTicketRequests> steamTicketRequests;
|
||||
|
||||
bool SteamClient::init() {
|
||||
if (!initialized) {
|
||||
initialized = SteamAPI_Init();
|
||||
}
|
||||
|
||||
if (!steamTicketRequests && initialized) {
|
||||
steamTicketRequests.reset(new SteamTicketRequests());
|
||||
}
|
||||
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void SteamClient::shutdown() {
|
||||
if (initialized) {
|
||||
SteamAPI_Shutdown();
|
||||
}
|
||||
|
||||
if (steamTicketRequests) {
|
||||
steamTicketRequests.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void SteamClient::runCallbacks() {
|
||||
if (!initialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
qDebug() << "Steam not initialized";
|
||||
return;
|
||||
}
|
||||
|
||||
auto steamPipe = SteamAPI_GetHSteamPipe();
|
||||
if (!steamPipe) {
|
||||
qDebug() << "Could not get SteamPipe";
|
||||
return;
|
||||
}
|
||||
|
||||
Steam_RunCallbacks(steamPipe, false);
|
||||
}
|
||||
|
||||
void SteamClient::requestTicket(TicketRequestCallback callback) {
|
||||
if (!initialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
qDebug() << "Steam not initialized";
|
||||
return;
|
||||
}
|
||||
|
||||
steamTicketRequests->startRequest(callback);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,8 +13,21 @@
|
|||
#ifndef hifi_SteamClient_h
|
||||
#define hifi_SteamClient_h
|
||||
|
||||
class SteamClient {
|
||||
#include <functional>
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
|
||||
using Ticket = QByteArray;
|
||||
using TicketRequestCallback = std::function<void(Ticket)>;
|
||||
|
||||
class SteamClient {
|
||||
public:
|
||||
static bool init();
|
||||
static void shutdown();
|
||||
|
||||
static void runCallbacks();
|
||||
|
||||
static void requestTicket(TicketRequestCallback callback);
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue