diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | gui/MainWindow.cpp | 204 | ||||
-rw-r--r-- | gui/MainWindow.h | 15 | ||||
-rw-r--r-- | gui/MainWindow.ui | 60 | ||||
-rw-r--r-- | gui/dialogs/AccountListDialog.cpp | 2 | ||||
-rw-r--r-- | logic/BaseInstance.h | 4 | ||||
-rw-r--r-- | logic/LegacyInstance.cpp | 15 | ||||
-rw-r--r-- | logic/LegacyInstance.h | 4 | ||||
-rw-r--r-- | logic/LegacyUpdate.cpp | 12 | ||||
-rw-r--r-- | logic/LegacyUpdate.h | 3 | ||||
-rw-r--r-- | logic/MinecraftProcess.cpp | 26 | ||||
-rw-r--r-- | logic/MinecraftProcess.h | 6 | ||||
-rw-r--r-- | logic/OneSixFTBInstance.cpp | 6 | ||||
-rw-r--r-- | logic/OneSixFTBInstance.h | 2 | ||||
-rw-r--r-- | logic/OneSixInstance.cpp | 39 | ||||
-rw-r--r-- | logic/OneSixInstance.h | 6 | ||||
-rw-r--r-- | logic/OneSixUpdate.cpp | 52 | ||||
-rw-r--r-- | logic/OneSixUpdate.h | 6 | ||||
-rw-r--r-- | logic/auth/AuthSession.cpp | 30 | ||||
-rw-r--r-- | logic/auth/AuthSession.h | 49 | ||||
-rw-r--r-- | logic/auth/MojangAccount.cpp | 82 | ||||
-rw-r--r-- | logic/auth/MojangAccount.h | 38 | ||||
-rw-r--r-- | logic/auth/YggdrasilTask.h | 17 | ||||
-rw-r--r-- | logic/auth/flows/RefreshTask.cpp | 4 | ||||
-rw-r--r-- | logic/auth/flows/RefreshTask.h | 3 | ||||
-rw-r--r-- | logic/net/NetJob.cpp | 2 | ||||
-rw-r--r-- | logic/net/NetJob.h | 2 |
27 files changed, 415 insertions, 276 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 047b9edf..5dd7dfb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -365,6 +365,8 @@ logic/net/PasteUpload.cpp logic/net/URLConstants.h # Yggdrasil login stuff +logic/auth/AuthSession.h +logic/auth/AuthSession.cpp logic/auth/MojangAccountList.h logic/auth/MojangAccountList.cpp logic/auth/MojangAccount.h diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index ee9c3fad..9977dc75 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -71,7 +71,6 @@ #include "logic/auth/flows/AuthenticateTask.h" #include "logic/auth/flows/RefreshTask.h" -#include "logic/auth/flows/ValidateTask.h" #include "logic/updater/DownloadUpdateTask.h" @@ -132,8 +131,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); ui->newsToolBar->insertWidget(ui->actionMoreNews, newsLabel); - QObject::connect(newsLabel, &QAbstractButton::clicked, this, &MainWindow::newsButtonClicked); - QObject::connect(MMC->newsChecker().get(), &NewsChecker::newsLoaded, this, &MainWindow::updateNewsLabel); + QObject::connect(newsLabel, &QAbstractButton::clicked, this, + &MainWindow::newsButtonClicked); + QObject::connect(MMC->newsChecker().get(), &NewsChecker::newsLoaded, this, + &MainWindow::updateNewsLabel); updateNewsLabel(); } @@ -173,8 +174,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi view->setModel(proxymodel); view->setContextMenuPolicy(Qt::CustomContextMenu); - connect(view, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(showInstanceContextMenu(const QPoint&))); + connect(view, SIGNAL(customContextMenuRequested(const QPoint &)), this, + SLOT(showInstanceContextMenu(const QPoint &))); ui->horizontalLayout->addWidget(view); } @@ -213,8 +214,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // Start status checker { - connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, &MainWindow::updateStatusUI); - connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, &MainWindow::updateStatusFailedUI); + connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, + &MainWindow::updateStatusUI); + connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, + &MainWindow::updateStatusFailedUI); connect(m_statusRefresh, &QAbstractButton::clicked, this, &MainWindow::reloadStatus); connect(&statusTimer, &QTimer::timeout, this, &MainWindow::reloadStatus); @@ -313,8 +316,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi if (MMC->settings()->get("AutoUpdate").toBool()) on_actionCheckUpdate_triggered(); - connect(MMC->notificationChecker().get(), &NotificationChecker::notificationCheckFinished, - this, &MainWindow::notificationsChanged); + connect(MMC->notificationChecker().get(), + &NotificationChecker::notificationCheckFinished, this, + &MainWindow::notificationsChanged); } setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString()); @@ -330,9 +334,9 @@ MainWindow::~MainWindow() delete drawer; } -void MainWindow::showInstanceContextMenu(const QPoint& pos) +void MainWindow::showInstanceContextMenu(const QPoint &pos) { - if(!view->indexAt(pos).isValid()) + if (!view->indexAt(pos).isValid()) { return; } @@ -522,9 +526,12 @@ static QString convertStatus(const QString &status) { QString ret = "?"; - if(status == "green") ret = "↑"; - else if(status == "yellow") ret = "-"; - else if(status == "red") ret="↓"; + if (status == "green") + ret = "↑"; + else if (status == "yellow") + ret = "-"; + else if (status == "red") + ret = "↓"; return "<span style=\"font-size:11pt; font-weight:600;\">" + ret + "</span>"; } @@ -533,7 +540,7 @@ void MainWindow::reloadStatus() { m_statusRefresh->setChecked(true); MMC->statusChecker()->reloadStatus(); - //updateStatusUI(); + // updateStatusUI(); } static QString makeStatusString(const QMap<QString, QString> statuses) @@ -632,7 +639,8 @@ void MainWindow::notificationsChanged() } QMessageBox box(icon, tr("Notification"), entry.message, QMessageBox::Close, this); - QPushButton *dontShowAgainButton = box.addButton(tr("Don't show again"), QMessageBox::AcceptRole); + QPushButton *dontShowAgainButton = + box.addButton(tr("Don't show again"), QMessageBox::AcceptRole); box.setDefaultButton(QMessageBox::Close); box.exec(); if (box.clickedButton() == dontShowAgainButton) @@ -657,9 +665,9 @@ void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit if (updateDlg.exec(&updateTask)) { UpdateFlags baseFlags = None; - #ifdef MultiMC_UPDATER_DRY_RUN - baseFlags |= DryRun; - #endif +#ifdef MultiMC_UPDATER_DRY_RUN + baseFlags |= DryRun; +#endif if (installOnExit) MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | OnExit); else @@ -751,7 +759,7 @@ void MainWindow::on_actionAddInstance_triggered() if (MMC->accounts()->anyAccountIsValid()) { ProgressDialog loadDialog(this); - auto update = newInstance->doUpdate(false); + auto update = newInstance->doUpdate(); connect(update.get(), &Task::failed, [this](QString reason) { QString error = QString("Instance load failed: %1").arg(reason); @@ -837,7 +845,7 @@ void MainWindow::on_actionChangeInstIcon_triggered() void MainWindow::iconUpdated(QString icon) { - if(icon == m_currentInstIcon) + if (icon == m_currentInstIcon) { ui->actionChangeInstIcon->setIcon(MMC->icons()->getBigIcon(m_currentInstIcon)); } @@ -860,7 +868,8 @@ void MainWindow::setSelectedInstanceById(const QString &id) selectionIndex = proxymodel->mapFromSource(index); } } - view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect); + view->selectionModel()->setCurrentIndex(selectionIndex, + QItemSelectionModel::ClearAndSelect); } void MainWindow::on_actionChangeInstGroup_triggered() @@ -1060,7 +1069,16 @@ void MainWindow::on_actionLaunchInstance_triggered() } } -void MainWindow::doLaunch() +void MainWindow::on_actionLaunchInstanceOffline_triggered() +{ + if (m_selectedInstance) + { + NagUtils::checkJVMArgs(m_selectedInstance->settings().get("JvmArgs").toString(), this); + doLaunch(false); + } +} + +void MainWindow::doLaunch(bool online) { if (!m_selectedInstance) return; @@ -1104,89 +1122,111 @@ void MainWindow::doLaunch() if (!account.get()) return; + // we try empty password first :) + QString password; + // we loop until the user succeeds in logging in or gives up + bool tryagain = true; + // the failure. the default failure. QString failReason = tr("Your account is currently not logged in. Please enter " "your password to log in again."); - // do the login. if the account has an access token, try to refresh it first. - if (account->accountStatus() != NotVerified) + + while (tryagain) { - // We'll need to validate the access token to make sure the account is still logged in. - ProgressDialog progDialog(this); - progDialog.setSkipButton(true, tr("Play Offline")); - auto task = account->login(); - progDialog.exec(task.get()); - - auto status = account->accountStatus(); - if (status != NotVerified) - { - updateInstance(m_selectedInstance, account); - } - else + AuthSessionPtr session(new AuthSession()); + session->wants_online = online; + auto task = account->login(session, password); + if (task) { + // We'll need to validate the access token to make sure the account + // is still logged in. + ProgressDialog progDialog(this); + if (online) + progDialog.setSkipButton(true, tr("Play Offline")); + progDialog.exec(task.get()); if (!task->successful()) { failReason = task->failReason(); } - if (loginWithPassword(account, failReason)) - updateInstance(m_selectedInstance, account); } - // in any case, revert from online to verified. - account->downgrade(); - } - else - { - if (loginWithPassword(account, failReason)) + switch (session->status) { - updateInstance(m_selectedInstance, account); - account->downgrade(); + case AuthSession::Undetermined: + { + QLOG_ERROR() << "Received undetermined session status during login. Bye."; + tryagain = false; + break; } - // in any case, revert from online to verified. - account->downgrade(); - } -} - -bool MainWindow::loginWithPassword(MojangAccountPtr account, const QString &errorMsg) -{ - EditAccountDialog passDialog(errorMsg, this, EditAccountDialog::PasswordField); - if (passDialog.exec() == QDialog::Accepted) - { - // To refresh the token, we just create an authenticate task with the given account and - // the user's password. - ProgressDialog progDialog(this); - auto task = account->login(passDialog.password()); - progDialog.exec(task.get()); - if (task->successful()) - return true; - else + case AuthSession::RequiresPassword: { - // If the authentication task failed, recurse with the task's error message. - return loginWithPassword(account, task->failReason()); + EditAccountDialog passDialog(failReason, this, EditAccountDialog::PasswordField); + 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 = session->player_name; + QString name = QInputDialog::getText(this, tr("Player name"), + tr("Choose your offline mode player name."), + QLineEdit::Normal, session->player_name, &ok); + if (!ok) + { + tryagain = false; + break; + } + if (name.length()) + { + usedname = name; + } + session->MakeOffline(usedname); + // offline flavored game from here :3 + } + case AuthSession::PlayableOnline: + { + // update first if the server actually responded + if (session->auth_server_online) + { + updateInstance(m_selectedInstance, session); + } + else + { + launchInstance(m_selectedInstance, session); + } + tryagain = false; + } } } - return false; } -void MainWindow::updateInstance(BaseInstance *instance, MojangAccountPtr account) +void MainWindow::updateInstance(BaseInstance *instance, AuthSessionPtr session) { - bool only_prepare = account->accountStatus() != Online; - auto updateTask = instance->doUpdate(only_prepare); + auto updateTask = instance->doUpdate(); if (!updateTask) { - launchInstance(instance, account); + launchInstance(instance, session); return; } ProgressDialog tDialog(this); - connect(updateTask.get(), &Task::succeeded, [this, instance, account] - { launchInstance(instance, account); }); + connect(updateTask.get(), &Task::succeeded, [this, instance, session] + { launchInstance(instance, session); }); connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); tDialog.exec(updateTask.get()); } -void MainWindow::launchInstance(BaseInstance *instance, MojangAccountPtr account) +void MainWindow::launchInstance(BaseInstance *instance, AuthSessionPtr session) { Q_ASSERT_X(instance != NULL, "launchInstance", "instance is NULL"); - Q_ASSERT_X(account.get() != nullptr, "launchInstance", "account is NULL"); + Q_ASSERT_X(session.get() != nullptr, "launchInstance", "session is NULL"); - proc = instance->prepareForLaunch(account); + proc = instance->prepareForLaunch(session); if (!proc) return; @@ -1195,7 +1235,7 @@ void MainWindow::launchInstance(BaseInstance *instance, MojangAccountPtr account console = new ConsoleWindow(proc); connect(console, SIGNAL(isClosing()), this, SLOT(instanceEnded())); - proc->setLogin(account); + proc->setLogin(session); proc->launch(); } @@ -1258,7 +1298,7 @@ void MainWindow::on_actionChangeInstMCVersion_triggered() VersionSelectDialog vselect(m_selectedInstance->versionList().get(), tr("Change Minecraft version"), this); vselect.setFilter(1, "OneSix"); - if(!vselect.exec() || !vselect.selectedVersion()) + if (!vselect.exec() || !vselect.selectedVersion()) return; if (!MMC->accounts()->anyAccountIsValid()) @@ -1276,7 +1316,7 @@ void MainWindow::on_actionChangeInstMCVersion_triggered() auto result = CustomMessageBox::selectable( this, tr("Are you sure?"), tr("This will remove any library/version customization you did previously. " - "This includes things like Forge install and similar."), + "This includes things like Forge install and similar."), QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort)->exec(); @@ -1285,7 +1325,7 @@ void MainWindow::on_actionChangeInstMCVersion_triggered() } m_selectedInstance->setIntendedVersionId(vselect.selectedVersion()->descriptor()); - auto updateTask = m_selectedInstance->doUpdate(false); + auto updateTask = m_selectedInstance->doUpdate(); if (!updateTask) { return; @@ -1384,7 +1424,7 @@ void MainWindow::instanceEnded() void MainWindow::checkMigrateLegacyAssets() { int legacyAssets = AssetsUtils::findLegacyAssets(); - if(legacyAssets > 0) + if (legacyAssets > 0) { ProgressDialog migrateDlg(this); AssetsMigrateTask migrateTask(legacyAssets, &migrateDlg); diff --git a/gui/MainWindow.h b/gui/MainWindow.h index eb478776..eeba2c26 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -96,6 +96,8 @@ slots: void on_actionLaunchInstance_triggered(); + void on_actionLaunchInstanceOffline_triggered(); + void on_actionDeleteInstance_triggered(); void on_actionRenameInstance_triggered(); @@ -112,25 +114,18 @@ slots: * Launches the currently selected instance with the default account. * If no default account is selected, prompts the user to pick an account. */ - void doLaunch(); - - /*! - * Opens an input dialog, allowing the user to input their password and refresh its access token. - * This function will execute the proper Yggdrasil task to refresh the access token. - * Returns true if successful. False if the user cancelled. - */ - bool loginWithPassword(MojangAccountPtr account, const QString& errorMsg=""); + void doLaunch(bool online = true); /*! * Launches the given instance with the given account. * This function assumes that the given account has a valid, usable access token. */ - void launchInstance(BaseInstance* instance, MojangAccountPtr account); + void launchInstance(BaseInstance *instance, AuthSessionPtr session); /*! * Prepares the given instance for launch with the given account. */ - void updateInstance(BaseInstance* instance, MojangAccountPtr account); + void updateInstance(BaseInstance *instance, AuthSessionPtr account); void onGameUpdateError(QString error); diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui index 25af6f60..8cf26d18 100644 --- a/gui/MainWindow.ui +++ b/gui/MainWindow.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>688</width> - <height>460</height> + <width>694</width> + <height>563</height> </rect> </property> <property name="windowTitle"> @@ -107,6 +107,7 @@ </attribute> <addaction name="actionChangeInstIcon"/> <addaction name="actionLaunchInstance"/> + <addaction name="actionLaunchInstanceOffline"/> <addaction name="separator"/> <addaction name="actionEditInstNotes"/> <addaction name="actionChangeInstGroup"/> @@ -152,7 +153,9 @@ </widget> <action name="actionAddInstance"> <property name="icon"> - <iconset theme="new"/> + <iconset theme="new"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Add Instance</string> @@ -166,7 +169,9 @@ </action> <action name="actionViewInstanceFolder"> <property name="icon"> - <iconset theme="viewfolder"/> + <iconset theme="viewfolder"> + <normaloff/> + </iconset> </property> <property name="text"> <string>View Instance Folder</string> @@ -180,7 +185,9 @@ </action> <action name="actionRefresh"> <property name="icon"> - <iconset theme="refresh"/> + <iconset theme="refresh"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Refresh</string> @@ -194,7 +201,9 @@ </action> <action name="actionViewCentralModsFolder"> <property name="icon"> - <iconset theme="centralmods"/> + <iconset theme="centralmods"> + <normaloff/> + </iconset> </property> <property name="text"> <string>View Central Mods Folder</string> @@ -208,7 +217,9 @@ </action> <action name="actionCheckUpdate"> <property name="icon"> - <iconset theme="checkupdate"/> + <iconset theme="checkupdate"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Check for Updates</string> @@ -222,7 +233,9 @@ </action> <action name="actionSettings"> <property name="icon"> - <iconset theme="settings"/> + <iconset theme="settings"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Settings</string> @@ -239,7 +252,9 @@ </action> <action name="actionReportBug"> <property name="icon"> - <iconset theme="bug"/> + <iconset theme="bug"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Report a Bug</string> @@ -253,7 +268,9 @@ </action> <action name="actionMoreNews"> <property name="icon"> - <iconset theme="news"/> + <iconset theme="news"> + <normaloff/> + </iconset> </property> <property name="text"> <string>More News</string> @@ -270,7 +287,9 @@ </action> <action name="actionAbout"> <property name="icon"> - <iconset theme="about"/> + <iconset theme="about"> + <normaloff/> + </iconset> </property> <property name="text"> <string>About MultiMC</string> @@ -463,7 +482,9 @@ <bool>true</bool> </property> <property name="icon"> - <iconset theme="cat"/> + <iconset theme="cat"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Meow</string> @@ -474,7 +495,9 @@ </action> <action name="actionCopyInstance"> <property name="icon"> - <iconset theme="copy"/> + <iconset theme="copy"> + <normaloff/> + </iconset> </property> <property name="text"> <string>Copy Instance</string> @@ -494,6 +517,17 @@ <string>Manage your Mojang or Minecraft accounts.</string> </property> </action> + <action name="actionLaunchInstanceOffline"> + <property name="text"> + <string>Play Offline</string> + </property> + <property name="toolTip"> + <string>Launch the selected instance in offline mode.</string> + </property> + <property name="statusTip"> + <string>Launch the selected instance.</string> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11"/> <resources> diff --git a/gui/dialogs/AccountListDialog.cpp b/gui/dialogs/AccountListDialog.cpp index 1712e352..a38035a6 100644 --- a/gui/dialogs/AccountListDialog.cpp +++ b/gui/dialogs/AccountListDialog.cpp @@ -126,7 +126,7 @@ void AccountListDialog::addAccount(const QString& errMsg) MojangAccountPtr account = MojangAccount::createFromUsername(username); ProgressDialog progDialog(this); - auto task = account->login(password); + auto task = account->login(nullptr, password); progDialog.exec(task.get()); if(task->successful()) { diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index a861e9b2..cd49f99b 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -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' diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 2828bcbf..a9f0d112 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -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"; diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h index 1e7d9eb6..636addeb 100644 --- a/logic/LegacyInstance.h +++ b/logic/LegacyInstance.h @@ -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; diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index cb3598a7..5d82a76b 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -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) diff --git a/logic/LegacyUpdate.h b/logic/LegacyUpdate.h index 0b573ca5..613eb1f9 100644 --- a/logic/LegacyUpdate.h +++ b/logic/LegacyUpdate.h @@ -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; }; diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 84610021..9c0a7074 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -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; diff --git a/logic/MinecraftProcess.h b/logic/MinecraftProcess.h index 70e5df52..26214026 100644 --- a/logic/MinecraftProcess.h +++ b/logic/MinecraftProcess.h @@ -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; diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp index e50a5b53..f8e695b9 100644 --- a/logic/OneSixFTBInstance.cpp +++ b/logic/OneSixFTBInstance.cpp @@ -106,7 +106,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)); @@ -114,11 +114,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; } diff --git a/logic/OneSixFTBInstance.h b/logic/OneSixFTBInstance.h index dc028819..bc543aeb 100644 --- a/logic/OneSixFTBInstance.h +++ b/logic/OneSixFTBInstance.h @@ -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; diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index ab87a1db..67649f77 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -41,9 +41,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o reloadFullVersion(); } -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) @@ -130,7 +130,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; @@ -138,17 +138,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(); @@ -159,17 +153,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; @@ -182,7 +167,7 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account) return parts; } -MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account) +MinecraftProcess *OneSixInstance::prepareForLaunch(AuthSessionPtr session) { I_D(OneSixInstance); @@ -207,7 +192,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"; } diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index f869e345..c159723b 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -40,8 +40,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; @@ -73,6 +73,6 @@ public: virtual QString getStatusbarDescription() override; private: - QStringList processMinecraftArgs(MojangAccountPtr account); + QStringList processMinecraftArgs(AuthSessionPtr account); QDir reconstructAssets(std::shared_ptr<OneSixVersion> version); }; diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index ae647bfe..7685952c 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -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(); -} diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h index bc717a94..3c18211e 100644 --- a/logic/OneSixUpdate.h +++ b/logic/OneSixUpdate.h @@ -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; }; diff --git a/logic/auth/AuthSession.cpp b/logic/auth/AuthSession.cpp new file mode 100644 index 00000000..8758bfbd --- /dev/null +++ b/logic/auth/AuthSession.cpp @@ -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; +} diff --git a/logic/auth/AuthSession.h b/logic/auth/AuthSession.h new file mode 100644 index 00000000..2ac170fa --- /dev/null +++ b/logic/auth/AuthSession.h @@ -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; diff --git a/logic/auth/MojangAccount.cpp b/logic/auth/MojangAccount.cpp index f41985ec..6c937ef1 100644 --- a/logic/auth/MojangAccount.cpp +++ b/logic/auth/MojangAccount.cpp @@ -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(); +} diff --git a/logic/auth/MojangAccount.h b/logic/auth/MojangAccount.h index dd5d54ae..a0565e2c 100644 --- a/logic/auth/MojangAccount.h +++ b/logic/auth/MojangAccount.h @@ -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; diff --git a/logic/auth/YggdrasilTask.h b/logic/auth/YggdrasilTask.h index 85f5a1e1..4a87067a 100644 --- a/logic/auth/YggdrasilTask.h +++ b/logic/auth/YggdrasilTask.h @@ -36,6 +36,21 @@ 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. */ struct Error @@ -117,4 +132,6 @@ protected: const int timeout_max = 10000; const int time_step = 50; + + AuthSessionPtr m_session; }; diff --git a/logic/auth/flows/RefreshTask.cpp b/logic/auth/flows/RefreshTask.cpp index f63c736e..5a55ed91 100644 --- a/logic/auth/flows/RefreshTask.cpp +++ b/logic/auth/flows/RefreshTask.cpp @@ -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."; diff --git a/logic/auth/flows/RefreshTask.h b/logic/auth/flows/RefreshTask.h index 2fd50c60..0dadc025 100644 --- a/logic/auth/flows/RefreshTask.h +++ b/logic/auth/flows/RefreshTask.h @@ -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; }; + diff --git a/logic/net/NetJob.cpp b/logic/net/NetJob.cpp index 8b79bc54..9e800d13 100644 --- a/logic/net/NetJob.cpp +++ b/logic/net/NetJob.cpp @@ -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."; diff --git a/logic/net/NetJob.h b/logic/net/NetJob.h index 68c4c408..03d6a36e 100644 --- a/logic/net/NetJob.h +++ b/logic/net/NetJob.h @@ -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 |