Merge remote-tracking branch 'upstream/feature_derpstances' into feature_derpstances
This commit is contained in:
@ -155,10 +155,10 @@ public:
|
||||
virtual SettingsObject &settings() const;
|
||||
|
||||
/// returns a valid update task
|
||||
virtual std::shared_ptr<Task> doUpdate(bool only_prepare) = 0;
|
||||
virtual std::shared_ptr<Task> doUpdate() = 0;
|
||||
|
||||
/// returns a valid minecraft process, ready for launch with the given account.
|
||||
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0;
|
||||
virtual MinecraftProcess *prepareForLaunch(AuthSessionPtr account) = 0;
|
||||
|
||||
/// do any necessary cleanups after the instance finishes. also runs before
|
||||
/// 'prepareForLaunch'
|
||||
|
@ -42,15 +42,15 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings,
|
||||
settings->registerSetting("IntendedJarVersion", "");
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> LegacyInstance::doUpdate(bool only_prepare)
|
||||
std::shared_ptr<Task> LegacyInstance::doUpdate()
|
||||
{
|
||||
// make sure the jar mods list is initialized by asking for it.
|
||||
auto list = jarModList();
|
||||
// create an update task
|
||||
return std::shared_ptr<Task>(new LegacyUpdate(this, only_prepare, this));
|
||||
return std::shared_ptr<Task>(new LegacyUpdate(this, this));
|
||||
}
|
||||
|
||||
MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
|
||||
MinecraftProcess *LegacyInstance::prepareForLaunch(AuthSessionPtr account)
|
||||
{
|
||||
MinecraftProcess *proc = new MinecraftProcess(this);
|
||||
|
||||
@ -66,13 +66,14 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
|
||||
if (settings().get("LaunchMaximized").toBool())
|
||||
windowParams = "max";
|
||||
else
|
||||
windowParams = QString("%1x%2").arg(settings().get("MinecraftWinWidth").toInt()).arg(
|
||||
settings().get("MinecraftWinHeight").toInt());
|
||||
windowParams = QString("%1x%2")
|
||||
.arg(settings().get("MinecraftWinWidth").toInt())
|
||||
.arg(settings().get("MinecraftWinHeight").toInt());
|
||||
|
||||
QString lwjgl = QDir(MMC->settings()->get("LWJGLDir").toString() + "/" + lwjglVersion())
|
||||
.absolutePath();
|
||||
launchScript += "userName " + account->currentProfile()->name + "\n";
|
||||
launchScript += "sessionId " + account->sessionId() + "\n";
|
||||
launchScript += "userName " + account->player_name + "\n";
|
||||
launchScript += "sessionId " + account->session + "\n";
|
||||
launchScript += "windowTitle " + windowTitle() + "\n";
|
||||
launchScript += "windowParams " + windowParams + "\n";
|
||||
launchScript += "lwjgl " + lwjgl + "\n";
|
||||
|
@ -76,9 +76,9 @@ public:
|
||||
|
||||
virtual bool shouldUpdate() const override;
|
||||
virtual void setShouldUpdate(bool val) override;
|
||||
virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override;
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
|
||||
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
|
||||
virtual MinecraftProcess *prepareForLaunch(AuthSessionPtr account) override;
|
||||
virtual void cleanupAfterRun() override;
|
||||
virtual QDialog *createModEditDialog(QWidget *parent) override;
|
||||
|
||||
|
@ -27,13 +27,13 @@
|
||||
#include "logger/QsLog.h"
|
||||
#include "logic/net/URLConstants.h"
|
||||
|
||||
LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool only_prepare, QObject *parent)
|
||||
: Task(parent), m_inst(inst), m_only_prepare(only_prepare)
|
||||
LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
|
||||
{
|
||||
}
|
||||
|
||||
void LegacyUpdate::executeTask()
|
||||
{
|
||||
/*
|
||||
if(m_only_prepare)
|
||||
{
|
||||
// FIXME: think this through some more.
|
||||
@ -49,8 +49,9 @@ void LegacyUpdate::executeTask()
|
||||
}
|
||||
else
|
||||
{
|
||||
lwjglStart();
|
||||
}
|
||||
*/
|
||||
lwjglStart();
|
||||
//}
|
||||
}
|
||||
|
||||
void LegacyUpdate::lwjglStart()
|
||||
@ -268,7 +269,6 @@ void LegacyUpdate::jarStart()
|
||||
|
||||
auto dljob = new NetJob("Minecraft.jar for version " + version_id);
|
||||
|
||||
|
||||
auto metacache = MMC->metacache();
|
||||
auto entry = metacache->resolveEntry("versions", localPath);
|
||||
dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
|
||||
@ -425,7 +425,7 @@ void LegacyUpdate::ModTheJar()
|
||||
auto &mod = modList->operator[](i);
|
||||
|
||||
// do not merge disabled mods.
|
||||
if(!mod.enabled())
|
||||
if (!mod.enabled())
|
||||
continue;
|
||||
|
||||
if (mod.type() == Mod::MOD_ZIPFILE)
|
||||
|
@ -31,7 +31,7 @@ class LegacyUpdate : public Task
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LegacyUpdate(BaseInstance *inst, bool only_prepare, QObject *parent = 0);
|
||||
explicit LegacyUpdate(BaseInstance *inst, QObject *parent = 0);
|
||||
virtual void executeTask();
|
||||
|
||||
private
|
||||
@ -72,5 +72,4 @@ private:
|
||||
private:
|
||||
NetJobPtr legacyDownloadJob;
|
||||
BaseInstance *m_inst = nullptr;
|
||||
bool m_only_prepare = false;
|
||||
};
|
||||
|
@ -79,26 +79,18 @@ void MinecraftProcess::setWorkdir(QString path)
|
||||
|
||||
QString MinecraftProcess::censorPrivateInfo(QString in)
|
||||
{
|
||||
if(!m_account)
|
||||
if(!m_session)
|
||||
return in;
|
||||
|
||||
QString sessionId = m_account->sessionId();
|
||||
QString accessToken = m_account->accessToken();
|
||||
QString clientToken = m_account->clientToken();
|
||||
in.replace(sessionId, "<SESSION ID>");
|
||||
in.replace(accessToken, "<ACCESS TOKEN>");
|
||||
in.replace(clientToken, "<CLIENT TOKEN>");
|
||||
auto profile = m_account->currentProfile();
|
||||
if(profile)
|
||||
{
|
||||
QString profileId = profile->id;
|
||||
QString profileName = profile->name;
|
||||
in.replace(profileId, "<PROFILE ID>");
|
||||
in.replace(profileName, "<PROFILE NAME>");
|
||||
}
|
||||
if(m_session->session != "-")
|
||||
in.replace(m_session->session, "<SESSION ID>");
|
||||
in.replace(m_session->access_token, "<ACCESS TOKEN>");
|
||||
in.replace(m_session->client_token, "<CLIENT TOKEN>");
|
||||
in.replace(m_session->uuid, "<PROFILE ID>");
|
||||
in.replace(m_session->player_name, "<PROFILE NAME>");
|
||||
|
||||
auto i = m_account->user().properties.begin();
|
||||
while (i != m_account->user().properties.end())
|
||||
auto i = m_session->u.properties.begin();
|
||||
while (i != m_session->u.properties.end())
|
||||
{
|
||||
in.replace(i.value(), "<" + i.key().toUpper() + ">");
|
||||
++i;
|
||||
|
@ -78,9 +78,9 @@ public:
|
||||
|
||||
void killMinecraft();
|
||||
|
||||
inline void setLogin(MojangAccountPtr account)
|
||||
inline void setLogin(AuthSessionPtr session)
|
||||
{
|
||||
m_account = account;
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
signals:
|
||||
@ -117,7 +117,7 @@ protected:
|
||||
QString m_out_leftover;
|
||||
QProcess m_prepostlaunchprocess;
|
||||
bool killed = false;
|
||||
MojangAccountPtr m_account;
|
||||
AuthSessionPtr m_session;
|
||||
QString launchScript;
|
||||
QString m_nativeFolder;
|
||||
|
||||
|
@ -104,7 +104,7 @@ bool OneSixFTBInstance::menuActionEnabled(QString action_name) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> OneSixFTBInstance::doUpdate(bool only_prepare)
|
||||
std::shared_ptr<Task> OneSixFTBInstance::doUpdate()
|
||||
{
|
||||
std::shared_ptr<SequentialTask> task;
|
||||
task.reset(new SequentialTask(this));
|
||||
@ -112,11 +112,11 @@ std::shared_ptr<Task> OneSixFTBInstance::doUpdate(bool only_prepare)
|
||||
{
|
||||
task->addTask(std::shared_ptr<Task>(MMC->forgelist()->getLoadTask()));
|
||||
}
|
||||
task->addTask(OneSixInstance::doUpdate(only_prepare));
|
||||
task->addTask(OneSixInstance::doUpdate());
|
||||
task->addTask(std::shared_ptr<Task>(new OneSixFTBInstanceForge(m_forge->version(), this, this)));
|
||||
//FIXME: yes. this may appear dumb. but the previous step can change the list, so we do it all again.
|
||||
//TODO: Add a graph task. Construct graphs of tasks so we may capture the logic properly.
|
||||
task->addTask(OneSixInstance::doUpdate(only_prepare));
|
||||
task->addTask(OneSixInstance::doUpdate());
|
||||
return task;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
virtual QString getStatusbarDescription();
|
||||
virtual bool menuActionEnabled(QString action_name) const;
|
||||
|
||||
virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override;
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
|
||||
virtual QString id() const;
|
||||
|
||||
|
@ -46,9 +46,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings,
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> OneSixInstance::doUpdate(bool only_prepare)
|
||||
std::shared_ptr<Task> OneSixInstance::doUpdate()
|
||||
{
|
||||
return std::shared_ptr<Task>(new OneSixUpdate(this, only_prepare));
|
||||
return std::shared_ptr<Task>(new OneSixUpdate(this));
|
||||
}
|
||||
|
||||
QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
||||
@ -135,7 +135,7 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr<OneSixVersion> version)
|
||||
return virtualRoot;
|
||||
}
|
||||
|
||||
QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
|
||||
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
||||
{
|
||||
I_D(OneSixInstance);
|
||||
auto version = d->version;
|
||||
@ -147,17 +147,11 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
|
||||
|
||||
QMap<QString, QString> token_mapping;
|
||||
// yggdrasil!
|
||||
token_mapping["auth_username"] = account->username();
|
||||
token_mapping["auth_session"] = account->sessionId();
|
||||
token_mapping["auth_access_token"] = account->accessToken();
|
||||
token_mapping["auth_player_name"] = account->currentProfile()->name;
|
||||
token_mapping["auth_uuid"] = account->currentProfile()->id;
|
||||
|
||||
// this is for offline?:
|
||||
/*
|
||||
map["auth_player_name"] = "Player";
|
||||
map["auth_player_name"] = "00000000-0000-0000-0000-000000000000";
|
||||
*/
|
||||
token_mapping["auth_username"] = session->username;
|
||||
token_mapping["auth_session"] = session->session;
|
||||
token_mapping["auth_access_token"] = session->access_token;
|
||||
token_mapping["auth_player_name"] = session->player_name;
|
||||
token_mapping["auth_uuid"] = session->uuid;
|
||||
|
||||
// these do nothing and are stupid.
|
||||
token_mapping["profile_name"] = name();
|
||||
@ -168,17 +162,8 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
|
||||
QString absAssetsDir = QDir("assets/").absolutePath();
|
||||
token_mapping["game_assets"] = reconstructAssets(d->version).absolutePath();
|
||||
|
||||
auto user = account->user();
|
||||
QJsonObject userAttrs;
|
||||
for (auto key : user.properties.keys())
|
||||
{
|
||||
auto array = QJsonArray::fromStringList(user.properties.values(key));
|
||||
userAttrs.insert(key, array);
|
||||
}
|
||||
QJsonDocument value(userAttrs);
|
||||
|
||||
token_mapping["user_properties"] = value.toJson(QJsonDocument::Compact);
|
||||
token_mapping["user_type"] = account->currentProfile()->legacy ? "legacy" : "mojang";
|
||||
token_mapping["user_properties"] = session->serializeUserProperties();
|
||||
token_mapping["user_type"] = session->user_type;
|
||||
// 1.7.3+ assets tokens
|
||||
token_mapping["assets_root"] = absAssetsDir;
|
||||
token_mapping["assets_index_name"] = version->assets;
|
||||
@ -191,7 +176,7 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
|
||||
return parts;
|
||||
}
|
||||
|
||||
MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account)
|
||||
MinecraftProcess *OneSixInstance::prepareForLaunch(AuthSessionPtr session)
|
||||
{
|
||||
I_D(OneSixInstance);
|
||||
|
||||
@ -216,7 +201,7 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account)
|
||||
}
|
||||
launchScript += "mainClass " + version->mainClass + "\n";
|
||||
|
||||
for (auto param : processMinecraftArgs(account))
|
||||
for (auto param : processMinecraftArgs(session))
|
||||
{
|
||||
launchScript += "param " + param + "\n";
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
QString loaderModsDir() const;
|
||||
virtual QString instanceConfigFolder() const override;
|
||||
|
||||
virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override;
|
||||
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
virtual MinecraftProcess *prepareForLaunch(AuthSessionPtr session) override;
|
||||
|
||||
virtual void cleanupAfterRun() override;
|
||||
|
||||
@ -72,6 +72,6 @@ signals:
|
||||
void versionReloaded();
|
||||
|
||||
private:
|
||||
QStringList processMinecraftArgs(MojangAccountPtr account);
|
||||
QStringList processMinecraftArgs(AuthSessionPtr account);
|
||||
QDir reconstructAssets(std::shared_ptr<OneSixVersion> version);
|
||||
};
|
||||
|
@ -35,8 +35,8 @@
|
||||
#include "pathutils.h"
|
||||
#include <JlCompress.h>
|
||||
|
||||
OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool only_prepare, QObject *parent)
|
||||
: Task(parent), m_inst(inst), m_only_prepare(only_prepare)
|
||||
OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent)
|
||||
: Task(parent), m_inst(inst)
|
||||
{
|
||||
}
|
||||
|
||||
@ -52,12 +52,6 @@ void OneSixUpdate::executeTask()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_only_prepare)
|
||||
{
|
||||
prepareForLaunch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_inst->shouldUpdate())
|
||||
{
|
||||
// Get a pointer to the version object that corresponds to the instance's version.
|
||||
@ -222,7 +216,7 @@ void OneSixUpdate::assetIndexFailed()
|
||||
|
||||
void OneSixUpdate::assetsFinished()
|
||||
{
|
||||
prepareForLaunch();
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
void OneSixUpdate::assetsFailed()
|
||||
@ -330,43 +324,3 @@ void OneSixUpdate::jarlibFailed()
|
||||
emitFailed("Failed to download the following files:\n" + failed_all +
|
||||
"\n\nPlease try again.");
|
||||
}
|
||||
|
||||
void OneSixUpdate::prepareForLaunch()
|
||||
{
|
||||
setStatus(tr("Preparing for launch..."));
|
||||
QLOG_INFO() << m_inst->name() << ": preparing for launch";
|
||||
auto OneSix_inst = (OneSixInstance *)m_inst;
|
||||
|
||||
// delete any leftovers, if they are present.
|
||||
OneSix_inst->cleanupAfterRun();
|
||||
|
||||
QString natives_dir_raw = PathCombine(OneSix_inst->instanceRoot(), "natives/");
|
||||
auto version = OneSix_inst->getFullVersion();
|
||||
if (!version)
|
||||
{
|
||||
emitFailed("The version information for this instance is not complete. Try re-creating "
|
||||
"it or changing the version.");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
for (auto lib : version->getActiveNativeLibs())
|
||||
{
|
||||
if (!lib->filesExist())
|
||||
{
|
||||
emitFailed("Native library is missing some files:\n" + lib->storagePath() +
|
||||
"\n\nRun the instance at least once in online mode to get all the "
|
||||
"required files.");
|
||||
return;
|
||||
}
|
||||
if (!lib->extractTo(natives_dir_raw))
|
||||
{
|
||||
emitFailed("Could not extract the native library:\n" + lib->storagePath() + " to " +
|
||||
natives_dir_raw +
|
||||
"\n\nMake sure MultiMC has appropriate permissions and there is enough "
|
||||
"space on the storage device.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
emitSucceeded();
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class OneSixUpdate : public Task
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OneSixUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent = 0);
|
||||
explicit OneSixUpdate(BaseInstance *inst, QObject *parent = 0);
|
||||
virtual void executeTask();
|
||||
|
||||
private
|
||||
@ -49,9 +49,6 @@ slots:
|
||||
void assetsFinished();
|
||||
void assetsFailed();
|
||||
|
||||
// extract the appropriate libraries
|
||||
void prepareForLaunch();
|
||||
|
||||
private:
|
||||
NetJobPtr specificVersionDownloadJob;
|
||||
NetJobPtr jarlibDownloadJob;
|
||||
@ -59,5 +56,4 @@ private:
|
||||
// target version, determined during this task
|
||||
std::shared_ptr<MinecraftVersion> targetVersion;
|
||||
BaseInstance *m_inst = nullptr;
|
||||
bool m_only_prepare = false;
|
||||
};
|
||||
|
30
logic/auth/AuthSession.cpp
Normal file
30
logic/auth/AuthSession.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "AuthSession.h"
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QStringList>
|
||||
|
||||
QString AuthSession::serializeUserProperties()
|
||||
{
|
||||
QJsonObject userAttrs;
|
||||
for (auto key : u.properties.keys())
|
||||
{
|
||||
auto array = QJsonArray::fromStringList(u.properties.values(key));
|
||||
userAttrs.insert(key, array);
|
||||
}
|
||||
QJsonDocument value(userAttrs);
|
||||
return value.toJson(QJsonDocument::Compact);
|
||||
|
||||
}
|
||||
|
||||
bool AuthSession::MakeOffline(QString offline_playername)
|
||||
{
|
||||
if (status != PlayableOffline && status != PlayableOnline)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
session = "-";
|
||||
player_name = offline_playername;
|
||||
status = PlayableOffline;
|
||||
return true;
|
||||
}
|
49
logic/auth/AuthSession.h
Normal file
49
logic/auth/AuthSession.h
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QMultiMap>
|
||||
#include <memory>
|
||||
|
||||
struct User
|
||||
{
|
||||
QString id;
|
||||
QMultiMap<QString, QString> properties;
|
||||
};
|
||||
|
||||
struct AuthSession
|
||||
{
|
||||
bool MakeOffline(QString offline_playername);
|
||||
|
||||
QString serializeUserProperties();
|
||||
|
||||
enum Status
|
||||
{
|
||||
Undetermined,
|
||||
RequiresPassword,
|
||||
PlayableOffline,
|
||||
PlayableOnline
|
||||
} status = Undetermined;
|
||||
|
||||
User u;
|
||||
|
||||
// client token
|
||||
QString client_token;
|
||||
// account user name
|
||||
QString username;
|
||||
// combined session ID
|
||||
QString session;
|
||||
// volatile auth token
|
||||
QString access_token;
|
||||
// profile name
|
||||
QString player_name;
|
||||
// profile ID
|
||||
QString uuid;
|
||||
// 'legacy' or 'mojang', depending on account type
|
||||
QString user_type;
|
||||
// Did the auth server reply?
|
||||
bool auth_server_online = false;
|
||||
// Did the user request online mode?
|
||||
bool wants_online = true;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<AuthSession> AuthSessionPtr;
|
@ -24,6 +24,7 @@
|
||||
#include <QJsonArray>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <logger/QsLog.h>
|
||||
|
||||
@ -165,15 +166,26 @@ AccountStatus MojangAccount::accountStatus() const
|
||||
{
|
||||
if (m_accessToken.isEmpty())
|
||||
return NotVerified;
|
||||
if (!m_online)
|
||||
else
|
||||
return Verified;
|
||||
return Online;
|
||||
}
|
||||
|
||||
std::shared_ptr<YggdrasilTask> MojangAccount::login(QString password)
|
||||
std::shared_ptr<YggdrasilTask> MojangAccount::login(AuthSessionPtr session,
|
||||
QString password)
|
||||
{
|
||||
if (m_currentTask)
|
||||
return m_currentTask;
|
||||
Q_ASSERT(m_currentTask.get() == nullptr);
|
||||
|
||||
// take care of the true offline status
|
||||
if (accountStatus() == NotVerified && password.isEmpty())
|
||||
{
|
||||
if (session)
|
||||
{
|
||||
session->status = AuthSession::RequiresPassword;
|
||||
fillSession(session);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (password.isEmpty())
|
||||
{
|
||||
m_currentTask.reset(new RefreshTask(this));
|
||||
@ -182,6 +194,8 @@ std::shared_ptr<YggdrasilTask> MojangAccount::login(QString password)
|
||||
{
|
||||
m_currentTask.reset(new AuthenticateTask(this, password));
|
||||
}
|
||||
m_currentTask->assignSession(session);
|
||||
|
||||
connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
|
||||
connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
|
||||
return m_currentTask;
|
||||
@ -189,24 +203,76 @@ std::shared_ptr<YggdrasilTask> MojangAccount::login(QString password)
|
||||
|
||||
void MojangAccount::authSucceeded()
|
||||
{
|
||||
m_online = true;
|
||||
auto session = m_currentTask->getAssignedSession();
|
||||
if (session)
|
||||
{
|
||||
session->status =
|
||||
session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
|
||||
fillSession(session);
|
||||
session->auth_server_online = true;
|
||||
}
|
||||
m_currentTask.reset();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void MojangAccount::authFailed(QString reason)
|
||||
{
|
||||
auto session = m_currentTask->getAssignedSession();
|
||||
// This is emitted when the yggdrasil tasks time out or are cancelled.
|
||||
// -> we treat the error as no-op
|
||||
if (reason == "Yggdrasil task cancelled.")
|
||||
{
|
||||
// do nothing
|
||||
if (session)
|
||||
{
|
||||
session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
|
||||
: AuthSession::RequiresPassword;
|
||||
session->auth_server_online = false;
|
||||
fillSession(session);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_online = false;
|
||||
m_accessToken = QString();
|
||||
emit changed();
|
||||
if (session)
|
||||
{
|
||||
session->status = AuthSession::RequiresPassword;
|
||||
session->auth_server_online = true;
|
||||
fillSession(session);
|
||||
}
|
||||
}
|
||||
m_currentTask.reset();
|
||||
}
|
||||
|
||||
void MojangAccount::fillSession(AuthSessionPtr session)
|
||||
{
|
||||
// the user name. you have to have an user name
|
||||
session->username = m_username;
|
||||
// volatile auth token
|
||||
session->access_token = m_accessToken;
|
||||
// the semi-permanent client token
|
||||
session->client_token = m_clientToken;
|
||||
if (currentProfile())
|
||||
{
|
||||
// profile name
|
||||
session->player_name = currentProfile()->name;
|
||||
// profile ID
|
||||
session->uuid = currentProfile()->id;
|
||||
// 'legacy' or 'mojang', depending on account type
|
||||
session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
|
||||
if (!session->access_token.isEmpty())
|
||||
{
|
||||
session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
|
||||
}
|
||||
else
|
||||
{
|
||||
session->session = "-";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
session->player_name = "Player";
|
||||
session->session = "-";
|
||||
}
|
||||
session->u = user();
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <QMap>
|
||||
|
||||
#include <memory>
|
||||
#include "AuthSession.h"
|
||||
|
||||
class Task;
|
||||
class YggdrasilTask;
|
||||
@ -45,17 +46,10 @@ struct AccountProfile
|
||||
bool legacy;
|
||||
};
|
||||
|
||||
struct User
|
||||
{
|
||||
QString id;
|
||||
QMultiMap<QString,QString> properties;
|
||||
};
|
||||
|
||||
enum AccountStatus
|
||||
{
|
||||
NotVerified,
|
||||
Verified,
|
||||
Online
|
||||
Verified
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,7 +78,7 @@ public: /* construction */
|
||||
QJsonObject saveToJson() const;
|
||||
|
||||
public: /* manipulation */
|
||||
/**
|
||||
/**
|
||||
* 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.
|
||||
@ -95,12 +89,9 @@ public: /* manipulation */
|
||||
* 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<YggdrasilTask> login(QString password = QString());
|
||||
std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session,
|
||||
QString password = QString());
|
||||
|
||||
void downgrade()
|
||||
{
|
||||
m_online = false;
|
||||
}
|
||||
public: /* queries */
|
||||
const QString &username() const
|
||||
{
|
||||
@ -122,19 +113,11 @@ public: /* queries */
|
||||
return m_profiles;
|
||||
}
|
||||
|
||||
const User & user()
|
||||
const User &user()
|
||||
{
|
||||
return m_user;
|
||||
}
|
||||
|
||||
//! Get the session ID required for legacy Minecraft versions
|
||||
QString sessionId() const
|
||||
{
|
||||
if (m_currentProfile != -1 && !m_accessToken.isEmpty())
|
||||
return "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
|
||||
return "-";
|
||||
}
|
||||
|
||||
//! Returns the currently selected profile (if none, returns nullptr)
|
||||
const AccountProfile *currentProfile() const;
|
||||
|
||||
@ -169,16 +152,17 @@ protected: /* variables */
|
||||
// the user structure, whatever it is.
|
||||
User m_user;
|
||||
|
||||
// true when the account is verified
|
||||
bool m_online = false;
|
||||
|
||||
// current task we are executing here
|
||||
std::shared_ptr<YggdrasilTask> m_currentTask;
|
||||
|
||||
private slots:
|
||||
private
|
||||
slots:
|
||||
void authSucceeded();
|
||||
void authFailed(QString reason);
|
||||
|
||||
private:
|
||||
void fillSession(AuthSessionPtr session);
|
||||
|
||||
public:
|
||||
friend class YggdrasilTask;
|
||||
friend class AuthenticateTask;
|
||||
|
@ -35,6 +35,21 @@ class YggdrasilTask : public Task
|
||||
public:
|
||||
explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0);
|
||||
|
||||
/**
|
||||
* assign a session to this task. the session will be filled with required infomration
|
||||
* upon completion
|
||||
*/
|
||||
void assignSession(AuthSessionPtr session)
|
||||
{
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
/// get the assigned session for filling with information.
|
||||
AuthSessionPtr getAssignedSession()
|
||||
{
|
||||
return m_session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class describing a Yggdrasil error response.
|
||||
*/
|
||||
@ -117,4 +132,6 @@ protected:
|
||||
|
||||
const int timeout_max = 10000;
|
||||
const int time_step = 50;
|
||||
|
||||
AuthSessionPtr m_session;
|
||||
};
|
||||
|
@ -25,8 +25,7 @@
|
||||
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
RefreshTask::RefreshTask(MojangAccount *account, QObject *parent)
|
||||
: YggdrasilTask(account, parent)
|
||||
RefreshTask::RefreshTask(MojangAccount *account) : YggdrasilTask(account)
|
||||
{
|
||||
}
|
||||
|
||||
@ -126,7 +125,6 @@ bool RefreshTask::processResponse(QJsonObject responseData)
|
||||
m_account->m_user = u;
|
||||
}
|
||||
|
||||
|
||||
// We've made it through the minefield of possible errors. Return true to indicate that
|
||||
// we've succeeded.
|
||||
QLOG_DEBUG() << "Finished reading refresh response.";
|
||||
|
@ -30,7 +30,7 @@ class RefreshTask : public YggdrasilTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RefreshTask(MojangAccount * account, QObject *parent = 0);
|
||||
RefreshTask(MojangAccount * account);
|
||||
|
||||
protected:
|
||||
virtual QJsonObject getRequestContent() const;
|
||||
@ -41,3 +41,4 @@ protected:
|
||||
|
||||
QString getStateMessage(const YggdrasilTask::State state) const;
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,6 @@ void NetJob::partSucceeded(int index)
|
||||
num_succeeded++;
|
||||
QLOG_INFO() << m_job_name.toLocal8Bit() << "progress:" << num_succeeded << "/"
|
||||
<< downloads.size();
|
||||
emit filesProgress(num_succeeded, num_failed, downloads.size());
|
||||
|
||||
if (num_failed + num_succeeded == downloads.size())
|
||||
{
|
||||
@ -55,7 +54,6 @@ void NetJob::partFailed(int index)
|
||||
{
|
||||
QLOG_ERROR() << "Part" << index << "failed 3 times (" << downloads[index]->m_url << ")";
|
||||
num_failed++;
|
||||
emit filesProgress(num_succeeded, num_failed, downloads.size());
|
||||
if (num_failed + num_succeeded == downloads.size())
|
||||
{
|
||||
QLOG_ERROR() << m_job_name.toLocal8Bit() << "failed.";
|
||||
|
@ -84,7 +84,6 @@ public:
|
||||
{
|
||||
return m_job_name;
|
||||
}
|
||||
;
|
||||
virtual bool isRunning() const
|
||||
{
|
||||
return m_running;
|
||||
@ -94,7 +93,6 @@ public:
|
||||
signals:
|
||||
void started();
|
||||
void progress(qint64 current, qint64 total);
|
||||
void filesProgress(int, int, int);
|
||||
void succeeded();
|
||||
void failed();
|
||||
public
|
||||
|
Reference in New Issue
Block a user