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:
parent
50a4a1e19e
commit
f9e186ab70
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user