summaryrefslogtreecommitdiffstats
path: root/api/logic/minecraft
diff options
context:
space:
mode:
Diffstat (limited to 'api/logic/minecraft')
-rw-r--r--api/logic/minecraft/Library.cpp23
-rw-r--r--api/logic/minecraft/Library_test.cpp2
-rw-r--r--api/logic/minecraft/MinecraftInstance.cpp7
-rw-r--r--api/logic/minecraft/MinecraftProfile.cpp39
-rw-r--r--api/logic/minecraft/MinecraftProfile.h12
-rw-r--r--api/logic/minecraft/MinecraftVersion.cpp230
-rw-r--r--api/logic/minecraft/MinecraftVersion.h132
-rw-r--r--api/logic/minecraft/MinecraftVersionList.cpp677
-rw-r--r--api/logic/minecraft/MinecraftVersionList.h73
-rw-r--r--api/logic/minecraft/MojangVersionFormat.cpp21
-rw-r--r--api/logic/minecraft/ProfilePatch.cpp175
-rw-r--r--api/logic/minecraft/ProfilePatch.h136
-rw-r--r--api/logic/minecraft/ProfileStrategy.h1
-rw-r--r--api/logic/minecraft/ProfileUtils.cpp6
-rw-r--r--api/logic/minecraft/VersionBuildError.h17
-rw-r--r--api/logic/minecraft/VersionFile.cpp42
-rw-r--r--api/logic/minecraft/VersionFile.h121
-rw-r--r--api/logic/minecraft/VersionFilterData.cpp11
-rw-r--r--api/logic/minecraft/VersionFilterData.h4
-rw-r--r--api/logic/minecraft/forge/ForgeInstaller.cpp458
-rw-r--r--api/logic/minecraft/forge/ForgeInstaller.h52
-rw-r--r--api/logic/minecraft/forge/ForgeVersion.cpp55
-rw-r--r--api/logic/minecraft/forge/ForgeVersion.h42
-rw-r--r--api/logic/minecraft/forge/ForgeVersionList.cpp333
-rw-r--r--api/logic/minecraft/forge/ForgeVersionList.h90
-rw-r--r--api/logic/minecraft/forge/LegacyForge.cpp56
-rw-r--r--api/logic/minecraft/forge/LegacyForge.h25
-rw-r--r--api/logic/minecraft/ftb/FTBInstanceProvider.cpp14
-rw-r--r--api/logic/minecraft/ftb/FTBPlugin.cpp2
-rw-r--r--api/logic/minecraft/ftb/FTBProfileStrategy.cpp13
-rw-r--r--api/logic/minecraft/ftb/FTBVersion.h32
-rw-r--r--api/logic/minecraft/legacy/LegacyUpdate.cpp1
-rw-r--r--api/logic/minecraft/legacy/LwjglVersionList.cpp5
-rw-r--r--api/logic/minecraft/legacy/LwjglVersionList.h4
-rw-r--r--api/logic/minecraft/liteloader/LiteLoaderInstaller.cpp106
-rw-r--r--api/logic/minecraft/liteloader/LiteLoaderInstaller.h39
-rw-r--r--api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp332
-rw-r--r--api/logic/minecraft/liteloader/LiteLoaderVersionList.h123
-rw-r--r--api/logic/minecraft/onesix/OneSixInstance.cpp66
-rw-r--r--api/logic/minecraft/onesix/OneSixInstance.h4
-rw-r--r--api/logic/minecraft/onesix/OneSixProfileStrategy.cpp226
-rw-r--r--api/logic/minecraft/onesix/OneSixUpdate.cpp49
-rw-r--r--api/logic/minecraft/onesix/OneSixVersionFormat.cpp32
-rw-r--r--api/logic/minecraft/onesix/update/LibrariesTask.cpp18
44 files changed, 575 insertions, 3331 deletions
diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp
index 5a75fe79..7521a049 100644
--- a/api/logic/minecraft/Library.cpp
+++ b/api/logic/minecraft/Library.cpp
@@ -30,14 +30,15 @@ void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& na
};
if(m_mojangDownloads)
{
- if(m_mojangDownloads->artifact)
+ if(!isNative())
{
- auto artifact = m_mojangDownloads->artifact;
- jar += actualPath(artifact->path);
+ if(m_mojangDownloads->artifact)
+ {
+ auto artifact = m_mojangDownloads->artifact;
+ jar += actualPath(artifact->path);
+ }
}
- if(!isNative())
- return;
- if(m_nativeClassifiers.contains(system))
+ else if(m_nativeClassifiers.contains(system))
{
auto nativeClassifier = m_nativeClassifiers[system];
if(nativeClassifier.contains("${arch}"))
@@ -55,7 +56,15 @@ void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& na
}
else
{
- native += actualPath(m_mojangDownloads->getDownloadInfo(nativeClassifier)->path);
+ auto dlinfo = m_mojangDownloads->getDownloadInfo(nativeClassifier);
+ if(!dlinfo)
+ {
+ qWarning() << "Cannot get native for" << nativeClassifier << "while processing" << m_name;
+ }
+ else
+ {
+ native += actualPath(dlinfo->path);
+ }
}
}
}
diff --git a/api/logic/minecraft/Library_test.cpp b/api/logic/minecraft/Library_test.cpp
index fe61d305..3f4828c9 100644
--- a/api/logic/minecraft/Library_test.cpp
+++ b/api/logic/minecraft/Library_test.cpp
@@ -234,7 +234,7 @@ slots:
auto test = readMojangJson("data/lib-native.json");
QStringList jar, native, native32, native64;
test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
- QCOMPARE(jar, getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"));
+ QCOMPARE(jar, QStringList());
QCOMPARE(native, getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"));
QCOMPARE(native32, {});
QCOMPARE(native64, {});
diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp
index 7b1aef1e..cb080bfe 100644
--- a/api/logic/minecraft/MinecraftInstance.cpp
+++ b/api/logic/minecraft/MinecraftInstance.cpp
@@ -5,7 +5,6 @@
#include <settings/Setting.h>
#include "settings/SettingsObject.h"
#include "Env.h"
-#include "minecraft/MinecraftVersionList.h"
#include <MMCStrings.h>
#include <pathmatcher/RegexpMatcher.h>
#include <pathmatcher/MultiMatcher.h>
@@ -21,9 +20,13 @@
#include "minecraft/launch/ModMinecraftJar.h"
#include "minecraft/launch/ClaimAccount.h"
#include "java/launch/CheckJava.h"
+#include <meta/Index.h>
+#include <meta/VersionList.h>
#include <icons/IIconList.h>
+#include <QCoreApplication>
+
#define IBUS "@im=ibus"
// all of this because keeping things compatible with deprecated old settings
@@ -104,7 +107,7 @@ QString MinecraftInstance::binRoot() const
std::shared_ptr< BaseVersionList > MinecraftInstance::versionList() const
{
- return ENV.getVersionList("net.minecraft");
+ return ENV.metadataIndex()->get("net.minecraft");
}
QStringList MinecraftInstance::javaArguments() const
diff --git a/api/logic/minecraft/MinecraftProfile.cpp b/api/logic/minecraft/MinecraftProfile.cpp
index 46235a18..c04669c1 100644
--- a/api/logic/minecraft/MinecraftProfile.cpp
+++ b/api/logic/minecraft/MinecraftProfile.cpp
@@ -80,7 +80,7 @@ void MinecraftProfile::clear()
m_traits.clear();
m_jarMods.clear();
mojangDownloads.clear();
- m_problemSeverity = ProblemSeverity::PROBLEM_NONE;
+ m_problemSeverity = ProblemSeverity::None;
}
void MinecraftProfile::clearPatches()
@@ -273,9 +273,9 @@ QVariant MinecraftProfile::data(const QModelIndex &index, int role) const
auto severity = patch->getProblemSeverity();
switch (severity)
{
- case PROBLEM_WARNING:
+ case ProblemSeverity::Warning:
return "warning";
- case PROBLEM_ERROR:
+ case ProblemSeverity::Error:
return "error";
default:
return QVariant();
@@ -491,20 +491,29 @@ void MinecraftProfile::applyLibrary(LibraryPtr library)
{
return;
}
+
+ QList<LibraryPtr> * list = &m_libraries;
+ if(library->isNative())
+ {
+ list = &m_nativeLibraries;
+ }
+
+ auto libraryCopy = Library::limitedCopy(library);
+
// find the library by name.
- const int index = findLibraryByName(m_libraries, library->rawName());
+ const int index = findLibraryByName(*list, library->rawName());
// library not found? just add it.
if (index < 0)
{
- m_libraries.append(Library::limitedCopy(library));
+ list->append(libraryCopy);
return;
}
- auto existingLibrary = m_libraries.at(index);
+
+ auto existingLibrary = list->at(index);
// if we are higher it means we should update
if (Version(library->version()) > Version(existingLibrary->version()))
{
- auto libraryCopy = Library::limitedCopy(library);
- m_libraries.replace(index, libraryCopy);
+ list->replace(index, libraryCopy);
}
}
@@ -581,6 +590,11 @@ const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
return m_libraries;
}
+const QList<LibraryPtr> & MinecraftProfile::getNativeLibraries() const
+{
+ return m_nativeLibraries;
+}
+
void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList& jars, QStringList& nativeJars, const QString& overridePath) const
{
QStringList native32, native64;
@@ -590,6 +604,10 @@ void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList&
{
lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
}
+ for (auto lib : getNativeLibraries())
+ {
+ lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
+ }
if(architecture == "32")
{
nativeJars.append(native32);
@@ -621,6 +639,11 @@ void MinecraftProfile::installJarMods(QStringList selectedFiles)
m_strategy->installJarMods(selectedFiles);
}
+void MinecraftProfile::installVersion(BaseVersionPtr version)
+{
+ // TODO: implement
+}
+
/*
* TODO: get rid of this. Get rid of all order numbers.
*/
diff --git a/api/logic/minecraft/MinecraftProfile.h b/api/logic/minecraft/MinecraftProfile.h
index 392c8f5f..5b1ea539 100644
--- a/api/logic/minecraft/MinecraftProfile.h
+++ b/api/logic/minecraft/MinecraftProfile.h
@@ -22,8 +22,9 @@
#include <memory>
#include "Library.h"
-#include "VersionFile.h"
+#include "ProfilePatch.h"
#include "JarMod.h"
+#include "BaseVersion.h"
#include "MojangDownloadInfo.h"
#include "multimc_logic_export.h"
@@ -58,6 +59,9 @@ public:
/// install more jar mods
void installJarMods(QStringList selectedFiles);
+ /// install more jar mods
+ void installVersion(BaseVersionPtr version);
+
/// DEPRECATED, remove ASAP
int getFreeOrderNumber();
@@ -111,6 +115,7 @@ public: /* getters for profile variables */
const QStringList & getTweakers() const;
const QList<JarmodPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const;
+ const QList<LibraryPtr> & getNativeLibraries() const;
void getLibraryFiles(const QString & architecture, QStringList & jars, QStringList & nativeJars, const QString & overridePath) const;
QString getMainJarUrl() const;
bool hasTrait(const QString & trait) const;
@@ -165,13 +170,16 @@ private: /* data */
/// the list of libraries
QList<LibraryPtr> m_libraries;
+ /// the list of libraries
+ QList<LibraryPtr> m_nativeLibraries;
+
/// traits, collected from all the version files (version files can only add)
QSet<QString> m_traits;
/// A list of jar mods. version files can add those.
QList<JarmodPtr> m_jarMods;
- ProblemSeverity m_problemSeverity = PROBLEM_NONE;
+ ProblemSeverity m_problemSeverity = ProblemSeverity::None;
/*
FIXME: add support for those rules here? Looks like a pile of quick hacks to me though.
diff --git a/api/logic/minecraft/MinecraftVersion.cpp b/api/logic/minecraft/MinecraftVersion.cpp
deleted file mode 100644
index 248c7eed..00000000
--- a/api/logic/minecraft/MinecraftVersion.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-#include "MinecraftVersion.h"
-#include "MinecraftProfile.h"
-#include "VersionBuildError.h"
-#include "ProfileUtils.h"
-#include "settings/SettingsObject.h"
-
-bool MinecraftVersion::usesLegacyLauncher()
-{
- return m_traits.contains("legacyLaunch") || m_traits.contains("aplhaLaunch");
-}
-
-QString MinecraftVersion::descriptor()
-{
- return m_descriptor;
-}
-
-QString MinecraftVersion::name()
-{
- return m_name;
-}
-
-QString MinecraftVersion::typeString() const
-{
- if(m_type == "snapshot")
- {
- return QObject::tr("Snapshot");
- }
- else if (m_type == "release")
- {
- return QObject::tr("Regular release");
- }
- else if (m_type == "old_alpha")
- {
- return QObject::tr("Alpha");
- }
- else if (m_type == "old_beta")
- {
- return QObject::tr("Beta");
- }
- else
- {
- return QString();
- }
-}
-
-VersionSource MinecraftVersion::getVersionSource()
-{
- return m_versionSource;
-}
-
-bool MinecraftVersion::hasJarMods()
-{
- return false;
-}
-
-bool MinecraftVersion::isMinecraftVersion()
-{
- return true;
-}
-
-void MinecraftVersion::applyFileTo(MinecraftProfile *profile)
-{
- if(m_versionSource == VersionSource::Local && getVersionFile())
- {
- getVersionFile()->applyTo(profile);
- }
- else
- {
- throw VersionIncomplete(QObject::tr("Can't apply incomplete/builtin Minecraft version %1").arg(m_name));
- }
-}
-
-QString MinecraftVersion::getUrl() const
-{
- // legacy fallback
- if(m_versionFileURL.isEmpty())
- {
- return QString("http://") + URLConstants::AWS_DOWNLOAD_VERSIONS + m_descriptor + "/" + m_descriptor + ".json";
- }
- // current
- return m_versionFileURL;
-}
-
-VersionFilePtr MinecraftVersion::getVersionFile()
-{
- QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_descriptor));
- m_problems.clear();
- m_problemSeverity = PROBLEM_NONE;
- if(!versionFile.exists())
- {
- if(m_loadedVersionFile)
- {
- m_loadedVersionFile.reset();
- }
- addProblem(PROBLEM_WARNING, QObject::tr("The patch file doesn't exist locally. It's possible it just needs to be downloaded."));
- }
- else
- {
- try
- {
- if(versionFile.lastModified() != m_loadedVersionFileTimestamp)
- {
- auto loadedVersionFile = ProfileUtils::parseBinaryJsonFile(versionFile);
- loadedVersionFile->name = "Minecraft";
- loadedVersionFile->setCustomizable(true);
- m_loadedVersionFileTimestamp = versionFile.lastModified();
- m_loadedVersionFile = loadedVersionFile;
- }
- }
- catch(Exception e)
- {
- m_loadedVersionFile.reset();
- addProblem(PROBLEM_ERROR, QObject::tr("The patch file couldn't be read:\n%1").arg(e.cause()));
- }
- }
- return m_loadedVersionFile;
-}
-
-bool MinecraftVersion::isCustomizable()
-{
- switch(m_versionSource)
- {
- case VersionSource::Local:
- case VersionSource::Remote:
- // locally cached file, or a remote file that we can acquire can be customized
- return true;
- case VersionSource::Builtin:
- // builtins do not follow the normal OneSix format. They are not customizable.
- default:
- // Everything else is undefined and therefore not customizable.
- return false;
- }
- return false;
-}
-
-const QList<PatchProblem> &MinecraftVersion::getProblems()
-{
- if(m_versionSource != VersionSource::Builtin && getVersionFile())
- {
- return getVersionFile()->getProblems();
- }
- return ProfilePatch::getProblems();
-}
-
-ProblemSeverity MinecraftVersion::getProblemSeverity()
-{
- if(m_versionSource != VersionSource::Builtin && getVersionFile())
- {
- return getVersionFile()->getProblemSeverity();
- }
- return ProfilePatch::getProblemSeverity();
-}
-
-void MinecraftVersion::applyTo(MinecraftProfile *profile)
-{
- // do we have this one cached?
- if (m_versionSource == VersionSource::Local)
- {
- applyFileTo(profile);
- return;
- }
- // if not builtin, do not proceed any further.
- if (m_versionSource != VersionSource::Builtin)
- {
- throw VersionIncomplete(QObject::tr(
- "Minecraft version %1 could not be applied: version files are missing.").arg(m_descriptor));
- }
- profile->applyMinecraftVersion(m_descriptor);
- profile->applyMainClass(m_mainClass);
- profile->applyAppletClass(m_appletClass);
- profile->applyMinecraftArguments(" ${auth_player_name} ${auth_session}"); // all builtin versions are legacy
- profile->applyMinecraftVersionType(m_type);
- profile->applyTraits(m_traits);
- profile->applyProblemSeverity(m_problemSeverity);
-}
-
-int MinecraftVersion::getOrder()
-{
- return order;
-}
-
-void MinecraftVersion::setOrder(int order)
-{
- this->order = order;
-}
-
-QList<JarmodPtr> MinecraftVersion::getJarMods()
-{
- return QList<JarmodPtr>();
-}
-
-QString MinecraftVersion::getName()
-{
- return "Minecraft";
-}
-QString MinecraftVersion::getVersion()
-{
- return m_descriptor;
-}
-QString MinecraftVersion::getID()
-{
- return "net.minecraft";
-}
-QString MinecraftVersion::getFilename()
-{
- return QString();
-}
-QDateTime MinecraftVersion::getReleaseDateTime()
-{
- return m_releaseTime;
-}
-
-
-bool MinecraftVersion::needsUpdate()
-{
- return m_versionSource == VersionSource::Remote || hasUpdate();
-}
-
-bool MinecraftVersion::hasUpdate()
-{
- return m_versionSource == VersionSource::Remote || (m_versionSource == VersionSource::Local && upstreamUpdate);
-}
-
-bool MinecraftVersion::isCustom()
-{
- // if we add any other source types, this will evaluate to false for them.
- return m_versionSource != VersionSource::Builtin
- && m_versionSource != VersionSource::Local
- && m_versionSource != VersionSource::Remote;
-}
diff --git a/api/logic/minecraft/MinecraftVersion.h b/api/logic/minecraft/MinecraftVersion.h
deleted file mode 100644
index 7ac9bcbb..00000000
--- a/api/logic/minecraft/MinecraftVersion.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright 2013-2017 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 <QStringList>
-#include <QSet>
-#include <QDateTime>
-
-#include "BaseVersion.h"
-#include "ProfilePatch.h"
-#include "VersionFile.h"
-
-#include "multimc_logic_export.h"
-
-class MinecraftProfile;
-class MinecraftVersion;
-typedef std::shared_ptr<MinecraftVersion> MinecraftVersionPtr;
-
-class MULTIMC_LOGIC_EXPORT MinecraftVersion : public BaseVersion, public ProfilePatch
-{
-friend class MinecraftVersionList;
-
-public: /* methods */
- bool usesLegacyLauncher();
- virtual QString descriptor() override;
- virtual QString name() override;
- virtual QString typeString() const override;
- virtual bool hasJarMods() override;
- virtual bool isMinecraftVersion() override;
- virtual void applyTo(MinecraftProfile *profile) override;
- virtual int getOrder() override;
- virtual void setOrder(int order) override;
- virtual QList<JarmodPtr> getJarMods() override;
- virtual QString getID() override;
- virtual QString getVersion() override;
- virtual QString getName() override;
- virtual QString getFilename() override;
- QDateTime getReleaseDateTime() override;
- VersionSource getVersionSource() override;
-
- bool needsUpdate();
- bool hasUpdate();
- virtual bool isCustom() override;
- virtual bool isMoveable() override
- {
- return false;
- }
- virtual bool isCustomizable() override;
- virtual bool isRemovable() override
- {
- return false;
- }
- virtual bool isRevertible() override
- {
- return false;
- }
- virtual bool isEditable() override
- {
- return false;
- }
- virtual bool isVersionChangeable() override
- {
- return true;
- }
-
- virtual VersionFilePtr getVersionFile() override;
-
- // virtual QJsonDocument toJson(bool saveOrder) override;
-
- QString getUrl() const;
-
- virtual const QList<PatchProblem> &getProblems() override;
- virtual ProblemSeverity getProblemSeverity() override;
-
-private: /* methods */
- void applyFileTo(MinecraftProfile *profile);
-
-protected: /* data */
- VersionSource m_versionSource = VersionSource::Builtin;
-
- /// The URL that this version will be downloaded from.
- QString m_versionFileURL;
-
- /// the human readable version name
- QString m_name;
-
- /// the version ID.
- QString m_descriptor;
-
- /// version traits. added by MultiMC
- QSet<QString> m_traits;
-
- /// The main class this version uses (if any, can be empty).
- QString m_mainClass;
-
- /// The applet class this version uses (if any, can be empty).
- QString m_appletClass;
-
- /// The type of this release
- QString m_type;
-
- /// the time this version was actually released by Mojang
- QDateTime m_releaseTime;
-
- /// the time this version was last updated by Mojang
- QDateTime m_updateTime;
-
- /// MD5 hash of the minecraft jar
- QString m_jarChecksum;
-
- /// order of this file... default = -2
- int order = -2;
-
- /// an update available from Mojang
- MinecraftVersionPtr upstreamUpdate;
-
- QDateTime m_loadedVersionFileTimestamp;
- mutable VersionFilePtr m_loadedVersionFile;
-};
diff --git a/api/logic/minecraft/MinecraftVersionList.cpp b/api/logic/minecraft/MinecraftVersionList.cpp
deleted file mode 100644
index 2c9a8035..00000000
--- a/api/logic/minecraft/MinecraftVersionList.cpp
+++ /dev/null
@@ -1,677 +0,0 @@
-/* Copyright 2013-2017 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 <QtXml>
-#include "Json.h"
-#include <QtAlgorithms>
-#include <QtNetwork>
-
-#include "Env.h"
-#include "Exception.h"
-
-#include "MinecraftVersionList.h"
-#include "net/URLConstants.h"
-
-#include "ParseUtils.h"
-#include "ProfileUtils.h"
-#include "VersionFilterData.h"
-#include "onesix/OneSixVersionFormat.h"
-#include "MojangVersionFormat.h"
-#include <FileSystem.h>
-
-static const char * localVersionCache = "versions/versions.dat";
-
-class MCVListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit MCVListLoadTask(MinecraftVersionList *vlist);
- virtual ~MCVListLoadTask() override{};
-
- virtual void executeTask() override;
-
-protected
-slots:
- void list_downloaded();
-
-protected:
- QNetworkReply *vlistReply;
- MinecraftVersionList *m_list;
- MinecraftVersion *m_currentStable;
-};
-
-class MCVListVersionUpdateTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr<MinecraftVersion> updatedVersion);
- virtual ~MCVListVersionUpdateTask() override{};
- virtual void executeTask() override;
- bool canAbort() const override;
-
-public slots:
- bool abort() override;
-
-protected
-slots:
- void json_downloaded();
-
-protected:
- NetJobPtr specificVersionDownloadJob;
- QByteArray versionIndexData;
- std::shared_ptr<MinecraftVersion> updatedVersion;
- MinecraftVersionList *m_list;
- bool m_aborted = false;
-};
-
-class ListLoadError : public Exception
-{
-public:
- ListLoadError(QString cause) : Exception(cause) {};
- virtual ~ListLoadError() noexcept
- {
- }
-};
-
-MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent)
-{
- loadBuiltinList();
- loadCachedList();
-}
-
-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->getReleaseDateTime() > right->getReleaseDateTime();
-}
-
-void MinecraftVersionList::sortInternal()
-{
- qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
-}
-
-void MinecraftVersionList::loadCachedList()
-{
- QFile localIndex(localVersionCache);
- if (!localIndex.exists())
- {
- return;
- }
- if (!localIndex.open(QIODevice::ReadOnly))
- {
- // FIXME: this is actually a very bad thing! How do we deal with this?
- qCritical() << "The minecraft version cache can't be read.";
- return;
- }
- auto data = localIndex.readAll();
- try
- {
- localIndex.close();
- QJsonDocument jsonDoc = QJsonDocument::fromBinaryData(data);
- if (jsonDoc.isNull())
- {
- throw ListLoadError(tr("Error reading the version list."));
- }
- loadMojangList(jsonDoc, VersionSource::Local);
- }
- catch (Exception &e)
- {
- // the cache has gone bad for some reason... flush it.
- qCritical() << "The minecraft version cache is corrupted. Flushing cache.";
- localIndex.remove();
- return;
- }
- m_hasLocalIndex = true;
-}
-
-void MinecraftVersionList::loadBuiltinList()
-{
- qDebug() << "Loading builtin version list.";
- // grab the version list data from internal resources.
- const QJsonDocument doc =
- Json::requireDocument(QString(":/versions/minecraft.json"), "builtin version list");
- const QJsonObject root = doc.object();
-
- // parse all the versions
- for (const auto version : Json::requireArray(root.value("versions")))
- {
- QJsonObject versionObj = version.toObject();
- QString versionID = versionObj.value("id").toString("");
- QString versionTypeStr = versionObj.value("type").toString("");
- if (versionID.isEmpty() || versionTypeStr.isEmpty())
- {
- qCritical() << "Parsed version is missing ID or type";
- continue;
- }
-
- if (g_VersionFilterData.legacyBlacklist.contains(versionID))
- {
- qWarning() << "Blacklisted legacy version ignored: " << versionID;
- continue;
- }
-
- // 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;
-
- // Parse the timestamp.
- mcVersion->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString(""));
- mcVersion->m_versionFileURL = QString();
- mcVersion->m_versionSource = VersionSource::Builtin;
- mcVersion->m_type = versionTypeStr;
- mcVersion->m_appletClass = versionObj.value("appletClass").toString("");
- mcVersion->m_mainClass = versionObj.value("mainClass").toString("");
- mcVersion->m_jarChecksum = versionObj.value("checksum").toString("");
- if (versionObj.contains("+traits"))
- {
- for (auto traitVal : Json::requireArray(versionObj.value("+traits")))
- {
- mcVersion->m_traits.insert(Json::requireString(traitVal));
- }
- }
- m_lookup[versionID] = mcVersion;
- m_vlist.append(mcVersion);
- }
-}
-
-void MinecraftVersionList::loadMojangList(QJsonDocument jsonDoc, VersionSource source)
-{
- qDebug() << "Loading" << ((source == VersionSource::Remote) ? "remote" : "local") << "version list.";
-
- if (!jsonDoc.isObject())
- {
- throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object"));
- }
-
- QJsonObject root = jsonDoc.object();
-
- try
- {
- QJsonObject latest = Json::requireObject(root.value("latest"));
- m_latestReleaseID = Json::requireString(latest.value("release"));
- m_latestSnapshotID = Json::requireString(latest.value("snapshot"));
- }
- catch (Exception &err)
- {
- qCritical()
- << tr("Error parsing version list JSON: couldn't determine latest versions");
- }
-
- // Now, get the array of versions.
- if (!root.value("versions").isArray())
- {
- throw ListLoadError(tr("Error parsing version list JSON: version list object is "
- "missing 'versions' array"));
- }
- QJsonArray versions = root.value("versions").toArray();
-
- QList<BaseVersionPtr> tempList;
- for (auto version : versions)
- {
- // Load the version info.
- if (!version.isObject())
- {
- qCritical() << "Error while parsing version list : invalid JSON structure";
- continue;
- }
-
- QJsonObject versionObj = version.toObject();
- QString versionID = versionObj.value("id").toString("");
- if (versionID.isEmpty())
- {
- qCritical() << "Error while parsing version : version ID is missing";
- continue;
- }
-
- if (g_VersionFilterData.legacyBlacklist.contains(versionID))
- {
- qWarning() << "Blacklisted legacy version ignored: " << versionID;
- continue;
- }
-
- // 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->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString(""));
- mcVersion->m_updateTime = timeFromS3Time(versionObj.value("time").toString(""));
-
- if (mcVersion->m_releaseTime < g_VersionFilterData.legacyCutoffDate)
- {
- continue;
- }
-
- // depends on where we load the version from -- network request or local file?
- mcVersion->m_versionSource = source;
- mcVersion->m_versionFileURL = versionObj.value("url").toString("");
- QString versionTypeStr = versionObj.value("type").toString("");
- if (versionTypeStr.isEmpty())
- {
- qCritical() << "Ignoring" << versionID
- << "because it doesn't have the version type set.";
- continue;
- }
- // OneSix or Legacy. use filter to determine type
- if (versionTypeStr == "release")
- {
- }
- else if (versionTypeStr == "snapshot") // It's a snapshot... yay
- {
- }
- else if (versionTypeStr == "old_alpha")
- {
- }
- else if (versionTypeStr == "old_beta")
- {
- }
- else
- {
- qCritical() << "Ignoring" << versionID
- << "because it has an invalid version type.";
- continue;
- }
- mcVersion->m_type = versionTypeStr;
- qDebug() << "Loaded version" << versionID << "from"
- << ((source == VersionSource::Remote) ? "remote" : "local") << "version list.";
- tempList.append(mcVersion);
- }
- updateListData(tempList);
- if(source == VersionSource::Remote)
- {
- m_loaded = true;
- }
-}
-
-void MinecraftVersionList::sortVersions()
-{
- beginResetModel();
- sortInternal();
- endResetModel();
-}
-
-QVariant MinecraftVersionList::data(const QModelIndex& index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<MinecraftVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case RecommendedRole:
- return version->descriptor() == m_latestReleaseID;
-
- case LatestRole:
- {
- if(version->descriptor() != m_latestSnapshotID)
- return false;
- MinecraftVersionPtr latestRelease = std::dynamic_pointer_cast<MinecraftVersion>(getLatestStable());
- /*
- if(latestRelease && latestRelease->m_releaseTime > version->m_releaseTime)
- {
- return false;
- }
- */
- return true;
- }
-
- case TypeRole:
- return version->typeString();
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList MinecraftVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, RecommendedRole, LatestRole, TypeRole};
-}
-
-BaseVersionPtr MinecraftVersionList::getLatestStable() const
-{
- if(m_lookup.contains(m_latestReleaseID))
- return m_lookup[m_latestReleaseID];
- return BaseVersionPtr();
-}
-
-BaseVersionPtr MinecraftVersionList::getRecommended() const
-{
- return getLatestStable();
-}
-
-void MinecraftVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- for (auto version : versions)
- {
- auto descr = version->descriptor();
-
- if (!m_lookup.contains(descr))
- {
- m_lookup[version->descriptor()] = version;
- m_vlist.append(version);
- continue;
- }
- auto orig = std::dynamic_pointer_cast<MinecraftVersion>(m_lookup[descr]);
- auto added = std::dynamic_pointer_cast<MinecraftVersion>(version);
- // updateListData is called after Mojang list loads. those can be local or remote
- // remote comes always after local
- // any other options are ignored
- if (orig->m_versionSource != VersionSource::Local || added->m_versionSource != VersionSource::Remote)
- {
- continue;
- }
- // alright, it's an update. put it inside the original, for further processing.
- orig->upstreamUpdate = added;
- }
- sortInternal();
- endResetModel();
-}
-
-MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist)
-{
- m_list = vlist;
- m_currentStable = NULL;
- vlistReply = nullptr;
-}
-
-void MCVListLoadTask::executeTask()
-{
- setStatus(tr("Loading instance version list..."));
- vlistReply = ENV.qnam().get(QNetworkRequest(QUrl("https://launchermeta.mojang.com/mc/game/version_manifest.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 data = vlistReply->readAll();
- vlistReply->deleteLater();
- try
- {
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- throw ListLoadError(
- tr("Error parsing version list JSON: %1").arg(jsonError.errorString()));
- }
- m_list->loadMojangList(jsonDoc, VersionSource::Remote);
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- return;
- }
-
- emitSucceeded();
- return;
-}
-
-MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr<MinecraftVersion> updatedVersion)
- : Task()
-{
- m_list = vlist;
- this->updatedVersion = updatedVersion;
-}
-
-void MCVListVersionUpdateTask::executeTask()
-{
- if(m_aborted)
- {
- emitFailed(tr("Task aborted."));
- return;
- }
- auto job = new NetJob("Version index");
- job->addNetAction(Net::Download::makeByteArray(QUrl(updatedVersion->getUrl()), &versionIndexData));
- specificVersionDownloadJob.reset(job);
- connect(specificVersionDownloadJob.get(), SIGNAL(succeeded()), SLOT(json_downloaded()));
- connect(specificVersionDownloadJob.get(), SIGNAL(failed(QString)), SIGNAL(failed(QString)));
- connect(specificVersionDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- specificVersionDownloadJob->start();
-}
-
-bool MCVListVersionUpdateTask::canAbort() const
-{
- return true;
-}
-
-bool MCVListVersionUpdateTask::abort()
-{
- m_aborted = true;
- if(specificVersionDownloadJob)
- {
- return specificVersionDownloadJob->abort();
- }
- return true;
-}
-
-void MCVListVersionUpdateTask::json_downloaded()
-{
- specificVersionDownloadJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(versionIndexData, &jsonError);
- versionIndexData.clear();
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed(tr("The download version file is not valid."));
- return;
- }
- VersionFilePtr file;
- try
- {
- file = MojangVersionFormat::versionFileFromJson(jsonDoc, "net.minecraft.json");
- }
- catch (Exception &e)
- {
- emitFailed(tr("Couldn't process version file: %1").arg(e.cause()));
- return;
- }
-
- // Strip LWJGL from the version file. We use our own.
- ProfileUtils::removeLwjglFromPatch(file);
-
- // TODO: recognize and add LWJGL versions here.
-
- file->fileId = "net.minecraft";
-
- // now dump the file to disk
- auto doc = OneSixVersionFormat::versionFileToJson(file, false);
- auto newdata = doc.toBinaryData();
- auto id = updatedVersion->descriptor();
- QString targetPath = "versions/" + id + "/" + id + ".dat";
- FS::ensureFilePathExists(targetPath);
- QSaveFile vfile1(targetPath);
- if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
- {
- emitFailed(tr("Can't open %1 for writing.").arg(targetPath));
- return;
- }
- qint64 actual = 0;
- if ((actual = vfile1.write(newdata)) != newdata.size())
- {
- emitFailed(tr("Failed to write into %1. Written %2 out of %3.")
- .arg(targetPath)
- .arg(actual)
- .arg(newdata.size()));
- return;
- }
- if (!vfile1.commit())
- {
- emitFailed(tr("Can't commit changes to %1").arg(targetPath));
- return;
- }
-
- m_list->finalizeUpdate(id);
- emitSucceeded();
-}
-
-std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version)
-{
- auto iter = m_lookup.find(version);
- if(iter == m_lookup.end())
- return nullptr;
-
- auto mcversion = std::dynamic_pointer_cast<MinecraftVersion>(*iter);
- if(!mcversion)
- {
- return nullptr;
- }
-
- return std::shared_ptr<Task>(new MCVListVersionUpdateTask(this, mcversion));
-}
-
-void MinecraftVersionList::saveCachedList()
-{
- // FIXME: throw.
- if (!FS::ensureFilePathExists(localVersionCache))
- return;
- QSaveFile tfile(localVersionCache);
- if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
- return;
- QJsonObject toplevel;
- QJsonArray entriesArr;
- for (auto version : m_vlist)
- {
- auto mcversion = std::dynamic_pointer_cast<MinecraftVersion>(version);
- // do not save the remote versions.
- if (mcversion->m_versionSource != VersionSource::Local)
- continue;
- QJsonObject entryObj;
-
- entryObj.insert("id", mcversion->descriptor());
- entryObj.insert("version", mcversion->descriptor());
- entryObj.insert("time", timeToS3Time(mcversion->m_updateTime));
- entryObj.insert("releaseTime", timeToS3Time(mcversion->m_releaseTime));
- entryObj.insert("url", mcversion->m_versionFileURL);
- entryObj.insert("type", mcversion->m_type);
- entriesArr.append(entryObj);
- }
- toplevel.insert("versions", entriesArr);
-
- {
- bool someLatest = false;
- QJsonObject latestObj;
- if(!m_latestReleaseID.isNull())
- {
- latestObj.insert("release", m_latestReleaseID);
- someLatest = true;
- }
- if(!m_latestSnapshotID.isNull())
- {
- latestObj.insert("snapshot", m_latestSnapshotID);
- someLatest = true;
- }
- if(someLatest)
- {
- toplevel.insert("latest", latestObj);
- }
- }
-
- QJsonDocument doc(toplevel);
- QByteArray jsonData = doc.toBinaryData();
- qint64 result = tfile.write(jsonData);
- if (result == -1)
- return;
- if (result != jsonData.size())
- return;
- tfile.commit();
-}
-
-void MinecraftVersionList::finalizeUpdate(QString version)
-{
- int idx = -1;
- for (int i = 0; i < m_vlist.size(); i++)
- {
- if (version == m_vlist[i]->descriptor())
- {
- idx = i;
- break;
- }
- }
- if (idx == -1)
- {
- return;
- }
-
- auto updatedVersion = std::dynamic_pointer_cast<MinecraftVersion>(m_vlist[idx]);
-
- // reject any updates to builtin versions.
- if (updatedVersion->m_versionSource == VersionSource::Builtin)
- return;
-
- // if we have an update for the version, replace it, make the update local
- if (updatedVersion->upstreamUpdate)
- {
- auto updatedWith = updatedVersion->upstreamUpdate;
- updatedWith->m_versionSource = VersionSource::Local;
- m_vlist[idx] = updatedWith;
- m_lookup[version] = updatedWith;
- }
- else
- {
- // otherwise, just set the version as local;
- updatedVersion->m_versionSource = VersionSource::Local;
- }
-
- dataChanged(index(idx), index(idx));
-
- saveCachedList();
-}
-
-#include "MinecraftVersionList.moc"
diff --git a/api/logic/minecraft/MinecraftVersionList.h b/api/logic/minecraft/MinecraftVersionList.h
deleted file mode 100644
index 42333678..00000000
--- a/api/logic/minecraft/MinecraftVersionList.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright 2013-2017 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 "tasks/Task.h"
-#include "minecraft/MinecraftVersion.h"
-#include <net/NetJob.h>
-
-#include "multimc_logic_export.h"
-
-class MCVListLoadTask;
-class MCVListVersionUpdateTask;
-
-class MULTIMC_LOGIC_EXPORT MinecraftVersionList : public BaseVersionList
-{
- Q_OBJECT
-private:
- void sortInternal();
- void loadBuiltinList();
- void loadMojangList(QJsonDocument jsonDoc, VersionSource source);
- void loadCachedList();
- void saveCachedList();
- void finalizeUpdate(QString version);
-public:
- friend class MCVListLoadTask;
- friend class MCVListVersionUpdateTask;
-
- explicit MinecraftVersionList(QObject *parent = 0);
-
- std::shared_ptr<Task> createUpdateTask(QString version);
-
- virtual Task *getLoadTask() override;
- virtual bool isLoaded() override;
- virtual const BaseVersionPtr at(int i) const override;
- virtual int count() const override;
- virtual void sortVersions() override;
- virtual QVariant data(const QModelIndex & index, int role) const override;
- virtual RoleList providesRoles() const override;
-
- virtual BaseVersionPtr getLatestStable() const override;
- virtual BaseVersionPtr getRecommended() const override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
- QMap<QString, BaseVersionPtr> m_lookup;
-
- bool m_loaded = false;
- bool m_hasLocalIndex = false;
- QString m_latestReleaseID = "INVALID";
- QString m_latestSnapshotID = "INVALID";
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions) override;
-};
diff --git a/api/logic/minecraft/MojangVersionFormat.cpp b/api/logic/minecraft/MojangVersionFormat.cpp
index 34129c9e..ea8dcd4d 100644
--- a/api/logic/minecraft/MojangVersionFormat.cpp
+++ b/api/logic/minecraft/MojangVersionFormat.cpp
@@ -1,6 +1,5 @@
#include "MojangVersionFormat.h"
#include "onesix/OneSixVersionFormat.h"
-#include "MinecraftVersion.h"
#include "VersionBuildError.h"
#include "MojangDownloadInfo.h"
@@ -152,7 +151,7 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
}
else if (!toCompare.isEmpty())
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
}
}
Bits::readString(in, "type", out->type);
@@ -167,8 +166,8 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
}
- out->m_releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
- out->m_updateTime = timeFromS3Time(in.value("time").toString(""));
+ out->releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
+ out->updateTime = timeFromS3Time(in.value("time").toString(""));
if (in.contains("minimumLauncherVersion"))
{
@@ -176,7 +175,7 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION)
{
out->addProblem(
- PROBLEM_WARNING,
+ ProblemSeverity::Warning,
QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!")
.arg(out->minimumLauncherVersion)
.arg(CURRENT_MINIMUM_LAUNCHER_VERSION));
@@ -211,9 +210,9 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc
readVersionProperties(root, out.get());
out->name = "Minecraft";
- out->fileId = "net.minecraft";
+ out->uid = "net.minecraft";
out->version = out->minecraftVersion;
- out->filename = filename;
+ // out->filename = filename;
if (root.contains("libraries"))
@@ -235,13 +234,13 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
writeString(out, "mainClass", in->mainClass);
writeString(out, "minecraftArguments", in->minecraftArguments);
writeString(out, "type", in->type);
- if(!in->m_releaseTime.isNull())
+ if(!in->releaseTime.isNull())
{
- writeString(out, "releaseTime", timeToS3Time(in->m_releaseTime));
+ writeString(out, "releaseTime", timeToS3Time(in->releaseTime));
}
- if(!in->m_updateTime.isNull())
+ if(!in->updateTime.isNull())
{
- writeString(out, "time", timeToS3Time(in->m_updateTime));
+ writeString(out, "time", timeToS3Time(in->updateTime));
}
if(in->minimumLauncherVersion != -1)
{
diff --git a/api/logic/minecraft/ProfilePatch.cpp b/api/logic/minecraft/ProfilePatch.cpp
new file mode 100644
index 00000000..6a90f64b
--- /dev/null
+++ b/api/logic/minecraft/ProfilePatch.cpp
@@ -0,0 +1,175 @@
+#include <meta/VersionList.h>
+#include <meta/Index.h>
+#include <Env.h>
+#include "ProfilePatch.h"
+
+#include "meta/Version.h"
+#include "VersionFile.h"
+
+ProfilePatch::ProfilePatch(std::shared_ptr<Meta::Version> version)
+ :m_metaVersion(version)
+{
+}
+
+ProfilePatch::ProfilePatch(std::shared_ptr<VersionFile> file, const QString& filename)
+ :m_file(file), m_filename(filename)
+{
+}
+
+void ProfilePatch::applyTo(MinecraftProfile* profile)
+{
+ auto vfile = getVersionFile();
+ if(vfile)
+ {
+ vfile->applyTo(profile);
+ }
+}
+
+std::shared_ptr<class VersionFile> ProfilePatch::getVersionFile()
+{
+ if(m_metaVersion)
+ {
+ if(!m_metaVersion->isLoaded())
+ {
+ m_metaVersion->load();
+ }
+ return m_metaVersion->data();
+ }
+ return m_file;
+}
+
+std::shared_ptr<class Meta::VersionList> ProfilePatch::getVersionList()
+{
+ if(m_metaVersion)
+ {
+ return ENV.metadataIndex()->get(m_metaVersion->uid());
+ }
+ return nullptr;
+}
+
+int ProfilePatch::getOrder()
+{
+ if(m_orderOverride)
+ return m_order;
+
+ auto vfile = getVersionFile();
+ if(vfile)
+ {
+ return vfile->order;
+ }
+ return 0;
+}
+void ProfilePatch::setOrder(int order)
+{
+ m_orderOverride = true;
+ m_order = order;
+}
+QString ProfilePatch::getID()
+{
+ if(m_metaVersion)
+ return m_metaVersion->uid();
+ return getVersionFile()->uid;
+}
+QString ProfilePatch::getName()
+{
+ if(m_metaVersion)
+ return m_metaVersion->name();
+ return getVersionFile()->name;
+}
+QString ProfilePatch::getVersion()
+{
+ if(m_metaVersion)
+ return m_metaVersion->version();
+ return getVersionFile()->version;
+}
+QString ProfilePatch::getFilename()
+{
+ return m_filename;
+}
+QDateTime ProfilePatch::getReleaseDateTime()
+{
+ if(m_metaVersion)
+ {
+ return m_metaVersion->time();
+ }
+ return getVersionFile()->releaseTime;
+}
+
+bool ProfilePatch::isCustom()
+{
+ return !m_isVanilla;
+};
+
+bool ProfilePatch::isCustomizable()
+{
+ if(m_metaVersion)
+ {
+ if(getVersionFile())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+bool ProfilePatch::isRemovable()
+{
+ return m_isRemovable;
+}
+bool ProfilePatch::isRevertible()
+{
+ return m_isRevertible;
+}
+bool ProfilePatch::isMoveable()
+{
+ return m_isMovable;
+}
+bool ProfilePatch::isVersionChangeable()
+{
+ auto list = getVersionList();
+ if(list)
+ {
+ if(!list->isLoaded())
+ {
+ list->load();
+ }
+ return list->count() != 0;
+ }
+ return false;
+}
+
+void ProfilePatch::setVanilla (bool state)
+{
+ m_isVanilla = state;
+}
+void ProfilePatch::setRemovable (bool state)
+{
+ m_isRemovable = state;
+}
+void ProfilePatch::setRevertible (bool state)
+{
+ m_isRevertible = state;
+}
+void ProfilePatch::setMovable (bool state)
+{
+ m_isMovable = state;
+}
+
+ProblemSeverity ProfilePatch::getProblemSeverity()
+{
+ auto file = getVersionFile();
+ if(file)
+ {
+ return file->getProblemSeverity();
+ }
+ return ProblemSeverity::Error;
+}
+
+const QList<PatchProblem> ProfilePatch::getProblems()
+{
+ auto file = getVersionFile();
+ if(file)
+ {
+ return file->getProblems();
+ }
+ return {PatchProblem(ProblemSeverity::Error, QObject::tr("Patch is not loaded yet."))};
+}
diff --git a/api/logic/minecraft/ProfilePatch.h b/api/logic/minecraft/ProfilePatch.h
index 26230092..fb6b2f05 100644
--- a/api/logic/minecraft/ProfilePatch.h
+++ b/api/logic/minecraft/ProfilePatch.h
@@ -5,101 +5,67 @@
#include <QJsonDocument>
#include <QDateTime>
#include "JarMod.h"
+#include "ProblemProvider.h"
class MinecraftProfile;
-
-enum ProblemSeverity
-{
- PROBLEM_NONE,
- PROBLEM_WARNING,
- PROBLEM_ERROR
-};
-
-/// where is a version from?
-enum class VersionSource
+namespace Meta
{
- Builtin, //!< version loaded from the internal resources.
- Local, //!< version loaded from a file in the cache.
- Remote, //!< incomplete version on a remote server.
-};
+ class Version;
+ class VersionList;
+}
+class VersionFile;
-class PatchProblem
+class ProfilePatch : public ProblemProvider
{
public:
- PatchProblem(ProblemSeverity severity, const QString & description)
- {
- m_severity = severity;
- m_description = description;
- }
- const QString & getDescription() const
- {
- return m_description;
- }
- const ProblemSeverity getSeverity() const
- {
- return m_severity;
- }
-private:
- ProblemSeverity m_severity;
- QString m_description;
-};
+ ProfilePatch(std::shared_ptr<Meta::Version> version);
+ ProfilePatch(std::shared_ptr<VersionFile> file, const QString &filename = QString());
-class ProfilePatch : public std::enable_shared_from_this<ProfilePatch>
-{
-public:
virtual ~ProfilePatch(){};
- virtual void applyTo(MinecraftProfile *profile) = 0;
-
- virtual bool isMinecraftVersion() = 0;
- virtual bool hasJarMods() = 0;
- virtual QList<JarmodPtr> getJarMods() = 0;
-
- virtual bool isMoveable() = 0;
- virtual bool isCustomizable() = 0;
- virtual bool isRevertible() = 0;
- virtual bool isRemovable() = 0;
- virtual bool isCustom() = 0;
- virtual bool isEditable() = 0;
- virtual bool isVersionChangeable() = 0;
-
- virtual void setOrder(int order) = 0;
- virtual int getOrder() = 0;
-
- virtual QString getID() = 0;
- virtual QString getName() = 0;
- virtual QString getVersion() = 0;
- virtual QDateTime getReleaseDateTime() = 0;
-
- virtual QString getFilename() = 0;
-
- virtual VersionSource getVersionSource() = 0;
-
- virtual std::shared_ptr<class VersionFile> getVersionFile() = 0;
-
- virtual const QList<PatchProblem>& getProblems()
- {
- return m_problems;
- }
- virtual void addProblem(ProblemSeverity severity, const QString &description)
- {
- if(severity > m_problemSeverity)
- {
- m_problemSeverity = severity;
- }
- m_problems.append(PatchProblem(severity, description));
- }
- virtual ProblemSeverity getProblemSeverity()
- {
- return m_problemSeverity;
- }
- virtual bool hasFailed()
- {
- return getProblemSeverity() == PROBLEM_ERROR;
- }
+ virtual void applyTo(MinecraftProfile *profile);
+
+ virtual bool isMoveable();
+ virtual bool isCustomizable();
+ virtual bool isRevertible();
+ virtual bool isRemovable();
+ virtual bool isCustom();
+ virtual bool isVersionChangeable();
+
+ virtual void setOrder(int order);
+ virtual int getOrder();
+
+ virtual QString getID();
+ virtual QString getName();
+ virtual QString getVersion();
+ virtual QDateTime getReleaseDateTime();
+
+ virtual QString getFilename();
+
+ virtual std::shared_ptr<class VersionFile> getVersionFile();
+ virtual std::shared_ptr<class Meta::VersionList> getVersionList();
+
+ void setVanilla (bool state);
+ void setRemovable (bool state);
+ void setRevertible (bool state);
+ void setMovable (bool state);
+
+
+ const QList<PatchProblem> getProblems() override;
+ ProblemSeverity getProblemSeverity() override;
protected:
- QList<PatchProblem> m_problems;
- ProblemSeverity m_problemSeverity = PROBLEM_NONE;
+ // Properties for UI and version manipulation from UI in general
+ bool m_isMovable = false;
+ bool m_isRevertible = false;
+ bool m_isRemovable = false;
+ bool m_isVanilla = false;
+
+ bool m_orderOverride = false;
+ int m_order = 0;
+
+ std::shared_ptr<Meta::Version> m_metaVersion;
+ std::shared_ptr<VersionFile> m_file;
+ QString m_filename;
};
typedef std::shared_ptr<ProfilePatch> ProfilePatchPtr;
diff --git a/api/logic/minecraft/ProfileStrategy.h b/api/logic/minecraft/ProfileStrategy.h
index b4dfc4b3..26bdf661 100644
--- a/api/logic/minecraft/ProfileStrategy.h
+++ b/api/logic/minecraft/ProfileStrategy.h
@@ -1,6 +1,7 @@
#pragma once
#include "ProfileUtils.h"
+#include "ProfilePatch.h"
class MinecraftProfile;
diff --git a/api/logic/minecraft/ProfileUtils.cpp b/api/logic/minecraft/ProfileUtils.cpp
index ef9b3b28..8c5bc052 100644
--- a/api/logic/minecraft/ProfileUtils.cpp
+++ b/api/logic/minecraft/ProfileUtils.cpp
@@ -102,9 +102,9 @@ bool readOverrideOrders(QString path, PatchOrder &order)
static VersionFilePtr createErrorVersionFile(QString fileId, QString filepath, QString error)
{
auto outError = std::make_shared<VersionFile>();
- outError->fileId = outError->name = fileId;
- outError->filename = filepath;
- outError->addProblem(PROBLEM_ERROR, error);
+ outError->uid = outError->name = fileId;
+ // outError->filename = filepath;
+ outError->addProblem(ProblemSeverity::Error, error);
return outError;
}
diff --git a/api/logic/minecraft/VersionBuildError.h b/api/logic/minecraft/VersionBuildError.h
index fda453e5..f362c405 100644
--- a/api/logic/minecraft/VersionBuildError.h
+++ b/api/logic/minecraft/VersionBuildError.h
@@ -27,23 +27,6 @@ public:
};
/**
- * some patch was intended for a different version of minecraft
- */
-class MinecraftVersionMismatch : public VersionBuildError
-{
-public:
- MinecraftVersionMismatch(QString fileId, QString mcVersion, QString parentMcVersion)
- : VersionBuildError(QObject::tr("The patch %1 is for a different version of Minecraft "
- "(%2) than that of the instance (%3).")
- .arg(fileId)
- .arg(mcVersion)
- .arg(parentMcVersion)) {};
- virtual ~MinecraftVersionMismatch() noexcept
- {
- }
-};
-
-/**
* files required for the version are not (yet?) present
*/
class VersionIncomplete : public VersionBuildError
diff --git a/api/logic/minecraft/VersionFile.cpp b/api/logic/minecraft/VersionFile.cpp
index 573c4cb4..b261ff2a 100644
--- a/api/logic/minecraft/VersionFile.cpp
+++ b/api/logic/minecraft/VersionFile.cpp
@@ -12,37 +12,28 @@
#include "VersionBuildError.h"
#include <Version.h>
-bool VersionFile::isMinecraftVersion()
+static bool isMinecraftVersion(const QString &uid)
{
- return fileId == "net.minecraft";
-}
-
-bool VersionFile::hasJarMods()
-{
- return !jarMods.isEmpty();
+ return uid == "net.minecraft";
}
void VersionFile::applyTo(MinecraftProfile *profile)
{
- auto theirVersion = profile->getMinecraftVersion();
- if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
+ // Only real Minecraft can set those. Don't let anything override them.
+ if (isMinecraftVersion(uid))
{
- if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
- {
- throw MinecraftVersionMismatch(fileId, dependsOnMinecraftVersion, theirVersion);
- }
+ profile->applyMinecraftVersion(minecraftVersion);
+ profile->applyMinecraftVersionType(type);
+ // HACK: ignore assets from other version files than Minecraft
+ // workaround for stupid assets issue caused by amazon:
+ // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
+ profile->applyMinecraftAssets(mojangAssetIndex);
}
- profile->applyMinecraftVersion(minecraftVersion);
+
profile->applyMainClass(mainClass);
profile->applyAppletClass(appletClass);
profile->applyMinecraftArguments(minecraftArguments);
- if (isMinecraftVersion())
- {
- profile->applyMinecraftVersionType(type);
- }
- profile->applyMinecraftAssets(mojangAssetIndex);
profile->applyTweakers(addTweakers);
-
profile->applyJarMods(jarMods);
profile->applyTraits(traits);
@@ -58,3 +49,14 @@ void VersionFile::applyTo(MinecraftProfile *profile)
iter++;
}
}
+
+/*
+ auto theirVersion = profile->getMinecraftVersion();
+ if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
+ {
+ if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
+ {
+ throw MinecraftVersionMismatch(uid, dependsOnMinecraftVersion, theirVersion);
+ }
+ }
+*/ \ No newline at end of file
diff --git a/api/logic/minecraft/VersionFile.h b/api/logic/minecraft/VersionFile.h
index 249d0965..312d0a3b 100644
--- a/api/logic/minecraft/VersionFile.h
+++ b/api/logic/minecraft/VersionFile.h
@@ -8,7 +8,7 @@
#include <memory>
#include "minecraft/OpSys.h"
#include "minecraft/Rule.h"
-#include "ProfilePatch.h"
+#include "ProblemProvider.h"
#include "Library.h"
#include "JarMod.h"
@@ -18,126 +18,25 @@ struct MojangDownloadInfo;
struct MojangAssetIndexInfo;
typedef std::shared_ptr<VersionFile> VersionFilePtr;
-class VersionFile : public ProfilePatch
+class VersionFile : public ProblemContainer
{
friend class MojangVersionFormat;
friend class OneSixVersionFormat;
public: /* methods */
- virtual void applyTo(MinecraftProfile *profile) override;
- virtual bool isMinecraftVersion() override;
- virtual bool hasJarMods() override;
- virtual int getOrder() override
- {
- return order;
- }
- virtual void setOrder(int order) override
- {
- this->order = order;
- }
- virtual QList<JarmodPtr> getJarMods() override
- {
- return jarMods;
- }
- virtual QString getID() override
- {
- return fileId;
- }
- virtual QString getName() override
- {
- return name;
- }
- virtual QString getVersion() override
- {
- return version;
- }
- virtual QString getFilename() override
- {
- return filename;
- }
- virtual QDateTime getReleaseDateTime() override
- {
- return m_releaseTime;
- }
- VersionSource getVersionSource() override
- {
- return VersionSource::Local;
- }
-
- std::shared_ptr<class VersionFile> getVersionFile() override
- {
- return std::dynamic_pointer_cast<VersionFile>(shared_from_this());
- }
-
- virtual bool isCustom() override
- {
- return !m_isVanilla;
- };
- virtual bool isCustomizable() override
- {
- return m_isCustomizable;
- }
- virtual bool isRemovable() override
- {
- return m_isRemovable;
- }
- virtual bool isRevertible() override
- {
- return m_isRevertible;
- }
- virtual bool isMoveable() override
- {
- return m_isMovable;
- }
- virtual bool isEditable() override
- {
- return isCustom();
- }
- virtual bool isVersionChangeable() override
- {
- return false;
- }
-
- void setVanilla (bool state)
- {
- m_isVanilla = state;
- }
- void setRemovable (bool state)
- {
- m_isRemovable = state;
- }
- void setRevertible (bool state)
- {
- m_isRevertible = state;
- }
- void setCustomizable (bool state)
- {
- m_isCustomizable = state;
- }
- void setMovable (bool state)
- {
- m_isMovable = state;
- }
-
+ void applyTo(MinecraftProfile *profile);
public: /* data */
/// MultiMC: order hint for this version file if no explicit order is set
int order = 0;
- // Flags for UI and version file manipulation in general
- bool m_isVanilla = false;
- bool m_isRemovable = false;
- bool m_isRevertible = false;
- bool m_isCustomizable = false;
- bool m_isMovable = false;
-
/// MultiMC: filename of the file this was loaded from
- QString filename;
+ // QString filename;
/// MultiMC: human readable name of this package
QString name;
/// MultiMC: package ID of this package
- QString fileId;
+ QString uid;
/// MultiMC: version of this package
QString version;
@@ -148,13 +47,13 @@ public: /* data */
/// Mojang: used to version the Mojang version format
int minimumLauncherVersion = -1;
- /// Mojang: version of Minecraft this is
+ /// Mojang: DEPRECATED version of Minecraft this is
QString minecraftVersion;
/// Mojang: class to launch Minecraft with
QString mainClass;
- /// MultiMC: DEPRECATED class to launch legacy Minecraft with (ambed in a custom window)
+ /// MultiMC: class to launch legacy Minecraft with (embed in a custom window)
QString appletClass;
/// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
@@ -164,10 +63,10 @@ public: /* data */
QString type;
/// Mojang: the time this version was actually released by Mojang
- QDateTime m_releaseTime;
+ QDateTime releaseTime;
/// Mojang: the time this version was last updated by Mojang
- QDateTime m_updateTime;
+ QDateTime updateTime;
/// Mojang: DEPRECATED asset group to be used with Minecraft
QString assets;
@@ -191,5 +90,3 @@ public:
// Mojang: extended asset index download information
std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
};
-
-
diff --git a/api/logic/minecraft/VersionFilterData.cpp b/api/logic/minecraft/VersionFilterData.cpp
index 0c4a6e3d..5f4ceee6 100644
--- a/api/logic/minecraft/VersionFilterData.cpp
+++ b/api/logic/minecraft/VersionFilterData.cpp
@@ -58,18 +58,11 @@ VersionFilterData::VersionFilterData()
// don't use installers for those.
forgeInstallerBlacklist = QSet<QString>({"1.5.2"});
- // these won't show up in version lists because they are extremely bad and dangerous
- legacyBlacklist = QSet<QString>({"rd-160052"});
- /*
- * nothing older than this will be accepted from Mojang servers
- * (these versions need to be tested by us first)
- */
+
+ // FIXME: remove, used for deciding when core mods should display
legacyCutoffDate = timeFromS3Time("2013-06-25T15:08:56+02:00");
lwjglWhitelist =
QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform",
"net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl",
"org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"};
-
- // Version list magic
- recommendedMinecraftVersion = "1.7.10";
}
diff --git a/api/logic/minecraft/VersionFilterData.h b/api/logic/minecraft/VersionFilterData.h
index f7d4ebe7..2408e704 100644
--- a/api/logic/minecraft/VersionFilterData.h
+++ b/api/logic/minecraft/VersionFilterData.h
@@ -20,13 +20,9 @@ struct VersionFilterData
QMap<QString, QList<FMLlib>> fmlLibsMapping;
// set of minecraft versions for which using forge installers is blacklisted
QSet<QString> forgeInstallerBlacklist;
- // set of 'legacy' versions that will not show up in the version lists.
- QSet<QString> legacyBlacklist;
// no new versions below this date will be accepted from Mojang servers
QDateTime legacyCutoffDate;
// Libraries that belong to LWJGL
QSet<QString> lwjglWhitelist;
- // Currently recommended minecraft version
- QString recommendedMinecraftVersion;
};
extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData;
diff --git a/api/logic/minecraft/forge/ForgeInstaller.cpp b/api/logic/minecraft/forge/ForgeInstaller.cpp
deleted file mode 100644
index a9c12fcd..00000000
--- a/api/logic/minecraft/forge/ForgeInstaller.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright 2013-2017 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 "ForgeInstaller.h"
-#include "ForgeVersionList.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/GradleSpecifier.h"
-#include "net/HttpMetaCache.h"
-#include "tasks/Task.h"
-#include "minecraft/onesix/OneSixInstance.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-#include "minecraft/VersionFilterData.h"
-#include "minecraft/MinecraftVersion.h"
-#include "Env.h"
-#include "Exception.h"
-#include <FileSystem.h>
-
-#include <quazip.h>
-#include <quazipfile.h>
-#include <QStringList>
-#include <QRegularExpression>
-#include <QRegularExpressionMatch>
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QSaveFile>
-#include <QCryptographicHash>
-
-ForgeInstaller::ForgeInstaller() : BaseInstaller()
-{
-}
-
-void ForgeInstaller::prepare(const QString &filename, const QString &universalUrl)
-{
- VersionFilePtr newVersion;
- m_universal_url = universalUrl;
-
- QuaZip zip(filename);
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- // read the install profile
- if (!zip.setCurrentFile("install_profile.json"))
- return;
-
- QJsonParseError jsonError;
- if (!file.open(QIODevice::ReadOnly))
- return;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError);
- file.close();
- if (jsonError.error != QJsonParseError::NoError)
- return;
-
- if (!jsonDoc.isObject())
- return;
-
- QJsonObject root = jsonDoc.object();
-
- auto installVal = root.value("install");
- auto versionInfoVal = root.value("versionInfo");
- if (!installVal.isObject() || !versionInfoVal.isObject())
- return;
-
- try
- {
- newVersion = OneSixVersionFormat::versionFileFromJson(QJsonDocument(versionInfoVal.toObject()), QString(), false);
- }
- catch(Exception &err)
- {
- qWarning() << "Forge: Fatal error while parsing version file:" << err.what();
- return;
- }
-
- for(auto problem: newVersion->getProblems())
- {
- qWarning() << "Forge: Problem found: " << problem.getDescription();
- }
- if(newVersion->getProblemSeverity() == ProblemSeverity::PROBLEM_ERROR)
- {
- qWarning() << "Forge: Errors found while parsing version file";
- return;
- }
-
- QJsonObject installObj = installVal.toObject();
- QString libraryName = installObj.value("path").toString();
- internalPath = installObj.value("filePath").toString();
- m_forgeVersionString = installObj.value("version").toString().remove("Forge", Qt::CaseInsensitive).trimmed();
-
- // where do we put the library? decode the mojang path
- GradleSpecifier lib(libraryName);
-
- auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.toPath());
- finalPath = "libraries/" + lib.toPath();
- if (!FS::ensureFilePathExists(finalPath))
- return;
-
- if (!zip.setCurrentFile(internalPath))
- return;
- if (!file.open(QIODevice::ReadOnly))
- return;
- {
- QByteArray data = file.readAll();
- // extract file
- QSaveFile extraction(finalPath);
- if (!extraction.open(QIODevice::WriteOnly))
- return;
- if (extraction.write(data) != data.size())
- return;
- if (!extraction.commit())
- return;
- QCryptographicHash md5sum(QCryptographicHash::Md5);
- md5sum.addData(data);
-
- cacheentry->setStale(false);
- cacheentry->setMD5Sum(md5sum.result().toHex().constData());
- ENV.metacache()->updateEntry(cacheentry);
- }
- file.close();
-
- m_forge_json = newVersion;
-}
-
-bool ForgeInstaller::add(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
-
- if (!m_forge_json)
- {
- return false;
- }
-
- // A blacklist
- QSet<QString> blacklist{"authlib", "realms"};
- QList<QString> xzlist{"org.scala-lang", "com.typesafe"};
-
- // get the minecraft version from the instance
- VersionFilePtr minecraft;
- auto minecraftPatch = to->getMinecraftProfile()->versionPatch("net.minecraft");
- if(minecraftPatch)
- {
- minecraft = std::dynamic_pointer_cast<VersionFile>(minecraftPatch);
- if(!minecraft)
- {
- auto mcWrap = std::dynamic_pointer_cast<MinecraftVersion>(minecraftPatch);
- if(mcWrap)
- {
- minecraft = mcWrap->getVersionFile();
- }
- }
- }
-
- // for each library in the version we are adding (except for the blacklisted)
- QMutableListIterator<LibraryPtr> iter(m_forge_json->libraries);
- while (iter.hasNext())
- {
- auto library = iter.next();
- QString libName = library->artifactId();
- QString libVersion = library->version();
- QString rawName = library->rawName();
-
- // ignore lwjgl libraries.
- if (g_VersionFilterData.lwjglWhitelist.contains(library->artifactPrefix()))
- {
- iter.remove();
- continue;
- }
- // ignore other blacklisted (realms, authlib)
- if (blacklist.contains(libName))
- {
- iter.remove();
- continue;
- }
- // if minecraft version was found, ignore everything that is already in the minecraft version
- if(minecraft)
- {
- bool found = false;
- for (auto & lib: minecraft->libraries)
- {
- if(library->artifactPrefix() == lib->artifactPrefix() && library->version() == lib->version())
- {
- found = true;
- break;
- }
- }
- if (found)
- continue;
- }
-
- // if this is the actual forge lib, set an absolute url for the download
- if (m_forge_version->type == ForgeVersion::Gradle)
- {
- if (libName == "forge")
- {
- library->setClassifier("universal");
- }
- else if (libName == "minecraftforge")
- {
- QString forgeCoord("net.minecraftforge:forge:%1:universal");
- // using insane form of the MC version...
- QString longVersion = m_forge_version->mcver + "-" + m_forge_version->jobbuildver;
- GradleSpecifier spec(forgeCoord.arg(longVersion));
- library->setRawName(spec);
- }
- }
- else
- {
- if (libName.contains("minecraftforge"))
- {
- library->setAbsoluteUrl(m_universal_url);
- }
- }
-
- // mark bad libraries based on the xzlist above
- for (auto entry : xzlist)
- {
- qDebug() << "Testing " << rawName << " : " << entry;
- if (rawName.startsWith(entry))
- {
- library->setHint("forge-pack-xz");
- break;
- }
- }
- }
- QString &args = m_forge_json->minecraftArguments;
- QStringList tweakers;
- {
- QRegularExpression expression("--tweakClass ([a-zA-Z0-9\\.]*)");
- QRegularExpressionMatch match = expression.match(args);
- while (match.hasMatch())
- {
- tweakers.append(match.captured(1));
- args.remove(match.capturedStart(), match.capturedLength());
- match = expression.match(args);
- }
- if(tweakers.size())
- {
- args.operator=(args.trimmed());
- m_forge_json->addTweakers = tweakers;
- }
- }
- if(minecraft && args == minecraft->minecraftArguments)
- {
- args.clear();
- }
-
- m_forge_json->name = "Forge";
- m_forge_json->fileId = id();
- m_forge_json->version = m_forgeVersionString;
- m_forge_json->dependsOnMinecraftVersion = to->intendedVersionId();
- m_forge_json->order = 5;
-
- // reset some things we do not want to be passed along.
- m_forge_json->m_releaseTime = QDateTime();
- m_forge_json->m_updateTime = QDateTime();
- m_forge_json->minimumLauncherVersion = -1;
- m_forge_json->type.clear();
- m_forge_json->minecraftArguments.clear();
- m_forge_json->minecraftVersion.clear();
-
- QSaveFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(m_forge_json, true).toJson());
- file.commit();
-
- return true;
-}
-
-bool ForgeInstaller::addLegacy(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
- auto entry = ENV.metacache()->resolveEntry("minecraftforge", m_forge_version->filename());
- finalPath = FS::PathCombine(to->jarModsDir(), m_forge_version->filename());
- if (!FS::ensureFilePathExists(finalPath))
- {
- return false;
- }
- if (!QFile::copy(entry->getFullPath(), finalPath))
- {
- return false;
- }
- QJsonObject obj;
- obj.insert("order", 5);
- {
- QJsonArray jarmodsPlus;
- {
- QJsonObject libObj;
- libObj.insert("name", m_forge_version->universal_filename);
- jarmodsPlus.append(libObj);
- }
- obj.insert("+jarMods", jarmodsPlus);
- }
-
- obj.insert("name", QString("Forge"));
- obj.insert("fileId", id());
- obj.insert("version", m_forge_version->jobbuildver);
- obj.insert("mcVersion", to->intendedVersionId());
- if (g_VersionFilterData.fmlLibsMapping.contains(m_forge_version->mcver))
- {
- QJsonArray traitsPlus;
- traitsPlus.append(QString("legacyFML"));
- obj.insert("+traits", traitsPlus);
- }
- auto fullversion = to->getMinecraftProfile();
- fullversion->remove("net.minecraftforge");
-
- QFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(QJsonDocument(obj).toJson());
- file.close();
- return true;
-}
-
-class ForgeInstallTask : public Task
-{
- Q_OBJECT
-public:
- ForgeInstallTask(ForgeInstaller *installer, OneSixInstance *instance,
- BaseVersionPtr version, QObject *parent = 0)
- : Task(parent), m_installer(installer), m_instance(instance), m_version(version)
- {
- }
-
-protected:
- void executeTask() override
- {
- setStatus(tr("Installing Forge..."));
- ForgeVersionPtr forgeVersion = std::dynamic_pointer_cast<ForgeVersion>(m_version);
- if (!forgeVersion)
- {
- emitFailed(tr("Unknown error occured"));
- return;
- }
- prepare(forgeVersion);
- }
- void prepare(ForgeVersionPtr forgeVersion)
- {
- auto entry = ENV.metacache()->resolveEntry("minecraftforge", forgeVersion->filename());
- auto installFunction = [this, entry, forgeVersion]()
- {
- if (!install(entry, forgeVersion))
- {
- qCritical() << "Failure installing Forge";
- emitFailed(tr("Failure to install Forge"));
- }
- else
- {
- reload();
- }
- };
-
- /*
- * HACK IF the local non-stale file is too small, mark is as stale
- *
- * This fixes some problems with bad files acquired because of unhandled HTTP redirects
- * in old versions of MultiMC.
- */
- if (!entry->isStale())
- {
- QFileInfo localFile(entry->getFullPath());
- if (localFile.size() <= 0x4000)
- {
- entry->setStale(true);
- }
- }
-
- if (entry->isStale())
- {
- NetJob *fjob = new NetJob("Forge download");
- fjob->addNetAction(Net::Download::makeCached(forgeVersion->url(), entry));
- connect(fjob, &NetJob::progress, this, &Task::setProgress);
- connect(fjob, &NetJob::status, this, &Task::setStatus);
- connect(fjob, &NetJob::failed, [this](QString reason)
- { emitFailed(tr("Failure to download Forge:\n%1").arg(reason)); });
- connect(fjob, &NetJob::succeeded, installFunction);
- fjob->start();
- }
- else
- {
- installFunction();
- }
- }
- bool install(const std::shared_ptr<MetaEntry> &entry, const ForgeVersionPtr &forgeVersion)
- {
- if (forgeVersion->usesInstaller())
- {
- QString forgePath = entry->getFullPath();
- m_installer->prepare(forgePath, forgeVersion->universal_url);
- return m_installer->add(m_instance);
- }
- else
- return m_installer->addLegacy(m_instance);
- }
- void reload()
- {
- try
- {
- m_instance->reloadProfile();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- }
- catch (...)
- {
- emitFailed(tr("Failed to load the version description file for reasons unknown."));
- }
- }
-
-private:
- ForgeInstaller *m_installer;
- OneSixInstance *m_instance;
- BaseVersionPtr m_version;
-};
-
-Task *ForgeInstaller::createInstallTask(OneSixInstance *instance,
- BaseVersionPtr version, QObject *parent)
-{
- if (!version)
- {
- return nullptr;
- }
- m_forge_version = std::dynamic_pointer_cast<ForgeVersion>(version);
- return new ForgeInstallTask(this, instance, version, parent);
-}
-
-#include "ForgeInstaller.moc"
diff --git a/api/logic/minecraft/forge/ForgeInstaller.h b/api/logic/minecraft/forge/ForgeInstaller.h
deleted file mode 100644
index 26286be7..00000000
--- a/api/logic/minecraft/forge/ForgeInstaller.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2013-2017 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 "BaseInstaller.h"
-
-#include <QString>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class VersionFile;
-class ForgeInstallTask;
-struct ForgeVersion;
-
-class MULTIMC_LOGIC_EXPORT ForgeInstaller : public BaseInstaller
-{
- friend class ForgeInstallTask;
-public:
- ForgeInstaller();
- virtual ~ForgeInstaller(){}
- virtual Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
- virtual QString id() const override { return "net.minecraftforge"; }
-
-protected:
- void prepare(const QString &filename, const QString &universalUrl);
- bool add(OneSixInstance *to) override;
- bool addLegacy(OneSixInstance *to);
-
-private:
- // the parsed version json, read from the installer
- std::shared_ptr<VersionFile> m_forge_json;
- // the actual forge version
- std::shared_ptr<ForgeVersion> m_forge_version;
- QString internalPath;
- QString finalPath;
- QString m_forgeVersionString;
- QString m_universal_url;
-};
diff --git a/api/logic/minecraft/forge/ForgeVersion.cpp b/api/logic/minecraft/forge/ForgeVersion.cpp
deleted file mode 100644
index b859a28c..00000000
--- a/api/logic/minecraft/forge/ForgeVersion.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "ForgeVersion.h"
-#include "minecraft/VersionFilterData.h"
-#include <QObject>
-
-QString ForgeVersion::name()
-{
- return "Forge " + jobbuildver;
-}
-
-QString ForgeVersion::descriptor()
-{
- return universal_filename;
-}
-
-QString ForgeVersion::typeString() const
-{
- if (is_recommended)
- return QObject::tr("Recommended");
- return QString();
-}
-
-bool ForgeVersion::operator<(BaseVersion &a)
-{
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if (!pa)
- return true;
- return m_buildnr < pa->m_buildnr;
-}
-
-bool ForgeVersion::operator>(BaseVersion &a)
-{
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if (!pa)
- return false;
- return m_buildnr > pa->m_buildnr;
-}
-
-bool ForgeVersion::usesInstaller()
-{
- if(installer_url.isEmpty())
- return false;
- if(g_VersionFilterData.forgeInstallerBlacklist.contains(mcver))
- return false;
- return true;
-}
-
-QString ForgeVersion::filename()
-{
- return usesInstaller() ? installer_filename : universal_filename;
-}
-
-QString ForgeVersion::url()
-{
- return usesInstaller() ? installer_url : universal_url;
-}
diff --git a/api/logic/minecraft/forge/ForgeVersion.h b/api/logic/minecraft/forge/ForgeVersion.h
deleted file mode 100644
index e77d32f1..00000000
--- a/api/logic/minecraft/forge/ForgeVersion.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-#include <QString>
-#include <memory>
-#include "BaseVersion.h"
-
-struct ForgeVersion;
-typedef std::shared_ptr<ForgeVersion> ForgeVersionPtr;
-
-struct ForgeVersion : public BaseVersion
-{
- virtual QString descriptor() override;
- virtual QString name() override;
- virtual QString typeString() const override;
- virtual bool operator<(BaseVersion &a) override;
- virtual bool operator>(BaseVersion &a) override;
-
- QString filename();
- QString url();
-
- enum
- {
- Invalid,
- Legacy,
- Gradle
- } type = Invalid;
-
- bool usesInstaller();
-
- int m_buildnr = 0;
- QString branch;
- QString universal_url;
- QString changelog_url;
- QString installer_url;
- QString jobbuildver;
- QString mcver;
- QString mcver_sane;
- QString universal_filename;
- QString installer_filename;
- bool is_recommended = false;
-};
-
-Q_DECLARE_METATYPE(ForgeVersionPtr)
diff --git a/api/logic/minecraft/forge/ForgeVersionList.cpp b/api/logic/minecraft/forge/ForgeVersionList.cpp
deleted file mode 100644
index 2fb3d012..00000000
--- a/api/logic/minecraft/forge/ForgeVersionList.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright 2013-2017 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ForgeVersionList.h"
-#include "ForgeVersion.h"
-
-#include "net/NetJob.h"
-#include "net/URLConstants.h"
-#include "Env.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include <QDebug>
-
-ForgeVersionList::ForgeVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *ForgeVersionList::getLoadTask()
-{
- return new ForgeListLoadTask(this);
-}
-
-bool ForgeVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr ForgeVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int ForgeVersionList::count() const
-{
- return m_vlist.count();
-}
-
-int ForgeVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ForgeVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<ForgeVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case ParentGameVersionRole:
- return version->mcver_sane;
-
- case RecommendedRole:
- return version->is_recommended;
-
- case BranchRole:
- return version->branch;
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList ForgeVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole, BranchRole};
-}
-
-BaseVersionPtr ForgeVersionList::getLatestStable() const
-{
- return BaseVersionPtr();
-}
-
-void ForgeVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- endResetModel();
- // NOW SORT!!
- // sort();
-}
-
-void ForgeVersionList::sortVersions()
-{
- // NO-OP for now
-}
-
-ForgeListLoadTask::ForgeListLoadTask(ForgeVersionList *vlist) : Task()
-{
- m_list = vlist;
-}
-
-void ForgeListLoadTask::executeTask()
-{
- setStatus(tr("Fetching Forge version lists..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto forgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "list.json");
- auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json");
-
- // verify by poking the server.
- forgeListEntry->setStale(true);
- gradleForgeListEntry->setStale(true);
-
- job->addNetAction(listDownload = Net::Download::makeCached(QUrl(URLConstants::FORGE_LEGACY_URL),forgeListEntry));
- job->addNetAction(gradleListDownload = Net::Download::makeCached(QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
- connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-bool ForgeListLoadTask::abort()
-{
- return listJob->abort();
-}
-
-bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out)
-{
- QMap<int, std::shared_ptr<ForgeVersion>> lookup;
- QByteArray data;
- {
- auto filename = gradleListDownload->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- gradleListDownload.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing gradle version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing gradle version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // we probably could hard code these, but it might still be worth doing it this way
- const QString webpath = root.value("webpath").toString();
- const QString artifact = root.value("artifact").toString();
-
- QJsonObject numbers = root.value("number").toObject();
- for (auto it = numbers.begin(); it != numbers.end(); ++it)
- {
- QJsonObject number = it.value().toObject();
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->m_buildnr = number.value("build").toDouble();
- if(fVersion->m_buildnr >= 953 && fVersion->m_buildnr <= 965)
- {
- qDebug() << fVersion->m_buildnr;
- }
- fVersion->jobbuildver = number.value("version").toString();
- fVersion->branch = number.value("branch").toString("");
- fVersion->mcver = number.value("mcversion").toString();
- fVersion->universal_filename = "";
- fVersion->installer_filename = "";
- // HACK: here, we fix the minecraft version used by forge.
- // HACK: this will inevitably break (later)
- // FIXME: replace with a dictionary
- fVersion->mcver_sane = fVersion->mcver;
- fVersion->mcver_sane.replace("_pre", "-pre");
-
- QString universal_filename, installer_filename;
- QJsonArray files = number.value("files").toArray();
- for (auto fIt = files.begin(); fIt != files.end(); ++fIt)
- {
- // TODO with gradle we also get checksums, use them
- QJsonArray file = (*fIt).toArray();
- if (file.size() < 3)
- {
- continue;
- }
-
- QString extension = file.at(0).toString();
- QString part = file.at(1).toString();
- QString checksum = file.at(2).toString();
-
- // insane form of mcver is used here
- QString longVersion = fVersion->mcver + "-" + fVersion->jobbuildver;
- if (!fVersion->branch.isEmpty())
- {
- longVersion = longVersion + "-" + fVersion->branch;
- }
- QString filename = artifact + "-" + longVersion + "-" + part + "." + extension;
-
- QString url = QString("%1/%2/%3")
- .arg(webpath)
- .arg(longVersion)
- .arg(filename);
-
- if (part == "installer")
- {
- fVersion->installer_url = url;
- installer_filename = filename;
- }
- else if (part == "universal" || part == "client")
- {
- fVersion->universal_url = url;
- universal_filename = filename;
- }
- else if (part == "changelog")
- {
- fVersion->changelog_url = url;
- }
- }
- if (fVersion->installer_url.isEmpty() && fVersion->universal_url.isEmpty())
- {
- continue;
- }
- fVersion->universal_filename = universal_filename;
- fVersion->installer_filename = installer_filename;
- fVersion->type = ForgeVersion::Gradle;
- out.append(fVersion);
- lookup[fVersion->m_buildnr] = fVersion;
- }
- QJsonObject promos = root.value("promos").toObject();
- for (auto it = promos.begin(); it != promos.end(); ++it)
- {
- QString key = it.key();
- int build = it.value().toInt();
- QRegularExpression regexp("^(?<mcversion>[0-9]+(.[0-9]+)*)-(?<label>[a-z]+)$");
- auto match = regexp.match(key);
- if(!match.hasMatch())
- {
- qDebug() << key << "doesn't match." << "build" << build;
- continue;
- }
-
- QString label = match.captured("label");
- if(label != "recommended")
- {
- continue;
- }
- QString mcversion = match.captured("mcversion");
- qDebug() << "Forge build" << build << "is the" << label << "for Minecraft" << mcversion << QString("<%1>").arg(key);
- lookup[build]->is_recommended = true;
- }
- return true;
-}
-
-void ForgeListLoadTask::listDownloaded()
-{
- QList<BaseVersionPtr> list;
- bool ret = true;
-
- if (!parseForgeGradleList(list))
- {
- ret = false;
- }
-
- if (!ret)
- {
- return;
- }
- std::sort(list.begin(), list.end(), [](const BaseVersionPtr & l, const BaseVersionPtr & r)
- { return (*l > *r); });
-
- m_list->updateListData(list);
-
- emitSucceeded();
- return;
-}
-
-void ForgeListLoadTask::listFailed()
-{
- auto &reply = listDownload->m_reply;
- if (reply)
- {
- qCritical() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- qCritical() << "Getting forge version list failed for reasons unknown.";
- }
-}
-
-void ForgeListLoadTask::gradleListFailed()
-{
- auto &reply = gradleListDownload->m_reply;
- if (reply)
- {
- qCritical() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- qCritical() << "Getting forge version list failed for reasons unknown.";
- }
-}
diff --git a/api/logic/minecraft/forge/ForgeVersionList.h b/api/logic/minecraft/forge/ForgeVersionList.h
deleted file mode 100644
index ee4b79d2..00000000
--- a/api/logic/minecraft/forge/ForgeVersionList.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright 2013-2017 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 "ForgeVersion.h"
-
-#include <QObject>
-#include <QAbstractListModel>
-#include <QUrl>
-#include <QNetworkReply>
-
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT ForgeVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class ForgeListLoadTask;
-
- explicit ForgeVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask() override;
- virtual bool isLoaded() override;
- virtual const BaseVersionPtr at(int i) const override;
- virtual int count() const override;
- virtual void sortVersions() override;
-
- virtual BaseVersionPtr getLatestStable() const override;
-
- ForgeVersionPtr findVersionByVersionNr(QString version);
-
- virtual QVariant data(const QModelIndex &index, int role) const override;
- virtual RoleList providesRoles() const override;
-
- virtual int columnCount(const QModelIndex &parent) const override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions) override;
-};
-
-class ForgeListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit ForgeListLoadTask(ForgeVersionList *vlist);
-
- virtual void executeTask();
- virtual bool abort();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
- void gradleListFailed();
-
-protected:
- NetJobPtr listJob;
- ForgeVersionList *m_list;
-
- Net::Download::Ptr listDownload;
- Net::Download::Ptr gradleListDownload;
-
-private:
- bool parseForgeList(QList<BaseVersionPtr> &out);
- bool parseForgeGradleList(QList<BaseVersionPtr> &out);
-};
diff --git a/api/logic/minecraft/forge/LegacyForge.cpp b/api/logic/minecraft/forge/LegacyForge.cpp
deleted file mode 100644
index 2e4508e9..00000000
--- a/api/logic/minecraft/forge/LegacyForge.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright 2013-2017 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 "LegacyForge.h"
-
-MinecraftForge::MinecraftForge(const QString &file) : Mod(file)
-{
-}
-
-bool MinecraftForge::FixVersionIfNeeded(QString newVersion)
-{/*
- wxString reportedVersion = GetModVersion();
- if(reportedVersion == "..." || reportedVersion.empty())
- {
- std::auto_ptr<wxFFileInputStream> in(new wxFFileInputStream("forge.zip"));
- wxTempFileOutputStream out("forge.zip");
- wxTextOutputStream textout(out);
- wxZipInputStream inzip(*in);
- wxZipOutputStream outzip(out);
- std::auto_ptr<wxZipEntry> entry;
- // preserve metadata
- outzip.CopyArchiveMetaData(inzip);
- // copy all entries
- while (entry.reset(inzip.GetNextEntry()), entry.get() != NULL)
- if (!outzip.CopyEntry(entry.release(), inzip))
- return false;
- // release last entry
- in.reset();
- outzip.PutNextEntry("forgeversion.properties");
-
- wxStringTokenizer tokenizer(newVersion,".");
- wxString verFile;
- verFile << wxString("forge.major.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.minor.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.revision.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.build.number=") << tokenizer.GetNextToken() << "\n";
- auto buf = verFile.ToUTF8();
- outzip.Write(buf.data(), buf.length());
- // check if we succeeded
- return inzip.Eof() && outzip.Close() && out.Commit();
- }
- */
- return true;
-}
diff --git a/api/logic/minecraft/forge/LegacyForge.h b/api/logic/minecraft/forge/LegacyForge.h
deleted file mode 100644
index 4a51e74a..00000000
--- a/api/logic/minecraft/forge/LegacyForge.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2013-2017 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 "minecraft/Mod.h"
-
-class MinecraftForge : public Mod
-{
-public:
- MinecraftForge(const QString &file);
- bool FixVersionIfNeeded(QString newVersion);
-};
diff --git a/api/logic/minecraft/ftb/FTBInstanceProvider.cpp b/api/logic/minecraft/ftb/FTBInstanceProvider.cpp
index 1321ea1b..fe23a84e 100644
--- a/api/logic/minecraft/ftb/FTBInstanceProvider.cpp
+++ b/api/logic/minecraft/ftb/FTBInstanceProvider.cpp
@@ -9,7 +9,6 @@
#include <FileSystem.h>
#include "Env.h"
-#include "minecraft/MinecraftVersion.h"
#include "LegacyFTBInstance.h"
#include "OneSixFTBInstance.h"
@@ -246,17 +245,8 @@ InstancePtr FTBInstanceProvider::createInstance(const FTBRecord & record) const
m_settings->registerSetting("InstanceType", "Legacy");
// all legacy versions are built in. therefore we can do this even if we don't have ALL the versions Mojang has on their servers.
- auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion));
- if (mcVersion && mcVersion->usesLegacyLauncher())
- {
- m_settings->set("InstanceType", "LegacyFTB");
- inst.reset(new LegacyFTBInstance(m_globalSettings, m_settings, record.instanceDir));
- }
- else
- {
- m_settings->set("InstanceType", "OneSixFTB");
- inst.reset(new OneSixFTBInstance(m_globalSettings, m_settings, record.instanceDir));
- }
+ m_settings->set("InstanceType", "OneSixFTB");
+ inst.reset(new OneSixFTBInstance(m_globalSettings, m_settings, record.instanceDir));
// initialize
{
diff --git a/api/logic/minecraft/ftb/FTBPlugin.cpp b/api/logic/minecraft/ftb/FTBPlugin.cpp
index d14eea63..541879a1 100644
--- a/api/logic/minecraft/ftb/FTBPlugin.cpp
+++ b/api/logic/minecraft/ftb/FTBPlugin.cpp
@@ -1,11 +1,9 @@
#include "FTBPlugin.h"
#include <Env.h>
-#include "FTBVersion.h"
#include "LegacyFTBInstance.h"
#include "OneSixFTBInstance.h"
#include <BaseInstance.h>
#include <InstanceList.h>
-#include <minecraft/MinecraftVersionList.h>
#include <settings/INISettingsObject.h>
#include <FileSystem.h>
diff --git a/api/logic/minecraft/ftb/FTBProfileStrategy.cpp b/api/logic/minecraft/ftb/FTBProfileStrategy.cpp
index e4e6a6ae..c3d9cc6a 100644
--- a/api/logic/minecraft/ftb/FTBProfileStrategy.cpp
+++ b/api/logic/minecraft/ftb/FTBProfileStrategy.cpp
@@ -2,7 +2,6 @@
#include "OneSixFTBInstance.h"
#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
#include <FileSystem.h>
#include <QDir>
@@ -28,9 +27,8 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
if(QFile::exists(mcJson))
{
auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
- file->fileId = "net.minecraft";
+ file->uid = "net.minecraft";
file->name = QObject::tr("Minecraft (tracked)");
- file->setVanilla(true);
if(file->version.isEmpty())
{
file->version = mcVersion;
@@ -40,7 +38,8 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
addLib->setHint("local");
addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
}
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
+ minecraftPatch = std::make_shared<ProfilePatch>(file);
+ minecraftPatch->setVanilla(true);
}
else
{
@@ -65,8 +64,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
addLib->setHint("local");
addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
}
- file->fileId = "org.multimc.ftb.pack";
- file->setVanilla(true);
+ file->uid = "org.multimc.ftb.pack";
file->name = QObject::tr("%1 (FTB pack)").arg(m_instance->name());
if(file->version.isEmpty())
{
@@ -82,7 +80,8 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
}
}
}
- packPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
+ packPatch = std::make_shared<ProfilePatch>(file);
+ packPatch->setVanilla(true);
}
else
{
diff --git a/api/logic/minecraft/ftb/FTBVersion.h b/api/logic/minecraft/ftb/FTBVersion.h
deleted file mode 100644
index 805319b4..00000000
--- a/api/logic/minecraft/ftb/FTBVersion.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-#include <minecraft/MinecraftVersion.h>
-
-class FTBVersion : public BaseVersion
-{
-public:
- FTBVersion(MinecraftVersionPtr parent) : m_version(parent){};
-
-public:
- virtual QString descriptor() override
- {
- return m_version->descriptor();
- }
-
- virtual QString name() override
- {
- return m_version->name();
- }
-
- virtual QString typeString() const override
- {
- return m_version->typeString();
- }
-
- MinecraftVersionPtr getMinecraftVersion()
- {
- return m_version;
- }
-
-private:
- MinecraftVersionPtr m_version;
-};
diff --git a/api/logic/minecraft/legacy/LegacyUpdate.cpp b/api/logic/minecraft/legacy/LegacyUpdate.cpp
index fbef47f5..337a3e4e 100644
--- a/api/logic/minecraft/legacy/LegacyUpdate.cpp
+++ b/api/logic/minecraft/legacy/LegacyUpdate.cpp
@@ -27,7 +27,6 @@
#include "LegacyModList.h"
#include "LwjglVersionList.h"
-#include "minecraft/MinecraftVersionList.h"
#include "LegacyInstance.h"
#include <FileSystem.h>
diff --git a/api/logic/minecraft/legacy/LwjglVersionList.cpp b/api/logic/minecraft/legacy/LwjglVersionList.cpp
index 7f4e7b38..3d7ad2d4 100644
--- a/api/logic/minecraft/legacy/LwjglVersionList.cpp
+++ b/api/logic/minecraft/legacy/LwjglVersionList.cpp
@@ -99,6 +99,7 @@ inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
void LWJGLVersionList::rssFailed(const QString& reason)
{
+ m_rssDLJob.reset();
m_loading = false;
qWarning() << "Failed to load LWJGL list. Network error: " + reason;
}
@@ -116,8 +117,9 @@ void LWJGLVersionList::rssSucceeded()
if (!doc.setContent(m_rssData, false, &xmlErrorMsg, &errorLine))
{
qWarning() << "Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " + QString::number(errorLine);
- m_loading = false;
+ m_rssDLJob.reset();
m_rssData.clear();
+ m_loading = false;
return;
}
m_rssData.clear();
@@ -162,5 +164,6 @@ void LWJGLVersionList::rssSucceeded()
endResetModel();
qDebug() << "Loaded LWJGL list.";
+ m_rssDLJob.reset();
m_loading = false;
}
diff --git a/api/logic/minecraft/legacy/LwjglVersionList.h b/api/logic/minecraft/legacy/LwjglVersionList.h
index 652a3fda..f5312e2c 100644
--- a/api/logic/minecraft/legacy/LwjglVersionList.h
+++ b/api/logic/minecraft/legacy/LwjglVersionList.h
@@ -78,9 +78,9 @@ public:
return m_vlist[i];
}
- virtual Task* getLoadTask() override
+ virtual shared_qobject_ptr<Task> getLoadTask() override
{
- return nullptr;
+ return m_rssDLJob;
}
virtual void sortVersions() override {};
diff --git a/api/logic/minecraft/liteloader/LiteLoaderInstaller.cpp b/api/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
deleted file mode 100644
index 2a88cfd6..00000000
--- a/api/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright 2013-2017 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 "LiteLoaderInstaller.h"
-
-#include <QJsonArray>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/Library.h"
-#include "minecraft/onesix/OneSixInstance.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-#include "minecraft/liteloader/LiteLoaderVersionList.h"
-#include "Exception.h"
-
-LiteLoaderInstaller::LiteLoaderInstaller() : BaseInstaller()
-{
-}
-
-void LiteLoaderInstaller::prepare(LiteLoaderVersionPtr version)
-{
- m_version = version;
-}
-bool LiteLoaderInstaller::add(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
- QFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(m_version->getVersionFile(), true).toJson());
- file.close();
-
- return true;
-}
-
-class LiteLoaderInstallTask : public Task
-{
- Q_OBJECT
-public:
- LiteLoaderInstallTask(LiteLoaderInstaller *installer, OneSixInstance *instance, BaseVersionPtr version, QObject *parent)
- : Task(parent), m_installer(installer), m_instance(instance), m_version(version)
- {
- }
-
-protected:
- void executeTask() override
- {
- LiteLoaderVersionPtr liteloaderVersion = std::dynamic_pointer_cast<LiteLoaderVersion>(m_version);
- if (!liteloaderVersion)
- {
- return;
- }
- m_installer->prepare(liteloaderVersion);
- if (!m_installer->add(m_instance))
- {
- emitFailed(tr("For reasons unknown, the LiteLoader installation failed. Check your MultiMC log files for details."));
- return;
- }
- try
- {
- m_instance->reloadProfile();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- }
- catch (...)
- {
- emitFailed(tr("Failed to load the version description file for reasons unknown."));
- }
- }
-
-private:
- LiteLoaderInstaller *m_installer;
- OneSixInstance *m_instance;
- BaseVersionPtr m_version;
-};
-
-Task *LiteLoaderInstaller::createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent)
-{
- return new LiteLoaderInstallTask(this, instance, version, parent);
-}
-
-#include "LiteLoaderInstaller.moc"
diff --git a/api/logic/minecraft/liteloader/LiteLoaderInstaller.h b/api/logic/minecraft/liteloader/LiteLoaderInstaller.h
deleted file mode 100644
index 65e6c192..00000000
--- a/api/logic/minecraft/liteloader/LiteLoaderInstaller.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2017 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 <QString>
-#include <QMap>
-
-#include "BaseInstaller.h"
-#include "LiteLoaderVersionList.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT LiteLoaderInstaller : public BaseInstaller
-{
-public:
- LiteLoaderInstaller();
-
- void prepare(LiteLoaderVersionPtr version);
- bool add(OneSixInstance *to) override;
- virtual QString id() const override { return "com.mumfrey.liteloader"; }
-
- Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
-
-private:
- LiteLoaderVersionPtr m_version;
-};
diff --git a/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
deleted file mode 100644
index 023d2f14..00000000
--- a/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/* Copyright 2013-2017 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 <minecraft/onesix/OneSixVersionFormat.h>
-#include "Env.h"
-#include "net/URLConstants.h"
-#include "Exception.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;
-}
-
-VersionFilePtr LiteLoaderVersion::getVersionFile()
-{
- auto f = std::make_shared<VersionFile>();
- f->mainClass = "net.minecraft.launchwrapper.Launch";
- f->addTweakers += tweakClass;
- f->order = 10;
- f->libraries = libraries;
- f->name = "LiteLoader";
- f->fileId = "com.mumfrey.liteloader";
- f->version = version;
- f->minecraftVersion = mcVersion;
- return f;
-}
-
-void LiteLoaderVersionList::sortVersions()
-{
- beginResetModel();
- std::sort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-QVariant LiteLoaderVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case ParentGameVersionRole:
- return version->mcVersion;
-
- case LatestRole:
- return version->isLatest;
-
- case RecommendedRole:
- return version->isRecommended;
-
- case TypeRole:
- return version->isSnapshot ? tr("Snapshot") : tr("Release");
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList LiteLoaderVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole, LatestRole, TypeRole};
-}
-
-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->isRecommended)
- {
- return m_vlist.at(i);
- }
- }
- return BaseVersionPtr();
-}
-
-void LiteLoaderVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- std::sort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-LLListLoadTask::LLListLoadTask(LiteLoaderVersionList *vlist)
-{
- m_list = vlist;
-}
-
-LLListLoadTask::~LLListLoadTask()
-{
-}
-
-void LLListLoadTask::executeTask()
-{
- setStatus(tr("Loading LiteLoader version list..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto liteloaderEntry = ENV.metacache()->resolveEntry("liteloader", "versions.json");
-
- // verify by poking the server.
- liteloaderEntry->setStale(true);
-
- job->addNetAction(listDownload = Net::Download::makeCached(QUrl(URLConstants::LITELOADER_URL), liteloaderEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-void LLListLoadTask::listFailed()
-{
- emitFailed("Failed to load LiteLoader version list.");
- return;
-}
-
-void LLListLoadTask::listDownloaded()
-{
- QByteArray data;
- {
- auto filename = listDownload->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- emitFailed("Failed to open the LiteLoader version list.");
- return;
- }
- data = listFile.readAll();
- listFile.close();
- listDownload.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: jsonDoc is not an object");
- return;
- }
-
- const QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("versions").isObject())
- {
- emitFailed("Error parsing version list JSON: missing 'versions' object");
- return;
- }
-
- auto meta = root.value("meta").toObject();
- QString description = meta.value("description").toString(tr("This is a lightweight loader for mods that don't change game mechanics."));
- QString defaultUrl = meta.value("url").toString("http://dl.liteloader.com");
- QString authors = meta.value("authors").toString("Mumfrey");
- auto versions = root.value("versions").toObject();
-
- QList<BaseVersionPtr> tempList;
- for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt)
- {
- const QString mcVersion = vIt.key();
- const QJsonObject versionObject = vIt.value().toObject();
-
- auto processArtefacts = [&](QJsonObject artefacts, bool notSnapshots, std::shared_ptr<LiteLoaderVersion> &latest)
- {
- QString latestVersion;
- 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")
- {
- latestVersion = artefact.value("version").toString();
- continue;
- }
- LiteLoaderVersionPtr version(new LiteLoaderVersion());
- version->version = artefact.value("version").toString();
- version->mcVersion = mcVersion;
- version->md5 = artefact.value("md5").toString();
- version->timestamp = artefact.value("timestamp").toString().toLong();
- version->tweakClass = artefact.value("tweakClass").toString();
- version->authors = authors;
- version->description = description;
- version->defaultUrl = defaultUrl;
- version->isSnapshot = !notSnapshots;
- const QJsonArray libs = artefact.value("libraries").toArray();
- for (auto lIt = libs.begin(); lIt != libs.end(); ++lIt)
- {
- auto libobject = (*lIt).toObject();
- try
- {
- auto lib = OneSixVersionFormat::libraryFromJson(libobject, "versions.json");
- // hack to make liteloader 1.7.10_00 work
- if(lib->rawName() == GradleSpecifier("org.ow2.asm:asm-all:5.0.3"))
- {
- lib->setRepositoryURL("http://repo.maven.apache.org/maven2/");
- }
- version->libraries.append(lib);
- }
- catch (Exception &e)
- {
- qCritical() << "Couldn't read JSON object:";
- continue; // FIXME: ignores bad libraries and continues loading
- }
- }
- auto liteloaderLib = std::make_shared<Library>("com.mumfrey:liteloader:" + version->version);
- liteloaderLib->setRepositoryURL("http://dl.liteloader.com/versions/");
- if(!notSnapshots)
- {
- liteloaderLib->setHint("always-stale");
- }
- version->libraries.append(liteloaderLib);
- perMcVersionList.append(version);
- }
- if(notSnapshots)
- {
- for (auto version : perMcVersionList)
- {
- auto v = std::dynamic_pointer_cast<LiteLoaderVersion>(version);
- if(v->version == latestVersion)
- {
- latest = v;
- }
- }
- }
- tempList.append(perMcVersionList);
- };
-
- std::shared_ptr<LiteLoaderVersion> latestSnapshot;
- std::shared_ptr<LiteLoaderVersion> latestRelease;
- // are there actually released versions for this mc version?
- if(versionObject.contains("artefacts"))
- {
- const QJsonObject artefacts = versionObject.value("artefacts").toObject().value("com.mumfrey:liteloader").toObject();
- processArtefacts(artefacts, true, latestRelease);
- }
- if(versionObject.contains("snapshots"))
- {
- QJsonObject artefacts = versionObject.value("snapshots").toObject().value("com.mumfrey:liteloader").toObject();
- processArtefacts(artefacts, false, latestSnapshot);
- }
- if(latestSnapshot)
- {
- latestSnapshot->isLatest = true;
- }
- else if(latestRelease)
- {
- latestRelease->isLatest = true;
- }
- if(latestRelease)
- {
- latestRelease->isRecommended = true;
- }
- }
- m_list->updateListData(tempList);
-
- emitSucceeded();
-}
diff --git a/api/logic/minecraft/liteloader/LiteLoaderVersionList.h b/api/logic/minecraft/liteloader/LiteLoaderVersionList.h
deleted file mode 100644
index 6074978c..00000000
--- a/api/logic/minecraft/liteloader/LiteLoaderVersionList.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright 2013-2017 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-
-#include <QString>
-#include <QStringList>
-#include "BaseVersion.h"
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-#include <minecraft/Library.h>
-#include <minecraft/VersionFile.h>
-
-#include "multimc_logic_export.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;
- }
- VersionFilePtr getVersionFile();
-
- // important info
- QString version;
- QString mcVersion;
- QString md5;
- long timestamp = 0;
- bool isLatest = false;
- bool isRecommended = false;
- bool isSnapshot = false;
-
- QString tweakClass;
- QList<LibraryPtr> libraries;
-
- // meta
- QString defaultUrl;
- QString description;
- QString authors;
-};
-typedef std::shared_ptr<LiteLoaderVersion> LiteLoaderVersionPtr;
-
-class MULTIMC_LOGIC_EXPORT LiteLoaderVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class LLListLoadTask;
-
- explicit LiteLoaderVersionList(QObject *parent = 0);
-
- Task *getLoadTask() override;
- bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
- int count() const override;
- void sortVersions() override;
- QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
- RoleList providesRoles() const override;
-
- virtual BaseVersionPtr getLatestStable() const override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- void updateListData(QList<BaseVersionPtr> versions) override;
-};
-
-class LLListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit LLListLoadTask(LiteLoaderVersionList *vlist);
- ~LLListLoadTask();
-
- virtual void executeTask();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
-
-protected:
- NetJobPtr listJob;
- Net::Download::Ptr listDownload;
- LiteLoaderVersionList *m_list;
-};
-
-Q_DECLARE_METATYPE(LiteLoaderVersionPtr)
diff --git a/api/logic/minecraft/onesix/OneSixInstance.cpp b/api/logic/minecraft/onesix/OneSixInstance.cpp
index b471ff3e..fd54f544 100644
--- a/api/logic/minecraft/onesix/OneSixInstance.cpp
+++ b/api/logic/minecraft/onesix/OneSixInstance.cpp
@@ -34,7 +34,15 @@
OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
{
+ // set explicitly during instance creation
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
+
+ // defaults to the version we've been using for years (2.9.1)
+ m_settings->registerSetting("LWJGLVersion", "2.9.1");
+
+ // optionals
+ m_settings->registerSetting("ForgeVersion", "");
+ m_settings->registerSetting("LiteloaderVersion", "");
}
void OneSixInstance::init()
@@ -275,6 +283,8 @@ QStringList OneSixInstance::verboseDescription(AuthSessionPtr session)
printLibFile(file);
}
printLibFile(mainJarPath());
+ out << "";
+ out << "Native libraries:";
for(auto file: nativeJars)
{
printLibFile(file);
@@ -480,7 +490,32 @@ std::shared_ptr<WorldList> OneSixInstance::worldList() const
bool OneSixInstance::setIntendedVersionId(QString version)
{
- settings()->set("IntendedVersion", version);
+ return setComponentVersion("net.minecraft", version);
+}
+
+QString OneSixInstance::intendedVersionId() const
+{
+ return getComponentVersion("net.minecraft");
+}
+
+bool OneSixInstance::setComponentVersion(const QString& uid, const QString& version)
+{
+ if(uid == "net.minecraft")
+ {
+ settings()->set("IntendedVersion", version);
+ }
+ else if (uid == "org.lwjgl")
+ {
+ settings()->set("LWJGLVersion", version);
+ }
+ else if (uid == "net.minecraftforge")
+ {
+ settings()->set("ForgeVersion", version);
+ }
+ else if (uid == "com.mumfrey.liteloader")
+ {
+ settings()->set("LiteloaderVersion", version);
+ }
if(getMinecraftProfile())
{
clearProfile();
@@ -489,6 +524,27 @@ bool OneSixInstance::setIntendedVersionId(QString version)
return true;
}
+QString OneSixInstance::getComponentVersion(const QString& uid) const
+{
+ if(uid == "net.minecraft")
+ {
+ return settings()->get("IntendedVersion").toString();
+ }
+ else if(uid == "org.lwjgl")
+ {
+ return settings()->get("LWJGLVersion").toString();
+ }
+ else if(uid == "net.minecraftforge")
+ {
+ return settings()->get("ForgeVersion").toString();
+ }
+ else if(uid == "com.mumfrey.liteloader")
+ {
+ return settings()->get("LiteloaderVersion").toString();
+ }
+ return QString();
+}
+
QList< Mod > OneSixInstance::getJarMods() const
{
QList<Mod> mods;
@@ -500,12 +556,6 @@ QList< Mod > OneSixInstance::getJarMods() const
return mods;
}
-
-QString OneSixInstance::intendedVersionId() const
-{
- return settings()->get("IntendedVersion").toString();
-}
-
void OneSixInstance::setShouldUpdate(bool)
{
}
@@ -523,7 +573,7 @@ QString OneSixInstance::currentVersionId() const
void OneSixInstance::reloadProfile()
{
m_profile->reload();
- setVersionBroken(m_profile->getProblemSeverity() == ProblemSeverity::PROBLEM_ERROR);
+ setVersionBroken(m_profile->getProblemSeverity() == ProblemSeverity::Error);
emit versionReloaded();
}
diff --git a/api/logic/minecraft/onesix/OneSixInstance.h b/api/logic/minecraft/onesix/OneSixInstance.h
index 72c05ad7..ec8c2597 100644
--- a/api/logic/minecraft/onesix/OneSixInstance.h
+++ b/api/logic/minecraft/onesix/OneSixInstance.h
@@ -59,9 +59,11 @@ public:
virtual QString intendedVersionId() const override;
virtual bool setIntendedVersionId(QString version) override;
-
virtual QString currentVersionId() const override;
+ QString getComponentVersion(const QString &uid) const;
+ bool setComponentVersion(const QString &uid, const QString &version);
+
virtual bool shouldUpdate() const override;
virtual void setShouldUpdate(bool val) override;
diff --git a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
index 07c9f075..d3e137c7 100644
--- a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
+++ b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
@@ -3,7 +3,6 @@
#include "OneSixVersionFormat.h"
#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
#include "Env.h"
#include <FileSystem.h>
@@ -11,6 +10,12 @@
#include <QUuid>
#include <QJsonDocument>
#include <QJsonArray>
+#include <QSaveFile>
+#include <QResource>
+#include <meta/Index.h>
+#include <meta/Version.h>
+
+#include <tuple>
OneSixProfileStrategy::OneSixProfileStrategy(OneSixInstance* instance)
{
@@ -53,7 +58,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
}
auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
ProfileUtils::removeLwjglFromPatch(file);
- file->fileId = "net.minecraft";
+ file->uid = "net.minecraft";
file->version = file->minecraftVersion;
file->name = "Minecraft";
auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson();
@@ -80,156 +85,128 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
void OneSixProfileStrategy::loadDefaultBuiltinPatches()
{
+ auto addBuiltinPatch = [&](const QString &uid, const QString intendedVersion, int order)
{
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
+ auto jsonFilePath = FS::PathCombine(m_instance->instanceRoot(), "patches" , uid + ".json");
// load up the base minecraft patch
- ProfilePatchPtr minecraftPatch;
- if(QFile::exists(mcJson))
+ ProfilePatchPtr profilePatch;
+ if(QFile::exists(jsonFilePath))
{
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
+ auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
if(file->version.isEmpty())
{
- file->version = m_instance->intendedVersionId();
+ file->version = intendedVersion;
}
- file->setVanilla(false);
- file->setRevertible(true);
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
+ profilePatch = std::make_shared<ProfilePatch>(file, jsonFilePath);
+ profilePatch->setVanilla(false);
+ profilePatch->setRevertible(true);
}
else
{
- auto mcversion = ENV.getVersion("net.minecraft", m_instance->intendedVersionId());
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(mcversion);
+ auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion);
+ profilePatch = std::make_shared<ProfilePatch>(metaVersion);
+ profilePatch->setVanilla(true);
}
- if (!minecraftPatch)
+ if (!profilePatch)
{
- throw VersionIncomplete("net.minecraft");
+ throw VersionIncomplete(uid);
}
- minecraftPatch->setOrder(-2);
- profile->appendPatch(minecraftPatch);
- }
+ profilePatch->setOrder(order);
+ profile->appendPatch(profilePatch);
+ };
+ addBuiltinPatch("net.minecraft", m_instance->getComponentVersion("net.minecraft"), -2);
+ addBuiltinPatch("org.lwjgl", m_instance->getComponentVersion("org.lwjgl"), -1);
+}
+void OneSixProfileStrategy::loadUserPatches()
+{
+ // first, collect all patches (that are not builtins of OneSix) and load them
+ QMap<QString, ProfilePatchPtr> loadedPatches;
+ QDir patchesDir(FS::PathCombine(m_instance->instanceRoot(),"patches"));
+ for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
{
- auto lwjglJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "org.lwjgl.json");
- ProfilePatchPtr lwjglPatch;
- if(QFile::exists(lwjglJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(lwjglJson), false);
- file->setVanilla(false);
- file->setRevertible(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
+ // parse the file
+ qDebug() << "Reading" << info.fileName();
+ auto file = ProfileUtils::parseJsonFile(info, true);
+ // ignore builtins
+ if (file->uid == "net.minecraft")
+ continue;
+ if (file->uid == "org.lwjgl")
+ continue;
+ auto patch = std::make_shared<ProfilePatch>(file, info.filePath());
+ patch->setRemovable(true);
+ patch->setMovable(true);
+ if(ENV.metadataIndex()->hasUid(file->uid))
{
- // NOTE: this is obviously fake, is fixed in unstable.
- QResource LWJGL(":/versions/LWJGL/2.9.1.json");
- auto lwjgl = ProfileUtils::parseJsonFile(LWJGL.absoluteFilePath(), false);
- lwjgl->setVanilla(true);
- lwjgl->setCustomizable(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(lwjgl);
+ // FIXME: requesting a uid/list creates it in the index... this allows reverting to possibly invalid versions...
+ patch->setRevertible(true);
}
- if (!lwjglPatch)
+ loadedPatches[file->uid] = patch;
+ }
+ // these are 'special'... if not already loaded from instance files, grab them from the metadata repo.
+ auto loadSpecial = [&](const QString & uid, int order)
+ {
+ auto patchVersion = m_instance->getComponentVersion(uid);
+ if(!patchVersion.isEmpty() && !loadedPatches.contains(uid))
{
- throw VersionIncomplete("org.lwjgl");
+ auto patch = std::make_shared<ProfilePatch>(ENV.metadataIndex()->get(uid, patchVersion));
+ patch->setOrder(order);
+ patch->setVanilla(true);
+ patch->setRemovable(true);
+ patch->setMovable(true);
+ loadedPatches[uid] = patch;
}
- lwjglPatch->setOrder(-1);
- profile->appendPatch(lwjglPatch);
- }
-}
+ };
+ loadSpecial("net.minecraftforge", 5);
+ loadSpecial("com.mumfrey.liteloader", 10);
-void OneSixProfileStrategy::loadUserPatches()
-{
- // load all patches, put into map for ordering, apply in the right order
+ // now add all the patches by user sort order
ProfileUtils::PatchOrder userOrder;
ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches"));
- QSet<QString> seen_extra;
-
- // first, load things by sort order.
- for (auto id : userOrder)
+ bool orderIsDirty = false;
+ for (auto uid : userOrder)
{
// ignore builtins
- if (id == "net.minecraft")
+ if (uid == "net.minecraft")
continue;
- if (id == "org.lwjgl")
+ if (uid == "org.lwjgl")
continue;
- // parse the file
- QString filename = patches.absoluteFilePath(id + ".json");
- QFileInfo finfo(filename);
- if(!finfo.exists())
+ // ordering has a patch that is gone?
+ if(!loadedPatches.contains(uid))
{
- qDebug() << "Patch file " << filename << " was deleted by external means...";
+ orderIsDirty = true;
continue;
}
- qDebug() << "Reading" << filename << "by user order";
- VersionFilePtr file = ProfileUtils::parseJsonFile(finfo, false);
- // sanity check. prevent tampering with files.
- if (file->fileId != id)
- {
- file->addProblem(PROBLEM_WARNING, QObject::tr("load id %1 does not match internal id %2").arg(id, file->fileId));
- seen_extra.insert(file->fileId);
- }
- file->setRemovable(true);
- file->setMovable(true);
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- file->assets = QString();
- file->mojangAssetIndex.reset();
- // HACK
- profile->appendPatch(file);
+ profile->appendPatch(loadedPatches.take(uid));
}
- // now load the rest by internal preference.
- QMultiMap<int, VersionFilePtr> files;
- for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files))
+
+ // is there anything left to sort?
+ if(loadedPatches.isEmpty())
{
- // parse the file
- qDebug() << "Reading" << info.fileName();
- auto file = ProfileUtils::parseJsonFile(info, true);
- // ignore builtins
- if (file->fileId == "net.minecraft")
- continue;
- if (file->fileId == "org.lwjgl")
- continue;
- // do not load versions with broken IDs twice
- if(seen_extra.contains(file->fileId))
- continue;
- // do not load what we already loaded in the first pass
- if (userOrder.contains(file->fileId))
- continue;
- file->setRemovable(true);
- file->setMovable(true);
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- file->assets = QString();
- file->mojangAssetIndex.reset();
- // HACK
- files.insert(file->order, file);
+ // TODO: save the order here?
+ return;
+ }
+
+ // inserting into multimap by order number as key sorts the patches and detects duplicates
+ QMultiMap<int, ProfilePatchPtr> files;
+ auto iter = loadedPatches.begin();
+ while(iter != loadedPatches.end())
+ {
+ files.insert((*iter)->getOrder(), *iter);
+ iter++;
}
- QSet<int> seen;
+
+ // then just extract the patches and put them in the list
for (auto order : files.keys())
{
- if(seen.contains(order))
- continue;
- seen.insert(order);
const auto &values = files.values(order);
- if(values.size() == 1)
- {
- profile->appendPatch(values[0]);
- continue;
- }
- for(auto &file: values)
+ for(auto &value: values)
{
- QStringList list;
- for(auto &file2: values)
- {
- if(file != file2)
- list.append(file2->name);
- }
- file->addProblem(PROBLEM_WARNING, QObject::tr("%1 has the same order as the following components:\n%2").arg(file->name, list.join(", ")));
- profile->appendPatch(file);
+ // TODO: put back the insertion of problem messages here, so the user knows about the id duplication
+ profile->appendPatch(value);
}
}
+ // TODO: save the order here?
}
@@ -266,7 +243,10 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
return false;
}
}
-
+ if(!m_instance->getComponentVersion(patch->getID()).isEmpty())
+ {
+ m_instance->setComponentVersion(patch->getID(), QString());
+ }
auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool
{
@@ -285,7 +265,8 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
return true;
};
- for(auto &jarmod: patch->getJarMods())
+ auto &jarMods = patch->getVersionFile()->jarMods;
+ for(auto &jarmod: jarMods)
{
ok &= preRemoveJarMod(jarmod);
}
@@ -405,12 +386,9 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
jarMod->originalName = sourceInfo.completeBaseName();
f->jarMods.append(jarMod);
f->name = target_name;
- f->fileId = target_id;
+ f->uid = target_id;
f->order = profile->getFreeOrderNumber();
QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
- f->filename = patchFileName;
- f->setMovable(true);
- f->setRemovable(true);
QFile file(patchFileName);
if (!file.open(QFile::WriteOnly))
@@ -421,7 +399,11 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
}
file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
file.close();
- profile->appendPatch(f);
+
+ auto patch = std::make_shared<ProfilePatch>(f, patchFileName);
+ patch->setMovable(true);
+ patch->setRemovable(true);
+ profile->appendPatch(patch);
}
profile->saveCurrentOrder();
profile->reapplyPatches();
diff --git a/api/logic/minecraft/onesix/OneSixUpdate.cpp b/api/logic/minecraft/onesix/OneSixUpdate.cpp
index 4bc80bfe..bf234189 100644
--- a/api/logic/minecraft/onesix/OneSixUpdate.cpp
+++ b/api/logic/minecraft/onesix/OneSixUpdate.cpp
@@ -24,7 +24,6 @@
#include <QDataStream>
#include "BaseInstance.h"
-#include "minecraft/MinecraftVersionList.h"
#include "minecraft/MinecraftProfile.h"
#include "minecraft/Library.h"
#include "net/URLConstants.h"
@@ -35,6 +34,9 @@
#include "update/FMLLibrariesTask.h"
#include "update/AssetUpdateTask.h"
+#include <meta/Index.h>
+#include <meta/Version.h>
+
OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
// create folders
@@ -44,29 +46,23 @@ OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent)
// add a version update task, if necessary
{
- auto list = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft"));
- auto version = std::dynamic_pointer_cast<MinecraftVersion>(list->findVersion(m_inst->intendedVersionId()));
- if (version == nullptr)
- {
- // don't do anything if it was invalid
- m_preFailure = tr("The specified Minecraft version is invalid. Choose a different one.");
- }
- else if (m_inst->providesVersionFile() || !version->needsUpdate())
+ /*
+ * FIXME: there are some corner cases here that remain unhandled:
+ * what if local load succeeds but remote fails? The version is still usable...
+ */
+ // FIXME: derive this from the actual list of version patches...
+ auto loadVersion = [&](const QString & uid, const QString & version)
{
- qDebug() << "Instance either provides a version file or doesn't need an update.";
- }
- else
- {
- auto versionUpdateTask = list->createUpdateTask(m_inst->intendedVersionId());
- if (!versionUpdateTask)
- {
- qDebug() << "Didn't spawn an update task.";
- }
- else
+ auto obj = ENV.metadataIndex()->get(uid, version);
+ obj->load();
+ auto task = obj->getCurrentTask();
+ if(task)
{
- m_tasks.append(versionUpdateTask);
+ m_tasks.append(task.unwrap());
}
- }
+ };
+ loadVersion("org.lwjgl", m_inst->getComponentVersion("org.lwjgl"));
+ loadVersion("net.minecraft", m_inst->getComponentVersion("net.minecraft"));
}
// libraries download
@@ -117,11 +113,20 @@ void OneSixUpdate::next()
return;
}
auto task = m_tasks[m_currentTask];
+ // if the task is already finished by the time we look at it, skip it
+ if(task->isFinished())
+ {
+ next();
+ }
connect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded);
connect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed);
connect(task.get(), &Task::progress, this, &OneSixUpdate::progress);
connect(task.get(), &Task::status, this, &OneSixUpdate::setStatus);
- task->start();
+ // if the task is already running, do not start it again
+ if(!task->isRunning())
+ {
+ task->start();
+ }
}
void OneSixUpdate::subtaskSucceeded()
diff --git a/api/logic/minecraft/onesix/OneSixVersionFormat.cpp b/api/logic/minecraft/onesix/OneSixVersionFormat.cpp
index 541fb109..266bd4bd 100644
--- a/api/logic/minecraft/onesix/OneSixVersionFormat.cpp
+++ b/api/logic/minecraft/onesix/OneSixVersionFormat.cpp
@@ -1,7 +1,6 @@
#include "OneSixVersionFormat.h"
#include <Json.h>
#include "minecraft/ParseUtils.h"
-#include <minecraft/MinecraftVersion.h>
#include <minecraft/VersionBuildError.h>
#include <minecraft/MojangVersionFormat.h>
@@ -62,10 +61,19 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
}
out->name = root.value("name").toString();
- out->fileId = root.value("fileId").toString();
+
+ if(root.contains("uid"))
+ {
+ out->uid = root.value("uid").toString();
+ }
+ else
+ {
+ out->uid = root.value("fileId").toString();
+ }
+
out->version = root.value("version").toString();
out->dependsOnMinecraftVersion = root.value("mcVersion").toString();
- out->filename = filename;
+ // out->filename = filename;
MojangVersionFormat::readVersionProperties(root, out.get());
@@ -120,7 +128,8 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
bool hasLibs = root.contains("libraries");
if (hasPlusLibs && hasLibs)
{
- out->addProblem(PROBLEM_WARNING, QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported."));
+ out->addProblem(ProblemSeverity::Warning,
+ QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported."));
readLibs("libraries");
readLibs("+libraries");
}
@@ -136,23 +145,23 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
/* removed features that shouldn't be used */
if (root.contains("tweakers"))
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element 'tweakers'"));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element 'tweakers'"));
}
if (root.contains("-libraries"))
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-libraries'"));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-libraries'"));
}
if (root.contains("-tweakers"))
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-tweakers'"));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-tweakers'"));
}
if (root.contains("-minecraftArguments"))
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-minecraftArguments'"));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-minecraftArguments'"));
}
if (root.contains("+minecraftArguments"))
{
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
}
return out;
}
@@ -165,7 +174,10 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch
root.insert("order", patch->order);
}
writeString(root, "name", patch->name);
- writeString(root, "fileId", patch->fileId);
+
+ writeString(root, "uid", patch->uid);
+ writeString(root, "fileId", patch->uid);
+
writeString(root, "version", patch->version);
writeString(root, "mcVersion", patch->dependsOnMinecraftVersion);
diff --git a/api/logic/minecraft/onesix/update/LibrariesTask.cpp b/api/logic/minecraft/onesix/update/LibrariesTask.cpp
index f60c2b5e..3e6bb12a 100644
--- a/api/logic/minecraft/onesix/update/LibrariesTask.cpp
+++ b/api/logic/minecraft/onesix/update/LibrariesTask.cpp
@@ -35,19 +35,23 @@ void LibrariesTask::executeTask()
downloadJob.reset(job);
}
- auto libs = profile->getLibraries();
-
auto metacache = ENV.metacache();
QList<LibraryPtr> brokenLocalLibs;
QStringList failedFiles;
- for (auto lib : libs)
+ auto createJobs = [&](const QList<LibraryPtr> & libs)
{
- auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath());
- for(auto dl : dls)
+ for (auto lib : libs)
{
- downloadJob->addNetAction(dl);
+ auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath());
+ for(auto dl : dls)
+ {
+ downloadJob->addNetAction(dl);
+ }
}
- }
+ };
+ createJobs(profile->getLibraries());
+ createJobs(profile->getNativeLibraries());
+
// FIXME: this is never filled!!!!
if (!brokenLocalLibs.empty())
{