309 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "Library.h"
 | 
						|
#include "MinecraftInstance.h"
 | 
						|
 | 
						|
#include <net/Download.h>
 | 
						|
#include <net/ChecksumValidator.h>
 | 
						|
#include <FileSystem.h>
 | 
						|
#include <BuildConfig.h>
 | 
						|
 | 
						|
 | 
						|
void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& native, QStringList& native32,
 | 
						|
                                 QStringList& native64, const QString &overridePath) const
 | 
						|
{
 | 
						|
    bool local = isLocal();
 | 
						|
    auto actualPath = [&](QString relPath)
 | 
						|
    {
 | 
						|
        QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
 | 
						|
        if(local && !overridePath.isEmpty())
 | 
						|
        {
 | 
						|
            QString fileName = out.fileName();
 | 
						|
            return QFileInfo(FS::PathCombine(overridePath, fileName)).absoluteFilePath();
 | 
						|
        }
 | 
						|
        return out.absoluteFilePath();
 | 
						|
    };
 | 
						|
    QString raw_storage = storageSuffix(system);
 | 
						|
    if(isNative())
 | 
						|
    {
 | 
						|
        if (raw_storage.contains("${arch}"))
 | 
						|
        {
 | 
						|
            auto nat32Storage = raw_storage;
 | 
						|
            nat32Storage.replace("${arch}", "32");
 | 
						|
            auto nat64Storage = raw_storage;
 | 
						|
            nat64Storage.replace("${arch}", "64");
 | 
						|
            native32 += actualPath(nat32Storage);
 | 
						|
            native64 += actualPath(nat64Storage);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            native += actualPath(raw_storage);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        jar += actualPath(raw_storage);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
QList<NetAction::Ptr> Library::getDownloads(
 | 
						|
    OpSys system,
 | 
						|
    class HttpMetaCache* cache,
 | 
						|
    QStringList& failedLocalFiles,
 | 
						|
    const QString & overridePath
 | 
						|
) const
 | 
						|
{
 | 
						|
    QList<NetAction::Ptr> out;
 | 
						|
    bool stale = isAlwaysStale();
 | 
						|
    bool local = isLocal();
 | 
						|
 | 
						|
    auto check_local_file = [&](QString storage)
 | 
						|
    {
 | 
						|
        QFileInfo fileinfo(storage);
 | 
						|
        QString fileName = fileinfo.fileName();
 | 
						|
        auto fullPath = FS::PathCombine(overridePath, fileName);
 | 
						|
        QFileInfo localFileInfo(fullPath);
 | 
						|
        if(!localFileInfo.exists())
 | 
						|
        {
 | 
						|
            failedLocalFiles.append(localFileInfo.filePath());
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    };
 | 
						|
 | 
						|
    auto add_download = [&](QString storage, QString url, QString sha1)
 | 
						|
    {
 | 
						|
        if(local)
 | 
						|
        {
 | 
						|
            return check_local_file(storage);
 | 
						|
        }
 | 
						|
        auto entry = cache->resolveEntry("libraries", storage);
 | 
						|
        if(stale)
 | 
						|
        {
 | 
						|
            entry->setStale(true);
 | 
						|
        }
 | 
						|
        if (!entry->isStale())
 | 
						|
            return true;
 | 
						|
        Net::Download::Options options;
 | 
						|
        if(stale)
 | 
						|
        {
 | 
						|
            options |= Net::Download::Option::AcceptLocalFiles;
 | 
						|
        }
 | 
						|
 | 
						|
        if(sha1.size())
 | 
						|
        {
 | 
						|
            auto rawSha1 = QByteArray::fromHex(sha1.toLatin1());
 | 
						|
            auto dl = Net::Download::makeCached(url, entry, options);
 | 
						|
            dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
 | 
						|
            qDebug() << "Checksummed Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url;
 | 
						|
            out.append(dl);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            out.append(Net::Download::makeCached(url, entry, options));
 | 
						|
            qDebug() << "Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url;
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    };
 | 
						|
 | 
						|
    QString raw_storage = storageSuffix(system);
 | 
						|
    if(m_mojangDownloads)
 | 
						|
    {
 | 
						|
        if(isNative())
 | 
						|
        {
 | 
						|
            if(m_nativeClassifiers.contains(system))
 | 
						|
            {
 | 
						|
                auto nativeClassifier = m_nativeClassifiers[system];
 | 
						|
                if(nativeClassifier.contains("${arch}"))
 | 
						|
                {
 | 
						|
                    auto nat32Classifier = nativeClassifier;
 | 
						|
                    nat32Classifier.replace("${arch}", "32");
 | 
						|
                    auto nat64Classifier = nativeClassifier;
 | 
						|
                    nat64Classifier.replace("${arch}", "64");
 | 
						|
                    auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
 | 
						|
                    if(nat32info)
 | 
						|
                    {
 | 
						|
                        auto cooked_storage = raw_storage;
 | 
						|
                        cooked_storage.replace("${arch}", "32");
 | 
						|
                        add_download(cooked_storage, nat32info->url, nat32info->sha1);
 | 
						|
                    }
 | 
						|
                    auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
 | 
						|
                    if(nat64info)
 | 
						|
                    {
 | 
						|
                        auto cooked_storage = raw_storage;
 | 
						|
                        cooked_storage.replace("${arch}", "64");
 | 
						|
                        add_download(cooked_storage, nat64info->url, nat64info->sha1);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier);
 | 
						|
                    if(info)
 | 
						|
                    {
 | 
						|
                        add_download(raw_storage, info->url, info->sha1);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                qDebug() << "Ignoring native library" << m_name.serialize() << "because it has no classifier for current OS";
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if(m_mojangDownloads->artifact)
 | 
						|
            {
 | 
						|
                auto artifact = m_mojangDownloads->artifact;
 | 
						|
                add_download(raw_storage, artifact->url, artifact->sha1);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                qDebug() << "Ignoring java library" << m_name.serialize() << "because it has no artifact";
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        auto raw_dl = [&]()
 | 
						|
        {
 | 
						|
            if (!m_absoluteURL.isEmpty())
 | 
						|
            {
 | 
						|
                return m_absoluteURL;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_repositoryURL.isEmpty())
 | 
						|
            {
 | 
						|
                return BuildConfig.LIBRARY_BASE + raw_storage;
 | 
						|
            }
 | 
						|
 | 
						|
            if(m_repositoryURL.endsWith('/'))
 | 
						|
            {
 | 
						|
                return m_repositoryURL + raw_storage;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                return m_repositoryURL + QChar('/') + raw_storage;
 | 
						|
            }
 | 
						|
        }();
 | 
						|
        if (raw_storage.contains("${arch}"))
 | 
						|
        {
 | 
						|
            QString cooked_storage = raw_storage;
 | 
						|
            QString cooked_dl = raw_dl;
 | 
						|
            add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"), QString());
 | 
						|
            cooked_storage = raw_storage;
 | 
						|
            cooked_dl = raw_dl;
 | 
						|
            add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"), QString());
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            add_download(raw_storage, raw_dl, QString());
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return out;
 | 
						|
}
 | 
						|
 | 
						|
bool Library::isActive() const
 | 
						|
{
 | 
						|
    bool result = true;
 | 
						|
    if (m_rules.empty())
 | 
						|
    {
 | 
						|
        result = true;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        RuleAction ruleResult = Disallow;
 | 
						|
        for (auto rule : m_rules)
 | 
						|
        {
 | 
						|
            RuleAction temp = rule->apply(this);
 | 
						|
            if (temp != Defer)
 | 
						|
                ruleResult = temp;
 | 
						|
        }
 | 
						|
        result = result && (ruleResult == Allow);
 | 
						|
    }
 | 
						|
    if (isNative())
 | 
						|
    {
 | 
						|
        result = result && m_nativeClassifiers.contains(currentSystem);
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
bool Library::isLocal() const
 | 
						|
{
 | 
						|
    return m_hint == "local";
 | 
						|
}
 | 
						|
 | 
						|
bool Library::isAlwaysStale() const
 | 
						|
{
 | 
						|
    return m_hint == "always-stale";
 | 
						|
}
 | 
						|
 | 
						|
void Library::setStoragePrefix(QString prefix)
 | 
						|
{
 | 
						|
    m_storagePrefix = prefix;
 | 
						|
}
 | 
						|
 | 
						|
QString Library::defaultStoragePrefix()
 | 
						|
{
 | 
						|
    return "libraries/";
 | 
						|
}
 | 
						|
 | 
						|
QString Library::storagePrefix() const
 | 
						|
{
 | 
						|
    if(m_storagePrefix.isEmpty())
 | 
						|
    {
 | 
						|
        return defaultStoragePrefix();
 | 
						|
    }
 | 
						|
    return m_storagePrefix;
 | 
						|
}
 | 
						|
 | 
						|
QString Library::filename(OpSys system) const
 | 
						|
{
 | 
						|
    if(!m_filename.isEmpty())
 | 
						|
    {
 | 
						|
        return m_filename;
 | 
						|
    }
 | 
						|
    // non-native? use only the gradle specifier
 | 
						|
    if (!isNative())
 | 
						|
    {
 | 
						|
        return m_name.getFileName();
 | 
						|
    }
 | 
						|
 | 
						|
    // otherwise native, override classifiers. Mojang HACK!
 | 
						|
    GradleSpecifier nativeSpec = m_name;
 | 
						|
    if (m_nativeClassifiers.contains(system))
 | 
						|
    {
 | 
						|
        nativeSpec.setClassifier(m_nativeClassifiers[system]);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        nativeSpec.setClassifier("INVALID");
 | 
						|
    }
 | 
						|
    return nativeSpec.getFileName();
 | 
						|
}
 | 
						|
 | 
						|
QString Library::displayName(OpSys system) const
 | 
						|
{
 | 
						|
    if(!m_displayname.isEmpty())
 | 
						|
        return m_displayname;
 | 
						|
    return filename(system);
 | 
						|
}
 | 
						|
 | 
						|
QString Library::storageSuffix(OpSys system) const
 | 
						|
{
 | 
						|
    // non-native? use only the gradle specifier
 | 
						|
    if (!isNative())
 | 
						|
    {
 | 
						|
        return m_name.toPath(m_filename);
 | 
						|
    }
 | 
						|
 | 
						|
    // otherwise native, override classifiers. Mojang HACK!
 | 
						|
    GradleSpecifier nativeSpec = m_name;
 | 
						|
    if (m_nativeClassifiers.contains(system))
 | 
						|
    {
 | 
						|
        nativeSpec.setClassifier(m_nativeClassifiers[system]);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        nativeSpec.setClassifier("INVALID");
 | 
						|
    }
 | 
						|
    return nativeSpec.toPath(m_filename);
 | 
						|
}
 |