diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | MultiMC.cpp | 10 | ||||
-rw-r--r-- | MultiMC.h | 4 | ||||
-rw-r--r-- | gui/dialogs/OneSixModEditDialog.cpp | 40 | ||||
-rw-r--r-- | gui/dialogs/VersionSelectDialog.cpp | 1 | ||||
-rw-r--r-- | logic/BaseInstaller.h | 1 | ||||
-rw-r--r-- | logic/LiteLoaderInstaller.cpp | 41 | ||||
-rw-r--r-- | logic/LiteLoaderInstaller.h | 13 | ||||
-rw-r--r-- | logic/lists/LiteLoaderVersionList.cpp | 190 | ||||
-rw-r--r-- | logic/lists/LiteLoaderVersionList.h | 101 | ||||
-rw-r--r-- | logic/lists/MinecraftVersionList.cpp | 2 | ||||
-rw-r--r-- | logic/net/URLConstants.h | 1 |
12 files changed, 355 insertions, 51 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e7dea67..4ea4c27a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -460,6 +460,8 @@ logic/lists/ForgeVersionList.h logic/lists/ForgeVersionList.cpp logic/lists/JavaVersionList.h logic/lists/JavaVersionList.cpp +logic/lists/LiteLoaderVersionList.h +logic/lists/LiteLoaderVersionList.cpp # Icons logic/icons/MMCIcon.h diff --git a/MultiMC.cpp b/MultiMC.cpp index 598a3a80..39a4443e 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -17,6 +17,7 @@ #include "logic/lists/LwjglVersionList.h" #include "logic/lists/MinecraftVersionList.h" #include "logic/lists/ForgeVersionList.h" +#include "logic/lists/LiteLoaderVersionList.h" #include "logic/news/NewsChecker.h" @@ -536,6 +537,15 @@ std::shared_ptr<ForgeVersionList> MultiMC::forgelist() return m_forgelist; } +std::shared_ptr<LiteLoaderVersionList> MultiMC::liteloaderlist() +{ + if (!m_liteloaderlist) + { + m_liteloaderlist.reset(new LiteLoaderVersionList()); + } + return m_liteloaderlist; +} + std::shared_ptr<MinecraftVersionList> MultiMC::minecraftlist() { if (!m_minecraftlist) @@ -17,6 +17,7 @@ class MojangAccountList; class IconList; class QNetworkAccessManager; class ForgeVersionList; +class LiteLoaderVersionList; class JavaVersionList; class UpdateChecker; class NotificationChecker; @@ -123,6 +124,8 @@ public: std::shared_ptr<ForgeVersionList> forgelist(); + std::shared_ptr<LiteLoaderVersionList> liteloaderlist(); + std::shared_ptr<MinecraftVersionList> minecraftlist(); std::shared_ptr<JavaVersionList> javalist(); @@ -196,6 +199,7 @@ private: std::shared_ptr<HttpMetaCache> m_metacache; std::shared_ptr<LWJGLVersionList> m_lwjgllist; std::shared_ptr<ForgeVersionList> m_forgelist; + std::shared_ptr<LiteLoaderVersionList> m_liteloaderlist; std::shared_ptr<MinecraftVersionList> m_minecraftlist; std::shared_ptr<JavaVersionList> m_javalist; QsLogging::DestinationPtr m_fileDestination; diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp index 9e585de5..fe621a9a 100644 --- a/gui/dialogs/OneSixModEditDialog.cpp +++ b/gui/dialogs/OneSixModEditDialog.cpp @@ -37,6 +37,7 @@ #include "logic/OneSixVersion.h" #include "logic/EnabledItemFilter.h" #include "logic/lists/ForgeVersionList.h" +#include "logic/lists/LiteLoaderVersionList.h" #include "logic/ForgeInstaller.h" #include "logic/LiteLoaderInstaller.h" #include "logic/OneSixVersionBuilder.h" @@ -108,7 +109,7 @@ OneSixModEditDialog::~OneSixModEditDialog() void OneSixModEditDialog::updateVersionControls() { ui->forgeBtn->setEnabled(true); - ui->liteloaderBtn->setEnabled(LiteLoaderInstaller().canApply(m_inst)); + ui->liteloaderBtn->setEnabled(true); ui->mainClassEdit->setText(m_version->mainClass); } @@ -290,24 +291,27 @@ void OneSixModEditDialog::on_liteloaderBtn_clicked() QDir(m_inst->instanceRoot()).remove("custom.json"); m_inst->reloadVersion(this); } - LiteLoaderInstaller liteloader; - if (!liteloader.canApply(m_inst)) - { - QMessageBox::critical( - this, tr("LiteLoader"), - tr("There is no information available on how to install LiteLoader " - "into this version of Minecraft")); - return; - } - if (!liteloader.add(m_inst)) - { - QMessageBox::critical(this, tr("LiteLoader"), - tr("For reasons unknown, the LiteLoader installation failed. " - "Check your MultiMC log files for details.")); - } - else + VersionSelectDialog vselect(MMC->liteloaderlist().get(), tr("Select LiteLoader version"), this); + vselect.setFilter(1, m_inst->currentVersionId()); + vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + + m_inst->currentVersionId()); + if (vselect.exec() && vselect.selectedVersion()) { - m_inst->reloadVersion(this); + LiteLoaderVersionPtr liteloaderVersion = + std::dynamic_pointer_cast<LiteLoaderVersion>(vselect.selectedVersion()); + if (!liteloaderVersion) + return; + LiteLoaderInstaller liteloader(liteloaderVersion); + if (!liteloader.add(m_inst)) + { + QMessageBox::critical(this, tr("LiteLoader"), + tr("For reasons unknown, the LiteLoader installation failed. " + "Check your MultiMC log files for details.")); + } + else + { + m_inst->reloadVersion(this); + } } } diff --git a/gui/dialogs/VersionSelectDialog.cpp b/gui/dialogs/VersionSelectDialog.cpp index 0f379f56..3277fd2f 100644 --- a/gui/dialogs/VersionSelectDialog.cpp +++ b/gui/dialogs/VersionSelectDialog.cpp @@ -82,6 +82,7 @@ void VersionSelectDialog::loadList() Task *loadTask = m_vlist->getLoadTask(); loadTask->setParent(taskDlg); taskDlg->exec(loadTask); + delete taskDlg; } BaseVersionPtr VersionSelectDialog::selectedVersion() const diff --git a/logic/BaseInstaller.h b/logic/BaseInstaller.h index df7eab89..c572e004 100644 --- a/logic/BaseInstaller.h +++ b/logic/BaseInstaller.h @@ -26,7 +26,6 @@ class BaseInstaller public: BaseInstaller(); - virtual bool canApply(OneSixInstance *instance) const { return true; } bool isApplied(OneSixInstance *on); virtual bool add(OneSixInstance *to); diff --git a/logic/LiteLoaderInstaller.cpp b/logic/LiteLoaderInstaller.cpp index c363cad6..126027fb 100644 --- a/logic/LiteLoaderInstaller.cpp +++ b/logic/LiteLoaderInstaller.cpp @@ -24,23 +24,9 @@ #include "OneSixLibrary.h" #include "OneSixInstance.h" -QMap<QString, QString> LiteLoaderInstaller::m_launcherWrapperVersionMapping; - -LiteLoaderInstaller::LiteLoaderInstaller() - : BaseInstaller() -{ - if (m_launcherWrapperVersionMapping.isEmpty()) - { - m_launcherWrapperVersionMapping["1.6.2"] = "1.3"; - m_launcherWrapperVersionMapping["1.6.4"] = "1.8"; - //m_launcherWrapperVersionMapping["1.7.2"] = "1.8"; - //m_launcherWrapperVersionMapping["1.7.4"] = "1.8"; - } -} - -bool LiteLoaderInstaller::canApply(OneSixInstance *instance) const +LiteLoaderInstaller::LiteLoaderInstaller(LiteLoaderVersionPtr version) + : BaseInstaller(), m_version(version) { - return m_launcherWrapperVersionMapping.contains(instance->intendedVersionId()); } bool LiteLoaderInstaller::add(OneSixInstance *to) @@ -53,24 +39,26 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) QJsonObject obj; obj.insert("mainClass", QString("net.minecraft.launchwrapper.Launch")); - obj.insert("+tweakers", QJsonArray::fromStringList(QStringList() << "com.mumfrey.liteloader.launch.LiteLoaderTweaker")); + obj.insert("+tweakers", QJsonArray::fromStringList(QStringList() << m_version->tweakClass)); obj.insert("order", 10); QJsonArray libraries; - // launchwrapper + for (auto libStr : m_version->libraries) { - OneSixLibrary launchwrapperLib("net.minecraft:launchwrapper:" + m_launcherWrapperVersionMapping[to->intendedVersionId()]); - launchwrapperLib.finalize(); - QJsonObject lwLibObj = launchwrapperLib.toJson(); - lwLibObj.insert("insert", QString("prepend")); - libraries.append(lwLibObj); + OneSixLibrary lib(libStr); + lib.finalize(); + QJsonObject libObj = lib.toJson(); + libObj.insert("insert", QString("prepend")); + libraries.append(libObj); } // liteloader { - OneSixLibrary liteloaderLib("com.mumfrey:liteloader:" + to->intendedVersionId()); - liteloaderLib.setBaseUrl("http://dl.liteloader.com/versions/"); + OneSixLibrary liteloaderLib("com.mumfrey:liteloader:" + m_version->version); + liteloaderLib.setAbsoluteUrl( + QString("http://dl.liteloader.com/versions/com/mumfrey/liteloader/%1/%2") + .arg(m_version->mcVersion, m_version->file)); liteloaderLib.finalize(); QJsonObject llLibObj = liteloaderLib.toJson(); llLibObj.insert("insert", QString("prepend")); @@ -87,7 +75,8 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) QFile file(filename(to->instanceRoot())); if (!file.open(QFile::WriteOnly)) { - QLOG_ERROR() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); + QLOG_ERROR() << "Error opening" << file.fileName() + << "for reading:" << file.errorString(); return false; } file.write(QJsonDocument(obj).toJson()); diff --git a/logic/LiteLoaderInstaller.h b/logic/LiteLoaderInstaller.h index 5e01b16c..2e0de64a 100644 --- a/logic/LiteLoaderInstaller.h +++ b/logic/LiteLoaderInstaller.h @@ -20,16 +20,19 @@ #include <QString> #include <QMap> +#include "logic/lists/LiteLoaderVersionList.h" + class LiteLoaderInstaller : public BaseInstaller { public: - LiteLoaderInstaller(); + LiteLoaderInstaller(LiteLoaderVersionPtr version); - bool canApply(OneSixInstance *instance) const override; bool add(OneSixInstance *to) override; private: - virtual QString id() const override { return "com.mumfrey.liteloader"; } - - static QMap<QString, QString> m_launcherWrapperVersionMapping; + virtual QString id() const override + { + return "com.mumfrey.liteloader"; + } + LiteLoaderVersionPtr m_version; }; diff --git a/logic/lists/LiteLoaderVersionList.cpp b/logic/lists/LiteLoaderVersionList.cpp new file mode 100644 index 00000000..b8cea442 --- /dev/null +++ b/logic/lists/LiteLoaderVersionList.cpp @@ -0,0 +1,190 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LiteLoaderVersionList.h" +#include "MultiMC.h" +#include "logic/net/URLConstants.h" + +#include <QtXml> + +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonArray> +#include <QJsonValue> +#include <QJsonParseError> + +#include <QtAlgorithms> + +#include <QtNetwork> + +LiteLoaderVersionList::LiteLoaderVersionList(QObject *parent) : BaseVersionList(parent) +{ +} + +Task *LiteLoaderVersionList::getLoadTask() +{ + return new LLListLoadTask(this); +} + +bool LiteLoaderVersionList::isLoaded() +{ + return m_loaded; +} + +const BaseVersionPtr LiteLoaderVersionList::at(int i) const +{ + return m_vlist.at(i); +} + +int LiteLoaderVersionList::count() const +{ + return m_vlist.count(); +} + +static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second) +{ + auto left = std::dynamic_pointer_cast<LiteLoaderVersion>(first); + auto right = std::dynamic_pointer_cast<LiteLoaderVersion>(second); + return left->timestamp > right->timestamp; +} + +void LiteLoaderVersionList::sort() +{ + beginResetModel(); + qSort(m_vlist.begin(), m_vlist.end(), cmpVersions); + endResetModel(); +} + +BaseVersionPtr LiteLoaderVersionList::getLatestStable() const +{ + for (int i = 0; i < m_vlist.length(); i++) + { + auto ver = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist.at(i)); + if (ver->isLatest) + { + return m_vlist.at(i); + } + } + return BaseVersionPtr(); +} + +void LiteLoaderVersionList::updateListData(QList<BaseVersionPtr> versions) +{ + beginResetModel(); + m_vlist = versions; + m_loaded = true; + qSort(m_vlist.begin(), m_vlist.end(), cmpVersions); + endResetModel(); +} + +LLListLoadTask::LLListLoadTask(LiteLoaderVersionList *vlist) +{ + m_list = vlist; + vlistReply = nullptr; +} + +LLListLoadTask::~LLListLoadTask() +{ +} + +void LLListLoadTask::executeTask() +{ + setStatus(tr("Loading LiteLoader version list...")); + auto worker = MMC->qnam(); + vlistReply = worker->get(QNetworkRequest(QUrl(URLConstants::LITELOADER_URL))); + connect(vlistReply, SIGNAL(finished()), this, SLOT(listDownloaded())); +} + +void LLListLoadTask::listDownloaded() +{ + if (vlistReply->error() != QNetworkReply::NoError) + { + vlistReply->deleteLater(); + emitFailed("Failed to load LiteLoader version list" + vlistReply->errorString()); + return; + } + + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(vlistReply->readAll(), &jsonError); + vlistReply->deleteLater(); + + if (jsonError.error != QJsonParseError::NoError) + { + emitFailed("Error parsing version list JSON:" + jsonError.errorString()); + return; + } + + if (!jsonDoc.isObject()) + { + emitFailed("Error parsing version list JSON: jsonDoc is not an object"); + return; + } + + const QJsonObject root = jsonDoc.object(); + + // Now, get the array of versions. + if (!root.value("versions").isObject()) + { + emitFailed("Error parsing version list JSON: missing 'versions' object"); + return; + } + const QJsonObject versions = root.value("versions").toObject(); + + QList<BaseVersionPtr> tempList; + for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt) + { + const QString mcVersion = vIt.key(); + QString latest; + const QJsonObject artefacts = vIt.value() + .toObject() + .value("artefacts") + .toObject() + .value("com.mumfrey:liteloader") + .toObject(); + QList<BaseVersionPtr> perMcVersionList; + for (auto aIt = artefacts.begin(); aIt != artefacts.end(); ++aIt) + { + const QString identifier = aIt.key(); + const QJsonObject artefact = aIt.value().toObject(); + if (identifier == "latest") + { + latest = artefact.value("version").toString(); + continue; + } + LiteLoaderVersionPtr version(new LiteLoaderVersion()); + version->version = artefact.value("version").toString(); + version->file = artefact.value("file").toString(); + version->mcVersion = mcVersion; + version->md5 = artefact.value("md5").toString(); + version->timestamp = artefact.value("timestamp").toDouble(); + version->tweakClass = artefact.value("tweakClass").toString(); + const QJsonArray libs = artefact.value("libraries").toArray(); + for (auto lIt = libs.begin(); lIt != libs.end(); ++lIt) + { + version->libraries.append((*lIt).toObject().value("name").toString()); + } + perMcVersionList.append(version); + } + for (auto version : perMcVersionList) + { + auto v = std::dynamic_pointer_cast<LiteLoaderVersion>(version); + v->isLatest = v->version == latest; + } + tempList.append(perMcVersionList); + } + m_list->updateListData(tempList); + + emitSucceeded(); +} diff --git a/logic/lists/LiteLoaderVersionList.h b/logic/lists/LiteLoaderVersionList.h new file mode 100644 index 00000000..58927b8f --- /dev/null +++ b/logic/lists/LiteLoaderVersionList.h @@ -0,0 +1,101 @@ +/* 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 "BaseVersionList.h" +#include "logic/tasks/Task.h" +#include "logic/BaseVersion.h" + +class LLListLoadTask; +class QNetworkReply; + +class LiteLoaderVersion : public BaseVersion +{ +public: + QString descriptor() override + { + if (isLatest) + { + return QObject::tr("Latest"); + } + return QString(); + } + QString typeString() const override + { + return mcVersion; + } + QString name() override + { + return version; + } + + QString version; + QString file; + QString mcVersion; + QString md5; + int timestamp; + bool isLatest; + QString tweakClass; + QStringList libraries; +}; +typedef std::shared_ptr<LiteLoaderVersion> LiteLoaderVersionPtr; + +class LiteLoaderVersionList : public BaseVersionList +{ + Q_OBJECT +public: + friend class LLListLoadTask; + + explicit LiteLoaderVersionList(QObject *parent = 0); + + virtual Task *getLoadTask(); + virtual bool isLoaded(); + virtual const BaseVersionPtr at(int i) const; + virtual int count() const; + virtual void sort(); + + virtual BaseVersionPtr getLatestStable() const; + +protected: + QList<BaseVersionPtr> m_vlist; + + bool m_loaded = false; + +protected +slots: + virtual void updateListData(QList<BaseVersionPtr> versions); +}; + +class LLListLoadTask : public Task +{ + Q_OBJECT + +public: + explicit LLListLoadTask(LiteLoaderVersionList *vlist); + ~LLListLoadTask(); + + virtual void executeTask(); + +protected +slots: + void listDownloaded(); + +protected: + QNetworkReply *vlistReply; + LiteLoaderVersionList *m_list; +}; diff --git a/logic/lists/MinecraftVersionList.cpp b/logic/lists/MinecraftVersionList.cpp index ece31e3d..b9d60c61 100644 --- a/logic/lists/MinecraftVersionList.cpp +++ b/logic/lists/MinecraftVersionList.cpp @@ -53,7 +53,7 @@ int MinecraftVersionList::count() const return m_vlist.count(); } -bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second) +static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second) { auto left = std::dynamic_pointer_cast<MinecraftVersion>(first); auto right = std::dynamic_pointer_cast<MinecraftVersion>(second); diff --git a/logic/net/URLConstants.h b/logic/net/URLConstants.h index 8cb1f3fd..07b35c4f 100644 --- a/logic/net/URLConstants.h +++ b/logic/net/URLConstants.h @@ -33,4 +33,5 @@ const QString FORGE_LEGACY_URL("http://files.minecraftforge.net/minecraftforge/j const QString FORGE_GRADLE_URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/json"); const QString MOJANG_STATUS_URL("http://status.mojang.com/check"); const QString MOJANG_STATUS_NEWS_URL("http://status.mojang.com/news"); +const QString LITELOADER_URL("http://dl.liteloader.com/versions/versions.json"); } |