diff options
author | Petr Mrázek <peterix@gmail.com> | 2014-07-26 23:00:35 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2014-07-26 23:00:35 +0200 |
commit | 03b13b0b3f43e830ca924338b38e1947cd0cc739 (patch) | |
tree | 08941e693ab365f934beba04d69aacf481be40d1 | |
parent | 9b82c87c92761515a11f00540a6bf74df6c76298 (diff) | |
download | MultiMC-03b13b0b3f43e830ca924338b38e1947cd0cc739.tar MultiMC-03b13b0b3f43e830ca924338b38e1947cd0cc739.tar.gz MultiMC-03b13b0b3f43e830ca924338b38e1947cd0cc739.tar.lz MultiMC-03b13b0b3f43e830ca924338b38e1947cd0cc739.tar.xz MultiMC-03b13b0b3f43e830ca924338b38e1947cd0cc739.zip |
Rearrange RawLibrary and OneSixLibrary heavily.
Fix #396
-rw-r--r-- | logic/OneSixFTBInstance.cpp | 1 | ||||
-rw-r--r-- | logic/forge/ForgeInstaller.cpp | 15 | ||||
-rw-r--r-- | logic/liteloader/LiteLoaderInstaller.cpp | 2 | ||||
-rw-r--r-- | logic/liteloader/LiteLoaderVersionList.cpp | 2 | ||||
-rw-r--r-- | logic/minecraft/GradleSpecifier.h | 4 | ||||
-rw-r--r-- | logic/minecraft/MinecraftVersionList.cpp | 2 | ||||
-rw-r--r-- | logic/minecraft/OneSixLibrary.cpp | 195 | ||||
-rw-r--r-- | logic/minecraft/OneSixLibrary.h | 92 | ||||
-rw-r--r-- | logic/minecraft/OneSixRule.h | 11 | ||||
-rw-r--r-- | logic/minecraft/RawLibrary.cpp | 159 | ||||
-rw-r--r-- | logic/minecraft/RawLibrary.h | 128 | ||||
-rw-r--r-- | logic/minecraft/VersionFile.cpp | 143 |
12 files changed, 335 insertions, 419 deletions
diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp index ef951987..8dfd3051 100644 --- a/logic/OneSixFTBInstance.cpp +++ b/logic/OneSixFTBInstance.cpp @@ -73,7 +73,6 @@ void OneSixFTBInstance::copy(const QDir &newDir) for (auto library : libraryNames) { OneSixLibrary *lib = new OneSixLibrary(library); - lib->finalize(); const QString out = QDir::current().absoluteFilePath("libraries/" + lib->storagePath()); if (QFile::exists(out)) { diff --git a/logic/forge/ForgeInstaller.cpp b/logic/forge/ForgeInstaller.cpp index 74db2bfc..a230b038 100644 --- a/logic/forge/ForgeInstaller.cpp +++ b/logic/forge/ForgeInstaller.cpp @@ -85,7 +85,6 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr // where do we put the library? decode the mojang path OneSixLibrary lib(libraryName); - lib.finalize(); auto cacheentry = MMC->metacache()->resolveEntry("libraries", lib.storagePath()); finalPath = "libraries/" + lib.storagePath(); @@ -140,11 +139,11 @@ bool ForgeInstaller::add(OneSixInstance *to) // for each library in the version we are adding (except for the blacklisted) for (auto lib : m_forge_json->libraries) { - QString libName = lib->name(); + QString libName = lib->artifactId(); QString rawName = lib->rawName(); // ignore lwjgl libraries. - if (g_VersionFilterData.lwjglWhitelist.contains(lib->fullname())) + if (g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) continue; // ignore other blacklisted (realms, authlib) if (blacklist.contains(libName)) @@ -156,8 +155,7 @@ bool ForgeInstaller::add(OneSixInstance *to) { if (libName == "forge") { - lib->m_name.setClassifier("universal"); - lib->finalize(); + lib->setClassifier("universal"); } else if (libName == "minecraftforge") { @@ -165,8 +163,7 @@ bool ForgeInstaller::add(OneSixInstance *to) // using insane form of the MC version... QString longVersion = m_forge_version->mcver + "-" + m_forge_version->jobbuildver; GradleSpecifier spec(forgeCoord.arg(longVersion)); - lib->m_name = spec; - lib->finalize(); + lib->setRawName(spec); } } else @@ -196,7 +193,7 @@ bool ForgeInstaller::add(OneSixInstance *to) // find an entry that matches this one for (auto tolib : to->getFullVersion()->vanillaLibraries) { - if (tolib->name() != libName) + if (tolib->artifactId() != libName) continue; found = true; if (tolib->toJson() == libObj) @@ -215,7 +212,7 @@ bool ForgeInstaller::add(OneSixInstance *to) { // add lib libObj.insert("insert", QString("prepend")); - if (lib->name() == "minecraftforge" || lib->name() == "forge") + if (lib->artifactId() == "minecraftforge" || lib->artifactId() == "forge") { libObj.insert("MMC-depend", QString("hard")); } diff --git a/logic/liteloader/LiteLoaderInstaller.cpp b/logic/liteloader/LiteLoaderInstaller.cpp index 863c7fcb..f1f9885a 100644 --- a/logic/liteloader/LiteLoaderInstaller.cpp +++ b/logic/liteloader/LiteLoaderInstaller.cpp @@ -53,7 +53,6 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) { rawLibrary->insertType = RawLibrary::Prepend; OneSixLibrary lib(rawLibrary); - lib.finalize(); libraries.append(lib.toJson()); } @@ -63,7 +62,6 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) liteloaderLib.setAbsoluteUrl( QString("http://dl.liteloader.com/versions/com/mumfrey/liteloader/%1/%2") .arg(m_version->mcVersion, m_version->file)); - liteloaderLib.finalize(); QJsonObject llLibObj = liteloaderLib.toJson(); llLibObj.insert("insert", QString("prepend")); llLibObj.insert("MMC-depend", QString("hard")); diff --git a/logic/liteloader/LiteLoaderVersionList.cpp b/logic/liteloader/LiteLoaderVersionList.cpp index af8509d6..bf57867a 100644 --- a/logic/liteloader/LiteLoaderVersionList.cpp +++ b/logic/liteloader/LiteLoaderVersionList.cpp @@ -212,7 +212,7 @@ void LLListLoadTask::listDownloaded() { auto lib = RawLibrary::fromJson(libobject, "versions.json"); // hack to make liteloader 1.7.10_00 work - if(lib->m_name == GradleSpecifier("org.ow2.asm:asm-all:5.0.3")) + if(lib->rawName() == GradleSpecifier("org.ow2.asm:asm-all:5.0.3")) { lib->m_base_url = "http://repo.maven.apache.org/maven2/"; } diff --git a/logic/minecraft/GradleSpecifier.h b/logic/minecraft/GradleSpecifier.h index 8a02e4d9..411aed65 100644 --- a/logic/minecraft/GradleSpecifier.h +++ b/logic/minecraft/GradleSpecifier.h @@ -101,11 +101,11 @@ struct GradleSpecifier { return m_groupId + ":" + m_artifactId; } - bool matchName(const GradleSpecifier & other) + bool matchName(const GradleSpecifier & other) const { return other.artifactId() == artifactId() && other.groupId() == groupId(); } - bool operator==(const GradleSpecifier & other) + bool operator==(const GradleSpecifier & other) const { if(m_groupId != other.m_groupId) return false; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index ee228528..bde2170b 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -452,7 +452,7 @@ void MCVListVersionUpdateTask::json_downloaded() for (auto lib : file->overwriteLibs) { - if (g_VersionFilterData.lwjglWhitelist.contains(lib->fullname())) + if (g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) { lwjglLibs.append(lib); } diff --git a/logic/minecraft/OneSixLibrary.cpp b/logic/minecraft/OneSixLibrary.cpp index c562f353..9b3f3b3e 100644 --- a/logic/minecraft/OneSixLibrary.cpp +++ b/logic/minecraft/OneSixLibrary.cpp @@ -32,198 +32,15 @@ OneSixLibrary::OneSixLibrary(RawLibraryPtr base) extract_excludes = base->extract_excludes; m_native_classifiers = base->m_native_classifiers; m_rules = base->m_rules; - finalize(); + dependType = base->dependType; + // these only make sense for raw libraries. OneSix + /* + insertType = base->insertType; + insertData = base->insertData; + */ } OneSixLibraryPtr OneSixLibrary::fromRawLibrary(RawLibraryPtr lib) { return OneSixLibraryPtr(new OneSixLibrary(lib)); } - -void OneSixLibrary::finalize() -{ - QString relative; - - if (m_rules.empty()) - { - m_is_active = true; - } - else - { - RuleAction result = Disallow; - for (auto rule : m_rules) - { - RuleAction temp = rule->apply(this); - if (temp != Defer) - result = temp; - } - m_is_active = (result == Allow); - } - if (isNative()) - { - GradleSpecifier nativeSpec = m_name; - m_is_active = m_is_active && m_native_classifiers.contains(currentSystem); - m_decenttype = "Native"; - if(m_native_classifiers.contains(currentSystem)) - { - nativeSpec.setClassifier(m_native_classifiers[currentSystem]); - } - else - { - nativeSpec.setClassifier("INVALID"); - } - relative = nativeSpec.toPath(); - } - else - { - relative = m_name.toPath(); - m_decenttype = "Java"; - } - - m_decentname = m_name.artifactId(); - m_decentversion = minVersion = m_name.version(); - m_storage_path = relative; - if(m_base_url.isEmpty()) - m_download_url = QString("https://" + URLConstants::LIBRARY_BASE) + relative; - else - m_download_url = m_base_url + relative; -} - -void OneSixLibrary::setName(const QString &name) -{ - m_name = name; -} -void OneSixLibrary::setBaseUrl(const QString &base_url) -{ - m_base_url = base_url; -} -void OneSixLibrary::addNative(OpSys os, const QString &suffix) -{ - m_native_classifiers[os] = suffix; -} -void OneSixLibrary::clearSuffixes() -{ - m_native_classifiers.clear(); -} -void OneSixLibrary::setRules(QList<std::shared_ptr<Rule>> rules) -{ - m_rules = rules; -} -bool OneSixLibrary::isActive() const -{ - return m_is_active; -} -QString OneSixLibrary::downloadUrl() const -{ - if (m_absolute_url.size()) - return m_absolute_url; - return m_download_url; -} -QString OneSixLibrary::storagePath() const -{ - return m_storage_path; -} - -void OneSixLibrary::setAbsoluteUrl(const QString &absolute_url) -{ - m_absolute_url = absolute_url; -} - -QString OneSixLibrary::absoluteUrl() const -{ - return m_absolute_url; -} - -void OneSixLibrary::setHint(const QString &hint) -{ - m_hint = hint; -} - -QString OneSixLibrary::hint() const -{ - return m_hint; -} - -QStringList OneSixLibrary::files() -{ - QStringList retval; - QString storage = storagePath(); - if (storage.contains("${arch}")) - { - QString cooked_storage = storage; - cooked_storage.replace("${arch}", "32"); - retval.append(cooked_storage); - cooked_storage = storage; - cooked_storage.replace("${arch}", "64"); - retval.append(cooked_storage); - } - else - retval.append(storage); - return retval; -} - -bool OneSixLibrary::filesExist(const QDir &base) -{ - auto libFiles = files(); - for(auto file: libFiles) - { - QFileInfo info(base, file); - QLOG_WARN() << info.absoluteFilePath() << "doesn't exist"; - if (!info.exists()) - return false; - } - return true; -} - -bool OneSixLibrary::extractTo(QString target_dir) -{ - QString storage = storagePath(); - if (storage.contains("${arch}")) - { - QString cooked_storage = storage; - cooked_storage.replace("${arch}", "32"); - QString origin = PathCombine("libraries", cooked_storage); - QString target_dir_cooked = PathCombine(target_dir, "32"); - if (!ensureFolderPathExists(target_dir_cooked)) - { - QLOG_ERROR() << "Couldn't create folder " + target_dir_cooked; - return false; - } - if (JlCompress::extractWithExceptions(origin, target_dir_cooked, extract_excludes) - .isEmpty()) - { - QLOG_ERROR() << "Couldn't extract " + origin; - return false; - } - cooked_storage = storage; - cooked_storage.replace("${arch}", "64"); - origin = PathCombine("libraries", cooked_storage); - target_dir_cooked = PathCombine(target_dir, "64"); - if (!ensureFolderPathExists(target_dir_cooked)) - { - QLOG_ERROR() << "Couldn't create folder " + target_dir_cooked; - return false; - } - if (JlCompress::extractWithExceptions(origin, target_dir_cooked, extract_excludes) - .isEmpty()) - { - QLOG_ERROR() << "Couldn't extract " + origin; - return false; - } - } - else - { - if (!ensureFolderPathExists(target_dir)) - { - QLOG_ERROR() << "Couldn't create folder " + target_dir; - return false; - } - QString path = PathCombine("libraries", storage); - if (JlCompress::extractWithExceptions(path, target_dir, extract_excludes).isEmpty()) - { - QLOG_ERROR() << "Couldn't extract " + path; - return false; - } - } - return true; -} diff --git a/logic/minecraft/OneSixLibrary.h b/logic/minecraft/OneSixLibrary.h index 3d38985b..2f60405a 100644 --- a/logic/minecraft/OneSixLibrary.h +++ b/logic/minecraft/OneSixLibrary.h @@ -26,38 +26,18 @@ #include "logic/minecraft/OpSys.h" #include "logic/minecraft/RawLibrary.h" -class Rule; - class OneSixLibrary; typedef std::shared_ptr<OneSixLibrary> OneSixLibraryPtr; +/** + * This is a leftover from a previous design. + * All it does is separate the 'Raw' libraries read from files from the 'OneSix' libraries + * used for actually doing things. + * + * DEPRECATED, but still useful to keep the data clean and separated by type. + */ class OneSixLibrary : public RawLibrary { -private: - /// a decent name fit for display - QString m_decentname; - /// a decent version fit for display - QString m_decentversion; - /// a decent type fit for display - QString m_decenttype; - /// where to store the lib locally - QString m_storage_path; - /// where to download the lib from - QString m_download_url; - /// is this lib actually active on the current OS? - bool m_is_active = false; - -public: - - QString minVersion; - - enum DependType - { - Soft, - Hard - }; - DependType dependType; - public: /// Constructor OneSixLibrary(const QString &name, const DependType type = Soft) @@ -69,62 +49,4 @@ public: OneSixLibrary(RawLibraryPtr base); static OneSixLibraryPtr fromRawLibrary(RawLibraryPtr lib); - /// Returns the raw name field - QString rawName() const - { - return m_name; - } - - /** - * finalize the library, processing the input values into derived values and state - * - * This SHALL be called after all the values are parsed or after any further change. - */ - void finalize(); - - /// Set the library composite name - void setName(const QString &name); - /// get a decent-looking name - QString name() const - { - return m_decentname; - } - /// get a decent-looking version - QString version() const - { - return m_decentversion; - } - /// what kind of library is it? (for display) - QString type() const - { - return m_decenttype; - } - /// Set the url base for downloads - void setBaseUrl(const QString &base_url); - - /// Attach a name suffix to the specified OS native - void addNative(OpSys os, const QString &suffix); - /// Clears all suffixes - void clearSuffixes(); - /// Set the load rules - void setRules(QList<std::shared_ptr<Rule>> rules); - - /// Returns true if the library should be loaded (or extracted, in case of natives) - bool isActive() const; - /// Get the URL to download the library from - QString downloadUrl() const; - /// Get the relative path where the library should be saved - QString storagePath() const; - - /// set an absolute URL for the library. This is an MMC extension. - void setAbsoluteUrl(const QString &absolute_url); - QString absoluteUrl() const; - - /// set a hint about how to treat the library. This is an MMC extension. - void setHint(const QString &hint); - QString hint() const; - - bool extractTo(QString target_dir); - bool filesExist(const QDir &base); - QStringList files(); }; diff --git a/logic/minecraft/OneSixRule.h b/logic/minecraft/OneSixRule.h index a18093b0..33f7ff93 100644 --- a/logic/minecraft/OneSixRule.h +++ b/logic/minecraft/OneSixRule.h @@ -21,7 +21,7 @@ #include <memory> #include "OpSys.h" -class OneSixLibrary; +class RawLibrary; class Rule; enum RuleAction @@ -37,7 +37,7 @@ class Rule { protected: RuleAction m_result; - virtual bool applies(OneSixLibrary *parent) = 0; + virtual bool applies(const RawLibrary *parent) = 0; public: Rule(RuleAction result) : m_result(result) @@ -45,14 +45,13 @@ public: } virtual ~Rule() {}; virtual QJsonObject toJson() = 0; - RuleAction apply(OneSixLibrary *parent) + RuleAction apply(const RawLibrary *parent) { if (applies(parent)) return m_result; else return Defer; } - ; }; class OsRule : public Rule @@ -64,7 +63,7 @@ private: QString m_version_regexp; protected: - virtual bool applies(OneSixLibrary *) + virtual bool applies(const RawLibrary *) { return (m_system == currentSystem); } @@ -85,7 +84,7 @@ public: class ImplicitRule : public Rule { protected: - virtual bool applies(OneSixLibrary *) + virtual bool applies(const RawLibrary *) { return true; } diff --git a/logic/minecraft/RawLibrary.cpp b/logic/minecraft/RawLibrary.cpp index 76bd7260..c3df6e0c 100644 --- a/logic/minecraft/RawLibrary.cpp +++ b/logic/minecraft/RawLibrary.cpp @@ -72,44 +72,54 @@ RawLibraryPtr RawLibrary::fromJsonPlus(const QJsonObject &libObj, const QString if (libObj.contains("insert")) { QJsonValue insertVal = ensureExists(libObj.value("insert"), "library insert rule"); - QString insertString; + if (insertVal.isString()) { - if (insertVal.isString()) + // it's just a simple string rule. OK. + QString insertString = insertVal.toString(); + if (insertString == "apply") { - insertString = insertVal.toString(); + lib->insertType = RawLibrary::Apply; } - else if (insertVal.isObject()) + else if (insertString == "prepend") { - QJsonObject insertObj = insertVal.toObject(); - if (insertObj.isEmpty()) - { - throw JSONValidationError("One library has an empty insert object in " + - filename); - } - insertString = insertObj.keys().first(); - lib->insertData = insertObj.value(insertString).toString(); + lib->insertType = RawLibrary::Prepend; + } + else if (insertString == "append") + { + lib->insertType = RawLibrary::Append; + } + else if (insertString == "replace") + { + lib->insertType = RawLibrary::Replace; + } + else + { + throw JSONValidationError("A '+' library in " + filename + + " contains an invalid insert type"); } } - if (insertString == "apply") - { - lib->insertType = RawLibrary::Apply; - } - else if (insertString == "prepend") - { - lib->insertType = RawLibrary::Prepend; - } - else if (insertString == "append") - { - lib->insertType = RawLibrary::Append; - } - else if (insertString == "replace") + else if (insertVal.isObject()) { - lib->insertType = RawLibrary::Replace; + // it's a more complex rule, specifying what should be: + // * replaced (for now only this) + // this was never used, AFAIK. tread carefully. + QJsonObject insertObj = insertVal.toObject(); + if (insertObj.isEmpty()) + { + throw JSONValidationError("Empty compound insert rule in " + filename); + } + QString insertString = insertObj.keys().first(); + // really, only replace makes sense in combination with + if(insertString != "replace") + { + throw JSONValidationError("Compound insert rule is not 'replace' in " + filename); + } + lib->insertData = insertObj.value(insertString).toString(); } else { throw JSONValidationError("A '+' library in " + filename + - " contains an invalid insert type"); + " contains an unknown/invalid insert rule"); } } if (libObj.contains("MMC-depend")) @@ -132,12 +142,7 @@ RawLibraryPtr RawLibrary::fromJsonPlus(const QJsonObject &libObj, const QString return lib; } -bool RawLibrary::isNative() const -{ - return m_native_classifiers.size() != 0; -} - -QJsonObject RawLibrary::toJson() +QJsonObject RawLibrary::toJson() const { QJsonObject libRoot; libRoot.insert("name", (QString)m_name); @@ -186,7 +191,91 @@ QJsonObject RawLibrary::toJson() return libRoot; } -QString RawLibrary::fullname() +QStringList RawLibrary::files() const +{ + QStringList retval; + QString storage = storagePath(); + if (storage.contains("${arch}")) + { + QString cooked_storage = storage; + cooked_storage.replace("${arch}", "32"); + retval.append(cooked_storage); + cooked_storage = storage; + cooked_storage.replace("${arch}", "64"); + retval.append(cooked_storage); + } + else + retval.append(storage); + return retval; +} + +bool RawLibrary::filesExist(const QDir &base) const +{ + auto libFiles = files(); + for(auto file: libFiles) + { + QFileInfo info(base, file); + QLOG_WARN() << info.absoluteFilePath() << "doesn't exist"; + if (!info.exists()) + return false; + } + return true; +} +QString RawLibrary::downloadUrl() const +{ + if (m_absolute_url.size()) + return m_absolute_url; + + if (m_base_url.isEmpty()) + { + return QString("https://" + URLConstants::LIBRARY_BASE) + storagePath(); + } + + return m_base_url + storagePath(); +} + +bool RawLibrary::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_native_classifiers.contains(currentSystem); + } + return result; +} + +QString RawLibrary::storagePath() const { - return m_name.artifactPrefix(); + // 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_native_classifiers.contains(currentSystem)) + { + nativeSpec.setClassifier(m_native_classifiers[currentSystem]); + } + else + { + nativeSpec.setClassifier("INVALID"); + } + return nativeSpec.toPath(); } diff --git a/logic/minecraft/RawLibrary.h b/logic/minecraft/RawLibrary.h index 6e8f7f10..6263f99a 100644 --- a/logic/minecraft/RawLibrary.h +++ b/logic/minecraft/RawLibrary.h @@ -4,6 +4,7 @@ #include <QList> #include <QStringList> #include <QMap> +#include <QDir> #include <memory> #include "logic/minecraft/OneSixRule.h" @@ -16,36 +17,141 @@ typedef std::shared_ptr<RawLibrary> RawLibraryPtr; class RawLibrary { + friend class OneSixLibrary; public: /* methods */ /// read and create a basic library static RawLibraryPtr fromJson(const QJsonObject &libObj, const QString &filename); + /// read and create a MultiMC '+' library. Those have some extra fields. static RawLibraryPtr fromJsonPlus(const QJsonObject &libObj, const QString &filename); - QJsonObject toJson(); + + /// Convert the library back to an JSON object + QJsonObject toJson() const; + + /// Returns the raw name field + const GradleSpecifier & rawName() const + { + return m_name; + } - QString fullname(); + void setRawName(const GradleSpecifier & spec) + { + m_name = spec; + } + + void setClassifier(const QString & spec) + { + m_name.setClassifier(spec); + } -public: /* data */ + /// 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_native_classifiers.size() != 0; + } + + /// Set the url base for downloads + void setBaseUrl(const QString &base_url) + { + m_base_url = base_url; + } + + /// List of files this library describes. Required because of platform-specificness of native libs + QStringList files() const; + + /// List Shortcut for checking if all the above files exist + bool filesExist(const QDir &base) const; + + void setAbsoluteUrl(const QString &absolute_url) + { + m_absolute_url = absolute_url; + } + + QString absoluteUrl() const + { + return m_absolute_url; + } + + void setHint(const QString &hint) + { + m_hint = hint; + } + + QString hint() const + { + return m_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 the URL to download the library from + QString downloadUrl() const; + + /// Get the relative path where the library should be saved + QString storagePath() const; + + +protected: /* data */ + /// the basic gradle dependency specifier. GradleSpecifier m_name; + /// where to store the lib locally + QString m_storage_path; + /// is this lib actually active on the current OS? + bool m_is_active = false; + + +public: /* data */ + // TODO: make all of these protected, clean up semantics of implicit vs. explicit values. + /// URL where the file can be downloaded QString m_base_url; + /// DEPRECATED: absolute URL. takes precedence the normal download URL, if defined + QString m_absolute_url; + /// type hint - modifies how the library is treated QString m_hint; - /// DEPRECATED: absolute URL. takes precedence over m_download_path, if defined - QString m_absolute_url; + /// true if the library had an extract/excludes section (even empty) bool applyExcludes = false; + + /// a list of files that shouldn't be extracted from the library QStringList extract_excludes; - /// Returns true if the library is native - bool isNative() const; /// native suffixes per OS QMap<OpSys, QString> m_native_classifiers; + /// 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; - // used for '+' libraries + /// used for '+' libraries, determines how to add them enum InsertType { Apply, @@ -55,10 +161,10 @@ public: /* data */ } insertType = Append; QString insertData; - // soft or hard dependency? hard means 'needs equal', soft means 'needs equal or newer' + /// determines how can libraries be applied. conflicting dependencies cause errors. enum DependType { - Soft, - Hard + Soft, //! needs equal or newer version + Hard //! needs equal version (different versions mean version conflict) } dependType = Soft; }; diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 600c71ae..778c5a27 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -23,7 +23,7 @@ int findLibraryByName(QList<OneSixLibraryPtr> haystack, const GradleSpecifier &n for (int i = 0; i < haystack.size(); ++i) { - if(haystack.at(i)->m_name.matchName(needle)) + if(haystack.at(i)->rawName().matchName(needle)) { // only one is allowed. if (retval != -1) @@ -375,119 +375,108 @@ void VersionFile::applyTo(InstanceVersion *version) } version->libraries = libs; } - for (auto lib : addLibs) + for (auto addedLibrary : addLibs) { - switch (lib->insertType) + switch (addedLibrary->insertType) { case RawLibrary::Apply: { // QLOG_INFO() << "Applying lib " << lib->name; - int index = findLibraryByName(version->libraries, lib->m_name); + int index = findLibraryByName(version->libraries, addedLibrary->rawName()); if (index >= 0) { - auto library = version->libraries[index]; - if (!lib->m_base_url.isNull()) + auto existingLibrary = version->libraries[index]; + if (!addedLibrary->m_base_url.isNull()) { - library->setBaseUrl(lib->m_base_url); + existingLibrary->setBaseUrl(addedLibrary->m_base_url); } - if (!lib->m_hint.isNull()) + if (!addedLibrary->m_hint.isNull()) { - library->setHint(lib->m_hint); + existingLibrary->setHint(addedLibrary->m_hint); } - if (!lib->m_absolute_url.isNull()) + if (!addedLibrary->m_absolute_url.isNull()) { - library->setAbsoluteUrl(lib->m_absolute_url); + existingLibrary->setAbsoluteUrl(addedLibrary->m_absolute_url); } - if (lib->applyExcludes) + if (addedLibrary->applyExcludes) { - library->extract_excludes = lib->extract_excludes; + existingLibrary->extract_excludes = addedLibrary->extract_excludes; } - if (lib->isNative()) + if (addedLibrary->isNative()) { - // library->clearSuffixes(); - library->m_native_classifiers = lib->m_native_classifiers; - /* - for (auto native : lib->natives) - { - library->addNative(native.first, native.second); - } - */ + existingLibrary->m_native_classifiers = addedLibrary->m_native_classifiers; } - if (lib->applyRules) + if (addedLibrary->applyRules) { - library->setRules(lib->m_rules); + existingLibrary->setRules(addedLibrary->m_rules); } - library->finalize(); } else { - QLOG_WARN() << "Couldn't find" << lib->m_name << "(skipping)"; + QLOG_WARN() << "Couldn't find" << addedLibrary->rawName() << "(skipping)"; } break; } case RawLibrary::Append: case RawLibrary::Prepend: { - // QLOG_INFO() << "Adding lib " << lib->name; - const int index = findLibraryByName(version->libraries, lib->m_name); + // find the library by name. + const int index = findLibraryByName(version->libraries, addedLibrary->rawName()); + // library not found? just add it. if (index < 0) { - if (lib->insertType == RawLibrary::Append) + if (addedLibrary->insertType == RawLibrary::Append) { - version->libraries.append(OneSixLibrary::fromRawLibrary(lib)); + version->libraries.append(OneSixLibrary::fromRawLibrary(addedLibrary)); } else { - version->libraries.prepend(OneSixLibrary::fromRawLibrary(lib)); + version->libraries.prepend(OneSixLibrary::fromRawLibrary(addedLibrary)); } + break; } - else + + // otherwise apply differences, if allowed + auto existingLibrary = version->libraries.at(index); + const Util::Version addedVersion = addedLibrary->version(); + const Util::Version existingVersion = existingLibrary->version(); + // if the existing version is a hard dependency we can either use it or + // fail, but we can't change it + if (existingLibrary->dependType == OneSixLibrary::Hard) { - auto otherLib = version->libraries.at(index); - const Util::Version ourVersion = lib->m_name.version(); - const Util::Version otherVersion = otherLib->m_name.version(); - // if the existing version is a hard dependency we can either use it or - // fail, but we can't change it - if (otherLib->dependType == OneSixLibrary::Hard) + // we need a higher version, or we're hard to and the versions aren't + // equal + if (addedVersion > existingVersion || + (addedLibrary->dependType == RawLibrary::Hard && addedVersion != existingVersion)) { - // we need a higher version, or we're hard to and the versions aren't - // equal - if (ourVersion > otherVersion || - (lib->dependType == RawLibrary::Hard && ourVersion != otherVersion)) - { - throw VersionBuildError( - QObject::tr( - "Error resolving library dependencies between %1 and %2 in %3.") - .arg(otherLib->rawName(), lib->m_name, filename)); - } - else - { - // the library is already existing, so we don't have to do anything - } + throw VersionBuildError(QObject::tr( + "Error resolving library dependencies between %1 and %2 in %3.") + .arg(existingLibrary->rawName(), + addedLibrary->rawName(), filename)); + } + else + { + // the library is already existing, so we don't have to do anything } - else if (otherLib->dependType == OneSixLibrary::Soft) + } + else if (existingLibrary->dependType == OneSixLibrary::Soft) + { + // if we are higher it means we should update + if (addedVersion > existingVersion) { - // if we are higher it means we should update - if (ourVersion > otherVersion) - { - auto library = OneSixLibrary::fromRawLibrary(lib); - if (Util::Version(otherLib->minVersion) < ourVersion) - { - library->minVersion = ourVersion.toString(); - } - version->libraries.replace(index, library); - } - else + auto library = OneSixLibrary::fromRawLibrary(addedLibrary); + version->libraries.replace(index, library); + } + else + { + // our version is smaller than the existing version, but we require + // it: fail + if (addedLibrary->dependType == RawLibrary::Hard) { - // our version is smaller than the existing version, but we require - // it: fail - if (lib->dependType == RawLibrary::Hard) - { - throw VersionBuildError(QObject::tr( - "Error resolving library dependencies between %1 and %2 in %3.") - .arg(otherLib->rawName(), lib->m_name, - filename)); - } + throw VersionBuildError(QObject::tr( + "Error resolving library dependencies between %1 and %2 in %3.") + .arg(existingLibrary->rawName(), + addedLibrary->rawName(), filename)); } } } @@ -496,19 +485,19 @@ void VersionFile::applyTo(InstanceVersion *version) case RawLibrary::Replace: { GradleSpecifier toReplace; - if (lib->insertData.isEmpty()) + if (addedLibrary->insertData.isEmpty()) { - toReplace = lib->m_name; + toReplace = addedLibrary->rawName(); } else { - toReplace = lib->insertData; + toReplace = addedLibrary->insertData; } // QLOG_INFO() << "Replacing lib " << toReplace << " with " << lib->name; int index = findLibraryByName(version->libraries, toReplace); if (index >= 0) { - version->libraries.replace(index, OneSixLibrary::fromRawLibrary(lib)); + version->libraries.replace(index, OneSixLibrary::fromRawLibrary(addedLibrary)); } else { |