diff options
Diffstat (limited to 'logic/lists')
-rw-r--r-- | logic/lists/JavaVersionList.cpp | 83 | ||||
-rw-r--r-- | logic/lists/JavaVersionList.h | 5 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.cpp | 9 | ||||
-rw-r--r-- | logic/lists/MojangAccountList.cpp | 381 | ||||
-rw-r--r-- | logic/lists/MojangAccountList.h | 193 |
5 files changed, 66 insertions, 605 deletions
diff --git a/logic/lists/JavaVersionList.cpp b/logic/lists/JavaVersionList.cpp index 3dc1969b..d2f0972c 100644 --- a/logic/lists/JavaVersionList.cpp +++ b/logic/lists/JavaVersionList.cpp @@ -21,7 +21,8 @@ #include <QRegExp> #include "logger/QsLog.h" -#include <logic/JavaUtils.h> +#include "logic/JavaCheckerJob.h" +#include "logic/JavaUtils.h" JavaVersionList::JavaVersionList(QObject *parent) : BaseVersionList(parent) { @@ -49,7 +50,7 @@ int JavaVersionList::count() const int JavaVersionList::columnCount(const QModelIndex &parent) const { - return 4; + return 3; } QVariant JavaVersionList::data(const QModelIndex &index, int role) const @@ -75,9 +76,6 @@ QVariant JavaVersionList::data(const QModelIndex &index, int role) const case 2: return version->path; - case 3: - return version->recommended ? tr("Yes") : tr("No"); - default: return QVariant(); } @@ -109,9 +107,6 @@ QVariant JavaVersionList::headerData(int section, Qt::Orientation orientation, i case 2: return "Path"; - case 3: - return "Recommended"; - default: return QVariant(); } @@ -128,9 +123,6 @@ QVariant JavaVersionList::headerData(int section, Qt::Orientation orientation, i case 2: return "Path to this Java version."; - case 3: - return "Whether the version is recommended or not."; - default: return QVariant(); } @@ -142,15 +134,15 @@ QVariant JavaVersionList::headerData(int section, Qt::Orientation orientation, i BaseVersionPtr JavaVersionList::getTopRecommended() const { - for (int i = 0; i < m_vlist.length(); i++) + auto first = m_vlist.first(); + if(first != nullptr) { - auto ver = std::dynamic_pointer_cast<JavaVersion>(m_vlist.at(i)); - if (ver->recommended) - { - return m_vlist.at(i); - } + return first; + } + else + { + return BaseVersionPtr(); } - return BaseVersionPtr(); } void JavaVersionList::updateListData(QList<BaseVersionPtr> versions) @@ -183,20 +175,63 @@ void JavaListLoadTask::executeTask() setStatus("Detecting Java installations..."); JavaUtils ju; - QList<JavaVersionPtr> javas = ju.FindJavaPaths(); + QList<QString> candidate_paths = ju.FindJavaPaths(); + + auto job = new JavaCheckerJob("Java detection"); + connect(job, SIGNAL(finished(QList<JavaCheckResult>)), this, SLOT(javaCheckerFinished(QList<JavaCheckResult>))); + connect(job, SIGNAL(progress(int, int)), this, SLOT(checkerProgress(int, int))); + + QLOG_DEBUG() << "Probing the following Java paths: "; + for(QString candidate : candidate_paths) + { + QLOG_DEBUG() << " " << candidate; + + auto candidate_checker = new JavaChecker(); + candidate_checker->path = candidate; + job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker)); + } + + job->start(); +} + +void JavaListLoadTask::checkerProgress(int current, int total) +{ + float progress = (current * 100.0) / total; + this->setProgress((int) progress); +} + +void JavaListLoadTask::javaCheckerFinished(QList<JavaCheckResult> results) +{ + QList<JavaVersionPtr> candidates; + + QLOG_DEBUG() << "Found the following valid Java installations:"; + for(JavaCheckResult result : results) + { + if(result.valid) + { + JavaVersionPtr javaVersion(new JavaVersion()); + + javaVersion->id = result.javaVersion; + javaVersion->arch = result.mojangPlatform; + javaVersion->path = result.path; + candidates.append(javaVersion); + + QLOG_DEBUG() << " " << javaVersion->id << javaVersion->arch << javaVersion->path; + } + } QList<BaseVersionPtr> javas_bvp; - for (int i = 0; i < javas.length(); i++) + for (auto &java : candidates) { - BaseVersionPtr java = std::dynamic_pointer_cast<BaseVersion>(javas.at(i)); + //QLOG_INFO() << java->id << java->arch << " at " << java->path; + BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java); - if (java) + if (bp_java) { - javas_bvp.append(java); + javas_bvp.append(bp_java); } } m_list->updateListData(javas_bvp); - emitSucceeded(); } diff --git a/logic/lists/JavaVersionList.h b/logic/lists/JavaVersionList.h index f816c932..879b2480 100644 --- a/logic/lists/JavaVersionList.h +++ b/logic/lists/JavaVersionList.h @@ -20,6 +20,7 @@ #include "BaseVersionList.h" #include "logic/tasks/Task.h" +#include "logic/JavaCheckerJob.h" class JavaListLoadTask; @@ -43,7 +44,6 @@ struct JavaVersion : public BaseVersion QString id; QString arch; QString path; - bool recommended; }; typedef std::shared_ptr<JavaVersion> JavaVersionPtr; @@ -85,6 +85,9 @@ public: ~JavaListLoadTask(); virtual void executeTask(); +public slots: + void javaCheckerFinished(QList<JavaCheckResult> results); + void checkerProgress(int current, int total); protected: JavaVersionList *m_list; diff --git a/logic/lists/MinecraftVersionList.cpp b/logic/lists/MinecraftVersionList.cpp index 2a9c0d3b..523b81ac 100644 --- a/logic/lists/MinecraftVersionList.cpp +++ b/logic/lists/MinecraftVersionList.cpp @@ -15,6 +15,7 @@ #include "MinecraftVersionList.h" #include "MultiMC.h" +#include "logic/net/URLConstants.h" #include <QtXml> @@ -28,10 +29,6 @@ #include <QtNetwork> -#define MCVLIST_URLBASE "http://s3.amazonaws.com/Minecraft.Download/versions/" -#define ASSETS_URLBASE "http://assets.minecraft.net/" -#define MCN_URLBASE "http://sonicrules.org/mcnweb.py" - MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent) { } @@ -144,7 +141,7 @@ void MCVListLoadTask::executeTask() { setStatus("Loading instance version list..."); auto worker = MMC->qnam(); - vlistReply = worker->get(QNetworkRequest(QUrl(QString(MCVLIST_URLBASE) + "versions.json"))); + vlistReply = worker->get(QNetworkRequest(QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json"))); connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded())); } @@ -270,7 +267,7 @@ void MCVListLoadTask::list_downloaded() continue; } // Get the download URL. - QString dlUrl = QString(MCVLIST_URLBASE) + versionID + "/"; + QString dlUrl = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionID + "/"; // Now, we construct the version object and add it to the list. std::shared_ptr<MinecraftVersion> mcVersion(new MinecraftVersion()); diff --git a/logic/lists/MojangAccountList.cpp b/logic/lists/MojangAccountList.cpp deleted file mode 100644 index 439b5da6..00000000 --- a/logic/lists/MojangAccountList.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "logic/lists/MojangAccountList.h" - -#include <QIODevice> -#include <QFile> -#include <QTextStream> -#include <QJsonDocument> -#include <QJsonArray> -#include <QJsonObject> -#include <QJsonParseError> -#include <QDir> - -#include "logger/QsLog.h" - -#include "logic/auth/MojangAccount.h" - -#define ACCOUNT_LIST_FORMAT_VERSION 1 - -MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent) -{ -} - -MojangAccountPtr MojangAccountList::findAccount(const QString &username) const -{ - for (int i = 0; i < count(); i++) - { - MojangAccountPtr account = at(i); - if (account->username() == username) - return account; - } - return nullptr; -} - -const MojangAccountPtr MojangAccountList::at(int i) const -{ - return MojangAccountPtr(m_accounts.at(i)); -} - -void MojangAccountList::addAccount(const MojangAccountPtr account) -{ - beginResetModel(); - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); - m_accounts.append(account); - endResetModel(); - onListChanged(); -} - -void MojangAccountList::removeAccount(const QString &username) -{ - beginResetModel(); - for (auto account : m_accounts) - { - if (account->username() == username) - { - m_accounts.removeOne(account); - return; - } - } - endResetModel(); - onListChanged(); -} - -void MojangAccountList::removeAccount(QModelIndex index) -{ - beginResetModel(); - m_accounts.removeAt(index.row()); - endResetModel(); - onListChanged(); -} - -MojangAccountPtr MojangAccountList::activeAccount() const -{ - if (m_activeAccount.isEmpty()) - return nullptr; - else - return findAccount(m_activeAccount); -} - -void MojangAccountList::setActiveAccount(const QString &username) -{ - beginResetModel(); - if (username.isEmpty()) - { - m_activeAccount = ""; - } - else - { - for (MojangAccountPtr account : m_accounts) - { - if (account->username() == username) - m_activeAccount = username; - } - } - endResetModel(); - onActiveChanged(); -} - -void MojangAccountList::accountChanged() -{ - // the list changed. there is no doubt. - onListChanged(); -} - -void MojangAccountList::onListChanged() -{ - if (m_autosave) - // TODO: Alert the user if this fails. - saveList(); - - emit listChanged(); -} - -void MojangAccountList::onActiveChanged() -{ - if (m_autosave) - saveList(); - - emit activeAccountChanged(); -} - -int MojangAccountList::count() const -{ - return m_accounts.count(); -} - -QVariant MojangAccountList::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() > count()) - return QVariant(); - - MojangAccountPtr account = at(index.row()); - - switch (role) - { - case Qt::DisplayRole: - switch (index.column()) - { - case ActiveColumn: - return account->username() == m_activeAccount; - - case NameColumn: - return account->username(); - - default: - return QVariant(); - } - - case Qt::ToolTipRole: - return account->username(); - - case PointerRole: - return qVariantFromValue(account); - - default: - return QVariant(); - } -} - -QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const -{ - switch (role) - { - case Qt::DisplayRole: - switch (section) - { - case ActiveColumn: - return "Active?"; - - case NameColumn: - return "Name"; - - default: - return QVariant(); - } - - case Qt::ToolTipRole: - switch (section) - { - case NameColumn: - return "The name of the version."; - - default: - return QVariant(); - } - - default: - return QVariant(); - } -} - -int MojangAccountList::rowCount(const QModelIndex &parent) const -{ - // Return count - return count(); -} - -int MojangAccountList::columnCount(const QModelIndex &parent) const -{ - return 2; -} - -void MojangAccountList::updateListData(QList<MojangAccountPtr> versions) -{ - beginResetModel(); - m_accounts = versions; - endResetModel(); -} - -bool MojangAccountList::loadList(const QString &filePath) -{ - QString path = filePath; - if (path.isEmpty()) - path = m_listFilePath; - if (path.isEmpty()) - { - QLOG_ERROR() << "Can't load Mojang account list. No file path given and no default set."; - return false; - } - - if (!QDir::current().exists(path)) - { - QDir::current().mkpath(path); - } - - QFile file(path); - - // Try to open the file and fail if we can't. - // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::ReadOnly)) - { - QLOG_ERROR() << QString("Failed to read the account list file (%1).").arg(path).toUtf8(); - return false; - } - - // Read the file and close it. - QByteArray jsonData = file.readAll(); - file.close(); - - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); - - // Fail if the JSON is invalid. - if (parseError.error != QJsonParseError::NoError) - { - QLOG_ERROR() << QString("Failed to parse account list file: %1 at offset %2") - .arg(parseError.errorString(), QString::number(parseError.offset)) - .toUtf8(); - return false; - } - - // Make sure the root is an object. - if (!jsonDoc.isObject()) - { - QLOG_ERROR() << "Invalid account list JSON: Root should be an array."; - return false; - } - - QJsonObject root = jsonDoc.object(); - - // Make sure the format version matches. - if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION) - { - QString newName = "accounts-old.json"; - QLOG_WARN() << "Format version mismatch when loading account list. Existing one will be renamed to" - << newName; - - // Attempt to rename the old version. - file.rename(newName); - return false; - } - - // Now, load the accounts array. - beginResetModel(); - QJsonArray accounts = root.value("accounts").toArray(); - for (QJsonValue accountVal : accounts) - { - QJsonObject accountObj = accountVal.toObject(); - MojangAccountPtr account = MojangAccount::loadFromJson(accountObj); - if (account.get() != nullptr) - { - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); - m_accounts.append(account); - } - else - { - QLOG_WARN() << "Failed to load an account."; - } - } - endResetModel(); - - // Load the active account. - m_activeAccount = root.value("activeAccount").toString(""); - - return true; -} - -bool MojangAccountList::saveList(const QString &filePath) -{ - QString path(filePath); - if (path.isEmpty()) - path = m_listFilePath; - if (path.isEmpty()) - { - QLOG_ERROR() << "Can't save Mojang account list. No file path given and no default set."; - return false; - } - - if (!QDir::current().exists(path)) - { - QDir::current().mkpath(path); - } - - QLOG_INFO() << "Writing account list to" << path; - - QLOG_DEBUG() << "Building JSON data structure."; - // Build the JSON document to write to the list file. - QJsonObject root; - - root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION); - - // Build a list of accounts. - QLOG_DEBUG() << "Building account array."; - QJsonArray accounts; - for (MojangAccountPtr account : m_accounts) - { - QJsonObject accountObj = account->saveToJson(); - accounts.append(accountObj); - } - - // Insert the account list into the root object. - root.insert("accounts", accounts); - - // Save the active account. - root.insert("activeAccount", m_activeAccount); - - // Create a JSON document object to convert our JSON to bytes. - QJsonDocument doc(root); - - // Now that we're done building the JSON object, we can write it to the file. - QLOG_DEBUG() << "Writing account list to file."; - QFile file(path); - - // Try to open the file and fail if we can't. - // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::WriteOnly)) - { - QLOG_ERROR() << QString("Failed to read the account list file (%1).").arg(path).toUtf8(); - return false; - } - - // Write the JSON to the file. - file.write(doc.toJson()); - file.close(); - - QLOG_INFO() << "Saved account list to" << path; - - return true; -} - -void MojangAccountList::setListFilePath(QString path, bool autosave) -{ - m_listFilePath = path; - m_autosave = autosave; -} diff --git a/logic/lists/MojangAccountList.h b/logic/lists/MojangAccountList.h deleted file mode 100644 index 744f3c51..00000000 --- a/logic/lists/MojangAccountList.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <QObject> -#include <QVariant> -#include <QAbstractListModel> -#include <QSharedPointer> - -#include "logic/auth/MojangAccount.h" - -/*! - * \brief List of available Mojang accounts. - * This should be loaded in the background by MultiMC on startup. - * - * This class also inherits from QAbstractListModel. Methods from that - * class determine how this list shows up in a list view. Said methods - * all have a default implementation, but they can be overridden by subclasses to - * change the behavior of the list. - */ -class MojangAccountList : public QAbstractListModel -{ - Q_OBJECT -public: - enum ModelRoles - { - PointerRole = 0x34B1CB48 - }; - - enum VListColumns - { - // TODO: Add icon column. - - // First column - Active? - ActiveColumn = 0, - - // Second column - Name - NameColumn, - }; - - explicit MojangAccountList(QObject *parent = 0); - - //! Gets the account at the given index. - virtual const MojangAccountPtr at(int i) const; - - //! Returns the number of accounts in the list. - virtual int count() const; - - //////// List Model Functions //////// - virtual QVariant data(const QModelIndex &index, int role) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; - virtual int rowCount(const QModelIndex &parent) const; - virtual int columnCount(const QModelIndex &parent) const; - - /*! - * Adds a the given Mojang account to the account list. - */ - virtual void addAccount(const MojangAccountPtr account); - - /*! - * Removes the mojang account with the given username from the account list. - */ - virtual void removeAccount(const QString &username); - - /*! - * Removes the account at the given QModelIndex. - */ - virtual void removeAccount(QModelIndex index); - - /*! - * \brief Finds an account by its username. - * \param The username of the account to find. - * \return A const pointer to the account with the given username. NULL if - * one doesn't exist. - */ - virtual MojangAccountPtr findAccount(const QString &username) const; - - /*! - * Sets the default path to save the list file to. - * If autosave is true, this list will automatically save to the given path whenever it changes. - * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately - * after calling this function to ensure an autosaved change doesn't overwrite the list you intended - * to load. - */ - virtual void setListFilePath(QString path, bool autosave = false); - - /*! - * \brief Loads the account list from the given file path. - * If the given file is an empty string (default), will load from the default account list file. - * \return True if successful, otherwise false. - */ - virtual bool loadList(const QString &file = ""); - - /*! - * \brief Saves the account list to the given file. - * If the given file is an empty string (default), will save from the default account list file. - * \return True if successful, otherwise false. - */ - virtual bool saveList(const QString &file = ""); - - /*! - * \brief Gets a pointer to the account that the user has selected as their "active" account. - * Which account is active can be overridden on a per-instance basis, but this will return the one that - * is set as active globally. - * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer. - */ - virtual MojangAccountPtr activeAccount() const; - - /*! - * Sets the given account as the current active account. - * If the username given is an empty string, sets the active account to nothing. - */ - virtual void setActiveAccount(const QString &username); - -signals: - /*! - * Signal emitted to indicate that the account list has changed. - * This will also fire if the value of an element in the list changes (will be implemented - * later). - */ - void listChanged(); - - /*! - * Signal emitted to indicate that the active account has changed. - */ - void activeAccountChanged(); - -public -slots: - /** - * This is called when one of the accounts changes and the list needs to be updated - */ - void accountChanged(); - -protected: - /*! - * Called whenever the list changes. - * This emits the listChanged() signal and autosaves the list (if autosave is enabled). - */ - void onListChanged(); - - /*! - * Called whenever the active account changes. - * Emits the activeAccountChanged() signal and autosaves the list if enabled. - */ - void onActiveChanged(); - - QList<MojangAccountPtr> m_accounts; - - /*! - * Username of the account that is currently active. - * Empty string if no account is active. - */ - QString m_activeAccount; - - //! Path to the account list file. Empty string if there isn't one. - QString m_listFilePath; - - /*! - * If true, the account list will automatically save to the account list path when it changes. - * Ignored if m_listFilePath is blank. - */ - bool m_autosave = false; - -protected -slots: - /*! - * Updates this list with the given list of accounts. - * This is done by copying each account in the given list and inserting it - * into this one. - * We need to do this so that we can set the parents of the accounts are set to this - * account list. This can't be done in the load task, because the accounts the load - * task creates are on the load task's thread and Qt won't allow their parents - * to be set to something created on another thread. - * To get around that problem, we invoke this method on the GUI thread, which - * then copies the accounts and sets their parents correctly. - * \param accounts List of accounts whose parents should be set. - */ - virtual void updateListData(QList<MojangAccountPtr> versions); -}; |