diff options
author | Petr Mrázek <peterix@gmail.com> | 2016-10-03 00:55:54 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2016-10-26 18:21:24 +0200 |
commit | d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5 (patch) | |
tree | 4f385106ce732d4f7338feab5391f2a06c68a0e6 /api/logic/minecraft | |
parent | bbe139dce51a7965394c800cac974946820d3869 (diff) | |
download | MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.gz MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.lz MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.xz MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.zip |
NOISSUE Granular instance reload
Diffstat (limited to 'api/logic/minecraft')
-rw-r--r-- | api/logic/minecraft/ftb/FTBInstanceProvider.cpp | 278 | ||||
-rw-r--r-- | api/logic/minecraft/ftb/FTBInstanceProvider.h | 45 | ||||
-rw-r--r-- | api/logic/minecraft/ftb/FTBPlugin.cpp | 286 | ||||
-rw-r--r-- | api/logic/minecraft/ftb/FTBPlugin.h | 1 |
4 files changed, 325 insertions, 285 deletions
diff --git a/api/logic/minecraft/ftb/FTBInstanceProvider.cpp b/api/logic/minecraft/ftb/FTBInstanceProvider.cpp new file mode 100644 index 00000000..a583c039 --- /dev/null +++ b/api/logic/minecraft/ftb/FTBInstanceProvider.cpp @@ -0,0 +1,278 @@ +#include "FTBInstanceProvider.h" + +#include <QDir> +#include <QDebug> +#include <QXmlStreamReader> +#include <QRegularExpression> + +#include <settings/INISettingsObject.h> +#include <FileSystem.h> + +#include "Env.h" +#include "minecraft/MinecraftVersion.h" + +#include "LegacyFTBInstance.h" +#include "OneSixFTBInstance.h" + +inline uint qHash(FTBRecord record) +{ + return qHash(record.instanceDir); +} + +FTBInstanceProvider::FTBInstanceProvider(SettingsObjectPtr settings) + : BaseInstanceProvider(settings) +{ + // nil +} + +QList<InstanceId> FTBInstanceProvider::discoverInstances() +{ + // nothing to load when we don't have + if (m_globalSettings->get("TrackFTBInstances").toBool() != true) + { + return {}; + } + m_records.clear(); + discoverFTBEntries(); + return m_records.keys(); +} + +InstancePtr FTBInstanceProvider::loadInstance(const InstanceId& id) +{ + // process the records we acquired. + auto iter = m_records.find(id); + if(iter == m_records.end()) + { + qWarning() << "Cannot load instance" << id << "without a record"; + return nullptr; + } + auto & record = m_records[id]; + qDebug() << "Loading FTB instance from " << record.instanceDir; + QString iconKey = record.iconKey; + auto icons = ENV.icons(); + if(icons) + { + icons->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), IconType::Transient); + } + auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg"); + qDebug() << "ICON get!"; + + if (QFileInfo(settingsFilePath).exists()) + { + auto instPtr = loadInstance(record); + if (!instPtr) + { + qWarning() << "Couldn't load instance config:" << settingsFilePath; + if(!QFile::remove(settingsFilePath)) + { + qWarning() << "Couldn't remove broken instance config!"; + return nullptr; + } + // failed to load, but removed the poisonous file + } + else + { + return InstancePtr(instPtr); + } + } + auto instPtr = createInstance(record); + if (!instPtr) + { + qWarning() << "Couldn't create FTB instance!"; + return nullptr; + } + return InstancePtr(instPtr); +} + +void FTBInstanceProvider::discoverFTBEntries() +{ + QDir dir = QDir(m_globalSettings->get("FTBLauncherLocal").toString()); + QDir dataDir = QDir(m_globalSettings->get("FTBRoot").toString()); + if (!dataDir.exists()) + { + qDebug() << "The FTB directory specified does not exist. Please check your settings"; + return; + } + else if (!dir.exists()) + { + qDebug() << "The FTB launcher data directory specified does not exist. Please check " + "your settings"; + return; + } + dir.cd("ModPacks"); + auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name); + for (auto filename : allFiles) + { + if (!filename.endsWith(".xml")) + continue; + auto fpath = dir.absoluteFilePath(filename); + QFile f(fpath); + qDebug() << "Discovering FTB instances -- " << fpath; + if (!f.open(QFile::ReadOnly)) + continue; + + // read the FTB packs XML. + QXmlStreamReader reader(&f); + while (!reader.atEnd()) + { + switch (reader.readNext()) + { + case QXmlStreamReader::StartElement: + { + if (reader.name() == "modpack") + { + QXmlStreamAttributes attrs = reader.attributes(); + FTBRecord record; + record.dirName = attrs.value("dir").toString(); + record.instanceDir = dataDir.absoluteFilePath(record.dirName); + record.templateDir = dir.absoluteFilePath(record.dirName); + QDir test(record.instanceDir); + qDebug() << dataDir.absolutePath() << record.instanceDir << record.dirName; + if (!test.exists()) + continue; + record.name = attrs.value("name").toString(); + record.logo = attrs.value("logo").toString(); + QString logo = record.logo; + record.iconKey = logo.remove(QRegularExpression("\\..*")); + auto customVersions = attrs.value("customMCVersions"); + if (!customVersions.isNull()) + { + QMap<QString, QString> versionMatcher; + QString customVersionsStr = customVersions.toString(); + QStringList list = customVersionsStr.split(';'); + for (auto item : list) + { + auto segment = item.split('^'); + if (segment.size() != 2) + { + qCritical() << "FTB: Segment of size < 2 in " + << customVersionsStr; + continue; + } + versionMatcher[segment[0]] = segment[1]; + } + auto actualVersion = attrs.value("version").toString(); + if (versionMatcher.contains(actualVersion)) + { + record.mcVersion = versionMatcher[actualVersion]; + } + else + { + record.mcVersion = attrs.value("mcVersion").toString(); + } + } + else + { + record.mcVersion = attrs.value("mcVersion").toString(); + } + record.description = attrs.value("description").toString(); + auto id = "FTB/" + record.dirName; + m_records[id] = record; + } + break; + } + case QXmlStreamReader::EndElement: + break; + case QXmlStreamReader::Characters: + break; + default: + break; + } + } + f.close(); + } +} + +InstancePtr FTBInstanceProvider::loadInstance(const FTBRecord & record) const +{ + InstancePtr inst; + + auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); + m_settings->registerSetting("InstanceType", "Legacy"); + + qDebug() << "Loading existing " << record.name; + + QString inst_type = m_settings->get("InstanceType").toString(); + if (inst_type == "LegacyFTB") + { + inst.reset(new LegacyFTBInstance(m_globalSettings, m_settings, record.instanceDir)); + } + else if (inst_type == "OneSixFTB") + { + inst.reset(new OneSixFTBInstance(m_globalSettings, m_settings, record.instanceDir)); + } + else + { + return nullptr; + } + qDebug() << "Construction " << record.instanceDir; + + SettingsObject::Lock lock(inst->settings()); + inst->init(); + qDebug() << "Init " << record.instanceDir; + inst->setGroupInitial("FTB"); + /** + * FIXME: this does not respect the user's preferences. BUT, it would work nicely with the planned pack support + * -> instead of changing the user values, change pack values (defaults you can look at and revert to) + */ + /* + inst->setName(record.name); + inst->setIconKey(record.iconKey); + inst->setNotes(record.description); + */ + if (inst->intendedVersionId() != record.mcVersion) + { + inst->setIntendedVersionId(record.mcVersion); + } + qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot(); + return inst; +} + +InstancePtr FTBInstanceProvider::createInstance(const FTBRecord & record) const +{ + QDir rootDir(record.instanceDir); + + InstancePtr inst; + + qDebug() << "Converting " << record.name << " as new."; + + auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion)); + if (!mcVersion) + { + qCritical() << "Can't load instance " << record.instanceDir + << " because minecraft version " << record.mcVersion + << " can't be resolved."; + return nullptr; + } + + if (!rootDir.exists() && !rootDir.mkpath(".")) + { + qCritical() << "Can't create instance folder" << record.instanceDir; + return nullptr; + } + + auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); + m_settings->registerSetting("InstanceType", "Legacy"); + + if (mcVersion->usesLegacyLauncher()) + { + m_settings->set("InstanceType", "LegacyFTB"); + inst.reset(new LegacyFTBInstance(m_globalSettings, m_settings, record.instanceDir)); + } + else + { + m_settings->set("InstanceType", "OneSixFTB"); + inst.reset(new OneSixFTBInstance(m_globalSettings, m_settings, record.instanceDir)); + } + // initialize + { + SettingsObject::Lock lock(inst->settings()); + inst->setIntendedVersionId(mcVersion->descriptor()); + inst->init(); + inst->setGroupInitial("FTB"); + inst->setName(record.name); + inst->setIconKey(record.iconKey); + inst->setNotes(record.description); + } + return inst; +} diff --git a/api/logic/minecraft/ftb/FTBInstanceProvider.h b/api/logic/minecraft/ftb/FTBInstanceProvider.h new file mode 100644 index 00000000..fb3ecb6c --- /dev/null +++ b/api/logic/minecraft/ftb/FTBInstanceProvider.h @@ -0,0 +1,45 @@ +#pragma once + +#include "BaseInstanceProvider.h" +#include <QMap> + +class QFileSystemWatcher; + +struct MULTIMC_LOGIC_EXPORT FTBRecord +{ + QString dirName; + QString name; + QString logo; + QString iconKey; + QString mcVersion; + QString description; + QString instanceDir; + QString templateDir; + bool operator==(const FTBRecord other) const + { + return instanceDir == other.instanceDir; + } +}; + +class MULTIMC_LOGIC_EXPORT FTBInstanceProvider : public BaseInstanceProvider +{ + Q_OBJECT + +public: + FTBInstanceProvider (SettingsObjectPtr settings); + +public: + QList<InstanceId> discoverInstances() override; + InstancePtr loadInstance(const InstanceId& id) override; + void loadGroupList() override {}; + void saveGroupList() override {}; + +private: /* methods */ + void discoverFTBEntries(); + InstancePtr createInstance(const FTBRecord & record) const; + InstancePtr loadInstance(const FTBRecord & record) const; + + +private: + QMap<InstanceId, FTBRecord> m_records; +}; diff --git a/api/logic/minecraft/ftb/FTBPlugin.cpp b/api/logic/minecraft/ftb/FTBPlugin.cpp index 134257bf..d14eea63 100644 --- a/api/logic/minecraft/ftb/FTBPlugin.cpp +++ b/api/logic/minecraft/ftb/FTBPlugin.cpp @@ -8,291 +8,9 @@ #include <minecraft/MinecraftVersionList.h> #include <settings/INISettingsObject.h> #include <FileSystem.h> -#include "QDebug" -#include <QXmlStreamReader> -#include <QRegularExpression> - -struct FTBRecord -{ - QString dirName; - QString name; - QString logo; - QString iconKey; - QString mcVersion; - QString description; - QString instanceDir; - QString templateDir; - bool operator==(const FTBRecord other) const - { - return instanceDir == other.instanceDir; - } -}; - -inline uint qHash(FTBRecord record) -{ - return qHash(record.instanceDir); -} - -QSet<FTBRecord> discoverFTBInstances(SettingsObjectPtr globalSettings) -{ - QSet<FTBRecord> records; - QDir dir = QDir(globalSettings->get("FTBLauncherLocal").toString()); - QDir dataDir = QDir(globalSettings->get("FTBRoot").toString()); - if (!dataDir.exists()) - { - qDebug() << "The FTB directory specified does not exist. Please check your settings"; - return records; - } - else if (!dir.exists()) - { - qDebug() << "The FTB launcher data directory specified does not exist. Please check " - "your settings"; - return records; - } - dir.cd("ModPacks"); - auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name); - for (auto filename : allFiles) - { - if (!filename.endsWith(".xml")) - continue; - auto fpath = dir.absoluteFilePath(filename); - QFile f(fpath); - qDebug() << "Discovering FTB instances -- " << fpath; - if (!f.open(QFile::ReadOnly)) - continue; - - // read the FTB packs XML. - QXmlStreamReader reader(&f); - while (!reader.atEnd()) - { - switch (reader.readNext()) - { - case QXmlStreamReader::StartElement: - { - if (reader.name() == "modpack") - { - QXmlStreamAttributes attrs = reader.attributes(); - FTBRecord record; - record.dirName = attrs.value("dir").toString(); - record.instanceDir = dataDir.absoluteFilePath(record.dirName); - record.templateDir = dir.absoluteFilePath(record.dirName); - QDir test(record.instanceDir); - qDebug() << dataDir.absolutePath() << record.instanceDir << record.dirName; - if (!test.exists()) - continue; - record.name = attrs.value("name").toString(); - record.logo = attrs.value("logo").toString(); - QString logo = record.logo; - record.iconKey = logo.remove(QRegularExpression("\\..*")); - auto customVersions = attrs.value("customMCVersions"); - if (!customVersions.isNull()) - { - QMap<QString, QString> versionMatcher; - QString customVersionsStr = customVersions.toString(); - QStringList list = customVersionsStr.split(';'); - for (auto item : list) - { - auto segment = item.split('^'); - if (segment.size() != 2) - { - qCritical() << "FTB: Segment of size < 2 in " - << customVersionsStr; - continue; - } - versionMatcher[segment[0]] = segment[1]; - } - auto actualVersion = attrs.value("version").toString(); - if (versionMatcher.contains(actualVersion)) - { - record.mcVersion = versionMatcher[actualVersion]; - } - else - { - record.mcVersion = attrs.value("mcVersion").toString(); - } - } - else - { - record.mcVersion = attrs.value("mcVersion").toString(); - } - record.description = attrs.value("description").toString(); - records.insert(record); - } - break; - } - case QXmlStreamReader::EndElement: - break; - case QXmlStreamReader::Characters: - break; - default: - break; - } - } - f.close(); - } - return records; -} - -InstancePtr loadInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record) -{ - InstancePtr inst; - - auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); - m_settings->registerSetting("InstanceType", "Legacy"); - - qDebug() << "Loading existing " << record.name; - - QString inst_type = m_settings->get("InstanceType").toString(); - if (inst_type == "LegacyFTB") - { - inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir)); - } - else if (inst_type == "OneSixFTB") - { - inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir)); - } - else - { - return nullptr; - } - qDebug() << "Construction " << record.instanceDir; - - SettingsObject::Lock lock(inst->settings()); - inst->init(); - qDebug() << "Init " << record.instanceDir; - inst->setGroupInitial("FTB"); - /** - * FIXME: this does not respect the user's preferences. BUT, it would work nicely with the planned pack support - * -> instead of changing the user values, change pack values (defaults you can look at and revert to) - */ - /* - inst->setName(record.name); - inst->setIconKey(record.iconKey); - inst->setNotes(record.description); - */ - if (inst->intendedVersionId() != record.mcVersion) - { - inst->setIntendedVersionId(record.mcVersion); - } - qDebug() << "Post-Process " << record.instanceDir; - if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap)) - { - return nullptr; - } - qDebug() << "Final " << record.instanceDir; - return inst; -} - -InstancePtr createInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record) -{ - QDir rootDir(record.instanceDir); - - InstancePtr inst; - - qDebug() << "Converting " << record.name << " as new."; - - auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion)); - if (!mcVersion) - { - qCritical() << "Can't load instance " << record.instanceDir - << " because minecraft version " << record.mcVersion - << " can't be resolved."; - return nullptr; - } - if (!rootDir.exists() && !rootDir.mkpath(".")) - { - qCritical() << "Can't create instance folder" << record.instanceDir; - return nullptr; - } - - auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); - m_settings->registerSetting("InstanceType", "Legacy"); - - if (mcVersion->usesLegacyLauncher()) - { - m_settings->set("InstanceType", "LegacyFTB"); - inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir)); - } - else - { - m_settings->set("InstanceType", "OneSixFTB"); - inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir)); - } - // initialize - { - SettingsObject::Lock lock(inst->settings()); - inst->setIntendedVersionId(mcVersion->descriptor()); - inst->init(); - inst->setGroupInitial("FTB"); - inst->setName(record.name); - inst->setIconKey(record.iconKey); - inst->setNotes(record.description); - qDebug() << "Post-Process " << record.instanceDir; - if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap)) - { - return nullptr; - } - } - return inst; -} - -void FTBPlugin::loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList) -{ - // nothing to load when we don't have - if (globalSettings->get("TrackFTBInstances").toBool() != true) - { - return; - } - - auto records = discoverFTBInstances(globalSettings); - if (!records.size()) - { - qDebug() << "No FTB instances to load."; - return; - } - qDebug() << "Loading FTB instances! -- got " << records.size(); - // process the records we acquired. - for (auto record : records) - { - qDebug() << "Loading FTB instance from " << record.instanceDir; - QString iconKey = record.iconKey; - auto icons = ENV.icons(); - if(icons) - { - icons->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), IconType::Transient); - } - auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg"); - qDebug() << "ICON get!"; - - if (QFileInfo(settingsFilePath).exists()) - { - auto instPtr = loadInstance(globalSettings, groupMap, record); - if (!instPtr) - { - qWarning() << "Couldn't load instance config:" << settingsFilePath; - if(!QFile::remove(settingsFilePath)) - { - qWarning() << "Couldn't remove broken instance config!"; - continue; - } - // failed to load, but removed the poisonous file - } - else - { - tempList.append(InstancePtr(instPtr)); - continue; - } - } - auto instPtr = createInstance(globalSettings, groupMap, record); - if (!instPtr) - { - qWarning() << "Couldn't create FTB instance!"; - continue; - } - tempList.append(InstancePtr(instPtr)); - } -} +#include <QDebug> +#include <QRegularExpression> #ifdef Q_OS_WIN32 #include <windows.h> diff --git a/api/logic/minecraft/ftb/FTBPlugin.h b/api/logic/minecraft/ftb/FTBPlugin.h index 6851d8a5..e1b56545 100644 --- a/api/logic/minecraft/ftb/FTBPlugin.h +++ b/api/logic/minecraft/ftb/FTBPlugin.h @@ -9,5 +9,4 @@ class MULTIMC_LOGIC_EXPORT FTBPlugin { public: static void initialize(SettingsObjectPtr globalSettings); - static void loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList); }; |