diff options
author | Petr Mrázek <peterix@gmail.com> | 2014-05-08 21:20:10 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2014-06-09 01:38:30 +0200 |
commit | 8a3a0f5a529a95c7511436051b63887dff158c50 (patch) | |
tree | 0162e0d6a37cd5a5b3aa5facf6ba6561e33f60bf /logic/lists | |
parent | 69a9ca39ad0685663092a4455de3865715f0122e (diff) | |
download | MultiMC-8a3a0f5a529a95c7511436051b63887dff158c50.tar MultiMC-8a3a0f5a529a95c7511436051b63887dff158c50.tar.gz MultiMC-8a3a0f5a529a95c7511436051b63887dff158c50.tar.lz MultiMC-8a3a0f5a529a95c7511436051b63887dff158c50.tar.xz MultiMC-8a3a0f5a529a95c7511436051b63887dff158c50.zip |
Reorganize logic code.
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/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/LwjglVersionList.cpp | 199 | ||||
-rw-r--r-- | logic/lists/LwjglVersionList.h | 148 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.cpp | 330 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.h | 76 |
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; -}; |