diff options
Diffstat (limited to 'logic')
42 files changed, 294 insertions, 159 deletions
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index 9a811577..be6ea184 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -29,6 +29,7 @@ #include <cmdutils.h> #include "logic/minecraft/MinecraftVersionList.h" #include "logic/icons/IconList.h" +#include "logic/InstanceList.h" BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir, SettingsObject *settings_obj, QObject *parent) @@ -143,10 +144,12 @@ QString BaseInstance::minecraftRoot() const InstanceList *BaseInstance::instList() const { - if (parent()->inherits("InstanceList")) - return (InstanceList *)parent(); - else - return NULL; + return qobject_cast<InstanceList *>(parent()); +} + +InstancePtr BaseInstance::getSharedPtr() +{ + return instList()->getInstanceById(id()); } std::shared_ptr<BaseVersionList> BaseInstance::versionList() const @@ -160,13 +163,12 @@ SettingsObject &BaseInstance::settings() const return *d->m_settings; } -QSet<BaseInstance::InstanceFlag> BaseInstance::flags() const +BaseInstance::InstanceFlags BaseInstance::flags() const { I_D(const BaseInstance); - return QSet<InstanceFlag>(d->m_flags); + return d->m_flags; } - -void BaseInstance::setFlags(const QSet<InstanceFlag> &flags) +void BaseInstance::setFlags(const InstanceFlags &flags) { I_D(BaseInstance); if (flags != d->m_flags) @@ -176,10 +178,24 @@ void BaseInstance::setFlags(const QSet<InstanceFlag> &flags) emit propertiesChanged(this); } } +void BaseInstance::setFlag(const BaseInstance::InstanceFlag flag) +{ + I_D(BaseInstance); + d->m_flags |= flag; + emit flagsChanged(); + emit propertiesChanged(this); +} +void BaseInstance::unsetFlag(const BaseInstance::InstanceFlag flag) +{ + I_D(BaseInstance); + d->m_flags &= ~flag; + emit flagsChanged(); + emit propertiesChanged(this); +} bool BaseInstance::canLaunch() const { - return !flags().contains(VersionBrokenFlag); + return !(flags() & VersionBrokenFlag); } bool BaseInstance::reload() diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index 0cd17de9..ed5840e2 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -34,6 +34,10 @@ class OneSixUpdate; class InstanceList; class BaseInstancePrivate; +// pointer for lazy people +class BaseInstance; +typedef std::shared_ptr<BaseInstance> InstancePtr; + /*! * \brief Base class for instances. * This class implements many functions that are common between instances and @@ -163,6 +167,8 @@ public: */ InstanceList *instList() const; + InstancePtr getSharedPtr(); + /*! * \brief Gets a pointer to this instance's version list. * \return A pointer to the available version list for this instance. @@ -193,11 +199,14 @@ public: enum InstanceFlag { - NoFlags = 0x00, - VersionBrokenFlag = 0x01 + VersionBrokenFlag = 0x01, + UpdateAvailable = 0x02 }; - QSet<InstanceFlag> flags() const; - void setFlags(const QSet<InstanceFlag> &flags); + Q_DECLARE_FLAGS(InstanceFlags, InstanceFlag) + InstanceFlags flags() const; + void setFlags(const InstanceFlags &flags); + void setFlag(const InstanceFlag flag); + void unsetFlag(const InstanceFlag flag); bool canLaunch() const; @@ -226,7 +235,6 @@ protected: std::shared_ptr<BaseInstancePrivate> inst_d; }; -// pointer for lazy people -typedef std::shared_ptr<BaseInstance> InstancePtr; - +Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>) Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) diff --git a/logic/BaseInstance_p.h b/logic/BaseInstance_p.h index 77486abc..3d1a4cbe 100644 --- a/logic/BaseInstance_p.h +++ b/logic/BaseInstance_p.h @@ -31,6 +31,6 @@ public: QString m_rootDir; QString m_group; std::shared_ptr<SettingsObject> m_settings; - QSet<BaseInstance::InstanceFlag> m_flags; + BaseInstance::InstanceFlags m_flags; bool m_isRunning = false; }; diff --git a/logic/BaseVersion.h b/logic/BaseVersion.h index ed63f551..04d0a10b 100644 --- a/logic/BaseVersion.h +++ b/logic/BaseVersion.h @@ -24,6 +24,7 @@ */ struct BaseVersion { + virtual ~BaseVersion() {} /*! * A string used to identify this version in config files. * This should be unique within the version list or shenanigans will occur. diff --git a/logic/InstanceFactory.cpp b/logic/InstanceFactory.cpp index f0f7ffb3..e1cc64df 100644 --- a/logic/InstanceFactory.cpp +++ b/logic/InstanceFactory.cpp @@ -52,19 +52,19 @@ InstanceFactory::InstLoadError InstanceFactory::loadInstance(InstancePtr &inst, // FIXME: replace with a map lookup, where instance classes register their types if (inst_type == "OneSix" || inst_type == "Nostalgia") { - inst.reset(new OneSixInstance(instDir, m_settings, this)); + inst.reset(new OneSixInstance(instDir, m_settings)); } else if (inst_type == "Legacy") { - inst.reset(new LegacyInstance(instDir, m_settings, this)); + inst.reset(new LegacyInstance(instDir, m_settings)); } else if (inst_type == "LegacyFTB") { - inst.reset(new LegacyFTBInstance(instDir, m_settings, this)); + inst.reset(new LegacyFTBInstance(instDir, m_settings)); } else if (inst_type == "OneSixFTB") { - inst.reset(new OneSixFTBInstance(instDir, m_settings, this)); + inst.reset(new OneSixFTBInstance(instDir, m_settings)); } else { @@ -82,11 +82,15 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in QLOG_DEBUG() << instDir.toUtf8(); if (!rootDir.exists() && !rootDir.mkpath(".")) { + QLOG_ERROR() << "Can't create instance folder" << instDir; return InstanceFactory::CantCreateDir; } auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version); if (!mcVer) + { + QLOG_ERROR() << "Can't create instance for non-existing MC version"; return InstanceFactory::NoSuchVersion; + } auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg")); m_settings->registerSetting("InstanceType", "Legacy"); @@ -94,7 +98,7 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in if (type == NormalInst) { m_settings->set("InstanceType", "OneSix"); - inst.reset(new OneSixInstance(instDir, m_settings, this)); + inst.reset(new OneSixInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); } @@ -103,14 +107,14 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in if(mcVer->usesLegacyLauncher()) { m_settings->set("InstanceType", "LegacyFTB"); - inst.reset(new LegacyFTBInstance(instDir, m_settings, this)); + inst.reset(new LegacyFTBInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); } else { m_settings->set("InstanceType", "OneSixFTB"); - inst.reset(new OneSixFTBInstance(instDir, m_settings, this)); + inst.reset(new OneSixFTBInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); } diff --git a/logic/InstanceFactory.h b/logic/InstanceFactory.h index 32a31080..3a4a55a8 100644 --- a/logic/InstanceFactory.h +++ b/logic/InstanceFactory.h @@ -26,7 +26,7 @@ struct BaseVersion; class BaseInstance; /*! - * The \bInstanceFactory\b is a singleton that manages loading and creating instances. + * The \b InstanceFactory\b is a singleton that manages loading and creating instances. */ class InstanceFactory : public QObject { diff --git a/logic/LegacyFTBInstance.cpp b/logic/LegacyFTBInstance.cpp index 73a1f73d..06bef948 100644 --- a/logic/LegacyFTBInstance.cpp +++ b/logic/LegacyFTBInstance.cpp @@ -7,7 +7,7 @@ LegacyFTBInstance::LegacyFTBInstance(const QString &rootDir, SettingsObject *set QString LegacyFTBInstance::getStatusbarDescription() { - if (flags().contains(VersionBrokenFlag)) + if (flags() & VersionBrokenFlag) { return "Legacy FTB: " + intendedVersionId() + " (broken)"; } diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 0239a325..eede7070 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -287,7 +287,7 @@ QString LegacyInstance::defaultCustomBaseJar() const QString LegacyInstance::getStatusbarDescription() { - if (flags().contains(VersionBrokenFlag)) + if (flags() & VersionBrokenFlag) { return tr("Legacy : %1 (broken)").arg(intendedVersionId()); } diff --git a/logic/MMCJson.cpp b/logic/MMCJson.cpp index 8de88b6b..23af4fff 100644 --- a/logic/MMCJson.cpp +++ b/logic/MMCJson.cpp @@ -1,13 +1,26 @@ #include "MMCJson.h" + #include <QString> +#include <QUrl> #include <QStringList> #include <math.h> +QJsonDocument MMCJson::parseDocument(const QByteArray &data, const QString &what) +{ + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError) + { + throw JSONValidationError(what + " is not valid JSON: " + error.errorString() + " at " + error.offset); + } + return doc; +} + bool MMCJson::ensureBoolean(const QJsonValue val, const QString what) { if (!val.isBool()) throw JSONValidationError(what + " is not boolean"); - return val.isBool(); + return val.toBool(); } QJsonValue MMCJson::ensureExists(QJsonValue val, const QString what) @@ -24,6 +37,15 @@ QJsonArray MMCJson::ensureArray(const QJsonValue val, const QString what) return val.toArray(); } +QJsonArray MMCJson::ensureArray(const QJsonDocument &val, const QString &what) +{ + if (!val.isArray()) + { + throw JSONValidationError(what + " is not an array"); + } + return val.array(); +} + double MMCJson::ensureDouble(const QJsonValue val, const QString what) { if (!val.isDouble()) @@ -60,9 +82,36 @@ QString MMCJson::ensureString(const QJsonValue val, const QString what) return val.toString(); } +QUrl MMCJson::ensureUrl(const QJsonValue &val, const QString &what) +{ + const QUrl url = QUrl(ensureString(val, what)); + if (!url.isValid()) + { + throw JSONValidationError(what + " is not an url"); + } + return url; +} + +QJsonDocument MMCJson::parseFile(const QString &filename, const QString &what) +{ + QFile f(filename); + if (!f.open(QFile::ReadOnly)) + { + throw FileOpenError(f); + } + return parseDocument(f.readAll(), what); +} + +int MMCJson::ensureInteger(const QJsonValue val, QString what, const int def) +{ + if (val.isUndefined()) + return def; + return ensureInteger(val, what); +} + void MMCJson::writeString(QJsonObject &to, QString key, QString value) { - if(value.size()) + if (!value.isEmpty()) { to.insert(key, value); } @@ -70,7 +119,7 @@ void MMCJson::writeString(QJsonObject &to, QString key, QString value) void MMCJson::writeStringList(QJsonObject &to, QString key, QStringList values) { - if(values.size()) + if (!values.isEmpty()) { QJsonArray array; for(auto value: values) @@ -81,3 +130,13 @@ void MMCJson::writeStringList(QJsonObject &to, QString key, QStringList values) } } +QStringList MMCJson::ensureStringList(const QJsonValue val, QString what) +{ + const QJsonArray array = ensureArray(val, what); + QStringList out; + for (const auto value : array) + { + out.append(ensureString(value)); + } + return out; +} diff --git a/logic/MMCJson.h b/logic/MMCJson.h index 8408f29b..dc0b4224 100644 --- a/logic/MMCJson.h +++ b/logic/MMCJson.h @@ -9,17 +9,29 @@ #include <QJsonObject> #include <QJsonDocument> #include <QJsonArray> +#include <QFile> +#include <memory> #include "MMCError.h" class JSONValidationError : public MMCError { public: - JSONValidationError(QString cause) : MMCError(cause) {}; - virtual ~JSONValidationError() noexcept {} + JSONValidationError(QString cause) : MMCError(cause) {} +}; +class FileOpenError : public MMCError +{ +public: + FileOpenError(const QFile &file) : MMCError(QObject::tr("Error opening %1: %2").arg(file.fileName(), file.errorString())) {} }; namespace MMCJson { +/// parses the data into a json document. throws if there's a parse error +QJsonDocument parseDocument(const QByteArray &data, const QString &what); + +/// tries to open and then parses the specified file. throws if there's an error +QJsonDocument parseFile(const QString &filename, const QString &what); + /// make sure the value exists. throw otherwise. QJsonValue ensureExists(QJsonValue val, const QString what = "value"); @@ -27,39 +39,63 @@ QJsonValue ensureExists(QJsonValue val, const QString what = "value"); QJsonObject ensureObject(const QJsonValue val, const QString what = "value"); /// make sure the document is converted into an object. throw otherwise. -QJsonObject ensureObject(const QJsonDocument val, const QString what = "value"); +QJsonObject ensureObject(const QJsonDocument val, const QString what = "document"); /// make sure the value is converted into an array. throw otherwise. QJsonArray ensureArray(const QJsonValue val, QString what = "value"); +/// make sure the document is converted into an array. throw otherwise. +QJsonArray ensureArray(const QJsonDocument &val, const QString &what = "document"); + /// make sure the value is converted into a string. throw otherwise. QString ensureString(const QJsonValue val, QString what = "value"); +/// make sure the value is converted into a string that's parseable as an url. throw otherwise. +QUrl ensureUrl(const QJsonValue &val, const QString &what = "value"); + /// make sure the value is converted into a boolean. throw otherwise. bool ensureBoolean(const QJsonValue val, QString what = "value"); /// make sure the value is converted into an integer. throw otherwise. int ensureInteger(const QJsonValue val, QString what = "value"); +/// make sure the value is converted into an integer. throw otherwise. this version will return the default value if the field is undefined. +int ensureInteger(const QJsonValue val, QString what, const int def); + /// make sure the value is converted into a double precision floating number. throw otherwise. double ensureDouble(const QJsonValue val, QString what = "value"); +QStringList ensureStringList(const QJsonValue val, QString what); + void writeString(QJsonObject & to, QString key, QString value); -void writeStringList (QJsonObject & to, QString key, QStringList values); +void writeStringList(QJsonObject & to, QString key, QStringList values); template <typename T> -void writeObjectList (QJsonObject & to, QString key, QList<T> values) +void writeObjectList(QJsonObject & to, QString key, QList<std::shared_ptr<T>> values) { - if(values.size()) + if (!values.isEmpty()) { QJsonArray array; - for(auto value: values) + for (auto value: values) { array.append(value->toJson()); } to.insert(key, array); } } +template <typename T> +void writeObjectList(QJsonObject & to, QString key, QList<T> values) +{ + if (!values.isEmpty()) + { + QJsonArray array; + for (auto value: values) + { + array.append(value.toJson()); + } + to.insert(key, array); + } +} } diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp index 8dfd3051..903c4437 100644 --- a/logic/OneSixFTBInstance.cpp +++ b/logic/OneSixFTBInstance.cpp @@ -118,7 +118,7 @@ bool OneSixFTBInstance::providesVersionFile() const QString OneSixFTBInstance::getStatusbarDescription() { - if (flags().contains(VersionBrokenFlag)) + if (flags() & VersionBrokenFlag) { return "OneSix FTB: " + intendedVersionId() + " (broken)"; } diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 82d4e480..00d8a9db 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -418,7 +418,7 @@ void OneSixInstance::reloadVersion() try { d->version->reload(externalPatches()); - d->m_flags.remove(VersionBrokenFlag); + unsetFlag(VersionBrokenFlag); emit versionReloaded(); } catch (VersionIncomplete &error) @@ -427,7 +427,7 @@ void OneSixInstance::reloadVersion() catch (MMCError &error) { d->version->clear(); - d->m_flags.insert(VersionBrokenFlag); + setFlag(VersionBrokenFlag); // TODO: rethrow to show some error message(s)? emit versionReloaded(); throw; @@ -464,7 +464,7 @@ QString OneSixInstance::getStatusbarDescription() { traits.append(tr("custom")); } - if (flags().contains(VersionBrokenFlag)) + if (flags() & VersionBrokenFlag) { traits.append(tr("broken")); } @@ -569,3 +569,8 @@ QStringList OneSixInstance::extraArguments() const } return list; } + +std::shared_ptr<OneSixInstance> OneSixInstance::getSharedPtr() +{ + return std::dynamic_pointer_cast<OneSixInstance>(BaseInstance::getSharedPtr()); +} diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index 75caef1f..f7b01608 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -96,8 +96,11 @@ public: virtual bool providesVersionFile() const; bool reload() override; + virtual QStringList extraArguments() const override; - + + std::shared_ptr<OneSixInstance> getSharedPtr(); + signals: void versionReloaded(); @@ -105,3 +108,5 @@ private: QStringList processMinecraftArgs(AuthSessionPtr account); QDir reconstructAssets(std::shared_ptr<InstanceVersion> version); }; + +Q_DECLARE_METATYPE(std::shared_ptr<OneSixInstance>) diff --git a/logic/forge/ForgeInstaller.h b/logic/forge/ForgeInstaller.h index 1c7452d7..655fbc89 100644 --- a/logic/forge/ForgeInstaller.h +++ b/logic/forge/ForgeInstaller.h @@ -29,11 +29,11 @@ class ForgeInstaller : public BaseInstaller friend class ForgeInstallTask; public: ForgeInstaller(); - virtual ~ForgeInstaller(){}; + virtual ~ForgeInstaller(){} virtual ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override; + virtual QString id() const override { return "net.minecraftforge"; } protected: - virtual QString id() const override { return "net.minecraftforge"; } void prepare(const QString &filename, const QString &universalUrl); bool add(OneSixInstance *to) override; bool addLegacy(OneSixInstance *to); diff --git a/logic/forge/ForgeVersion.h b/logic/forge/ForgeVersion.h index c7adc572..e3c1aab9 100644 --- a/logic/forge/ForgeVersion.h +++ b/logic/forge/ForgeVersion.h @@ -38,3 +38,5 @@ struct ForgeVersion : public BaseVersion QString installer_filename; bool is_recommended = false; }; + +Q_DECLARE_METATYPE(ForgeVersionPtr) diff --git a/logic/java/JavaCheckerJob.h b/logic/java/JavaCheckerJob.h index 132a92d4..4b79611b 100644 --- a/logic/java/JavaCheckerJob.h +++ b/logic/java/JavaCheckerJob.h @@ -59,22 +59,10 @@ public: { return javacheckers.size(); } - virtual void getProgress(qint64 ¤t, qint64 &total) - { - current = current_progress; - total = total_progress; - } - ; - virtual QString getStatus() const - { - return m_job_name; - } - ; virtual bool isRunning() const { return m_running; } - ; signals: void started(); diff --git a/logic/liteloader/LiteLoaderInstaller.h b/logic/liteloader/LiteLoaderInstaller.h index 43ad6b83..b3336bbd 100644 --- a/logic/liteloader/LiteLoaderInstaller.h +++ b/logic/liteloader/LiteLoaderInstaller.h @@ -28,13 +28,10 @@ public: void prepare(LiteLoaderVersionPtr version); bool add(OneSixInstance *to) override; + virtual QString id() const override { return "com.mumfrey.liteloader"; } ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override; private: - virtual QString id() const override - { - return "com.mumfrey.liteloader"; - } LiteLoaderVersionPtr m_version; }; diff --git a/logic/liteloader/LiteLoaderVersionList.h b/logic/liteloader/LiteLoaderVersionList.h index 91ed077c..5eecd926 100644 --- a/logic/liteloader/LiteLoaderVersionList.h +++ b/logic/liteloader/LiteLoaderVersionList.h @@ -111,3 +111,5 @@ protected: CacheDownloadPtr listDownload; LiteLoaderVersionList *m_list; }; + +Q_DECLARE_METATYPE(LiteLoaderVersionPtr) diff --git a/logic/minecraft/InstanceVersion.cpp b/logic/minecraft/InstanceVersion.cpp index c345e1fb..a243ebf4 100644 --- a/logic/minecraft/InstanceVersion.cpp +++ b/logic/minecraft/InstanceVersion.cpp @@ -264,6 +264,14 @@ QList<std::shared_ptr<OneSixLibrary> > InstanceVersion::getActiveNormalLibs() { if (lib->isActive() && !lib->isNative()) { + for (auto other : output) + { + if (other->rawName() == lib->rawName()) + { + QLOG_WARN() << "Multiple libraries with name" << lib->rawName() << "in library list!"; + continue; + } + } output.append(lib); } } diff --git a/logic/minecraft/InstanceVersion.h b/logic/minecraft/InstanceVersion.h index 6b69ab47..664e4242 100644 --- a/logic/minecraft/InstanceVersion.h +++ b/logic/minecraft/InstanceVersion.h @@ -140,10 +140,10 @@ public: QString appletClass; /// the list of libs - both active and inactive, native and java - QList<std::shared_ptr<OneSixLibrary>> libraries; - + QList<OneSixLibraryPtr> libraries; + /// same, but only vanilla. - QList<std::shared_ptr<OneSixLibrary>> vanillaLibraries; + QList<OneSixLibraryPtr> vanillaLibraries; /// traits, collected from all the version files (version files can only add) QSet<QString> traits; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index bde2170b..598fecdb 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/ |
