summaryrefslogtreecommitdiffstats
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/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/LwjglVersionList.cpp199
-rw-r--r--logic/lists/LwjglVersionList.h148
-rw-r--r--logic/lists/MinecraftVersionList.cpp330
-rw-r--r--logic/lists/MinecraftVersionList.h76
10 files changed, 0 insertions, 2101 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/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/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 cdf5fa77..00000000
--- a/logic/lists/MinecraftVersionList.cpp
+++ /dev/null
@@ -1,330 +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 <logic/MMCJson.h>
-
-#include <QtXml>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QJsonParseError>
-
-#include <QtAlgorithms>
-
-#include <QtNetwork>
-
-inline QDateTime timeFromS3Time(QString str)
-{
- return QDateTime::fromString(str, Qt::ISODate);
-}
-
-MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent)
-{
- loadBuiltinList();
-}
-
-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::loadBuiltinList()
-{
- // grab the version list data from internal resources.
- QResource versionList(":/versions/minecraft.json");
- QFile filez(versionList.absoluteFilePath());
- filez.open(QIODevice::ReadOnly);
- auto data = filez.readAll();
-
- // parse the data as json
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- QJsonObject root = jsonDoc.object();
-
- // parse all the versions
- for (const auto version : MMCJson::ensureArray(root.value("versions")))
- {
- QJsonObject versionObj = version.toObject();
- QString versionID = versionObj.value("id").toString("");
- QString versionTimeStr = versionObj.value("releaseTime").toString("");
- QString versionTypeStr = versionObj.value("type").toString("");
- QSet<QString> traits;
- if (versionObj.contains("+traits"))
- {
- for (auto traitVal : MMCJson::ensureArray(versionObj.value("+traits")))
- {
- traits.insert(MMCJson::ensureString(traitVal));
- }
- }
- 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;
- }
- // Get the download URL.
- QString dlUrl = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionID + "/";
-
- // main class and applet class
- QString mainClass = versionObj.value("type").toString("");
- QString appletClass = versionObj.value("type").toString("");
-
- // 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_builtin = true;
- mcVersion->m_appletClass = appletClass;
- mcVersion->m_mainClass = mainClass;
- mcVersion->m_traits = traits;
- m_vlist.append(mcVersion);
- }
-}
-
-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();
- for (auto version : versions)
- {
- auto descr = version->descriptor();
- for (auto builtin_v : m_vlist)
- {
- if (descr == builtin_v->descriptor())
- {
- goto SKIP_THIS_ONE;
- }
- }
- m_vlist.append(version);
- SKIP_THIS_ONE:
- {
- }
- }
- 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();
-}
-
-MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist)
-{
- m_list = vlist;
- m_currentStable = NULL;
- vlistReply = nullptr;
-}
-
-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;
- }
-
- auto foo = vlistReply->readAll();
- QJsonParseError jsonError;
- QLOG_INFO() << foo;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(foo, &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();
-
- QString latestReleaseID = "INVALID";
- QString latestSnapshotID = "INVALID";
- try
- {
- QJsonObject latest = MMCJson::ensureObject(root.value("latest"));
- latestReleaseID = MMCJson::ensureString(latest.value("release"));
- latestSnapshotID = MMCJson::ensureString(latest.value("snapshot"));
- }
- catch (MMCError &err)
- {
- QLOG_ERROR()
- << tr("Error parsing version list JSON: couldn't determine latest versions");
- }
-
- // 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 (auto version : versions)
- {
- bool is_snapshot = false;
- bool is_latest = false;
-
- // Load the version info.
- if (!version.isObject())
- {
- // FIXME: log this somewhere
- continue;
- }
- QJsonObject versionObj = version.toObject();
- QString versionID = versionObj.value("id").toString("");
- QString versionTimeStr = versionObj.value("releaseTime").toString("");
- QString versionTypeStr = versionObj.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;
- }
- // OneSix or Legacy. use filter to determine type
- if (versionTypeStr == "release")
- {
- is_latest = (versionID == latestReleaseID);
- is_snapshot = false;
- }
- else if (versionTypeStr == "snapshot") // It's a snapshot... yay
- {
- is_latest = (versionID == latestSnapshotID);
- is_snapshot = true;
- }
- else if (versionTypeStr == "old_alpha")
- {
- is_latest = false;
- is_snapshot = false;
- }
- else if (versionTypeStr == "old_beta")
- {
- 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;
- 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 4698fd8f..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();
- void loadBuiltinList();
-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;
-};