diff --git a/api/logic/minecraft/auth/AuthSession.cpp b/api/logic/minecraft/auth/AuthSession.cpp index b2ea62c8..35a4ccef 100644 --- a/api/logic/minecraft/auth/AuthSession.cpp +++ b/api/logic/minecraft/auth/AuthSession.cpp @@ -29,17 +29,3 @@ bool AuthSession::MakeOffline(QString offline_playername) status = PlayableOffline; return true; } - -bool AuthSession::MakeCracked(QString offline_playername) -{ - session = "-"; - // Filling session with dummy data - client_token = "ff64ff64ff64ff64ff64ff64ff64ff64"; - access_token = "ff64ff64ff64ff64ff64ff64ff64ff64"; - // TODO: Fetch actual UUID's from Mojang API so they match with real ones - uuid = QString(QCryptographicHash::hash(offline_playername.toLocal8Bit(), QCryptographicHash::Md5).toHex()); - - player_name = offline_playername; - status = PlayableOffline; - return true; -} diff --git a/api/logic/minecraft/auth/AuthSession.h b/api/logic/minecraft/auth/AuthSession.h index 02c7eb47..b397d9a1 100644 --- a/api/logic/minecraft/auth/AuthSession.h +++ b/api/logic/minecraft/auth/AuthSession.h @@ -17,7 +17,6 @@ struct User struct MULTIMC_LOGIC_EXPORT AuthSession { bool MakeOffline(QString offline_playername); - bool MakeCracked(QString offline_playername); QString serializeUserProperties(); diff --git a/api/logic/minecraft/auth/MojangAccount.cpp b/api/logic/minecraft/auth/MojangAccount.cpp index f5853fe3..0774b9a2 100644 --- a/api/logic/minecraft/auth/MojangAccount.cpp +++ b/api/logic/minecraft/auth/MojangAccount.cpp @@ -38,6 +38,7 @@ MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object) return nullptr; } + QString loginType = object.value("loginType").toString("mojang"); QString username = object.value("username").toString(""); QString clientToken = object.value("clientToken").toString(""); QString accessToken = object.value("accessToken").toString(""); @@ -82,6 +83,7 @@ MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object) */ account->m_user = u; } + account->m_loginType = loginType; account->m_username = username; account->m_clientToken = clientToken; account->m_accessToken = accessToken; @@ -106,6 +108,7 @@ MojangAccountPtr MojangAccount::createFromUsername(const QString &username) QJsonObject MojangAccount::saveToJson() const { QJsonObject json; + json.insert("loginType", m_loginType); json.insert("username", m_username); json.insert("clientToken", m_clientToken); json.insert("accessToken", m_accessToken); @@ -142,6 +145,17 @@ QJsonObject MojangAccount::saveToJson() const return json; } +bool MojangAccount::setLoginType(const QString &loginType) +{ + // TODO: Implement a cleaner validity check + if (loginType == "mojang" or loginType == "dummy") + { + m_loginType = loginType; + return true; + } + return false; +} + bool MojangAccount::setCurrentProfile(const QString &profileId) { for (int i = 0; i < m_profiles.length(); i++) @@ -174,6 +188,27 @@ std::shared_ptr MojangAccount::login(AuthSessionPtr session, QStr { Q_ASSERT(m_currentTask.get() == nullptr); + // Handling alternative account types + if (m_loginType == "dummy") + { + if (session) + { + session->status = AuthSession::PlayableOnline; + session->auth_server_online = false; + fillSession(session); + } + if (!currentProfile()) + { + // TODO: Proper profile support (idk how) + auto dummyProfile = AccountProfile(); + dummyProfile.name = m_username; + dummyProfile.id = "-"; + m_profiles.append(dummyProfile); + m_currentProfile = 0; + } + return nullptr; + } + // take care of the true offline status if (accountStatus() == NotVerified && password.isEmpty()) { @@ -280,7 +315,7 @@ void MojangAccount::fillSession(AuthSessionPtr session) } else { - session->player_name = "Player"; + session->player_name = m_username; session->session = "-"; } session->u = user(); diff --git a/api/logic/minecraft/auth/MojangAccount.h b/api/logic/minecraft/auth/MojangAccount.h index 30a5f2ff..96a9f46b 100644 --- a/api/logic/minecraft/auth/MojangAccount.h +++ b/api/logic/minecraft/auth/MojangAccount.h @@ -85,6 +85,12 @@ public: /* construction */ public: /* manipulation */ /** + * Overrides the login type on the account. + * Accepts "mojang" and "dummy". Returns false if other. + */ + bool setLoginType(const QString &loginType); + + /** * 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. @@ -99,6 +105,11 @@ public: /* manipulation */ void invalidateClientToken(); public: /* queries */ + const QString &loginType() const + { + return m_loginType; + } + const QString &username() const { return m_username; @@ -139,6 +150,11 @@ signals: // TODO: better signalling for the various possible state changes - especially errors protected: /* variables */ + // Authentication system used. + // Usable values: "mojang", "dummy" + QString m_loginType; + + // Username taken by account. QString m_username; // Used to identify the client - the user can have multiple clients for the same account diff --git a/application/LaunchController.cpp b/application/LaunchController.cpp index cbb9ca17..4113a0d3 100644 --- a/application/LaunchController.cpp +++ b/application/LaunchController.cpp @@ -36,27 +36,6 @@ void LaunchController::login() { JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget); - // Mojang account login bypass - bool ok = false; - QString usedname = "Player"; - QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), - tr("Choose your offline mode player name."), - QLineEdit::Normal, "Player", &ok); - if (!ok) - { - return; - } - if (name.length()) - { - usedname = name; - } - m_session = std::make_shared(); - m_session->MakeCracked(usedname); - - launchInstance(); - - // Original login code - /* // Find an account to use. std::shared_ptr accounts = MMC->accounts(); MojangAccountPtr account = accounts->activeAccount(); @@ -64,11 +43,11 @@ void LaunchController::login() { // Tell the user they need to log in at least one account in order to play. auto reply = CustomMessageBox::selectable( - m_parentWidget, tr("No Accounts"), - tr("In order to play Minecraft, you must have at least one Mojang or Minecraft " - "account logged in to MultiMC." - "Would you like to open the account manager to add an account now?"), - QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)->exec(); + m_parentWidget, tr("No Accounts"), + tr("In order to play Minecraft, you must have at least one Mojang or Minecraft " + "account logged in to MultiMC." + "Would you like to open the account manager to add an account now?"), + QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)->exec(); if (reply == QMessageBox::Yes) { @@ -135,75 +114,75 @@ void LaunchController::login() } switch (m_session->status) { - case AuthSession::Undetermined: - { - qCritical() << "Received undetermined session status during login. Bye."; - tryagain = false; - emitFailed(tr("Received undetermined session status during login.")); - break; - } - case AuthSession::RequiresPassword: - { - EditAccountDialog passDialog(failReason, m_parentWidget, EditAccountDialog::PasswordField); - auto username = m_session->username; - auto chopN = [](QString toChop, int N) -> QString - { - if(toChop.size() > N) - { - auto left = toChop.left(N); - left += QString("\u25CF").repeated(toChop.size() - N); - return left; - } - return toChop; - }; - - if(username.contains('@')) - { - auto parts = username.split('@'); - auto mailbox = chopN(parts[0],3); - QString domain = chopN(parts[1], 3); - username = mailbox + '@' + domain; - } - passDialog.setUsername(username); - if (passDialog.exec() == QDialog::Accepted) - { - password = passDialog.password(); - } - else - { - tryagain = false; - } - break; - } - case AuthSession::PlayableOffline: - { - // we ask the user for a player name - bool ok = false; - QString usedname = m_session->player_name; - QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), - tr("Choose your offline mode player name."), - QLineEdit::Normal, m_session->player_name, &ok); - if (!ok) + case AuthSession::Undetermined: { + qCritical() << "Received undetermined session status during login. Bye."; tryagain = false; + emitFailed(tr("Received undetermined session status during login.")); break; } - if (name.length()) + case AuthSession::RequiresPassword: { - usedname = name; + EditAccountDialog passDialog(failReason, m_parentWidget, EditAccountDialog::PasswordField); + auto username = m_session->username; + auto chopN = [](QString toChop, int N) -> QString + { + if(toChop.size() > N) + { + auto left = toChop.left(N); + left += QString("\u25CF").repeated(toChop.size() - N); + return left; + } + return toChop; + }; + + if(username.contains('@')) + { + auto parts = username.split('@'); + auto mailbox = chopN(parts[0],3); + QString domain = chopN(parts[1], 3); + username = mailbox + '@' + domain; + } + passDialog.setUsername(username); + if (passDialog.exec() == QDialog::Accepted) + { + password = passDialog.password(); + } + else + { + tryagain = false; + } + break; + } + case AuthSession::PlayableOffline: + { + // we ask the user for a player name + bool ok = false; + QString usedname = m_session->player_name; + QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), + tr("Choose your offline mode player name."), + QLineEdit::Normal, m_session->player_name, &ok); + if (!ok) + { + tryagain = false; + break; + } + if (name.length()) + { + usedname = name; + } + m_session->MakeOffline(usedname); + // offline flavored game from here :3 + } + case AuthSession::PlayableOnline: + { + launchInstance(); + tryagain = false; + return; } - m_session->MakeOffline(usedname); - // offline flavored game from here :3 - } - case AuthSession::PlayableOnline: - { - launchInstance(); - tryagain = false; - return; - } } } - emitFailed(tr("Failed to launch."));*/ + emitFailed(tr("Failed to launch.")); } void LaunchController::launchInstance() diff --git a/application/dialogs/LoginDialog.cpp b/application/dialogs/LoginDialog.cpp index 32f8a48f..dc1fe843 100644 --- a/application/dialogs/LoginDialog.cpp +++ b/application/dialogs/LoginDialog.cpp @@ -43,13 +43,22 @@ void LoginDialog::accept() // Setup the login task and start it m_account = MojangAccount::createFromUsername(ui->userTextBox->text()); + if (ui->radioMojang->isChecked()) + m_account->setLoginType("mojang"); + else if (ui->radioDummy->isChecked()) + m_account->setLoginType("dummy"); m_loginTask = m_account->login(nullptr, ui->passTextBox->text()); connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed); connect(m_loginTask.get(), &Task::succeeded, this, &LoginDialog::onTaskSucceeded); connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus); connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress); - m_loginTask->start(); + if (!m_loginTask) + { + onTaskSucceeded(); + } else { + m_loginTask->start(); + } } void LoginDialog::setUserInputsEnabled(bool enable) diff --git a/application/dialogs/LoginDialog.ui b/application/dialogs/LoginDialog.ui index d92fbae3..9ba5f80d 100644 --- a/application/dialogs/LoginDialog.ui +++ b/application/dialogs/LoginDialog.ui @@ -7,7 +7,7 @@ 0 0 400 - 162 + 219 @@ -60,6 +60,30 @@ + + + + + + Mojang / Minecraft + + + true + + + + + + + Offline (cracked) + + + false + + + + +