diff options
Diffstat (limited to 'logic/lists')
-rw-r--r-- | logic/lists/BaseVersionList.cpp | 121 | ||||
-rw-r--r-- | logic/lists/BaseVersionList.h | 120 | ||||
-rw-r--r-- | logic/lists/ForgeVersionList.cpp | 455 | ||||
-rw-r--r-- | logic/lists/ForgeVersionList.h | 130 | ||||
-rw-r--r-- | logic/lists/InstanceList.cpp | 618 | ||||
-rw-r--r-- | logic/lists/InstanceList.h | 152 | ||||
-rw-r--r-- | logic/lists/JavaVersionList.cpp | 241 | ||||
-rw-r--r-- | logic/lists/JavaVersionList.h | 96 | ||||
-rw-r--r-- | logic/lists/LiteLoaderVersionList.cpp | 223 | ||||
-rw-r--r-- | logic/lists/LiteLoaderVersionList.h | 112 | ||||
-rw-r--r-- | logic/lists/LwjglVersionList.cpp | 199 | ||||
-rw-r--r-- | logic/lists/LwjglVersionList.h | 148 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.cpp | 290 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.h | 76 |
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; -}; |