summaryrefslogtreecommitdiffstats
path: root/libraries/logic/minecraft
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/logic/minecraft')
-rw-r--r--libraries/logic/minecraft/AssetsUtils.cpp230
-rw-r--r--libraries/logic/minecraft/AssetsUtils.h48
-rw-r--r--libraries/logic/minecraft/GradleSpecifier.h129
-rw-r--r--libraries/logic/minecraft/JarMod.h12
-rw-r--r--libraries/logic/minecraft/Library.cpp239
-rw-r--r--libraries/logic/minecraft/Library.h184
-rw-r--r--libraries/logic/minecraft/MinecraftInstance.cpp369
-rw-r--r--libraries/logic/minecraft/MinecraftInstance.h69
-rw-r--r--libraries/logic/minecraft/MinecraftProfile.cpp610
-rw-r--r--libraries/logic/minecraft/MinecraftProfile.h200
-rw-r--r--libraries/logic/minecraft/MinecraftVersion.cpp215
-rw-r--r--libraries/logic/minecraft/MinecraftVersion.h119
-rw-r--r--libraries/logic/minecraft/MinecraftVersionList.cpp591
-rw-r--r--libraries/logic/minecraft/MinecraftVersionList.h72
-rw-r--r--libraries/logic/minecraft/Mod.cpp377
-rw-r--r--libraries/logic/minecraft/Mod.h134
-rw-r--r--libraries/logic/minecraft/ModList.cpp616
-rw-r--r--libraries/logic/minecraft/ModList.h160
-rw-r--r--libraries/logic/minecraft/MojangDownloadInfo.h71
-rw-r--r--libraries/logic/minecraft/MojangVersionFormat.cpp381
-rw-r--r--libraries/logic/minecraft/MojangVersionFormat.h25
-rw-r--r--libraries/logic/minecraft/OpSys.cpp42
-rw-r--r--libraries/logic/minecraft/OpSys.h37
-rw-r--r--libraries/logic/minecraft/ParseUtils.cpp34
-rw-r--r--libraries/logic/minecraft/ParseUtils.h11
-rw-r--r--libraries/logic/minecraft/ProfilePatch.h104
-rw-r--r--libraries/logic/minecraft/ProfileStrategy.h35
-rw-r--r--libraries/logic/minecraft/ProfileUtils.cpp191
-rw-r--r--libraries/logic/minecraft/ProfileUtils.h25
-rw-r--r--libraries/logic/minecraft/Rule.cpp93
-rw-r--r--libraries/logic/minecraft/Rule.h101
-rw-r--r--libraries/logic/minecraft/VersionBuildError.h58
-rw-r--r--libraries/logic/minecraft/VersionFile.cpp60
-rw-r--r--libraries/logic/minecraft/VersionFile.h195
-rw-r--r--libraries/logic/minecraft/VersionFilterData.cpp75
-rw-r--r--libraries/logic/minecraft/VersionFilterData.h32
-rw-r--r--libraries/logic/minecraft/World.cpp385
-rw-r--r--libraries/logic/minecraft/World.h83
-rw-r--r--libraries/logic/minecraft/WorldList.cpp355
-rw-r--r--libraries/logic/minecraft/WorldList.h125
-rw-r--r--libraries/logic/minecraft/auth/AuthSession.cpp30
-rw-r--r--libraries/logic/minecraft/auth/AuthSession.h51
-rw-r--r--libraries/logic/minecraft/auth/MojangAccount.cpp278
-rw-r--r--libraries/logic/minecraft/auth/MojangAccount.h173
-rw-r--r--libraries/logic/minecraft/auth/MojangAccountList.cpp427
-rw-r--r--libraries/logic/minecraft/auth/MojangAccountList.h201
-rw-r--r--libraries/logic/minecraft/auth/YggdrasilTask.cpp255
-rw-r--r--libraries/logic/minecraft/auth/YggdrasilTask.h150
-rw-r--r--libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp202
-rw-r--r--libraries/logic/minecraft/auth/flows/AuthenticateTask.h46
-rw-r--r--libraries/logic/minecraft/auth/flows/RefreshTask.cpp144
-rw-r--r--libraries/logic/minecraft/auth/flows/RefreshTask.h44
-rw-r--r--libraries/logic/minecraft/auth/flows/ValidateTask.cpp61
-rw-r--r--libraries/logic/minecraft/auth/flows/ValidateTask.h47
-rw-r--r--libraries/logic/minecraft/forge/ForgeInstaller.cpp458
-rw-r--r--libraries/logic/minecraft/forge/ForgeInstaller.h52
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersion.cpp55
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersion.h42
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersionList.cpp450
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersionList.h90
-rw-r--r--libraries/logic/minecraft/forge/ForgeXzDownload.cpp358
-rw-r--r--libraries/logic/minecraft/forge/ForgeXzDownload.h59
-rw-r--r--libraries/logic/minecraft/forge/LegacyForge.cpp56
-rw-r--r--libraries/logic/minecraft/forge/LegacyForge.h25
-rw-r--r--libraries/logic/minecraft/ftb/FTBPlugin.cpp395
-rw-r--r--libraries/logic/minecraft/ftb/FTBPlugin.h13
-rw-r--r--libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp128
-rw-r--r--libraries/logic/minecraft/ftb/FTBProfileStrategy.h21
-rw-r--r--libraries/logic/minecraft/ftb/FTBVersion.h32
-rw-r--r--libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp27
-rw-r--r--libraries/logic/minecraft/ftb/LegacyFTBInstance.h17
-rw-r--r--libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp138
-rw-r--r--libraries/logic/minecraft/ftb/OneSixFTBInstance.h30
-rw-r--r--libraries/logic/minecraft/legacy/LegacyInstance.cpp453
-rw-r--r--libraries/logic/minecraft/legacy/LegacyInstance.h142
-rw-r--r--libraries/logic/minecraft/legacy/LegacyUpdate.cpp393
-rw-r--r--libraries/logic/minecraft/legacy/LegacyUpdate.h70
-rw-r--r--libraries/logic/minecraft/legacy/LwjglVersionList.cpp189
-rw-r--r--libraries/logic/minecraft/legacy/LwjglVersionList.h156
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp142
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h39
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp276
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h119
-rw-r--r--libraries/logic/minecraft/onesix/OneSixInstance.cpp597
-rw-r--r--libraries/logic/minecraft/onesix/OneSixInstance.h117
-rw-r--r--libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp418
-rw-r--r--libraries/logic/minecraft/onesix/OneSixProfileStrategy.h26
-rw-r--r--libraries/logic/minecraft/onesix/OneSixUpdate.cpp342
-rw-r--r--libraries/logic/minecraft/onesix/OneSixUpdate.h67
-rw-r--r--libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp225
-rw-r--r--libraries/logic/minecraft/onesix/OneSixVersionFormat.h22
91 files changed, 0 insertions, 15240 deletions
diff --git a/libraries/logic/minecraft/AssetsUtils.cpp b/libraries/logic/minecraft/AssetsUtils.cpp
deleted file mode 100644
index 7a525abe..00000000
--- a/libraries/logic/minecraft/AssetsUtils.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright 2013-2015 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 <QFileInfo>
-#include <QDir>
-#include <QDirIterator>
-#include <QCryptographicHash>
-#include <QJsonParseError>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QVariant>
-#include <QDebug>
-
-#include "AssetsUtils.h"
-#include "FileSystem.h"
-#include "net/MD5EtagDownload.h"
-
-namespace AssetsUtils
-{
-
-/*
- * Returns true on success, with index populated
- * index is undefined otherwise
- */
-bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
-{
- /*
- {
- "objects": {
- "icons/icon_16x16.png": {
- "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
- "size": 3665
- },
- ...
- }
- }
- }
- */
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << "Failed to read assets index file" << path;
- return false;
- }
- index->id = assetsId;
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << "Failed to parse assets index file:" << parseError.errorString()
- << "at offset " << QString::number(parseError.offset);
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid assets index JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- QJsonValue isVirtual = root.value("virtual");
- if (!isVirtual.isUndefined())
- {
- index->isVirtual = isVirtual.toBool(false);
- }
-
- QJsonValue objects = root.value("objects");
- QVariantMap map = objects.toVariant().toMap();
-
- for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- {
- // qDebug() << iter.key();
-
- QVariant variant = iter.value();
- QVariantMap nested_objects = variant.toMap();
-
- AssetObject object;
-
- for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
- nested_iter != nested_objects.end(); ++nested_iter)
- {
- // qDebug() << nested_iter.key() << nested_iter.value().toString();
- QString key = nested_iter.key();
- QVariant value = nested_iter.value();
-
- if (key == "hash")
- {
- object.hash = value.toString();
- }
- else if (key == "size")
- {
- object.size = value.toDouble();
- }
- }
-
- index->objects.insert(iter.key(), object);
- }
-
- return true;
-}
-
-QDir reconstructAssets(QString assetsId)
-{
- QDir assetsDir = QDir("assets/");
- QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
- QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects"));
- QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual"));
-
- QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
- QFile indexFile(indexPath);
- QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
-
- if (!indexFile.exists())
- {
- qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets";
- return virtualRoot;
- }
-
- qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path()
- << objectDir.path() << virtualDir.path() << virtualRoot.path();
-
- AssetsIndex index;
- bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
-
- if (loadAssetsIndex && index.isVirtual)
- {
- qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path();
-
- for (QString map : index.objects.keys())
- {
- AssetObject asset_object = index.objects.value(map);
- QString target_path = FS::PathCombine(virtualRoot.path(), map);
- QFile target(target_path);
-
- QString tlk = asset_object.hash.left(2);
-
- QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash);
- QFile original(original_path);
- if (!original.exists())
- continue;
- if (!target.exists())
- {
- QFileInfo info(target_path);
- QDir target_dir = info.dir();
- // qDebug() << target_dir;
- if (!target_dir.exists())
- QDir("").mkpath(target_dir.path());
-
- bool couldCopy = original.copy(target_path);
- qDebug() << " Copying" << original_path << "to" << target_path
- << QString::number(couldCopy); // << original.errorString();
- }
- }
-
- // TODO: Write last used time to virtualRoot/.lastused
- }
-
- return virtualRoot;
-}
-
-}
-
-NetActionPtr AssetObject::getDownloadAction()
-{
- QFileInfo objectFile(getLocalPath());
- if ((!objectFile.isFile()) || (objectFile.size() != size))
- {
- auto objectDL = MD5EtagDownload::make(getUrl(), objectFile.filePath());
- objectDL->m_total_progress = size;
- return objectDL;
- }
- return nullptr;
-}
-
-QString AssetObject::getLocalPath()
-{
- return "assets/objects/" + getRelPath();
-}
-
-QUrl AssetObject::getUrl()
-{
- return QUrl("http://resources.download.minecraft.net/" + getRelPath());
-}
-
-QString AssetObject::getRelPath()
-{
- return hash.left(2) + "/" + hash;
-}
-
-NetJobPtr AssetsIndex::getDownloadJob()
-{
- auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
- for (auto &object : objects.values())
- {
- auto dl = object.getDownloadAction();
- if(dl)
- {
- job->addNetAction(dl);
- }
- }
- if(job->size())
- return job;
- return nullptr;
-}
diff --git a/libraries/logic/minecraft/AssetsUtils.h b/libraries/logic/minecraft/AssetsUtils.h
deleted file mode 100644
index 90251c2d..00000000
--- a/libraries/logic/minecraft/AssetsUtils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2013-2015 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 "net/NetAction.h"
-#include "net/NetJob.h"
-
-struct AssetObject
-{
- QString getRelPath();
- QUrl getUrl();
- QString getLocalPath();
- NetActionPtr getDownloadAction();
-
- QString hash;
- qint64 size;
-};
-
-struct AssetsIndex
-{
- NetJobPtr getDownloadJob();
-
- QString id;
- QMap<QString, AssetObject> objects;
- bool isVirtual = false;
-};
-
-namespace AssetsUtils
-{
-bool loadAssetsIndexJson(QString id, QString file, AssetsIndex* index);
-/// Reconstruct a virtual assets folder for the given assets ID and return the folder
-QDir reconstructAssets(QString assetsId);
-}
diff --git a/libraries/logic/minecraft/GradleSpecifier.h b/libraries/logic/minecraft/GradleSpecifier.h
deleted file mode 100644
index 18308537..00000000
--- a/libraries/logic/minecraft/GradleSpecifier.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QStringList>
-#include "DefaultVariable.h"
-
-struct GradleSpecifier
-{
- GradleSpecifier()
- {
- m_valid = false;
- }
- GradleSpecifier(QString value)
- {
- operator=(value);
- }
- GradleSpecifier & operator =(const QString & value)
- {
- /*
- org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar
- DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar"
- DEBUG 1 "org.gradle.test.classifiers"
- DEBUG 2 "service"
- DEBUG 3 "1.0"
- DEBUG 4 ":jdk15"
- DEBUG 5 "jdk15"
- DEBUG 6 "@jar"
- DEBUG 7 "jar"
- */
- QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?");
- m_valid = matcher.exactMatch(value);
- auto elements = matcher.capturedTexts();
- m_groupId = elements[1];
- m_artifactId = elements[2];
- m_version = elements[3];
- m_classifier = elements[5];
- if(!elements[7].isEmpty())
- {
- m_extension = elements[7];
- }
- return *this;
- }
- operator QString() const
- {
- if(!m_valid)
- return "INVALID";
- QString retval = m_groupId + ":" + m_artifactId + ":" + m_version;
- if(!m_classifier.isEmpty())
- {
- retval += ":" + m_classifier;
- }
- if(m_extension.isExplicit())
- {
- retval += "@" + m_extension;
- }
- return retval;
- }
- QString toPath() const
- {
- if(!m_valid)
- return "INVALID";
- QString path = m_groupId;
- path.replace('.', '/');
- path += '/' + m_artifactId + '/' + m_version + '/' + m_artifactId + '-' + m_version;
- if(!m_classifier.isEmpty())
- {
- path += "-" + m_classifier;
- }
- path += "." + m_extension;
- return path;
- }
- inline bool valid() const
- {
- return m_valid;
- }
- inline QString version() const
- {
- return m_version;
- }
- inline QString groupId() const
- {
- return m_groupId;
- }
- inline QString artifactId() const
- {
- return m_artifactId;
- }
- inline void setClassifier(const QString & classifier)
- {
- m_classifier = classifier;
- }
- inline QString classifier() const
- {
- return m_classifier;
- }
- inline QString extension() const
- {
- return m_extension;
- }
- inline QString artifactPrefix() const
- {
- return m_groupId + ":" + m_artifactId;
- }
- bool matchName(const GradleSpecifier & other) const
- {
- return other.artifactId() == artifactId() && other.groupId() == groupId();
- }
- bool operator==(const GradleSpecifier & other) const
- {
- if(m_groupId != other.m_groupId)
- return false;
- if(m_artifactId != other.m_artifactId)
- return false;
- if(m_version != other.m_version)
- return false;
- if(m_classifier != other.m_classifier)
- return false;
- if(m_extension != other.m_extension)
- return false;
- return true;
- }
-private:
- QString m_groupId;
- QString m_artifactId;
- QString m_version;
- QString m_classifier;
- DefaultVariable<QString> m_extension = DefaultVariable<QString>("jar");
- bool m_valid = false;
-};
diff --git a/libraries/logic/minecraft/JarMod.h b/libraries/logic/minecraft/JarMod.h
deleted file mode 100644
index 42d05da9..00000000
--- a/libraries/logic/minecraft/JarMod.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-#include <QString>
-#include <QJsonObject>
-#include <memory>
-class Jarmod;
-typedef std::shared_ptr<Jarmod> JarmodPtr;
-class Jarmod
-{
-public: /* data */
- QString name;
- QString originalName;
-};
diff --git a/libraries/logic/minecraft/Library.cpp b/libraries/logic/minecraft/Library.cpp
deleted file mode 100644
index 922db84e..00000000
--- a/libraries/logic/minecraft/Library.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "Library.h"
-#include <net/CacheDownload.h>
-#include <minecraft/forge/ForgeXzDownload.h>
-#include <Env.h>
-#include <FileSystem.h>
-
-void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& native, QStringList& native32, QStringList& native64) const
-{
- auto actualPath = [&](QString relPath)
- {
- QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
- return out.absoluteFilePath();
- };
- if(m_mojangDownloads)
- {
- if(m_mojangDownloads->artifact)
- {
- auto artifact = m_mojangDownloads->artifact;
- jar += actualPath(artifact->path);
- }
- if(!isNative())
- return;
- if(m_nativeClassifiers.contains(system))
- {
- auto nativeClassifier = m_nativeClassifiers[system];
- if(nativeClassifier.contains("${arch}"))
- {
- auto nat32Classifier = nativeClassifier;
- nat32Classifier.replace("${arch}", "32");
- auto nat64Classifier = nativeClassifier;
- nat64Classifier.replace("${arch}", "64");
- auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
- if(nat32info)
- native32 += actualPath(nat32info->path);
- auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
- if(nat64info)
- native64 += actualPath(nat64info->path);
- }
- else
- {
- native += actualPath(m_mojangDownloads->getDownloadInfo(nativeClassifier)->path);
- }
- }
- }
- else
- {
- QString raw_storage = storageSuffix(system);
- if(isNative())
- {
- if (raw_storage.contains("${arch}"))
- {
- auto nat32Storage = raw_storage;
- nat32Storage.replace("${arch}", "32");
- auto nat64Storage = raw_storage;
- nat64Storage.replace("${arch}", "64");
- native32 += actualPath(nat32Storage);
- native64 += actualPath(nat64Storage);
- }
- else
- {
- native += actualPath(raw_storage);
- }
- }
- else
- {
- jar += actualPath(raw_storage);
- }
- }
-}
-
-QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, QStringList &failedFiles) const
-{
- QList<NetActionPtr> out;
- bool isLocal = (hint() == "local");
- bool isForge = (hint() == "forge-pack-xz");
-
- auto add_download = [&](QString storage, QString dl)
- {
- auto entry = cache->resolveEntry("libraries", storage);
- if (!entry->isStale())
- return true;
- if(isLocal)
- {
- QFileInfo fileinfo(entry->getFullPath());
- if(!fileinfo.exists())
- {
- failedFiles.append(entry->getFullPath());
- return false;
- }
- return true;
- }
- if (isForge)
- {
- out.append(ForgeXzDownload::make(storage, entry));
- }
- else
- {
- out.append(CacheDownload::make(dl, entry));
- }
- return true;
- };
-
- if(m_mojangDownloads)
- {
- if(m_mojangDownloads->artifact)
- {
- auto artifact = m_mojangDownloads->artifact;
- add_download(artifact->path, artifact->url);
- }
- if(m_nativeClassifiers.contains(system))
- {
- auto nativeClassifier = m_nativeClassifiers[system];
- if(nativeClassifier.contains("${arch}"))
- {
- auto nat32Classifier = nativeClassifier;
- nat32Classifier.replace("${arch}", "32");
- auto nat64Classifier = nativeClassifier;
- nat64Classifier.replace("${arch}", "64");
- auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
- if(nat32info)
- add_download(nat32info->path, nat32info->url);
- auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
- if(nat64info)
- add_download(nat64info->path, nat64info->url);
- }
- else
- {
- auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier);
- if(info)
- {
- add_download(info->path, info->url);
- }
- }
- }
- }
- else
- {
- QString raw_storage = storageSuffix(system);
- auto raw_dl = [&](){
- if (!m_absoluteURL.isEmpty())
- {
- return m_absoluteURL;
- }
-
- if (m_repositoryURL.isEmpty())
- {
- return QString("https://" + URLConstants::LIBRARY_BASE) + raw_storage;
- }
-
- if(m_repositoryURL.endsWith('/'))
- {
- return m_repositoryURL + raw_storage;
- }
- else
- {
- return m_repositoryURL + QChar('/') + raw_storage;
- }
- }();
- if (raw_storage.contains("${arch}"))
- {
- QString cooked_storage = raw_storage;
- QString cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"));
- cooked_storage = raw_storage;
- cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"));
- }
- else
- {
- add_download(raw_storage, raw_dl);
- }
- }
- return out;
-}
-
-bool Library::isActive() const
-{
- bool result = true;
- if (m_rules.empty())
- {
- result = true;
- }
- else
- {
- RuleAction ruleResult = Disallow;
- for (auto rule : m_rules)
- {
- RuleAction temp = rule->apply(this);
- if (temp != Defer)
- ruleResult = temp;
- }
- result = result && (ruleResult == Allow);
- }
- if (isNative())
- {
- result = result && m_nativeClassifiers.contains(currentSystem);
- }
- return result;
-}
-
-void Library::setStoragePrefix(QString prefix)
-{
- m_storagePrefix = prefix;
-}
-
-QString Library::defaultStoragePrefix()
-{
- return "libraries/";
-}
-
-QString Library::storagePrefix() const
-{
- if(m_storagePrefix.isEmpty())
- {
- return defaultStoragePrefix();
- }
- return m_storagePrefix;
-}
-
-QString Library::storageSuffix(OpSys system) const
-{
- // non-native? use only the gradle specifier
- if (!isNative())
- {
- return m_name.toPath();
- }
-
- // otherwise native, override classifiers. Mojang HACK!
- GradleSpecifier nativeSpec = m_name;
- if (m_nativeClassifiers.contains(system))
- {
- nativeSpec.setClassifier(m_nativeClassifiers[system]);
- }
- else
- {
- nativeSpec.setClassifier("INVALID");
- }
- return nativeSpec.toPath();
-}
diff --git a/libraries/logic/minecraft/Library.h b/libraries/logic/minecraft/Library.h
deleted file mode 100644
index fdce93f3..00000000
--- a/libraries/logic/minecraft/Library.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#pragma once
-#include <QString>
-#include <net/NetAction.h>
-#include <QPair>
-#include <QList>
-#include <QStringList>
-#include <QMap>
-#include <QDir>
-#include <QUrl>
-#include <memory>
-
-#include "Rule.h"
-#include "minecraft/OpSys.h"
-#include "GradleSpecifier.h"
-#include "net/URLConstants.h"
-#include "MojangDownloadInfo.h"
-
-#include "multimc_logic_export.h"
-
-class Library;
-
-typedef std::shared_ptr<Library> LibraryPtr;
-
-class MULTIMC_LOGIC_EXPORT Library
-{
- friend class OneSixVersionFormat;
- friend class MojangVersionFormat;
- friend class LibraryTest;
-public:
- Library()
- {
- }
- Library(const QString &name)
- {
- m_name = name;
- }
- /// limited copy without some data. TODO: why?
- static LibraryPtr limitedCopy(LibraryPtr base)
- {
- auto newlib = std::make_shared<Library>();
- newlib->m_name = base->m_name;
- newlib->m_repositoryURL = base->m_repositoryURL;
- newlib->m_hint = base->m_hint;
- newlib->m_absoluteURL = base->m_absoluteURL;
- newlib->m_extractExcludes = base->m_extractExcludes;
- newlib->m_nativeClassifiers = base->m_nativeClassifiers;
- newlib->m_rules = base->m_rules;
- newlib->m_storagePrefix = base->m_storagePrefix;
- newlib->m_mojangDownloads = base->m_mojangDownloads;
- return newlib;
- }
-
-public: /* methods */
- /// Returns the raw name field
- const GradleSpecifier & rawName() const
- {
- return m_name;
- }
-
- void setRawName(const GradleSpecifier & spec)
- {
- m_name = spec;
- }
-
- void setClassifier(const QString & spec)
- {
- m_name.setClassifier(spec);
- }
-
- /// returns the full group and artifact prefix
- QString artifactPrefix() const
- {
- return m_name.artifactPrefix();
- }
-
- /// get the artifact ID
- QString artifactId() const
- {
- return m_name.artifactId();
- }
-
- /// get the artifact version
- QString version() const
- {
- return m_name.version();
- }
-
- /// Returns true if the library is native
- bool isNative() const
- {
- return m_nativeClassifiers.size() != 0;
- }
-
- void setStoragePrefix(QString prefix = QString());
-
- /// Set the url base for downloads
- void setRepositoryURL(const QString &base_url)
- {
- m_repositoryURL = base_url;
- }
-
- void getApplicableFiles(OpSys system, QStringList & jar, QStringList & native, QStringList & native32, QStringList & native64) const;
-
- void setAbsoluteUrl(const QString &absolute_url)
- {
- m_absoluteURL = absolute_url;
- }
-
- void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info)
- {
- m_mojangDownloads = info;
- }
-
- void setHint(const QString &hint)
- {
- m_hint = hint;
- }
-
- /// Set the load rules
- void setRules(QList<std::shared_ptr<Rule>> rules)
- {
- m_rules = rules;
- }
-
- /// Returns true if the library should be loaded (or extracted, in case of natives)
- bool isActive() const;
-
- // Get a list of downloads for this library
- QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache, QStringList &failedFiles) const;
-
-private: /* methods */
- /// the default storage prefix used by MultiMC
- static QString defaultStoragePrefix();
-
- /// Get the prefix - root of the storage to be used
- QString storagePrefix() const;
-
- /// Get the relative path where the library should be saved
- QString storageSuffix(OpSys system) const;
-
- QString hint() const
- {
- return m_hint;
- }
-
-protected: /* data */
- /// the basic gradle dependency specifier.
- GradleSpecifier m_name;
-
- /// DEPRECATED URL prefix of the maven repo where the file can be downloaded
- QString m_repositoryURL;
-
- /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined
- QString m_absoluteURL;
-
- /**
- * MultiMC-specific type hint - modifies how the library is treated
- */
- QString m_hint;
-
- /**
- * storage - by default the local libraries folder in multimc, but could be elsewhere
- * MultiMC specific, because of FTB.
- */
- QString m_storagePrefix;
-
- /// true if the library had an extract/excludes section (even empty)
- bool m_hasExcludes = false;
-
- /// a list of files that shouldn't be extracted from the library
- QStringList m_extractExcludes;
-
- /// native suffixes per OS
- QMap<OpSys, QString> m_nativeClassifiers;
-
- /// true if the library had a rules section (even empty)
- bool applyRules = false;
-
- /// rules associated with the library
- QList<std::shared_ptr<Rule>> m_rules;
-
- /// MOJANG: container with Mojang style download info
- MojangLibraryDownloadInfo::Ptr m_mojangDownloads;
-};
diff --git a/libraries/logic/minecraft/MinecraftInstance.cpp b/libraries/logic/minecraft/MinecraftInstance.cpp
deleted file mode 100644
index 405ccd26..00000000
--- a/libraries/logic/minecraft/MinecraftInstance.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-#include "MinecraftInstance.h"
-#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>
-#include <FileSystem.h>
-#include <java/JavaVersion.h>
-
-#define IBUS "@im=ibus"
-
-// all of this because keeping things compatible with deprecated old settings
-// if either of the settings {a, b} is true, this also resolves to true
-class OrSetting : public Setting
-{
- Q_OBJECT
-public:
- OrSetting(QString id, std::shared_ptr<Setting> a, std::shared_ptr<Setting> b)
- :Setting({id}, false), m_a(a), m_b(b)
- {
- }
- virtual QVariant get() const
- {
- bool a = m_a->get().toBool();
- bool b = m_b->get().toBool();
- return a || b;
- }
- virtual void reset() {}
- virtual void set(QVariant value) {}
-private:
- std::shared_ptr<Setting> m_a;
- std::shared_ptr<Setting> m_b;
-};
-
-MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : BaseInstance(globalSettings, settings, rootDir)
-{
- // Java Settings
- auto javaOverride = m_settings->registerSetting("OverrideJava", false);
- auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false);
- auto argsOverride = m_settings->registerSetting("OverrideJavaArgs", false);
-
- // combinations
- auto javaOrLocation = std::make_shared<OrSetting>("JavaOrLocationOverride", javaOverride, locationOverride);
- auto javaOrArgs = std::make_shared<OrSetting>("JavaOrArgsOverride", javaOverride, argsOverride);
-
- m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
- m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
-
- // special!
- m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
- m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
-
- // Window Size
- auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
- m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight"), windowSetting);
-
- // Memory
- auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
- m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
-}
-
-QString MinecraftInstance::minecraftRoot() const
-{
- QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
- QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
-
- if (dotMCDir.exists() && !mcDir.exists())
- return dotMCDir.filePath();
- else
- return mcDir.filePath();
-}
-
-std::shared_ptr< BaseVersionList > MinecraftInstance::versionList() const
-{
- return ENV.getVersionList("net.minecraft");
-}
-
-QStringList MinecraftInstance::javaArguments() const
-{
- QStringList args;
-
- // custom args go first. we want to override them if we have our own here.
- args.append(extraArguments());
-
- // OSX dock icon and name
-#ifdef Q_OS_MAC
- args << "-Xdock:icon=icon.png";
- args << QString("-Xdock:name=\"%1\"").arg(windowTitle());
-#endif
-
- // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767
-#ifdef Q_OS_WIN32
- args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
- "minecraft.exe.heapdump");
-#endif
-
- args << QString("-Xms%1m").arg(settings()->get("MinMemAlloc").toInt());
- args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt());
-
- // No PermGen in newer java.
- JavaVersion javaVersion(settings()->get("JavaVersion").toString());
- if(javaVersion.requiresPermGen())
- {
- auto permgen = settings()->get("PermGen").toInt();
- if (permgen != 64)
- {
- args << QString("-XX:PermSize=%1m").arg(permgen);
- }
- }
-
- args << "-Duser.language=en";
- args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
-
- return args;
-}
-
-QMap<QString, QString> MinecraftInstance::getVariables() const
-{
- QMap<QString, QString> out;
- out.insert("INST_NAME", name());
- out.insert("INST_ID", id());
- out.insert("INST_DIR", QDir(instanceRoot()).absolutePath());
- out.insert("INST_MC_DIR", QDir(minecraftRoot()).absolutePath());
- out.insert("INST_JAVA", settings()->get("JavaPath").toString());
- out.insert("INST_JAVA_ARGS", javaArguments().join(' '));
- return out;
-}
-
-static QString processLD_LIBRARY_PATH(const QString & LD_LIBRARY_PATH)
-{
- QDir mmcBin(QCoreApplication::applicationDirPath());
- auto items = LD_LIBRARY_PATH.split(':');
- QStringList final;
- for(auto & item: items)
- {
- QDir test(item);
- if(test == mmcBin)
- {
- qDebug() << "Env:LD_LIBRARY_PATH ignoring path" << item;
- continue;
- }
- final.append(item);
- }
- return final.join(':');
-}
-
-QProcessEnvironment MinecraftInstance::createEnvironment()
-{
- // prepare the process environment
- QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
- QProcessEnvironment env;
-
- QStringList ignored =
- {
- "JAVA_ARGS",
- "CLASSPATH",
- "CONFIGPATH",
- "JAVA_HOME",
- "JRE_HOME",
- "_JAVA_OPTIONS",
- "JAVA_OPTIONS",
- "JAVA_TOOL_OPTIONS"
- };
- for(auto key: rawenv.keys())
- {
- auto value = rawenv.value(key);
- // filter out dangerous java crap
- if(ignored.contains(key))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // filter MultiMC-related things
- if(key.startsWith("QT_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
-#ifdef Q_OS_LINUX
- // Do not pass LD_* variables to java. They were intended for MultiMC
- if(key.startsWith("LD_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // Strip IBus
- // IBus is a Linux IME framework. For some reason, it breaks MC?
- if (key == "XMODIFIERS" && value.contains(IBUS))
- {
- QString save = value;
- value.replace(IBUS, "");
- qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
- }
- if(key == "GAME_PRELOAD")
- {
- env.insert("LD_PRELOAD", value);
- continue;
- }
- if(key == "GAME_LIBRARY_PATH")
- {
- env.insert("LD_LIBRARY_PATH", processLD_LIBRARY_PATH(value));
- continue;
- }
-#endif
- qDebug() << "Env: " << key << value;
- env.insert(key, value);
- }
-#ifdef Q_OS_LINUX
- // HACK: Workaround for QTBUG42500
- if(!env.contains("LD_LIBRARY_PATH"))
- {
- env.insert("LD_LIBRARY_PATH", "");
- }
-#endif
-
- // export some infos
- auto variables = getVariables();
- for (auto it = variables.begin(); it != variables.end(); ++it)
- {
- env.insert(it.key(), it.value());
- }
- return env;
-}
-
-QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSessionPtr session)
-{
- if(!session)
- {
- return QMap<QString, QString>();
- }
- auto & sessionRef = *session.get();
- QMap<QString, QString> filter;
- auto addToFilter = [&filter](QString key, QString value)
- {
- if(key.trimmed().size())
- {
- filter[key] = value;
- }
- };
- if (sessionRef.session != "-")
- {
- addToFilter(sessionRef.session, tr("<SESSION ID>"));
- }
- addToFilter(sessionRef.access_token, tr("<ACCESS TOKEN>"));
- addToFilter(sessionRef.client_token, tr("<CLIENT TOKEN>"));
- addToFilter(sessionRef.uuid, tr("<PROFILE ID>"));
- addToFilter(sessionRef.player_name, tr("<PROFILE NAME>"));
-
- auto i = sessionRef.u.properties.begin();
- while (i != sessionRef.u.properties.end())
- {
- addToFilter(i.value(), "<" + i.key().toUpper() + ">");
- ++i;
- }
- return filter;
-}
-
-MessageLevel::Enum MinecraftInstance::guessLevel(const QString &line, MessageLevel::Enum level)
-{
- QRegularExpression re("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
- auto match = re.match(line);
- if(match.hasMatch())
- {
- // New style logs from log4j
- QString timestamp = match.captured("timestamp");
- QString levelStr = match.captured("level");
- if(levelStr == "INFO")
- level = MessageLevel::Message;
- if(levelStr == "WARN")
- level = MessageLevel::Warning;
- if(levelStr == "ERROR")
- level = MessageLevel::Error;
- if(levelStr == "FATAL")
- level = MessageLevel::Fatal;
- if(levelStr == "TRACE" || levelStr == "DEBUG")
- level = MessageLevel::Debug;
- }
- else
- {
- // Old style forge logs
- if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
- line.contains("[FINER]") || line.contains("[FINEST]"))
- level = MessageLevel::Message;
- if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
- level = MessageLevel::Error;
- if (line.contains("[WARNING]"))
- level = MessageLevel::Warning;
- if (line.contains("[DEBUG]"))
- level = MessageLevel::Debug;
- }
- if (line.contains("overwriting existing"))
- return MessageLevel::Fatal;
- //NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
- static const QString javaSymbol = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
- if (line.contains("Exception in thread")
- || line.contains(QRegularExpression("\\s+at " + javaSymbol))
- || line.contains(QRegularExpression("Caused by: " + javaSymbol))
- || line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)"))
- || line.contains(QRegularExpression("... \\d+ more$"))
- )
- return MessageLevel::Error;
- return level;
-}
-
-IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher()
-{
- auto combined = std::make_shared<MultiMatcher>();
- combined->add(std::make_shared<RegexpMatcher>(".*\\.log(\\.[0-9]*)?(\\.gz)?$"));
- combined->add(std::make_shared<RegexpMatcher>("crash-.*\\.txt"));
- combined->add(std::make_shared<RegexpMatcher>("IDMap dump.*\\.txt$"));
- combined->add(std::make_shared<RegexpMatcher>("ModLoader\\.txt(\\..*)?$"));
- return combined;
-}
-
-QString MinecraftInstance::getLogFileRoot()
-{
- return minecraftRoot();
-}
-
-QString MinecraftInstance::prettifyTimeDuration(int64_t duration)
-{
- int seconds = (int) (duration % 60);
- duration /= 60;
- int minutes = (int) (duration % 60);
- duration /= 60;
- int hours = (int) (duration % 24);
- int days = (int) (duration / 24);
- if((hours == 0)&&(days == 0))
- {
- return tr("%1m %2s").arg(minutes).arg(seconds);
- }
- if (days == 0)
- {
- return tr("%1h %2m").arg(hours).arg(minutes);
- }
- return tr("%1d %2h %3m").arg(days).arg(hours).arg(minutes);
-}
-
-QString MinecraftInstance::getStatusbarDescription()
-{
- QStringList traits;
- if (flags() & VersionBrokenFlag)
- {
- traits.append(tr("broken"));
- }
-
- QString description;
- description.append(tr("Minecraft %1 (%2)").arg(intendedVersionId()).arg(typeName()));
- if(totalTimePlayed() > 0)
- {
- description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
- }
- /*
- if(traits.size())
- {
- description.append(QString(" (%1)").arg(traits.join(", ")));
- }
- */
- return description;
-}
-
-#include "MinecraftInstance.moc"
diff --git a/libraries/logic/minecraft/MinecraftInstance.h b/libraries/logic/minecraft/MinecraftInstance.h
deleted file mode 100644
index cd3a8d90..00000000
--- a/libraries/logic/minecraft/MinecraftInstance.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-#include "BaseInstance.h"
-#include "minecraft/Mod.h"
-#include <QProcess>
-
-#include "multimc_logic_export.h"
-
-class ModList;
-class WorldList;
-
-class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
-{
-public:
- MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~MinecraftInstance() {};
-
- /// Path to the instance's minecraft directory.
- QString minecraftRoot() const;
-
- ////// Mod Lists //////
- virtual std::shared_ptr<ModList> resourcePackList() const
- {
- return nullptr;
- }
- virtual std::shared_ptr<ModList> texturePackList() const
- {
- return nullptr;
- }
- virtual std::shared_ptr<WorldList> worldList() const
- {
- return nullptr;
- }
- /// get all jar mods applicable to this instance's jar
- virtual QList<Mod> getJarMods() const
- {
- return QList<Mod>();
- }
-
- /// get the launch script to be used with this
- virtual QString createLaunchScript(AuthSessionPtr session) = 0;
-
- //FIXME: nuke?
- virtual std::shared_ptr<BaseVersionList> versionList() const override;
-
- /// get arguments passed to java
- QStringList javaArguments() const;
-
- /// get variables for launch command variable substitution/environment
- virtual QMap<QString, QString> getVariables() const override;
-
- /// create an environment for launching processes
- virtual QProcessEnvironment createEnvironment() override;
-
- /// guess log level from a line of minecraft log
- virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level) override;
-
- virtual IPathMatcher::Ptr getLogFileMatcher() override;
-
- virtual QString getLogFileRoot() override;
-
- virtual QString getStatusbarDescription() override;
-
-protected:
- QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
-private:
- QString prettifyTimeDuration(int64_t duration);
-};
-
-typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;
diff --git a/libraries/logic/minecraft/MinecraftProfile.cpp b/libraries/logic/minecraft/MinecraftProfile.cpp
deleted file mode 100644
index 70d0cee4..00000000
--- a/libraries/logic/minecraft/MinecraftProfile.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-/* Copyright 2013-2015 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 <QFile>
-#include <QCryptographicHash>
-#include <Version.h>
-#include <QDir>
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QDebug>
-
-#include "minecraft/MinecraftProfile.h"
-#include "ProfileUtils.h"
-#include "ProfileStrategy.h"
-#include "Exception.h"
-
-MinecraftProfile::MinecraftProfile(ProfileStrategy *strategy)
- : QAbstractListModel()
-{
- setStrategy(strategy);
- clear();
-}
-
-void MinecraftProfile::setStrategy(ProfileStrategy* strategy)
-{
- Q_ASSERT(strategy != nullptr);
-
- if(m_strategy != nullptr)
- {
- delete m_strategy;
- m_strategy = nullptr;
- }
- m_strategy = strategy;
- m_strategy->profile = this;
-}
-
-ProfileStrategy* MinecraftProfile::strategy()
-{
- return m_strategy;
-}
-
-void MinecraftProfile::reload()
-{
- beginResetModel();
- m_strategy->load();
- reapplyPatches();
- endResetModel();
-}
-
-void MinecraftProfile::clear()
-{
- m_minecraftVersion.clear();
- m_minecraftVersionType.clear();
- m_minecraftAssets.reset();
- m_minecraftArguments.clear();
- m_tweakers.clear();
- m_mainClass.clear();
- m_appletClass.clear();
- m_libraries.clear();
- m_traits.clear();
- m_jarMods.clear();
- mojangDownloads.clear();
- m_problemSeverity = ProblemSeverity::PROBLEM_NONE;
-}
-
-void MinecraftProfile::clearPatches()
-{
- beginResetModel();
- m_patches.clear();
- endResetModel();
-}
-
-void MinecraftProfile::appendPatch(ProfilePatchPtr patch)
-{
- int index = m_patches.size();
- beginInsertRows(QModelIndex(), index, index);
- m_patches.append(patch);
- endInsertRows();
-}
-
-bool MinecraftProfile::remove(const int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRemovable())
- {
- qDebug() << "Patch" << patch->getID() << "is non-removable";
- return false;
- }
-
- if(!m_strategy->removePatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be removed";
- return false;
- }
-
- beginRemoveRows(QModelIndex(), index, index);
- m_patches.removeAt(index);
- endRemoveRows();
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-bool MinecraftProfile::remove(const QString id)
-{
- int i = 0;
- for (auto patch : m_patches)
- {
- if (patch->getID() == id)
- {
- return remove(i);
- }
- i++;
- }
- return false;
-}
-
-bool MinecraftProfile::customize(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isCustomizable())
- {
- qDebug() << "Patch" << patch->getID() << "is not customizable";
- return false;
- }
- if(!m_strategy->customizePatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be customized";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-bool MinecraftProfile::revertToBase(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRevertible())
- {
- qDebug() << "Patch" << patch->getID() << "is not revertible";
- return false;
- }
- if(!m_strategy->revertPatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be reverted";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(const QString &id)
-{
- for (auto file : m_patches)
- {
- if (file->getID() == id)
- {
- return file;
- }
- }
- return nullptr;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(int index)
-{
- if(index < 0 || index >= m_patches.size())
- return nullptr;
- return m_patches[index];
-}
-
-bool MinecraftProfile::isVanilla()
-{
- for(auto patchptr: m_patches)
- {
- if(patchptr->isCustom())
- return false;
- }
- return true;
-}
-
-bool MinecraftProfile::revertToVanilla()
-{
- // remove patches, if present
- auto VersionPatchesCopy = m_patches;
- for(auto & it: VersionPatchesCopy)
- {
- if (!it->isCustom())
- {
- continue;
- }
- if(it->isRevertible() || it->isRemovable())
- {
- if(!remove(it->getID()))
- {
- qWarning() << "Couldn't remove" << it->getID() << "from profile!";
- reapplyPatches();
- saveCurrentOrder();
- return false;
- }
- }
- }
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-QVariant MinecraftProfile::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= m_patches.size())
- return QVariant();
-
- auto patch = m_patches.at(row);
-
- if (role == Qt::DisplayRole)
- {
- switch (column)
- {
- case 0:
- return m_patches.at(row)->getName();
- case 1:
- {
- if(patch->isCustom())
- {
- return QString("%1 (Custom)").arg(patch->getVersion());
- }
- else
- {
- return patch->getVersion();
- }
- }
- default:
- return QVariant();
- }
- }
- if(role == Qt::DecorationRole)
- {
- switch(column)
- {
- case 0:
- {
- auto severity = patch->getProblemSeverity();
- switch (severity)
- {
- case PROBLEM_WARNING:
- return "warning";
- case PROBLEM_ERROR:
- return "error";
- default:
- return QVariant();
- }
- }
- default:
- {
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-QVariant MinecraftProfile::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal)
- {
- if (role == Qt::DisplayRole)
- {
- switch (section)
- {
- case 0:
- return tr("Name");
- case 1:
- return tr("Version");
- default:
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-Qt::ItemFlags MinecraftProfile::flags(const QModelIndex &index) const
-{
- if (!index.isValid())
- return Qt::NoItemFlags;
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-}
-
-int MinecraftProfile::rowCount(const QModelIndex &parent) const
-{
- return m_patches.size();
-}
-
-int MinecraftProfile::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-void MinecraftProfile::saveCurrentOrder() const
-{
- ProfileUtils::PatchOrder order;
- for(auto item: m_patches)
- {
- if(!item->isMoveable())
- continue;
- order.append(item->getID());
- }
- m_strategy->saveOrder(order);
-}
-
-void MinecraftProfile::move(const int index, const MoveDirection direction)
-{
- int theirIndex;
- if (direction == MoveUp)
- {
- theirIndex = index - 1;
- }
- else
- {
- theirIndex = index + 1;
- }
-
- if (index < 0 || index >= m_patches.size())
- return;
- if (theirIndex >= rowCount())
- theirIndex = rowCount() - 1;
- if (theirIndex == -1)
- theirIndex = rowCount() - 1;
- if (index == theirIndex)
- return;
- int togap = theirIndex > index ? theirIndex + 1 : theirIndex;
-
- auto from = versionPatch(index);
- auto to = versionPatch(theirIndex);
-
- if (!from || !to || !to->isMoveable() || !from->isMoveable())
- {
- return;
- }
- beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
- m_patches.swap(index, theirIndex);
- endMoveRows();
- reapplyPatches();
- saveCurrentOrder();
-}
-void MinecraftProfile::resetOrder()
-{
- m_strategy->resetOrder();
- reload();
-}
-
-bool MinecraftProfile::reapplyPatches()
-{
- try
- {
- clear();
- for(auto file: m_patches)
- {
- file->applyTo(this);
- }
- }
- catch (Exception & error)
- {
- clear();
- qWarning() << "Couldn't apply profile patches because: " << error.cause();
- return false;
- }
- return true;
-}
-
-static void applyString(const QString & from, QString & to)
-{
- if(from.isEmpty())
- return;
- to = from;
-}
-
-void MinecraftProfile::applyMinecraftVersion(const QString& id)
-{
- applyString(id, this->m_minecraftVersion);
-}
-
-void MinecraftProfile::applyAppletClass(const QString& appletClass)
-{
- applyString(appletClass, this->m_appletClass);
-}
-
-void MinecraftProfile::applyMainClass(const QString& mainClass)
-{
- applyString(mainClass, this->m_mainClass);
-}
-
-void MinecraftProfile::applyMinecraftArguments(const QString& minecraftArguments)
-{
- applyString(minecraftArguments, this->m_minecraftArguments);
-}
-
-void MinecraftProfile::applyMinecraftVersionType(const QString& type)
-{
- applyString(type, this->m_minecraftVersionType);
-}
-
-void MinecraftProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets)
-{
- if(assets)
- {
- m_minecraftAssets = assets;
- }
-}
-
-void MinecraftProfile::applyMojangDownload(const QString &key, MojangDownloadInfo::Ptr download)
-{
- if(download)
- {
- mojangDownloads[key] = download;
- }
- else
- {
- mojangDownloads.remove(key);
- }
-}
-
-void MinecraftProfile::applyTraits(const QSet<QString>& traits)
-{
- this->m_traits.unite(traits);
-}
-
-void MinecraftProfile::applyTweakers(const QStringList& tweakers)
-{
- // FIXME: check for dupes?
- // FIXME: does order matter?
- for (auto tweaker : tweakers)
- {
- this->m_tweakers += tweaker;
- }
-}
-
-void MinecraftProfile::applyJarMods(const QList<JarmodPtr>& jarMods)
-{
- this->m_jarMods.append(jarMods);
-}
-
-static int findLibraryByName(QList<LibraryPtr> haystack, const GradleSpecifier &needle)
-{
- int retval = -1;
- for (int i = 0; i < haystack.size(); ++i)
- {
- if (haystack.at(i)->rawName().matchName(needle))
- {
- // only one is allowed.
- if (retval != -1)
- return -1;
- retval = i;
- }
- }
- return retval;
-}
-
-void MinecraftProfile::applyLibrary(LibraryPtr library)
-{
- if(!library->isActive())
- {
- return;
- }
- // find the library by name.
- const int index = findLibraryByName(m_libraries, library->rawName());
- // library not found? just add it.
- if (index < 0)
- {
- m_libraries.append(Library::limitedCopy(library));
- return;
- }
- auto existingLibrary = m_libraries.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);
- }
-}
-
-void MinecraftProfile::applyProblemSeverity(ProblemSeverity severity)
-{
- if (m_problemSeverity < severity)
- {
- m_problemSeverity = severity;
- }
-}
-
-
-QString MinecraftProfile::getMinecraftVersion() const
-{
- return m_minecraftVersion;
-}
-
-QString MinecraftProfile::getAppletClass() const
-{
- return m_appletClass;
-}
-
-QString MinecraftProfile::getMainClass() const
-{
- return m_mainClass;
-}
-
-const QSet<QString> &MinecraftProfile::getTraits() const
-{
- return m_traits;
-}
-
-const QStringList & MinecraftProfile::getTweakers() const
-{
- return m_tweakers;
-}
-
-bool MinecraftProfile::hasTrait(const QString& trait) const
-{
- return m_traits.contains(trait);
-}
-
-ProblemSeverity MinecraftProfile::getProblemSeverity() const
-{
- return m_problemSeverity;
-}
-
-QString MinecraftProfile::getMinecraftVersionType() const
-{
- return m_minecraftVersionType;
-}
-
-std::shared_ptr<MojangAssetIndexInfo> MinecraftProfile::getMinecraftAssets() const
-{
- if(!m_minecraftAssets)
- {
- return std::make_shared<MojangAssetIndexInfo>("legacy");
- }
- return m_minecraftAssets;
-}
-
-QString MinecraftProfile::getMinecraftArguments() const
-{
- return m_minecraftArguments;
-}
-
-const QList<JarmodPtr> & MinecraftProfile::getJarMods() const
-{
- return m_jarMods;
-}
-
-const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
-{
- return m_libraries;
-}
-
-QString MinecraftProfile::getMainJarUrl() const
-{
- auto iter = mojangDownloads.find("client");
- if(iter != mojangDownloads.end())
- {
- // current
- return iter.value()->url;
- }
- else
- {
- // legacy fallback
- return URLConstants::getLegacyJarUrl(getMinecraftVersion());
- }
-}
-
-void MinecraftProfile::installJarMods(QStringList selectedFiles)
-{
- m_strategy->installJarMods(selectedFiles);
-}
-
-/*
- * TODO: get rid of this. Get rid of all order numbers.
- */
-int MinecraftProfile::getFreeOrderNumber()
-{
- int largest = 100;
- // yes, I do realize this is dumb. The order thing itself is dumb. and to be removed next.
- for(auto thing: m_patches)
- {
- int order = thing->getOrder();
- if(order > largest)
- largest = order;
- }
- return largest + 1;
-}
diff --git a/libraries/logic/minecraft/MinecraftProfile.h b/libraries/logic/minecraft/MinecraftProfile.h
deleted file mode 100644
index ca9288ad..00000000
--- a/libraries/logic/minecraft/MinecraftProfile.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright 2013-2015 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 <QAbstractListModel>
-
-#include <QString>
-#include <QList>
-#include <memory>
-
-#include "Library.h"
-#include "VersionFile.h"
-#include "JarMod.h"
-#include "MojangDownloadInfo.h"
-
-#include "multimc_logic_export.h"
-
-class ProfileStrategy;
-class OneSixInstance;
-
-
-class MULTIMC_LOGIC_EXPORT MinecraftProfile : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- explicit MinecraftProfile(ProfileStrategy *strategy);
-
- void setStrategy(ProfileStrategy * strategy);
- ProfileStrategy *strategy();
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- virtual int columnCount(const QModelIndex &parent) const override;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
-
- /// is this version unchanged by the user?
- bool isVanilla();
-
- /// remove any customizations on top of whatever 'vanilla' means
- bool revertToVanilla();
-
- /// install more jar mods
- void installJarMods(QStringList selectedFiles);
-
- /// DEPRECATED, remove ASAP
- int getFreeOrderNumber();
-
- enum MoveDirection { MoveUp, MoveDown };
- /// move patch file # up or down the list
- void move(const int index, const MoveDirection direction);
-
- /// remove patch file # - including files/records
- bool remove(const int index);
-
- /// remove patch file by id - including files/records
- bool remove(const QString id);
-
- bool customize(int index);
-
- bool revertToBase(int index);
-
- void resetOrder();
-
- /// reload all profile patches from storage, clear the profile and apply the patches
- void reload();
-
- /// clear the profile
- void clear();
-
- /// apply the patches. Catches all the errors and returns true/false for success/failure
- bool reapplyPatches();
-
-public: /* application of profile variables from patches */
- void applyMinecraftVersion(const QString& id);
- void applyMainClass(const QString& mainClass);
- void applyAppletClass(const QString& appletClass);
- void applyMinecraftArguments(const QString& minecraftArguments);
- void applyMinecraftVersionType(const QString& type);
- void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
- void applyTraits(const QSet<QString> &traits);
- void applyTweakers(const QStringList &tweakers);
- void applyJarMods(const QList<JarmodPtr> &jarMods);
- void applyLibrary(LibraryPtr library);
- void applyProblemSeverity(ProblemSeverity severity);
- void applyMojangDownload(const QString & key, MojangDownloadInfo::Ptr download);
-
-public: /* getters for profile variables */
- QString getMinecraftVersion() const;
- QString getMainClass() const;
- QString getAppletClass() const;
- QString getMinecraftVersionType() const;
- MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
- QString getMinecraftArguments() const;
- const QSet<QString> & getTraits() const;
- const QStringList & getTweakers() const;
- const QList<JarmodPtr> & getJarMods() const;
- const QList<LibraryPtr> & getLibraries() const;
- QString getMainJarUrl() const;
- bool hasTrait(const QString & trait) const;
- ProblemSeverity getProblemSeverity() const;
-
-public:
- /// get the profile patch by id
- ProfilePatchPtr versionPatch(const QString &id);
-
- /// get the profile patch by index
- ProfilePatchPtr versionPatch(int index);
-
- /// save the current patch order
- void saveCurrentOrder() const;
-
- /// Remove all the patches
- void clearPatches();
-
- /// Add the patch object to the internal list of patches
- void appendPatch(ProfilePatchPtr patch);
-
-private: /* data */
- /// the version of Minecraft - jar to use
- QString m_minecraftVersion;
-
- /// Release type - "release" or "snapshot"
- QString m_minecraftVersionType;
-
- /// Assets type - "legacy" or a version ID
- MojangAssetIndexInfo::Ptr m_minecraftAssets;
-
- // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more.
- QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
-
- /**
- * arguments that should be used for launching minecraft
- *
- * ex: "--username ${auth_player_name} --session ${auth_session}
- * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}"
- */
- QString m_minecraftArguments;
-
- /// A list of all tweaker classes
- QStringList m_tweakers;
-
- /// The main class to load first
- QString m_mainClass;
-
- /// The applet class, for some very old minecraft releases
- QString m_appletClass;
-
- /// the list of libraries
- QList<LibraryPtr> m_libraries;
-
- /// 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;
-
- /*
- FIXME: add support for those rules here? Looks like a pile of quick hacks to me though.
-
- "rules": [
- {
- "action": "allow"
- },
- {
- "action": "disallow",
- "os": {
- "name": "osx",
- "version": "^10\\.5\\.\\d$"
- }
- }
- ],
- "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX
- 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!"
- }
- */
- // QList<Rule> rules;
-
- /// list of attached profile patches
- QList<ProfilePatchPtr> m_patches;
-
- /// strategy used for profile operations
- ProfileStrategy *m_strategy = nullptr;
-};
diff --git a/libraries/logic/minecraft/MinecraftVersion.cpp b/libraries/logic/minecraft/MinecraftVersion.cpp
deleted file mode 100644
index 1e1d273c..00000000
--- a/libraries/logic/minecraft/MinecraftVersion.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "MinecraftVersion.h"
-#include "MinecraftProfile.h"
-#include "VersionBuildError.h"
-#include "ProfileUtils.h"
-#include "settings/SettingsObject.h"
-#include "minecraft/VersionFilterData.h"
-
-bool MinecraftVersion::usesLegacyLauncher()
-{
- return getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate;
-}
-
-
-QString MinecraftVersion::descriptor()
-{
- return m_version;
-}
-
-QString MinecraftVersion::name()
-{
- return m_version;
-}
-
-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 == Local && getVersionFile())
- {
- getVersionFile()->applyTo(profile);
- }
- else
- {
- throw VersionIncomplete(QObject::tr("Can't apply incomplete/builtin Minecraft version %1").arg(m_version));
- }
-}
-
-QString MinecraftVersion::getUrl() const
-{
- // legacy fallback
- if(m_versionFileURL.isEmpty())
- {
- return QString("http://") + URLConstants::AWS_DOWNLOAD_VERSIONS + m_version + "/" + m_version + ".json";
- }
- // current
- return m_versionFileURL;
-}
-
-VersionFilePtr MinecraftVersion::getVersionFile()
-{
- QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_version));
- m_problems.clear();
- 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 Local:
- case Remote:
- // locally cached file, or a remote file that we can acquire can be customized
- return true;
- default:
- // Everything else is undefined and therefore not customizable.
- return false;
- }
- return false;
-}
-
-const QList<PatchProblem> &MinecraftVersion::getProblems()
-{
- if(getVersionFile())
- {
- return getVersionFile()->getProblems();
- }
- return ProfilePatch::getProblems();
-}
-
-ProblemSeverity MinecraftVersion::getProblemSeverity()
-{
- if(getVersionFile())
- {
- return getVersionFile()->getProblemSeverity();
- }
- return ProfilePatch::getProblemSeverity();
-}
-
-void MinecraftVersion::applyTo(MinecraftProfile *profile)
-{
- // do we have this one cached?
- if (m_versionSource == Local)
- {
- applyFileTo(profile);
- return;
- }
- throw VersionIncomplete(QObject::tr("Minecraft version %1 could not be applied: version files are missing.").arg(m_version));
-}
-
-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_version;
-}
-QString MinecraftVersion::getID()
-{
- return "net.minecraft";
-}
-QString MinecraftVersion::getFilename()
-{
- return QString();
-}
-QDateTime MinecraftVersion::getReleaseDateTime()
-{
- return m_releaseTime;
-}
-
-
-bool MinecraftVersion::needsUpdate()
-{
- return m_versionSource == Remote || hasUpdate();
-}
-
-bool MinecraftVersion::hasUpdate()
-{
- return m_versionSource == Remote || (m_versionSource == Local && upstreamUpdate);
-}
-
-bool MinecraftVersion::isCustom()
-{
- // if we add any other source types, this will evaluate to false for them.
- return m_versionSource != Local && m_versionSource != Remote;
-}
diff --git a/libraries/logic/minecraft/MinecraftVersion.h b/libraries/logic/minecraft/MinecraftVersion.h
deleted file mode 100644
index b21427d9..00000000
--- a/libraries/logic/minecraft/MinecraftVersion.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2015 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 */
- // FIXME: nuke this.
- 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 = Remote;
-
- /// The URL that this version will be downloaded from.
- QString m_versionFileURL;
-
- /// the human readable version name
- QString m_version;
-
- /// 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;
-
- /// 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/libraries/logic/minecraft/MinecraftVersionList.cpp b/libraries/logic/minecraft/MinecraftVersionList.cpp
deleted file mode 100644
index a5cc3a39..00000000
--- a/libraries/logic/minecraft/MinecraftVersionList.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-/* Copyright 2013-2015 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;
-
-protected
-slots:
- void json_downloaded();
-
-protected:
- NetJobPtr specificVersionDownloadJob;
- std::shared_ptr<MinecraftVersion> updatedVersion;
- MinecraftVersionList *m_list;
-};
-
-class ListLoadError : public Exception
-{
-public:
- ListLoadError(QString cause) : Exception(cause) {};
- virtual ~ListLoadError() noexcept
- {
- }
-};
-
-MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent)
-{
- 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."));
- }
- loadList(jsonDoc, 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::loadList(QJsonDocument jsonDoc, VersionSource source)
-{
- qDebug() << "Loading" << ((source == 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_version = versionID;
-
- mcVersion->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString(""));
- mcVersion->m_updateTime = timeFromS3Time(versionObj.value("time").toString(""));
-
- // 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 == Remote) ? "remote" : "local") << "version list.";
- tempList.append(mcVersion);
- }
- updateListData(tempList);
- if(source == 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 != Local || added->m_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..."));
- auto worker = ENV.qnam();
- vlistReply = worker->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->loadList(jsonDoc, 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()
-{
- auto job = new NetJob("Version index");
- job->addNetAction(ByteArrayDownload::make(QUrl(updatedVersion->getUrl())));
- 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();
-}
-
-void MCVListVersionUpdateTask::json_downloaded()
-{
- NetActionPtr DlJob = specificVersionDownloadJob->first();
- auto data = std::dynamic_pointer_cast<ByteArrayDownload>(DlJob)->m_data;
- specificVersionDownloadJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- 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);
-
- 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 != 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]);
-
- // if we have an update for the version, replace it, make the update local
- if (updatedVersion->upstreamUpdate)
- {
- auto updatedWith = updatedVersion->upstreamUpdate;
- updatedWith->m_versionSource = Local;
- m_vlist[idx] = updatedWith;
- m_lookup[version] = updatedWith;
- }
- else
- {
- // otherwise, just set the version as local;
- updatedVersion->m_versionSource = Local;
- }
-
- dataChanged(index(idx), index(idx));
-
- saveCachedList();
-}
-
-#include "MinecraftVersionList.moc"
diff --git a/libraries/logic/minecraft/MinecraftVersionList.h b/libraries/logic/minecraft/MinecraftVersionList.h
deleted file mode 100644
index 0fca02a7..00000000
--- a/libraries/logic/minecraft/MinecraftVersionList.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright 2013-2015 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 loadList(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/libraries/logic/minecraft/Mod.cpp b/libraries/logic/minecraft/Mod.cpp
deleted file mode 100644
index 9b9f76f9..00000000
--- a/libraries/logic/minecraft/Mod.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <QDir>
-#include <QString>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <quazip.h>
-#include <quazipfile.h>
-
-#include "Mod.h"
-#include "settings/INIFile.h"
-#include <FileSystem.h>
-#include <QDebug>
-
-Mod::Mod(const QFileInfo &file)
-{
- repath(file);
-}
-
-void Mod::repath(const QFileInfo &file)
-{
- m_file = file;
- QString name_base = file.fileName();
-
- m_type = Mod::MOD_UNKNOWN;
-
- if (m_file.isDir())
- {
- m_type = MOD_FOLDER;
- m_name = name_base;
- m_mmc_id = name_base;
- }
- else if (m_file.isFile())
- {
- if (name_base.endsWith(".disabled"))
- {
- m_enabled = false;
- name_base.chop(9);
- }
- else
- {
- m_enabled = true;
- }
- m_mmc_id = name_base;
- if (name_base.endsWith(".zip") || name_base.endsWith(".jar"))
- {
- m_type = MOD_ZIPFILE;
- name_base.chop(4);
- }
- else if (name_base.endsWith(".litemod"))
- {
- m_type = MOD_LITEMOD;
- name_base.chop(8);
- }
- else
- {
- m_type = MOD_SINGLEFILE;
- }
- m_name = name_base;
- }
-
- if (m_type == MOD_ZIPFILE)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- if (zip.setCurrentFile("mcmod.info"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadMCModInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
- else if (zip.setCurrentFile("forgeversion.properties"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadForgeInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
-
- zip.close();
- }
- else if (m_type == MOD_FOLDER)
- {
- QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
- if (mcmod_info.isFile())
- {
- QFile mcmod(mcmod_info.filePath());
- if (!mcmod.open(QIODevice::ReadOnly))
- return;
- auto data = mcmod.readAll();
- if (data.isEmpty() || data.isNull())
- return;
- ReadMCModInfo(data);
- }
- }
- else if (m_type == MOD_LITEMOD)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- if (zip.setCurrentFile("litemod.json"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadLiteModInfo(file.readAll());
- file.close();
- }
- zip.close();
- }
-}
-
-// NEW format
-// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3
-
-// OLD format:
-// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
-void Mod::ReadMCModInfo(QByteArray contents)
-{
- auto getInfoFromArray = [&](QJsonArray arr)->void
- {
- if (!arr.at(0).isObject())
- return;
- auto firstObj = arr.at(0).toObject();
- m_mod_id = firstObj.value("modid").toString();
- m_name = firstObj.value("name").toString();
- m_version = firstObj.value("version").toString();
- m_homeurl = firstObj.value("url").toString();
- m_updateurl = firstObj.value("updateUrl").toString();
- m_homeurl = m_homeurl.trimmed();
- if(!m_homeurl.isEmpty())
- {
- // fix up url.
- if (!m_homeurl.startsWith("http://") && !m_homeurl.startsWith("https://") &&
- !m_homeurl.startsWith("ftp://"))
- {
- m_homeurl.prepend("http://");
- }
- }
- m_description = firstObj.value("description").toString();
- QJsonArray authors = firstObj.value("authorList").toArray();
- if (authors.size() == 0)
- authors = firstObj.value("authors").toArray();
-
- if (authors.size() == 0)
- m_authors = "";
- else if (authors.size() >= 1)
- {
- m_authors = authors.at(0).toString();
- for (int i = 1; i < authors.size(); i++)
- {
- m_authors += ", " + authors.at(i).toString();
- }
- }
- m_credits = firstObj.value("credits").toString();
- return;
- }
- ;
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- // this is the very old format that had just the array
- if (jsonDoc.isArray())
- {
- getInfoFromArray(jsonDoc.array());
- }
- else if (jsonDoc.isObject())
- {
- auto val = jsonDoc.object().value("modinfoversion");
- if(val.isUndefined())
- val = jsonDoc.object().value("modListVersion");
- int version = val.toDouble();
- if (version != 2)
- {
- qCritical() << "BAD stuff happened to mod json:";
- qCritical() << contents;
- return;
- }
- auto arrVal = jsonDoc.object().value("modlist");
- if(arrVal.isUndefined())
- arrVal = jsonDoc.object().value("modList");
- if (arrVal.isArray())
- {
- getInfoFromArray(arrVal.toArray());
- }
- }
-}
-
-void Mod::ReadForgeInfo(QByteArray contents)
-{
- // Read the data
- m_name = "Minecraft Forge";
- m_mod_id = "Forge";
- m_homeurl = "http://www.minecraftforge.net/forum/";
- INIFile ini;
- if (!ini.loadFile(contents))
- return;
-
- QString major = ini.get("forge.major.number", "0").toString();
- QString minor = ini.get("forge.minor.number", "0").toString();
- QString revision = ini.get("forge.revision.number", "0").toString();
- QString build = ini.get("forge.build.number", "0").toString();
-
- m_version = major + "." + minor + "." + revision + "." + build;
-}
-
-void Mod::ReadLiteModInfo(QByteArray contents)
-{
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- auto object = jsonDoc.object();
- if (object.contains("name"))
- {
- m_mod_id = m_name = object.value("name").toString();
- }
- if (object.contains("version"))
- {
- m_version = object.value("version").toString("");
- }
- else
- {
- m_version = object.value("revision").toString("");
- }
- m_mcversion = object.value("mcversion").toString();
- m_authors = object.value("author").toString();
- m_description = object.value("description").toString();
- m_homeurl = object.value("url").toString();
-}
-
-bool Mod::replace(Mod &with)
-{
- if (!destroy())
- return false;
- bool success = false;
- auto t = with.type();
-
- if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE || t == MOD_LITEMOD)
- {
- qDebug() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath();
- success = QFile::copy(with.m_file.filePath(), m_file.filePath());
- }
- if (t == MOD_FOLDER)
- {
- success = FS::copy(with.m_file.filePath(), m_file.path())();
- }
- if (success)
- {
- m_name = with.m_name;
- m_mmc_id = with.m_mmc_id;
- m_mod_id = with.m_mod_id;
- m_version = with.m_version;
- m_mcversion = with.m_mcversion;
- m_description = with.m_description;
- m_authors = with.m_authors;
- m_credits = with.m_credits;
- m_homeurl = with.m_homeurl;
- m_type = with.m_type;
- m_file.refresh();
- }
- return success;
-}
-
-bool Mod::destroy()
-{
- if (m_type == MOD_FOLDER)
- {
- QDir d(m_file.filePath());
- if (d.removeRecursively())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
- {
- QFile f(m_file.filePath());
- if (f.remove())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- return true;
-}
-
-QString Mod::version() const
-{
- switch (type())
- {
- case MOD_ZIPFILE:
- case MOD_LITEMOD:
- return m_version;
- case MOD_FOLDER:
- return "Folder";
- case MOD_SINGLEFILE:
- return "File";
- default:
- return "VOID";
- }
-}
-
-bool Mod::enable(bool value)
-{
- if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
- return false;
-
- if (m_enabled == value)
- return false;
-
- QString path = m_file.absoluteFilePath();
- if (value)
- {
- QFile foo(path);
- if (!path.endsWith(".disabled"))
- return false;
- path.chop(9);
- if (!foo.rename(path))
- return false;
- }
- else
- {
- QFile foo(path);
- path += ".disabled";
- if (!foo.rename(path))
- return false;
- }
- m_file = QFileInfo(path);
- m_enabled = value;
- return true;
-}
-bool Mod::operator==(const Mod &other) const
-{
- return mmc_id() == other.mmc_id();
-}
-bool Mod::strongCompare(const Mod &other) const
-{
- return mmc_id() == other.mmc_id() && version() == other.version() && type() == other.type();
-}
diff --git a/libraries/logic/minecraft/Mod.h b/libraries/logic/minecraft/Mod.h
deleted file mode 100644
index 19f4c740..00000000
--- a/libraries/logic/minecraft/Mod.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright 2013-2015 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 <QFileInfo>
-
-class Mod
-{
-public:
- enum ModType
- {
- MOD_UNKNOWN, //!< Indicates an unspecified mod type.
- MOD_ZIPFILE, //!< The mod is a zip file containing the mod's class files.
- MOD_SINGLEFILE, //!< The mod is a single file (not a zip file).
- MOD_FOLDER, //!< The mod is in a folder on the filesystem.
- MOD_LITEMOD, //!< The mod is a litemod
- };
-
- Mod(const QFileInfo &file);
-
- QFileInfo filename() const
- {
- return m_file;
- }
- QString mmc_id() const
- {
- return m_mmc_id;
- }
- QString mod_id() const
- {
- return m_mod_id;
- }
- ModType type() const
- {
- return m_type;
- }
- QString mcversion() const
- {
- return m_mcversion;
- }
- ;
- bool valid()
- {
- return m_type != MOD_UNKNOWN;
- }
- QString name() const
- {
- if(m_name.trimmed().isEmpty())
- {
- return m_mmc_id;
- }
- return m_name;
- }
-
- QString version() const;
-
- QString homeurl() const
- {
- return m_homeurl;
- }
-
- QString description() const
- {
- return m_description;
- }
-
- QString authors() const
- {
- return m_authors;
- }
-
- QString credits() const
- {
- return m_credits;
- }
-
- bool enabled() const
- {
- return m_enabled;
- }
-
- bool enable(bool value);
-
- // delete all the files of this mod
- bool destroy();
- // replace this mod with a copy of the other
- bool replace(Mod &with);
- // change the mod's filesystem path (used by mod lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
-
- // WEAK compare operator - used for replacing mods
- bool operator==(const Mod &other) const;
- bool strongCompare(const Mod &other) const;
-
-private:
- void ReadMCModInfo(QByteArray contents);
- void ReadForgeInfo(QByteArray contents);
- void ReadLiteModInfo(QByteArray contents);
-
-protected:
-
- // FIXME: what do do with those? HMM...
- /*
- void ReadModInfoData(QString info);
- void ReadForgeInfoData(QString infoFileData);
- */
-
- QFileInfo m_file;
- QString m_mmc_id;
- QString m_mod_id;
- bool m_enabled = true;
- QString m_name;
- QString m_version;
- QString m_mcversion;
- QString m_homeurl;
- QString m_updateurl;
- QString m_description;
- QString m_authors;
- QString m_credits;
-
- ModType m_type;
-};
diff --git a/libraries/logic/minecraft/ModList.cpp b/libraries/logic/minecraft/ModList.cpp
deleted file mode 100644
index d9ed4886..00000000
--- a/libraries/logic/minecraft/ModList.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/* Copyright 2013-2015 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 "ModList.h"
-#include <FileSystem.h>
-#include <QMimeData>
-#include <QUrl>
-#include <QUuid>
-#include <QString>
-#include <QFileSystemWatcher>
-#include <QDebug>
-
-ModList::ModList(const QString &dir, const QString &list_file)
- : QAbstractListModel(), m_dir(dir), m_list_file(list_file)
-{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_list_id = QUuid::createUuid().toString();
- m_watcher = new QFileSystemWatcher(this);
- is_watching = false;
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
- SLOT(directoryChanged(QString)));
-}
-
-void ModList::startWatching()
-{
- update();
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
-}
-
-void ModList::stopWatching()
-{
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
-}
-
-void ModList::internalSort(QList<Mod> &what)
-{
- auto predicate = [](const Mod &left, const Mod &right)
- {
- if (left.name() == right.name())
- {
- return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
- }
- return left.name().localeAwareCompare(right.name()) < 0;
- };
- std::sort(what.begin(), what.end(), predicate);
-}
-
-bool ModList::update()
-{
- if (!isValid())
- return false;
-
- QList<Mod> orderedMods;
- QList<Mod> newMods;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- bool orderOrStateChanged = false;
-
- // first, process the ordered items (if any)
- OrderList listOrder = readListFile();
- for (auto item : listOrder)
- {
- QFileInfo infoEnabled(m_dir.filePath(item.id));
- QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
- int idxEnabled = folderContents.indexOf(infoEnabled);
- int idxDisabled = folderContents.indexOf(infoDisabled);
- bool isEnabled;
- // if both enabled and disabled versions are present, it's a special case...
- if (idxEnabled >= 0 && idxDisabled >= 0)
- {
- // we only process the one we actually have in the order file.
- // and exactly as we have it.
- // THIS IS A CORNER CASE
- isEnabled = item.enabled;
- }
- else
- {
- // only one is present.
- // we pick the one that we found.
- // we assume the mod was enabled/disabled by external means
- isEnabled = idxEnabled >= 0;
- }
- int idx = isEnabled ? idxEnabled : idxDisabled;
- QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
- // if the file from the index file exists
- if (idx != -1)
- {
- // remove from the actual folder contents list
- folderContents.takeAt(idx);
- // append the new mod
- orderedMods.append(Mod(info));
- if (isEnabled != item.enabled)
- orderOrStateChanged = true;
- }
- else
- {
- orderOrStateChanged = true;
- }
- }
- // if there are any untracked files...
- if (folderContents.size())
- {
- // the order surely changed!
- for (auto entry : folderContents)
- {
- newMods.append(Mod(entry));
- }
- internalSort(newMods);
- orderedMods.append(newMods);
- orderOrStateChanged = true;
- }
- // otherwise, if we were already tracking some mods
- else if (mods.size())
- {
- // if the number doesn't match, order changed.
- if (mods.size() != orderedMods.size())
- orderOrStateChanged = true;
- // if it does match, compare the mods themselves
- else
- for (int i = 0; i < mods.size(); i++)
- {
- if (!mods[i].strongCompare(orderedMods[i]))
- {
- orderOrStateChanged = true;
- break;
- }
- }
- }
- beginResetModel();
- mods.swap(orderedMods);
- endResetModel();
- if (orderOrStateChanged && !m_list_file.isEmpty())
- {
- qDebug() << "Mod list " << m_list_file << " changed!";
- saveListFile();
- emit changed();
- }
- return true;
-}
-
-void ModList::directoryChanged(QString path)
-{
- update();
-}
-
-ModList::OrderList ModList::readListFile()
-{
- OrderList itemList;
- if (m_list_file.isNull() || m_list_file.isEmpty())
- return itemList;
-
- QFile textFile(m_list_file);
- if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
- return OrderList();
-
- QTextStream textStream;
- textStream.setAutoDetectUnicode(true);
- textStream.setDevice(&textFile);
- while (true)
- {
- QString line = textStream.readLine();
- if (line.isNull() || line.isEmpty())
- break;
- else
- {
- OrderItem it;
- it.enabled = !line.endsWith(".disabled");
- if (!it.enabled)
- {
- line.chop(9);
- }
- it.id = line;
- itemList.append(it);
- }
- }
- textFile.close();
- return itemList;
-}
-
-bool ModList::saveListFile()
-{
- if (m_list_file.isNull() || m_list_file.isEmpty())
- return false;
- QFile textFile(m_list_file);
- if (!textFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- return false;
- QTextStream textStream;
- textStream.setGenerateByteOrderMark(true);
- textStream.setCodec("UTF-8");
- textStream.setDevice(&textFile);
- for (auto mod : mods)
- {
- textStream << mod.mmc_id();
- if (!mod.enabled())
- textStream << ".disabled";
- textStream << endl;
- }
- textFile.close();
- return false;
-}
-
-bool ModList::isValid()
-{
- return m_dir.exists() && m_dir.isReadable();
-}
-
-bool ModList::installMod(const QString &filename, int index)
-{
- // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
- QFileInfo fileinfo(FS::NormalizePath(filename));
-
- qDebug() << "installing: " << fileinfo.absoluteFilePath();
-
- if (!fileinfo.exists() || !fileinfo.isReadable() || index < 0)
- {
- return false;
- }
- Mod m(fileinfo);
- if (!m.valid())
- return false;
-
- // if it's already there, replace the original mod (in place)
- int idx = mods.indexOf(m);
- if (idx != -1)
- {
- int idx2 = mods.indexOf(m, idx + 1);
- if (idx2 != -1)
- return false;
- if (mods[idx].replace(m))
- {
-
- auto left = this->index(index);
- auto right = this->index(index, columnCount(QModelIndex()) - 1);
- emit dataChanged(left, right);
- saveListFile();
- update();
- return true;
- }
- return false;
- }
-
- auto type = m.type();
- if (type == Mod::MOD_UNKNOWN)
- return false;
- if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
- {
- QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!QFile::copy(fileinfo.filePath(), newpath))
- return false;
- m.repath(newpath);
- beginInsertRows(QModelIndex(), index, index);
- mods.insert(index, m);
- endInsertRows();
- saveListFile();
- update();
- return true;
- }
- else if (type == Mod::MOD_FOLDER)
- {
-
- QString from = fileinfo.filePath();
- QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!FS::copy(from, to)())
- return false;
- m.repath(to);
- beginInsertRows(QModelIndex(), index, index);
- mods.insert(index, m);
- endInsertRows();
- saveListFile();
- update();
- return true;
- }
- return false;
-}
-
-bool ModList::deleteMod(int index)
-{
- if (index >= mods.size() || index < 0)
- return false;
- Mod &m = mods[index];
- if (m.destroy())
- {
- beginRemoveRows(QModelIndex(), index, index);
- mods.removeAt(index);
- endRemoveRows();
- saveListFile();
- emit changed();
- return true;
- }
- return false;
-}
-
-bool ModList::deleteMods(int first, int last)
-{
- for (int i = first; i <= last; i++)
- {
- Mod &m = mods[i];
- m.destroy();
- }
- beginRemoveRows(QModelIndex(), first, last);
- mods.erase(mods.begin() + first, mods.begin() + last + 1);
- endRemoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModTo(int from, int to)
-{
- if (from < 0 || from >= mods.size())
- return false;
- if (to >= rowCount())
- to = rowCount() - 1;
- if (to == -1)
- to = rowCount() - 1;
- if (from == to)
- return false;
- int togap = to > from ? to + 1 : to;
- beginMoveRows(QModelIndex(), from, from, QModelIndex(), togap);
- mods.move(from, to);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModUp(int from)
-{
- if (from > 0)
- return moveModTo(from, from - 1);
- return false;
-}
-
-bool ModList::moveModsUp(int first, int last)
-{
- if (first == 0)
- return false;
-
- beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
- mods.move(first - 1, last);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModDown(int from)
-{
- if (from < 0)
- return false;
- if (from < mods.size() - 1)
- return moveModTo(from, from + 1);
- return false;
-}
-
-bool ModList::moveModsDown(int first, int last)
-{
- if (last == mods.size() - 1)
- return false;
-
- beginMoveRows(QModelIndex(), first, last, QModelIndex(), last + 2);
- mods.move(last + 1, first);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-int ModList::columnCount(const QModelIndex &parent) const
-{
- return 3;
-}
-
-QVariant ModList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= mods.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return mods[row].name();
- case VersionColumn:
- return mods[row].version();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return mods[row].mmc_id();
-
- case Qt::CheckStateRole:
- switch (column)
- {
- case ActiveColumn:
- return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
-}
-
-bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if (role == Qt::CheckStateRole)
- {
- auto &mod = mods[index.row()];
- if (mod.enable(!mod.enabled()))
- {
- emit dataChanged(index, index);
- return true;
- }
- }
- return false;
-}
-
-QVariant ModList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return QString();
- case NameColumn:
- return tr("Name");
- case VersionColumn:
- return tr("Version");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Is the mod enabled?");
- case NameColumn:
- return tr("The name of the mod.");
- case VersionColumn:
- return tr("The version of the mod.");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
-}
-
-Qt::ItemFlags ModList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
-}
-
-QStringList ModList::mimeTypes() const
-{
- QStringList types;
- types << "text/uri-list";
- types << "text/plain";
- return types;
-}
-
-Qt::DropActions ModList::supportedDropActions() const
-{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
-}
-
-Qt::DropActions ModList::supportedDragActions() const
-{
- // move to other mod lists or VOID
- return Qt::MoveAction;
-}
-
-QMimeData *ModList::mimeData(const QModelIndexList &indexes) const
-{
- QMimeData *data = new QMimeData();
-
- if (indexes.size() == 0)
- return data;
-
- auto idx = indexes[0];
- int row = idx.row();
- if (row < 0 || row >= mods.size())
- return data;
-
- QStringList params;
- params << m_list_id << QString::number(row);
- data->setText(params.join('|'));
- return data;
-}
-
-bool ModList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
-{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
- if (parent.isValid())
- {
- row = parent.row();
- column = parent.column();
- }
-
- if (row > rowCount())
- row = rowCount();
- if (row == -1)
- row = rowCount();
- if (column == -1)
- column = 0;
- qDebug() << "Drop row: " << row << " column: " << column;
-
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- stopWatching();
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- QString filename = url.toLocalFile();
- installMod(filename, row);
- // if there is no ordering, re-sort the list
- if (m_list_file.isEmpty())
- {
- beginResetModel();
- internalSort(mods);
- endResetModel();
- }
- }
- if (was_watching)
- startWatching();
- return true;
- }
- else if (data->hasText())
- {
- QString sourcestr = data->text();
- auto list = sourcestr.split('|');
- if (list.size() != 2)
- return false;
- QString remoteId = list[0];
- int remoteIndex = list[1].toInt();
- qDebug() << "move: " << sourcestr;
- // no moving of things between two lists
- if (remoteId != m_list_id)
- return false;
- // no point moving to the same place...
- if (row == remoteIndex)
- return false;
- // otherwise, move the mod :D
- moveModTo(remoteIndex, row);
- return true;
- }
- return false;
-}
diff --git a/libraries/logic/minecraft/ModList.h b/libraries/logic/minecraft/ModList.h
deleted file mode 100644
index 05ada8ee..00000000
--- a/libraries/logic/minecraft/ModList.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright 2013-2015 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 <QList>
-#include <QString>
-#include <QDir>
-#include <QAbstractListModel>
-
-#include "minecraft/Mod.h"
-
-#include "multimc_logic_export.h"
-
-class LegacyInstance;
-class BaseInstance;
-class QFileSystemWatcher;
-
-/**
- * A legacy mod list.
- * Backed by a folder.
- */
-class MULTIMC_LOGIC_EXPORT ModList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum Columns
- {
- ActiveColumn = 0,
- NameColumn,
- VersionColumn
- };
- ModList(const QString &dir, const QString &list_file = QString());
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- virtual bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole);
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return size();
- }
- ;
- virtual QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
- size_t size() const
- {
- return mods.size();
- }
- ;
- bool empty() const
- {
- return size() == 0;
- }
- Mod &operator[](size_t index)
- {
- return mods[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /**
- * Adds the given mod to the list at the given index - if the list supports custom ordering
- */
- virtual bool installMod(const QString & filename, int index = 0);
-
- /// Deletes the mod at the given index.
- virtual bool deleteMod(int index);
-
- /// Deletes all the selected mods
- virtual bool deleteMods(int first, int last);
-
- /**
- * move the mod at index to the position N
- * 0 is the beginning of the list, length() is the end of the list.
- */
- virtual bool moveModTo(int from, int to);
-
- /**
- * move the mod at index one position upwards
- */
- virtual bool moveModUp(int from);
- virtual bool moveModsUp(int first, int last);
-
- /**
- * move the mod at index one position downwards
- */
- virtual bool moveModDown(int from);
- virtual bool moveModsDown(int first, int last);
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- /// get data for drag action
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
- /// get the supported mime types
- virtual QStringList mimeTypes() const;
- /// process data from drop action
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent);
- /// what drag actions do we support?
- virtual Qt::DropActions supportedDragActions() const;
-
- /// what drop actions do we support?
- virtual Qt::DropActions supportedDropActions() const;
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir()
- {
- return m_dir;
- }
-
- const QList<Mod> & allMods()
- {
- return mods;
- }
-
-private:
- void internalSort(QList<Mod> & what);
- struct OrderItem
- {
- QString id;
- bool enabled = false;
- };
- typedef QList<OrderItem> OrderList;
- OrderList readListFile();
- bool saveListFile();
-private
-slots:
- void directoryChanged(QString path);
-
-signals:
- void changed();
-
-protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching;
- QDir m_dir;
- QString m_list_file;
- QString m_list_id;
- QList<Mod> mods;
-};
diff --git a/libraries/logic/minecraft/MojangDownloadInfo.h b/libraries/logic/minecraft/MojangDownloadInfo.h
deleted file mode 100644
index 1f3306e0..00000000
--- a/libraries/logic/minecraft/MojangDownloadInfo.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma once
-#include <QString>
-#include <QMap>
-#include <memory>
-
-struct MojangDownloadInfo
-{
- // types
- typedef std::shared_ptr<MojangDownloadInfo> Ptr;
-
- // data
- /// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested!
- QString path;
- /// absolute URL of this file
- QString url;
- /// sha-1 checksum of the file
- QString sha1;
- /// size of the file in bytes
- int size;
-};
-
-
-
-struct MojangLibraryDownloadInfo
-{
- MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {};
- MojangLibraryDownloadInfo() {};
-
- // types
- typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr;
-
- // methods
- MojangDownloadInfo *getDownloadInfo(QString classifier)
- {
- if (classifier.isNull())
- {
- return artifact.get();
- }
-
- return classifiers[classifier].get();
- }
-
- // data
- MojangDownloadInfo::Ptr artifact;
- QMap<QString, MojangDownloadInfo::Ptr> classifiers;
-};
-
-
-
-struct MojangAssetIndexInfo : public MojangDownloadInfo
-{
- // types
- typedef std::shared_ptr<MojangAssetIndexInfo> Ptr;
-
- // methods
- MojangAssetIndexInfo()
- {
- }
-
- MojangAssetIndexInfo(QString id)
- {
- this->id = id;
- url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json";
- known = false;
- }
-
- // data
- int totalSize;
- QString id;
- bool known = true;
-};
diff --git a/libraries/logic/minecraft/MojangVersionFormat.cpp b/libraries/logic/minecraft/MojangVersionFormat.cpp
deleted file mode 100644
index 34129c9e..00000000
--- a/libraries/logic/minecraft/MojangVersionFormat.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-#include "MojangVersionFormat.h"
-#include "onesix/OneSixVersionFormat.h"
-#include "MinecraftVersion.h"
-#include "VersionBuildError.h"
-#include "MojangDownloadInfo.h"
-
-#include "Json.h"
-using namespace Json;
-#include "ParseUtils.h"
-
-static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 18;
-
-static MojangAssetIndexInfo::Ptr assetIndexFromJson (const QJsonObject &obj);
-static MojangDownloadInfo::Ptr downloadInfoFromJson (const QJsonObject &obj);
-static MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson (const QJsonObject &libObj);
-static QJsonObject assetIndexToJson (MojangAssetIndexInfo::Ptr assetidxinfo);
-static QJsonObject libDownloadInfoToJson (MojangLibraryDownloadInfo::Ptr libinfo);
-static QJsonObject downloadInfoToJson (MojangDownloadInfo::Ptr info);
-
-namespace Bits
-{
-static void readString(const QJsonObject &root, const QString &key, QString &variable)
-{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
-}
-
-static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject &obj)
-{
- // optional, not used
- readString(obj, "path", out->path);
- // required!
- out->sha1 = requireString(obj, "sha1");
- out->url = requireString(obj, "url");
- out->size = requireInteger(obj, "size");
-}
-
-static void readAssetIndex(MojangAssetIndexInfo::Ptr out, const QJsonObject &obj)
-{
- out->totalSize = requireInteger(obj, "totalSize");
- out->id = requireString(obj, "id");
- // out->known = true;
-}
-}
-
-MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject &obj)
-{
- auto out = std::make_shared<MojangDownloadInfo>();
- Bits::readDownloadInfo(out, obj);
- return out;
-}
-
-MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject &obj)
-{
- auto out = std::make_shared<MojangAssetIndexInfo>();
- Bits::readDownloadInfo(out, obj);
- Bits::readAssetIndex(out, obj);
- return out;
-}
-
-QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info)
-{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- return out;
-}
-
-MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject &libObj)
-{
- auto out = std::make_shared<MojangLibraryDownloadInfo>();
- auto dlObj = requireObject(libObj.value("downloads"));
- if(dlObj.contains("artifact"))
- {
- out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact"));
- }
- if(dlObj.contains("classifiers"))
- {
- auto classifiersObj = requireObject(dlObj, "classifiers");
- for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->classifiers[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
- return out;
-}
-
-QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo)
-{
- QJsonObject out;
- if(libinfo->artifact)
- {
- out.insert("artifact", downloadInfoToJson(libinfo->artifact));
- }
- if(libinfo->classifiers.size())
- {
- QJsonObject classifiersOut;
- for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
- {
- classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("classifiers", classifiersOut);
- }
- return out;
-}
-
-QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info)
-{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- out.insert("totalSize", info->totalSize);
- out.insert("id", info->id);
- return out;
-}
-
-void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFile *out)
-{
- Bits::readString(in, "id", out->minecraftVersion);
- Bits::readString(in, "mainClass", out->mainClass);
- Bits::readString(in, "minecraftArguments", out->minecraftArguments);
- if(out->minecraftArguments.isEmpty())
- {
- QString processArguments;
- Bits::readString(in, "processArguments", processArguments);
- QString toCompare = processArguments.toLower();
- if (toCompare == "legacy")
- {
- out->minecraftArguments = " ${auth_player_name} ${auth_session}";
- }
- else if (toCompare == "username_session")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}";
- }
- else if (toCompare == "username_session_version")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}";
- }
- else if (!toCompare.isEmpty())
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
- }
- }
- Bits::readString(in, "type", out->type);
-
- Bits::readString(in, "assets", out->assets);
- if(in.contains("assetIndex"))
- {
- out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex"));
- }
- else if (!out->assets.isNull())
- {
- out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
- }
-
- out->m_releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
- out->m_updateTime = timeFromS3Time(in.value("time").toString(""));
-
- if (in.contains("minimumLauncherVersion"))
- {
- out->minimumLauncherVersion = requireInteger(in.value("minimumLauncherVersion"));
- if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION)
- {
- out->addProblem(
- PROBLEM_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));
- }
- }
- if(in.contains("downloads"))
- {
- auto downloadsObj = requireObject(in, "downloads");
- for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
-}
-
-VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename)
-{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
-
- QJsonObject root = doc.object();
-
- readVersionProperties(root, out.get());
-
- out->name = "Minecraft";
- out->fileId = "net.minecraft";
- out->version = out->minecraftVersion;
- out->filename = filename;
-
-
- if (root.contains("libraries"))
- {
- for (auto libVal : requireArray(root.value("libraries")))
- {
- auto libObj = requireObject(libVal);
-
- auto lib = MojangVersionFormat::libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- }
- return out;
-}
-
-void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObject& out)
-{
- writeString(out, "id", in->minecraftVersion);
- writeString(out, "mainClass", in->mainClass);
- writeString(out, "minecraftArguments", in->minecraftArguments);
- writeString(out, "type", in->type);
- if(!in->m_releaseTime.isNull())
- {
- writeString(out, "releaseTime", timeToS3Time(in->m_releaseTime));
- }
- if(!in->m_updateTime.isNull())
- {
- writeString(out, "time", timeToS3Time(in->m_updateTime));
- }
- if(in->minimumLauncherVersion != -1)
- {
- out.insert("minimumLauncherVersion", in->minimumLauncherVersion);
- }
- writeString(out, "assets", in->assets);
- if(in->mojangAssetIndex && in->mojangAssetIndex->known)
- {
- out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
- }
- if(in->mojangDownloads.size())
- {
- QJsonObject downloadsOut;
- for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
- {
- downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("downloads", downloadsOut);
- }
-}
-
-QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch)
-{
- QJsonObject root;
- writeVersionProperties(patch.get(), root);
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(MojangVersionFormat::libraryToJson(value.get()));
- }
- root.insert("libraries", array);
- }
-
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
-}
-
-LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
-{
- LibraryPtr out(new Library());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field");
- }
- out->m_name = libObj.value("name").toString();
-
- Bits::readString(libObj, "url", out->m_repositoryURL);
- if (libObj.contains("extract"))
- {
- out->m_hasExcludes = true;
- auto extractObj = requireObject(libObj.value("extract"));
- for (auto excludeVal : requireArray(extractObj.value("exclude")))
- {
- out->m_extractExcludes.append(requireString(excludeVal));
- }
- }
- if (libObj.contains("natives"))
- {
- QJsonObject nativesObj = requireObject(libObj.value("natives"));
- for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it)
- {
- if (!it.value().isString())
- {
- qWarning() << filename << "contains an invalid native (skipping)";
- }
- OpSys opSys = OpSys_fromString(it.key());
- if (opSys != Os_Other)
- {
- out->m_nativeClassifiers[opSys] = it.value().toString();
- }
- }
- }
- if (libObj.contains("rules"))
- {
- out->applyRules = true;
- out->m_rules = rulesFromJsonV4(libObj);
- }
- if (libObj.contains("downloads"))
- {
- out->m_mojangDownloads = libDownloadInfoFromJson(libObj);
- }
- return out;
-}
-
-QJsonObject MojangVersionFormat::libraryToJson(Library *library)
-{
- QJsonObject libRoot;
- libRoot.insert("name", (QString)library->m_name);
- if (!library->m_repositoryURL.isEmpty())
- {
- libRoot.insert("url", library->m_repositoryURL);
- }
- if (library->isNative())
- {
- QJsonObject nativeList;
- auto iter = library->m_nativeClassifiers.begin();
- while (iter != library->m_nativeClassifiers.end())
- {
- nativeList.insert(OpSys_toString(iter.key()), iter.value());
- iter++;
- }
- libRoot.insert("natives", nativeList);
- if (library->m_extractExcludes.size())
- {
- QJsonArray excludes;
- QJsonObject extract;
- for (auto exclude : library->m_extractExcludes)
- {
- excludes.append(exclude);
- }
- extract.insert("exclude", excludes);
- libRoot.insert("extract", extract);
- }
- }
- if (library->m_rules.size())
- {
- QJsonArray allRules;
- for (auto &rule : library->m_rules)
- {
- QJsonObject ruleObj = rule->toJson();
- allRules.append(ruleObj);
- }
- libRoot.insert("rules", allRules);
- }
- if(library->m_mojangDownloads)
- {
- auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads);
- libRoot.insert("downloads", downloadsObj);
- }
- return libRoot;
-}
diff --git a/libraries/logic/minecraft/MojangVersionFormat.h b/libraries/logic/minecraft/MojangVersionFormat.h
deleted file mode 100644
index 4e141088..00000000
--- a/libraries/logic/minecraft/MojangVersionFormat.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <minecraft/VersionFile.h>
-#include <minecraft/Library.h>
-#include <QJsonDocument>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT MojangVersionFormat
-{
-friend class OneSixVersionFormat;
-protected:
- // does not include libraries
- static void readVersionProperties(const QJsonObject& in, VersionFile* out);
- // does not include libraries
- static void writeVersionProperties(const VersionFile* in, QJsonObject& out);
-public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
-
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
-};
diff --git a/libraries/logic/minecraft/OpSys.cpp b/libraries/logic/minecraft/OpSys.cpp
deleted file mode 100644
index 4c2a236d..00000000
--- a/libraries/logic/minecraft/OpSys.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2013-2015 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 "OpSys.h"
-
-OpSys OpSys_fromString(QString name)
-{
- if (name == "linux")
- return Os_Linux;
- if (name == "windows")
- return Os_Windows;
- if (name == "osx")
- return Os_OSX;
- return Os_Other;
-}
-
-QString OpSys_toString(OpSys name)
-{
- switch (name)
- {
- case Os_Linux:
- return "linux";
- case Os_OSX:
- return "osx";
- case Os_Windows:
- return "windows";
- default:
- return "other";
- }
-} \ No newline at end of file
diff --git a/libraries/logic/minecraft/OpSys.h b/libraries/logic/minecraft/OpSys.h
deleted file mode 100644
index 9ebea3de..00000000
--- a/libraries/logic/minecraft/OpSys.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2013-2015 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>
-enum OpSys
-{
- Os_Windows,
- Os_Linux,
- Os_OSX,
- Os_Other
-};
-
-OpSys OpSys_fromString(QString);
-QString OpSys_toString(OpSys);
-
-#ifdef Q_OS_WIN32
-#define currentSystem Os_Windows
-#else
-#ifdef Q_OS_MAC
-#define currentSystem Os_OSX
-#else
-#define currentSystem Os_Linux
-#endif
-#endif \ No newline at end of file
diff --git a/libraries/logic/minecraft/ParseUtils.cpp b/libraries/logic/minecraft/ParseUtils.cpp
deleted file mode 100644
index ca188432..00000000
--- a/libraries/logic/minecraft/ParseUtils.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <QDateTime>
-#include <QString>
-#include "ParseUtils.h"
-#include <QDebug>
-#include <cstdlib>
-
-QDateTime timeFromS3Time(QString str)
-{
- return QDateTime::fromString(str, Qt::ISODate);
-}
-
-QString timeToS3Time(QDateTime time)
-{
- // this all because Qt can't format timestamps right.
- int offsetRaw = time.offsetFromUtc();
- bool negative = offsetRaw < 0;
- int offsetAbs = std::abs(offsetRaw);
-
- int offsetSeconds = offsetAbs % 60;
- offsetAbs -= offsetSeconds;
-
- int offsetMinutes = offsetAbs % 3600;
- offsetAbs -= offsetMinutes;
- offsetMinutes /= 60;
-
- int offsetHours = offsetAbs / 3600;
-
- QString raw = time.toString("yyyy-MM-ddTHH:mm:ss");
- raw += (negative ? QChar('-') : QChar('+'));
- raw += QString("%1").arg(offsetHours, 2, 10, QChar('0'));
- raw += ":";
- raw += QString("%1").arg(offsetMinutes, 2, 10, QChar('0'));
- return raw;
-}
diff --git a/libraries/logic/minecraft/ParseUtils.h b/libraries/logic/minecraft/ParseUtils.h
deleted file mode 100644
index 2b367a10..00000000
--- a/libraries/logic/minecraft/ParseUtils.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-#include <QString>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-/// take the timestamp used by S3 and turn it into QDateTime
-MULTIMC_LOGIC_EXPORT QDateTime timeFromS3Time(QString str);
-
-/// take a timestamp and convert it into an S3 timestamp
-MULTIMC_LOGIC_EXPORT QString timeToS3Time(QDateTime);
diff --git a/libraries/logic/minecraft/ProfilePatch.h b/libraries/logic/minecraft/ProfilePatch.h
deleted file mode 100644
index f0c65360..00000000
--- a/libraries/logic/minecraft/ProfilePatch.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <QList>
-#include <QJsonDocument>
-#include <QDateTime>
-#include "JarMod.h"
-
-class MinecraftProfile;
-
-enum ProblemSeverity
-{
- PROBLEM_NONE,
- PROBLEM_WARNING,
- PROBLEM_ERROR
-};
-
-/// where is a version from?
-enum VersionSource
-{
- Local, //!< version loaded from a file in the cache.
- Remote, //!< incomplete version on a remote server.
-};
-
-class PatchProblem
-{
-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;
-};
-
-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;
- }
-
-protected:
- QList<PatchProblem> m_problems;
- ProblemSeverity m_problemSeverity = PROBLEM_NONE;
-};
-
-typedef std::shared_ptr<ProfilePatch> ProfilePatchPtr;
diff --git a/libraries/logic/minecraft/ProfileStrategy.h b/libraries/logic/minecraft/ProfileStrategy.h
deleted file mode 100644
index b4dfc4b3..00000000
--- a/libraries/logic/minecraft/ProfileStrategy.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "ProfileUtils.h"
-
-class MinecraftProfile;
-
-class ProfileStrategy
-{
- friend class MinecraftProfile;
-public:
- virtual ~ProfileStrategy(){};
-
- /// load the patch files into the profile
- virtual void load() = 0;
-
- /// reset the order of patches
- virtual bool resetOrder() = 0;
-
- /// save the order of patches, given the order
- virtual bool saveOrder(ProfileUtils::PatchOrder order) = 0;
-
- /// install a list of jar mods into the instance
- virtual bool installJarMods(QStringList filepaths) = 0;
-
- /// remove any files or records that constitute the version patch
- virtual bool removePatch(ProfilePatchPtr jarMod) = 0;
-
- /// make the patch custom, if possible
- virtual bool customizePatch(ProfilePatchPtr patch) = 0;
-
- /// revert the custom patch to 'vanilla', if possible
- virtual bool revertPatch(ProfilePatchPtr patch) = 0;
-protected:
- MinecraftProfile *profile;
-};
diff --git a/libraries/logic/minecraft/ProfileUtils.cpp b/libraries/logic/minecraft/ProfileUtils.cpp
deleted file mode 100644
index ef9b3b28..00000000
--- a/libraries/logic/minecraft/ProfileUtils.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "ProfileUtils.h"
-#include "minecraft/VersionFilterData.h"
-#include "minecraft/onesix/OneSixVersionFormat.h"
-#include "Json.h"
-#include <QDebug>
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QRegularExpression>
-#include <QSaveFile>
-
-namespace ProfileUtils
-{
-
-static const int currentOrderFileVersion = 1;
-
-bool writeOverrideOrders(QString path, const PatchOrder &order)
-{
- QJsonObject obj;
- obj.insert("version", currentOrderFileVersion);
- QJsonArray orderArray;
- for(auto str: order)
- {
- orderArray.append(str);
- }
- obj.insert("order", orderArray);
- QSaveFile orderFile(path);
- if (!orderFile.open(QFile::WriteOnly))
- {
- qCritical() << "Couldn't open" << orderFile.fileName()
- << "for writing:" << orderFile.errorString();
- return false;
- }
- auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
- if(orderFile.write(data) != data.size())
- {
- qCritical() << "Couldn't write all the data into" << orderFile.fileName()
- << "because:" << orderFile.errorString();
- return false;
- }
- if(!orderFile.commit())
- {
- qCritical() << "Couldn't save" << orderFile.fileName()
- << "because:" << orderFile.errorString();
- }
- return true;
-}
-
-bool readOverrideOrders(QString path, PatchOrder &order)
-{
- QFile orderFile(path);
- if (!orderFile.exists())
- {
- qWarning() << "Order file doesn't exist. Ignoring.";
- return false;
- }
- if (!orderFile.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << orderFile.fileName()
- << " for reading:" << orderFile.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and it's valid JSON
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error);
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and then read it and process it if all above is true.
- try
- {
- auto obj = Json::requireObject(doc);
- // check order file version.
- auto version = Json::requireInteger(obj.value("version"));
- if (version != currentOrderFileVersion)
- {
- throw JSONValidationError(QObject::tr("Invalid order file version, expected %1")
- .arg(currentOrderFileVersion));
- }
- auto orderArray = Json::requireArray(obj.value("order"));
- for(auto item: orderArray)
- {
- order.append(Json::requireString(item));
- }
- }
- catch (JSONValidationError &err)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format";
- qWarning() << "Ignoring overriden order";
- order.clear();
- return false;
- }
- return true;
-}
-
-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);
- return outError;
-}
-
-static VersionFilePtr guardedParseJson(const QJsonDocument & doc,const QString &fileId,const QString &filepath,const bool &requireOrder)
-{
- try
- {
- return OneSixVersionFormat::versionFileFromJson(doc, filepath, requireOrder);
- }
- catch (Exception & e)
- {
- return createErrorVersionFile(fileId, filepath, e.cause());
- }
-}
-
-VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder)
-{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonParseError error;
- auto data = file.readAll();
- QJsonDocument doc = QJsonDocument::fromJson(data, &error);
- file.close();
- if (error.error != QJsonParseError::NoError)
- {
- int line = 1;
- int column = 0;
- for(int i = 0; i < error.offset; i++)
- {
- if(data[i] == '\n')
- {
- line++;
- column = 0;
- continue;
- }
- column++;
- }
- auto errorStr = QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.")
- .arg(fileInfo.fileName(), error.errorString())
- .arg(line).arg(column);
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), requireOrder);
-}
-
-VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo)
-{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll());
- file.close();
- if (doc.isNull())
- {
- file.remove();
- throw JSONValidationError(QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName()));
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), false);
-}
-
-void removeLwjglFromPatch(VersionFilePtr patch)
-{
- auto filter = [](QList<LibraryPtr>& libs)
- {
- QList<LibraryPtr> filteredLibs;
- for (auto lib : libs)
- {
- if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix()))
- {
- filteredLibs.append(lib);
- }
- }
- libs = filteredLibs;
- };
- filter(patch->libraries);
-}
-}
diff --git a/libraries/logic/minecraft/ProfileUtils.h b/libraries/logic/minecraft/ProfileUtils.h
deleted file mode 100644
index 267fd42b..00000000
--- a/libraries/logic/minecraft/ProfileUtils.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-#include "Library.h"
-#include "VersionFile.h"
-
-namespace ProfileUtils
-{
-typedef QStringList PatchOrder;
-
-/// Read and parse a OneSix format order file
-bool readOverrideOrders(QString path, PatchOrder &order);
-
-/// Write a OneSix format order file
-bool writeOverrideOrders(QString path, const PatchOrder &order);
-
-
-/// Parse a version file in JSON format
-VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder);
-
-/// Parse a version file in binary JSON format
-VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo);
-
-/// Remove LWJGL from a patch file. This is applied to all Mojang-like profile files.
-void removeLwjglFromPatch(VersionFilePtr patch);
-
-}
diff --git a/libraries/logic/minecraft/Rule.cpp b/libraries/logic/minecraft/Rule.cpp
deleted file mode 100644
index c8ba297b..00000000
--- a/libraries/logic/minecraft/Rule.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright 2013-2015 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 <QJsonObject>
-#include <QJsonArray>
-
-#include "Rule.h"
-
-RuleAction RuleAction_fromString(QString name)
-{
- if (name == "allow")
- return Allow;
- if (name == "disallow")
- return Disallow;
- return Defer;
-}
-
-QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules)
-{
- QList<std::shared_ptr<Rule>> rules;
- auto rulesVal = objectWithRules.value("rules");
- if (!rulesVal.isArray())
- return rules;
-
- QJsonArray ruleList = rulesVal.toArray();
- for (auto ruleVal : ruleList)
- {
- std::shared_ptr<Rule> rule;
- if (!ruleVal.isObject())
- continue;
- auto ruleObj = ruleVal.toObject();
- auto actionVal = ruleObj.value("action");
- if (!actionVal.isString())
- continue;
- auto action = RuleAction_fromString(actionVal.toString());
- if (action == Defer)
- continue;
-
- auto osVal = ruleObj.value("os");
- if (!osVal.isObject())
- {
- // add a new implicit action rule
- rules.append(ImplicitRule::create(action));
- continue;
- }
-
- auto osObj = osVal.toObject();
- auto osNameVal = osObj.value("name");
- if (!osNameVal.isString())
- continue;
- OpSys requiredOs = OpSys_fromString(osNameVal.toString());
- QString versionRegex = osObj.value("version").toString();
- // add a new OS rule
- rules.append(OsRule::create(action, requiredOs, versionRegex));
- }
- return rules;
-}
-
-QJsonObject ImplicitRule::toJson()
-{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- return ruleObj;
-}
-
-QJsonObject OsRule::toJson()
-{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- QJsonObject osObj;
- {
- osObj.insert("name", OpSys_toString(m_system));
- if(!m_version_regexp.isEmpty())
- {
- osObj.insert("version", m_version_regexp);
- }
- }
- ruleObj.insert("os", osObj);
- return ruleObj;
-}
-
diff --git a/libraries/logic/minecraft/Rule.h b/libraries/logic/minecraft/Rule.h
deleted file mode 100644
index c8bf6eaa..00000000
--- a/libraries/logic/minecraft/Rule.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2013-2015 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 <QList>
-#include <QJsonObject>
-#include <memory>
-#include "OpSys.h"
-
-class Library;
-class Rule;
-
-enum RuleAction
-{
- Allow,
- Disallow,
- Defer
-};
-
-QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules);
-
-class Rule
-{
-protected:
- RuleAction m_result;
- virtual bool applies(const Library *parent) = 0;
-
-public:
- Rule(RuleAction result) : m_result(result)
- {
- }
- virtual ~Rule() {};
- virtual QJsonObject toJson() = 0;
- RuleAction apply(const Library *parent)
- {
- if (applies(parent))
- return m_result;
- else
- return Defer;
- }
-};
-
-class OsRule : public Rule
-{
-private:
- // the OS
- OpSys m_system;
- // the OS version regexp
- QString m_version_regexp;
-
-protected:
- virtual bool applies(const Library *)
- {
- return (m_system == currentSystem);
- }
- OsRule(RuleAction result, OpSys system, QString version_regexp)
- : Rule(result), m_system(system), m_version_regexp(version_regexp)
- {
- }
-
-public:
- virtual QJsonObject toJson();
- static std::shared_ptr<OsRule> create(RuleAction result, OpSys system,
- QString version_regexp)
- {
- return std::shared_ptr<OsRule>(new OsRule(result, system, version_regexp));
- }
-};
-
-class ImplicitRule : public Rule
-{
-protected:
- virtual bool applies(const Library *)
- {
- return true;
- }
- ImplicitRule(RuleAction result) : Rule(result)
- {
- }
-
-public:
- virtual QJsonObject toJson();
- static std::shared_ptr<ImplicitRule> create(RuleAction result)
- {
- return std::shared_ptr<ImplicitRule>(new ImplicitRule(result));
- }
-};
diff --git a/libraries/logic/minecraft/VersionBuildError.h b/libraries/logic/minecraft/VersionBuildError.h
deleted file mode 100644
index fda453e5..00000000
--- a/libraries/logic/minecraft/VersionBuildError.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "Exception.h"
-
-class VersionBuildError : public Exception
-{
-public:
- explicit VersionBuildError(QString cause) : Exception(cause) {}
- virtual ~VersionBuildError() noexcept
- {
- }
-};
-
-/**
- * the base version file was meant for a newer version of the vanilla launcher than we support
- */
-class LauncherVersionError : public VersionBuildError
-{
-public:
- LauncherVersionError(int actual, int supported)
- : VersionBuildError(QObject::tr(
- "The base version file of this instance was meant for a newer (%1) "
- "version of the vanilla launcher than this version of MultiMC supports (%2).")
- .arg(actual)
- .arg(supported)) {};
- virtual ~LauncherVersionError() noexcept
- {
- }
-};
-
-/**
- * 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
-{
-public:
- VersionIncomplete(QString missingPatch)
- : VersionBuildError(QObject::tr("Version is incomplete: missing %1.")
- .arg(missingPatch)) {};
- virtual ~VersionIncomplete() noexcept
- {
- }
-};
diff --git a/libraries/logic/minecraft/VersionFile.cpp b/libraries/logic/minecraft/VersionFile.cpp
deleted file mode 100644
index 573c4cb4..00000000
--- a/libraries/logic/minecraft/VersionFile.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <QJsonArray>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-#include "minecraft/VersionFile.h"
-#include "minecraft/Library.h"
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/JarMod.h"
-#include "ParseUtils.h"
-
-#include "VersionBuildError.h"
-#include <Version.h>
-
-bool VersionFile::isMinecraftVersion()
-{
- return fileId == "net.minecraft";
-}
-
-bool VersionFile::hasJarMods()
-{
- return !jarMods.isEmpty();
-}
-
-void VersionFile::applyTo(MinecraftProfile *profile)
-{
- auto theirVersion = profile->getMinecraftVersion();
- if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
- {
- if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
- {
- throw MinecraftVersionMismatch(fileId, dependsOnMinecraftVersion, theirVersion);
- }
- }
- 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);
-
- for (auto library : libraries)
- {
- profile->applyLibrary(library);
- }
- profile->applyProblemSeverity(getProblemSeverity());
- auto iter = mojangDownloads.begin();
- while(iter != mojangDownloads.end())
- {
- profile->applyMojangDownload(iter.key(), iter.value());
- iter++;
- }
-}
diff --git a/libraries/logic/minecraft/VersionFile.h b/libraries/logic/minecraft/VersionFile.h
deleted file mode 100644
index 1b692f0f..00000000
--- a/libraries/logic/minecraft/VersionFile.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QStringList>
-#include <QDateTime>
-#include <QSet>
-
-#include <memory>
-#include "minecraft/OpSys.h"
-#include "minecraft/Rule.h"
-#include "ProfilePatch.h"
-#include "Library.h"
-#include "JarMod.h"
-
-class MinecraftProfile;
-class VersionFile;
-struct MojangDownloadInfo;
-struct MojangAssetIndexInfo;
-
-typedef std::shared_ptr<VersionFile> VersionFilePtr;
-class VersionFile : public ProfilePatch
-{
- 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 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;
- }
-
-
-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;
-
- /// MultiMC: human readable name of this package
- QString name;
-
- /// MultiMC: package ID of this package
- QString fileId;
-
- /// MultiMC: version of this package
- QString version;
-
- /// MultiMC: dependency on a Minecraft version
- QString dependsOnMinecraftVersion;
-
- /// Mojang: used to version the Mojang version format
- int minimumLauncherVersion = -1;
-
- /// Mojang: 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)
- QString appletClass;
-
- /// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
- QString minecraftArguments;
-
- /// Mojang: type of the Minecraft version
- QString type;
-
- /// Mojang: the time this version was actually released by Mojang
- QDateTime m_releaseTime;
-
- /// Mojang: the time this version was last updated by Mojang
- QDateTime m_updateTime;
-
- /// Mojang: DEPRECATED asset group to be used with Minecraft
- QString assets;
-
- /// MultiMC: list of tweaker mod arguments for launchwrapper
- QStringList addTweakers;
-
- /// Mojang: list of libraries to add to the version
- QList<LibraryPtr> libraries;
-
- /// MultiMC: list of attached traits of this version file - used to enable features
- QSet<QString> traits;
-
- /// MultiMC: list of jar mods added to this version
- QList<JarmodPtr> jarMods;
-
-public:
- // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more.
- QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
-
- // Mojang: extended asset index download information
- std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
-};
-
-
diff --git a/libraries/logic/minecraft/VersionFilterData.cpp b/libraries/logic/minecraft/VersionFilterData.cpp
deleted file mode 100644
index 0c4a6e3d..00000000
--- a/libraries/logic/minecraft/VersionFilterData.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "VersionFilterData.h"
-#include "ParseUtils.h"
-
-VersionFilterData g_VersionFilterData = VersionFilterData();
-
-VersionFilterData::VersionFilterData()
-{
- // 1.3.*
- auto libs13 =
- QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}};
-
- fmlLibsMapping["1.3.2"] = libs13;
-
- // 1.4.*
- auto libs14 = QList<FMLlib>{
- {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false},
- {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}};
-
- fmlLibsMapping["1.4"] = libs14;
- fmlLibsMapping["1.4.1"] = libs14;
- fmlLibsMapping["1.4.2"] = libs14;
- fmlLibsMapping["1.4.3"] = libs14;
- fmlLibsMapping["1.4.4"] = libs14;
- fmlLibsMapping["1.4.5"] = libs14;
- fmlLibsMapping["1.4.6"] = libs14;
- fmlLibsMapping["1.4.7"] = libs14;
-
- // 1.5
- fmlLibsMapping["1.5"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // 1.5.1
- fmlLibsMapping["1.5.1"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // 1.5.2
- fmlLibsMapping["1.5.2"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // 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)
- */
- 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/libraries/logic/minecraft/VersionFilterData.h b/libraries/logic/minecraft/VersionFilterData.h
deleted file mode 100644
index f7d4ebe7..00000000
--- a/libraries/logic/minecraft/VersionFilterData.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-#include <QMap>
-#include <QString>
-#include <QSet>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-struct FMLlib
-{
- QString filename;
- QString checksum;
- bool ours;
-};
-
-struct VersionFilterData
-{
- VersionFilterData();
- // mapping between minecraft versions and FML libraries required
- 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/libraries/logic/minecraft/World.cpp b/libraries/logic/minecraft/World.cpp
deleted file mode 100644
index 6081a8ec..00000000
--- a/libraries/logic/minecraft/World.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <QDir>
-#include <QString>
-#include <QDebug>
-#include <QSaveFile>
-#include "World.h"
-
-#include "GZip.h"
-#include <MMCZip.h>
-#include <FileSystem.h>
-#include <sstream>
-#include <io/stream_reader.h>
-#include <tag_string.h>
-#include <tag_primitive.h>
-#include <quazip.h>
-#include <quazipfile.h>
-#include <quazipdir.h>
-
-std::unique_ptr <nbt::tag_compound> parseLevelDat(QByteArray data)
-{
- QByteArray output;
- if(!GZip::unzip(data, output))
- {
- return nullptr;
- }
- std::istringstream foo(std::string(output.constData(), output.size()));
- auto pair = nbt::io::read_compound(foo);
-
- if(pair.first != "")
- return nullptr;
-
- if(pair.second == nullptr)
- return nullptr;
-
- return std::move(pair.second);
-}
-
-QByteArray serializeLevelDat(nbt::tag_compound * levelInfo)
-{
- std::ostringstream s;
- nbt::io::write_tag("", *levelInfo, s);
- QByteArray val( s.str().data(), (int) s.str().size() );
- return val;
-}
-
-QString getLevelDatFromFS(const QFileInfo &file)
-{
- QDir worldDir(file.filePath());
- if(!file.isDir() || !worldDir.exists("level.dat"))
- {
- return QString();
- }
- return worldDir.absoluteFilePath("level.dat");
-}
-
-QByteArray getLevelDatDataFromFS(const QFileInfo &file)
-{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return QByteArray();
- }
- QFile f(fullFilePath);
- if(!f.open(QIODevice::ReadOnly))
- {
- return QByteArray();
- }
- return f.readAll();
-}
-
-bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data)
-{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return false;
- }
- QSaveFile f(fullFilePath);
- if(!f.open(QIODevice::WriteOnly))
- {
- return false;
- }
- QByteArray compressed;
- if(!GZip::zip(data, compressed))
- {
- return false;
- }
- if(f.write(compressed) != compressed.size())
- {
- f.cancelWriting();
- return false;
- }
- return f.commit();
-}
-
-World::World(const QFileInfo &file)
-{
- repath(file);
-}
-
-void World::repath(const QFileInfo &file)
-{
- m_containerFile = file;
- m_folderName = file.fileName();
- if(file.isFile() && file.suffix() == "zip")
- {
- readFromZip(file);
- }
- else if(file.isDir())
- {
- readFromFS(file);
- }
-}
-
-void World::readFromFS(const QFileInfo &file)
-{
- auto bytes = getLevelDatDataFromFS(file);
- if(bytes.isEmpty())
- {
- is_valid = false;
- return;
- }
- loadFromLevelDat(bytes);
- levelDatTime = file.lastModified();
-}
-
-void World::readFromZip(const QFileInfo &file)
-{
- QuaZip zip(file.absoluteFilePath());
- is_valid = zip.open(QuaZip::mdUnzip);
- if (!is_valid)
- {
- return;
- }
- auto location = MMCZip::findFileInZip(&zip, "level.dat");
- is_valid = !location.isEmpty();
- if (!is_valid)
- {
- return;
- }
- m_containerOffsetPath = location;
- QuaZipFile zippedFile(&zip);
- // read the install profile
- is_valid = zip.setCurrentFile(location + "level.dat");
- if (!is_valid)
- {
- return;
- }
- is_valid = zippedFile.open(QIODevice::ReadOnly);
- QuaZipFileInfo64 levelDatInfo;
- zippedFile.getFileInfo(&levelDatInfo);
- auto modTime = levelDatInfo.getNTFSmTime();
- if(!modTime.isValid())
- {
- modTime = levelDatInfo.dateTime;
- }
- levelDatTime = modTime;
- if (!is_valid)
- {
- return;
- }
- loadFromLevelDat(zippedFile.readAll());
- zippedFile.close();
-}
-
-bool World::install(const QString &to, const QString &name)
-{
- auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to));
- if(!FS::ensureFolderPathExists(finalPath))
- {
- return false;
- }
- bool ok = false;
- if(m_containerFile.isFile())
- {
- QuaZip zip(m_containerFile.absoluteFilePath());
- if (!zip.open(QuaZip::mdUnzip))
- {
- return false;
- }
- ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
- }
- else if(m_containerFile.isDir())
- {
- QString from = m_containerFile.filePath();
- ok = FS::copy(from, finalPath)();
- }
-
- if(ok && !name.isEmpty() && m_actualName != name)
- {
- World newWorld(finalPath);
- if(newWorld.isValid())
- {
- newWorld.rename(name);
- }
- }
- return ok;
-}
-
-bool World::rename(const QString &newName)
-{
- if(m_containerFile.isFile())
- {
- return false;
- }
-
- auto data = getLevelDatDataFromFS(m_containerFile);
- if(data.isEmpty())
- {
- return false;
- }
-
- auto worldData = parseLevelDat(data);
- if(!worldData)
- {
- return false;
- }
- auto &val = worldData->at("Data");
- if(val.get_type() != nbt::tag_type::Compound)
- {
- return false;
- }
- auto &dataCompound = val.as<nbt::tag_compound>();
- dataCompound.put("LevelName", nbt::value_initializer(newName.toUtf8().data()));
- data = serializeLevelDat(worldData.get());
-
- putLevelDatDataToFS(m_containerFile, data);
-
- m_actualName = newName;
-
- QDir parentDir(m_containerFile.absoluteFilePath());
- parentDir.cdUp();
- QFile container(m_containerFile.absoluteFilePath());
- auto dirName = FS::DirNameFromString(m_actualName, parentDir.absolutePath());
- container.rename(parentDir.absoluteFilePath(dirName));
-
- return true;
-}
-
-static QString read_string (nbt::value& parent, const char * name, const QString & fallback = QString())
-{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::String)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_string>();
- return QString::fromStdString(tag_str.get());
- }
- catch(std::out_of_range e)
- {
- // fallback for old world formats
- qWarning() << "String NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch(std::bad_cast e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to string. Defaulting to" << fallback;
- return fallback;
- }
-};
-
-static int64_t read_long (nbt::value& parent, const char * name, const int64_t & fallback = 0)
-{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::Long)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_long>();
- return tag_str.get();
- }
- catch(std::out_of_range e)
- {
- // fallback for old world formats
- qWarning() << "Long NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch(std::bad_cast e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to long. Defaulting to" << fallback;
- return fallback;
- }
-};
-
-void World::loadFromLevelDat(QByteArray data)
-{
- try
- {
- auto levelData = parseLevelDat(data);
- if(!levelData)
- {
- is_valid = false;
- return;
- }
-
- auto &val = levelData->at("Data");
- is_valid = val.get_type() == nbt::tag_type::Compound;
- if(!is_valid)
- return;
-
- m_actualName = read_string(val, "LevelName", m_folderName);
-
-
- int64_t temp = read_long(val, "LastPlayed", 0);
- if(temp == 0)
- {
- m_lastPlayed = levelDatTime;
- }
- else
- {
- m_lastPlayed = QDateTime::fromMSecsSinceEpoch(temp);
- }
-
- m_randomSeed = read_long(val, "RandomSeed", 0);
-
- qDebug() << "World Name:" << m_actualName;
- qDebug() << "Last Played:" << m_lastPlayed.toString();
- qDebug() << "Seed:" << m_randomSeed;
- }
- catch (nbt::io::input_error e)
- {
- qWarning() << "Unable to load" << m_folderName << ":" << e.what();
- is_valid = false;
- return;
- }
-}
-
-bool World::replace(World &with)
-{
- if (!destroy())
- return false;
- bool success = FS::copy(with.m_containerFile.filePath(), m_containerFile.path())();
- if (success)
- {
- m_folderName = with.m_folderName;
- m_containerFile.refresh();
- }
- return success;
-}
-
-bool World::destroy()
-{
- if(!is_valid) return false;
- if (m_containerFile.isDir())
- {
- QDir d(m_containerFile.filePath());
- return d.removeRecursively();
- }
- else if(m_containerFile.isFile())
- {
- QFile file(m_containerFile.absoluteFilePath());
- return file.remove();
- }
- return true;
-}
-
-bool World::operator==(const World &other) const
-{
- return is_valid == other.is_valid && folderName() == other.folderName();
-}
-bool World::strongCompare(const World &other) const
-{
- return is_valid == other.is_valid && folderName() == other.folderName();
-}
diff --git a/libraries/logic/minecraft/World.h b/libraries/logic/minecraft/World.h
deleted file mode 100644
index 3cde5ea4..00000000
--- a/libraries/logic/minecraft/World.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright 2015 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 <QFileInfo>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT World
-{
-public:
- World(const QFileInfo &file);
- QString folderName() const
- {
- return m_folderName;
- }
- QString name() const
- {
- return m_actualName;
- }
- QDateTime lastPlayed() const
- {
- return m_lastPlayed;
- }
- int64_t seed() const
- {
- return m_randomSeed;
- }
- bool isValid() const
- {
- return is_valid;
- }
- bool isOnFS() const
- {
- return m_containerFile.isDir();
- }
- QFileInfo container() const
- {
- return m_containerFile;
- }
- // delete all the files of this world
- bool destroy();
- // replace this world with a copy of the other
- bool replace(World &with);
- // change the world's filesystem path (used by world lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
-
- bool rename(const QString &to);
- bool install(const QString &to, const QString &name= QString());
-
- // WEAK compare operator - used for replacing worlds
- bool operator==(const World &other) const;
- bool strongCompare(const World &other) const;
-
-private:
- void readFromZip(const QFileInfo &file);
- void readFromFS(const QFileInfo &file);
- void loadFromLevelDat(QByteArray data);
-
-protected:
-
- QFileInfo m_containerFile;
- QString m_containerOffsetPath;
- QString m_folderName;
- QString m_actualName;
- QDateTime levelDatTime;
- QDateTime m_lastPlayed;
- int64_t m_randomSeed = 0;
- bool is_valid = false;
-};
diff --git a/libraries/logic/minecraft/WorldList.cpp b/libraries/logic/minecraft/WorldList.cpp
deleted file mode 100644
index 42c8a3e6..00000000
--- a/libraries/logic/minecraft/WorldList.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/* Copyright 2015 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 "WorldList.h"
-#include <FileSystem.h>
-#include <QMimeData>
-#include <QUrl>
-#include <QUuid>
-#include <QString>
-#include <QFileSystemWatcher>
-#include <QDebug>
-
-WorldList::WorldList(const QString &dir)
- : QAbstractListModel(), m_dir(dir)
-{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_watcher = new QFileSystemWatcher(this);
- is_watching = false;
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
- SLOT(directoryChanged(QString)));
-}
-
-void WorldList::startWatching()
-{
- update();
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
-}
-
-void WorldList::stopWatching()
-{
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
-}
-
-bool WorldList::update()
-{
- if (!isValid())
- return false;
-
- QList<World> newWorlds;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- // if there are any untracked files...
- for (QFileInfo entry : folderContents)
- {
- if(!entry.isDir())
- continue;
-
- World w(entry);
- if(w.isValid())
- {
- newWorlds.append(w);
- }
- }
- beginResetModel();
- worlds.swap(newWorlds);
- endResetModel();
- return true;
-}
-
-void WorldList::directoryChanged(QString path)
-{
- update();
-}
-
-bool WorldList::isValid()
-{
- return m_dir.exists() && m_dir.isReadable();
-}
-
-bool WorldList::deleteWorld(int index)
-{
- if (index >= worlds.size() || index < 0)
- return false;
- World &m = worlds[index];
- if (m.destroy())
- {
- beginRemoveRows(QModelIndex(), index, index);
- worlds.removeAt(index);
- endRemoveRows();
- emit changed();
- return true;
- }
- return false;
-}
-
-bool WorldList::deleteWorlds(int first, int last)
-{
- for (int i = first; i <= last; i++)
- {
- World &m = worlds[i];
- m.destroy();
- }
- beginRemoveRows(QModelIndex(), first, last);
- worlds.erase(worlds.begin() + first, worlds.begin() + last + 1);
- endRemoveRows();
- emit changed();
- return true;
-}
-
-int WorldList::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-QVariant WorldList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= worlds.size())
- return QVariant();
-
- auto & world = worlds[row];
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return world.name();
-
- case LastPlayedColumn:
- return world.lastPlayed();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- {
- return world.folderName();
- }
- case ObjectRole:
- {
- return QVariant::fromValue<void *>((void *)&world);
- }
- case FolderRole:
- {
- return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName()));
- }
- case SeedRole:
- {
- return qVariantFromValue<qlonglong>(world.seed());
- }
- case NameRole:
- {
- return world.name();
- }
- case LastPlayedRole:
- {
- return world.lastPlayed();
- }
- default:
- return QVariant();
- }
-}
-
-QVariant WorldList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case NameColumn:
- return tr("Name");
- case LastPlayedColumn:
- return tr("Last Played");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the world.");
- case LastPlayedColumn:
- return tr("Date and time the world was last played.");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
-}
-
-QStringList WorldList::mimeTypes() const
-{
- QStringList types;
- types << "text/uri-list";
- return types;
-}
-
-class WorldMimeData : public QMimeData
-{
-Q_OBJECT
-
-public:
- WorldMimeData(QList<World> worlds)
- {
- m_worlds = worlds;
-
- }
- QStringList formats() const
- {
- return QMimeData::formats() << "text/uri-list";
- }
-
-protected:
- QVariant retrieveData(const QString &mimetype, QVariant::Type type) const
- {
- QList<QUrl> urls;
- for(auto &world: m_worlds)
- {
- if(!world.isValid() || !world.isOnFS())
- continue;
- QString worldPath = world.container().absoluteFilePath();
- qDebug() << worldPath;
- urls.append(QUrl::fromLocalFile(worldPath));
- }
- const_cast<WorldMimeData*>(this)->setUrls(urls);
- return QMimeData::retrieveData(mimetype, type);
- }
-private:
- QList<World> m_worlds;
-};
-
-QMimeData *WorldList::mimeData(const QModelIndexList &indexes) const
-{
- if (indexes.size() == 0)
- return new QMimeData();
-
- QList<World> worlds;
- for(auto idx : indexes)
- {
- if(idx.column() != 0)
- continue;
- int row = idx.row();
- if (row < 0 || row >= this->worlds.size())
- continue;
- worlds.append(this->worlds[row]);
- }
- if(!worlds.size())
- {
- return new QMimeData();
- }
- return new WorldMimeData(worlds);
-}
-
-Qt::ItemFlags WorldList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
-}
-
-Qt::DropActions WorldList::supportedDragActions() const
-{
- // move to other mod lists or VOID
- return Qt::MoveAction;
-}
-
-Qt::DropActions WorldList::supportedDropActions() const
-{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
-}
-
-void WorldList::installWorld(QFileInfo filename)
-{
- qDebug() << "installing: " << filename.absoluteFilePath();
- World w(filename);
- if(!w.isValid())
- {
- return;
- }
- w.install(m_dir.absolutePath());
-}
-
-bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
-{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- stopWatching();
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- QString filename = url.toLocalFile();
-
- QFileInfo worldInfo(filename);
-
- if(!m_dir.entryInfoList().contains(worldInfo))
- {
- installWorld(worldInfo);
- }
- }
- if (was_watching)
- startWatching();
- return true;
- }
- return false;
-}
-
-#include "WorldList.moc"
diff --git a/libraries/logic/minecraft/WorldList.h b/libraries/logic/minecraft/WorldList.h
deleted file mode 100644
index 34b30e9c..00000000
--- a/libraries/logic/minecraft/WorldList.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright 2015 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 <QList>
-#include <QString>
-#include <QDir>
-#include <QAbstractListModel>
-#include <QMimeData>
-#include "minecraft/World.h"
-
-#include "multimc_logic_export.h"
-
-class QFileSystemWatcher;
-
-class MULTIMC_LOGIC_EXPORT WorldList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum Columns
- {
- NameColumn,
- LastPlayedColumn
- };
-
- enum Roles
- {
- ObjectRole = Qt::UserRole + 1,
- FolderRole,
- SeedRole,
- NameRole,
- LastPlayedRole
- };
-
- WorldList(const QString &dir);
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return size();
- };
- virtual QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
- size_t size() const
- {
- return worlds.size();
- };
- bool empty() const
- {
- return size() == 0;
- }
- World &operator[](size_t index)
- {
- return worlds[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /// Install a world from location
- void installWorld(QFileInfo filename);
-
- /// Deletes the mod at the given index.
- virtual bool deleteWorld(int index);
-
- /// Deletes all the selected mods
- virtual bool deleteWorlds(int first, int last);
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- /// get data for drag action
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
- /// get the supported mime types
- virtual QStringList mimeTypes() const;
- /// process data from drop action
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
- /// what drag actions do we support?
- virtual Qt::DropActions supportedDragActions() const;
-
- /// what drop actions do we support?
- virtual Qt::DropActions supportedDropActions() const;
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir() const
- {
- return m_dir;
- }
-
- const QList<World> &allWorlds() const
- {
- return worlds;
- }
-
-private slots:
- void directoryChanged(QString path);
-
-signals:
- void changed();
-
-protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching;
- QDir m_dir;
- QList<World> worlds;
-};
diff --git a/libraries/logic/minecraft/auth/AuthSession.cpp b/libraries/logic/minecraft/auth/AuthSession.cpp
deleted file mode 100644
index 8758bfbd..00000000
--- a/libraries/logic/minecraft/auth/AuthSession.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "AuthSession.h"
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonDocument>
-#include <QStringList>
-
-QString AuthSession::serializeUserProperties()
-{
- QJsonObject userAttrs;
- for (auto key : u.properties.keys())
- {
- auto array = QJsonArray::fromStringList(u.properties.values(key));
- userAttrs.insert(key, array);
- }
- QJsonDocument value(userAttrs);
- return value.toJson(QJsonDocument::Compact);
-
-}
-
-bool AuthSession::MakeOffline(QString offline_playername)
-{
- if (status != PlayableOffline && status != PlayableOnline)
- {
- return false;
- }
- session = "-";
- player_name = offline_playername;
- status = PlayableOffline;
- return true;
-}
diff --git a/libraries/logic/minecraft/auth/AuthSession.h b/libraries/logic/minecraft/auth/AuthSession.h
deleted file mode 100644
index dede90a9..00000000
--- a/libraries/logic/minecraft/auth/AuthSession.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QMultiMap>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-struct User
-{
- QString id;
- QMultiMap<QString, QString> properties;
-};
-
-struct MULTIMC_LOGIC_EXPORT AuthSession
-{
- bool MakeOffline(QString offline_playername);
-
- QString serializeUserProperties();
-
- enum Status
- {
- Undetermined,
- RequiresPassword,
- PlayableOffline,
- PlayableOnline
- } status = Undetermined;
-
- User u;
-
- // client token
- QString client_token;
- // account user name
- QString username;
- // combined session ID
- QString session;
- // volatile auth token
- QString access_token;
- // profile name
- QString player_name;
- // profile ID
- QString uuid;
- // 'legacy' or 'mojang', depending on account type
- QString user_type;
- // Did the auth server reply?
- bool auth_server_online = false;
- // Did the user request online mode?
- bool wants_online = true;
-};
-
-typedef std::shared_ptr<AuthSession> AuthSessionPtr;
diff --git a/libraries/logic/minecraft/auth/MojangAccount.cpp b/libraries/logic/minecraft/auth/MojangAccount.cpp
deleted file mode 100644
index 69a24c09..00000000
--- a/libraries/logic/minecraft/auth/MojangAccount.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * 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 "MojangAccount.h"
-#include "flows/RefreshTask.h"
-#include "flows/AuthenticateTask.h"
-
-#include <QUuid>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QRegExp>
-#include <QStringList>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
-{
- // The JSON object must at least have a username for it to be valid.
- if (!object.value("username").isString())
- {
- qCritical() << "Can't load Mojang account info from JSON object. Username field is "
- "missing or of the wrong type.";
- return nullptr;
- }
-
- QString username = object.value("username").toString("");
- QString clientToken = object.value("clientToken").toString("");
- QString accessToken = object.value("accessToken").toString("");
-
- QJsonArray profileArray = object.value("profiles").toArray();
- if (profileArray.size() < 1)
- {
- qCritical() << "Can't load Mojang account with username \"" << username
- << "\". No profiles found.";
- return nullptr;
- }
-
- QList<AccountProfile> profiles;
- for (QJsonValue profileVal : profileArray)
- {
- QJsonObject profileObject = profileVal.toObject();
- QString id = profileObject.value("id").toString("");
- QString name = profileObject.value("name").toString("");
- bool legacy = profileObject.value("legacy").toBool(false);
- if (id.isEmpty() || name.isEmpty())
- {
- qWarning() << "Unable to load a profile because it was missing an ID or a name.";
- continue;
- }
- profiles.append({id, name, legacy});
- }
-
- MojangAccountPtr account(new MojangAccount());
- if (object.value("user").isObject())
- {
- User u;
- QJsonObject userStructure = object.value("user").toObject();
- u.id = userStructure.value("id").toString();
- /*
- QJsonObject propMap = userStructure.value("properties").toObject();
- for(auto key: propMap.keys())
- {
- auto values = propMap.operator[](key).toArray();
- for(auto value: values)
- u.properties.insert(key, value.toString());
- }
- */
- account->m_user = u;
- }
- account->m_username = username;
- account->m_clientToken = clientToken;
- account->m_accessToken = accessToken;
- account->m_profiles = profiles;
-
- // Get the currently selected profile.
- QString currentProfile = object.value("activeProfile").toString("");
- if (!currentProfile.isEmpty())
- account->setCurrentProfile(currentProfile);
-
- return account;
-}
-
-MojangAccountPtr MojangAccount::createFromUsername(const QString &username)
-{
- MojangAccountPtr account(new MojangAccount());
- account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
- account->m_username = username;
- return account;
-}
-
-QJsonObject MojangAccount::saveToJson() const
-{
- QJsonObject json;
- json.insert("username", m_username);
- json.insert("clientToken", m_clientToken);
- json.insert("accessToken", m_accessToken);
-
- QJsonArray profileArray;
- for (AccountProfile profile : m_profiles)
- {
- QJsonObject profileObj;
- profileObj.insert("id", profile.id);
- profileObj.insert("name", profile.name);
- profileObj.insert("legacy", profile.legacy);
- profileArray.append(profileObj);
- }
- json.insert("profiles", profileArray);
-
- QJsonObject userStructure;
- {
- userStructure.insert("id", m_user.id);
- /*
- QJsonObject userAttrs;
- for(auto key: m_user.properties.keys())
- {
- auto array = QJsonArray::fromStringList(m_user.properties.values(key));
- userAttrs.insert(key, array);
- }
- userStructure.insert("properties", userAttrs);
- */
- }
- json.insert("user", userStructure);
-
- if (m_currentProfile != -1)
- json.insert("activeProfile", currentProfile()->id);
-
- return json;
-}
-
-bool MojangAccount::setCurrentProfile(const QString &profileId)
-{
- for (int i = 0; i < m_profiles.length(); i++)
- {
- if (m_profiles[i].id == profileId)
- {
- m_currentProfile = i;
- return true;
- }
- }
- return false;
-}
-
-const AccountProfile *MojangAccount::currentProfile() const
-{
- if (m_currentProfile == -1)
- return nullptr;
- return &m_profiles[m_currentProfile];
-}
-
-AccountStatus MojangAccount::accountStatus() const
-{
- if (m_accessToken.isEmpty())
- return NotVerified;
- else
- return Verified;
-}
-
-std::shared_ptr<YggdrasilTask> MojangAccount::login(AuthSessionPtr session,
- QString password)
-{
- Q_ASSERT(m_currentTask.get() == nullptr);
-
- // take care of the true offline status
- if (accountStatus() == NotVerified && password.isEmpty())
- {
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- fillSession(session);
- }
- return nullptr;
- }
-
- if (password.isEmpty())
- {
- m_currentTask.reset(new RefreshTask(this));
- }
- else
- {
- m_currentTask.reset(new AuthenticateTask(this, password));
- }
- m_currentTask->assignSession(session);
-
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
- return m_currentTask;
-}
-
-void MojangAccount::authSucceeded()
-{
- auto session = m_currentTask->getAssignedSession();
- if (session)
- {
- session->status =
- session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
- fillSession(session);
- session->auth_server_online = true;
- }
- m_currentTask.reset();
- emit changed();
-}
-
-void MojangAccount::authFailed(QString reason)
-{
- auto session = m_currentTask->getAssignedSession();
- // This is emitted when the yggdrasil tasks time out or are cancelled.
- // -> we treat the error as no-op
- if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT)
- {
- if (session)
- {
- session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
- : AuthSession::RequiresPassword;
- session->auth_server_online = false;
- fillSession(session);
- }
- }
- else
- {
- m_accessToken = QString();
- emit changed();
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- session->auth_server_online = true;
- fillSession(session);
- }
- }
- m_currentTask.reset();
-}
-
-void MojangAccount::fillSession(AuthSessionPtr session)
-{
- // the user name. you have to have an user name
- session->username = m_username;
- // volatile auth token
- session->access_token = m_accessToken;
- // the semi-permanent client token
- session->client_token = m_clientToken;
- if (currentProfile())
- {
- // profile name
- session->player_name = currentProfile()->name;
- // profile ID
- session->uuid = currentProfile()->id;
- // 'legacy' or 'mojang', depending on account type
- session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
- if (!session->access_token.isEmpty())
- {
- session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
- }
- else
- {
- session->session = "-";
- }
- }
- else
- {
- session->player_name = "Player";
- session->session = "-";
- }
- session->u = user();
-}
diff --git a/libraries/logic/minecraft/auth/MojangAccount.h b/libraries/logic/minecraft/auth/MojangAccount.h
deleted file mode 100644
index 2de0c19c..00000000
--- a/libraries/logic/minecraft/auth/MojangAccount.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright 2013-2015 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 <QList>
-#include <QJsonObject>
-#include <QPair>
-#include <QMap>
-
-#include <memory>
-#include "AuthSession.h"
-
-#include "multimc_logic_export.h"
-
-class Task;
-class YggdrasilTask;
-class MojangAccount;
-
-typedef std::shared_ptr<MojangAccount> MojangAccountPtr;
-Q_DECLARE_METATYPE(MojangAccountPtr)
-
-/**
- * A profile within someone's Mojang account.
- *
- * Currently, the profile system has not been implemented by Mojang yet,
- * but we might as well add some things for it in MultiMC right now so
- * we don't have to rip the code to pieces to add it later.
- */
-struct AccountProfile
-{
- QString id;
- QString name;
- bool legacy;
-};
-
-enum AccountStatus
-{
- NotVerified,
- Verified
-};
-
-/**
- * Object that stores information about a certain Mojang account.
- *
- * Said information may include things such as that account's username, client token, and access
- * token if the user chose to stay logged in.
- */
-class MULTIMC_LOGIC_EXPORT MojangAccount : public QObject
-{
- Q_OBJECT
-public: /* construction */
- //! Do not copy accounts. ever.
- explicit MojangAccount(const MojangAccount &other, QObject *parent) = delete;
-
- //! Default constructor
- explicit MojangAccount(QObject *parent = 0) : QObject(parent) {};
-
- //! Creates an empty account for the specified user name.
- static MojangAccountPtr createFromUsername(const QString &username);
-
- //! Loads a MojangAccount from the given JSON object.
- static MojangAccountPtr loadFromJson(const QJsonObject &json);
-
- //! Saves a MojangAccount to a JSON object and returns it.
- QJsonObject saveToJson() const;
-
-public: /* manipulation */
- /**
- * Sets the currently selected profile to the profile with the given ID string.
- * If profileId is not in the list of available profiles, the function will simply return
- * false.
- */
- bool setCurrentProfile(const QString &profileId);
-
- /**
- * Attempt to login. Empty password means we use the token.
- * If the attempt fails because we already are performing some task, it returns false.
- */
- std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session,
- QString password = QString());
-
-public: /* queries */
- const QString &username() const
- {
- return m_username;
- }
-
- const QString &clientToken() const
- {
- return m_clientToken;
- }
-
- const QString &accessToken() const
- {
- return m_accessToken;
- }
-
- const QList<AccountProfile> &profiles() const
- {
- return m_profiles;
- }
-
- const User &user()
- {
- return m_user;
- }
-
- //! Returns the currently selected profile (if none, returns nullptr)
- const AccountProfile *currentProfile() const;
-
- //! Returns whether the account is NotVerified, Verified or Online
- AccountStatus accountStatus() const;
-
-signals:
- /**
- * This signal is emitted when the account changes
- */
- void changed();
-
- // TODO: better signalling for the various possible state changes - especially errors
-
-protected: /* variables */
- QString m_username;
-
- // Used to identify the client - the user can have multiple clients for the same account
- // Think: different launchers, all connecting to the same account/profile
- QString m_clientToken;
-
- // Blank if not logged in.
- QString m_accessToken;
-
- // Index of the selected profile within the list of available
- // profiles. -1 if nothing is selected.
- int m_currentProfile = -1;
-
- // List of available profiles.
- QList<AccountProfile> m_profiles;
-
- // the user structure, whatever it is.
- User m_user;
-
- // current task we are executing here
- std::shared_ptr<YggdrasilTask> m_currentTask;
-
-private
-slots:
- void authSucceeded();
- void authFailed(QString reason);
-
-private:
- void fillSession(AuthSessionPtr session);
-
-public:
- friend class YggdrasilTask;
- friend class AuthenticateTask;
- friend class ValidateTask;
- friend class RefreshTask;
-};
diff --git a/libraries/logic/minecraft/auth/MojangAccountList.cpp b/libraries/logic/minecraft/auth/MojangAccountList.cpp
deleted file mode 100644
index 26cbc81a..00000000
--- a/libraries/logic/minecraft/auth/MojangAccountList.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/* Copyright 2013-2015 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 "MojangAccountList.h"
-#include "MojangAccount.h"
-
-#include <QIODevice>
-#include <QFile>
-#include <QTextStream>
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QJsonObject>
-#include <QJsonParseError>
-#include <QDir>
-
-#include <QDebug>
-
-#include <FileSystem.h>
-
-#define ACCOUNT_LIST_FORMAT_VERSION 2
-
-MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-MojangAccountPtr MojangAccountList::findAccount(const QString &username) const
-{
- for (int i = 0; i < count(); i++)
- {
- MojangAccountPtr account = at(i);
- if (account->username() == username)
- return account;
- }
- return nullptr;
-}
-
-const MojangAccountPtr MojangAccountList::at(int i) const
-{
- return MojangAccountPtr(m_accounts.at(i));
-}
-
-void MojangAccountList::addAccount(const MojangAccountPtr account)
-{
- beginResetModel();
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- endResetModel();
- onListChanged();
-}
-
-void MojangAccountList::removeAccount(const QString &username)
-{
- beginResetModel();
- for (auto account : m_accounts)
- {
- if (account->username() == username)
- {
- m_accounts.removeOne(account);
- return;
- }
- }
- endResetModel();
- onListChanged();
-}
-
-void MojangAccountList::removeAccount(QModelIndex index)
-{
- beginResetModel();
- m_accounts.removeAt(index.row());
- endResetModel();
- onListChanged();
-}
-
-MojangAccountPtr MojangAccountList::activeAccount() const
-{
- return m_activeAccount;
-}
-
-void MojangAccountList::setActiveAccount(const QString &username)
-{
- beginResetModel();
- if (username.isEmpty())
- {
- m_activeAccount = nullptr;
- }
- else
- {
- for (MojangAccountPtr account : m_accounts)
- {
- if (account->username() == username)
- m_activeAccount = account;
- }
- }
- endResetModel();
- onActiveChanged();
-}
-
-void MojangAccountList::accountChanged()
-{
- // the list changed. there is no doubt.
- onListChanged();
-}
-
-void MojangAccountList::onListChanged()
-{
- if (m_autosave)
- // TODO: Alert the user if this fails.
- saveList();
-
- emit listChanged();
-}
-
-void MojangAccountList::onActiveChanged()
-{
- if (m_autosave)
- saveList();
-
- emit activeAccountChanged();
-}
-
-int MojangAccountList::count() const
-{
- return m_accounts.count();
-}
-
-QVariant MojangAccountList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- MojangAccountPtr account = at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case NameColumn:
- return account->username();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return account->username();
-
- case PointerRole:
- return qVariantFromValue(account);
-
- case Qt::CheckStateRole:
- switch (index.column())
- {
- case ActiveColumn:
- return account == m_activeAccount;
- }
-
- default:
- return QVariant();
- }
-}
-
-QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Active?");
-
- case NameColumn:
- return tr("Name");
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the version.");
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
-}
-
-int MojangAccountList::rowCount(const QModelIndex &parent) const
-{
- // Return count
- return count();
-}
-
-int MojangAccountList::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-Qt::ItemFlags MojangAccountList::flags(const QModelIndex &index) const
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return Qt::NoItemFlags;
- }
-
- return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-}
-
-bool MojangAccountList::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if(role == Qt::CheckStateRole)
- {
- if(value == Qt::Checked)
- {
- MojangAccountPtr account = this->at(index.row());
- this->setActiveAccount(account->username());
- }
- }
-
- emit dataChanged(index, index);
- return true;
-}
-
-void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
-{
- beginResetModel();
- m_accounts = versions;
- endResetModel();
-}
-
-bool MojangAccountList::loadList(const QString &filePath)
-{
- QString path = filePath;
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't load Mojang account list. No file path given and no default set.";
- return false;
- }
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << QString("Failed to parse account list file: %1 at offset %2")
- .arg(parseError.errorString(), QString::number(parseError.offset))
- .toUtf8();
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid account list JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Make sure the format version matches.
- if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION)
- {
- QString newName = "accounts-old.json";
- qWarning() << "Format version mismatch when loading account list. Existing one will be renamed to"
- << newName;
-
- // Attempt to rename the old version.
- file.rename(newName);
- return false;
- }
-
- // Now, load the accounts array.
- beginResetModel();
- QJsonArray accounts = root.value("accounts").toArray();
- for (QJsonValue accountVal : accounts)
- {
- QJsonObject accountObj = accountVal.toObject();
- MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
- if (account.get() != nullptr)
- {
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- }
- else
- {
- qWarning() << "Failed to load an account.";
- }
- }
- // Load the active account.
- m_activeAccount = findAccount(root.value("activeAccount").toString(""));
- endResetModel();
- return true;
-}
-
-bool MojangAccountList::saveList(const QString &filePath)
-{
- QString path(filePath);
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't save Mojang account list. No file path given and no default set.";
- return false;
- }
-
- // make sure the parent folder exists
- if(!FS::ensureFilePathExists(path))
- return false;
-
- // make sure the file wasn't overwritten with a folder before (fixes a bug)
- QFileInfo finfo(path);
- if(finfo.isDir())
- {
- QDir badDir(path);
- badDir.removeRecursively();
- }
-
- qDebug() << "Writing account list to" << path;
-
- qDebug() << "Building JSON data structure.";
- // Build the JSON document to write to the list file.
- QJsonObject root;
-
- root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION);
-
- // Build a list of accounts.
- qDebug() << "Building account array.";
- QJsonArray accounts;
- for (MojangAccountPtr account : m_accounts)
- {
- QJsonObject accountObj = account->saveToJson();
- accounts.append(accountObj);
- }
-
- // Insert the account list into the root object.
- root.insert("accounts", accounts);
-
- if(m_activeAccount)
- {
- // Save the active account.
- root.insert("activeAccount", m_activeAccount->username());
- }
-
- // Create a JSON document object to convert our JSON to bytes.
- QJsonDocument doc(root);
-
- // Now that we're done building the JSON object, we can write it to the file.
- qDebug() << "Writing account list to file.";
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::WriteOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Write the JSON to the file.
- file.write(doc.toJson());
- file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser);
- file.close();
-
- qDebug() << "Saved account list to" << path;
-
- return true;
-}
-
-void MojangAccountList::setListFilePath(QString path, bool autosave)
-{
- m_listFilePath = path;
- m_autosave = autosave;
-}
-
-bool MojangAccountList::anyAccountIsValid()
-{
- for(auto account:m_accounts)
- {
- if(account->accountStatus() != NotVerified)
- return true;
- }
- return false;
-}
diff --git a/libraries/logic/minecraft/auth/MojangAccountList.h b/libraries/logic/minecraft/auth/MojangAccountList.h
deleted file mode 100644
index c40fa6a3..00000000
--- a/libraries/logic/minecraft/auth/MojangAccountList.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Copyright 2013-2015 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 "MojangAccount.h"
-
-#include <QObject>
-#include <QVariant>
-#include <QAbstractListModel>
-#include <QSharedPointer>
-
-#include "multimc_logic_export.h"
-
-/*!
- * \brief List of available Mojang accounts.
- * This should be loaded in the background by MultiMC on startup.
- *
- * This class also inherits from QAbstractListModel. Methods from that
- * class determine how this list shows up in a list view. Said methods
- * all have a default implementation, but they can be overridden by subclasses to
- * change the behavior of the list.
- */
-class MULTIMC_LOGIC_EXPORT MojangAccountList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum ModelRoles
- {
- PointerRole = 0x34B1CB48
- };
-
- enum VListColumns
- {
- // TODO: Add icon column.
-
- // First column - Active?
- ActiveColumn = 0,
-
- // Second column - Name
- NameColumn,
- };
-
- explicit MojangAccountList(QObject *parent = 0);
-
- //! Gets the account at the given index.
- virtual const MojangAccountPtr at(int i) const;
-
- //! Returns the number of accounts in the list.
- virtual int count() const;
-
- //////// List Model Functions ////////
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int rowCount(const QModelIndex &parent) const;
- virtual int columnCount(const QModelIndex &parent) const;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
-
- /*!
- * Adds a the given Mojang account to the account list.
- */
- virtual void addAccount(const MojangAccountPtr account);
-
- /*!
- * Removes the mojang account with the given username from the account list.
- */
- virtual void removeAccount(const QString &username);
-
- /*!
- * Removes the account at the given QModelIndex.
- */
- virtual void removeAccount(QModelIndex index);
-
- /*!
- * \brief Finds an account by its username.
- * \param The username of the account to find.
- * \return A const pointer to the account with the given username. NULL if
- * one doesn't exist.
- */
- virtual MojangAccountPtr findAccount(const QString &username) const;
-
- /*!
- * Sets the default path to save the list file to.
- * If autosave is true, this list will automatically save to the given path whenever it changes.
- * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
- * after calling this function to ensure an autosaved change doesn't overwrite the list you intended
- * to load.
- */
- virtual void setListFilePath(QString path, bool autosave = false);
-
- /*!
- * \brief Loads the account list from the given file path.
- * If the given file is an empty string (default), will load from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool loadList(const QString &file = "");
-
- /*!
- * \brief Saves the account list to the given file.
- * If the given file is an empty string (default), will save from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool saveList(const QString &file = "");
-
- /*!
- * \brief Gets a pointer to the account that the user has selected as their "active" account.
- * Which account is active can be overridden on a per-instance basis, but this will return the one that
- * is set as active globally.
- * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer.
- */
- virtual MojangAccountPtr activeAccount() const;
-
- /*!
- * Sets the given account as the current active account.
- * If the username given is an empty string, sets the active account to nothing.
- */
- virtual void setActiveAccount(const QString &username);
-
- /*!
- * Returns true if any of the account is at least Validated
- */
- bool anyAccountIsValid();
-
-signals:
- /*!
- * Signal emitted to indicate that the account list has changed.
- * This will also fire if the value of an element in the list changes (will be implemented
- * later).
- */
- void listChanged();
-
- /*!
- * Signal emitted to indicate that the active account has changed.
- */
- void activeAccountChanged();
-
-public
-slots:
- /**
- * This is called when one of the accounts changes and the list needs to be updated
- */
- void accountChanged();
-
-protected:
- /*!
- * Called whenever the list changes.
- * This emits the listChanged() signal and autosaves the list (if autosave is enabled).
- */
- void onListChanged();
-
- /*!
- * Called whenever the active account changes.
- * Emits the activeAccountChanged() signal and autosaves the list if enabled.
- */
- void onActiveChanged();
-
- QList<MojangAccountPtr> m_accounts;
-
- /*!
- * Account that is currently active.
- */
- MojangAccountPtr m_activeAccount;
-
- //! Path to the account list file. Empty string if there isn't one.
- QString m_listFilePath;
-
- /*!
- * If true, the account list will automatically save to the account list path when it changes.
- * Ignored if m_listFilePath is blank.
- */
- bool m_autosave = false;
-
-protected
-slots:
- /*!
- * Updates this list with the given list of accounts.
- * This is done by copying each account in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the accounts are set to this
- * account list. This can't be done in the load task, because the accounts the load
- * task creates are on the load task's thread and Qt won't allow their parents
- * to be set to something created on another thread.
- * To get around that problem, we invoke this method on the GUI thread, which
- * then copies the accounts and sets their parents correctly.
- * \param accounts List of accounts whose parents should be set.
- */
- virtual void updateListData(QList<MojangAccountPtr> versions);
-};
diff --git a/libraries/logic/minecraft/auth/YggdrasilTask.cpp b/libraries/logic/minecraft/auth/YggdrasilTask.cpp
deleted file mode 100644
index c6971c9f..00000000
--- a/libraries/logic/minecraft/auth/YggdrasilTask.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Copyright 2013-2015 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 "YggdrasilTask.h"
-#include "MojangAccount.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-#include <QJsonDocument>
-#include <QNetworkReply>
-#include <QByteArray>
-
-#include <Env.h>
-
-#include <net/URLConstants.h>
-
-#include <QDebug>
-
-YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent)
- : Task(parent), m_account(account)
-{
- changeState(STATE_CREATED);
-}
-
-void YggdrasilTask::executeTask()
-{
- changeState(STATE_SENDING_REQUEST);
-
- // Get the content of the request we're going to send to the server.
- QJsonDocument doc(getRequestContent());
-
- auto worker = ENV.qnam();
- QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint());
- QNetworkRequest netRequest(reqUrl);
- netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- QByteArray requestData = doc.toJson();
- m_netReply = worker->post(netRequest, requestData);
- connect(m_netReply, &QNetworkReply::finished, this, &YggdrasilTask::processReply);
- connect(m_netReply, &QNetworkReply::uploadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::downloadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::sslErrors, this, &YggdrasilTask::sslErrors);
- timeout_keeper.setSingleShot(true);
- timeout_keeper.start(timeout_max);
- counter.setSingleShot(false);
- counter.start(time_step);
- progress(0, timeout_max);
- connect(&timeout_keeper, &QTimer::timeout, this, &YggdrasilTask::abortByTimeout);
- connect(&counter, &QTimer::timeout, this, &YggdrasilTask::heartbeat);
-}
-
-void YggdrasilTask::refreshTimers(qint64, qint64)
-{
- timeout_keeper.stop();
- timeout_keeper.start(timeout_max);
- progress(count = 0, timeout_max);
-}
-void YggdrasilTask::heartbeat()
-{
- count += time_step;
- progress(count, timeout_max);
-}
-
-bool YggdrasilTask::abort()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_USER;
- m_netReply->abort();
- return true;
-}
-
-void YggdrasilTask::abortByTimeout()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_TIMEOUT;
- m_netReply->abort();
-}
-
-void YggdrasilTask::sslErrors(QList<QSslError> errors)
-{
- int i = 1;
- for (auto error : errors)
- {
- qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
- auto cert = error.certificate();
- qCritical() << "Certificate in question:\n" << cert.toText();
- i++;
- }
-}
-
-void YggdrasilTask::processReply()
-{
- changeState(STATE_PROCESSING_RESPONSE);
-
- switch (m_netReply->error())
- {
- case QNetworkReply::NoError:
- break;
- case QNetworkReply::TimeoutError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out."));
- return;
- case QNetworkReply::OperationCanceledError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
- return;
- case QNetworkReply::SslHandshakeFailedError:
- changeState(
- STATE_FAILED_SOFT,
- tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
- "<ul>"
- "<li>You use Windows XP and need to <a "
- "href=\"http://www.microsoft.com/en-us/download/details.aspx?id=38918\">update "
- "your root certificates</a></li>"
- "<li>Some device on your network is interfering with SSL traffic. In that case, "
- "you have bigger worries than Minecraft not starting.</li>"
- "<li>Possibly something else. Check the MultiMC log file for details</li>"
- "</ul>"));
- return;
- // used for invalid credentials and similar errors. Fall through.
- case QNetworkReply::ContentOperationNotPermittedError:
- break;
- default:
- changeState(STATE_FAILED_SOFT,
- tr("Authentication operation failed due to a network error: %1 (%2)")
- .arg(m_netReply->errorString()).arg(m_netReply->error()));
- return;
- }
-
- // Try to parse the response regardless of the response code.
- // Sometimes the auth server will give more information and an error code.
- QJsonParseError jsonError;
- QByteArray replyData = m_netReply->readAll();
- QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
- // Check the response code.
- int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-
- if (responseCode == 200)
- {
- // If the response code was 200, then there shouldn't be an error. Make sure
- // anyways.
- // Also, sometimes an empty reply indicates success. If there was no data received,
- // pass an empty json object to the processResponse function.
- if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
- {
- processResponse(replyData.size() > 0 ? doc.object() : QJsonObject());
- return;
- }
- else
- {
- changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response "
- "JSON response: %1 at offset %2.")
- .arg(jsonError.errorString())
- .arg(jsonError.offset));
- qCritical() << replyData;
- }
- return;
- }
-
- // If the response code was not 200, then Yggdrasil may have given us information
- // about the error.
- // If we can parse the response, then get information from it. Otherwise just say
- // there was an unknown error.
- if (jsonError.error == QJsonParseError::NoError)
- {
- // We were able to parse the server's response. Woo!
- // Call processError. If a subclass has overridden it then they'll handle their
- // stuff there.
- qDebug() << "The request failed, but the server gave us an error message. "
- "Processing error.";
- processError(doc.object());
- }
- else
- {
- // The server didn't say anything regarding the error. Give the user an unknown
- // error.
- qDebug()
- << "The request failed and the server gave no error message. Unknown error.";
- changeState(STATE_FAILED_SOFT,
- tr("An unknown error occurred when trying to communicate with the "
- "authentication server: %1").arg(m_netReply->errorString()));
- }
-}
-
-void YggdrasilTask::processError(QJsonObject responseData)
-{
- QJsonValue errorVal = responseData.value("error");
- QJsonValue errorMessageValue = responseData.value("errorMessage");
- QJsonValue causeVal = responseData.value("cause");
-
- if (errorVal.isString() && errorMessageValue.isString())
- {
- m_error = std::shared_ptr<Error>(new Error{
- errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")});
- changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
- }
- else
- {
- // Error is not in standard format. Don't set m_error and return unknown error.
- changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
- }
-}
-
-QString YggdrasilTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_CREATED:
- return "Waiting...";
- case STATE_SENDING_REQUEST:
- return tr("Sending request to auth servers...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Processing response from servers...");
- case STATE_SUCCEEDED:
- return tr("Authentication task succeeded.");
- case STATE_FAILED_SOFT:
- return tr("Failed to contact the authentication server.");
- case STATE_FAILED_HARD:
- return tr("Failed to authenticate.");
- default:
- return tr("...");
- }
-}
-
-void YggdrasilTask::changeState(YggdrasilTask::State newState, QString reason)
-{
- m_state = newState;
- setStatus(getStateMessage());
- if (newState == STATE_SUCCEEDED)
- {
- emitSucceeded();
- }
- else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT)
- {
- emitFailed(reason);
- }
-}
-
-YggdrasilTask::State YggdrasilTask::state()
-{
- return m_state;
-}
diff --git a/libraries/logic/minecraft/auth/YggdrasilTask.h b/libraries/logic/minecraft/auth/YggdrasilTask.h
deleted file mode 100644
index c84cfc06..00000000
--- a/libraries/logic/minecraft/auth/YggdrasilTask.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright 2013-2015 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 <tasks/Task.h>
-
-#include <QString>
-#include <QJsonObject>
-#include <QTimer>
-#include <qsslerror.h>
-
-#include "MojangAccount.h"
-
-class QNetworkReply;
-
-/**
- * A Yggdrasil task is a task that performs an operation on a given mojang account.
- */
-class YggdrasilTask : public Task
-{
- Q_OBJECT
-public:
- explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0);
-
- /**
- * assign a session to this task. the session will be filled with required infomration
- * upon completion
- */
- void assignSession(AuthSessionPtr session)
- {
- m_session = session;
- }
-
- /// get the assigned session for filling with information.
- AuthSessionPtr getAssignedSession()
- {
- return m_session;
- }
-
- /**
- * Class describing a Yggdrasil error response.
- */
- struct Error
- {
- QString m_errorMessageShort;
- QString m_errorMessageVerbose;
- QString m_cause;
- };
-
- enum AbortedBy
- {
- BY_NOTHING,
- BY_USER,
- BY_TIMEOUT
- } m_aborted = BY_NOTHING;
-
- /**
- * Enum for describing the state of the current task.
- * Used by the getStateMessage function to determine what the status message should be.
- */
- enum State
- {
- STATE_CREATED,
- STATE_SENDING_REQUEST,
- STATE_PROCESSING_RESPONSE,
- STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
- STATE_FAILED_HARD, //!< hard failure. auth is invalid
- STATE_SUCCEEDED
- } m_state = STATE_CREATED;
-
-protected:
-
- virtual void executeTask() override;
-
- /**
- * Gets the JSON object that will be sent to the authentication server.
- * Should be overridden by subclasses.
- */
- virtual QJsonObject getRequestContent() const = 0;
-
- /**
- * Gets the endpoint to POST to.
- * No leading slash.
- */
- virtual QString getEndpoint() const = 0;
-
- /**
- * Processes the response received from the server.
- * If an error occurred, this should emit a failed signal and return false.
- * If Yggdrasil gave an error response, it should call setError() first, and then return false.
- * Otherwise, it should return true.
- * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with
- * an empty QJsonObject.
- */
- virtual void processResponse(QJsonObject responseData) = 0;
-
- /**
- * Processes an error response received from the server.
- * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error.
- * \returns a QString error message that will be passed to emitFailed.
- */
- virtual void processError(QJsonObject responseData);
-
- /**
- * Returns the state message for the given state.
- * Used to set the status message for the task.
- * Should be overridden by subclasses that want to change messages for a given state.
- */
- virtual QString getStateMessage() const;
-
-protected
-slots:
- void processReply();
- void refreshTimers(qint64, qint64);
- void heartbeat();
- void sslErrors(QList<QSslError>);
-
- void changeState(State newState, QString reason=QString());
-public
-slots:
- virtual bool abort() override;
- void abortByTimeout();
- State state();
-protected:
- // FIXME: segfault disaster waiting to happen
- MojangAccount *m_account = nullptr;
- QNetworkReply *m_netReply = nullptr;
- std::shared_ptr<Error> m_error;
- QTimer timeout_keeper;
- QTimer counter;
- int count = 0; // num msec since time reset
-
- const int timeout_max = 30000;
- const int time_step = 50;
-
- AuthSessionPtr m_session;
-};
diff --git a/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp b/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp
deleted file mode 100644
index 8d136f0b..00000000
--- a/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/* Copyright 2013-2015 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 "AuthenticateTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-#include <QUuid>
-
-AuthenticateTask::AuthenticateTask(MojangAccount * account, const QString &password,
- QObject *parent)
- : YggdrasilTask(account, parent), m_password(password)
-{
-}
-
-QJsonObject AuthenticateTask::getRequestContent() const
-{
- /*
- * {
- * "agent": { // optional
- * "name": "Minecraft", // So far this is the only encountered value
- * "version": 1 // This number might be increased
- * // by the vanilla client in the future
- * },
- * "username": "mojang account name", // Can be an email address or player name for
- // unmigrated accounts
- * "password": "mojang account password",
- * "clientToken": "client identifier" // optional
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
-
- {
- QJsonObject agent;
- // C++ makes string literals void* for some stupid reason, so we have to tell it
- // QString... Thanks Obama.
- agent.insert("name", QString("Minecraft"));
- agent.insert("version", 1);
- req.insert("agent", agent);
- }
-
- req.insert("username", m_account->username());
- req.insert("password", m_password);
- req.insert("requestUser", true);
-
- // If we already have a client token, give it to the server.
- // Otherwise, let the server give us one.
-
- if(m_account->m_clientToken.isEmpty())
- {
- auto uuid = QUuid::createUuid();
- auto uuidString = uuid.toString().remove('{').remove('-').remove('}');
- m_account->m_clientToken = uuidString;
- }
- req.insert("clientToken", m_account->m_clientToken);
-
- return req;
-}
-
-void AuthenticateTask::processResponse(QJsonObject responseData)
-{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- qDebug() << "Getting client token.";
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
- // Set the client token.
- m_account->m_clientToken = clientToken;
-
- // Now, we set the access token.
- qDebug() << "Getting access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
- // Set the access token.
- m_account->m_accessToken = accessToken;
-
- // Now we load the list of available profiles.
- // Mojang hasn't yet implemented the profile system,
- // but we might as well support what's there so we
- // don't have trouble implementing it later.
- qDebug() << "Loading profile list.";
- QJsonArray availableProfiles = responseData.value("availableProfiles").toArray();
- QList<AccountProfile> loadedProfiles;
- for (auto iter : availableProfiles)
- {
- QJsonObject profile = iter.toObject();
- // Profiles are easy, we just need their ID and name.
- QString id = profile.value("id").toString("");
- QString name = profile.value("name").toString("");
- bool legacy = profile.value("legacy").toBool(false);
-
- if (id.isEmpty() || name.isEmpty())
- {
- // This should never happen, but we might as well
- // warn about it if it does so we can debug it easily.
- // You never know when Mojang might do something truly derpy.
- qWarning() << "Found entry in available profiles list with missing ID or name "
- "field. Ignoring it.";
- }
-
- // Now, add a new AccountProfile entry to the list.
- loadedProfiles.append({id, name, legacy});
- }
- // Put the list of profiles we loaded into the MojangAccount object.
- m_account->m_profiles = loadedProfiles;
-
- // Finally, we set the current profile to the correct value. This is pretty simple.
- // We do need to make sure that the current profile that the server gave us
- // is actually in the available profiles list.
- // If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know).
- qDebug() << "Setting current profile.";
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (currentProfileId.isEmpty())
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify a currently selected profile. The account exists, but likely isn't premium."));
- return;
- }
- if (!m_account->setCurrentProfile(currentProfileId))
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server specified a selected profile that wasn't in the available profiles list."));
- return;
- }
-
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading authentication response.";
- changeState(STATE_SUCCEEDED);
-}
-
-QString AuthenticateTask::getEndpoint() const
-{
- return "authenticate";
-}
-
-QString AuthenticateTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Authenticating: Sending request...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Authenticating: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/AuthenticateTask.h b/libraries/logic/minecraft/auth/flows/AuthenticateTask.h
deleted file mode 100644
index 398fab98..00000000
--- a/libraries/logic/minecraft/auth/flows/AuthenticateTask.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2013-2015 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 "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The authenticate task takes a MojangAccount with no access token and password and attempts to
- * authenticate with Mojang's servers.
- * If successful, it will set the MojangAccount's access token.
- */
-class AuthenticateTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- AuthenticateTask(MojangAccount *account, const QString &password, QObject *parent = 0);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-
-private:
- QString m_password;
-};
diff --git a/libraries/logic/minecraft/auth/flows/RefreshTask.cpp b/libraries/logic/minecraft/auth/flows/RefreshTask.cpp
deleted file mode 100644
index a0fb2e48..00000000
--- a/libraries/logic/minecraft/auth/flows/RefreshTask.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright 2013-2015 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 "RefreshTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-
-RefreshTask::RefreshTask(MojangAccount *account) : YggdrasilTask(account)
-{
-}
-
-QJsonObject RefreshTask::getRequestContent() const
-{
- /*
- * {
- * "clientToken": "client identifier"
- * "accessToken": "current access token to be refreshed"
- * "selectedProfile": // specifying this causes errors
- * {
- * "id": "profile ID"
- * "name": "profile name"
- * }
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
- req.insert("clientToken", m_account->m_clientToken);
- req.insert("accessToken", m_account->m_accessToken);
- /*
- {
- auto currentProfile = m_account->currentProfile();
- QJsonObject profile;
- profile.insert("id", currentProfile->id());
- profile.insert("name", currentProfile->name());
- req.insert("selectedProfile", profile);
- }
- */
- req.insert("requestUser", true);
-
- return req;
-}
-
-void RefreshTask::processResponse(QJsonObject responseData)
-{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
-
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
-
- // Now, we set the access token.
- qDebug() << "Getting new access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
-
- // we validate that the server responded right. (our current profile = returned current
- // profile)
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (m_account->currentProfile()->id != currentProfileId)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify the same prefile as expected."));
- return;
- }
-
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading refresh response.";
- // Reset the access token.
- m_account->m_accessToken = accessToken;
- changeState(STATE_SUCCEEDED);
-}
-
-QString RefreshTask::getEndpoint() const
-{
- return "refresh";
-}
-
-QString RefreshTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Refreshing login token...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Refreshing login token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/RefreshTask.h b/libraries/logic/minecraft/auth/flows/RefreshTask.h
deleted file mode 100644
index 17714b4f..00000000
--- a/libraries/logic/minecraft/auth/flows/RefreshTask.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2013-2015 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 "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The authenticate task takes a MojangAccount with a possibly timed-out access token
- * and attempts to authenticate with Mojang's servers.
- * If successful, it will set the new access token. The token is considered validated.
- */
-class RefreshTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- RefreshTask(MojangAccount * account);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-};
-
diff --git a/libraries/logic/minecraft/auth/flows/ValidateTask.cpp b/libraries/logic/minecraft/auth/flows/ValidateTask.cpp
deleted file mode 100644
index 4deceb6a..00000000
--- a/libraries/logic/minecraft/auth/flows/ValidateTask.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* Copyright 2013-2015 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 "ValidateTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-
-ValidateTask::ValidateTask(MojangAccount * account, QObject *parent)
- : YggdrasilTask(account, parent)
-{
-}
-
-QJsonObject ValidateTask::getRequestContent() const
-{
- QJsonObject req;
- req.insert("accessToken", m_account->m_accessToken);
- return req;
-}
-
-void ValidateTask::processResponse(QJsonObject responseData)
-{
- // Assume that if processError wasn't called, then the request was successful.
- changeState(YggdrasilTask::STATE_SUCCEEDED);
-}
-
-QString ValidateTask::getEndpoint() const
-{
- return "validate";
-}
-
-QString ValidateTask::getStateMessage() const
-{
- switch (m_state)
- {
- case YggdrasilTask::STATE_SENDING_REQUEST:
- return tr("Validating access token: Sending request...");
- case YggdrasilTask::STATE_PROCESSING_RESPONSE:
- return tr("Validating access token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/ValidateTask.h b/libraries/logic/minecraft/auth/flows/ValidateTask.h
deleted file mode 100644
index 77d628a0..00000000
--- a/libraries/logic/minecraft/auth/flows/ValidateTask.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright 2013-2015 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.
- */
-
-/*
- * :FIXME: DEAD CODE, DEAD CODE, DEAD CODE! :FIXME:
- */
-
-#pragma once
-
-#include "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The validate task takes a MojangAccount and checks to make sure its access token is valid.
- */
-class ValidateTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- ValidateTask(MojangAccount *account, QObject *parent = 0);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-
-private:
-};
diff --git a/libraries/logic/minecraft/forge/ForgeInstaller.cpp b/libraries/logic/minecraft/forge/ForgeInstaller.cpp
deleted file mode 100644
index 353328ab..00000000
--- a/libraries/logic/minecraft/forge/ForgeInstaller.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright 2013-2015 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(CacheDownload::make(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/libraries/logic/minecraft/forge/ForgeInstaller.h b/libraries/logic/minecraft/forge/ForgeInstaller.h
deleted file mode 100644
index 499a6fb3..00000000
--- a/libraries/logic/minecraft/forge/ForgeInstaller.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2013-2015 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/libraries/logic/minecraft/forge/ForgeVersion.cpp b/libraries/logic/minecraft/forge/ForgeVersion.cpp
deleted file mode 100644
index b859a28c..00000000
--- a/libraries/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/libraries/logic/minecraft/forge/ForgeVersion.h b/libraries/logic/minecraft/forge/ForgeVersion.h
deleted file mode 100644
index e77d32f1..00000000
--- a/libraries/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/libraries/logic/minecraft/forge/ForgeVersionList.cpp b/libraries/logic/minecraft/forge/ForgeVersionList.cpp
deleted file mode 100644
index de185e5f..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersionList.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/* Copyright 2013-2015 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 = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL),
- forgeListEntry));
- job->addNetAction(gradleListDownload = CacheDownload::make(
- QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
- connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-bool ForgeListLoadTask::abort()
-{
- return listJob->abort();
-}
-
-bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out)
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("builds").isArray())
- {
- emitFailed(
- "Error parsing version list JSON: version list object is missing 'builds' array");
- return false;
- }
- QJsonArray builds = root.value("builds").toArray();
-
- for (int i = 0; i < builds.count(); i++)
- {
- // Load the version info.
- if (!builds[i].isObject())
- {
- // FIXME: log this somewhere
- continue;
- }
- QJsonObject obj = builds[i].toObject();
- int build_nr = obj.value("build").toDouble(0);
- if (!build_nr)
- continue;
- QJsonArray files = obj.value("files").toArray();
- QString url, jobbuildver, mcver, buildtype, universal_filename;
- QString changelog_url, installer_url;
- QString installer_filename;
- bool valid = false;
- for (int j = 0; j < files.count(); j++)
- {
- if (!files[j].isObject())
- {
- continue;
- }
- QJsonObject file = files[j].toObject();
- buildtype = file.value("buildtype").toString();
- if ((buildtype == "client" || buildtype == "universal") && !valid)
- {
- mcver = file.value("mcver").toString();
- url = file.value("url").toString();
- jobbuildver = file.value("jobbuildver").toString();
- int lastSlash = url.lastIndexOf('/');
- universal_filename = url.mid(lastSlash + 1);
- valid = true;
- }
- else if (buildtype == "changelog")
- {
- QString ext = file.value("ext").toString();
- if (ext.isEmpty())
- {
- continue;
- }
- changelog_url = file.value("url").toString();
- }
- else if (buildtype == "installer")
- {
- installer_url = file.value("url").toString();
- int lastSlash = installer_url.lastIndexOf('/');
- installer_filename = installer_url.mid(lastSlash + 1);
- }
- }
- if (valid)
- {
- // Now, we construct the version object and add it to the list.
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->universal_url = url;
- fVersion->changelog_url = changelog_url;
- fVersion->installer_url = installer_url;
- fVersion->jobbuildver = jobbuildver;
- fVersion->mcver = fVersion->mcver_sane = mcver;
- fVersion->installer_filename = installer_filename;
- fVersion->universal_filename = universal_filename;
- fVersion->m_buildnr = build_nr;
- fVersion->type = ForgeVersion::Legacy;
- out.append(fVersion);
- }
- }
-
- return true;
-}
-
-bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out)
-{
- QMap<int, std::shared_ptr<ForgeVersion>> lookup;
- QByteArray data;
- {
- auto dlJob = gradleListDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing gradle version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing gradle version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // we probably could hard code these, but it might still be worth doing it this way
- const QString webpath = root.value("webpath").toString();
- const QString artifact = root.value("artifact").toString();
-
- QJsonObject numbers = root.value("number").toObject();
- for (auto it = numbers.begin(); it != numbers.end(); ++it)
- {
- QJsonObject number = it.value().toObject();
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->m_buildnr = number.value("build").toDouble();
- 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")
- {
- 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 (!parseForgeList(list))
- {
- ret = false;
- }
- if (!parseForgeGradleList(list))
- {
- ret = false;
- }
-
- if (!ret)
- {
- return;
- }
- std::sort(list.begin(), list.end(), [](const BaseVersionPtr & l, const BaseVersionPtr & r)
- { return (*l > *r); });
-
- m_list->updateListData(list);
-
- emitSucceeded();
- return;
-}
-
-void ForgeListLoadTask::listFailed()
-{
- auto &reply = listDownload->m_reply;
- if (reply)
- {
- 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/libraries/logic/minecraft/forge/ForgeVersionList.h b/libraries/logic/minecraft/forge/ForgeVersionList.h
deleted file mode 100644
index 62c08b2a..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersionList.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright 2013-2015 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;
-
- CacheDownloadPtr listDownload;
- CacheDownloadPtr gradleListDownload;
-
-private:
- bool parseForgeList(QList<BaseVersionPtr> &out);
- bool parseForgeGradleList(QList<BaseVersionPtr> &out);
-};
diff --git a/libraries/logic/minecraft/forge/ForgeXzDownload.cpp b/libraries/logic/minecraft/forge/ForgeXzDownload.cpp
deleted file mode 100644
index adf96552..00000000
--- a/libraries/logic/minecraft/forge/ForgeXzDownload.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include "ForgeXzDownload.h"
-#include <FileSystem.h>
-
-#include <QCryptographicHash>
-#include <QFileInfo>
-#include <QDateTime>
-#include <QDir>
-#include <QDebug>
-
-ForgeXzDownload::ForgeXzDownload(QString relative_path, MetaEntryPtr entry) : NetAction()
-{
- m_entry = entry;
- m_target_path = entry->getFullPath();
- m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX");
- m_status = Job_NotStarted;
- m_url_path = relative_path;
- m_url = "http://files.minecraftforge.net/maven/" + m_url_path + ".pack.xz";
-}
-
-void ForgeXzDownload::start()
-{
- m_status = Job_InProgress;
- if (!m_entry->isStale())
- {
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- // can we actually create the real, final file?
- if (!FS::ensureFilePathExists(m_target_path))
- {
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
-
- qDebug() << "Downloading " << m_url.toString();
- QNetworkRequest request(m_url);
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
- SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
-}
-
-void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
-
-void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error)
-{
- // error happened during download.
- // TODO: log the reason why
- m_status = Job_Failed;
-}
-
-void ForgeXzDownload::failAndTryNextMirror()
-{
- m_status = Job_Failed;
- emit failed(m_index_within_job);
-}
-
-void ForgeXzDownload::downloadFinished()
-{
- // if the download succeeded
- if (m_status != Job_Failed)
- {
- // nothing went wrong...
- m_status = Job_Finished;
- if (m_pack200_xz_file.isOpen())
- {
- // we actually downloaded something! process and isntall it
- decompressAndInstall();
- return;
- }
- else
- {
- // something bad happened -- on the local machine!
- m_status = Job_Failed;
- m_pack200_xz_file.remove();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- }
- // else the download failed
- else
- {
- m_status = Job_Failed;
- m_pack200_xz_file.close();
- m_pack200_xz_file.remove();
- m_reply.reset();
- failAndTryNextMirror();
- return;
- }
-}
-
-void ForgeXzDownload::downloadReadyRead()
-{
-
- if (!m_pack200_xz_file.isOpen())
- {
- if (!m_pack200_xz_file.open())
- {
- /*
- * Can't open the file... the job failed
- */
- m_reply->abort();
- emit failed(m_index_within_job);
- return;
- }
- }
- m_pack200_xz_file.write(m_reply->readAll());
-}
-
-#include "xz.h"
-#include "unpack200.h"
-#include <stdexcept>
-#include <unistd.h>
-
-const size_t buffer_size = 8196;
-
-void ForgeXzDownload::decompressAndInstall()
-{
- // rewind the downloaded temp file
- m_pack200_xz_file.seek(0);
- // de-xz'd file
- QTemporaryFile pack200_file("./dl_temp.XXXXXX");
- pack200_file.open();
-
- bool xz_success = false;
- // first, de-xz
- {
- uint8_t in[buffer_size];
- uint8_t out[buffer_size];
- struct xz_buf b;
- struct xz_dec *s;
- enum xz_ret ret;
- xz_crc32_init();
- xz_crc64_init();
- s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
- if (s == nullptr)
- {
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- b.in = in;
- b.in_pos = 0;
- b.in_size = 0;
- b.out = out;
- b.out_pos = 0;
- b.out_size = buffer_size;
- while (!xz_success)
- {
- if (b.in_pos == b.in_size)
- {
- b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in));
- b.in_pos = 0;
- }
-
- ret = xz_dec_run(s, &b);
-
- if (b.out_pos == sizeof(out))
- {
- if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
- {
- // msg = "Write error\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
-
- b.out_pos = 0;
- }
-
- if (ret == XZ_OK)
- continue;
-
- if (ret == XZ_UNSUPPORTED_CHECK)
- {
- // unsupported check. this is OK, but we should log this
- continue;
- }
-
- if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
- {
- // write error
- pack200_file.close();
- xz_dec_end(s);
- return;
- }
-
- switch (ret)
- {
- case XZ_STREAM_END:
- xz_dec_end(s);
- xz_success = true;
- break;
-
- case XZ_MEM_ERROR:
- qCritical() << "Memory allocation failed\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_MEMLIMIT_ERROR:
- qCritical() << "Memory usage limit reached\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_FORMAT_ERROR:
- qCritical() << "Not a .xz file\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_OPTIONS_ERROR:
- qCritical() << "Unsupported options in the .xz headers\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_DATA_ERROR:
- case XZ_BUF_ERROR:
- qCritical() << "File is corrupt\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- default:
- qCritical() << "Bug!\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- }
- }
- m_pack200_xz_file.remove();
-
- // revert pack200
- pack200_file.seek(0);
- int handle_in = pack200_file.handle();
- // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects.
- if(handle_in == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_in_dup = dup (handle_in);
- if(handle_in_dup == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_in = fdopen (handle_in_dup, "rb");
- if(!file_in)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- QFile qfile_out(m_target_path);
- if(!qfile_out.open(QIODevice::WriteOnly))
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out = qfile_out.handle();
- if(handle_out == -1)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out_dup = dup (handle_out);
- if(handle_out_dup == -1)
- {
- qCritical() << "Error reopening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_out = fdopen (handle_out_dup, "wb");
- if(!file_out)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- try
- {
- // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above.
- unpack_200(file_in, file_out);
- }
- catch (std::runtime_error &err)
- {
- m_status = Job_Failed;
- qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what();
- QFile f(m_target_path);
- if (f.exists())
- f.remove();
- failAndTryNextMirror();
- return;
- }
- pack200_file.remove();
-
- QFile jar_file(m_target_path);
-
- if (!jar_file.open(QIODevice::ReadOnly))
- {
- jar_file.remove();
- failAndTryNextMirror();
- return;
- }
- auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5);
- m_entry->setMD5Sum(hash.toHex().constData());
- jar_file.close();
-
- QFileInfo output_file_info(m_target_path);
- m_entry->setETag(m_reply->rawHeader("ETag").constData());
- m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
- m_entry->setStale(false);
- ENV.metacache()->updateEntry(m_entry);
-
- m_reply.reset();
- emit succeeded(m_index_within_job);
-}
diff --git a/libraries/logic/minecraft/forge/ForgeXzDownload.h b/libraries/logic/minecraft/forge/ForgeXzDownload.h
deleted file mode 100644
index 67524405..00000000
--- a/libraries/logic/minecraft/forge/ForgeXzDownload.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2013-2015 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 "net/NetAction.h"
-#include "net/HttpMetaCache.h"
-#include <QFile>
-#include <QTemporaryFile>
-
-typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr;
-
-class ForgeXzDownload : public NetAction
-{
- Q_OBJECT
-public:
- MetaEntryPtr m_entry;
- /// if saving to file, use the one specified in this string
- QString m_target_path;
- /// this is the output file, if any
- QTemporaryFile m_pack200_xz_file;
- /// path relative to the mirror base
- QString m_url_path;
-
-public:
- explicit ForgeXzDownload(QString relative_path, MetaEntryPtr entry);
- static ForgeXzDownloadPtr make(QString relative_path, MetaEntryPtr entry)
- {
- return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry));
- }
- virtual ~ForgeXzDownload(){};
-
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead();
-
-public
-slots:
- virtual void start();
-
-private:
- void decompressAndInstall();
- void failAndTryNextMirror();
-};
diff --git a/libraries/logic/minecraft/forge/LegacyForge.cpp b/libraries/logic/minecraft/forge/LegacyForge.cpp
deleted file mode 100644
index aa2c8063..00000000
--- a/libraries/logic/minecraft/forge/LegacyForge.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright 2013-2015 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/libraries/logic/minecraft/forge/LegacyForge.h b/libraries/logic/minecraft/forge/LegacyForge.h
deleted file mode 100644
index f51d5e85..00000000
--- a/libraries/logic/minecraft/forge/LegacyForge.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2013-2015 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/libraries/logic/minecraft/ftb/FTBPlugin.cpp b/libraries/logic/minecraft/ftb/FTBPlugin.cpp
deleted file mode 100644
index a142c106..00000000
--- a/libraries/logic/minecraft/ftb/FTBPlugin.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-#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>
-#include "QDebug"
-#include <QXmlStreamReader>
-#include <QRegularExpression>
-
-struct FTBRecord
-{
- QString dirName;
- QString name;
- QString logo;
- QString iconKey;
- QString mcVersion;
- QString description;
- QString instanceDir;
- QString templateDir;
- bool operator==(const FTBRecord other) const
- {
- return instanceDir == other.instanceDir;
- }
-};
-
-inline uint qHash(FTBRecord record)
-{
- return qHash(record.instanceDir);
-}
-
-QSet<FTBRecord> discoverFTBInstances(SettingsObjectPtr globalSettings)
-{
- QSet<FTBRecord> records;
- QDir dir = QDir(globalSettings->get("FTBLauncherLocal").toString());
- QDir dataDir = QDir(globalSettings->get("FTBRoot").toString());
- if (!dataDir.exists())
- {
- qDebug() << "The FTB directory specified does not exist. Please check your settings";
- return records;
- }
- else if (!dir.exists())
- {
- qDebug() << "The FTB launcher data directory specified does not exist. Please check "
- "your settings";
- return records;
- }
- dir.cd("ModPacks");
- auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name);
- for (auto filename : allFiles)
- {
- if (!filename.endsWith(".xml"))
- continue;
- auto fpath = dir.absoluteFilePath(filename);
- QFile f(fpath);
- qDebug() << "Discovering FTB instances -- " << fpath;
- if (!f.open(QFile::ReadOnly))
- continue;
-
- // read the FTB packs XML.
- QXmlStreamReader reader(&f);
- while (!reader.atEnd())
- {
- switch (reader.readNext())
- {
- case QXmlStreamReader::StartElement:
- {
- if (reader.name() == "modpack")
- {
- QXmlStreamAttributes attrs = reader.attributes();
- FTBRecord record;
- record.dirName = attrs.value("dir").toString();
- record.instanceDir = dataDir.absoluteFilePath(record.dirName);
- record.templateDir = dir.absoluteFilePath(record.dirName);
- QDir test(record.instanceDir);
- qDebug() << dataDir.absolutePath() << record.instanceDir << record.dirName;
- if (!test.exists())
- continue;
- record.name = attrs.value("name").toString();
- record.logo = attrs.value("logo").toString();
- QString logo = record.logo;
- record.iconKey = logo.remove(QRegularExpression("\\..*"));
- auto customVersions = attrs.value("customMCVersions");
- if (!customVersions.isNull())
- {
- QMap<QString, QString> versionMatcher;
- QString customVersionsStr = customVersions.toString();
- QStringList list = customVersionsStr.split(';');
- for (auto item : list)
- {
- auto segment = item.split('^');
- if (segment.size() != 2)
- {
- qCritical() << "FTB: Segment of size < 2 in "
- << customVersionsStr;
- continue;
- }
- versionMatcher[segment[0]] = segment[1];
- }
- auto actualVersion = attrs.value("version").toString();
- if (versionMatcher.contains(actualVersion))
- {
- record.mcVersion = versionMatcher[actualVersion];
- }
- else
- {
- record.mcVersion = attrs.value("mcVersion").toString();
- }
- }
- else
- {
- record.mcVersion = attrs.value("mcVersion").toString();
- }
- record.description = attrs.value("description").toString();
- records.insert(record);
- }
- break;
- }
- case QXmlStreamReader::EndElement:
- break;
- case QXmlStreamReader::Characters:
- break;
- default:
- break;
- }
- }
- f.close();
- }
- return records;
-}
-
-InstancePtr loadInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record)
-{
- InstancePtr inst;
-
- auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
- m_settings->registerSetting("InstanceType", "Legacy");
-
- qDebug() << "Loading existing " << record.name;
-
- QString inst_type = m_settings->get("InstanceType").toString();
- if (inst_type == "LegacyFTB")
- {
- inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else if (inst_type == "OneSixFTB")
- {
- inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else
- {
- return nullptr;
- }
- qDebug() << "Construction " << record.instanceDir;
-
- SettingsObject::Lock lock(inst->settings());
- inst->init();
- qDebug() << "Init " << record.instanceDir;
- inst->setGroupInitial("FTB");
- /**
- * FIXME: this does not respect the user's preferences. BUT, it would work nicely with the planned pack support
- * -> instead of changing the user values, change pack values (defaults you can look at and revert to)
- */
- /*
- inst->setName(record.name);
- inst->setIconKey(record.iconKey);
- inst->setNotes(record.description);
- */
- if (inst->intendedVersionId() != record.mcVersion)
- {
- inst->setIntendedVersionId(record.mcVersion);
- }
- qDebug() << "Post-Process " << record.instanceDir;
- if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap))
- {
- return nullptr;
- }
- qDebug() << "Final " << record.instanceDir;
- return inst;
-}
-
-InstancePtr createInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record)
-{
- QDir rootDir(record.instanceDir);
-
- InstancePtr inst;
-
- qDebug() << "Converting " << record.name << " as new.";
-
- auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion));
- if (!mcVersion)
- {
- qCritical() << "Can't load instance " << record.instanceDir
- << " because minecraft version " << record.mcVersion
- << " can't be resolved.";
- return nullptr;
- }
-
- if (!rootDir.exists() && !rootDir.mkpath("."))
- {
- qCritical() << "Can't create instance folder" << record.instanceDir;
- return nullptr;
- }
-
- auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
- m_settings->registerSetting("InstanceType", "Legacy");
-
- if (mcVersion->usesLegacyLauncher())
- {
- m_settings->set("InstanceType", "LegacyFTB");
- inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else
- {
- m_settings->set("InstanceType", "OneSixFTB");
- inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- // initialize
- {
- SettingsObject::Lock lock(inst->settings());
- inst->setIntendedVersionId(mcVersion->descriptor());
- inst->init();
- inst->setGroupInitial("FTB");
- inst->setName(record.name);
- inst->setIconKey(record.iconKey);
- inst->setNotes(record.description);
- qDebug() << "Post-Process " << record.instanceDir;
- if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap))
- {
- return nullptr;
- }
- }
- return inst;
-}
-
-void FTBPlugin::loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList)
-{
- // nothing to load when we don't have
- if (globalSettings->get("TrackFTBInstances").toBool() != true)
- {
- return;
- }
-
- auto records = discoverFTBInstances(globalSettings);
- if (!records.size())
- {
- qDebug() << "No FTB instances to load.";
- return;
- }
- qDebug() << "Loading FTB instances! -- got " << records.size();
- // process the records we acquired.
- for (auto record : records)
- {
- qDebug() << "Loading FTB instance from " << record.instanceDir;
- QString iconKey = record.iconKey;
- // MMC->icons()->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), MMCIcon::Transient);
- auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg");
- qDebug() << "ICON get!";
-
- if (QFileInfo(settingsFilePath).exists())
- {
- auto instPtr = loadInstance(globalSettings, groupMap, record);
- if (!instPtr)
- {
- qWarning() << "Couldn't load instance config:" << settingsFilePath;
- if(!QFile::remove(settingsFilePath))
- {
- qWarning() << "Couldn't remove broken instance config!";
- continue;
- }
- // failed to load, but removed the poisonous file
- }
- else
- {
- tempList.append(InstancePtr(instPtr));
- continue;
- }
- }
- auto instPtr = createInstance(globalSettings, groupMap, record);
- if (!instPtr)
- {
- qWarning() << "Couldn't create FTB instance!";
- continue;
- }
- tempList.append(InstancePtr(instPtr));
- }
-}
-
-#ifdef Q_OS_WIN32
-#include <windows.h>
-static const int APPDATA_BUFFER_SIZE = 1024;
-#endif
-
-static QString getLocalCacheStorageLocation()
-{
- QString ftbDefault;
-#ifdef Q_OS_WIN32
- wchar_t buf[APPDATA_BUFFER_SIZE];
- if (GetEnvironmentVariableW(L"LOCALAPPDATA", buf, APPDATA_BUFFER_SIZE)) // local
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE)) // roaming
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else
- {
- qCritical() << "Your LOCALAPPDATA and APPDATA folders are missing!"
- " If you are on windows, this means your system is broken.";
- }
-#elif defined(Q_OS_MAC)
- ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher");
-#else
- ftbDefault = QDir::home().absoluteFilePath(".ftblauncher");
-#endif
- return ftbDefault;
-}
-
-
-static QString getRoamingStorageLocation()
-{
- QString ftbDefault;
-#ifdef Q_OS_WIN32
- wchar_t buf[APPDATA_BUFFER_SIZE];
- QString cacheStorage;
- if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE))
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else
- {
- qCritical() << "Your APPDATA folder is missing! If you are on windows, this means your system is broken.";
- }
-#elif defined(Q_OS_MAC)
- ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher");
-#else
- ftbDefault = QDir::home().absoluteFilePath(".ftblauncher");
-#endif
- return ftbDefault;
-}
-
-void FTBPlugin::initialize(SettingsObjectPtr globalSettings)
-{
- // FTB
- globalSettings->registerSetting("TrackFTBInstances", false);
- QString ftbRoaming = getRoamingStorageLocation();
- QString ftbLocal = getLocalCacheStorageLocation();
-
- globalSettings->registerSetting("FTBLauncherRoaming", ftbRoaming);
- globalSettings->registerSetting("FTBLauncherLocal", ftbLocal);
- qDebug() << "FTB Launcher paths:" << globalSettings->get("FTBLauncherRoaming").toString()
- << "and" << globalSettings->get("FTBLauncherLocal").toString();
-
- globalSettings->registerSetting("FTBRoot");
- if (globalSettings->get("FTBRoot").isNull())
- {
- QString ftbRoot;
- QFile f(QDir(globalSettings->get("FTBLauncherRoaming").toString()).absoluteFilePath("ftblaunch.cfg"));
- qDebug() << "Attempting to read" << f.fileName();
- if (f.open(QFile::ReadOnly))
- {
- const QString data = QString::fromLatin1(f.readAll());
- QRegularExpression exp("installPath=(.*)");
- ftbRoot = QDir::cleanPath(exp.match(data).captured(1));
-#ifdef Q_OS_WIN32
- if (!ftbRoot.isEmpty())
- {
- if (ftbRoot.at(0).isLetter() && ftbRoot.size() > 1 && ftbRoot.at(1) == '/')
- {
- ftbRoot.remove(1, 1);
- }
- }
-#endif
- if (ftbRoot.isEmpty())
- {
- qDebug() << "Failed to get FTB root path";
- }
- else
- {
- qDebug() << "FTB is installed at" << ftbRoot;
- globalSettings->set("FTBRoot", ftbRoot);
- }
- }
- else
- {
- qWarning() << "Couldn't open" << f.fileName() << ":" << f.errorString();
- qWarning() << "This is perfectly normal if you don't have FTB installed";
- }
- }
-}
diff --git a/libraries/logic/minecraft/ftb/FTBPlugin.h b/libraries/logic/minecraft/ftb/FTBPlugin.h
deleted file mode 100644
index 6851d8a5..00000000
--- a/libraries/logic/minecraft/ftb/FTBPlugin.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <BaseInstance.h>
-
-#include "multimc_logic_export.h"
-
-// Pseudo-plugin for FTB related things. Super derpy!
-class MULTIMC_LOGIC_EXPORT FTBPlugin
-{
-public:
- static void initialize(SettingsObjectPtr globalSettings);
- static void loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList);
-};
diff --git a/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp b/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp
deleted file mode 100644
index f5faacae..00000000
--- a/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "FTBProfileStrategy.h"
-#include "OneSixFTBInstance.h"
-
-#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
-#include <FileSystem.h>
-
-#include <QDir>
-#include <QUuid>
-#include <QJsonDocument>
-#include <QJsonArray>
-
-FTBProfileStrategy::FTBProfileStrategy(OneSixFTBInstance* instance) : OneSixProfileStrategy(instance)
-{
-}
-
-void FTBProfileStrategy::loadDefaultBuiltinPatches()
-{
- // FIXME: this should be here, but it needs us to be able to deal with multiple libraries paths
- // OneSixProfileStrategy::loadDefaultBuiltinPatches();
- auto mcVersion = m_instance->intendedVersionId();
- auto nativeInstance = dynamic_cast<OneSixFTBInstance *>(m_instance);
-
- ProfilePatchPtr minecraftPatch;
- {
- auto mcJson = m_instance->versionsPath().absoluteFilePath(mcVersion + "/" + mcVersion + ".json");
- // load up the base minecraft patch
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
- file->fileId = "net.minecraft";
- file->name = QObject::tr("Minecraft (tracked)");
- file->setVanilla(true);
- if(file->version.isEmpty())
- {
- file->version = mcVersion;
- }
- for(auto addLib: file->libraries)
- {
- addLib->setHint("local");
- addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
- }
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- throw VersionIncomplete("net.minecraft");
- }
- minecraftPatch->setOrder(-2);
- }
- profile->appendPatch(minecraftPatch);
-
- ProfilePatchPtr packPatch;
- {
- auto mcJson = m_instance->minecraftRoot() + "/pack.json";
- // load up the base minecraft patch
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
-
- // adapt the loaded file - the FTB patch file format is different than ours.
- file->minecraftVersion.clear();
- for(auto addLib: file->libraries)
- {
- addLib->setHint("local");
- addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
- }
- file->fileId = "org.multimc.ftb.pack";
- file->setVanilla(true);
- file->name = QObject::tr("%1 (FTB pack)").arg(m_instance->name());
- if(file->version.isEmpty())
- {
- file->version = QObject::tr("Unknown");
- QFile versionFile (FS::PathCombine(m_instance->instanceRoot(), "version"));
- if(versionFile.exists())
- {
- if(versionFile.open(QIODevice::ReadOnly))
- {
- // FIXME: just guessing the encoding/charset here.
- auto version = QString::fromUtf8(versionFile.readAll());
- file->version = version;
- }
- }
- }
- packPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- throw VersionIncomplete("org.multimc.ftb.pack");
- }
- packPatch->setOrder(1);
- }
- profile->appendPatch(packPatch);
-
-}
-
-void FTBProfileStrategy::load()
-{
- profile->clearPatches();
-
- loadDefaultBuiltinPatches();
- loadUserPatches();
-}
-
-bool FTBProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
-{
- return false;
-}
-
-bool FTBProfileStrategy::resetOrder()
-{
- return false;
-}
-
-bool FTBProfileStrategy::installJarMods(QStringList filepaths)
-{
- return false;
-}
-
-bool FTBProfileStrategy::customizePatch(ProfilePatchPtr patch)
-{
- return false;
-}
-
-bool FTBProfileStrategy::revertPatch(ProfilePatchPtr patch)
-{
- return false;
-}
diff --git a/libraries/logic/minecraft/ftb/FTBProfileStrategy.h b/libraries/logic/minecraft/ftb/FTBProfileStrategy.h
deleted file mode 100644
index 522af098..00000000
--- a/libraries/logic/minecraft/ftb/FTBProfileStrategy.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include "minecraft/ProfileStrategy.h"
-#include "minecraft/onesix/OneSixProfileStrategy.h"
-
-class OneSixFTBInstance;
-
-class FTBProfileStrategy : public OneSixProfileStrategy
-{
-public:
- FTBProfileStrategy(OneSixFTBInstance * instance);
- virtual ~FTBProfileStrategy() {};
- virtual void load() override;
- virtual bool resetOrder() override;
- virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
- virtual bool installJarMods(QStringList filepaths) override;
- virtual bool customizePatch (ProfilePatchPtr patch) override;
- virtual bool revertPatch (ProfilePatchPtr patch) override;
-
-protected:
- virtual void loadDefaultBuiltinPatches() override;
-};
diff --git a/libraries/logic/minecraft/ftb/FTBVersion.h b/libraries/logic/minecraft/ftb/FTBVersion.h
deleted file mode 100644
index 805319b4..00000000
--- a/libraries/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/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp b/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp
deleted file mode 100644
index a7091f1d..00000000
--- a/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "LegacyFTBInstance.h"
-#include <settings/INISettingsObject.h>
-#include <QDir>
-
-LegacyFTBInstance::LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
- LegacyInstance(globalSettings, settings, rootDir)
-{
-}
-
-QString LegacyFTBInstance::id() const
-{
- return "FTB/" + BaseInstance::id();
-}
-
-void LegacyFTBInstance::copy(const QDir &newDir)
-{
- // set the target instance to be plain Legacy
- INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg"));
- settings_obj.registerSetting("InstanceType", "Legacy");
- QString inst_type = settings_obj.get("InstanceType").toString();
- settings_obj.set("InstanceType", "Legacy");
-}
-
-QString LegacyFTBInstance::typeName() const
-{
- return tr("Legacy FTB");
-}
diff --git a/libraries/logic/minecraft/ftb/LegacyFTBInstance.h b/libraries/logic/minecraft/ftb/LegacyFTBInstance.h
deleted file mode 100644
index 7178bca4..00000000
--- a/libraries/logic/minecraft/ftb/LegacyFTBInstance.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "minecraft/legacy/LegacyInstance.h"
-
-class LegacyFTBInstance : public LegacyInstance
-{
- Q_OBJECT
-public:
- explicit LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual QString id() const;
- virtual void copy(const QDir &newDir);
- virtual QString typeName() const;
- bool canExport() const override
- {
- return false;
- }
-};
diff --git a/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp b/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp
deleted file mode 100644
index 81e939a1..00000000
--- a/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "OneSixFTBInstance.h"
-#include "FTBProfileStrategy.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/GradleSpecifier.h"
-#include "tasks/SequentialTask.h"
-#include <settings/INISettingsObject.h>
-#include <FileSystem.h>
-
-#include <QJsonArray>
-
-OneSixFTBInstance::OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
- OneSixInstance(globalSettings, settings, rootDir)
-{
- m_globalSettings = globalSettings;
-}
-
-void OneSixFTBInstance::copy(const QDir &newDir)
-{
- QStringList libraryNames;
- // create patch file
- {
- qDebug()<< "Creating patch file for FTB instance...";
- QFile f(minecraftRoot() + "/pack.json");
- if (!f.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << f.fileName() << ":" << f.errorString();
- return;
- }
- QJsonObject root = QJsonDocument::fromJson(f.readAll()).object();
- QJsonArray libs = root.value("libraries").toArray();
- QJsonArray outLibs;
- for (auto lib : libs)
- {
- QJsonObject libObj = lib.toObject();
- libObj.insert("MMC-hint", QString("local"));
- libObj.insert("insert", QString("prepend"));
- libraryNames.append(libObj.value("name").toString());
- outLibs.append(libObj);
- }
- root.remove("libraries");
- root.remove("id");
-
- // HACK HACK HACK HACK
- // A workaround for a problem in MultiMC, triggered by a historical problem in FTB,
- // triggered by Mojang getting their library versions wrong in 1.7.10
- if(intendedVersionId() == "1.7.10")
- {
- auto insert = [&outLibs, &libraryNames](QString name)
- {
- QJsonObject libObj;
- libObj.insert("insert", QString("replace"));
- libObj.insert("name", name);
- libraryNames.push_back(name);
- outLibs.prepend(libObj);
- };
- insert("com.google.guava:guava:16.0");
- insert("org.apache.commons:commons-lang3:3.2.1");
- }
- root.insert("+libraries", outLibs);
- root.insert("order", 1);
- root.insert("fileId", QString("org.multimc.ftb.pack.json"));
- root.insert("name", name());
- root.insert("mcVersion", intendedVersionId());
- root.insert("version", intendedVersionId());
- FS::ensureFilePathExists(newDir.absoluteFilePath("patches/ftb.json"));
- QFile out(newDir.absoluteFilePath("patches/ftb.json"));
- if (!out.open(QFile::WriteOnly | QFile::Truncate))
- {
- qCritical() << "Couldn't open" << out.fileName() << ":" << out.errorString();
- return;
- }
- out.write(QJsonDocument(root).toJson());
- }
- // copy libraries
- {
- qDebug() << "Copying FTB libraries";
- for (auto library : libraryNames)
- {
- GradleSpecifier lib(library);
- const QString out = QDir::current().absoluteFilePath("libraries/" + lib.toPath());
- if (QFile::exists(out))
- {
- continue;
- }
- if (!FS::ensureFilePathExists(out))
- {
- qCritical() << "Couldn't create folder structure for" << out;
- }
- if (!QFile::copy(librariesPath().absoluteFilePath(lib.toPath()), out))
- {
- qCritical() << "Couldn't copy" << QString(lib);
- }
- }
- }
- // now set the target instance to be plain OneSix
- INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg"));
- settings_obj.registerSetting("InstanceType", "Legacy");
- QString inst_type = settings_obj.get("InstanceType").toString();
- settings_obj.set("InstanceType", "OneSix");
-}
-
-QString OneSixFTBInstance::id() const
-{
- return "FTB/" + BaseInstance::id();
-}
-
-QDir OneSixFTBInstance::librariesPath() const
-{
- return QDir(m_globalSettings->get("FTBRoot").toString() + "/libraries");
-}
-
-QDir OneSixFTBInstance::versionsPath() const
-{
- return QDir(m_globalSettings->get("FTBRoot").toString() + "/versions");
-}
-
-bool OneSixFTBInstance::providesVersionFile() const
-{
- return true;
-}
-
-void OneSixFTBInstance::createProfile()
-{
- m_profile.reset(new MinecraftProfile(new FTBProfileStrategy(this)));
-}
-
-std::shared_ptr<Task> OneSixFTBInstance::createUpdateTask()
-{
- return OneSixInstance::createUpdateTask();
-}
-
-QString OneSixFTBInstance::typeName() const
-{
- return tr("OneSix FTB");
-}
-
-#include "OneSixFTBInstance.moc"
diff --git a/libraries/logic/minecraft/ftb/OneSixFTBInstance.h b/libraries/logic/minecraft/ftb/OneSixFTBInstance.h
deleted file mode 100644
index e7f8f485..00000000
--- a/libraries/logic/minecraft/ftb/OneSixFTBInstance.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "minecraft/onesix/OneSixInstance.h"
-
-class OneSixFTBInstance : public OneSixInstance
-{
- Q_OBJECT
-public:
- explicit OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~OneSixFTBInstance(){};
-
- void copy(const QDir &newDir) override;
-
- virtual void createProfile() override;
-
- virtual std::shared_ptr<Task> createUpdateTask() override;
-
- virtual QString id() const override;
-
- QDir librariesPath() const override;
- QDir versionsPath() const override;
- bool providesVersionFile() const override;
- virtual QString typeName() const override;
- bool canExport() const override
- {
- return false;
- }
-private:
- SettingsObjectPtr m_globalSettings;
-};
diff --git a/libraries/logic/minecraft/legacy/LegacyInstance.cpp b/libraries/logic/minecraft/legacy/LegacyInstance.cpp
deleted file mode 100644
index f8264f20..00000000
--- a/libraries/logic/minecraft/legacy/LegacyInstance.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Copyright 2013-2015 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 <QFileInfo>
-#include <QDir>
-#include <settings/Setting.h>
-
-#include "LegacyInstance.h"
-
-#include "minecraft/legacy/LegacyUpdate.h"
-#include "launch/LaunchTask.h"
-#include <launch/steps/LaunchMinecraft.h>
-#include <launch/steps/PostLaunchCommand.h>
-#include <launch/steps/ModMinecraftJar.h>
-#include <launch/steps/Update.h>
-#include <launch/steps/PreLaunchCommand.h>
-#include <launch/steps/TextPrint.h>
-#include <launch/steps/CheckJava.h>
-#include "minecraft/ModList.h"
-#include "minecraft/WorldList.h"
-#include <MMCZip.h>
-#include <FileSystem.h>
-
-LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : MinecraftInstance(globalSettings, settings, rootDir)
-{
- m_lwjglFolderSetting = globalSettings->getSetting("LWJGLDir");
- settings->registerSetting("NeedsRebuild", true);
- settings->registerSetting("ShouldUpdate", false);
- settings->registerSetting("JarVersion", "Unknown");
- settings->registerSetting("LwjglVersion", "2.9.0");
- settings->registerSetting("IntendedJarVersion", "");
- /*
- * custom base jar has no default. it is determined in code... see the accessor methods for
- *it
- *
- * for instances that DO NOT have the CustomBaseJar setting (legacy instances),
- * [.]minecraft/bin/mcbackup.jar is the default base jar
- */
- settings->registerSetting("UseCustomBaseJar", true);
- settings->registerSetting("CustomBaseJar", "");
-}
-
-QString LegacyInstance::baseJar() const
-{
- bool customJar = m_settings->get("UseCustomBaseJar").toBool();
- if (customJar)
- {
- return customBaseJar();
- }
- else
- return defaultBaseJar();
-}
-
-QString LegacyInstance::customBaseJar() const
-{
- QString value = m_settings->get("CustomBaseJar").toString();
- if (value.isNull() || value.isEmpty())
- {
- return defaultCustomBaseJar();
- }
- return value;
-}
-
-void LegacyInstance::setCustomBaseJar(QString val)
-{
- if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar())
- m_settings->reset("CustomBaseJar");
- else
- m_settings->set("CustomBaseJar", val);
-}
-
-void LegacyInstance::setShouldUseCustomBaseJar(bool val)
-{
- m_settings->set("UseCustomBaseJar", val);
-}
-
-bool LegacyInstance::shouldUseCustomBaseJar() const
-{
- return m_settings->get("UseCustomBaseJar").toBool();
-}
-
-
-std::shared_ptr<Task> LegacyInstance::createUpdateTask()
-{
- // make sure the jar mods list is initialized by asking for it.
- auto list = jarModList();
- // create an update task
- return std::shared_ptr<Task>(new LegacyUpdate(this, this));
-}
-
-std::shared_ptr<LaunchTask> LegacyInstance::createLaunchTask(AuthSessionPtr session)
-{
- auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
- auto pptr = process.get();
-
- // print a header
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
- }
- {
- auto step = std::make_shared<CheckJava>(pptr);
- process->appendStep(step);
- }
- // run pre-launch command if that's needed
- if(getPreLaunchCommand().size())
- {
- auto step = std::make_shared<PreLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- // if we aren't in offline mode,.
- if(session->status != AuthSession::PlayableOffline)
- {
- process->appendStep(std::make_shared<Update>(pptr));
- }
- // if there are any jar mods
- if(getJarMods().size())
- {
- auto step = std::make_shared<ModMinecraftJar>(pptr);
- process->appendStep(step);
- }
- // actually launch the game
- {
- auto step = std::make_shared<LaunchMinecraft>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- // run post-exit command if that's needed
- if(getPostExitCommand().size())
- {
- auto step = std::make_shared<PostLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- if (session)
- {
- process->setCensorFilter(createCensorFilterFromSession(session));
- }
- return process;
-}
-
-std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
-{
- class JarModTask : public Task
- {
- public:
- explicit JarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst)
- {
- }
- virtual void executeTask()
- {
- if (!m_inst->shouldRebuild())
- {
- emitSucceeded();
- return;
- }
-
- // Get the mod list
- auto modList = m_inst->getJarMods();
-
- QFileInfo runnableJar(m_inst->runnableJar());
- QFileInfo baseJar(m_inst->baseJar());
- bool base_is_custom = m_inst->shouldUseCustomBaseJar();
-
- // Nothing to do if there are no jar mods to install, no backup and just the mc jar
- if (base_is_custom)
- {
- // yes, this can happen if the instance only has the runnable jar and not the base jar
- // it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
- // because that's not something mmc4 guarantees
- if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
- {
- m_inst->setShouldRebuild(false);
- emitSucceeded();
- return;
- }
-
- setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
- if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
- {
- emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
- "be used on next run.");
- m_inst->setShouldRebuild(true);
- m_inst->setShouldUpdate(true);
- m_inst->setShouldUseCustomBaseJar(false);
- return;
- }
- }
-
- if (!baseJar.exists())
- {
- emitFailed("The base jar " + baseJar.filePath() + " does not exist");
- return;
- }
-
- if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
- {
- emitFailed("Failed to delete old minecraft.jar");
- return;
- }
-
- setStatus(tr("Installing mods: Opening minecraft.jar ..."));
-
- QString outputJarPath = runnableJar.filePath();
- QString inputJarPath = baseJar.filePath();
-
- if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- m_inst->setShouldRebuild(false);
- // inst->UpdateVersion(true);
- emitSucceeded();
- return;
-
- }
- std::shared_ptr<LegacyInstance> m_inst;
- };
- return std::make_shared<JarModTask>(std::dynamic_pointer_cast<LegacyInstance>(shared_from_this()));
-}
-
-QString LegacyInstance::createLaunchScript(AuthSessionPtr session)
-{
- QString launchScript;
-
- // window size
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- {
- windowParams = "max";
- }
- else
- {
- windowParams = QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt());
- }
-
- QString lwjgl = QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath();
- launchScript += "userName " + session->player_name + "\n";
- launchScript += "sessionId " + session->session + "\n";
- launchScript += "windowTitle " + windowTitle() + "\n";
- launchScript += "windowParams " + windowParams + "\n";
- launchScript += "lwjgl " + lwjgl + "\n";
- launchScript += "launcher legacy\n";
- return launchScript;
-}
-
-void LegacyInstance::cleanupAfterRun()
-{
- // FIXME: delete the launcher and icons and whatnot.
-}
-
-std::shared_ptr<ModList> LegacyInstance::coreModList() const
-{
- if (!core_mod_list)
- {
- core_mod_list.reset(new ModList(coreModsDir()));
- }
- core_mod_list->update();
- return core_mod_list;
-}
-
-std::shared_ptr<ModList> LegacyInstance::jarModList() const
-{
- if (!jar_mod_list)
- {
- auto list = new ModList(jarModsDir(), modListFile());
- connect(list, SIGNAL(changed()), SLOT(jarModsChanged()));
- jar_mod_list.reset(list);
- }
- jar_mod_list->update();
- return jar_mod_list;
-}
-
-QList<Mod> LegacyInstance::getJarMods() const
-{
- return jarModList()->allMods();
-}
-
-void LegacyInstance::jarModsChanged()
-{
- qDebug() << "Jar mods of instance " << name() << " have changed. Jar will be rebuilt.";
- setShouldRebuild(true);
-}
-
-std::shared_ptr<ModList> LegacyInstance::loaderModList() const
-{
- if (!loader_mod_list)
- {
- loader_mod_list.reset(new ModList(loaderModsDir()));
- }
- loader_mod_list->update();
- return loader_mod_list;
-}
-
-std::shared_ptr<ModList> LegacyInstance::texturePackList() const
-{
- if (!texture_pack_list)
- {
- texture_pack_list.reset(new ModList(texturePacksDir()));
- }
- texture_pack_list->update();
- return texture_pack_list;
-}
-
-std::shared_ptr<WorldList> LegacyInstance::worldList() const
-{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(savesDir()));
- }
- return m_world_list;
-}
-
-QString LegacyInstance::jarModsDir() const
-{
- return FS::PathCombine(instanceRoot(), "instMods");
-}
-
-QString LegacyInstance::binDir() const
-{
- return FS::PathCombine(minecraftRoot(), "bin");
-}
-
-QString LegacyInstance::libDir() const
-{
- return FS::PathCombine(minecraftRoot(), "lib");
-}
-
-QString LegacyInstance::savesDir() const
-{
- return FS::PathCombine(minecraftRoot(), "saves");
-}
-
-QString LegacyInstance::loaderModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "mods");
-}
-
-QString LegacyInstance::coreModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "coremods");
-}
-
-QString LegacyInstance::resourceDir() const
-{
- return FS::PathCombine(minecraftRoot(), "resources");
-}
-QString LegacyInstance::texturePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
-}
-
-QString LegacyInstance::runnableJar() const
-{
- return FS::PathCombine(binDir(), "minecraft.jar");
-}
-
-QString LegacyInstance::modListFile() const
-{
- return FS::PathCombine(instanceRoot(), "modlist");
-}
-
-QString LegacyInstance::instanceConfigFolder() const
-{
- return FS::PathCombine(minecraftRoot(), "config");
-}
-
-bool LegacyInstance::shouldRebuild() const
-{
- return m_settings->get("NeedsRebuild").toBool();
-}
-
-void LegacyInstance::setShouldRebuild(bool val)
-{
- m_settings->set("NeedsRebuild", val);
-}
-
-QString LegacyInstance::currentVersionId() const
-{
- return m_settings->get("JarVersion").toString();
-}
-
-QString LegacyInstance::lwjglVersion() const
-{
- return m_settings->get("LwjglVersion").toString();
-}
-
-void LegacyInstance::setLWJGLVersion(QString val)
-{
- m_settings->set("LwjglVersion", val);
-}
-
-QString LegacyInstance::intendedVersionId() const
-{
- return m_settings->get("IntendedJarVersion").toString();
-}
-
-bool LegacyInstance::setIntendedVersionId(QString version)
-{
- settings()->set("IntendedJarVersion", version);
- setShouldUpdate(true);
- return true;
-}
-
-bool LegacyInstance::shouldUpdate() const
-{
- QVariant var = settings()->get("ShouldUpdate");
- if (!var.isValid() || var.toBool() == false)
- {
- return intendedVersionId() != currentVersionId();
- }
- return true;
-}
-
-void LegacyInstance::setShouldUpdate(bool val)
-{
- settings()->set("ShouldUpdate", val);
-}
-
-QString LegacyInstance::defaultBaseJar() const
-{
- return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
-}
-
-QString LegacyInstance::defaultCustomBaseJar() const
-{
- return FS::PathCombine(binDir(), "mcbackup.jar");
-}
-
-QString LegacyInstance::lwjglFolder() const
-{
- return m_lwjglFolderSetting->get().toString();
-}
-
-QString LegacyInstance::typeName() const
-{
- return tr("Legacy");
-}
diff --git a/libraries/logic/minecraft/legacy/LegacyInstance.h b/libraries/logic/minecraft/legacy/LegacyInstance.h
deleted file mode 100644
index 3bef240d..00000000
--- a/libraries/logic/minecraft/legacy/LegacyInstance.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright 2013-2015 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/MinecraftInstance.h"
-
-#include "multimc_logic_export.h"
-
-class ModList;
-class Task;
-
-class MULTIMC_LOGIC_EXPORT LegacyInstance : public MinecraftInstance
-{
- Q_OBJECT
-public:
-
- explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
-
- virtual void init() override {};
-
- /// Path to the instance's minecraft.jar
- QString runnableJar() const;
-
- //! Path to the instance's modlist file.
- QString modListFile() const;
-
- /*
- ////// Edit Instance Dialog stuff //////
- virtual QList<BasePage *> getPages();
- virtual QString dialogTitle();
- */
-
- ////// Mod Lists //////
- std::shared_ptr<ModList> jarModList() const ;
- virtual QList< Mod > getJarMods() const override;
- std::shared_ptr<ModList> coreModList() const;
- std::shared_ptr<ModList> loaderModList() const;
- std::shared_ptr<ModList> texturePackList() const override;
- std::shared_ptr<WorldList> worldList() const override;
-
- ////// Directories //////
- QString libDir() const;
- QString savesDir() const;
- QString texturePacksDir() const;
- QString jarModsDir() const;
- QString binDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
- QString resourceDir() const;
- virtual QString instanceConfigFolder() const override;
-
- /// Get the curent base jar of this instance. By default, it's the
- /// versions/$version/$version.jar
- QString baseJar() const;
-
- /// the default base jar of this instance
- QString defaultBaseJar() const;
- /// the default custom base jar of this instance
- QString defaultCustomBaseJar() const;
-
- /*!
- * Whether or not custom base jar is used
- */
- bool shouldUseCustomBaseJar() const;
- void setShouldUseCustomBaseJar(bool val);
-
- /*!
- * The value of the custom base jar
- */
- QString customBaseJar() const;
- void setCustomBaseJar(QString val);
-
- /*!
- * Whether or not the instance's minecraft.jar needs to be rebuilt.
- * If this is true, when the instance launches, its jar mods will be
- * re-added to a fresh minecraft.jar file.
- */
- bool shouldRebuild() const;
- void setShouldRebuild(bool val);
-
- virtual QString currentVersionId() const override;
-
- //! The version of LWJGL that this instance uses.
- QString lwjglVersion() const;
-
- //! Where the lwjgl versions foor this instance can be found... HACK HACK HACK
- QString lwjglFolder() const;
-
- /// st the version of LWJGL libs this instance will use
- void setLWJGLVersion(QString val);
-
- virtual QString intendedVersionId() const override;
- virtual bool setIntendedVersionId(QString version) override;
-
- virtual QSet<QString> traits() override
- {
- return {"legacy-instance", "texturepacks"};
- };
-
- virtual bool shouldUpdate() const override;
- virtual void setShouldUpdate(bool val) override;
- virtual std::shared_ptr<Task> createUpdateTask() override;
-
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
-
- virtual std::shared_ptr<Task> createJarModdingTask() override;
-
- virtual QString createLaunchScript(AuthSessionPtr session) override;
-
- virtual void cleanupAfterRun() override;
-
- virtual QString typeName() const override;
-
- bool canExport() const override
- {
- return true;
- }
-
-protected:
- mutable std::shared_ptr<ModList> jar_mod_list;
- mutable std::shared_ptr<ModList> core_mod_list;
- mutable std::shared_ptr<ModList> loader_mod_list;
- mutable std::shared_ptr<ModList> texture_pack_list;
- mutable std::shared_ptr<WorldList> m_world_list;
- std::shared_ptr<Setting> m_lwjglFolderSetting;
-protected
-slots:
- virtual void jarModsChanged();
-};
diff --git a/libraries/logic/minecraft/legacy/LegacyUpdate.cpp b/libraries/logic/minecraft/legacy/LegacyUpdate.cpp
deleted file mode 100644
index 2d7e8dd2..00000000
--- a/libraries/logic/minecraft/legacy/LegacyUpdate.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/* Copyright 2013-2015 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 <QStringList>
-#include <quazip.h>
-#include <quazipfile.h>
-#include <QDebug>
-
-#include "Env.h"
-#include "BaseInstance.h"
-#include "net/URLConstants.h"
-#include "MMCZip.h"
-
-#include "LegacyUpdate.h"
-
-#include "LwjglVersionList.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "minecraft/ModList.h"
-#include "LegacyInstance.h"
-#include <FileSystem.h>
-
-LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
-{
-}
-
-void LegacyUpdate::executeTask()
-{
- fmllibsStart();
-}
-
-void LegacyUpdate::fmllibsStart()
-{
- // Get the mod list
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- auto modList = inst->jarModList();
-
- bool forge_present = false;
-
- QString version = inst->intendedVersionId();
- auto & fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- lwjglStart();
- return;
- }
-
- auto &libList = fmlLibsMapping[version];
-
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- for (unsigned i = 0; i < modList->size(); i++)
- {
- auto &mod = modList->operator[](i);
-
- // do not use disabled mods.
- if (!mod.enabled())
- continue;
-
- if (mod.type() != Mod::MOD_ZIPFILE)
- continue;
-
- if (mod.mmc_id().contains("forge", Qt::CaseInsensitive))
- {
- forge_present = true;
- break;
- }
- if (mod.mmc_id().contains("fml", Qt::CaseInsensitive))
- {
- forge_present = true;
- break;
- }
- }
- // we don't...
- if (!forge_present)
- {
- lwjglStart();
- return;
- }
-
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
-
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- lwjglStart();
- return;
- }
-
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
- }
-
- connect(dljob, &NetJob::succeeded, this, &LegacyUpdate::fmllibsFinished);
- connect(dljob, &NetJob::failed, this, &LegacyUpdate::fmllibsFailed);
- connect(dljob, &NetJob::progress, this, &LegacyUpdate::progress);
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void LegacyUpdate::fmllibsFinished()
-{
- legacyDownloadJob.reset();
- if(!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = FS::PathCombine(inst->libDir(), lib.filename);
- if(!FS::ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- lwjglStart();
-}
-
-void LegacyUpdate::fmllibsFailed(QString reason)
-{
- emitFailed(tr("Game update failed: it was impossible to fetch the required FML libraries. Reason: %1").arg(reason));
- return;
-}
-
-void LegacyUpdate::lwjglStart()
-{
- LegacyInstance *inst = (LegacyInstance *)m_inst;
-
- lwjglVersion = inst->lwjglVersion();
- lwjglTargetPath = FS::PathCombine(inst->lwjglFolder(), lwjglVersion);
- lwjglNativesPath = FS::PathCombine(lwjglTargetPath, "natives");
-
- // if the 'done' file exists, we don't have to download this again
- QFileInfo doneFile(FS::PathCombine(lwjglTargetPath, "done"));
- if (doneFile.exists())
- {
- jarStart();
- return;
- }
-
- auto list = std::dynamic_pointer_cast<LWJGLVersionList>(ENV.getVersionList("org.lwjgl.legacy"));
- if (!list->isLoaded())
- {
- emitFailed("Too soon! Let the LWJGL list load :)");
- return;
- }
-
- setStatus(tr("Downloading new LWJGL..."));
- auto version = std::dynamic_pointer_cast<LWJGLVersion>(list->findVersion(lwjglVersion));
- if (!version)
- {
- emitFailed("Game update failed: the selected LWJGL version is invalid.");
- return;
- }
-
- QString url = version->url();
- QUrl realUrl(url);
- QString hostname = realUrl.host();
- auto worker = ENV.qnam();
- QNetworkRequest req(realUrl);
- req.setRawHeader("Host", hostname.toLatin1());
- req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
- QNetworkReply *rep = worker->get(req);
-
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
- connect(worker.get(), &QNetworkAccessManager::finished, this, &LegacyUpdate::lwjglFinished);
-}
-
-void LegacyUpdate::lwjglFinished(QNetworkReply *reply)
-{
- if (m_reply.get() != reply)
- {
- return;
- }
- if (reply->error() != QNetworkReply::NoError)
- {
- emitFailed("Failed to download: " + reply->errorString() +
- "\nSometimes you have to wait a bit if you download many LWJGL versions in "
- "a row. YMMV");
- return;
- }
- auto worker = ENV.qnam();
- // Here i check if there is a cookie for me in the reply and extract it
- QList<QNetworkCookie> cookies =
- qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader));
- if (cookies.count() != 0)
- {
- // you must tell which cookie goes with which url
- worker->cookieJar()->setCookiesFromUrl(cookies, QUrl("sourceforge.net"));
- }
-
- // here you can check for the 302 or whatever other header i need
- QVariant newLoc = reply->header(QNetworkRequest::LocationHeader);
- if (newLoc.isValid())
- {
- QString redirectedTo = reply->header(QNetworkRequest::LocationHeader).toString();
- QUrl realUrl(redirectedTo);
- QString hostname = realUrl.host();
- QNetworkRequest req(redirectedTo);
- req.setRawHeader("Host", hostname.toLatin1());
- req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
- QNetworkReply *rep = worker->get(req);
- connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- return;
- }
- QFile saveMe("lwjgl.zip");
- saveMe.open(QIODevice::WriteOnly);
- saveMe.write(m_reply->readAll());
- saveMe.close();
- setStatus(tr("Installing new LWJGL..."));
- extractLwjgl();
- jarStart();
-}
-void LegacyUpdate::extractLwjgl()
-{
- // make sure the directories are there
-
- bool success = FS::ensureFolderPathExists(lwjglNativesPath);
-
- if (!success)
- {
- emitFailed("Failed to extract the lwjgl libs - error when creating required folders.");
- return;
- }
-
- QuaZip zip("lwjgl.zip");
- if (!zip.open(QuaZip::mdUnzip))
- {
- emitFailed("Failed to extract the lwjgl libs - not a valid archive.");
- return;
- }
-
- // and now we are going to access files inside it
- QuaZipFile file(&zip);
- const QString jarNames[] = {"jinput.jar", "lwjgl_util.jar", "lwjgl.jar"};
- for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- emitFailed("Failed to extract the lwjgl libs - error while reading archive.");
- return;
- }
- QuaZipFileInfo info;
- QString name = file.getActualFileName();
- if (name.endsWith('/'))
- {
- file.close();
- continue;
- }
- QString destFileName;
- // Look for the jars
- for (int i = 0; i < 3; i++)
- {
- if (name.endsWith(jarNames[i]))
- {
- destFileName = FS::PathCombine(lwjglTargetPath, jarNames[i]);
- }
- }
- // Not found? look for the natives
- if (destFileName.isEmpty())
- {
-#ifdef Q_OS_WIN32
- QString nativesDir = "windows";
-#else
-#ifdef Q_OS_MAC
- QString nativesDir = "macosx";
-#else
- QString nativesDir = "linux";
-#endif
-#endif
- if (name.contains(nativesDir))
- {
- int lastSlash = name.lastIndexOf('/');
- int lastBackSlash = name.lastIndexOf('\\');
- if (lastSlash != -1)
- name = name.mid(lastSlash + 1);
- else if (lastBackSlash != -1)
- name = name.mid(lastBackSlash + 1);
- destFileName = FS::PathCombine(lwjglNativesPath, name);
- }
- }
- // Now if destFileName is still empty, go to the next file.
- if (!destFileName.isEmpty())
- {
- setStatus(tr("Installing new LWJGL - extracting ") + name + "...");
- QFile output(destFileName);
- output.open(QIODevice::WriteOnly);
- output.write(file.readAll());
- output.close();
- }
- file.close(); // do not forget to close!
- }
- zip.close();
- m_reply.reset();
- QFile doneFile(FS::PathCombine(lwjglTargetPath, "done"));
- doneFile.open(QIODevice::WriteOnly);
- doneFile.write("done.");
- doneFile.close();
-}
-
-void LegacyUpdate::lwjglFailed(QString reason)
-{
- emitFailed(tr("Bad stuff happened while trying to get the lwjgl libs: %1").arg(reason));
-}
-
-void LegacyUpdate::jarStart()
-{
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
- {
- emitSucceeded();
- return;
- }
-
- setStatus(tr("Checking for jar updates..."));
- // Make directories
- QDir binDir(inst->binDir());
- if (!binDir.exists() && !binDir.mkpath("."))
- {
- emitFailed("Failed to create bin folder.");
- return;
- }
-
- // Build a list of URLs that will need to be downloaded.
- setStatus(tr("Downloading new minecraft.jar ..."));
-
- QString version_id = inst->intendedVersionId();
-
- auto dljob = new NetJob("Minecraft.jar for version " + version_id);
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", URLConstants::getJarPath(version_id));
- dljob->addNetAction(CacheDownload::make(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry));
- connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
- connect(dljob, SIGNAL(failed(QString)), SLOT(jarFailed(QString)));
- connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void LegacyUpdate::jarFinished()
-{
- // process the jar
- emitSucceeded();
-}
-
-void LegacyUpdate::jarFailed(QString reason)
-{
- // bad, bad
- emitFailed(tr("Failed to download the minecraft jar: %1.").arg(reason));
-}
diff --git a/libraries/logic/minecraft/legacy/LegacyUpdate.h b/libraries/logic/minecraft/legacy/LegacyUpdate.h
deleted file mode 100644
index c52bf934..00000000
--- a/libraries/logic/minecraft/legacy/LegacyUpdate.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2013-2015 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 <QUrl>
-
-#include "net/NetJob.h"
-#include "tasks/Task.h"
-#include "minecraft/VersionFilterData.h"
-
-class MinecraftVersion;
-class BaseInstance;
-class QuaZip;
-class Mod;
-
-class LegacyUpdate : public Task
-{
- Q_OBJECT
-public:
- explicit LegacyUpdate(BaseInstance *inst, QObject *parent = 0);
- virtual void executeTask();
-
-private
-slots:
- void lwjglStart();
- void lwjglFinished(QNetworkReply *);
- void lwjglFailed(QString reason);
-
- void jarStart();
- void jarFinished();
- void jarFailed(QString reason);
-
- void fmllibsStart();
- void fmllibsFinished();
- void fmllibsFailed(QString reason);
-
- void extractLwjgl();
-
-private:
-
- std::shared_ptr<QNetworkReply> m_reply;
-
- // target version, determined during this task
- // MinecraftVersion *targetVersion;
- QString lwjglURL;
- QString lwjglVersion;
-
- QString lwjglTargetPath;
- QString lwjglNativesPath;
-
-private:
- NetJobPtr legacyDownloadJob;
- BaseInstance *m_inst = nullptr;
- QList<FMLlib> fmlLibsToProcess;
-};
diff --git a/libraries/logic/minecraft/legacy/LwjglVersionList.cpp b/libraries/logic/minecraft/legacy/LwjglVersionList.cpp
deleted file mode 100644
index bb017368..00000000
--- a/libraries/logic/minecraft/legacy/LwjglVersionList.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "LwjglVersionList.h"
-#include "Env.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include <QDebug>
-
-#define RSS_URL "http://sourceforge.net/projects/java-game-lib/rss"
-
-LWJGLVersionList::LWJGLVersionList(QObject *parent) : BaseVersionList(parent)
-{
- setLoading(false);
-}
-
-QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- const PtrLWJGLVersion version = m_vlist.at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- return version->name();
-
- case Qt::ToolTipRole:
- return version->url();
-
- default:
- return QVariant();
- }
-}
-
-QVariant LWJGLVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- return tr("Version");
-
- case Qt::ToolTipRole:
- return tr("LWJGL version name.");
-
- default:
- return QVariant();
- }
-}
-
-int LWJGLVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-bool LWJGLVersionList::isLoading() const
-{
- return m_loading;
-}
-
-void LWJGLVersionList::loadList()
-{
- Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)");
-
- setLoading(true);
- auto worker = ENV.qnam();
- QNetworkRequest req(QUrl(RSS_URL));
- req.setRawHeader("Accept", "application/rss+xml, text/xml, */*");
- req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)");
- reply = worker->get(req);
- connect(reply, SIGNAL(finished()), SLOT(netRequestComplete()));
-}
-
-inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
-{
- QDomNodeList elementList = parent.elementsByTagName(tagname);
- if (elementList.count())
- return elementList.at(0).toElement();
- else
- return QDomElement();
-}
-
-void LWJGLVersionList::netRequestComplete()
-{
- if (reply->error() == QNetworkReply::NoError)
- {
- QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
- Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid");
-
- QDomDocument doc;
-
- QString xmlErrorMsg;
- int errorLine;
- auto rawData = reply->readAll();
- if (!doc.setContent(rawData, false, &xmlErrorMsg, &errorLine))
- {
- failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " +
- QString::number(errorLine));
- setLoading(false);
- return;
- }
-
- QDomNodeList items = doc.elementsByTagName("item");
-
- QList<PtrLWJGLVersion> tempList;
-
- for (int i = 0; i < items.length(); i++)
- {
- Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list",
- "XML element isn't an element... wat?");
-
- QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
- if (linkElement.isNull())
- {
- qDebug() << "Link element" << i << "in RSS feed doesn't exist! Skipping.";
- continue;
- }
-
- QString link = linkElement.text();
-
- // Make sure it's a download link.
- if (link.endsWith("/download") && link.contains(lwjglRegex))
- {
- QString name = link.mid(lwjglRegex.indexIn(link) + 6);
- // Subtract 4 here to remove the .zip file extension.
- name = name.left(lwjglRegex.matchedLength() - 10);
-
- QUrl url(link);
- if (!url.isValid())
- {
- qWarning() << "LWJGL version URL isn't valid:" << link << "Skipping.";
- continue;
- }
- qDebug() << "Discovered LWGL version" << name << "at" << link;
- tempList.append(std::make_shared<LWJGLVersion>(name, link));
- }
- }
-
- beginResetModel();
- m_vlist.swap(tempList);
- endResetModel();
-
- qDebug() << "Loaded LWJGL list.";
- finished();
- }
- else
- {
- failed("Failed to load LWJGL list. Network error: " + reply->errorString());
- }
-
- setLoading(false);
- reply->deleteLater();
-}
-
-void LWJGLVersionList::failed(QString msg)
-{
- qCritical() << msg;
- emit loadListFailed(msg);
-}
-
-void LWJGLVersionList::finished()
-{
- emit loadListFinished();
-}
-
-void LWJGLVersionList::setLoading(bool loading)
-{
- m_loading = loading;
- emit loadingStateUpdated(m_loading);
-}
diff --git a/libraries/logic/minecraft/legacy/LwjglVersionList.h b/libraries/logic/minecraft/legacy/LwjglVersionList.h
deleted file mode 100644
index f043f6e2..00000000
--- a/libraries/logic/minecraft/legacy/LwjglVersionList.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QAbstractListModel>
-#include <QUrl>
-#include <QNetworkReply>
-#include <memory>
-
-#include "BaseVersion.h"
-#include "BaseVersionList.h"
-
-#include "multimc_logic_export.h"
-
-class LWJGLVersion;
-typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion;
-
-class MULTIMC_LOGIC_EXPORT LWJGLVersion : public BaseVersion
-{
-public:
- LWJGLVersion(const QString &name, const QString &url)
- : m_name(name), m_url(url)
- {
- }
-
- virtual QString descriptor()
- {
- return m_name;
- }
-
- virtual QString name()
- {
- return m_name;
- }
-
- virtual QString typeString() const
- {
- return QObject::tr("Upstream");
- }
-
- QString url() const
- {
- return m_url;
- }
-
-protected:
- QString m_name;
- QString m_url;
-};
-
-class MULTIMC_LOGIC_EXPORT LWJGLVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- explicit LWJGLVersionList(QObject *parent = 0);
-
- bool isLoaded() override
- {
- return m_vlist.length() > 0;
- }
- virtual const BaseVersionPtr at(int i) const override
- {
- return m_vlist[i];
- }
-
- virtual Task* getLoadTask() override
- {
- return nullptr;
- }
-
- virtual void sortVersions() override {};
-
- virtual void updateListData(QList< BaseVersionPtr > versions) override {};
-
- int count() const override
- {
- return m_vlist.length();
- }
-
- virtual QVariant data(const QModelIndex &index, int role) const override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- virtual int rowCount(const QModelIndex &parent) const override
- {
- return count();
- }
- virtual int columnCount(const QModelIndex &parent) const override;
-
- virtual bool isLoading() const;
- virtual bool errored() const
- {
- return m_errored;
- }
-
- virtual QString lastErrorMsg() const
- {
- return m_lastErrorMsg;
- }
-
-public
-slots:
- /*!
- * Loads the version list.
- * This is done asynchronously. On success, the loadListFinished() signal will
- * be emitted. The list model will be reset as well, resulting in the modelReset()
- * signal being emitted. Note that the model will be reset before loadListFinished() is
- * emitted.
- * If loading the list failed, the loadListFailed(QString msg),
- * signal will be emitted.
- */
- virtual void loadList();
-
-signals:
- /*!
- * Emitted when the list either starts or finishes loading.
- * \param loading Whether or not the list is loading.
- */
- void loadingStateUpdated(bool loading);
-
- void loadListFinished();
-
- void loadListFailed(QString msg);
-
-private:
- QList<PtrLWJGLVersion> m_vlist;
-
- QNetworkReply *m_netReply;
- QNetworkReply *reply;
-
- bool m_loading;
- bool m_errored;
- QString m_lastErrorMsg;
-
- void failed(QString msg);
-
- void finished();
-
- void setLoading(bool loading);
-
-private
-slots:
- virtual void netRequestComplete();
-};
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp b/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
deleted file mode 100644
index 25297fa4..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright 2013-2015 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;
- }
-
- QJsonObject obj;
-
- obj.insert("mainClass", QString("net.minecraft.launchwrapper.Launch"));
- obj.insert("+tweakers", QJsonArray::fromStringList(QStringList() << m_version->tweakClass));
- obj.insert("order", 10);
-
- QJsonArray libraries;
-
- for (auto Library : m_version->libraries)
- {
- libraries.append(OneSixVersionFormat::libraryToJson(Library.get()));
- }
-
- // liteloader
- {
- Library liteloaderLib("com.mumfrey:liteloader:" + m_version->version);
- liteloaderLib.setAbsoluteUrl(QString("http://dl.liteloader.com/versions/com/mumfrey/liteloader/%1/%2").arg(m_version->mcVersion, m_version->file));
- QJsonObject llLibObj = OneSixVersionFormat::libraryToJson(&liteloaderLib);
- libraries.append(llLibObj);
- }
-
- obj.insert("+libraries", libraries);
- obj.insert("name", QString("LiteLoader"));
- obj.insert("fileId", id());
- obj.insert("version", m_version->version);
- obj.insert("mcVersion", to->intendedVersionId());
-
- 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 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."));
- }
- else
- {
- 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/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h b/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h
deleted file mode 100644
index fe0aee3d..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2015 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/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
deleted file mode 100644
index b0c9736a..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* Copyright 2013-2015 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;
-}
-
-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 RecommendedRole:
- return version->isLatest;
-
- default:
- return QVariant();
- }
-}
-
-QList<BaseVersionList::ModelRoles> LiteLoaderVersionList::providesRoles()
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole};
-}
-
-BaseVersionPtr LiteLoaderVersionList::getLatestStable() const
-{
- for (int i = 0; i < m_vlist.length(); i++)
- {
- auto ver = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist.at(i));
- if (ver->isLatest)
- {
- return m_vlist.at(i);
- }
- }
- return BaseVersionPtr();
-}
-
-void LiteLoaderVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- 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 = CacheDownload::make(QUrl(URLConstants::LITELOADER_URL),
- liteloaderEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-void LLListLoadTask::listFailed()
-{
- emitFailed("Failed to load LiteLoader version list.");
- return;
-}
-
-void LLListLoadTask::listDownloaded()
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- emitFailed("Failed to open the LiteLoader version list.");
- return;
- }
- data = listFile.readAll();
- listFile.close();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: jsonDoc is not an object");
- return;
- }
-
- const QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("versions").isObject())
- {
- emitFailed("Error parsing version list JSON: missing 'versions' object");
- return;
- }
-
- auto meta = root.value("meta").toObject();
- QString description = meta.value("description").toString(tr("This is a lightweight loader for mods that don't change game mechanics."));
- QString defaultUrl = meta.value("url").toString("http://dl.liteloader.com");
- QString authors = meta.value("authors").toString("Mumfrey");
- auto versions = root.value("versions").toObject();
-
- QList<BaseVersionPtr> tempList;
- for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt)
- {
- const QString mcVersion = vIt.key();
- QString latest;
- const QJsonObject artefacts = vIt.value()
- .toObject()
- .value("artefacts")
- .toObject()
- .value("com.mumfrey:liteloader")
- .toObject();
- QList<BaseVersionPtr> perMcVersionList;
- for (auto aIt = artefacts.begin(); aIt != artefacts.end(); ++aIt)
- {
- const QString identifier = aIt.key();
- const QJsonObject artefact = aIt.value().toObject();
- if (identifier == "latest")
- {
- latest = artefact.value("version").toString();
- continue;
- }
- LiteLoaderVersionPtr version(new LiteLoaderVersion());
- version->version = artefact.value("version").toString();
- version->file = artefact.value("file").toString();
- version->mcVersion = mcVersion;
- version->md5 = artefact.value("md5").toString();
- version->timestamp = artefact.value("timestamp").toString().toInt();
- version->tweakClass = artefact.value("tweakClass").toString();
- version->authors = authors;
- version->description = description;
- version->defaultUrl = defaultUrl;
- const QJsonArray libs = artefact.value("libraries").toArray();
- for (auto lIt = libs.begin(); lIt != libs.end(); ++lIt)
- {
- 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;
- }
- }
- perMcVersionList.append(version);
- }
- for (auto version : perMcVersionList)
- {
- auto v = std::dynamic_pointer_cast<LiteLoaderVersion>(version);
- v->isLatest = v->version == latest;
- }
- tempList.append(perMcVersionList);
- }
- m_list->updateListData(tempList);
-
- emitSucceeded();
-}
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h b/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h
deleted file mode 100644
index 1dba4b6a..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2015 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 "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;
- }
-
- // important info
- QString version;
- QString file;
- QString mcVersion;
- QString md5;
- int timestamp;
- bool isLatest;
- 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);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sortVersions();
- virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
- virtual QList< ModelRoles > providesRoles();
-
- virtual BaseVersionPtr getLatestStable() const;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-};
-
-class LLListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit LLListLoadTask(LiteLoaderVersionList *vlist);
- ~LLListLoadTask();
-
- virtual void executeTask();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
-
-protected:
- NetJobPtr listJob;
- CacheDownloadPtr listDownload;
- LiteLoaderVersionList *m_list;
-};
-
-Q_DECLARE_METATYPE(LiteLoaderVersionPtr)
diff --git a/libraries/logic/minecraft/onesix/OneSixInstance.cpp b/libraries/logic/minecraft/onesix/OneSixInstance.cpp
deleted file mode 100644
index 258e26c5..00000000
--- a/libraries/logic/minecraft/onesix/OneSixInstance.cpp
+++ /dev/null
@@ -1,597 +0,0 @@
-/* Copyright 2013-2015 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 <QDebug>
-#include <Env.h>
-
-#include "OneSixInstance.h"
-#include "OneSixUpdate.h"
-#include "OneSixProfileStrategy.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/VersionBuildError.h"
-#include "launch/LaunchTask.h"
-#include "launch/steps/PreLaunchCommand.h"
-#include "launch/steps/Update.h"
-#include "launch/steps/LaunchMinecraft.h"
-#include "launch/steps/PostLaunchCommand.h"
-#include "launch/steps/TextPrint.h"
-#include "launch/steps/ModMinecraftJar.h"
-#include "launch/steps/CheckJava.h"
-#include "MMCZip.h"
-
-#include "minecraft/AssetsUtils.h"
-#include "minecraft/WorldList.h"
-#include <FileSystem.h>
-
-OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : MinecraftInstance(globalSettings, settings, rootDir)
-{
- m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
-}
-
-void OneSixInstance::init()
-{
- createProfile();
-}
-
-void OneSixInstance::createProfile()
-{
- m_profile.reset(new MinecraftProfile(new OneSixProfileStrategy(this)));
-}
-
-QSet<QString> OneSixInstance::traits()
-{
- auto version = getMinecraftProfile();
- if (!version)
- {
- return {"version-incomplete"};
- }
- else
- {
- return version->getTraits();
- }
-}
-
-std::shared_ptr<Task> OneSixInstance::createUpdateTask()
-{
- return std::shared_ptr<Task>(new OneSixUpdate(this));
-}
-
-QString replaceTokensIn(QString text, QMap<QString, QString> with)
-{
- QString result;
- QRegExp token_regexp("\\$\\{(.+)\\}");
- token_regexp.setMinimal(true);
- QStringList list;
- int tail = 0;
- int head = 0;
- while ((head = token_regexp.indexIn(text, head)) != -1)
- {
- result.append(text.mid(tail, head - tail));
- QString key = token_regexp.cap(1);
- auto iter = with.find(key);
- if (iter != with.end())
- {
- result.append(*iter);
- }
- head += token_regexp.matchedLength();
- tail = head;
- }
- result.append(text.mid(tail));
- return result;
-}
-
-QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
-{
- QString args_pattern = m_profile->getMinecraftArguments();
- for (auto tweaker : m_profile->getTweakers())
- {
- args_pattern += " --tweakClass " + tweaker;
- }
-
- QMap<QString, QString> token_mapping;
- // yggdrasil!
- token_mapping["auth_username"] = session->username;
- token_mapping["auth_session"] = session->session;
- token_mapping["auth_access_token"] = session->access_token;
- token_mapping["auth_player_name"] = session->player_name;
- token_mapping["auth_uuid"] = session->uuid;
-
- // blatant self-promotion.
- token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
- if(m_profile->isVanilla())
- {
- token_mapping["version_type"] = m_profile->getMinecraftVersionType();
- }
- else
- {
- token_mapping["version_type"] = "custom";
- }
-
- QString absRootDir = QDir(minecraftRoot()).absolutePath();
- token_mapping["game_directory"] = absRootDir;
- QString absAssetsDir = QDir("assets/").absolutePath();
- auto assets = m_profile->getMinecraftAssets();
- token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
-
- token_mapping["user_properties"] = session->serializeUserProperties();
- token_mapping["user_type"] = session->user_type;
-
- // 1.7.3+ assets tokens
- token_mapping["assets_root"] = absAssetsDir;
- token_mapping["assets_index_name"] = assets->id;
-
- QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
- for (int i = 0; i < parts.length(); i++)
- {
- parts[i] = replaceTokensIn(parts[i], token_mapping);
- }
- return parts;
-}
-
-QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
-{
- QString launchScript;
-
- if (!m_profile)
- return nullptr;
-
- for(auto & mod: loaderModList()->allMods())
- {
- if(!mod.enabled())
- continue;
- if(mod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- launchScript += "mod " + mod.filename().completeBaseName() + "\n";;
- }
-
- for(auto & coremod: coreModList()->allMods())
- {
- if(!coremod.enabled())
- continue;
- if(coremod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- launchScript += "coremod " + coremod.filename().completeBaseName() + "\n";;
- }
-
- for(auto & jarmod: m_profile->getJarMods())
- {
- launchScript += "jarmod " + jarmod->originalName + " (" + jarmod->name + ")\n";
- }
-
- auto mainClass = m_profile->getMainClass();
- if (!mainClass.isEmpty())
- {
- launchScript += "mainClass " + mainClass + "\n";
- }
- auto appletClass = m_profile->getAppletClass();
- if (!appletClass.isEmpty())
- {
- launchScript += "appletClass " + appletClass + "\n";
- }
-
- // generic minecraft params
- for (auto param : processMinecraftArgs(session))
- {
- launchScript += "param " + param + "\n";
- }
-
- // window size, title and state, legacy
- {
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- windowParams = "max";
- else
- windowParams = QString("%1x%2")
- .arg(settings()->get("MinecraftWinWidth").toInt())
- .arg(settings()->get("MinecraftWinHeight").toInt());
- launchScript += "windowTitle " + windowTitle() + "\n";
- launchScript += "windowParams " + windowParams + "\n";
- }
-
- // legacy auth
- {
- launchScript += "userName " + session->player_name + "\n";
- launchScript += "sessionId " + session->session + "\n";
- }
-
- // libraries and class path.
- {
- auto libs = m_profile->getLibraries();
-
- QStringList jar, native, native32, native64;
- for (auto lib : libs)
- {
- lib->getApplicableFiles(currentSystem, jar, native, native32, native64);
- }
- for(auto file: jar)
- {
- launchScript += "cp " + file + "\n";
- }
- for(auto file: native)
- {
- launchScript += "ext " + file + "\n";
- }
- for(auto file: native32)
- {
- launchScript += "ext32 " + file + "\n";
- }
- for(auto file: native64)
- {
- launchScript += "ext64 " + file + "\n";
- }
- QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
- launchScript += "natives " + natives_dir.absolutePath() + "\n";
- auto jarMods = getJarMods();
- if (!jarMods.isEmpty())
- {
- launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("minecraft.jar") + "\n";
- }
- else
- {
- QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar";
- launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n";
- }
- }
-
- // traits. including legacyLaunch and others ;)
- for (auto trait : m_profile->getTraits())
- {
- launchScript += "traits " + trait + "\n";
- }
- launchScript += "launcher onesix\n";
- return launchScript;
-}
-
-std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr session)
-{
- auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
- auto pptr = process.get();
-
- // print a header
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
- }
- {
- auto step = std::make_shared<CheckJava>(pptr);
- process->appendStep(step);
- }
- // run pre-launch command if that's needed
- if(getPreLaunchCommand().size())
- {
- auto step = std::make_shared<PreLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- // if we aren't in offline mode,.
- if(session->status != AuthSession::PlayableOffline)
- {
- process->appendStep(std::make_shared<Update>(pptr));
- }
- // if there are any jar mods
- if(getJarMods().size())
- {
- auto step = std::make_shared<ModMinecraftJar>(pptr);
- process->appendStep(step);
- }
- // actually launch the game
- {
- auto step = std::make_shared<LaunchMinecraft>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- // run post-exit command if that's needed
- if(getPostExitCommand().size())
- {
- auto step = std::make_shared<PostLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- if (session)
- {
- process->setCensorFilter(createCensorFilterFromSession(session));
- }
- return process;
-}
-
-std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
-{
- class JarModTask : public Task
- {
- public:
- explicit JarModTask(std::shared_ptr<OneSixInstance> inst) : Task(nullptr), m_inst(inst)
- {
- }
- virtual void executeTask()
- {
- auto profile = m_inst->getMinecraftProfile();
- // nuke obsolete stripped jar(s) if needed
- QString version_id = profile->getMinecraftVersion();
- QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
- QFile strippedJar(strippedPath);
- if(strippedJar.exists())
- {
- strippedJar.remove();
- }
- auto tempJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
- QFile tempJar(tempJarPath);
- if(tempJar.exists())
- {
- tempJar.remove();
- }
- auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("minecraft.jar");
- QFile finalJar(finalJarPath);
- if(finalJar.exists())
- {
- if(!finalJar.remove())
- {
- emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
- return;
- }
- }
-
- // create temporary modded jar, if needed
- auto jarMods = m_inst->getJarMods();
- if(jarMods.size())
- {
- auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version_id + "/" + version_id + ".jar");
- QString localPath = version_id + "/" + version_id + ".jar";
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- QString fullJarPath = entry->getFullPath();
- if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- }
- emitSucceeded();
- }
- std::shared_ptr<OneSixInstance> m_inst;
- };
- return std::make_shared<JarModTask>(std::dynamic_pointer_cast<OneSixInstance>(shared_from_this()));
-}
-
-void OneSixInstance::cleanupAfterRun()
-{
- QString target_dir = FS::PathCombine(instanceRoot(), "natives/");
- QDir dir(target_dir);
- dir.removeRecursively();
-}
-
-std::shared_ptr<ModList> OneSixInstance::loaderModList() const
-{
- if (!m_loader_mod_list)
- {
- m_loader_mod_list.reset(new ModList(loaderModsDir()));
- }
- m_loader_mod_list->update();
- return m_loader_mod_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::coreModList() const
-{
- if (!m_core_mod_list)
- {
- m_core_mod_list.reset(new ModList(coreModsDir()));
- }
- m_core_mod_list->update();
- return m_core_mod_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::resourcePackList() const
-{
- if (!m_resource_pack_list)
- {
- m_resource_pack_list.reset(new ModList(resourcePacksDir()));
- }
- m_resource_pack_list->update();
- return m_resource_pack_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::texturePackList() const
-{
- if (!m_texture_pack_list)
- {
- m_texture_pack_list.reset(new ModList(texturePacksDir()));
- }
- m_texture_pack_list->update();
- return m_texture_pack_list;
-}
-
-std::shared_ptr<WorldList> OneSixInstance::worldList() const
-{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(worldDir()));
- }
- return m_world_list;
-}
-
-bool OneSixInstance::setIntendedVersionId(QString version)
-{
- settings()->set("IntendedVersion", version);
- if(getMinecraftProfile())
- {
- clearProfile();
- }
- emit propertiesChanged(this);
- return true;
-}
-
-QList< Mod > OneSixInstance::getJarMods() const
-{
- QList<Mod> mods;
- for (auto jarmod : m_profile->getJarMods())
- {
- QString filePath = jarmodsPath().absoluteFilePath(jarmod->name);
- mods.push_back(Mod(QFileInfo(filePath)));
- }
- return mods;
-}
-
-
-QString OneSixInstance::intendedVersionId() const
-{
- return settings()->get("IntendedVersion").toString();
-}
-
-void OneSixInstance::setShouldUpdate(bool)
-{
-}
-
-bool OneSixInstance::shouldUpdate() const
-{
- return true;
-}
-
-QString OneSixInstance::currentVersionId() const
-{
- return intendedVersionId();
-}
-
-void OneSixInstance::reloadProfile()
-{
- m_profile->reload();
- auto severity = m_profile->getProblemSeverity();
- if(severity == ProblemSeverity::PROBLEM_ERROR)
- {
- setFlag(VersionBrokenFlag);
- }
- else
- {
- unsetFlag(VersionBrokenFlag);
- }
- emit versionReloaded();
-}
-
-void OneSixInstance::clearProfile()
-{
- m_profile->clear();
- emit versionReloaded();
-}
-
-std::shared_ptr<MinecraftProfile> OneSixInstance::getMinecraftProfile() const
-{
- return m_profile;
-}
-
-QDir OneSixInstance::librariesPath() const
-{
- return QDir::current().absoluteFilePath("libraries");
-}
-
-QDir OneSixInstance::jarmodsPath() const
-{
- return QDir(jarModsDir());
-}
-
-QDir OneSixInstance::versionsPath() const
-{
- return QDir::current().absoluteFilePath("versions");
-}
-
-bool OneSixInstance::providesVersionFile() const
-{
- return false;
-}
-
-bool OneSixInstance::reload()
-{
- if (BaseInstance::reload())
- {
- try
- {
- reloadProfile();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- return false;
-}
-
-QString OneSixInstance::loaderModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "mods");
-}
-
-QString OneSixInstance::coreModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "coremods");
-}
-
-QString OneSixInstance::resourcePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "resourcepacks");
-}
-
-QString OneSixInstance::texturePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
-}
-
-QString OneSixInstance::instanceConfigFolder() const
-{
- return FS::PathCombine(minecraftRoot(), "config");
-}
-
-QString OneSixInstance::jarModsDir() const
-{
- return FS::PathCombine(instanceRoot(), "jarmods");
-}
-
-QString OneSixInstance::libDir() const
-{
- return FS::PathCombine(minecraftRoot(), "lib");
-}
-
-QString OneSixInstance::worldDir() const
-{
- return FS::PathCombine(minecraftRoot(), "saves");
-}
-
-QStringList OneSixInstance::extraArguments() const
-{
- auto list = BaseInstance::extraArguments();
- auto version = getMinecraftProfile();
- if (!version)
- return list;
- auto jarMods = getJarMods();
- if (!jarMods.isEmpty())
- {
- list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
- "-Dfml.ignorePatchDiscrepancies=true"});
- }
- return list;
-}
-
-std::shared_ptr<OneSixInstance> OneSixInstance::getSharedPtr()
-{
- return std::dynamic_pointer_cast<OneSixInstance>(BaseInstance::getSharedPtr());
-}
-
-QString OneSixInstance::typeName() const
-{
- return tr("OneSix");
-}
diff --git a/libraries/logic/minecraft/onesix/OneSixInstance.h b/libraries/logic/minecraft/onesix/OneSixInstance.h
deleted file mode 100644
index 2dfab48c..00000000
--- a/libraries/logic/minecraft/onesix/OneSixInstance.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright 2013-2015 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/MinecraftInstance.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/ModList.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT OneSixInstance : public MinecraftInstance
-{
- Q_OBJECT
-public:
- explicit OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~OneSixInstance(){};
-
- virtual void init() override;
-
- ////// Mod Lists //////
- std::shared_ptr<ModList> loaderModList() const;
- std::shared_ptr<ModList> coreModList() const;
- std::shared_ptr<ModList> resourcePackList() const override;
- std::shared_ptr<ModList> texturePackList() const override;
- std::shared_ptr<WorldList> worldList() const override;
- virtual QList<Mod> getJarMods() const override;
- virtual void createProfile();
-
- virtual QSet<QString> traits() override;
-
- ////// Directories and files //////
- QString jarModsDir() const;
- QString resourcePacksDir() const;
- QString texturePacksDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
- QString libDir() const;
- QString worldDir() const;
- virtual QString instanceConfigFolder() const override;
-
- virtual std::shared_ptr<Task> createUpdateTask() override;
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
- virtual std::shared_ptr<Task> createJarModdingTask() override;
-
- virtual QString createLaunchScript(AuthSessionPtr session) override;
-
- virtual void cleanupAfterRun() override;
-
- virtual QString intendedVersionId() const override;
- virtual bool setIntendedVersionId(QString version) override;
-
- virtual QString currentVersionId() const override;
-
- virtual bool shouldUpdate() const override;
- virtual void setShouldUpdate(bool val) override;
-
- /**
- * reload the profile, including version json files.
- *
- * throws various exceptions :3
- */
- void reloadProfile();
-
- /// clears all version information in preparation for an update
- void clearProfile();
-
- /// get the current full version info
- std::shared_ptr<MinecraftProfile> getMinecraftProfile() const;
-
- virtual QDir jarmodsPath() const;
- virtual QDir librariesPath() const;
- virtual QDir versionsPath() const;
- virtual bool providesVersionFile() const;
-
- bool reload() override;
-
- virtual QStringList extraArguments() const override;
-
- std::shared_ptr<OneSixInstance> getSharedPtr();
-
- virtual QString typeName() const override;
-
- bool canExport() const override
- {
- return true;
- }
-
-signals:
- void versionReloaded();
-
-private:
- QStringList processMinecraftArgs(AuthSessionPtr account);
-
-protected:
- std::shared_ptr<MinecraftProfile> m_profile;
- mutable std::shared_ptr<ModList> m_loader_mod_list;
- mutable std::shared_ptr<ModList> m_core_mod_list;
- mutable std::shared_ptr<ModList> m_resource_pack_list;
- mutable std::shared_ptr<ModList> m_texture_pack_list;
- mutable std::shared_ptr<WorldList> m_world_list;
-};
-
-Q_DECLARE_METATYPE(std::shared_ptr<OneSixInstance>)
diff --git a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp
deleted file mode 100644
index af42286d..00000000
--- a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-#include "OneSixProfileStrategy.h"
-#include "OneSixInstance.h"
-#include "OneSixVersionFormat.h"
-
-#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "Env.h"
-#include <FileSystem.h>
-
-#include <QDir>
-#include <QUuid>
-#include <QJsonDocument>
-#include <QJsonArray>
-
-OneSixProfileStrategy::OneSixProfileStrategy(OneSixInstance* instance)
-{
- m_instance = instance;
-}
-
-void OneSixProfileStrategy::upgradeDeprecatedFiles()
-{
- auto versionJsonPath = FS::PathCombine(m_instance->instanceRoot(), "version.json");
- auto customJsonPath = FS::PathCombine(m_instance->instanceRoot(), "custom.json");
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
-
- QString sourceFile;
- QString renameFile;
-
- // convert old crap.
- if(QFile::exists(customJsonPath))
- {
- sourceFile = customJsonPath;
- renameFile = versionJsonPath;
- }
- else if(QFile::exists(versionJsonPath))
- {
- sourceFile = versionJsonPath;
- }
- if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
- {
- if(!FS::ensureFilePathExists(mcJson))
- {
- qWarning() << "Couldn't create patches folder for" << m_instance->name();
- return;
- }
- if(!renameFile.isEmpty() && QFile::exists(renameFile))
- {
- if(!QFile::rename(renameFile, renameFile + ".old"))
- {
- qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
- auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
- ProfileUtils::removeLwjglFromPatch(file);
- file->fileId = "net.minecraft";
- file->version = file->minecraftVersion;
- file->name = "Minecraft";
- auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson();
- QSaveFile newPatchFile(mcJson);
- if(!newPatchFile.open(QIODevice::WriteOnly))
- {
- newPatchFile.cancelWriting();
- qWarning() << "Couldn't open main patch for writing in" << m_instance->name();
- return;
- }
- newPatchFile.write(data);
- if(!newPatchFile.commit())
- {
- qWarning() << "Couldn't save main patch in" << m_instance->name();
- return;
- }
- if(!QFile::rename(sourceFile, sourceFile + ".old"))
- {
- qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
-}
-
-void OneSixProfileStrategy::loadDefaultBuiltinPatches()
-{
- {
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
- // load up the base minecraft patch
- ProfilePatchPtr minecraftPatch;
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
- if(file->version.isEmpty())
- {
- file->version = m_instance->intendedVersionId();
- }
- file->setVanilla(false);
- file->setRevertible(true);
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- auto mcversion = ENV.getVersion("net.minecraft", m_instance->intendedVersionId());
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(mcversion);
- }
- if (!minecraftPatch)
- {
- throw VersionIncomplete("net.minecraft");
- }
- minecraftPatch->setOrder(-2);
- profile->appendPatch(minecraftPatch);
- }
-
- {
- 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
- {
- // 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);
- }
- if (!lwjglPatch)
- {
- throw VersionIncomplete("org.lwjgl");
- }
- lwjglPatch->setOrder(-1);
- profile->appendPatch(lwjglPatch);
- }
-}
-
-void OneSixProfileStrategy::loadUserPatches()
-{
- // load all patches, put into map for ordering, apply in the right 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)
- {
- // ignore builtins
- if (id == "net.minecraft")
- continue;
- if (id == "org.lwjgl")
- continue;
- // parse the file
- QString filename = patches.absoluteFilePath(id + ".json");
- QFileInfo finfo(filename);
- if(!finfo.exists())
- {
- qDebug() << "Patch file " << filename << " was deleted by external means...";
- 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);
- profile->appendPatch(file);
- }
- // now load the rest by internal preference.
- QMultiMap<int, VersionFilePtr> files;
- for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files))
- {
- // 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);
- files.insert(file->order, file);
- }
- QSet<int> seen;
- 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)
- {
- 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);
- }
- }
-}
-
-
-void OneSixProfileStrategy::load()
-{
- profile->clearPatches();
-
- upgradeDeprecatedFiles();
- loadDefaultBuiltinPatches();
- loadUserPatches();
-}
-
-bool OneSixProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
-{
- return ProfileUtils::writeOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), order);
-}
-
-bool OneSixProfileStrategy::resetOrder()
-{
- return QDir(m_instance->instanceRoot()).remove("order.json");
-}
-
-bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
-{
- bool ok = true;
- // first, remove the patch file. this ensures it's not used anymore
- auto fileName = patch->getFilename();
- if(fileName.size())
- {
- QFile patchFile(fileName);
- if(patchFile.exists() && !patchFile.remove())
- {
- qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
- return false;
- }
- }
-
-
- auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool
- {
- QString fullpath = FS::PathCombine(m_instance->jarModsDir(), jarMod->name);
- QFileInfo finfo (fullpath);
- if(finfo.exists())
- {
- QFile jarModFile(fullpath);
- if(!jarModFile.remove())
- {
- qCritical() << "File" << fullpath << "could not be removed because:" << jarModFile.errorString();
- return false;
- }
- return true;
- }
- return true;
- };
-
- for(auto &jarmod: patch->getJarMods())
- {
- ok &= preRemoveJarMod(jarmod);
- }
- return ok;
-}
-
-bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch)
-{
- if(patch->isCustom())
- {
- return false;
- }
-
- auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getID() + ".json");
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- try
- {
- QSaveFile jsonFile(filename);
- if(!jsonFile.open(QIODevice::WriteOnly))
- {
- return false;
- }
- auto vfile = patch->getVersionFile();
- if(!vfile)
- {
- return false;
- }
- auto document = OneSixVersionFormat::versionFileToJson(vfile, true);
- jsonFile.write(document.toJson());
- if(!jsonFile.commit())
- {
- return false;
- }
- load();
- }
- catch (VersionIncomplete &error)
- {
- qDebug() << "Version was incomplete:" << error.cause();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return true;
-}
-
-bool OneSixProfileStrategy::revertPatch(ProfilePatchPtr patch)
-{
- if(!patch->isCustom())
- {
- // already not custom
- return true;
- }
- auto filename = patch->getFilename();
- if(!QFile::exists(filename))
- {
- // already gone / not custom
- return true;
- }
- // just kill the file and reload
- bool result = QFile::remove(filename);
- try
- {
- load();
- }
- catch (VersionIncomplete &error)
- {
- qDebug() << "Version was incomplete:" << error.cause();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return result;
-}
-
-bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
-{
- QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- if (!FS::ensureFolderPathExists(m_instance->jarModsDir()))
- {
- return false;
- }
-
- for(auto filepath:filepaths)
- {
- QFileInfo sourceInfo(filepath);
- auto uuid = QUuid::createUuid();
- QString id = uuid.toString().remove('{').remove('}');
- QString target_filename = id + ".jar";
- QString target_id = "org.multimc.jarmod." + id;
- QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
- QString finalPath = FS::PathCombine(m_instance->jarModsDir(), target_filename);
-
- QFileInfo targetInfo(finalPath);
- if(targetInfo.exists())
- {
- return false;
- }
-
- if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Jarmod>();
- jarMod->name = target_filename;
- jarMod->originalName = sourceInfo.completeBaseName();
- f->jarMods.append(jarMod);
- f->name = target_name;
- f->fileId = 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))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
- file.close();
- profile->appendPatch(f);
- }
- profile->saveCurrentOrder();
- profile->reapplyPatches();
- return true;
-}
-
diff --git a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h b/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h
deleted file mode 100644
index 96c1ba7b..00000000
--- a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-#include "minecraft/ProfileStrategy.h"
-
-class OneSixInstance;
-
-class OneSixProfileStrategy : public ProfileStrategy
-{
-public:
- OneSixProfileStrategy(OneSixInstance * instance);
- virtual ~OneSixProfileStrategy() {};
- virtual void load() override;
- virtual bool resetOrder() override;
- virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
- virtual bool installJarMods(QStringList filepaths) override;
- virtual bool removePatch(ProfilePatchPtr patch) override;
- virtual bool customizePatch(ProfilePatchPtr patch) override;
- virtual bool revertPatch(ProfilePatchPtr patch) override;
-
-protected:
- virtual void loadDefaultBuiltinPatches();
- virtual void loadUserPatches();
- void upgradeDeprecatedFiles();
-
-protected:
- OneSixInstance *m_instance;
-};
diff --git a/libraries/logic/minecraft/onesix/OneSixUpdate.cpp b/libraries/logic/minecraft/onesix/OneSixUpdate.cpp
deleted file mode 100644
index 1c2cd196..00000000
--- a/libraries/logic/minecraft/onesix/OneSixUpdate.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include <minecraft/forge/ForgeXzDownload.h>
-#include "OneSixUpdate.h"
-#include "OneSixInstance.h"
-
-#include <QtNetwork>
-
-#include <QFile>
-#include <QFileInfo>
-#include <QTextStream>
-#include <QDataStream>
-#include <JlCompress.h>
-
-#include "BaseInstance.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/Library.h"
-#include "net/URLConstants.h"
-#include "minecraft/AssetsUtils.h"
-#include "Exception.h"
-#include "MMCZip.h"
-#include <FileSystem.h>
-
-OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
-{
-}
-
-void OneSixUpdate::executeTask()
-{
- // Make directories
- QDir mcDir(m_inst->minecraftRoot());
- if (!mcDir.exists() && !mcDir.mkpath("."))
- {
- emitFailed(tr("Failed to create folder for minecraft binaries."));
- return;
- }
-
- // Get a pointer to the version object that corresponds to the instance's version.
- targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", m_inst->intendedVersionId()));
- if (targetVersion == nullptr)
- {
- // don't do anything if it was invalid
- emitFailed(tr("The specified Minecraft version is invalid. Choose a different one."));
- return;
- }
- if (m_inst->providesVersionFile() || !targetVersion->needsUpdate())
- {
- qDebug() << "Instance either provides a version file or doesn't need an update.";
- jarlibStart();
- return;
- }
- versionUpdateTask = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft"))->createUpdateTask(m_inst->intendedVersionId());
- if (!versionUpdateTask)
- {
- qDebug() << "Didn't spawn an update task.";
- jarlibStart();
- return;
- }
- connect(versionUpdateTask.get(), SIGNAL(succeeded()), SLOT(jarlibStart()));
- connect(versionUpdateTask.get(), &NetJob::failed, this, &OneSixUpdate::versionUpdateFailed);
- connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- setStatus(tr("Getting the version files from Mojang..."));
- versionUpdateTask->start();
-}
-
-void OneSixUpdate::versionUpdateFailed(QString reason)
-{
- emitFailed(reason);
-}
-
-void OneSixUpdate::assetIndexStart()
-{
- setStatus(tr("Updating assets index..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto profile = inst->getMinecraftProfile();
- auto assets = profile->getMinecraftAssets();
- QUrl indexUrl = assets->url;
- QString localPath = assets->id + ".json";
- auto job = new NetJob(tr("Asset index for %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", localPath);
- entry->setStale(true);
- job->addNetAction(CacheDownload::make(indexUrl, entry));
- jarlibDownloadJob.reset(job);
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetIndexFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
-
- qDebug() << m_inst->name() << ": Starting asset index download";
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::assetIndexFinished()
-{
- AssetsIndex index;
- qDebug() << m_inst->name() << ": Finished asset index download";
-
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto profile = inst->getMinecraftProfile();
- auto assets = profile->getMinecraftAssets();
-
- QString asset_fname = "assets/indexes/" + assets->id + ".json";
- // FIXME: this looks like a job for a generic validator based on json schema?
- if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index))
- {
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json");
- metacache->evictEntry(entry);
- emitFailed(tr("Failed to read the assets index!"));
- }
-
- auto job = index.getDownloadJob();
- if(job)
- {
- setStatus(tr("Getting the assets files from Mojang..."));
- jarlibDownloadJob = job;
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetsFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- jarlibDownloadJob->start();
- return;
- }
- assetsFinished();
-}
-
-void OneSixUpdate::assetIndexFailed(QString reason)
-{
- qDebug() << m_inst->name() << ": Failed asset index download";
- emitFailed(tr("Failed to download the assets index:\n%1").arg(reason));
-}
-
-void OneSixUpdate::assetsFinished()
-{
- emitSucceeded();
-}
-
-void OneSixUpdate::assetsFailed(QString reason)
-{
- emitFailed(tr("Failed to download assets:\n%1").arg(reason));
-}
-
-void OneSixUpdate::jarlibStart()
-{
- setStatus(tr("Getting the library files from Mojang..."));
- qDebug() << m_inst->name() << ": downloading libraries";
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- inst->reloadProfile();
- if(inst->flags() & BaseInstance::VersionBrokenFlag)
- {
- emitFailed(tr("Failed to load the version description files - check the instance for errors."));
- return;
- }
-
- // Build a list of URLs that will need to be downloaded.
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
- // minecraft.jar for this version
- {
- QString version_id = profile->getMinecraftVersion();
- QString localPath = version_id + "/" + version_id + ".jar";
- QString urlstr = profile->getMainJarUrl();
-
- auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
- jarlibDownloadJob.reset(job);
- }
-
- auto libs = profile->getLibraries();
-
- auto metacache = ENV.metacache();
- QList<LibraryPtr> brokenLocalLibs;
-
- QStringList failedFiles;
- for (auto lib : libs)
- {
- auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles);
- for(auto dl : dls)
- {
- jarlibDownloadJob->addNetAction(dl);
- }
- }
- if (!brokenLocalLibs.empty())
- {
- jarlibDownloadJob.reset();
-
- QString failed_all = failedFiles.join("\n");
- emitFailed(tr("Some libraries marked as 'local' are missing their jar "
- "files:\n%1\n\nYou'll have to correct this problem manually. If this is "
- "an externally tracked instance, make sure to run it at least once "
- "outside of MultiMC.").arg(failed_all));
- return;
- }
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::jarlibFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
-
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::jarlibFinished()
-{
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
-
- if (profile->hasTrait("legacyFML"))
- {
- fmllibsStart();
- }
- else
- {
- assetIndexStart();
- }
-}
-
-void OneSixUpdate::jarlibFailed(QString reason)
-{
- QStringList failed = jarlibDownloadJob->getFailedFiles();
- QString failed_all = failed.join("\n");
- emitFailed(
- tr("Failed to download the following files:\n%1\n\nReason:%2\nPlease try again.").arg(failed_all, reason));
-}
-
-void OneSixUpdate::fmllibsStart()
-{
- // Get the mod list
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
- bool forge_present = false;
-
- QString version = inst->intendedVersionId();
- auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- assetIndexStart();
- return;
- }
-
- auto &libList = fmlLibsMapping[version];
-
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- forge_present = (profile->versionPatch("net.minecraftforge") != nullptr);
- // we don't...
- if (!forge_present)
- {
- assetIndexStart();
- return;
- }
-
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
-
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- assetIndexStart();
- return;
- }
-
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
- }
-
- connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished()));
- connect(dljob, &NetJob::failed, this, &OneSixUpdate::fmllibsFailed);
- connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void OneSixUpdate::fmllibsFinished()
-{
- legacyDownloadJob.reset();
- if (!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = FS::PathCombine(inst->libDir(), lib.filename);
- if (!FS::ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- assetIndexStart();
-}
-
-void OneSixUpdate::fmllibsFailed(QString reason)
-{
- emitFailed(tr("Game update failed: it was impossible to fetch the required FML libraries.\nReason:\n%1").arg(reason));
- return;
-}
-
diff --git a/libraries/logic/minecraft/onesix/OneSixUpdate.h b/libraries/logic/minecraft/onesix/OneSixUpdate.h
deleted file mode 100644
index b5195364..00000000
--- a/libraries/logic/minecraft/onesix/OneSixUpdate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright 2013-2015 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 <QUrl>
-
-#include "net/NetJob.h"
-#include "tasks/Task.h"
-#include "minecraft/VersionFilterData.h"
-#include <quazip.h>
-
-class MinecraftVersion;
-class OneSixInstance;
-
-class OneSixUpdate : public Task
-{
- Q_OBJECT
-public:
- explicit OneSixUpdate(OneSixInstance *inst, QObject *parent = 0);
- virtual void executeTask();
-
-private
-slots:
- void versionUpdateFailed(QString reason);
-
- void jarlibStart();
- void jarlibFinished();
- void jarlibFailed(QString reason);
-
- void fmllibsStart();
- void fmllibsFinished();
- void fmllibsFailed(QString reason);
-
- void assetIndexStart();
- void assetIndexFinished();
- void assetIndexFailed(QString reason);
-
- void assetsFinished();
- void assetsFailed(QString reason);
-
-private:
- NetJobPtr jarlibDownloadJob;
- NetJobPtr legacyDownloadJob;
-
- /// target version, determined during this task
- std::shared_ptr<MinecraftVersion> targetVersion;
- /// the task that is spawned for version updates
- std::shared_ptr<Task> versionUpdateTask;
-
- OneSixInstance *m_inst = nullptr;
- QList<FMLlib> fmlLibsToProcess;
-};
diff --git a/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp b/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp
deleted file mode 100644
index 541fb109..00000000
--- a/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "OneSixVersionFormat.h"
-#include <Json.h>
-#include "minecraft/ParseUtils.h"
-#include <minecraft/MinecraftVersion.h>
-#include <minecraft/VersionBuildError.h>
-#include <minecraft/MojangVersionFormat.h>
-
-using namespace Json;
-
-static void readString(const QJsonObject &root, const QString &key, QString &variable)
-{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
-}
-
-LibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
-{
- LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename);
- readString(libObj, "MMC-hint", out->m_hint);
- readString(libObj, "MMC-absulute_url", out->m_absoluteURL);
- readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL);
- return out;
-}
-
-QJsonObject OneSixVersionFormat::libraryToJson(Library *library)
-{
- QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
- if (library->m_absoluteURL.size())
- libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
- if (library->m_hint.size())
- libRoot.insert("MMC-hint", library->m_hint);
- return libRoot;
-}
-
-VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder)
-{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
-
- QJsonObject root = doc.object();
-
- if (requireOrder)
- {
- if (root.contains("order"))
- {
- out->order = requireInteger(root.value("order"));
- }
- else
- {
- // FIXME: evaluate if we don't want to throw exceptions here instead
- qCritical() << filename << "doesn't contain an order field";
- }
- }
-
- out->name = root.value("name").toString();
- out->fileId = root.value("fileId").toString();
- out->version = root.value("version").toString();
- out->dependsOnMinecraftVersion = root.value("mcVersion").toString();
- out->filename = filename;
-
- MojangVersionFormat::readVersionProperties(root, out.get());
-
- // added for legacy Minecraft window embedding, TODO: remove
- readString(root, "appletClass", out->appletClass);
-
- if (root.contains("+tweakers"))
- {
- for (auto tweakerVal : requireArray(root.value("+tweakers")))
- {
- out->addTweakers.append(requireString(tweakerVal));
- }
- }
-
- if (root.contains("+traits"))
- {
- for (auto tweakerVal : requireArray(root.value("+traits")))
- {
- out->traits.insert(requireString(tweakerVal));
- }
- }
-
- if (root.contains("+jarMods"))
- {
- for (auto libVal : requireArray(root.value("+jarMods")))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the jarmod
- auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename, out->name);
- if(lib->originalName.isEmpty())
- {
- auto fixed = out->name;
- fixed.remove(" (jar mod)");
- lib->originalName = out->name;
- }
- // and add to jar mods
- out->jarMods.append(lib);
- }
- }
-
- auto readLibs = [&](const char * which)
- {
- for (auto libVal : requireArray(root.value(which)))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the library
- auto lib = libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- };
- bool hasPlusLibs = root.contains("+libraries");
- 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."));
- readLibs("libraries");
- readLibs("+libraries");
- }
- else if (hasLibs)
- {
- readLibs("libraries");
- }
- else if(hasPlusLibs)
- {
- readLibs("+libraries");
- }
-
- /* removed features that shouldn't be used */
- if (root.contains("tweakers"))
- {
- out->addProblem(PROBLEM_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'"));
- }
- if (root.contains("-tweakers"))
- {
- out->addProblem(PROBLEM_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'"));
- }
- if (root.contains("+minecraftArguments"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
- }
- return out;
-}
-
-QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch, bool saveOrder)
-{
- QJsonObject root;
- if (saveOrder)
- {
- root.insert("order", patch->order);
- }
- writeString(root, "name", patch->name);
- writeString(root, "fileId", patch->fileId);
- writeString(root, "version", patch->version);
- writeString(root, "mcVersion", patch->dependsOnMinecraftVersion);
-
- MojangVersionFormat::writeVersionProperties(patch.get(), root);
-
- writeString(root, "appletClass", patch->appletClass);
- writeStringList(root, "+tweakers", patch->addTweakers);
- writeStringList(root, "+traits", patch->traits.toList());
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(OneSixVersionFormat::libraryToJson(value.get()));
- }
- root.insert("+libraries", array);
- }
- if (!patch->jarMods.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->jarMods)
- {
- array.append(OneSixVersionFormat::jarModtoJson(value.get()));
- }
- root.insert("+jarMods", array);
- }
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
-}
-
-JarmodPtr OneSixVersionFormat::jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName)
-{
- JarmodPtr out(new Jarmod());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename +
- "contains a jarmod that doesn't have a 'name' field");
- }
- out->name = libObj.value("name").toString();
- out->originalName = libObj.value("originalName").toString();
- return out;
-}
-
-QJsonObject OneSixVersionFormat::jarModtoJson(Jarmod *jarmod)
-{
- QJsonObject out;
- writeString(out, "name", jarmod->name);
- if(!jarmod->originalName.isEmpty())
- {
- writeString(out, "originalName", jarmod->originalName);
- }
- return out;
-}
diff --git a/libraries/logic/minecraft/onesix/OneSixVersionFormat.h b/libraries/logic/minecraft/onesix/OneSixVersionFormat.h
deleted file mode 100644
index 5696e79e..00000000
--- a/libraries/logic/minecraft/onesix/OneSixVersionFormat.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <minecraft/VersionFile.h>
-#include <minecraft/MinecraftProfile.h>
-#include <minecraft/Library.h>
-#include <QJsonDocument>
-
-class OneSixVersionFormat
-{
-public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch, bool saveOrder);
-
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
-
- // jar mods
- static JarmodPtr jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName);
- static QJsonObject jarModtoJson(Jarmod * jarmod);
-};