mirror of
https://github.com/UltimMC/Launcher.git
synced 2025-12-24 20:34:59 +00:00
@@ -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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ struct User
|
||||
struct MULTIMC_LOGIC_EXPORT AuthSession
|
||||
{
|
||||
bool MakeOffline(QString offline_playername);
|
||||
bool MakeCracked(QString offline_playername);
|
||||
|
||||
QString serializeUserProperties();
|
||||
|
||||
|
||||
@@ -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<YggdrasilTask> 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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<AuthSession>();
|
||||
m_session->MakeCracked(usedname);
|
||||
|
||||
launchInstance();
|
||||
|
||||
// Original login code
|
||||
/*
|
||||
// Find an account to use.
|
||||
std::shared_ptr<MojangAccountList> 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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>162</height>
|
||||
<height>219</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -60,6 +60,30 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="radioLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioMojang">
|
||||
<property name="text">
|
||||
<string>Mojang / Minecraft</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioDummy">
|
||||
<property name="text">
|
||||
<string>Offline (cracked)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
|
||||
Reference in New Issue
Block a user