From 02c1df2c3c260fe625b9c3314e9eed2885a97456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 13 Mar 2016 00:23:45 +0100 Subject: NOISSUE continue version file format refactors --- logic/CMakeLists.txt | 1 - logic/minecraft/Library.h | 2 +- logic/minecraft/MinecraftProfile.cpp | 228 ++++++++++++++++++----- logic/minecraft/MinecraftProfile.h | 66 ++++--- logic/minecraft/MinecraftVersion.cpp | 67 ++----- logic/minecraft/MinecraftVersion.h | 20 +- logic/minecraft/MinecraftVersionList.cpp | 3 +- logic/minecraft/MojangVersionFormat.cpp | 9 +- logic/minecraft/ProfilePatch.h | 20 +- logic/minecraft/ProfileUtils.cpp | 1 - logic/minecraft/VersionFile.cpp | 126 ++----------- logic/minecraft/VersionFile.h | 39 ++-- logic/minecraft/VersionSource.h | 9 - logic/minecraft/forge/ForgeInstaller.cpp | 38 +--- logic/minecraft/ftb/FTBProfileStrategy.cpp | 5 - logic/minecraft/onesix/OneSixInstance.cpp | 44 ++--- logic/minecraft/onesix/OneSixProfileStrategy.cpp | 8 +- logic/minecraft/onesix/OneSixUpdate.cpp | 11 +- logic/minecraft/onesix/OneSixVersionFormat.cpp | 97 +++++----- 19 files changed, 401 insertions(+), 393 deletions(-) delete mode 100644 logic/minecraft/VersionSource.h (limited to 'logic') diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index 28c1b8fc..b8c36794 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -202,7 +202,6 @@ set(LOGIC_SOURCES minecraft/VersionFile.cpp minecraft/VersionFile.h minecraft/ProfilePatch.h - minecraft/VersionSource.h minecraft/VersionFilterData.h minecraft/VersionFilterData.cpp minecraft/Mod.h diff --git a/logic/minecraft/Library.h b/logic/minecraft/Library.h index 891601be..35b5cb99 100644 --- a/logic/minecraft/Library.h +++ b/logic/minecraft/Library.h @@ -13,7 +13,7 @@ #include "GradleSpecifier.h" #include "net/URLConstants.h" -class MojangLibraryDownloadInfo; +struct MojangLibraryDownloadInfo; class Library; typedef std::shared_ptr LibraryPtr; diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index 0cf8b548..7586c156 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -60,11 +61,8 @@ void MinecraftProfile::reload() void MinecraftProfile::clear() { id.clear(); - m_updateTime = QDateTime(); - m_releaseTime = QDateTime(); type.clear(); assets.clear(); - processArguments.clear(); minecraftArguments.clear(); mainClass.clear(); appletClass.clear(); @@ -94,13 +92,13 @@ bool MinecraftProfile::remove(const int index) auto patch = versionPatch(index); if (!patch->isRemovable()) { - qDebug() << "Patch" << patch->getPatchID() << "is non-removable"; + qDebug() << "Patch" << patch->getID() << "is non-removable"; return false; } if(!m_strategy->removePatch(patch)) { - qCritical() << "Patch" << patch->getPatchID() << "could not be removed"; + qCritical() << "Patch" << patch->getID() << "could not be removed"; return false; } @@ -117,7 +115,7 @@ bool MinecraftProfile::remove(const QString id) int i = 0; for (auto patch : VersionPatches) { - if (patch->getPatchID() == id) + if (patch->getID() == id) { return remove(i); } @@ -131,12 +129,12 @@ bool MinecraftProfile::customize(int index) auto patch = versionPatch(index); if (!patch->isCustomizable()) { - qDebug() << "Patch" << patch->getPatchID() << "is not customizable"; + qDebug() << "Patch" << patch->getID() << "is not customizable"; return false; } if(!m_strategy->customizePatch(patch)) { - qCritical() << "Patch" << patch->getPatchID() << "could not be customized"; + qCritical() << "Patch" << patch->getID() << "could not be customized"; return false; } reapplySafe(); @@ -151,12 +149,12 @@ bool MinecraftProfile::revertToBase(int index) auto patch = versionPatch(index); if (!patch->isRevertible()) { - qDebug() << "Patch" << patch->getPatchID() << "is not revertible"; + qDebug() << "Patch" << patch->getID() << "is not revertible"; return false; } if(!m_strategy->revertPatch(patch)) { - qCritical() << "Patch" << patch->getPatchID() << "could not be reverted"; + qCritical() << "Patch" << patch->getID() << "could not be reverted"; return false; } reapplySafe(); @@ -172,14 +170,14 @@ QString MinecraftProfile::versionFileId(const int index) const { return QString(); } - return VersionPatches.at(index)->getPatchID(); + return VersionPatches.at(index)->getID(); } ProfilePatchPtr MinecraftProfile::versionPatch(const QString &id) { for (auto file : VersionPatches) { - if (file->getPatchID() == id) + if (file->getID() == id) { return file; } @@ -216,9 +214,9 @@ bool MinecraftProfile::revertToVanilla() } if(it->isRevertible() || it->isRemovable()) { - if(!remove(it->getPatchID())) + if(!remove(it->getID())) { - qWarning() << "Couldn't remove" << it->getPatchID() << "from profile!"; + qWarning() << "Couldn't remove" << it->getID() << "from profile!"; reapplySafe(); saveCurrentOrder(); return false; @@ -230,7 +228,7 @@ bool MinecraftProfile::revertToVanilla() return true; } -QList > MinecraftProfile::getActiveNormalLibs() +QList > MinecraftProfile::getActiveNormalLibs() const { QList > output; for (auto lib : libraries) @@ -251,7 +249,7 @@ QList > MinecraftProfile::getActiveNormalLibs() return output; } -QList > MinecraftProfile::getActiveNativeLibs() +QList > MinecraftProfile::getActiveNativeLibs() const { QList > output; for (auto lib : libraries) @@ -282,16 +280,16 @@ QVariant MinecraftProfile::data(const QModelIndex &index, int role) const switch (column) { case 0: - return VersionPatches.at(row)->getPatchName(); + return VersionPatches.at(row)->getName(); case 1: { if(patch->isCustom()) { - return QString("%1 (Custom)").arg(patch->getPatchVersion()); + return QString("%1 (Custom)").arg(patch->getVersion()); } else { - return patch->getPatchVersion(); + return patch->getVersion(); } } default: @@ -366,7 +364,7 @@ void MinecraftProfile::saveCurrentOrder() const { if(!item->isMoveable()) continue; - order.append(item->getPatchID()); + order.append(item->getID()); } m_strategy->saveOrder(order); } @@ -419,7 +417,6 @@ void MinecraftProfile::reapply() { file->applyTo(this); } - finalize(); } bool MinecraftProfile::reapplySafe() @@ -437,41 +434,186 @@ bool MinecraftProfile::reapplySafe() return true; } -void MinecraftProfile::finalize() +static void applyString(const QString & from, QString & to) { - // HACK: deny april fools. my head hurts enough already. - QDate now = QDate::currentDate(); - bool isAprilFools = now.month() == 4 && now.day() == 1; - if (assets.endsWith("_af") && !isAprilFools) + if(from.isEmpty()) + return; + to = from; +} + +void MinecraftProfile::applyMinecraftVersion(const QString& id) +{ + applyString(id, this->id); +} + +void MinecraftProfile::applyAppletClass(const QString& appletClass) +{ + applyString(appletClass, this->appletClass); +} + +void MinecraftProfile::applyMainClass(const QString& mainClass) +{ + applyString(mainClass, this->mainClass); +} + +void MinecraftProfile::applyMinecraftArguments(const QString& minecraftArguments, bool isMinecraft) +{ + applyString(minecraftArguments, this->minecraftArguments); + if(isMinecraft) { - assets = assets.left(assets.length() - 3); + applyString(minecraftArguments, this->vanillaMinecraftArguments); } - if (assets.isEmpty()) +} + +void MinecraftProfile::applyMinecraftVersionType(const QString& type) +{ + applyString(type, this->type); +} + +void MinecraftProfile::applyMinecraftAssets(const QString& assets) +{ + applyString(assets, this->assets); +} + +void MinecraftProfile::applyTraits(const QSet& traits) +{ + this->traits.unite(traits); +} + +void MinecraftProfile::applyTweakers(const QStringList& tweakers) +{ + // FIXME: check for dupes? + // FIXME: does order matter? + for (auto tweaker : tweakers) { - assets = "legacy"; + this->tweakers += tweaker; } - auto finalizeArguments = [&]( QString & minecraftArguments, const QString & processArguments ) -> void +} + +void MinecraftProfile::applyJarMods(const QList& jarMods) +{ + this->jarMods.append(jarMods); +} + +static int findLibraryByName(QList haystack, const GradleSpecifier &needle) +{ + int retval = -1; + for (int i = 0; i < haystack.size(); ++i) { - if (!minecraftArguments.isEmpty()) - return; - QString toCompare = processArguments.toLower(); - if (toCompare == "legacy") + if (haystack.at(i)->rawName().matchName(needle)) { - minecraftArguments = " ${auth_player_name} ${auth_session}"; + // only one is allowed. + if (retval != -1) + return -1; + retval = i; } - else if (toCompare == "username_session") + } + return retval; +} + +void MinecraftProfile::applyLibrary(LibraryPtr library, bool isMinecraft) +{ + auto insert = [&](QList & into) + { + // find the library by name. + const int index = findLibraryByName(into, library->rawName()); + // library not found? just add it. + if (index < 0) { - minecraftArguments = "--username ${auth_player_name} --session ${auth_session}"; + into.append(Library::limitedCopy(library)); + return; } - else if (toCompare == "username_session_version") + auto existingLibrary = into.at(index); + // if we are higher it means we should update + if (Version(library->version()) > Version(existingLibrary->version())) { - minecraftArguments = "--username ${auth_player_name} " - "--session ${auth_session} " - "--version ${profile_name}"; + auto libraryCopy = Library::limitedCopy(library); + into.replace(index, libraryCopy); } }; - finalizeArguments(vanillaMinecraftArguments, vanillaProcessArguments); - finalizeArguments(minecraftArguments, processArguments); + insert(libraries); + if(isMinecraft) + { + insert(vanillaLibraries); + } +} + + +QString MinecraftProfile::getMinecraftVersion() const +{ + return id; +} + +QString MinecraftProfile::getAppletClass() const +{ + return appletClass; +} + +QString MinecraftProfile::getMainClass() const +{ + return mainClass; +} + +const QSet &MinecraftProfile::getTraits() const +{ + return traits; +} + +const QStringList & MinecraftProfile::getTweakers() const +{ + return tweakers; +} + +bool MinecraftProfile::hasTrait(const QString& trait) const +{ + return traits.contains(trait); +} + + +QString MinecraftProfile::getMinecraftVersionType() const +{ + return type; +} + +QString MinecraftProfile::getMinecraftAssets() const +{ + // HACK: deny april fools. my head hurts enough already. + QDate now = QDate::currentDate(); + bool isAprilFools = now.month() == 4 && now.day() == 1; + if (assets.endsWith("_af") && !isAprilFools) + { + return assets.left(assets.length() - 3); + } + if (assets.isEmpty()) + { + return QLatin1Literal("legacy"); + } + return assets; +} + +QString MinecraftProfile::getMinecraftArguments() const +{ + return minecraftArguments; +} + +QString MinecraftProfile::getVanillaMinecraftArguments() const +{ + return vanillaMinecraftArguments; +} + +const QList & MinecraftProfile::getJarMods() const +{ + return jarMods; +} + +const QList & MinecraftProfile::getLibraries() const +{ + return libraries; +} + +const QList & MinecraftProfile::getVanillaLibraries() const +{ + return vanillaLibraries; } void MinecraftProfile::installJarMods(QStringList selectedFiles) diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h index 84d3ce3b..24d13609 100644 --- a/logic/minecraft/MinecraftProfile.h +++ b/logic/minecraft/MinecraftProfile.h @@ -88,16 +88,40 @@ public: /// apply the patches. Catches all the errors and returns true/false for success/failure bool reapplySafe(); - /// do a finalization step (should always be done after applying all patches to profile) - void finalize(); +public: + void applyMinecraftVersion(const QString& id); + void applyMainClass(const QString& mainClass); + void applyAppletClass(const QString& appletClass); + void applyMinecraftArguments(const QString& minecraftArguments, bool isMinecraft); + void applyMinecraftVersionType(const QString& type); + void applyMinecraftAssets(const QString& assets); + void applyTraits(const QSet &traits); + void applyTweakers(const QStringList &tweakers); + void applyJarMods(const QList&jarMods); + void applyLibrary(LibraryPtr library, bool isMinecraft); public: /// get all java libraries that belong to the classpath - QList getActiveNormalLibs(); + QList getActiveNormalLibs() const; /// get all native libraries that need to be available to the process - QList getActiveNativeLibs(); + QList getActiveNativeLibs() const; + + QString getMinecraftVersion() const; + QString getMainClass() const; + QString getAppletClass() const; + QString getMinecraftVersionType() const; + QString getMinecraftAssets() const; + QString getMinecraftArguments() const; + QString getVanillaMinecraftArguments() const; + const QSet & getTraits() const; + const QStringList & getTweakers() const; + const QList & getJarMods() const; + const QList & getLibraries() const; + const QList & getVanillaLibraries() const; + bool hasTrait(const QString & trait) const; +public: /// get file ID of the patch file at # QString versionFileId(const int index) const; @@ -110,34 +134,22 @@ public: /// save the current patch order void saveCurrentOrder() const; -public: /* only use in ProfileStrategy */ /// Remove all the patches void clearPatches(); /// Add the patch object to the internal list of patches void appendPatch(ProfilePatchPtr patch); -public: /* data */ +protected: /* data */ /// the ID - determines which jar to use! ACTUALLY IMPORTANT! QString id; - /// the time this version was actually released by Mojang - QDateTime m_releaseTime; - - /// the time this version was last updated by Mojang - QDateTime m_updateTime; - /// Release type - "release" or "snapshot" QString type; + /// Assets type - "legacy" or a version ID QString assets; - /** - * DEPRECATED: Old versions of the new vanilla launcher used this - * ex: "username_session_version" - */ - QString processArguments; - /// Same as above, but only for vanilla - QString vanillaProcessArguments; + /** * arguments that should be used for launching minecraft * @@ -145,19 +157,17 @@ public: /* data */ * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}" */ QString minecraftArguments; + /// Same as above, but only for vanilla QString vanillaMinecraftArguments; - /** - * A list of all tweaker classes - */ + + /// A list of all tweaker classes QStringList tweakers; - /** - * The main class to load first - */ + + /// The main class to load first QString mainClass; - /** - * The applet class, for some very old minecraft releases - */ + + /// The applet class, for some very old minecraft releases QString appletClass; /// the list of libs - both active and inactive, native and java diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index 8a1ac501..3224de4c 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -43,6 +43,11 @@ QString MinecraftVersion::typeString() const } } +VersionSource MinecraftVersion::getVersionSource() +{ + return m_versionSource; +} + bool MinecraftVersion::hasJarMods() { return false; @@ -64,19 +69,6 @@ void MinecraftVersion::applyFileTo(MinecraftProfile *version) throw VersionIncomplete(QObject::tr("Can't apply incomplete/builtin Minecraft version %1").arg(m_name)); } } -/* -QJsonDocument MinecraftVersion::toJson(bool saveOrder) -{ - if(m_versionSource == Local && getVersionFile()) - { - return getVersionFile()->toJson(saveOrder); - } - else - { - throw VersionIncomplete(QObject::tr("Can't write incomplete/builtin Minecraft version %1").arg(m_name)); - } -} -*/ QString MinecraftVersion::getUrl() const { @@ -171,36 +163,12 @@ void MinecraftVersion::applyTo(MinecraftProfile *version) throw VersionIncomplete(QObject::tr( "Minecraft version %1 could not be applied: version files are missing.").arg(m_descriptor)); } - if (!m_descriptor.isNull()) - { - version->id = m_descriptor; - } - if (!m_mainClass.isNull()) - { - version->mainClass = m_mainClass; - } - if (!m_appletClass.isNull()) - { - version->appletClass = m_appletClass; - } - if (!m_processArguments.isNull()) - { - version->vanillaProcessArguments = m_processArguments; - version->processArguments = m_processArguments; - } - if (!m_type.isNull()) - { - version->type = m_type; - } - if (!m_releaseTime.isNull()) - { - version->m_releaseTime = m_releaseTime; - } - if (!m_updateTime.isNull()) - { - version->m_updateTime = m_updateTime; - } - version->traits.unite(m_traits); + version->applyMinecraftVersion(m_descriptor); + version->applyMainClass(m_mainClass); + version->applyAppletClass(m_appletClass); + version->applyMinecraftArguments(" ${auth_player_name} ${auth_session}", true); // all builtin versions are legacy + version->applyMinecraftVersionType(m_type); + version->applyTraits(m_traits); } int MinecraftVersion::getOrder() @@ -218,22 +186,27 @@ QList MinecraftVersion::getJarMods() return QList(); } -QString MinecraftVersion::getPatchName() +QString MinecraftVersion::getName() { return "Minecraft"; } -QString MinecraftVersion::getPatchVersion() +QString MinecraftVersion::getVersion() { return m_descriptor; } -QString MinecraftVersion::getPatchID() +QString MinecraftVersion::getID() { return "net.minecraft"; } -QString MinecraftVersion::getPatchFilename() +QString MinecraftVersion::getFilename() { return QString(); } +QDateTime MinecraftVersion::getReleaseDateTime() +{ + return m_releaseTime; +} + bool MinecraftVersion::needsUpdate() { diff --git a/logic/minecraft/MinecraftVersion.h b/logic/minecraft/MinecraftVersion.h index 33ca2899..aca9c08d 100644 --- a/logic/minecraft/MinecraftVersion.h +++ b/logic/minecraft/MinecraftVersion.h @@ -22,7 +22,6 @@ #include "BaseVersion.h" #include "ProfilePatch.h" #include "VersionFile.h" -#include "VersionSource.h" #include "multimc_logic_export.h" @@ -32,6 +31,8 @@ typedef std::shared_ptr MinecraftVersionPtr; class MULTIMC_LOGIC_EXPORT MinecraftVersion : public BaseVersion, public ProfilePatch { +friend class MinecraftVersionList; + public: /* methods */ bool usesLegacyLauncher(); virtual QString descriptor() override; @@ -43,10 +44,13 @@ public: /* methods */ virtual int getOrder() override; virtual void setOrder(int order) override; virtual QList getJarMods() override; - virtual QString getPatchID() override; - virtual QString getPatchVersion() override; - virtual QString getPatchName() override; - virtual QString getPatchFilename() 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; @@ -84,7 +88,7 @@ public: /* methods */ private: /* methods */ void applyFileTo(MinecraftProfile *version); -public: /* data */ +protected: /* data */ VersionSource m_versionSource = Builtin; /// The URL that this version will be downloaded from. @@ -105,9 +109,6 @@ public: /* data */ /// The applet class this version uses (if any, can be empty). QString m_appletClass; - /// The process arguments used by this version - QString m_processArguments; - /// The type of this release QString m_type; @@ -126,7 +127,6 @@ public: /* data */ /// an update available from Mojang MinecraftVersionPtr upstreamUpdate; -private: /* data */ QDateTime m_loadedVersionFileTimestamp; mutable VersionFilePtr m_loadedVersionFile; }; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 507d8254..f219c782 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -111,7 +111,7 @@ static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second) { auto left = std::dynamic_pointer_cast(first); auto right = std::dynamic_pointer_cast(second); - return left->m_releaseTime > right->m_releaseTime; + return left->getReleaseDateTime() > right->getReleaseDateTime(); } void MinecraftVersionList::sortInternal() @@ -191,7 +191,6 @@ void MinecraftVersionList::loadBuiltinList() mcVersion->m_appletClass = versionObj.value("appletClass").toString(""); mcVersion->m_mainClass = versionObj.value("mainClass").toString(""); mcVersion->m_jarChecksum = versionObj.value("checksum").toString(""); - mcVersion->m_processArguments = versionObj.value("processArguments").toString("legacy"); if (versionObj.contains("+traits")) { for (auto traitVal : Json::requireArray(versionObj.value("+traits"))) diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp index def388bf..2d4f26c5 100644 --- a/logic/minecraft/MojangVersionFormat.cpp +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -150,7 +150,7 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc Bits::readString(root, "id", out->id); Bits::readString(root, "mainClass", out->mainClass); - Bits::readString(root, "minecraftArguments", out->overwriteMinecraftArguments); + Bits::readString(root, "minecraftArguments", out->minecraftArguments); Bits::readString(root, "type", out->type); if(root.contains("assetIndex")) @@ -203,8 +203,7 @@ QJsonDocument versionFileToJson(VersionFilePtr patch) QJsonObject root; writeString(root, "id", patch->id); writeString(root, "mainClass", patch->mainClass); - writeString(root, "processArguments", patch->processArguments); - writeString(root, "minecraftArguments", patch->overwriteMinecraftArguments); + writeString(root, "minecraftArguments", patch->minecraftArguments); writeString(root, "type", patch->type); writeString(root, "assets", patch->assets); writeString(root, "releaseTime", timeToS3Time(patch->m_releaseTime)); @@ -246,7 +245,7 @@ QJsonDocument versionFileToJson(VersionFilePtr patch) static QJsonDocument minecraftVersionToJson(MinecraftVersionPtr patch) { - if(patch->m_versionSource == Local && patch->getVersionFile()) + if(patch->getVersionSource() == Local && patch->getVersionFile()) { return MojangVersionFormat::profilePatchToJson(patch->getVersionFile()); } @@ -268,7 +267,7 @@ QJsonDocument MojangVersionFormat::profilePatchToJson(const ProfilePatchPtr &pat { return minecraftVersionToJson(mversion); } - throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getPatchName())); + throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getName())); } LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) diff --git a/logic/minecraft/ProfilePatch.h b/logic/minecraft/ProfilePatch.h index cf7a1904..0d01ba87 100644 --- a/logic/minecraft/ProfilePatch.h +++ b/logic/minecraft/ProfilePatch.h @@ -14,6 +14,14 @@ enum ProblemSeverity PROBLEM_ERROR }; +/// where is a version from? +enum VersionSource +{ + Builtin, //!< version loaded from the internal resources. + Local, //!< version loaded from a file in the cache. + Remote, //!< incomplete version on a remote server. +}; + class PatchProblem { public: @@ -56,10 +64,14 @@ public: virtual void setOrder(int order) = 0; virtual int getOrder() = 0; - virtual QString getPatchID() = 0; - virtual QString getPatchName() = 0; - virtual QString getPatchVersion() = 0; - virtual QString getPatchFilename() = 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 const QList& getProblems() { diff --git a/logic/minecraft/ProfileUtils.cpp b/logic/minecraft/ProfileUtils.cpp index 30e83a1f..dfff7956 100644 --- a/logic/minecraft/ProfileUtils.cpp +++ b/logic/minecraft/ProfileUtils.cpp @@ -166,6 +166,5 @@ void removeLwjglFromPatch(VersionFilePtr patch) libs = filteredLibs; }; filter(patch->addLibs); - filter(patch->overwriteLibs); } } diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 410f6659..9cd8dd5e 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -12,22 +12,6 @@ #include "VersionBuildError.h" #include -int findLibraryByName(QList 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; -} - bool VersionFile::isMinecraftVersion() { return fileId == "net.minecraft"; @@ -40,105 +24,31 @@ bool VersionFile::hasJarMods() void VersionFile::applyTo(MinecraftProfile *version) { - if (!version->id.isNull() && !mcVersion.isNull()) - { - if (QRegExp(mcVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(version->id) == - -1) - { - throw MinecraftVersionMismatch(fileId, mcVersion, version->id); - } - } - - if (!id.isNull()) - { - version->id = id; - } - if (!mainClass.isNull()) - { - version->mainClass = mainClass; - } - if (!appletClass.isNull()) - { - version->appletClass = appletClass; - } - if (!processArguments.isNull()) - { - if (isMinecraftVersion()) - { - version->vanillaProcessArguments = processArguments; - } - version->processArguments = processArguments; - } - if (isMinecraftVersion()) - { - if (!type.isNull()) - { - version->type = type; - } - if (!m_releaseTime.isNull()) - { - version->m_releaseTime = m_releaseTime; - } - if (!m_updateTime.isNull()) - { - version->m_updateTime = m_updateTime; - } - } - if (!assets.isNull()) + auto theirVersion = version->getMinecraftVersion(); + if (!theirVersion.isNull() && !mcVersion.isNull()) { - version->assets = assets; - } - if (!overwriteMinecraftArguments.isNull()) - { - if (isMinecraftVersion()) + if (QRegExp(mcVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1) { - version->vanillaMinecraftArguments = overwriteMinecraftArguments; + throw MinecraftVersionMismatch(fileId, mcVersion, theirVersion); } - version->minecraftArguments = overwriteMinecraftArguments; - } - if (!addMinecraftArguments.isNull()) - { - version->minecraftArguments += addMinecraftArguments; - } - if (shouldOverwriteTweakers) - { - version->tweakers = overwriteTweakers; } - for (auto tweaker : addTweakers) + bool is_minecraft = isMinecraftVersion(); + version->applyMinecraftVersion(id); + version->applyMainClass(mainClass); + version->applyAppletClass(appletClass); + version->applyMinecraftArguments(minecraftArguments, is_minecraft); + if (is_minecraft) { - version->tweakers += tweaker; - } - version->jarMods.append(jarMods); - version->traits.unite(traits); - if (shouldOverwriteLibs) - { - QList libs; - for (auto lib : overwriteLibs) - { - libs.append(Library::limitedCopy(lib)); - } - if (isMinecraftVersion()) - { - version->vanillaLibraries = libs; - } - version->libraries = libs; + version->applyMinecraftVersionType(type); } + version->applyMinecraftAssets(assets); + version->applyTweakers(addTweakers); + + version->applyJarMods(jarMods); + version->applyTraits(traits); + for (auto addedLibrary : addLibs) { - // find the library by name. - const int index = findLibraryByName(version->libraries, addedLibrary->rawName()); - // library not found? just add it. - if (index < 0) - { - version->libraries.append(Library::limitedCopy(addedLibrary)); - continue; - } - auto existingLibrary = version->libraries.at(index); - // if we are higher it means we should update - if (Version(addedLibrary->version()) > Version(existingLibrary->version())) - { - auto library = Library::limitedCopy(addedLibrary); - version->libraries.replace(index, library); - } + version->applyLibrary(addedLibrary, isMinecraftVersion()); } } diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index 6c0225b0..69866fc5 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -20,6 +20,8 @@ struct MojangAssetIndexInfo; typedef std::shared_ptr VersionFilePtr; class VersionFile : public ProfilePatch { + friend class MojangVersionFormat; + friend class OneSixVersionFormat; public: /* methods */ virtual void applyTo(MinecraftProfile *version) override; virtual bool isMinecraftVersion() override; @@ -36,22 +38,32 @@ public: /* methods */ { return jarMods; } - virtual QString getPatchID() override + virtual QString getID() override { return fileId; } - virtual QString getPatchName() override + virtual QString getName() override { return name; } - virtual QString getPatchVersion() override + virtual QString getVersion() override { return version; } - virtual QString getPatchFilename() override + virtual QString getFilename() override { return filename; } + virtual QDateTime getReleaseDateTime() override + { + return m_releaseTime; + } + VersionSource getVersionSource() override + { + return Local; + } + + virtual bool isCustom() override { return !m_isVanilla; @@ -138,17 +150,11 @@ public: /* data */ /// Mojang: class to launch Minecraft with QString mainClass; - /// MultiMC: class to launch legacy Minecraft with (ambed in a custom window) + /// 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 overwriteMinecraftArguments; - - /// MultiMC: Minecraft launch arguments, additive variant - QString addMinecraftArguments; - - /// Mojang: DEPRECATED variant of the Minecraft arguments, hardcoded, do not use! - QString processArguments; + QString minecraftArguments; /// Mojang: type of the Minecraft version QString type; @@ -162,17 +168,9 @@ public: /* data */ /// Mojang: DEPRECATED asset group to be used with Minecraft QString assets; - /// MultiMC: override list of tweaker mod arguments for launchwrapper (replaces the previously assembled lists) - bool shouldOverwriteTweakers = false; - QStringList overwriteTweakers; - /// MultiMC: list of tweaker mod arguments for launchwrapper QStringList addTweakers; - /// MultiMC: override list of libraries (replaces the previously assembled lists) - bool shouldOverwriteLibs = false; - QList overwriteLibs; - /// Mojang: list of libraries to add to the version QList addLibs; @@ -182,6 +180,7 @@ public: /* data */ /// MultiMC: list of jar mods added to this version QList jarMods; +public: // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more. QMap > mojangDownloads; diff --git a/logic/minecraft/VersionSource.h b/logic/minecraft/VersionSource.h deleted file mode 100644 index 75b2c24b..00000000 --- a/logic/minecraft/VersionSource.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -/// where is a version from? -enum VersionSource -{ - Builtin, //!< version loaded from the internal resources. - Local, //!< version loaded from a file in the cache. - Remote, //!< incomplete version on a remote server. -}; \ No newline at end of file diff --git a/logic/minecraft/forge/ForgeInstaller.cpp b/logic/minecraft/forge/ForgeInstaller.cpp index bc0a967e..a72160a2 100644 --- a/logic/minecraft/forge/ForgeInstaller.cpp +++ b/logic/minecraft/forge/ForgeInstaller.cpp @@ -119,7 +119,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr file.close(); m_forge_json = newVersion; - m_forge_json->id = installObj.value("minecraft").toString(); + //m_forge_json->id = installObj.value("minecraft").toString(); } bool ForgeInstaller::add(OneSixInstance *to) @@ -134,15 +134,14 @@ bool ForgeInstaller::add(OneSixInstance *to) if (!m_forge_json) return false; - int sliding_insert_window = 0; { - QJsonArray librariesPlus; + QJsonArray libraries; // A blacklist QSet blacklist{"authlib", "realms"}; // QList xzlist{"org.scala-lang", "com.typesafe"}; // for each library in the version we are adding (except for the blacklisted) - for (auto lib : m_forge_json->libraries) + for (auto lib : m_forge_json->getLibraries()) { QString libName = lib->artifactId(); QString rawName = lib->rawName(); @@ -194,41 +193,27 @@ bool ForgeInstaller::add(OneSixInstance *to) QJsonObject libObj = OneSixVersionFormat::libraryToJson(lib.get()); - bool found = false; bool equals = false; // find an entry that matches this one - for (auto tolib : to->getMinecraftProfile()->vanillaLibraries) + for (auto tolib : to->getMinecraftProfile()->getVanillaLibraries()) { if (tolib->artifactId() != libName) continue; - found = true; if (OneSixVersionFormat::libraryToJson(tolib.get()) == libObj) { equals = true; } - // replace lib - libObj.insert("insert", QString("replace")); break; } if (equals) { continue; } - if (!found) - { - // add lib - libObj.insert("insert", QString("prepend")); - if (lib->artifactId() == "minecraftforge" || lib->artifactId() == "forge") - { - libObj.insert("MMC-depend", QString("hard")); - } - sliding_insert_window++; - } - librariesPlus.prepend(libObj); + libraries.append(libObj); } - obj.insert("+libraries", librariesPlus); - obj.insert("mainClass", m_forge_json->mainClass); - QString args = m_forge_json->minecraftArguments; + obj.insert("libraries", libraries); + obj.insert("mainClass", m_forge_json->getMainClass()); + QString args = m_forge_json->getMinecraftArguments(); QStringList tweakers; { QRegularExpression expression("--tweakClass ([a-zA-Z0-9\\.]*)"); @@ -240,7 +225,7 @@ bool ForgeInstaller::add(OneSixInstance *to) match = expression.match(args); } } - if (!args.isEmpty() && args != to->getMinecraftProfile()->vanillaMinecraftArguments) + if (!args.isEmpty() && args != to->getMinecraftProfile()->getVanillaMinecraftArguments()) { obj.insert("minecraftArguments", args); } @@ -248,11 +233,6 @@ bool ForgeInstaller::add(OneSixInstance *to) { obj.insert("+tweakers", QJsonArray::fromStringList(tweakers)); } - if (!m_forge_json->processArguments.isEmpty() && - m_forge_json->processArguments != to->getMinecraftProfile()->vanillaProcessArguments) - { - obj.insert("processArguments", m_forge_json->processArguments); - } } obj.insert("name", QString("Forge")); diff --git a/logic/minecraft/ftb/FTBProfileStrategy.cpp b/logic/minecraft/ftb/FTBProfileStrategy.cpp index a86cdee3..6f635fe8 100644 --- a/logic/minecraft/ftb/FTBProfileStrategy.cpp +++ b/logic/minecraft/ftb/FTBProfileStrategy.cpp @@ -54,9 +54,6 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches() auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false); // adapt the loaded file - the FTB patch file format is different than ours. - file->addLibs = file->overwriteLibs; - file->overwriteLibs.clear(); - file->shouldOverwriteLibs = false; file->id.clear(); for(auto addLib: file->addLibs) { @@ -98,8 +95,6 @@ void FTBProfileStrategy::load() loadDefaultBuiltinPatches(); loadUserPatches(); - - profile->finalize(); } bool FTBProfileStrategy::saveOrder(ProfileUtils::PatchOrder order) diff --git a/logic/minecraft/onesix/OneSixInstance.cpp b/logic/minecraft/onesix/OneSixInstance.cpp index 2846640c..93034925 100644 --- a/logic/minecraft/onesix/OneSixInstance.cpp +++ b/logic/minecraft/onesix/OneSixInstance.cpp @@ -61,7 +61,7 @@ QSet OneSixInstance::traits() return {"version-incomplete"}; } else - return version->traits; + return version->getTraits(); } std::shared_ptr OneSixInstance::createUpdateTask() @@ -95,8 +95,8 @@ QString replaceTokensIn(QString text, QMap with) QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) { - QString args_pattern = m_version->minecraftArguments; - for (auto tweaker : m_version->tweakers) + QString args_pattern = m_version->getMinecraftArguments(); + for (auto tweaker : m_version->getTweakers()) { args_pattern += " --tweakClass " + tweaker; } @@ -113,7 +113,7 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5"; if(m_version->isVanilla()) { - token_mapping["version_type"] = m_version->type; + token_mapping["version_type"] = m_version->getMinecraftVersionType(); } else { @@ -123,24 +123,14 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) QString absRootDir = QDir(minecraftRoot()).absolutePath(); token_mapping["game_directory"] = absRootDir; QString absAssetsDir = QDir("assets/").absolutePath(); - token_mapping["game_assets"] = AssetsUtils::reconstructAssets(m_version->assets).absolutePath(); + token_mapping["game_assets"] = AssetsUtils::reconstructAssets(m_version->getMinecraftAssets()).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"] = m_version->assets; - - // 1.9+ version type token - if(m_version->isVanilla()) - { - token_mapping["version_type"] = m_version->type; - } - else - { - token_mapping["version_type"] = "custom"; - } + token_mapping["assets_index_name"] = m_version->getMinecraftAssets(); QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts); for (int i = 0; i < parts.length(); i++) @@ -182,7 +172,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session) launchScript += "coremod " + coremod.filename().completeBaseName() + "\n";; } - for(auto & jarmod: m_version->jarMods) + for(auto & jarmod: m_version->getJarMods()) { launchScript += "jarmod " + jarmod->originalName + " (" + jarmod->name + ")\n"; } @@ -201,17 +191,19 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session) } else { - QString relpath = m_version->id + "/" + m_version->id + ".jar"; + QString relpath = m_version->getMinecraftVersion() + "/" + m_version->getMinecraftVersion() + ".jar"; launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n"; } } - if (!m_version->mainClass.isEmpty()) + auto mainClass = m_version->getMainClass(); + if (!mainClass.isEmpty()) { - launchScript += "mainClass " + m_version->mainClass + "\n"; + launchScript += "mainClass " + mainClass + "\n"; } - if (!m_version->appletClass.isEmpty()) + auto appletClass = m_version->getAppletClass(); + if (!appletClass.isEmpty()) { - launchScript += "appletClass " + m_version->appletClass + "\n"; + launchScript += "appletClass " + appletClass + "\n"; } // generic minecraft params @@ -251,7 +243,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session) } // traits. including legacyLaunch and others ;) - for (auto trait : m_version->traits) + for (auto trait : m_version->getTraits()) { launchScript += "traits " + trait + "\n"; } @@ -323,7 +315,7 @@ std::shared_ptr OneSixInstance::createJarModdingTask() { std::shared_ptr version = m_inst->getMinecraftProfile(); // nuke obsolete stripped jar(s) if needed - QString version_id = version->id; + QString version_id = version->getMinecraftVersion(); QString strippedPath = version_id + "/" + version_id + "-stripped.jar"; QFile strippedJar(strippedPath); if(strippedJar.exists()) @@ -351,7 +343,7 @@ std::shared_ptr OneSixInstance::createJarModdingTask() auto jarMods = m_inst->getJarMods(); if(jarMods.size()) { - auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar"); + 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); @@ -439,7 +431,7 @@ bool OneSixInstance::setIntendedVersionId(QString version) QList< Mod > OneSixInstance::getJarMods() const { QList mods; - for (auto jarmod : m_version->jarMods) + for (auto jarmod : m_version->getJarMods()) { QString filePath = jarmodsPath().absoluteFilePath(jarmod->name); mods.push_back(Mod(QFileInfo(filePath))); diff --git a/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/logic/minecraft/onesix/OneSixProfileStrategy.cpp index fe4e0d26..baec635e 100644 --- a/logic/minecraft/onesix/OneSixProfileStrategy.cpp +++ b/logic/minecraft/onesix/OneSixProfileStrategy.cpp @@ -228,8 +228,6 @@ void OneSixProfileStrategy::load() upgradeDeprecatedFiles(); loadDefaultBuiltinPatches(); loadUserPatches(); - - profile->finalize(); } bool OneSixProfileStrategy::saveOrder(ProfileUtils::PatchOrder order) @@ -246,7 +244,7 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch) { bool ok = true; // first, remove the patch file. this ensures it's not used anymore - auto fileName = patch->getPatchFilename(); + auto fileName = patch->getFilename(); if(fileName.size()) { QFile patchFile(fileName); @@ -289,7 +287,7 @@ bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch) return false; } - auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getPatchID() + ".json"); + auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getID() + ".json"); if(!FS::ensureFilePathExists(filename)) { return false; @@ -327,7 +325,7 @@ bool OneSixProfileStrategy::revertPatch(ProfilePatchPtr patch) // already not custom return true; } - auto filename = patch->getPatchFilename(); + auto filename = patch->getFilename(); if(!QFile::exists(filename)) { // already gone / not custom diff --git a/logic/minecraft/onesix/OneSixUpdate.cpp b/logic/minecraft/onesix/OneSixUpdate.cpp index da3bd504..c12674d4 100644 --- a/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/logic/minecraft/onesix/OneSixUpdate.cpp @@ -51,8 +51,7 @@ void OneSixUpdate::executeTask() } // Get a pointer to the version object that corresponds to the instance's version. - targetVersion = std::dynamic_pointer_cast( - ENV.getVersion("net.minecraft", m_inst->intendedVersionId())); + targetVersion = std::dynamic_pointer_cast(ENV.getVersion("net.minecraft", m_inst->intendedVersionId())); if (targetVersion == nullptr) { // don't do anything if it was invalid @@ -89,7 +88,7 @@ void OneSixUpdate::assetIndexStart() setStatus(tr("Updating assets index...")); OneSixInstance *inst = (OneSixInstance *)m_inst; std::shared_ptr version = inst->getMinecraftProfile(); - QString assetName = version->assets; + QString assetName = version->getMinecraftAssets(); QUrl indexUrl = "http://" + URLConstants::AWS_DOWNLOAD_INDEXES + assetName + ".json"; QString localPath = assetName + ".json"; auto job = new NetJob(tr("Asset index for %1").arg(inst->name())); @@ -115,7 +114,7 @@ void OneSixUpdate::assetIndexFinished() OneSixInstance *inst = (OneSixInstance *)m_inst; std::shared_ptr version = inst->getMinecraftProfile(); - QString assetName = version->assets; + QString assetName = version->getMinecraftAssets(); QString asset_fname = "assets/indexes/" + assetName + ".json"; if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index)) @@ -194,7 +193,7 @@ void OneSixUpdate::jarlibStart() std::shared_ptr version = inst->getMinecraftProfile(); // minecraft.jar for this version { - QString version_id = version->id; + QString version_id = version->getMinecraftVersion(); QString localPath = version_id + "/" + version_id + ".jar"; QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath; @@ -292,7 +291,7 @@ void OneSixUpdate::jarlibFinished() OneSixInstance *inst = (OneSixInstance *)m_inst; std::shared_ptr version = inst->getMinecraftProfile(); - if (version->traits.contains("legacyFML")) + if (version->hasTrait("legacyFML")) { fmllibsStart(); } diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp index 4ccf6e78..ff26ab92 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.cpp +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -81,9 +81,30 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc readString(root, "mainClass", out->mainClass); readString(root, "appletClass", out->appletClass); - readString(root, "processArguments", out->processArguments); - readString(root, "minecraftArguments", out->overwriteMinecraftArguments); - readString(root, "+minecraftArguments", out->addMinecraftArguments); + readString(root, "minecraftArguments", out->minecraftArguments); + if(out->minecraftArguments.isEmpty()) + { + QString processArguments; + readString(root, "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)); + } + } + readString(root, "type", out->type); out->m_releaseTime = timeFromS3Time(readStringRet(root, "releaseTime")); @@ -91,15 +112,6 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc readString(root, "assets", out->assets); - if (root.contains("tweakers")) - { - out->shouldOverwriteTweakers = true; - for (auto tweakerVal : requireArray(root.value("tweakers"))) - { - out->overwriteTweakers.append(requireString(tweakerVal)); - } - } - if (root.contains("+tweakers")) { for (auto tweakerVal : requireArray(root.value("+tweakers"))) @@ -108,7 +120,6 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - if (root.contains("+traits")) { for (auto tweakerVal : requireArray(root.value("+traits"))) @@ -117,18 +128,6 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - if (root.contains("libraries")) - { - out->shouldOverwriteLibs = true; - for (auto libVal : requireArray(root.value("libraries"))) - { - auto libObj = requireObject(libVal); - - auto lib = libraryFromJson(libObj, filename); - out->overwriteLibs.append(lib); - } - } - if (root.contains("+jarMods")) { for (auto libVal : requireArray(root.value("+jarMods"))) @@ -147,18 +146,38 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - if (root.contains("+libraries")) + auto readLibs = [&](const char * which) { - for (auto libVal : requireArray(root.value("+libraries"))) + for (auto libVal : requireArray(root.value(which))) { QJsonObject libObj = requireObject(libVal); // parse the library auto lib = libraryFromJson(libObj, filename); out->addLibs.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'")); @@ -171,6 +190,10 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc { 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; } @@ -197,9 +220,7 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) writeString(root, "id", patch->id); writeString(root, "mainClass", patch->mainClass); writeString(root, "appletClass", patch->appletClass); - writeString(root, "processArguments", patch->processArguments); - writeString(root, "minecraftArguments", patch->overwriteMinecraftArguments); - writeString(root, "+minecraftArguments", patch->addMinecraftArguments); + writeString(root, "minecraftArguments", patch->minecraftArguments); writeString(root, "type", patch->type); writeString(root, "assets", patch->assets); if (patch->isMinecraftVersion()) @@ -207,18 +228,8 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) writeString(root, "releaseTime", timeToS3Time(patch->m_releaseTime)); writeString(root, "time", timeToS3Time(patch->m_updateTime)); } - writeStringList(root, "tweakers", patch->overwriteTweakers); writeStringList(root, "+tweakers", patch->addTweakers); writeStringList(root, "+traits", patch->traits.toList()); - if (!patch->overwriteLibs.isEmpty()) - { - QJsonArray array; - for (auto value: patch->overwriteLibs) - { - array.append(OneSixVersionFormat::libraryToJson(value.get())); - } - root.insert("libraries", array); - } if (!patch->addLibs.isEmpty()) { QJsonArray array; @@ -226,7 +237,7 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) { array.append(OneSixVersionFormat::libraryToJson(value.get())); } - root.insert("+libraries", array); + root.insert("libraries", array); } if (!patch->jarMods.isEmpty()) { @@ -247,7 +258,7 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) static QJsonDocument minecraftVersionToJson(MinecraftVersionPtr patch, bool saveOrder) { - if(patch->m_versionSource == Local && patch->getVersionFile()) + if(patch->getVersionSource() == Local && patch->getVersionFile()) { return OneSixVersionFormat::profilePatchToJson(patch->getVersionFile(), saveOrder); } @@ -269,7 +280,7 @@ QJsonDocument OneSixVersionFormat::profilePatchToJson(const ProfilePatchPtr &pat { return minecraftVersionToJson(mversion, saveOrder); } - throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getPatchName())); + throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getName())); } std::shared_ptr OneSixVersionFormat::profileFromSingleJson(const QJsonObject &obj) -- cgit v1.2.3