From 4fa3e2a7144c532af62520c9da53f423d6f002ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 24 Apr 2017 01:30:51 +0200 Subject: [PATCH] GH-1856 Fix metadata version and list loading Shouldn't crash anymore, shouldn't overwrite data in some bad way anymore either. --- api/logic/meta/BaseEntity.cpp | 11 +++++ api/logic/meta/BaseEntity.h | 11 +---- api/logic/meta/Version.cpp | 10 ++++- api/logic/meta/Version.h | 3 +- api/logic/meta/VersionList.cpp | 45 ++++++++++----------- api/logic/minecraft/MinecraftProfile.cpp | 6 +-- api/logic/minecraft/MinecraftProfile.h | 3 -- api/logic/minecraft/ProfilePatch.cpp | 5 +++ api/logic/minecraft/ProfilePatch.h | 1 + api/logic/minecraft/onesix/OneSixUpdate.cpp | 33 ++++++++++----- 10 files changed, 73 insertions(+), 55 deletions(-) diff --git a/api/logic/meta/BaseEntity.cpp b/api/logic/meta/BaseEntity.cpp index 633afab2..439256b5 100644 --- a/api/logic/meta/BaseEntity.cpp +++ b/api/logic/meta/BaseEntity.cpp @@ -141,6 +141,17 @@ void Meta::BaseEntity::load() m_updateTask->start(); } +bool Meta::BaseEntity::isLoaded() const +{ + return m_loadStatus > LoadStatus::NotLoaded; +} + +bool Meta::BaseEntity::shouldStartRemoteUpdate() const +{ + // TODO: version-locks and offline mode? + return m_updateStatus != UpdateStatus::InProgress; +} + shared_qobject_ptr Meta::BaseEntity::getCurrentTask() { if(m_updateStatus == UpdateStatus::InProgress) diff --git a/api/logic/meta/BaseEntity.h b/api/logic/meta/BaseEntity.h index 85c25e48..4483beab 100644 --- a/api/logic/meta/BaseEntity.h +++ b/api/logic/meta/BaseEntity.h @@ -51,15 +51,8 @@ public: virtual QString localFilename() const = 0; virtual QUrl url() const; - bool isLoaded() const - { - return m_loadStatus > LoadStatus::NotLoaded; - } - bool shouldStartRemoteUpdate() const - { - // TODO: version-locks and offline mode? - return m_updateStatus != UpdateStatus::InProgress; - } + bool isLoaded() const; + bool shouldStartRemoteUpdate() const; void load(); shared_qobject_ptr getCurrentTask(); diff --git a/api/logic/meta/Version.cpp b/api/logic/meta/Version.cpp index 338e180b..b00a29e7 100644 --- a/api/logic/meta/Version.cpp +++ b/api/logic/meta/Version.cpp @@ -25,6 +25,10 @@ Meta::Version::Version(const QString &uid, const QString &version) { } +Meta::Version::~Version() +{ +} + QString Meta::Version::descriptor() { return m_version; @@ -76,8 +80,10 @@ void Meta::Version::merge(const std::shared_ptr &other) { setParentUid(version->m_parentUid); } - - setData(version->m_data); + if(version->m_data) + { + setData(version->m_data); + } } QString Meta::Version::localFilename() const diff --git a/api/logic/meta/Version.h b/api/logic/meta/Version.h index f132b861..2f92ee9f 100644 --- a/api/logic/meta/Version.h +++ b/api/logic/meta/Version.h @@ -38,6 +38,7 @@ class MULTIMC_LOGIC_EXPORT Version : public QObject, public BaseVersion, public public: /* con/des */ explicit Version(const QString &uid, const QString &version); + virtual ~Version(); QString descriptor() override; QString name() override; @@ -104,7 +105,7 @@ private: QString m_parentUid; QString m_version; QString m_type; - qint64 m_time; + qint64 m_time = 0; QHash m_requires; VersionFilePtr m_data; }; diff --git a/api/logic/meta/VersionList.cpp b/api/logic/meta/VersionList.cpp index 0f1404ba..44687d3c 100644 --- a/api/logic/meta/VersionList.cpp +++ b/api/logic/meta/VersionList.cpp @@ -182,38 +182,35 @@ void VersionList::merge(const BaseEntity::Ptr &other) setParentUid(list->m_parentUid); } - if (m_versions.isEmpty()) + // TODO: do not reset the whole model. maybe? + beginResetModel(); + m_versions.clear(); + for (const VersionPtr &version : list->m_versions) { - setVersions(list->m_versions); - } - else - { - for (const VersionPtr &version : list->m_versions) + // we already have the version. merge the contents + if (m_lookup.contains(version->version())) { - if (m_lookup.contains(version->version())) - { - m_lookup.value(version->version())->merge(version); - } - else - { - beginInsertRows(QModelIndex(), m_versions.size(), m_versions.size()); - setupAddedVersion(m_versions.size(), version); - m_versions.append(version); - m_lookup.insert(version->uid(), version); - endInsertRows(); - - if (!m_recommended || (version->type() == "release" && version->rawTime() > m_recommended->rawTime())) - { - m_recommended = version; - emit dataChanged(index(0), index(m_versions.size() - 1), QVector() << RecommendedRole); - } - } + m_lookup.value(version->version())->merge(version); + } + else + { + m_lookup.insert(version->uid(), version); + } + // connect it. + setupAddedVersion(m_versions.size(), version); + m_versions.append(version); + if (!m_recommended || (version->type() == "release" && version->rawTime() > m_recommended->rawTime())) + { + m_recommended = version; } } + endResetModel(); } void VersionList::setupAddedVersion(const int row, const VersionPtr &version) { + // FIXME: do not disconnect from everythin, disconnect only the lambdas here + version->disconnect(); connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << RequiresRole); }); connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << TimeRole << SortRole); }); connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << TypeRole); }); diff --git a/api/logic/minecraft/MinecraftProfile.cpp b/api/logic/minecraft/MinecraftProfile.cpp index e7e88efd..4c1ab818 100644 --- a/api/logic/minecraft/MinecraftProfile.cpp +++ b/api/logic/minecraft/MinecraftProfile.cpp @@ -385,6 +385,7 @@ bool MinecraftProfile::reapplyPatches() clear(); for(auto file: m_patches) { + qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD"); file->applyTo(this); } } @@ -663,11 +664,6 @@ void MinecraftProfile::installJarMods(QStringList selectedFiles) m_strategy->installJarMods(selectedFiles); } -void MinecraftProfile::installVersion(BaseVersionPtr version) -{ - // TODO: implement -} - /* * TODO: get rid of this. Get rid of all order numbers. */ diff --git a/api/logic/minecraft/MinecraftProfile.h b/api/logic/minecraft/MinecraftProfile.h index 8cb5331f..192c77f9 100644 --- a/api/logic/minecraft/MinecraftProfile.h +++ b/api/logic/minecraft/MinecraftProfile.h @@ -58,9 +58,6 @@ public: /// install more jar mods void installJarMods(QStringList selectedFiles); - /// install more jar mods - void installVersion(BaseVersionPtr version); - /// DEPRECATED, remove ASAP int getFreeOrderNumber(); diff --git a/api/logic/minecraft/ProfilePatch.cpp b/api/logic/minecraft/ProfilePatch.cpp index 3ca2ac68..a2605278 100644 --- a/api/logic/minecraft/ProfilePatch.cpp +++ b/api/logic/minecraft/ProfilePatch.cpp @@ -17,6 +17,11 @@ ProfilePatch::ProfilePatch(std::shared_ptr file, const QString& fil { } +std::shared_ptr ProfilePatch::getMeta() +{ + return m_metaVersion; +} + void ProfilePatch::applyTo(MinecraftProfile* profile) { auto vfile = getVersionFile(); diff --git a/api/logic/minecraft/ProfilePatch.h b/api/logic/minecraft/ProfilePatch.h index 53f4c5e4..59171a0a 100644 --- a/api/logic/minecraft/ProfilePatch.h +++ b/api/logic/minecraft/ProfilePatch.h @@ -36,6 +36,7 @@ public: virtual QString getID(); virtual QString getName(); virtual QString getVersion(); + virtual std::shared_ptr getMeta(); virtual QDateTime getReleaseDateTime(); virtual QString getFilename(); diff --git a/api/logic/minecraft/onesix/OneSixUpdate.cpp b/api/logic/minecraft/onesix/OneSixUpdate.cpp index bf234189..e0027032 100644 --- a/api/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/api/logic/minecraft/onesix/OneSixUpdate.cpp @@ -44,25 +44,36 @@ OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent) m_tasks.append(std::make_shared(m_inst)); } - // add a version update task, if necessary + // add metadata update tasks, if necessary { /* * FIXME: there are some corner cases here that remain unhandled: * what if local load succeeds but remote fails? The version is still usable... + * We should not rely on the remote to be there... and prefer local files if it does not respond. */ - // FIXME: derive this from the actual list of version patches... - auto loadVersion = [&](const QString & uid, const QString & version) + qDebug() << "Updating patches..."; + auto profile = m_inst->getMinecraftProfile(); + m_inst->reloadProfile(); + for(int i = 0; i < profile->rowCount(); i++) { - auto obj = ENV.metadataIndex()->get(uid, version); - obj->load(); - auto task = obj->getCurrentTask(); - if(task) + auto patch = profile->versionPatch(i); + auto id = patch->getID(); + auto metadata = patch->getMeta(); + if(metadata) { - m_tasks.append(task.unwrap()); + metadata->load(); + auto task = metadata->getCurrentTask(); + if(task) + { + qDebug() << "Loading remote meta patch" << id; + m_tasks.append(task.unwrap()); + } } - }; - loadVersion("org.lwjgl", m_inst->getComponentVersion("org.lwjgl")); - loadVersion("net.minecraft", m_inst->getComponentVersion("net.minecraft")); + else + { + qDebug() << "Ignoring local patch" << id; + } + } } // libraries download