aboutsummaryrefslogtreecommitdiff
path: root/logic/lists
diff options
context:
space:
mode:
Diffstat (limited to 'logic/lists')
-rw-r--r--logic/lists/BaseVersionList.cpp121
-rw-r--r--logic/lists/BaseVersionList.h120
-rw-r--r--logic/lists/ForgeVersionList.cpp455
-rw-r--r--logic/lists/ForgeVersionList.h130
-rw-r--r--logic/lists/InstanceList.cpp618
-rw-r--r--logic/lists/InstanceList.h152
-rw-r--r--logic/lists/JavaVersionList.cpp241
-rw-r--r--logic/lists/JavaVersionList.h96
-rw-r--r--logic/lists/LiteLoaderVersionList.cpp223
-rw-r--r--logic/lists/LiteLoaderVersionList.h112
-rw-r--r--logic/lists/LwjglVersionList.cpp199
-rw-r--r--logic/lists/LwjglVersionList.h148
-rw-r--r--logic/lists/MinecraftVersionList.cpp290
-rw-r--r--logic/lists/MinecraftVersionList.h76
14 files changed, 0 insertions, 2981 deletions
diff --git a/logic/lists/BaseVersionList.cpp b/logic/lists/BaseVersionList.cpp
deleted file mode 100644
index 6e2c5282..00000000
--- a/logic/lists/BaseVersionList.cpp
+++ /dev/null
@@ -1,121 +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/BaseVersionList.h"
-#include "logic/BaseVersion.h"
-
-BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor)
-{
- for (int i = 0; i < count(); i++)
- {
- if (at(i)->descriptor() == descriptor)
- return at(i);
- }
- return BaseVersionPtr();
-}
-
-BaseVersionPtr BaseVersionList::getLatestStable() const
-{
- if (count() <= 0)
- return BaseVersionPtr();
- else
- return at(0);
-}
-
-QVariant BaseVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- BaseVersionPtr version = at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case NameColumn:
- return version->name();
-
- case TypeColumn:
- return version->typeString();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return version->descriptor();
-
- case VersionPointerRole:
- return qVariantFromValue(version);
-
- default:
- return QVariant();
- }
-}
-
-QVariant BaseVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case NameColumn:
- return "Name";
-
- case TypeColumn:
- return "Type";
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return "The name of the version.";
-
- case TypeColumn:
- return "The version's type.";
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
-}
-
-int BaseVersionList::rowCount(const QModelIndex &parent) const
-{
- // Return count
- return count();
-}
-
-int BaseVersionList::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
diff --git a/logic/lists/BaseVersionList.h b/logic/lists/BaseVersionList.h
deleted file mode 100644
index 21b44e8d..00000000
--- a/logic/lists/BaseVersionList.h
+++ /dev/null
@@ -1,120 +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 "logic/BaseVersion.h"
-
-class Task;
-
-/*!
- * \brief Class that each instance type's version list derives from.
- * Version lists are the lists that keep track of the available game versions
- * for that instance. This list will not be loaded on startup. It will be loaded
- * when the list's load function is called. Before using the version list, you
- * should check to see if it has been loaded yet and if not, load the list.
- *
- * Note that this class also inherits from QAbstractListModel. Methods from that
- * class determine how this version list shows up in a list view. Said methods
- * all have a default implementation, but they can be overridden by plugins to
- * change the behavior of the list.
- */
-class BaseVersionList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum ModelRoles
- {
- VersionPointerRole = 0x34B1CB48
- };
-
- enum VListColumns
- {
- // First column - Name
- NameColumn = 0,
-
- // Second column - Type
- TypeColumn,
-
- // Third column - Timestamp
- TimeColumn
- };
-
- explicit BaseVersionList(QObject *parent = 0);
-
- /*!
- * \brief Gets a task that will reload the version list.
- * Simply execute the task to load the list.
- * The task returned by this function should reset the model when it's done.
- * \return A pointer to a task that reloads the version list.
- */
- virtual Task *getLoadTask() = 0;
-
- //! Checks whether or not the list is loaded. If this returns false, the list should be
- //loaded.
- virtual bool isLoaded() = 0;
-
- //! Gets the version at the given index.
- virtual const BaseVersionPtr at(int i) const = 0;
-
- //! Returns the number of versions in the list.
- virtual int count() const = 0;
-
- //////// 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;
-
- /*!
- * \brief Finds a version by its descriptor.
- * \param The descriptor of the version to find.
- * \return A const pointer to the version with the given descriptor. NULL if
- * one doesn't exist.
- */
- virtual BaseVersionPtr findVersion(const QString &descriptor);
-
- /*!
- * \brief Gets the latest stable version of this instance type.
- * This is the version that will be selected by default.
- * By default, this is simply the first version in the list.
- */
- virtual BaseVersionPtr getLatestStable() const;
-
- /*!
- * Sorts the version list.
- */
- virtual void sort() = 0;
-
-protected
-slots:
- /*!
- * Updates this list with the given list of versions.
- * This is done by copying each version in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the versions are set to this
- * version list. This can't be done in the load task, because the versions 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 versions and sets their parents correctly.
- * \param versions List of versions whose parents should be set.
- */
- virtual void updateListData(QList<BaseVersionPtr> versions) = 0;
-};
diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp
deleted file mode 100644
index 50899d24..00000000
--- a/logic/lists/ForgeVersionList.cpp
+++ /dev/null
@@ -1,455 +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 "ForgeVersionList.h"
-#include <logic/net/NetJob.h>
-#include <logic/net/URLConstants.h>
-#include "MultiMC.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include "logger/QsLog.h"
-
-ForgeVersionList::ForgeVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *ForgeVersionList::getLoadTask()
-{
- return new ForgeListLoadTask(this);
-}
-
-bool ForgeVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr ForgeVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int ForgeVersionList::count() const
-{
- return m_vlist.count();
-}
-
-int ForgeVersionList::columnCount(const QModelIndex &parent) const
-{
- return 3;
-}
-
-QVariant ForgeVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<ForgeVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case 0:
- return version->name();
-
- case 1:
- return version->mcver_sane;
-
- case 2:
- return version->typeString();
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return version->descriptor();
-
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- default:
- return QVariant();
- }
-}
-
-QVariant ForgeVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case 0:
- return "Version";
-
- case 1:
- return "Minecraft";
-
- case 2:
- return "Type";
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case 0:
- return "The name of the version.";
-
- case 1:
- return "Minecraft version";
-
- case 2:
- return "The version's type.";
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionPtr ForgeVersionList::getLatestStable() const
-{
- return BaseVersionPtr();
-}
-
-void ForgeVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- endResetModel();
- // NOW SORT!!
- // sort();
-}
-
-void ForgeVersionList::sort()
-{
- // NO-OP for now
-}
-
-ForgeListLoadTask::ForgeListLoadTask(ForgeVersionList *vlist) : Task()
-{
- m_list = vlist;
-}
-
-void ForgeListLoadTask::executeTask()
-{
- setStatus(tr("Fetching Forge version lists..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto forgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "list.json");
- auto gradleForgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "json");
-
- // verify by poking the server.
- forgeListEntry->stale = true;
- gradleForgeListEntry->stale = true;
-
- job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL),
- forgeListEntry));
- job->addNetAction(gradleListDownload = CacheDownload::make(
- QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
- connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out)
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("builds").isArray())
- {
- emitFailed(
- "Error parsing version list JSON: version list object is missing 'builds' array");
- return false;
- }
- QJsonArray builds = root.value("builds").toArray();
-
- for (int i = 0; i < builds.count(); i++)
- {
- // Load the version info.
- if (!builds[i].isObject())
- {
- // FIXME: log this somewhere
- continue;
- }
- QJsonObject obj = builds[i].toObject();
- int build_nr = obj.value("build").toDouble(0);
- if (!build_nr)
- continue;
- QJsonArray files = obj.value("files").toArray();
- QString url, jobbuildver, mcver, buildtype, filename;
- QString changelog_url, installer_url;
- QString installer_filename;
- bool valid = false;
- for (int j = 0; j < files.count(); j++)
- {
- if (!files[j].isObject())
- {
- continue;
- }
- QJsonObject file = files[j].toObject();
- buildtype = file.value("buildtype").toString();
- if ((buildtype == "client" || buildtype == "universal") && !valid)
- {
- mcver = file.value("mcver").toString();
- url = file.value("url").toString();
- jobbuildver = file.value("jobbuildver").toString();
- int lastSlash = url.lastIndexOf('/');
- filename = url.mid(lastSlash + 1);
- valid = true;
- }
- else if (buildtype == "changelog")
- {
- QString ext = file.value("ext").toString();
- if (ext.isEmpty())
- {
- continue;
- }
- changelog_url = file.value("url").toString();
- }
- else if (buildtype == "installer")
- {
- installer_url = file.value("url").toString();
- int lastSlash = installer_url.lastIndexOf('/');
- installer_filename = installer_url.mid(lastSlash + 1);
- }
- }
- if (valid)
- {
- // Now, we construct the version object and add it to the list.
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->universal_url = url;
- fVersion->changelog_url = changelog_url;
- fVersion->installer_url = installer_url;
- fVersion->jobbuildver = jobbuildver;
- fVersion->mcver = fVersion->mcver_sane = mcver;
- if (installer_filename.isEmpty())
- {
- fVersion->filename = filename;
- }
- else
- {
- fVersion->filename = installer_filename;
- }
- fVersion->m_buildnr = build_nr;
- out.append(fVersion);
- }
- }
-
- return true;
-}
-
-bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out)
-{
- QByteArray data;
- {
- auto dlJob = gradleListDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing gradle version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing gradle version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // we probably could hard code these, but it might still be worth doing it this way
- const QString webpath = root.value("webpath").toString();
- const QString artifact = root.value("artifact").toString();
-
- QJsonObject numbers = root.value("number").toObject();
- for (auto it = numbers.begin(); it != numbers.end(); ++it)
- {
- QJsonObject number = it.value().toObject();
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->m_buildnr = number.value("build").toDouble();
- fVersion->jobbuildver = number.value("version").toString();
- fVersion->branch = number.value("branch").toString("");
- fVersion->mcver = number.value("mcversion").toString();
- // HACK: here, we fix the minecraft version used by forge.
- // HACK: this will inevitably break (later)
- // FIXME: replace with a dictionary
- fVersion->mcver_sane = fVersion->mcver;
- fVersion->mcver_sane.replace("_pre", "-pre");
- fVersion->filename = "";
-
- QString universal_filename, installer_filename;
- QJsonArray files = number.value("files").toArray();
- for (auto fIt = files.begin(); fIt != files.end(); ++fIt)
- {
- // TODO with gradle we also get checksums, use them
- QJsonArray file = (*fIt).toArray();
- if (file.size() < 3)
- {
- continue;
- }
-
- QString extension = file.at(0).toString();
- QString part = file.at(1).toString();
- QString checksum = file.at(2).toString();
-
- // insane form of mcver is used here
- QString longVersion = fVersion->mcver + "-" + fVersion->jobbuildver;
- if (!fVersion->branch.isEmpty())
- {
- longVersion = longVersion + "-" + fVersion->branch;
- }
- QString filename = artifact + "-" + longVersion + "-" + part + "." + extension;
-
- QString url = QString("%1/%2/%3")
- .arg(webpath)
- .arg(longVersion)
- .arg(filename);
-
- if (part == "installer")
- {
- fVersion->installer_url = url;
- installer_filename = filename;
- }
- else if (part == "universal")
- {
- fVersion->universal_url = url;
- universal_filename = filename;
- }
- else if (part == "changelog")
- {
- fVersion->changelog_url = url;
- }
- }
- if (fVersion->installer_url.isEmpty() && fVersion->universal_url.isEmpty())
- {
- continue;
- }
- fVersion->filename = fVersion->installer_url.isEmpty() ? universal_filename : installer_filename;
- out.append(fVersion);
- }
- return true;
-}
-
-void ForgeListLoadTask::listDownloaded()
-{
- QList<BaseVersionPtr> list;
- bool ret = true;
- if (!parseForgeList(list))
- {
- ret = false;
- }
- if (!parseForgeGradleList(list))
- {
- ret = false;
- }
-
- if (!ret)
- {
- return;
- }
- std::sort(list.begin(), list.end(), [](const BaseVersionPtr & l, const BaseVersionPtr & r)
- { return (*l > *r); });
-
- m_list->updateListData(list);
-
- emitSucceeded();
- return;
-}
-
-void ForgeListLoadTask::listFailed()
-{
- auto reply = listDownload->m_reply;
- if (reply)
- {
- QLOG_ERROR() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- QLOG_ERROR() << "Getting forge version list failed for reasons unknown.";
- }
-}
-void ForgeListLoadTask::gradleListFailed()
-{
- auto reply = gradleListDownload->m_reply;
- if (reply)
- {
- QLOG_ERROR() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- QLOG_ERROR() << "Getting forge version list failed for reasons unknown.";
- }
-}
diff --git a/logic/lists/ForgeVersionList.h b/logic/lists/ForgeVersionList.h
deleted file mode 100644
index 091072e4..00000000
--- a/logic/lists/ForgeVersionList.h
+++ /dev/null
@@ -1,130 +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 <QAbstractListModel>
-#include <QUrl>
-
-#include <QNetworkReply>
-#include "BaseVersionList.h"
-#include "logic/tasks/Task.h"
-#include "logic/net/NetJob.h"
-
-class ForgeVersion;
-typedef std::shared_ptr<ForgeVersion> ForgeVersionPtr;
-
-struct ForgeVersion : public BaseVersion
-{
- virtual QString descriptor() override
- {
- return filename;
- }
- ;
- virtual QString name() override
- {
- return "Forge " + jobbuildver;
- }
- ;
- virtual QString typeString() const override
- {
- if (installer_url.isEmpty())
- return "Universal";
- else
- return "Installer";
- }
-
- virtual bool operator<(BaseVersion &a) override
- {
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if(!pa)
- return true;
- return m_buildnr < pa->m_buildnr;
- }
- virtual bool operator>(BaseVersion &a) override
- {
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if(!pa)
- return false;
- return m_buildnr > pa->m_buildnr;
- }
- int m_buildnr = 0;
- QString universal_url;
- QString changelog_url;
- QString installer_url;
- QString jobbuildver;
- QString mcver;
- QString filename;
- QString branch;
- QString mcver_sane;
-};
-
-class ForgeVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class ForgeListLoadTask;
-
- explicit ForgeVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sort();
-
- virtual BaseVersionPtr getLatestStable() const;
-
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-};
-
-class ForgeListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit ForgeListLoadTask(ForgeVersionList *vlist);
-
- virtual void executeTask();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
- void gradleListFailed();
-
-protected:
- NetJobPtr listJob;
- ForgeVersionList *m_list;
-
- CacheDownloadPtr listDownload;
- CacheDownloadPtr gradleListDownload;
-
-private:
- bool parseForgeList(QList<BaseVersionPtr> &out);
- bool parseForgeGradleList(QList<BaseVersionPtr> &out);
-};
diff --git a/logic/lists/InstanceList.cpp b/logic/lists/InstanceList.cpp
deleted file mode 100644
index 8808d6b5..00000000
--- a/logic/lists/InstanceList.cpp
+++ /dev/null
@@ -1,618 +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 <QDir>
-#include <QSet>
-#include <QFile>
-#include <QDirIterator>
-#include <QThread>
-#include <QTextStream>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QXmlStreamReader>
-#include <QRegularExpression>
-#include <pathutils.h>
-
-#include "MultiMC.h"
-#include "logic/lists/InstanceList.h"
-#include "logic/icons/IconList.h"
-#include "logic/lists/MinecraftVersionList.h"
-#include "logic/BaseInstance.h"
-#include "logic/InstanceFactory.h"
-#include "logger/QsLog.h"
-#include <gui/groupview/GroupView.h>
-
-const static int GROUP_FILE_FORMAT_VERSION = 1;
-
-InstanceList::InstanceList(const QString &instDir, QObject *parent)
- : QAbstractListModel(parent), m_instDir(instDir)
-{
- connect(MMC, &MultiMC::aboutToQuit, this, &InstanceList::saveGroupList);
-
- if (!QDir::current().exists(m_instDir))
- {
- QDir::current().mkpath(m_instDir);
- }
-
- /*
- * FIXME HACK: instances sometimes need to be created at launch. They need the versions for
- * that.
- *
- * Remove this. it has no business of reloading the whole list. The instances which
- * need it should track such events themselves and CHANGE THEIR DATA ONLY!
- */
- connect(MMC->minecraftlist().get(), &MinecraftVersionList::modelReset, this,
- &InstanceList::loadList);
-}
-
-InstanceList::~InstanceList()
-{
-}
-
-int InstanceList::rowCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent);
- return m_instances.count();
-}
-
-QModelIndex InstanceList::index(int row, int column, const QModelIndex &parent) const
-{
- Q_UNUSED(parent);
- if (row < 0 || row >= m_instances.size())
- return QModelIndex();
- return createIndex(row, column, (void *)m_instances.at(row).get());
-}
-
-QVariant InstanceList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- {
- return QVariant();
- }
- BaseInstance *pdata = static_cast<BaseInstance *>(index.internalPointer());
- switch (role)
- {
- case InstancePointerRole:
- {
- QVariant v = qVariantFromValue((void *)pdata);
- return v;
- }
- case InstanceIDRole:
- {
- return pdata->id();
- }
- case Qt::DisplayRole:
- {
- return pdata->name();
- }
- case Qt::ToolTipRole:
- {
- return pdata->instanceRoot();
- }
- case Qt::DecorationRole:
- {
- QString key = pdata->iconKey();
- return MMC->icons()->getIcon(key);
- }
- // for now.
- case GroupViewRoles::GroupRole:
- {
- return pdata->group();
- }
- default:
- break;
- }
- return QVariant();
-}
-
-Qt::ItemFlags InstanceList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags f;
- if (index.isValid())
- {
- f |= (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- }
- return f;
-}
-
-void InstanceList::groupChanged()
-{
- // save the groups. save all of them.
- saveGroupList();
-}
-
-QStringList InstanceList::getGroups()
-{
- return m_groups.toList();
-}
-
-void InstanceList::saveGroupList()
-{
- QString groupFileName = m_instDir + "/instgroups.json";
- QFile groupFile(groupFileName);
-
- // if you can't open the file, fail
- if (!groupFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
- {
- // An error occurred. Ignore it.
- QLOG_ERROR() << "Failed to save instance group file.";
- return;
- }
- QTextStream out(&groupFile);
- QMap<QString, QSet<QString>> groupMap;
- for (auto instance : m_instances)
- {
- QString id = instance->id();
- QString group = instance->group();
- if (group.isEmpty())
- continue;
-
- // keep a list/set of groups for choosing
- m_groups.insert(group);
-
- if (!groupMap.count(group))
- {
- QSet<QString> set;
- set.insert(id);
- groupMap[group] = set;
- }
- else
- {
- QSet<QString> &set = groupMap[group];
- set.insert(id);
- }
- }
- QJsonObject toplevel;
- toplevel.insert("formatVersion", QJsonValue(QString("1")));
- QJsonObject groupsArr;
- for (auto iter = groupMap.begin(); iter != groupMap.end(); iter++)
- {
- auto list = iter.value();
- auto name = iter.key();
- QJsonObject groupObj;
- QJsonArray instanceArr;
- groupObj.insert("hidden", QJsonValue(QString("false")));
- for (auto item : list)
- {
- instanceArr.append(QJsonValue(item));
- }
- groupObj.insert("instances", instanceArr);
- groupsArr.insert(name, groupObj);
- }
- toplevel.insert("groups", groupsArr);
- QJsonDocument doc(toplevel);
- groupFile.write(doc.toJson());
- groupFile.close();
-}
-
-void InstanceList::loadGroupList(QMap<QString, QString> &groupMap)
-{
- QString groupFileName = m_instDir + "/instgroups.json";
-
- // if there's no group file, fail
- if (!QFileInfo(groupFileName).exists())
- return;
-
- QFile groupFile(groupFileName);
-
- // if you can't open the file, fail
- if (!groupFile.open(QIODevice::ReadOnly))
- {
- // An error occurred. Ignore it.
- QLOG_ERROR() << "Failed to read instance group file.";
- return;
- }
-
- QTextStream in(&groupFile);
- QString jsonStr = in.readAll();
- groupFile.close();
-
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error);
-
- // if the json was bad, fail
- if (error.error != QJsonParseError::NoError)
- {
- QLOG_ERROR() << QString("Failed to parse instance group file: %1 at offset %2")
- .arg(error.errorString(), QString::number(error.offset))
- .toUtf8();
- return;
- }
-
- // if the root of the json wasn't an object, fail
- if (!jsonDoc.isObject())
- {
- QLOG_WARN() << "Invalid group file. Root entry should be an object.";
- return;
- }
-
- QJsonObject rootObj = jsonDoc.object();
-
- // Make sure the format version matches, otherwise fail.
- if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION)
- return;
-
- // Get the groups. if it's not an object, fail
- if (!rootObj.value("groups").isObject())
- {
- QLOG_WARN() << "Invalid group list JSON: 'groups' should be an object.";
- return;
- }
-
- // Iterate through all the groups.
- QJsonObject groupMapping = rootObj.value("groups").toObject();
- for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++)
- {
- QString groupName = iter.key();
-
- // If not an object, complain and skip to the next one.
- if (!iter.value().isObject())
- {
- QLOG_WARN() << QString("Group '%1' in the group list should "
- "be an object.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- QJsonObject groupObj = iter.value().toObject();
- if (!groupObj.value("instances").isArray())
- {
- QLOG_WARN() << QString("Group '%1' in the group list is invalid. "
- "It should contain an array "
- "called 'instances'.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- // keep a list/set of groups for choosing
- m_groups.insert(groupName);
-
- // Iterate through the list of instances in the group.
- QJsonArray instancesArray = groupObj.value("instances").toArray();
-
- for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end();
- iter2++)
- {
- groupMap[(*iter2).toString()] = groupName;
- }
- }
-}
-
-QList<FTBRecord> InstanceList::discoverFTBInstances()
-{
- QList<FTBRecord> records;
- QDir dir = QDir(MMC->settings()->get("FTBLauncherDataRoot").toString());
- QDir dataDir = QDir(MMC->settings()->get("FTBRoot").toString());
- if (!dataDir.exists())
- {
- QLOG_INFO() << "The FTB directory specified does not exist. Please check your settings";
- return records;
- }
- else if (!dir.exists())
- {
- QLOG_INFO() << "The FTB launcher data directory specified does not exist. Please check your settings";
- return records;
- }
- dir.cd("ModPacks");
- auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name);
- for (auto filename : allFiles)
- {
- if (!filename.endsWith(".xml"))
- continue;
- auto fpath = dir.absoluteFilePath(filename);
- QFile f(fpath);
- QLOG_INFO() << "Discovering FTB instances -- " << fpath;
- if (!f.open(QFile::ReadOnly))
- continue;
-
- // read the FTB packs XML.
- QXmlStreamReader reader(&f);
- while (!reader.atEnd())
- {
- switch (reader.readNext())
- {
- case QXmlStreamReader::StartElement:
- {
- if (reader.name() == "modpack")
- {
- QXmlStreamAttributes attrs = reader.attributes();
- FTBRecord record;
- record.dirName = attrs.value("dir").toString();
- record.instanceDir = dataDir.absoluteFilePath(record.dirName);
- record.templateDir = dir.absoluteFilePath(record.dirName);
- QDir test(record.instanceDir);
- QLOG_DEBUG() << dataDir.absolutePath() << record.instanceDir << record.dirName;
- if (!test.exists())
- continue;
- record.name = attrs.value("name").toString();
- record.logo = attrs.value("logo").toString();
- record.mcVersion = attrs.value("mcVersion").toString();
- record.description = attrs.value("description").toString();
- records.append(record);
- }
- break;
- }
- case QXmlStreamReader::EndElement:
- break;
- case QXmlStreamReader::Characters:
- break;
- default:
- break;
- }
- }
- f.close();
- }
- return records;
-}
-
-void InstanceList::loadFTBInstances(QMap<QString, QString> &groupMap,
- QList<InstancePtr> &tempList)
-{
- auto records = discoverFTBInstances();
- if (!records.size())
- {
- QLOG_INFO() << "No FTB instances to load.";
- return;
- }
- QLOG_INFO() << "Loading FTB instances! -- got " << records.size();
- // process the records we acquired.
- for (auto record : records)
- {
- QLOG_INFO() << "Loading FTB instance from " << record.instanceDir;
- QString iconKey = record.logo;
- iconKey.remove(QRegularExpression("\\..*"));
- MMC->icons()->addIcon(iconKey, iconKey, PathCombine(record.templateDir, record.logo),
- MMCIcon::Transient);
-
- if (!QFileInfo(PathCombine(record.instanceDir, "instance.cfg")).exists())
- {
- QLOG_INFO() << "Converting " << record.name << " as new.";
- InstancePtr instPtr;
- auto &factory = InstanceFactory::get();
- auto version = MMC->minecraftlist()->findVersion(record.mcVersion);
- if (!version)
- {
- QLOG_ERROR() << "Can't load instance " << record.instanceDir
- << " because minecraft version " << record.mcVersion
- << " can't be resolved.";
- continue;
- }
- auto error = factory.createInstance(instPtr, version, record.instanceDir,
- InstanceFactory::FTBInstance);
-
- if (!instPtr || error != InstanceFactory::NoCreateError)
- continue;
-
- instPtr->setGroupInitial("FTB");
- instPtr->setName(record.name);
- instPtr->setIconKey(iconKey);
- instPtr->setIntendedVersionId(record.mcVersion);
- instPtr->setNotes(record.description);
- if(!continueProcessInstance(instPtr, error, record.instanceDir, groupMap))
- continue;
- tempList.append(InstancePtr(instPtr));
- }
- else
- {
- QLOG_INFO() << "Loading existing " << record.name;
- InstancePtr instPtr;
- auto error = InstanceFactory::get().loadInstance(instPtr, record.instanceDir);
- if (!instPtr || error != InstanceFactory::NoLoadError)
- continue;
- instPtr->setGroupInitial("FTB");
- instPtr->setName(record.name);
- instPtr->setIconKey(iconKey);
- if (instPtr->intendedVersionId() != record.mcVersion)
- instPtr->setIntendedVersionId(record.mcVersion);
- instPtr->setNotes(record.description);
- if(!continueProcessInstance(instPtr, error, record.instanceDir, groupMap))
- continue;
- tempList.append(InstancePtr(instPtr));
- }
- }
-}
-
-InstanceList::InstListError InstanceList::loadList()
-{
- // load the instance groups
- QMap<QString, QString> groupMap;
- loadGroupList(groupMap);
-
- QList<InstancePtr> tempList;
- {
- QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable,
- QDirIterator::FollowSymlinks);
- while (iter.hasNext())
- {
- QString subDir = iter.next();
- if (!QFileInfo(PathCombine(subDir, "instance.cfg")).exists())
- continue;
- QLOG_INFO() << "Loading MultiMC instance from " << subDir;
- InstancePtr instPtr;
- auto error = InstanceFactory::get().loadInstance(instPtr, subDir);
- if(!continueProcessInstance(instPtr, error, subDir, groupMap))
- continue;
- tempList.append(instPtr);
- }
- }
-
- if (MMC->settings()->get("TrackFTBInstances").toBool())
- {
- loadFTBInstances(groupMap, tempList);
- }
- beginResetModel();
- m_instances.clear();
- for(auto inst: tempList)
- {
- inst->setParent(this);
- connect(inst.get(), SIGNAL(propertiesChanged(BaseInstance *)), this,
- SLOT(propertiesChanged(BaseInstance *)));
- connect(inst.get(), SIGNAL(groupChanged()), this, SLOT(groupChanged()));
- connect(inst.get(), SIGNAL(nuked(BaseInstance *)), this,
- SLOT(instanceNuked(BaseInstance *)));
- m_instances.append(inst);
- }
- endResetModel();
- emit dataIsInvalid();
- return NoError;
-}
-
-/// Clear all instances. Triggers notifications.
-void InstanceList::clear()
-{
- beginResetModel();
- saveGroupList();
- m_instances.clear();
- endResetModel();
- emit dataIsInvalid();
-}
-
-void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value)
-{
- m_instDir = value.toString();
- loadList();
-}
-
-/// Add an instance. Triggers notifications, returns the new index
-int InstanceList::add(InstancePtr t)
-{
- beginInsertRows(QModelIndex(), m_instances.size(), m_instances.size());
- m_instances.append(t);
- t->setParent(this);
- connect(t.get(), SIGNAL(propertiesChanged(BaseInstance *)), this,
- SLOT(propertiesChanged(BaseInstance *)));
- connect(t.get(), SIGNAL(groupChanged()), this, SLOT(groupChanged()));
- connect(t.get(), SIGNAL(nuked(BaseInstance *)), this, SLOT(instanceNuked(BaseInstance *)));
- endInsertRows();
- return count() - 1;
-}
-
-InstancePtr InstanceList::getInstanceById(QString instId) const
-{
- if (m_instances.isEmpty())
- {
- return InstancePtr();
- }
-
- QListIterator<InstancePtr> iter(m_instances);
- InstancePtr inst;
- while (iter.hasNext())
- {
- inst = iter.next();
- if (inst->id() == instId)
- break;
- }
- if (inst->id() != instId)
- return InstancePtr();
- else
- return iter.peekPrevious();
-}
-
-QModelIndex InstanceList::getInstanceIndexById(const QString &id) const
-{
- return index(getInstIndex(getInstanceById(id).get()));
-}
-
-int InstanceList::getInstIndex(BaseInstance *inst) const
-{
- for (int i = 0; i < m_instances.count(); i++)
- {
- if (inst == m_instances[i].get())
- {
- return i;
- }
- }
- return -1;
-}
-
-bool InstanceList::continueProcessInstance(InstancePtr instPtr, const int error,
- const QDir &dir, QMap<QString, QString> &groupMap)
-{
- if (error != InstanceFactory::NoLoadError && error != InstanceFactory::NotAnInstance)
- {
- QString errorMsg = QString("Failed to load instance %1: ")
- .arg(QFileInfo(dir.absolutePath()).baseName())
- .toUtf8();
-
- switch (error)
- {
- default:
- errorMsg += QString("Unknown instance loader error %1").arg(error);
- break;
- }
- QLOG_ERROR() << errorMsg.toUtf8();
- return false;
- }
- else if (!instPtr)
- {
- QLOG_ERROR() << QString("Error loading instance %1. Instance loader returned null.")
- .arg(QFileInfo(dir.absolutePath()).baseName())
- .toUtf8();
- return false;
- }
- else
- {
- auto iter = groupMap.find(instPtr->id());
- if (iter != groupMap.end())
- {
- instPtr->setGroupInitial((*iter));
- }
- QLOG_INFO() << "Loaded instance " << instPtr->name() << " from " << dir.absolutePath();
- return true;
- }
-}
-
-void InstanceList::instanceNuked(BaseInstance *inst)
-{
- int i = getInstIndex(inst);
- if (i != -1)
- {
- beginRemoveRows(QModelIndex(), i, i);
- m_instances.removeAt(i);
- endRemoveRows();
- }
-}
-
-void InstanceList::propertiesChanged(BaseInstance *inst)
-{
- int i = getInstIndex(inst);
- if (i != -1)
- {
- emit dataChanged(index(i), index(i));
- }
-}
-
-InstanceProxyModel::InstanceProxyModel(QObject *parent) : GroupedProxyModel(parent)
-{
-}
-
-bool InstanceProxyModel::subSortLessThan(const QModelIndex &left,
- const QModelIndex &right) const
-{
- BaseInstance *pdataLeft = static_cast<BaseInstance *>(left.internalPointer());
- BaseInstance *pdataRight = static_cast<BaseInstance *>(right.internalPointer());
- QString sortMode = MMC->settings()->get("InstSortMode").toString();
- if (sortMode == "LastLaunch")
- {
- return pdataLeft->lastLaunch() > pdataRight->lastLaunch();
- }
- else
- {
- return QString::localeAwareCompare(pdataLeft->name(), pdataRight->name()) < 0;
- }
-}
diff --git a/logic/lists/InstanceList.h b/logic/lists/InstanceList.h
deleted file mode 100644
index f0bbb7ec..00000000
--- a/logic/lists/InstanceList.h
+++ /dev/null
@@ -1,152 +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 <QAbstractListModel>
-#include <QSet>
-#include <gui/groupview/GroupedProxyModel.h>
-#include <QIcon>
-
-#include "logic/BaseInstance.h"
-
-class BaseInstance;
-
-class QDir;
-
-struct FTBRecord
-{
- QString dirName;
- QString name;
- QString logo;
- QString mcVersion;
- QString description;
- QString instanceDir;
- QString templateDir;
-};
-
-class InstanceList : public QAbstractListModel
-{
- Q_OBJECT
-private:
- void loadGroupList(QMap<QString, QString> &groupList);
- QList<FTBRecord> discoverFTBInstances();
- void loadFTBInstances(QMap<QString, QString> &groupMap, QList<InstancePtr> & tempList);
-
-private
-slots:
- void saveGroupList();
-
-public:
- explicit InstanceList(const QString &instDir, QObject *parent = 0);
- virtual ~InstanceList();
-
-public:
- QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- enum AdditionalRoles
- {
- InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
- InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
- };
- /*!
- * \brief Error codes returned by functions in the InstanceList class.
- * NoError Indicates that no error occurred.
- * UnknownError indicates that an unspecified error occurred.
- */
- enum InstListError
- {
- NoError = 0,
- UnknownError
- };
-
- QString instDir() const
- {
- return m_instDir;
- }
-
- /*!
- * \brief Get the instance at index
- */
- InstancePtr at(int i) const
- {
- return m_instances.at(i);
- }
- ;
-
- /*!
- * \brief Get the count of loaded instances
- */
- int count() const
- {
- return m_instances.count();
- }
- ;
-
- /// Clear all instances. Triggers notifications.
- void clear();
-
- /// Add an instance. Triggers notifications, returns the new index
- int add(InstancePtr t);
-
- /// Get an instance by ID
- InstancePtr getInstanceById(QString id) const;
-
- QModelIndex getInstanceIndexById(const QString &id) const;
-
- // FIXME: instead of iterating through all instances and forming a set, keep the set around
- QStringList getGroups();
-signals:
- void dataIsInvalid();
-
-public
-slots:
- void on_InstFolderChanged(const Setting &setting, QVariant value);
-
- /*!
- * \brief Loads the instance list. Triggers notifications.
- */
- InstListError loadList();
-
-private
-slots:
- void propertiesChanged(BaseInstance *inst);
- void instanceNuked(BaseInstance *inst);
- void groupChanged();
-
-private:
- int getInstIndex(BaseInstance *inst) const;
-
- bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir,
- QMap<QString, QString> &groupMap);
-
-protected:
- QString m_instDir;
- QList<InstancePtr> m_instances;
- QSet<QString> m_groups;
-};
-
-class InstanceProxyModel : public GroupedProxyModel
-{
-public:
- explicit InstanceProxyModel(QObject *parent = 0);
-
-protected:
- virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
-};
diff --git a/logic/lists/JavaVersionList.cpp b/logic/lists/JavaVersionList.cpp
deleted file mode 100644
index 4fd0bc19..00000000
--- a/logic/lists/JavaVersionList.cpp
+++ /dev/null
@@ -1,241 +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 "JavaVersionList.h"
-#include "MultiMC.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include "logger/QsLog.h"
-#include "logic/JavaCheckerJob.h"
-#include "logic/JavaUtils.h"
-
-JavaVersionList::JavaVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *JavaVersionList::getLoadTask()
-{
- return new JavaListLoadTask(this);
-}
-
-const BaseVersionPtr JavaVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-bool JavaVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-int JavaVersionList::count() const
-{
- return m_vlist.count();
-}
-
-int JavaVersionList::columnCount(const QModelIndex &parent) const
-{
- return 3;
-}
-
-QVariant JavaVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<JavaVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case 0:
- return version->id;
-
- case 1:
- return version->arch;
-
- case 2:
- return version->path;
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return version->descriptor();
-
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- default:
- return QVariant();
- }
-}
-
-QVariant JavaVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case 0:
- return "Version";
-
- case 1:
- return "Arch";
-
- case 2:
- return "Path";
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case 0:
- return "The name of the version.";
-
- case 1:
- return "The architecture this version is for.";
-
- case 2:
- return "Path to this Java version.";
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionPtr JavaVersionList::getTopRecommended() const
-{
- auto first = m_vlist.first();
- if(first != nullptr)
- {
- return first;
- }
- else
- {
- return BaseVersionPtr();
- }
-}
-
-void JavaVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- endResetModel();
- // NOW SORT!!
- // sort();
-}
-
-void JavaVersionList::sort()
-{
- // NO-OP for now
-}
-
-JavaListLoadTask::JavaListLoadTask(JavaVersionList *vlist) : Task()
-{
- m_list = vlist;
- m_currentRecommended = NULL;
-}
-
-JavaListLoadTask::~JavaListLoadTask()
-{
-}
-
-void JavaListLoadTask::executeTask()
-{
- setStatus(tr("Detecting Java installations..."));
-
- JavaUtils ju;
- QList<QString> candidate_paths = ju.FindJavaPaths();
-
- m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
- connect(m_job.get(), SIGNAL(finished(QList<JavaCheckResult>)), this, SLOT(javaCheckerFinished(QList<JavaCheckResult>)));
- connect(m_job.get(), SIGNAL(progress(int, int)), this, SLOT(checkerProgress(int, int)));
-
- QLOG_DEBUG() << "Probing the following Java paths: ";
- int id = 0;
- for(QString candidate : candidate_paths)
- {
- QLOG_DEBUG() << " " << candidate;
-
- auto candidate_checker = new JavaChecker();
- candidate_checker->path = candidate;
- candidate_checker->id = id;
- m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker));
-
- id++;
- }
-
- m_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 (auto java : candidates)
- {
- //QLOG_INFO() << java->id << java->arch << " at " << java->path;
- BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
-
- if (bp_java)
- {
- javas_bvp.append(java);
- }
- }
-
- m_list->updateListData(javas_bvp);
- emitSucceeded();
-}
diff --git a/logic/lists/JavaVersionList.h b/logic/lists/JavaVersionList.h
deleted file mode 100644
index e6cc8e5f..00000000
--- a/logic/lists/JavaVersionList.h
+++ /dev/null
@@ -1,96 +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 <QAbstractListModel>
-
-#include "BaseVersionList.h"
-#include "logic/tasks/Task.h"
-#include "logic/JavaCheckerJob.h"
-
-class JavaListLoadTask;
-
-struct JavaVersion : public BaseVersion
-{
- virtual QString descriptor()
- {
- return id;
- }
-
- virtual QString name()
- {
- return id;
- }
-
- virtual QString typeString() const
- {
- return arch;
- }
-
- QString id;
- QString arch;
- QString path;
-};
-
-typedef std::shared_ptr<JavaVersion> JavaVersionPtr;
-
-class JavaVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- explicit JavaVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sort();
-
- virtual BaseVersionPtr getTopRecommended() const;
-
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
-public
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-};
-
-class JavaListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit JavaListLoadTask(JavaVersionList *vlist);
- ~JavaListLoadTask();
-
- virtual void executeTask();
-public slots:
- void javaCheckerFinished(QList<JavaCheckResult> results);
- void checkerProgress(int current, int total);
-
-protected:
- std::shared_ptr<JavaCheckerJob> m_job;
- JavaVersionList *m_list;
- JavaVersion *m_currentRecommended;
-};
diff --git a/logic/lists/LiteLoaderVersionList.cpp b/logic/lists/LiteLoaderVersionList.cpp
deleted file mode 100644
index ef95eefd..00000000
--- a/logic/lists/LiteLoaderVersionList.cpp
+++ /dev/null
@@ -1,223 +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 "LiteLoaderVersionList.h"
-#include "MultiMC.h"
-#include "logic/net/URLConstants.h"
-
-#include <QtXml>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QJsonParseError>
-
-#include <QtAlgorithms>
-
-#include <QtNetwork>
-
-LiteLoaderVersionList::LiteLoaderVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *LiteLoaderVersionList::getLoadTask()
-{
- return new LLListLoadTask(this);
-}
-
-bool LiteLoaderVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr LiteLoaderVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int LiteLoaderVersionList::count() const
-{
- return m_vlist.count();
-}
-
-static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
-{
- auto left = std::dynamic_pointer_cast<LiteLoaderVersion>(first);
- auto right = std::dynamic_pointer_cast<LiteLoaderVersion>(second);
- return left->timestamp > right->timestamp;
-}
-
-void LiteLoaderVersionList::sort()
-{
- beginResetModel();
- qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-BaseVersionPtr LiteLoaderVersionList::getLatestStable() const
-{
- for (int i = 0; i < m_vlist.length(); i++)
- {
- auto ver = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist.at(i));
- if (ver->isLatest)
- {
- return m_vlist.at(i);
- }
- }
- return BaseVersionPtr();
-}
-
-void LiteLoaderVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-LLListLoadTask::LLListLoadTask(LiteLoaderVersionList *vlist)
-{
- m_list = vlist;
-}
-
-LLListLoadTask::~LLListLoadTask()
-{
-}
-
-void LLListLoadTask::executeTask()
-{
- setStatus(tr("Loading LiteLoader version list..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto liteloaderEntry = MMC->metacache()->resolveEntry("liteloader", "versions.json");
-
- // verify by poking the server.
- liteloaderEntry->stale = true;
-
- job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::LITELOADER_URL),
- liteloaderEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-void LLListLoadTask::listFailed()
-{
- emitFailed("Failed to load LiteLoader version list.");
- return;
-}
-
-void LLListLoadTask::listDownloaded()
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- emitFailed("Failed to open the LiteLoader version list.");
- return;
- }
- data = listFile.readAll();
- listFile.close();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: jsonDoc is not an object");
- return;
- }
-
- const QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("versions").isObject())
- {
- emitFailed("Error parsing version list JSON: missing 'versions' object");
- return;
- }
-
- auto meta = root.value("meta").toObject();
- QString description = meta.value("description").toString(tr("This is a lightweight loader for mods that don't change game mechanics."));
- QString defaultUrl = meta.value("url").toString("http://dl.liteloader.com");
- QString authors = meta.value("authors").toString("Mumfrey");
- auto versions = root.value("versions").toObject();
-
- QList<BaseVersionPtr> tempList;
- for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt)
- {
- const QString mcVersion = vIt.key();
- QString latest;
- const QJsonObject artefacts = vIt.value()
- .toObject()
- .value("artefacts")
- .toObject()
- .value("com.mumfrey:liteloader")
- .toObject();
- QList<BaseVersionPtr> perMcVersionList;
- for (auto aIt = artefacts.begin(); aIt != artefacts.end(); ++aIt)
- {
- const QString identifier = aIt.key();
- const QJsonObject artefact = aIt.value().toObject();
- if (identifier == "latest")
- {
- latest = artefact.value("version").toString();
- continue;
- }
- LiteLoaderVersionPtr version(new LiteLoaderVersion());
- version->version = artefact.value("version").toString();
- version->file = artefact.value("file").toString();
- version->mcVersion = mcVersion;
- version->md5 = artefact.value("md5").toString();
- version->timestamp = artefact.value("timestamp").toDouble();
- version->tweakClass = artefact.value("tweakClass").toString();
- version->authors = authors;
- version->description = description;
- version->defaultUrl = defaultUrl;
- const QJsonArray libs = artefact.value("libraries").toArray();
- for (auto lIt = libs.begin(); lIt != libs.end(); ++lIt)
- {
- version->libraries.append((*lIt).toObject().value("name").toString());
- }
- perMcVersionList.append(version);
- }
- for (auto version : perMcVersionList)
- {
- auto v = std::dynamic_pointer_cast<LiteLoaderVersion>(version);
- v->isLatest = v->version == latest;
- }
- tempList.append(perMcVersionList);
- }
- m_list->updateListData(tempList);
-
- emitSucceeded();
-}
diff --git a/logic/lists/LiteLoaderVersionList.h b/logic/lists/LiteLoaderVersionList.h
deleted file mode 100644
index bfc913e5..00000000
--- a/logic/lists/LiteLoaderVersionList.h
+++ /dev/null
@@ -1,112 +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 <QString>
-#include <QStringList>
-#include "BaseVersionList.h"
-#include "logic/tasks/Task.h"
-#include "logic/BaseVersion.h"
-#include <logic/net/NetJob.h>
-
-class LLListLoadTask;
-class QNetworkReply;
-
-class LiteLoaderVersion : public BaseVersion
-{
-public:
- QString descriptor() override
- {
- if (isLatest)
- {
- return QObject::tr("Latest");
- }
- return QString();
- }
- QString typeString() const override
- {
- return mcVersion;
- }
- QString name() override
- {
- return version;
- }
-
- // important info
- QString version;
- QString file;
- QString mcVersion;
- QString md5;
- int timestamp;
- bool isLatest;
- QString tweakClass;
- QStringList libraries;
-
- // meta
- QString defaultUrl;
- QString description;
- QString authors;
-};
-typedef std::shared_ptr<LiteLoaderVersion> LiteLoaderVersionPtr;
-
-class LiteLoaderVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class LLListLoadTask;
-
- explicit LiteLoaderVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sort();
-
- virtual BaseVersionPtr getLatestStable() const;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-};
-
-class LLListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit LLListLoadTask(LiteLoaderVersionList *vlist);
- ~LLListLoadTask();
-
- virtual void executeTask();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
-
-protected:
- NetJobPtr listJob;
- CacheDownloadPtr listDownload;
- LiteLoaderVersionList *m_list;
-};
diff --git a/logic/lists/LwjglVersionList.cpp b/logic/lists/LwjglVersionList.cpp
deleted file mode 100644
index df46d7be..00000000
--- a/logic/lists/LwjglVersionList.cpp
+++ /dev/null
@@ -1,199 +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 "LwjglVersionList.h"
-#include "MultiMC.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include "logger/QsLog.h"
-
-#define RSS_URL "http://sourceforge.net/api/file/index/project-id/58488/mtime/desc/rss"
-
-LWJGLVersionList::LWJGLVersionList(QObject *parent) : QAbstractListModel(parent)
-{
- setLoading(false);
-}
-
-QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- const PtrLWJGLVersion version = at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- return version->name();
-
- case Qt::ToolTipRole:
- return version->url();
-
- default:
- return QVariant();
- }
-}
-
-QVariant LWJGLVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- return "Version";
-
- case Qt::ToolTipRole:
- return "LWJGL version name.";
-
- default:
- return QVariant();
- }
-}
-
-int LWJGLVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-bool LWJGLVersionList::isLoading() const
-{
- return m_loading;
-}
-
-void LWJGLVersionList::loadList()
-{
- Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)");
-
- setLoading(true);
- auto worker = MMC->qnam();
- QNetworkRequest req(QUrl(RSS_URL));
- req.setRawHeader("Accept", "text/xml");
- req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)");
- reply = worker->get(req);
- connect(reply, SIGNAL(finished()), SLOT(netRequestComplete()));
-}
-
-inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
-{
- QDomNodeList elementList = parent.elementsByTagName(tagname);
- if (elementList.count())
- return elementList.at(0).toElement();
- else
- return QDomElement();
-}
-
-void LWJGLVersionList::netRequestComplete()
-{
- if (reply->error() == QNetworkReply::NoError)
- {
- QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
- Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid");
-
- QDomDocument doc;
-
- QString xmlErrorMsg;
- int errorLine;
- if (!doc.setContent(reply->readAll(), false, &xmlErrorMsg, &errorLine))
- {
- failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " +
- QString::number(errorLine));
- setLoading(false);
- return;
- }
-
- QDomNodeList items = doc.elementsByTagName("item");
-
- QList<PtrLWJGLVersion> tempList;
-
- for (int i = 0; i < items.length(); i++)
- {
- Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list",
- "XML element isn't an element... wat?");
-
- QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
- if (linkElement.isNull())
- {
- QLOG_INFO() << "Link element" << i << "in RSS feed doesn't exist! Skipping.";
- continue;
- }
-
- QString link = linkElement.text();
-
- // Make sure it's a download link.
- if (link.endsWith("/download") && link.contains(lwjglRegex))
- {
- QString name = link.mid(lwjglRegex.indexIn(link) + 6);
- // Subtract 4 here to remove the .zip file extension.
- name = name.left(lwjglRegex.matchedLength() - 10);
-
- QUrl url(link);
- if (!url.isValid())
- {
- QLOG_INFO() << "LWJGL version URL isn't valid:" << link << "Skipping.";
- continue;
- }
-
- tempList.append(LWJGLVersion::Create(name, link));
- }
- }
-
- beginResetModel();
- m_vlist.swap(tempList);
- endResetModel();
-
- QLOG_INFO() << "Loaded LWJGL list.";
- finished();
- }
- else
- {
- failed("Failed to load LWJGL list. Network error: " + reply->errorString());
- }
-
- setLoading(false);
- reply->deleteLater();
-}
-
-const PtrLWJGLVersion LWJGLVersionList::getVersion(const QString &versionName)
-{
- for (int i = 0; i < count(); i++)
- {
- QString name = at(i)->name();
- if (name == versionName)
- return at(i);
- }
- return PtrLWJGLVersion();
-}
-
-void LWJGLVersionList::failed(QString msg)
-{
- QLOG_INFO() << msg;
- emit loadListFailed(msg);
-}
-
-void LWJGLVersionList::finished()
-{
- emit loadListFinished();
-}
-
-void LWJGLVersionList::setLoading(bool loading)
-{
- m_loading = loading;
- emit loadingStateUpdated(m_loading);
-}
diff --git a/logic/lists/LwjglVersionList.h b/logic/lists/LwjglVersionList.h
deleted file mode 100644
index fa57e8eb..00000000
--- a/logic/lists/LwjglVersionList.h
+++ /dev/null
@@ -1,148 +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 <QAbstractListModel>
-#include <QUrl>
-#include <QNetworkReply>
-
-#include <memory>
-
-class LWJGLVersion;
-typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion;
-
-class LWJGLVersion : public QObject
-{
- Q_OBJECT
-
- LWJGLVersion(const QString &name, const QString &url, QObject *parent = 0)
- : QObject(parent), m_name(name), m_url(url)
- {
- }
-
-public:
-
- static PtrLWJGLVersion Create(const QString &name, const QString &url, QObject *parent = 0)
- {
- return PtrLWJGLVersion(new LWJGLVersion(name, url, parent));
- }
- ;
-
- QString name() const
- {
- return m_name;
- }
-
- QString url() const
- {
- return m_url;
- }
-
-protected:
- QString m_name;
- QString m_url;
-};
-
-class LWJGLVersionList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- explicit LWJGLVersionList(QObject *parent = 0);
-
- bool isLoaded()
- {
- return m_vlist.length() > 0;
- }
-
- const PtrLWJGLVersion getVersion(const QString &versionName);
- PtrLWJGLVersion at(int index)
- {
- return m_vlist[index];
- }
- const PtrLWJGLVersion at(int index) const
- {
- return m_vlist[index];
- }
-
- int count() const
- {
- return m_vlist.length();
- }
-
- 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
- {
- return count();
- }
- virtual int columnCount(const QModelIndex &parent) const;
-
- virtual bool isLoading() const;
- virtual bool errored() const
- {
- return m_errored;
- }
-
- virtual QString lastErrorMsg() const
- {
- return m_lastErrorMsg;
- }
-
-public
-slots:
- /*!
- * Loads the version list.
- * This is done asynchronously. On success, the loadListFinished() signal will
- * be emitted. The list model will be reset as well, resulting in the modelReset()
- * signal being emitted. Note that the model will be reset before loadListFinished() is
- * emitted.
- * If loading the list failed, the loadListFailed(QString msg),
- * signal will be emitted.
- */
- virtual void loadList();
-
-signals:
- /*!
- * Emitted when the list either starts or finishes loading.
- * \param loading Whether or not the list is loading.
- */
- void loadingStateUpdated(bool loading);
-
- void loadListFinished();
-
- void loadListFailed(QString msg);
-
-private:
- QList<PtrLWJGLVersion> m_vlist;
-
- QNetworkReply *m_netReply;
- QNetworkReply *reply;
-
- bool m_loading;
- bool m_errored;
- QString m_lastErrorMsg;
-
- void failed(QString msg);
-
- void finished();
-
- void setLoading(bool loading);
-
-private
-slots:
- virtual void netRequestComplete();
-};
diff --git a/logic/lists/MinecraftVersionList.cpp b/logic/lists/MinecraftVersionList.cpp
deleted file mode 100644
index b9d60c61..00000000
--- a/logic/lists/MinecraftVersionList.cpp
+++ /dev/null
@@ -1,290 +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 "MinecraftVersionList.h"
-#include "MultiMC.h"
-#include "logic/net/URLConstants.h"
-
-#include <QtXml>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QJsonParseError>
-
-#include <QtAlgorithms>
-
-#include <QtNetwork>
-
-MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *MinecraftVersionList::getLoadTask()
-{
- return new MCVListLoadTask(this);
-}
-
-bool MinecraftVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr MinecraftVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int MinecraftVersionList::count() const
-{
- return m_vlist.count();
-}
-
-static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
-{
- auto left = std::dynamic_pointer_cast<MinecraftVersion>(first);
- auto right = std::dynamic_pointer_cast<MinecraftVersion>(second);
- return left->timestamp > right->timestamp;
-}
-
-void MinecraftVersionList::sortInternal()
-{
- qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
-}
-
-void MinecraftVersionList::sort()
-{
- beginResetModel();
- sortInternal();
- endResetModel();
-}
-
-BaseVersionPtr MinecraftVersionList::getLatestStable() const
-{
- for (int i = 0; i < m_vlist.length(); i++)
- {
- auto ver = std::dynamic_pointer_cast<MinecraftVersion>(m_vlist.at(i));
- if (ver->is_latest && !ver->is_snapshot)
- {
- return m_vlist.at(i);
- }
- }
- return BaseVersionPtr();
-}
-
-void MinecraftVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- sortInternal();
- endResetModel();
-}
-
-inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
-{
- QDomNodeList elementList = parent.elementsByTagName(tagname);
- if (elementList.count())
- return elementList.at(0).toElement();
- else
- return QDomElement();
-}
-
-inline QDateTime timeFromS3Time(QString str)
-{
- return QDateTime::fromString(str, Qt::ISODate);
-}
-
-MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist)
-{
- m_list = vlist;
- m_currentStable = NULL;
- vlistReply = nullptr;
- legacyWhitelist.insert("1.5.2");
- legacyWhitelist.insert("1.5.1");
- legacyWhitelist.insert("1.5");
- legacyWhitelist.insert("1.4.7");
- legacyWhitelist.insert("1.4.6");
- legacyWhitelist.insert("1.4.5");
- legacyWhitelist.insert("1.4.4");
- legacyWhitelist.insert("1.4.3");
- legacyWhitelist.insert("1.4.2");
- legacyWhitelist.insert("1.4.1");
- legacyWhitelist.insert("1.4");
- legacyWhitelist.insert("1.3.2");
- legacyWhitelist.insert("1.3.1");
- legacyWhitelist.insert("1.3");
- legacyWhitelist.insert("1.2.5");
- legacyWhitelist.insert("1.2.4");
- legacyWhitelist.insert("1.2.3");
- legacyWhitelist.insert("1.2.2");
- legacyWhitelist.insert("1.2.1");
- legacyWhitelist.insert("1.1");
- legacyWhitelist.insert("1.0.1");
- legacyWhitelist.insert("1.0");
-}
-
-MCVListLoadTask::~MCVListLoadTask()
-{
-}
-
-void MCVListLoadTask::executeTask()
-{
- setStatus(tr("Loading instance version list..."));
- auto worker = MMC->qnam();
- vlistReply = worker->get(QNetworkRequest(QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json")));
- connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded()));
-}
-
-void MCVListLoadTask::list_downloaded()
-{
- if (vlistReply->error() != QNetworkReply::NoError)
- {
- vlistReply->deleteLater();
- emitFailed("Failed to load Minecraft main version list" + vlistReply->errorString());
- return;
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(vlistReply->readAll(), &jsonError);
- vlistReply->deleteLater();
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: jsonDoc is not an object");
- return;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Get the ID of the latest release and the latest snapshot.
- if (!root.value("latest").isObject())
- {
- emitFailed("Error parsing version list JSON: version list is missing 'latest' object");
- return;
- }
-
- QJsonObject latest = root.value("latest").toObject();
-
- QString latestReleaseID = latest.value("release").toString("");
- QString latestSnapshotID = latest.value("snapshot").toString("");
- if (latestReleaseID.isEmpty())
- {
- emitFailed("Error parsing version list JSON: latest release field is missing");
- return;
- }
- if (latestSnapshotID.isEmpty())
- {
- emitFailed("Error parsing version list JSON: latest snapshot field is missing");
- return;
- }
-
- // Now, get the array of versions.
- if (!root.value("versions").isArray())
- {
- emitFailed(
- "Error parsing version list JSON: version list object is missing 'versions' array");
- return;
- }
- QJsonArray versions = root.value("versions").toArray();
-
- QList<BaseVersionPtr> tempList;
- for (int i = 0; i < versions.count(); i++)
- {
- bool is_snapshot = false;
- bool is_latest = false;
-
- // Load the version info.
- if (!versions[i].isObject())
- {
- // FIXME: log this somewhere
- continue;
- }
- QJsonObject version = versions[i].toObject();
- QString versionID = version.value("id").toString("");
- QString versionTimeStr = version.value("releaseTime").toString("");
- QString versionTypeStr = version.value("type").toString("");
- if (versionID.isEmpty() || versionTimeStr.isEmpty() || versionTypeStr.isEmpty())
- {
- // FIXME: log this somewhere
- continue;
- }
-
- // Parse the timestamp.
- QDateTime versionTime = timeFromS3Time(versionTimeStr);
- if (!versionTime.isValid())
- {
- // FIXME: log this somewhere
- continue;
- }
- // Parse the type.
- MinecraftVersion::VersionType versionType;
- // OneSix or Legacy. use filter to determine type
- if (versionTypeStr == "release")
- {
- versionType = legacyWhitelist.contains(versionID) ? MinecraftVersion::Legacy
- : MinecraftVersion::OneSix;
- is_latest = (versionID == latestReleaseID);
- is_snapshot = false;
- }
- else if (versionTypeStr == "snapshot") // It's a snapshot... yay
- {
- versionType = legacyWhitelist.contains(versionID) ? MinecraftVersion::Legacy
- : MinecraftVersion::OneSix;
- is_latest = (versionID == latestSnapshotID);
- is_snapshot = true;
- }
- else if (versionTypeStr == "old_alpha")
- {
- versionType = MinecraftVersion::Nostalgia;
- is_latest = false;
- is_snapshot = false;
- }
- else if (versionTypeStr == "old_beta")
- {
- versionType = MinecraftVersion::Legacy;
- is_latest = false;
- is_snapshot = false;
- }
- else
- {
- // FIXME: log this somewhere
- continue;
- }
- // Get the download URL.
- 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());
- mcVersion->m_name = mcVersion->m_descriptor = versionID;
- mcVersion->timestamp = versionTime.toMSecsSinceEpoch();
- mcVersion->download_url = dlUrl;
- mcVersion->is_latest = is_latest;
- mcVersion->is_snapshot = is_snapshot;
- mcVersion->type = versionType;
- tempList.append(mcVersion);
- }
- m_list->updateListData(tempList);
-
- emitSucceeded();
- return;
-}
diff --git a/logic/lists/MinecraftVersionList.h b/logic/lists/MinecraftVersionList.h
deleted file mode 100644
index 167f4d11..00000000
--- a/logic/lists/MinecraftVersionList.h
+++ /dev/null
@@ -1,76 +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 <QList>
-#include <QSet>
-
-#include "BaseVersionList.h"
-#include "logic/tasks/Task.h"
-#include "logic/MinecraftVersion.h"
-
-class MCVListLoadTask;
-class QNetworkReply;
-
-class MinecraftVersionList : public BaseVersionList
-{
- Q_OBJECT
-private:
- void sortInternal();
-public:
- friend class MCVListLoadTask;
-
- explicit MinecraftVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sort();
-
- virtual BaseVersionPtr getLatestStable() const;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-};
-
-class MCVListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit MCVListLoadTask(MinecraftVersionList *vlist);
- ~MCVListLoadTask();
-
- virtual void executeTask();
-
-protected
-slots:
- void list_downloaded();
-
-protected:
- QNetworkReply *vlistReply;
- MinecraftVersionList *m_list;
- MinecraftVersion *m_currentStable;
- QSet<QString> legacyWhitelist;
-};