GH-967 make libraries handle their own path prefix

Makes it possible to mix libraries managed by FTB and MultiMC
Backport from unstable
This commit is contained in:
Petr Mrázek 2015-05-27 01:30:18 +02:00
parent 50a4a1e19e
commit f9e186ab70
9 changed files with 82 additions and 29 deletions

View File

@ -87,8 +87,8 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr
// where do we put the library? decode the mojang path // where do we put the library? decode the mojang path
OneSixLibrary lib(libraryName); OneSixLibrary lib(libraryName);
auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.storagePath()); auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.storageSuffix());
finalPath = "libraries/" + lib.storagePath(); finalPath = "libraries/" + lib.storageSuffix();
if (!ensureFilePathExists(finalPath)) if (!ensureFilePathExists(finalPath))
return; return;

View File

@ -41,6 +41,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
} }
profile->appendPatch(minecraftPatch); profile->appendPatch(minecraftPatch);
auto nativeInstance = dynamic_cast<OneSixFTBInstance *>(m_instance);
ProfilePatchPtr packPatch; ProfilePatchPtr packPatch;
{ {
auto mcJson = m_instance->minecraftRoot() + "/pack.json"; auto mcJson = m_instance->minecraftRoot() + "/pack.json";
@ -58,6 +59,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
{ {
addLib->m_hint = "local"; addLib->m_hint = "local";
addLib->insertType = RawLibrary::Prepend; addLib->insertType = RawLibrary::Prepend;
addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
} }
file->fileId = "org.multimc.ftb.pack"; file->fileId = "org.multimc.ftb.pack";
file->setVanilla(true); file->setVanilla(true);

View File

@ -78,7 +78,7 @@ void OneSixFTBInstance::copy(const QDir &newDir)
for (auto library : libraryNames) for (auto library : libraryNames)
{ {
OneSixLibrary *lib = new OneSixLibrary(library); OneSixLibrary *lib = new OneSixLibrary(library);
const QString out = QDir::current().absoluteFilePath("libraries/" + lib->storagePath()); const QString out = QDir::current().absoluteFilePath("libraries/" + lib->storageSuffix());
if (QFile::exists(out)) if (QFile::exists(out))
{ {
continue; continue;
@ -87,7 +87,7 @@ void OneSixFTBInstance::copy(const QDir &newDir)
{ {
qCritical() << "Couldn't create folder structure for" << out; qCritical() << "Couldn't create folder structure for" << out;
} }
if (!QFile::copy(librariesPath().absoluteFilePath(lib->storagePath()), out)) if (!QFile::copy(librariesPath().absoluteFilePath(lib->storageSuffix()), out))
{ {
qCritical() << "Couldn't copy" << lib->rawName(); qCritical() << "Couldn't copy" << lib->rawName();
} }

View File

@ -139,7 +139,7 @@ BaseProcess *OneSixInstance::prepareForLaunch(AuthSessionPtr session)
auto libs = m_version->getActiveNormalLibs(); auto libs = m_version->getActiveNormalLibs();
for (auto lib : libs) for (auto lib : libs)
{ {
launchScript += "cp " + librariesPath().absoluteFilePath(lib->storagePath()) + "\n"; launchScript += "cp " + QFileInfo(lib->storagePath()).absoluteFilePath() + "\n";
} }
auto jarMods = getJarMods(); auto jarMods = getJarMods();
if (!jarMods.isEmpty()) if (!jarMods.isEmpty())
@ -191,7 +191,7 @@ BaseProcess *OneSixInstance::prepareForLaunch(AuthSessionPtr session)
QDir natives_dir(PathCombine(instanceRoot(), "natives/")); QDir natives_dir(PathCombine(instanceRoot(), "natives/"));
for (auto native : m_version->getActiveNativeLibs()) for (auto native : m_version->getActiveNativeLibs())
{ {
QFileInfo finfo(PathCombine("libraries", native->storagePath())); QFileInfo finfo(native->storagePath());
launchScript += "ext " + finfo.absoluteFilePath() + "\n"; launchScript += "ext " + finfo.absoluteFilePath() + "\n";
} }
launchScript += "natives " + natives_dir.absolutePath() + "\n"; launchScript += "natives " + natives_dir.absolutePath() + "\n";

View File

@ -29,6 +29,7 @@ OneSixLibrary::OneSixLibrary(RawLibraryPtr base)
m_native_classifiers = base->m_native_classifiers; m_native_classifiers = base->m_native_classifiers;
m_rules = base->m_rules; m_rules = base->m_rules;
dependType = base->dependType; dependType = base->dependType;
m_storagePrefix = base->m_storagePrefix;
// these only make sense for raw libraries. OneSix // these only make sense for raw libraries. OneSix
/* /*
insertType = base->insertType; insertType = base->insertType;

View File

@ -227,8 +227,8 @@ void OneSixUpdate::jarlibStart()
continue; continue;
} }
QString raw_storage = lib->storagePath(); QString raw_storage = lib->storageSuffix();
QString raw_dl = lib->downloadUrl(); QString raw_dl = lib->url().toString();
auto f = [&](QString storage, QString dl) auto f = [&](QString storage, QString dl)
{ {

View File

@ -2,6 +2,7 @@
using namespace MMCJson; using namespace MMCJson;
#include "RawLibrary.h" #include "RawLibrary.h"
#include <pathutils.h>
RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename) RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename)
{ {
@ -29,7 +30,9 @@ RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &fil
return true; return true;
}; };
readString("url", out->m_base_url); QString urlStr;
readString("url", urlStr);
out->m_base_url = urlStr;
readString("MMC-hint", out->m_hint); readString("MMC-hint", out->m_hint);
readString("MMC-absulute_url", out->m_absolute_url); readString("MMC-absulute_url", out->m_absolute_url);
readString("MMC-absoluteUrl", out->m_absolute_url); readString("MMC-absoluteUrl", out->m_absolute_url);
@ -109,7 +112,7 @@ RawLibraryPtr RawLibrary::fromJsonPlus(const QJsonObject &libObj, const QString
throw JSONValidationError("Empty compound insert rule in " + filename); throw JSONValidationError("Empty compound insert rule in " + filename);
} }
QString insertString = insertObj.keys().first(); QString insertString = insertObj.keys().first();
// really, only replace makes sense in combination with // really, only replace makes sense in combination with
if(insertString != "replace") if(insertString != "replace")
{ {
throw JSONValidationError("Compound insert rule is not 'replace' in " + filename); throw JSONValidationError("Compound insert rule is not 'replace' in " + filename);
@ -154,7 +157,7 @@ QJsonObject RawLibrary::toJson() const
m_base_url != "https://" + URLConstants::AWS_DOWNLOAD_LIBRARIES && m_base_url != "https://" + URLConstants::AWS_DOWNLOAD_LIBRARIES &&
m_base_url != "https://" + URLConstants::LIBRARY_BASE && !m_base_url.isEmpty()) m_base_url != "https://" + URLConstants::LIBRARY_BASE && !m_base_url.isEmpty())
{ {
libRoot.insert("url", m_base_url); libRoot.insert("url", m_base_url.toString());
} }
if (isNative()) if (isNative())
{ {
@ -194,7 +197,7 @@ QJsonObject RawLibrary::toJson() const
QStringList RawLibrary::files() const QStringList RawLibrary::files() const
{ {
QStringList retval; QStringList retval;
QString storage = storagePath(); QString storage = storageSuffix();
if (storage.contains("${arch}")) if (storage.contains("${arch}"))
{ {
QString cooked_storage = storage; QString cooked_storage = storage;
@ -221,17 +224,19 @@ bool RawLibrary::filesExist(const QDir &base) const
} }
return true; return true;
} }
QString RawLibrary::downloadUrl() const QUrl RawLibrary::url() const
{ {
if (m_absolute_url.size()) if (!m_absolute_url.isEmpty())
{
return m_absolute_url; return m_absolute_url;
}
if (m_base_url.isEmpty()) if (m_base_url.isEmpty())
{ {
return QString("https://" + URLConstants::LIBRARY_BASE) + storagePath(); return QString("https://" + URLConstants::LIBRARY_BASE) + storageSuffix();
} }
return m_base_url + storagePath(); return m_base_url.resolved(storageSuffix());
} }
bool RawLibrary::isActive() const bool RawLibrary::isActive() const
@ -259,7 +264,26 @@ bool RawLibrary::isActive() const
return result; return result;
} }
QString RawLibrary::storagePath() const void RawLibrary::setStoragePrefix(QString prefix)
{
m_storagePrefix = prefix;
}
QString RawLibrary::defaultStoragePrefix()
{
return "libraries/";
}
QString RawLibrary::storagePrefix() const
{
if(m_storagePrefix.isEmpty())
{
return defaultStoragePrefix();
}
return m_storagePrefix;
}
QString RawLibrary::storageSuffix() const
{ {
// non-native? use only the gradle specifier // non-native? use only the gradle specifier
if (!isNative()) if (!isNative())
@ -269,7 +293,7 @@ QString RawLibrary::storagePath() const
// otherwise native, override classifiers. Mojang HACK! // otherwise native, override classifiers. Mojang HACK!
GradleSpecifier nativeSpec = m_name; GradleSpecifier nativeSpec = m_name;
if(m_native_classifiers.contains(currentSystem)) if (m_native_classifiers.contains(currentSystem))
{ {
nativeSpec.setClassifier(m_native_classifiers[currentSystem]); nativeSpec.setClassifier(m_native_classifiers[currentSystem]);
} }
@ -279,3 +303,13 @@ QString RawLibrary::storagePath() const
} }
return nativeSpec.toPath(); return nativeSpec.toPath();
} }
QString RawLibrary::storagePath() const
{
return PathCombine(storagePrefix(), storageSuffix());
}
bool RawLibrary::storagePathIsDefault() const
{
return m_storagePrefix.isEmpty();
}

View File

@ -5,6 +5,7 @@
#include <QStringList> #include <QStringList>
#include <QMap> #include <QMap>
#include <QDir> #include <QDir>
#include <QUrl>
#include <memory> #include <memory>
#include "minecraft/OneSixRule.h" #include "minecraft/OneSixRule.h"
@ -33,7 +34,7 @@ public: /* methods */
{ {
return m_name; return m_name;
} }
void setRawName(const GradleSpecifier & spec) void setRawName(const GradleSpecifier & spec)
{ {
m_name = spec; m_name = spec;
@ -43,7 +44,7 @@ public: /* methods */
{ {
m_name.setClassifier(spec); m_name.setClassifier(spec);
} }
/// returns the full group and artifact prefix /// returns the full group and artifact prefix
QString artifactPrefix() const QString artifactPrefix() const
{ {
@ -68,8 +69,24 @@ public: /* methods */
return m_native_classifiers.size() != 0; return m_native_classifiers.size() != 0;
} }
void setStoragePrefix(QString prefix = QString());
/// the default storage prefix used by MultiMC
static QString defaultStoragePrefix();
bool storagePathIsDefault() const;
/// 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() const;
/// Get the absolute path where the library should be saved
QString storagePath() const;
/// Set the url base for downloads /// Set the url base for downloads
void setBaseUrl(const QString &base_url) void setBaseUrl(const QUrl &base_url)
{ {
m_base_url = base_url; m_base_url = base_url;
} }
@ -110,11 +127,7 @@ public: /* methods */
bool isActive() const; bool isActive() const;
/// Get the URL to download the library from /// Get the URL to download the library from
QString downloadUrl() const; QUrl url() const;
/// Get the relative path where the library should be saved
QString storagePath() const;
protected: /* data */ protected: /* data */
/// the basic gradle dependency specifier. /// the basic gradle dependency specifier.
@ -128,7 +141,7 @@ protected: /* data */
public: /* data */ public: /* data */
// TODO: make all of these protected, clean up semantics of implicit vs. explicit values. // TODO: make all of these protected, clean up semantics of implicit vs. explicit values.
/// URL where the file can be downloaded /// URL where the file can be downloaded
QString m_base_url; QUrl m_base_url;
/// DEPRECATED: absolute URL. takes precedence the normal download URL, if defined /// DEPRECATED: absolute URL. takes precedence the normal download URL, if defined
QString m_absolute_url; QString m_absolute_url;
@ -136,6 +149,9 @@ public: /* data */
/// type hint - modifies how the library is treated /// type hint - modifies how the library is treated
QString m_hint; QString m_hint;
/// storage - by default the local libraries folder in multimc, but could be elsewhere
QString m_storagePrefix;
/// true if the library had an extract/excludes section (even empty) /// true if the library had an extract/excludes section (even empty)
bool applyExcludes = false; bool applyExcludes = false;
@ -160,7 +176,7 @@ public: /* data */
Replace Replace
} insertType = Append; } insertType = Append;
QString insertData; QString insertData;
/// determines how can libraries be applied. conflicting dependencies cause errors. /// determines how can libraries be applied. conflicting dependencies cause errors.
enum DependType enum DependType
{ {

View File

@ -369,7 +369,7 @@ void VersionFile::applyTo(MinecraftProfile *version)
if (index >= 0) if (index >= 0)
{ {
auto existingLibrary = version->libraries[index]; auto existingLibrary = version->libraries[index];
if (!addedLibrary->m_base_url.isNull()) if (!addedLibrary->m_base_url.isEmpty())
{ {
existingLibrary->setBaseUrl(addedLibrary->m_base_url); existingLibrary->setBaseUrl(addedLibrary->m_base_url);
} }