aboutsummaryrefslogtreecommitdiff
path: root/logic/lists
diff options
context:
space:
mode:
Diffstat (limited to 'logic/lists')
-rw-r--r--logic/lists/JavaVersionList.cpp83
-rw-r--r--logic/lists/JavaVersionList.h5
-rw-r--r--logic/lists/MinecraftVersionList.cpp9
-rw-r--r--logic/lists/MojangAccountList.cpp381
-rw-r--r--logic/lists/MojangAccountList.h193
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);
-};