/* Copyright 2013-2021 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include "AuthSession.h" #include "AccountProfile.h" #include "Usable.h" #include "providers/BaseAuthProvider.h" #include "multimc_logic_export.h" class Task; class YggdrasilTask; class Account; typedef std::shared_ptr AccountPtr; Q_DECLARE_METATYPE(AccountPtr) /** * A profile within someone's Mojang account. * * Currently, the profile system has not been implemented by Mojang yet, * but we might as well add some things for it in MultiMC right now so * we don't have to rip the code to pieces to add it later. */ enum AccountStatus { NotVerified, Verified }; /** * Object that stores information about a certain Mojang account. * * Said information may include things such as that account's username, client token, and access * token if the user chose to stay logged in. */ class MULTIMC_LOGIC_EXPORT Account : public QObject, public Usable, public std::enable_shared_from_this { Q_OBJECT public: /* construction */ //! Do not copy accounts. ever. explicit Account(const Account &other, QObject *parent) = delete; //! Default constructor explicit Account(QObject *parent = 0) : QObject(parent) {}; //! Creates an empty account for the specified user name. static AccountPtr createFromUsername(const QString &username); //! Loads a Account from the given JSON object. static AccountPtr loadFromJson(const QJsonObject &json); //! Saves a Account to a JSON object and returns it. QJsonObject saveToJson() const; public: /* manipulation */ /** * Overrides the login type on the account. */ bool setProvider(AuthProviderPtr provider); /** * Sets the currently selected profile to the profile with the given ID string. * If profileId is not in the list of available profiles, the function will simply return * false. */ bool setCurrentProfile(const QString &profileId); /** * Attempt to login. Empty password means we use the token. * If the attempt fails because we already are performing some task, it returns false. */ std::shared_ptr login(AuthSessionPtr session, QString password = QString()); void invalidateClientToken(); public: /* queries */ const AuthProviderPtr provider() const { return m_provider; } const QString &username() const { return m_username; } const QString &clientToken() const { return m_clientToken; } const QString &accessToken() const { return m_accessToken; } const QList &profiles() const { return m_profiles; } const User &user() { return m_user; } //! Returns the currently selected profile (if none, returns nullptr) const AccountProfile *currentProfile() const; //! Returns whether the account is NotVerified, Verified or Online AccountStatus accountStatus() const; signals: /** * This signal is emitted when the account changes */ void changed(); // TODO: better signalling for the various possible state changes - especially errors protected: /* variables */ // Authentication system used. // Usable values: "mojang", "dummy", "elyby" AuthProviderPtr m_provider; // Username taken by account. QString m_username; // Used to identify the client - the user can have multiple clients for the same account // Think: different launchers, all connecting to the same account/profile QString m_clientToken; // Blank if not logged in. QString m_accessToken; // Index of the selected profile within the list of available // profiles. -1 if nothing is selected. int m_currentProfile = -1; // List of available profiles. QList m_profiles; // the user structure, whatever it is. User m_user; // current task we are executing here std::shared_ptr m_currentTask; protected: /* methods */ void incrementUses() override; void decrementUses() override; private slots: void authSucceeded(); void authFailed(QString reason); private: void fillSession(AuthSessionPtr session); public: friend class YggdrasilTask; friend class AuthenticateTask; friend class ValidateTask; friend class RefreshTask; };