diff options
Diffstat (limited to 'libmultimc')
-rw-r--r-- | libmultimc/include/fullversion.h | 73 | ||||
-rw-r--r-- | libmultimc/include/instance.h | 1 | ||||
-rw-r--r-- | libmultimc/include/instancelist.h | 6 | ||||
-rw-r--r-- | libmultimc/include/instanceloader.h | 32 | ||||
-rw-r--r-- | libmultimc/include/instancetypeinterface.h | 94 | ||||
-rw-r--r-- | libmultimc/include/library.h | 81 | ||||
-rw-r--r-- | libmultimc/src/fullversion.cpp | 26 | ||||
-rw-r--r-- | libmultimc/src/instancelist.cpp | 240 | ||||
-rw-r--r-- | libmultimc/src/instanceloader.cpp | 10 | ||||
-rw-r--r-- | libmultimc/src/library.cpp | 44 |
10 files changed, 289 insertions, 318 deletions
diff --git a/libmultimc/include/fullversion.h b/libmultimc/include/fullversion.h index 523ac87c..8547960f 100644 --- a/libmultimc/include/fullversion.h +++ b/libmultimc/include/fullversion.h @@ -6,64 +6,71 @@ class Library; class FullVersion { public: - FullVersion() - { - minimumLauncherVersion = 0xDEADBEEF; - isLegacy = false; - } - // the ID - determines which jar to use! ACTUALLY IMPORTANT! + /// the ID - determines which jar to use! ACTUALLY IMPORTANT! QString id; - // do we actually care about parsing this? + /// Last updated time - as a string QString time; - // I don't think we do. + /// Release time - as a string QString releaseTime; - // eh, not caring - "release" or "snapshot" + /// Release type - "release" or "snapshot" QString type; - /* + /** * DEPRECATED: Old versions of the new vanilla launcher used this * ex: "username_session_version" */ QString processArguments; - /* + /** * arguments that should be used for launching minecraft * * ex: "--username ${auth_player_name} --session ${auth_session} * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}" */ QString minecraftArguments; - /* + /** * the minimum launcher version required by this version ... current is 4 (at point of writing) */ int minimumLauncherVersion; - /* + /** * The main class to load first */ QString mainClass; - // the list of libs. just the names for now. expand to full-blown strutures! + /// the list of libs - both active and inactive, native and java QList<QSharedPointer<Library> > libraries; - // is this actually a legacy version? if so, none of the other stuff here will be ever used. - // added by FullVersionFactory + /** + * is this actually a legacy version? if so, none of the other stuff here will be ever used. + * added by FullVersionFactory + */ bool isLegacy; -/* -FIXME: add support for those rules here? Looks like a pile of quick hacks to me though. + /* + FIXME: add support for those rules here? Looks like a pile of quick hacks to me though. - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx", - "version": "^10\\.5\\.\\d$" - } - } - ], - "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!" -} -*/ + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx", + "version": "^10\\.5\\.\\d$" + } + } + ], + "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!" + } + */ // QList<Rule> rules; + +public: + FullVersion() + { + minimumLauncherVersion = 0xDEADBEEF; + isLegacy = false; + } + + QList<QSharedPointer<Library> > getActiveNormalLibs(); + QList<QSharedPointer<Library> > getActiveNativeLibs(); };
\ No newline at end of file diff --git a/libmultimc/include/instance.h b/libmultimc/include/instance.h index f6857cd8..36db7ffb 100644 --- a/libmultimc/include/instance.h +++ b/libmultimc/include/instance.h @@ -22,7 +22,6 @@ #include <settingsobject.h> #include "inifile.h" -#include "instancetypeinterface.h" #include "instversionlist.h" #include "libmmc_config.h" diff --git a/libmultimc/include/instancelist.h b/libmultimc/include/instancelist.h index a0d8788a..bd8d0627 100644 --- a/libmultimc/include/instancelist.h +++ b/libmultimc/include/instancelist.h @@ -27,6 +27,12 @@ class Instance; class LIBMULTIMC_EXPORT InstanceList : public QObject { Q_OBJECT +private: + /*! + * \brief Get the instance groups + */ + void loadGroupList(QMap<QString, QString> & groupList); + public: explicit InstanceList(const QString &instDir, QObject *parent = 0); diff --git a/libmultimc/include/instanceloader.h b/libmultimc/include/instanceloader.h index fd6d04d6..af5bf92d 100644 --- a/libmultimc/include/instanceloader.h +++ b/libmultimc/include/instanceloader.h @@ -36,22 +36,18 @@ public: */ static InstanceLoader &get() { return loader; } - /*! - * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes. - * - * - NoError indicates that no error occurred. - * - OtherError indicates that an unspecified error occurred. - * - InstExists is returned by createInstance() if the given instance directory is already an instance. - * - NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. - * - CantCreateDir is returned by createInstance( if the given instance directory can't be created.) - */ - enum InstLoaderError + enum InstLoadError + { + NoLoadError = 0, + UnknownLoadError, + NotAnInstance + }; + + enum InstCreateError { - NoError = 0, - OtherError, - + NoCreateError = 0, + UnknownCreateError, InstExists, - NotAnInstance, CantCreateDir }; @@ -61,21 +57,21 @@ public: * \param inst Pointer to store the created instance in. * \param type The type of instance to create. * \param instDir The instance's directory. - * \return An InstLoaderError error code. + * \return An InstCreateError error code. * - InstExists if the given instance directory is already an instance. * - CantCreateDir if the given instance directory cannot be created. */ - InstLoaderError createInstance(Instance *&inst, const QString &instDir); + InstCreateError createInstance(Instance *&inst, const QString &instDir); /*! * \brief Loads an instance from the given directory. * Checks the instance's INI file to figure out what the instance's type is first. * \param inst Pointer to store the loaded instance in. * \param instDir The instance's directory. - * \return An InstLoaderError error code. + * \return An InstLoadError error code. * - NotAnInstance if the given instance directory isn't a valid instance. */ - InstLoaderError loadInstance(Instance *&inst, const QString &instDir); + InstLoadError loadInstance(Instance *&inst, const QString &instDir); private: InstanceLoader(); diff --git a/libmultimc/include/instancetypeinterface.h b/libmultimc/include/instancetypeinterface.h deleted file mode 100644 index 4fbc2593..00000000 --- a/libmultimc/include/instancetypeinterface.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef INSTANCETYPE_H -#define INSTANCETYPE_H - -#include <QObject> - -#include "instanceloader.h" - -class InstVersionList; - -//! The InstanceTypeInterface's interface ID. -#define InstanceTypeInterface_IID "net.forkk.MultiMC.InstanceTypeInterface/0.1" - -/*! - * \brief The InstanceType class is an interface for all instance types. - * InstanceTypes are usually provided by plugins. - * It handles loading and creating instances of a certain type. There should be - * one of these for each type of instance and they should be registered with the - * InstanceLoader. - * To create an instance, the InstanceLoader calls the type's createInstance() - * function. Loading is done through the loadInstance() function. - */ -class InstanceTypeInterface -{ -public: - friend class InstanceLoader; - - /*! - * \brief Gets the ID for this instance type. - * The type ID should be unique as it is used to identify the type - * of instances when they are loaded. - * Changing this value at runtime results in undefined behavior. - * \return This instance type's ID string. - */ - virtual QString typeID() const = 0; - - /*! - * \brief Gets the name of this instance type as it is displayed to the user. - * \return The instance type's display name. - */ - virtual QString displayName() const = 0; - - /*! - * \brief Gets a longer, more detailed description of this instance type. - * \return The instance type's description. - */ - virtual QString description() const = 0; - - /*! - * \brief Gets the version list for this instance type. - * \return A pointer to this instance type's version list. - */ - virtual InstVersionList *versionList() const = 0; - -protected: - /*! - * \brief Creates an instance and stores it in inst. - * \param inst Pointer to store the created instance in. - * \param instDir The instance's directory. - * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * InstExists if the given instance directory is already an instance. - */ - virtual InstanceLoader::InstLoaderError createInstance(Instance *&inst, const QString &instDir) const = 0; - - /*! - * \brief Loads an instance from the given directory. - * \param inst Pointer to store the loaded instance in. - * \param instDir The instance's directory. - * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * NotAnInstance if the given instance directory isn't a valid instance. - * WrongInstType if the given instance directory's type isn't an instance of this type. - */ - virtual InstanceLoader::InstLoaderError loadInstance(Instance *&inst, const QString &instDir) const = 0; -}; - -Q_DECLARE_INTERFACE(InstanceTypeInterface, InstanceTypeInterface_IID) - -#endif // INSTANCETYPE_H diff --git a/libmultimc/include/library.h b/libmultimc/include/library.h index 8d97b4a6..ed377ddd 100644 --- a/libmultimc/include/library.h +++ b/libmultimc/include/library.h @@ -133,51 +133,7 @@ public: QStringList extract_excludes; public: - /// finalize the library, processing the input values into derived values and state - void finalize() - { - QStringList parts = m_name.split(':'); - QString relative = parts[0]; - relative.replace('.','/'); - relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2]; - if(!m_is_native) - relative += ".jar"; - else - { - if(m_native_suffixes.contains(currentSystem)) - { - relative += "-" + m_native_suffixes[currentSystem] + ".jar"; - } - else - { - // really, bad. - relative += ".jar"; - } - } - m_storage_path = relative; - m_download_path = m_base_url + 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(m_is_native) - { - m_is_active = m_is_active && m_native_suffixes.contains(currentSystem); - } - }; - + /// Constructor Library(QString name) { m_is_native = false; @@ -186,34 +142,67 @@ public: m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/"; } + /** + * 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(QString name) { m_name = name; } + /** + * Set the url base for downloads + */ void setBaseUrl(QString base_url) { m_base_url = base_url; } + /** + * Call this to mark the library as 'native' (it's a zip archive with DLLs) + */ void setIsNative() { m_is_native = true; } + /** + * Attach a name suffix to the specified OS native + */ void addNative(OpSys os, QString suffix) { m_is_native = true; m_native_suffixes[os] = suffix; } + /** + * Set the load rules + */ void setRules(QList<QSharedPointer<Rule> > rules) { m_rules = rules; } - bool applies() + /** + * Returns true if the library should be loaded (or extracted, in case of natives) + */ + bool getIsActive() { return m_is_active; } + /** + * Returns true if the library is native + */ + bool getIsNative() + { + return m_is_native; + } }; diff --git a/libmultimc/src/fullversion.cpp b/libmultimc/src/fullversion.cpp index 53664c2a..24047c9f 100644 --- a/libmultimc/src/fullversion.cpp +++ b/libmultimc/src/fullversion.cpp @@ -2,4 +2,28 @@ #include "fullversion.h" #include <library.h> -// ECHO, echo, echo, ....
\ No newline at end of file +QList<QSharedPointer<Library> > FullVersion::getActiveNormalLibs() +{ + QList<QSharedPointer<Library> > output; + for ( auto lib: libraries ) + { + if (lib->getIsActive() && !lib->getIsNative()) + { + output.append(lib); + } + } + return output; +} + +QList<QSharedPointer<Library> > FullVersion::getActiveNativeLibs() +{ + QList<QSharedPointer<Library> > output; + for ( auto lib: libraries ) + { + if (lib->getIsActive() && lib->getIsNative()) + { + output.append(lib); + } + } + return output; +} diff --git a/libmultimc/src/instancelist.cpp b/libmultimc/src/instancelist.cpp index 6f5a9f99..1a7dc10d 100644 --- a/libmultimc/src/instancelist.cpp +++ b/libmultimc/src/instancelist.cpp @@ -37,152 +37,152 @@ InstanceList::InstanceList(const QString &instDir, QObject *parent) : } -InstanceList::InstListError InstanceList::loadList() +void InstanceList::loadGroupList(QMap<QString, QString> & groupMap) { - QDir dir(m_instDir); - QDirIterator iter(dir); - QString groupFileName = m_instDir + "/instgroups.json"; - // temporary map from instance ID to group name - QMap<QString, QString> groupMap; - // HACK: this is really an if. breaks after one iteration. - while (QFileInfo(groupFileName).exists()) + // if there's no group file, fail + if(!QFileInfo(groupFileName).exists()) + return; + + QFile groupFile(groupFileName); + + // if you can't open the file, fail + if (!groupFile.open(QIODevice::ReadOnly)) { - QFile groupFile(groupFileName); - - if (!groupFile.open(QIODevice::ReadOnly)) - { - // An error occurred. Ignore it. - qDebug("Failed to read instance group file."); - break; - } - - QTextStream in(&groupFile); - QString jsonStr = in.readAll(); - groupFile.close(); + // An error occurred. Ignore it. + qDebug("Failed to read instance group file."); + return; + } + + QTextStream in(&groupFile); + QString jsonStr = in.readAll(); + groupFile.close(); + + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error); + + // if the json was bad, fail + if (error.error != QJsonParseError::NoError) + { + qWarning(QString("Failed to parse instance group file: %1 at offset %2"). + arg(error.errorString(), QString::number(error.offset)).toUtf8()); + return; + } + + // if the root of the json wasn't an object, fail + if (!jsonDoc.isObject()) + { + qWarning("Invalid group file. Root entry should be an object."); + return; + } + + QJsonObject rootObj = jsonDoc.object(); + + // Make sure the format version matches, otherwise fail. + if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION) + return; + + // Get the groups. if it's not an object, fail + if (!rootObj.value("groups").isObject()) + { + qWarning("Invalid group list JSON: 'groups' should be an object."); + return; + } - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error); + // Iterate through all the groups. + QJsonObject groupMapping = rootObj.value("groups").toObject(); + for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++) + { + QString groupName = iter.key(); - if (error.error != QJsonParseError::NoError) + // If not an object, complain and skip to the next one. + if (!iter.value().isObject()) { - qWarning(QString("Failed to parse instance group file: %1 at offset %2"). - arg(error.errorString(), QString::number(error.offset)).toUtf8()); - break; + qWarning(QString("Group '%1' in the group list should " + "be an object.").arg(groupName).toUtf8()); + continue; } - if (!jsonDoc.isObject()) + QJsonObject groupObj = iter.value().toObject(); + if (!groupObj.value("instances").isArray()) { - qWarning("Invalid group file. Root entry should be an object."); - break; + qWarning(QString("Group '%1' in the group list is invalid. " + "It should contain an array " + "called 'instances'.").arg(groupName).toUtf8()); + continue; } - QJsonObject rootObj = jsonDoc.object(); + // Iterate through the list of instances in the group. + QJsonArray instancesArray = groupObj.value("instances").toArray(); - // Make sure the format version matches. - if (rootObj.value("formatVersion").toVariant().toInt() == GROUP_FILE_FORMAT_VERSION) + for (QJsonArray::iterator iter2 = instancesArray.begin(); + iter2 != instancesArray.end(); iter2++) { - // Get the group list. - if (!rootObj.value("groups").isObject()) - { - qWarning("Invalid group list JSON: 'groups' should be an object."); - break; - } - - // Iterate through the list. - QJsonObject groupList = rootObj.value("groups").toObject(); - - for (QJsonObject::iterator iter = groupList.begin(); - iter != groupList.end(); iter++) - { - QString groupName = iter.key(); - - // If not an object, complain and skip to the next one. - if (!iter.value().isObject()) - { - qWarning(QString("Group '%1' in the group list should " - "be an object.").arg(groupName).toUtf8()); - continue; - } - - QJsonObject groupObj = iter.value().toObject(); - /* - // Create the group object. - InstanceGroup *group = new InstanceGroup(groupName, this); - groups.push_back(group); - - // If 'hidden' isn't a bool value, just assume it's false. - if (groupObj.value("hidden").isBool() && groupObj.value("hidden").toBool()) - { - group->setHidden(groupObj.value("hidden").toBool()); - } - */ - - if (!groupObj.value("instances").isArray()) - { - qWarning(QString("Group '%1' in the group list is invalid. " - "It should contain an array " - "called 'instances'.").arg(groupName).toUtf8()); - continue; - } - - // Iterate through the list of instances in the group. - QJsonArray instancesArray = groupObj.value("instances").toArray(); - - for (QJsonArray::iterator iter2 = instancesArray.begin(); - iter2 != instancesArray.end(); iter2++) - { - groupMap[(*iter2).toString()] = groupName; - } - } + groupMap[(*iter2).toString()] = groupName; } - break; } +} + +InstanceList::InstListError InstanceList::loadList() +{ + // load the instance groups + QMap<QString, QString> groupMap; + loadGroupList(groupMap); + m_instances.clear(); + QDir dir(m_instDir); + QDirIterator iter(dir); while (iter.hasNext()) { QString subDir = iter.next(); - if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) + if (!QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) + continue; + + Instance *instPtr = NULL; + auto &loader = InstanceLoader::get(); + auto error = loader.loadInstance(instPtr, subDir); + + switch(error) { - Instance *instPtr = NULL; - - InstanceLoader::InstLoaderError error = InstanceLoader::get(). - loadInstance(instPtr, subDir); + case InstanceLoader::NoLoadError: + break; + case InstanceLoader::NotAnInstance: + break; + } + + if (error != InstanceLoader::NoLoadError && + error != InstanceLoader::NotAnInstance) + { + QString errorMsg = QString("Failed to load instance %1: "). + arg(QFileInfo(subDir).baseName()).toUtf8(); - if (error != InstanceLoader::NoError && - error != InstanceLoader::NotAnInstance) + switch (error) { - QString errorMsg = QString("Failed to load instance %1: "). - arg(QFileInfo(subDir).baseName()).toUtf8(); - - switch (error) - { - default: - errorMsg += QString("Unknown instance loader error %1"). - arg(error); - break; - } - qDebug(errorMsg.toUtf8()); - } - else if (!instPtr) - { - qDebug(QString("Error loading instance %1. Instance loader returned null."). - arg(QFileInfo(subDir).baseName()).toUtf8()); + default: + errorMsg += QString("Unknown instance loader error %1"). + arg(error); + break; } - else + qDebug(errorMsg.toUtf8()); + } + else if (!instPtr) + { + qDebug(QString("Error loading instance %1. Instance loader returned null."). + arg(QFileInfo(subDir).baseName()).toUtf8()); + } + else + { + QSharedPointer<Instance> inst(instPtr); + auto iter = groupMap.find(inst->id()); + if(iter != groupMap.end()) { - QSharedPointer<Instance> inst(instPtr); - auto iter = groupMap.find(inst->id()); - if(iter != groupMap.end()) - { - inst->setGroup((*iter)); - } - qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); - inst->setParent(this); - m_instances.append(inst); - connect(instPtr, SIGNAL(propertiesChanged(Instance*)),this, SLOT(propertiesChanged(Instance*))); + inst->setGroup((*iter)); } + qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); + inst->setParent(this); + m_instances.append(inst); + connect(instPtr, SIGNAL(propertiesChanged(Instance*)),this, SLOT(propertiesChanged(Instance*))); } } emit invalidated(); diff --git a/libmultimc/src/instanceloader.cpp b/libmultimc/src/instanceloader.cpp index e9924af4..e30435a9 100644 --- a/libmultimc/src/instanceloader.cpp +++ b/libmultimc/src/instanceloader.cpp @@ -32,8 +32,7 @@ InstanceLoader::InstanceLoader() : } -InstanceLoader::InstLoaderError InstanceLoader::loadInstance( - Instance *&inst, const QString &instDir) +InstanceLoader::InstLoadError InstanceLoader::loadInstance(Instance *&inst, const QString &instDir) { Instance *loadedInst = new Instance(instDir, this); @@ -41,11 +40,11 @@ InstanceLoader::InstLoaderError InstanceLoader::loadInstance( inst = loadedInst; - return NoError; + return NoLoadError; } -InstanceLoader::InstLoaderError InstanceLoader::createInstance(Instance *&inst, const QString &instDir) +InstanceLoader::InstCreateError InstanceLoader::createInstance(Instance *&inst, const QString &instDir) { QDir rootDir(instDir); @@ -57,5 +56,6 @@ InstanceLoader::InstLoaderError InstanceLoader::createInstance(Instance *&inst, inst = new Instance(instDir, this); - return InstanceLoader::NoError; + //FIXME: really, how do you even know? + return InstanceLoader::NoCreateError; } diff --git a/libmultimc/src/library.cpp b/libmultimc/src/library.cpp index 9d4cc6e3..691786e8 100644 --- a/libmultimc/src/library.cpp +++ b/libmultimc/src/library.cpp @@ -34,4 +34,48 @@ OpSys OpSys_fromString(QString name) return Os_OSX; return Os_Other; } + +void Library::finalize() +{ + QStringList parts = m_name.split ( ':' ); + QString relative = parts[0]; + relative.replace ( '.','/' ); + relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2]; + if ( !m_is_native ) + relative += ".jar"; + else + { + if ( m_native_suffixes.contains ( currentSystem ) ) + { + relative += "-" + m_native_suffixes[currentSystem] + ".jar"; + } + else + { + // really, bad. + relative += ".jar"; + } + } + m_storage_path = relative; + m_download_path = m_base_url + 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 ( m_is_native ) + { + m_is_active = m_is_active && m_native_suffixes.contains ( currentSystem ); + } +} // default url for lib: |