From 43b9db6e45a2ea74384f7851722952b9a1547213 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 10 Jun 2022 19:27:25 -0300 Subject: change: allow deleting mods while preserving their metadata Signed-off-by: flow --- launcher/minecraft/mod/Mod.cpp | 5 +++-- launcher/minecraft/mod/Mod.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 742709e3..37ec8eca 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -162,13 +162,14 @@ void Mod::setMetadata(Metadata::ModStruct* metadata) } } -auto Mod::destroy(QDir& index_dir) -> bool +auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool { auto n = name(); // FIXME: This can fail to remove the metadata if the // "ModMetadataDisabled" setting is on, since there could // be a name mismatch! - Metadata::remove(index_dir, n); + if(!preserve_metadata) + Metadata::remove(index_dir, n); m_type = MOD_UNKNOWN; return FS::deletePath(m_file.filePath()); diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 5f9c4684..abb8a52d 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -82,7 +82,7 @@ public: auto enable(bool value) -> bool; // delete all the files of this mod - auto destroy(QDir& index_dir) -> bool; + auto destroy(QDir& index_dir, bool preserve_metadata = false) -> bool; // change the mod's filesystem path (used by mod lists for *MAGIC* purposes) void repath(const QFileInfo &file); -- cgit From 2d10c246a8e80a5af7535e2ff94442c6db178486 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 4 Jun 2022 21:18:51 -0300 Subject: feat: add update mods to the ui / mod model Signed-off-by: flow --- launcher/minecraft/mod/ModFolderModel.cpp | 12 ++++++++++++ launcher/minecraft/mod/ModFolderModel.h | 2 ++ 2 files changed, 14 insertions(+) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 5ee08cbf..e72eb13e 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -259,6 +259,18 @@ bool ModFolderModel::isValid() return m_dir.exists() && m_dir.isReadable(); } +auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list +{ + std::list selected_mods; + for (auto i : indexes) { + if(i.column() != 0) + continue; + + selected_mods.push_back(mods[i.row()]); + } + return selected_mods; +} + // FIXME: this does not take disabled mod (with extra .disable extension) into account... bool ModFolderModel::installMod(const QString &filename) { diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 24b4d358..c3b493b8 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -144,6 +144,8 @@ public: return mods; } + auto selectedMods(QModelIndexList& indexes) -> std::list; + public slots: void disableInteraction(bool disabled); -- cgit From dfab55112b783d191ac9b596df9c2972b5fe74cb Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 10 Jun 2022 16:43:01 -0300 Subject: feat: remove existing mod when updating/redownloading it Signed-off-by: flow --- launcher/minecraft/mod/Mod.cpp | 7 +++++-- launcher/minecraft/mod/ModFolderModel.cpp | 14 ++++++++++++++ launcher/minecraft/mod/ModFolderModel.h | 2 ++ launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp | 5 +++++ launcher/minecraft/mod/tasks/LocalModUpdateTask.h | 3 +++ 5 files changed, 29 insertions(+), 2 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 37ec8eca..81bb902f 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -183,9 +183,12 @@ auto Mod::details() const -> const ModDetails& auto Mod::name() const -> QString { auto d_name = details().name; - if (!d_name.isEmpty()) { + if (!d_name.isEmpty()) return d_name; - } + + if (status() != ModStatus::NoMetadata) + return metadata()->name; + return m_name; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index e72eb13e..adc828c2 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -356,6 +356,20 @@ bool ModFolderModel::installMod(const QString &filename) return false; } +bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadata) +{ + + for(auto mod : allMods()){ + if(mod.fileinfo().fileName() == filename){ + auto index_dir = indexDir(); + mod.destroy(index_dir, preserve_metadata); + return true; + } + } + + return false; +} + bool ModFolderModel::setModStatus(const QModelIndexList& indexes, ModStatusAction enable) { if(interaction_disabled) { diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index c3b493b8..10289f8d 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -118,6 +118,8 @@ public: */ bool installMod(const QString& filename); + bool uninstallMod(const QString& filename, bool preserve_metadata = false); + /// Deletes all the selected mods bool deleteMods(const QModelIndexList &indexes); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index 1bdecb8c..c73e855e 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -44,6 +44,11 @@ void LocalModUpdateTask::executeTask() { setStatus(tr("Updating index for mod:\n%1").arg(m_mod.name)); + auto old_metadata = Metadata::get(m_index_dir, m_mod.name); + if (old_metadata.isValid()) { + emit hasOldMod(old_metadata.name, old_metadata.filename); + } + auto pw_mod = Metadata::create(m_index_dir, m_mod, m_mod_version); Metadata::update(m_index_dir, pw_mod); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h index 2db183e0..1d2f06a6 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h @@ -37,6 +37,9 @@ class LocalModUpdateTask : public Task { //! Entry point for tasks. void executeTask() override; + signals: + void hasOldMod(QString name, QString filename); + private: QDir m_index_dir; ModPlatform::IndexedPack& m_mod; -- cgit From 91a5c4bdcbd3ae18139b85899f051fb3d9cbd1fc Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 11 Jun 2022 17:19:34 -0300 Subject: feat: add metadata get/delete via mod id This is, in many cases, more reliable than name comparisons, so it's useful specially in cases where a mod changes name between versions Signed-off-by: flow --- launcher/minecraft/mod/MetadataHandler.h | 10 ++++++++++ launcher/minecraft/mod/Mod.cpp | 8 ++------ launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 56962818..d5f01c42 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -52,8 +52,18 @@ class Metadata { Packwiz::V1::deleteModIndex(index_dir, mod_name); } + static void remove(QDir& index_dir, QVariant& mod_id) + { + Packwiz::V1::deleteModIndex(index_dir, mod_id); + } + static auto get(QDir& index_dir, QString& mod_name) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_name); } + + static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct + { + return Packwiz::V1::getIndexForMod(index_dir, mod_id); + } }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 81bb902f..bba7b342 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -164,12 +164,8 @@ void Mod::setMetadata(Metadata::ModStruct* metadata) auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool { - auto n = name(); - // FIXME: This can fail to remove the metadata if the - // "ModMetadataDisabled" setting is on, since there could - // be a name mismatch! - if(!preserve_metadata) - Metadata::remove(index_dir, n); + if (!preserve_metadata && status() != ModStatus::NoMetadata) + Metadata::remove(index_dir, metadata()->mod_id()); m_type = MOD_UNKNOWN; return FS::deletePath(m_file.filePath()); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index c73e855e..f0ef795d 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -44,7 +44,7 @@ void LocalModUpdateTask::executeTask() { setStatus(tr("Updating index for mod:\n%1").arg(m_mod.name)); - auto old_metadata = Metadata::get(m_index_dir, m_mod.name); + auto old_metadata = Metadata::get(m_index_dir, m_mod.addonId); if (old_metadata.isValid()) { emit hasOldMod(old_metadata.name, old_metadata.filename); } -- cgit From a53ee2e35cafd36964663d632877badcf53d8786 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 17 Jun 2022 11:21:43 -0300 Subject: fix: mod parsing of 'String-fied' version (i.e. OpenBlocks) Signed-off-by: flow --- launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 3354732b..1519f49d 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,13 @@ std::shared_ptr ReadMCModInfo(QByteArray contents) if(val.isUndefined()) { val = jsonDoc.object().value("modListVersion"); } - int version = val.toDouble(); + + int version = Json::ensureInteger(val, -1); + + // Some mods set the number with "", so it's a String instead + if (version < 0) + version = Json::ensureString(val, "").toInt(); + if (version != 2) { qCritical() << "BAD stuff happened to mod json:"; -- cgit From fd6755c93f3f3f7551f9b7c11d1bbbb48c22e210 Mon Sep 17 00:00:00 2001 From: flow Date: Sun, 19 Jun 2022 14:26:15 -0300 Subject: change: mod metadata improvements - Use slug instead of name - Keep temporary status before having local details Signed-off-by: flow --- launcher/minecraft/mod/MetadataHandler.h | 12 ++++---- launcher/minecraft/mod/Mod.cpp | 36 ++++++++++++++-------- launcher/minecraft/mod/Mod.h | 4 +-- launcher/minecraft/mod/ModFolderModel.cpp | 30 ++++++++++++------ .../minecraft/mod/tasks/LocalModUpdateTask.cpp | 12 ++++++-- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 2 +- 6 files changed, 61 insertions(+), 35 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index d5f01c42..39723b49 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -37,9 +37,9 @@ class Metadata { return Packwiz::V1::createModFormat(index_dir, mod_pack, mod_version); } - static auto create(QDir& index_dir, Mod& internal_mod) -> ModStruct + static auto create(QDir& index_dir, Mod& internal_mod, QString mod_slug) -> ModStruct { - return Packwiz::V1::createModFormat(index_dir, internal_mod); + return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); } static void update(QDir& index_dir, ModStruct& mod) @@ -47,9 +47,9 @@ class Metadata { Packwiz::V1::updateModIndex(index_dir, mod); } - static void remove(QDir& index_dir, QString& mod_name) + static void remove(QDir& index_dir, QString mod_slug) { - Packwiz::V1::deleteModIndex(index_dir, mod_name); + Packwiz::V1::deleteModIndex(index_dir, mod_slug); } static void remove(QDir& index_dir, QVariant& mod_id) @@ -57,9 +57,9 @@ class Metadata { Packwiz::V1::deleteModIndex(index_dir, mod_id); } - static auto get(QDir& index_dir, QString& mod_name) -> ModStruct + static auto get(QDir& index_dir, QString mod_slug) -> ModStruct { - return Packwiz::V1::getIndexForMod(index_dir, mod_name); + return Packwiz::V1::getIndexForMod(index_dir, mod_slug); } static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index bba7b342..7227fc94 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -147,25 +147,36 @@ void Mod::setStatus(ModStatus status) if (m_localDetails) { m_localDetails->status = status; } else { - m_temp_status = status; + if (!m_temp_status.get()) + m_temp_status.reset(new ModStatus()); + + *m_temp_status = status; } } -void Mod::setMetadata(Metadata::ModStruct* metadata) +void Mod::setMetadata(const Metadata::ModStruct& metadata) { if (status() == ModStatus::NoMetadata) setStatus(ModStatus::Installed); if (m_localDetails) { - m_localDetails->metadata.reset(metadata); + m_localDetails->metadata = std::make_shared(std::move(metadata)); } else { - m_temp_metadata.reset(metadata); + m_temp_metadata = std::make_shared(std::move(metadata)); } } auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool { - if (!preserve_metadata && status() != ModStatus::NoMetadata) - Metadata::remove(index_dir, metadata()->mod_id()); + if (!preserve_metadata) { + qDebug() << QString("Destroying metadata for '%1' on purpose").arg(name()); + + if (metadata()) { + Metadata::remove(index_dir, metadata()->slug); + } else { + auto n = name(); + Metadata::remove(index_dir, n); + } + } m_type = MOD_UNKNOWN; return FS::deletePath(m_file.filePath()); @@ -182,7 +193,7 @@ auto Mod::name() const -> QString if (!d_name.isEmpty()) return d_name; - if (status() != ModStatus::NoMetadata) + if (metadata()) return metadata()->name; return m_name; @@ -211,7 +222,7 @@ auto Mod::authors() const -> QStringList auto Mod::status() const -> ModStatus { if (!m_localDetails) - return m_temp_status; + return m_temp_status ? *m_temp_status : ModStatus::NoMetadata; return details().status; } @@ -235,11 +246,10 @@ void Mod::finishResolvingWithDetails(std::shared_ptr details) m_resolved = true; m_localDetails = details; + setStatus(m_temp_status ? *m_temp_status : ModStatus::NoMetadata); + if (m_localDetails && m_temp_metadata && m_temp_metadata->isValid()) { - m_localDetails->metadata = m_temp_metadata; - if (status() == ModStatus::NoMetadata) - setStatus(ModStatus::Installed); + setMetadata(*m_temp_metadata); + m_temp_metadata.reset(); } - - setStatus(m_temp_status); } diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index abb8a52d..cbbbd362 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -77,7 +77,7 @@ public: auto metadata() const -> const std::shared_ptr; void setStatus(ModStatus status); - void setMetadata(Metadata::ModStruct* metadata); + void setMetadata(const Metadata::ModStruct& metadata); auto enable(bool value) -> bool; @@ -111,7 +111,7 @@ protected: std::shared_ptr m_temp_metadata; /* Set the mod status while it doesn't have local details just yet */ - ModStatus m_temp_status = ModStatus::NotInstalled; + std::shared_ptr m_temp_status; std::shared_ptr m_localDetails; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index adc828c2..d8170067 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -65,15 +65,21 @@ void ModFolderModel::startWatching() update(); + // Watch the mods folder is_watching = m_watcher->addPath(m_dir.absolutePath()); - if (is_watching) - { + if (is_watching) { qDebug() << "Started watching " << m_dir.absolutePath(); - } - else - { + } else { qDebug() << "Failed to start watching " << m_dir.absolutePath(); } + + // Watch the mods index folder + is_watching = m_watcher->addPath(indexDir().absolutePath()); + if (is_watching) { + qDebug() << "Started watching " << indexDir().absolutePath(); + } else { + qDebug() << "Failed to start watching " << indexDir().absolutePath(); + } } void ModFolderModel::stopWatching() @@ -82,14 +88,18 @@ void ModFolderModel::stopWatching() return; is_watching = !m_watcher->removePath(m_dir.absolutePath()); - if (!is_watching) - { + if (!is_watching) { qDebug() << "Stopped watching " << m_dir.absolutePath(); - } - else - { + } else { qDebug() << "Failed to stop watching " << m_dir.absolutePath(); } + + is_watching = !m_watcher->removePath(indexDir().absolutePath()); + if (!is_watching) { + qDebug() << "Stopped watching " << indexDir().absolutePath(); + } else { + qDebug() << "Failed to stop watching " << indexDir().absolutePath(); + } } bool ModFolderModel::update() diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index f0ef795d..4b878918 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -47,12 +47,18 @@ void LocalModUpdateTask::executeTask() auto old_metadata = Metadata::get(m_index_dir, m_mod.addonId); if (old_metadata.isValid()) { emit hasOldMod(old_metadata.name, old_metadata.filename); + if (m_mod.slug.isEmpty()) + m_mod.slug = old_metadata.slug; } auto pw_mod = Metadata::create(m_index_dir, m_mod, m_mod_version); - Metadata::update(m_index_dir, pw_mod); - - emitSucceeded(); + if (pw_mod.isValid()) { + Metadata::update(m_index_dir, pw_mod); + emitSucceeded(); + } else { + qCritical() << "Tried to update an invalid mod!"; + emitFailed(tr("Invalid metadata")); + } } auto LocalModUpdateTask::abort() -> bool diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 276414e4..4ffb626a 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -71,7 +71,7 @@ void ModFolderLoadTask::run() auto metadata = m_result->mods[chopped_id].metadata(); if (metadata) { - mod.setMetadata(new Metadata::ModStruct(*metadata)); + mod.setMetadata(*metadata); m_result->mods[mod.internal_id()].setStatus(ModStatus::Installed); m_result->mods.remove(chopped_id); -- cgit From c4316e81e64ad4ac63b0b50106b324a73abdc150 Mon Sep 17 00:00:00 2001 From: flow Date: Sun, 26 Jun 2022 14:17:15 -0300 Subject: change: make Mod a QObject used as a pointer Prevents problems when copying it around! Signed-off-by: flow --- launcher/minecraft/mod/Mod.h | 6 +- launcher/minecraft/mod/ModFolderModel.cpp | 76 +++++++++++----------- launcher/minecraft/mod/ModFolderModel.h | 16 ++--- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 32 ++++----- launcher/minecraft/mod/tasks/ModFolderLoadTask.h | 2 +- 5 files changed, 69 insertions(+), 63 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index cbbbd362..3d3becd7 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -39,10 +39,12 @@ #include #include +#include "QObjectPtr.h" #include "ModDetails.h" -class Mod +class Mod : public QObject { + Q_OBJECT public: enum ModType { @@ -53,6 +55,8 @@ public: MOD_LITEMOD, //!< The mod is a litemod }; + using Ptr = shared_qobject_ptr; + Mod() = default; Mod(const QFileInfo &file); explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata); diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index d8170067..e0391c01 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -134,7 +134,7 @@ void ModFolderModel::finishUpdate() QSet newSet(newList.begin(), newList.end()); #else QSet currentSet = modsIndex.keys().toSet(); - auto & newMods = m_update->mods; + auto& newMods = m_update->mods; QSet newSet = newMods.keys().toSet(); #endif @@ -142,19 +142,20 @@ void ModFolderModel::finishUpdate() { QSet kept = currentSet; kept.intersect(newSet); - for(auto & keptMod: kept) { - auto & newMod = newMods[keptMod]; + for(auto& keptMod : kept) { + auto* newMod = newMods[keptMod]; auto row = modsIndex[keptMod]; - auto & currentMod = mods[row]; - if(newMod.dateTimeChanged() == currentMod.dateTimeChanged()) { + auto currentMod = mods[row]; + if(newMod->dateTimeChanged() == currentMod->dateTimeChanged()) { // no significant change, ignore... continue; } - auto & oldMod = mods[row]; - if(oldMod.isResolving()) { - activeTickets.remove(oldMod.resolutionTicket()); + auto oldMod = mods[row]; + if(oldMod->isResolving()) { + activeTickets.remove(oldMod->resolutionTicket()); } - oldMod = newMod; + + mods[row] = newMod; resolveMod(mods[row]); emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1)); } @@ -173,9 +174,10 @@ void ModFolderModel::finishUpdate() int removedIndex = *iter; beginRemoveRows(QModelIndex(), removedIndex, removedIndex); auto removedIter = mods.begin() + removedIndex; - if(removedIter->isResolving()) { - activeTickets.remove(removedIter->resolutionTicket()); + if((*removedIter)->isResolving()) { + activeTickets.remove((*removedIter)->resolutionTicket()); } + mods.erase(removedIter); endRemoveRows(); } @@ -201,8 +203,8 @@ void ModFolderModel::finishUpdate() { modsIndex.clear(); int idx = 0; - for(auto & mod: mods) { - modsIndex[mod.internal_id()] = idx; + for(auto mod: mods) { + modsIndex[mod->internal_id()] = idx; idx++; } } @@ -217,17 +219,17 @@ void ModFolderModel::finishUpdate() } } -void ModFolderModel::resolveMod(Mod& m) +void ModFolderModel::resolveMod(Mod::Ptr m) { - if(!m.shouldResolve()) { + if(!m->shouldResolve()) { return; } - auto task = new LocalModParseTask(nextResolutionTicket, m.type(), m.fileinfo()); + auto task = new LocalModParseTask(nextResolutionTicket, m->type(), m->fileinfo()); auto result = task->result(); - result->id = m.internal_id(); + result->id = m->internal_id(); activeTickets.insert(nextResolutionTicket, result); - m.setResolving(true, nextResolutionTicket); + m->setResolving(true, nextResolutionTicket); nextResolutionTicket++; QThreadPool *threadPool = QThreadPool::globalInstance(); connect(task, &LocalModParseTask::finished, this, &ModFolderModel::finishModParse); @@ -243,8 +245,8 @@ void ModFolderModel::finishModParse(int token) auto result = *iter; activeTickets.remove(token); int row = modsIndex[result->id]; - auto & mod = mods[row]; - mod.finishResolvingWithDetails(result->details); + auto mod = mods[row]; + mod->finishResolvingWithDetails(result->details); emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); } @@ -269,9 +271,9 @@ bool ModFolderModel::isValid() return m_dir.exists() && m_dir.isReadable(); } -auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list +auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list { - std::list selected_mods; + std::list selected_mods; for (auto i : indexes) { if(i.column() != 0) continue; @@ -370,9 +372,9 @@ bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadat { for(auto mod : allMods()){ - if(mod.fileinfo().fileName() == filename){ + if(mod->fileinfo().fileName() == filename){ auto index_dir = indexDir(); - mod.destroy(index_dir, preserve_metadata); + mod->destroy(index_dir, preserve_metadata); return true; } } @@ -413,9 +415,9 @@ bool ModFolderModel::deleteMods(const QModelIndexList& indexes) if(i.column() != 0) { continue; } - Mod &m = mods[i.row()]; + auto m = mods[i.row()]; auto index_dir = indexDir(); - m.destroy(index_dir); + m->destroy(index_dir); } return true; } @@ -442,9 +444,9 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const switch (column) { case NameColumn: - return mods[row].name(); + return mods[row]->name(); case VersionColumn: { - switch(mods[row].type()) { + switch(mods[row]->type()) { case Mod::MOD_FOLDER: return tr("Folder"); case Mod::MOD_SINGLEFILE: @@ -452,23 +454,23 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const default: break; } - return mods[row].version(); + return mods[row]->version(); } case DateColumn: - return mods[row].dateTimeChanged(); + return mods[row]->dateTimeChanged(); default: return QVariant(); } case Qt::ToolTipRole: - return mods[row].internal_id(); + return mods[row]->internal_id(); case Qt::CheckStateRole: switch (column) { case ActiveColumn: - return mods[row].enabled() ? Qt::Checked : Qt::Unchecked; + return mods[row]->enabled() ? Qt::Checked : Qt::Unchecked; default: return QVariant(); } @@ -508,20 +510,20 @@ bool ModFolderModel::setModStatus(int row, ModFolderModel::ModStatusAction actio break; case Toggle: default: - desiredStatus = !mod.enabled(); + desiredStatus = !mod->enabled(); break; } - if(desiredStatus == mod.enabled()) { + if(desiredStatus == mod->enabled()) { return true; } // preserve the row, but change its ID - auto oldId = mod.internal_id(); - if(!mod.enable(!mod.enabled())) { + auto oldId = mod->internal_id(); + if(!mod->enable(!mod->enabled())) { return false; } - auto newId = mod.internal_id(); + auto newId = mod->internal_id(); if(modsIndex.contains(newId)) { // NOTE: this could handle a corner case, where we are overwriting a file, because the same 'mod' exists both enabled and disabled // But is it necessary? diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 10289f8d..04681879 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -101,13 +101,13 @@ public: { return size() == 0; } - Mod &operator[](size_t index) + Mod& operator[](size_t index) { - return mods[index]; + return *mods[index]; } - const Mod &at(size_t index) const + const Mod& at(size_t index) const { - return mods.at(index); + return *mods.at(index); } /// Reloads the mod list and returns true if the list changed. @@ -141,12 +141,12 @@ public: return { QString("%1/.index").arg(dir().absolutePath()) }; } - const QList & allMods() + const QList& allMods() { return mods; } - auto selectedMods(QModelIndexList& indexes) -> std::list; + auto selectedMods(QModelIndexList& indexes) -> std::list; public slots: void disableInteraction(bool disabled); @@ -161,7 +161,7 @@ signals: void updateFinished(); private: - void resolveMod(Mod& m); + void resolveMod(Mod::Ptr m); bool setModStatus(int index, ModStatusAction action); protected: @@ -175,5 +175,5 @@ protected: QMap modsIndex; QMap activeTickets; int nextResolutionTicket = 0; - QList mods; + QList mods; }; diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 4ffb626a..63a6ca90 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -53,33 +53,33 @@ void ModFolderLoadTask::run() // Read JAR files that don't have metadata m_mods_dir.refresh(); for (auto entry : m_mods_dir.entryInfoList()) { - Mod mod(entry); + auto* mod = new Mod(entry); - if (mod.enabled()) { - if (m_result->mods.contains(mod.internal_id())) { - m_result->mods[mod.internal_id()].setStatus(ModStatus::Installed); + if (mod->enabled()) { + if (m_result->mods.contains(mod->internal_id())) { + m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); } else { - m_result->mods[mod.internal_id()] = mod; - m_result->mods[mod.internal_id()].setStatus(ModStatus::NoMetadata); + m_result->mods[mod->internal_id()] = mod; + m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); } } else { - QString chopped_id = mod.internal_id().chopped(9); + QString chopped_id = mod->internal_id().chopped(9); if (m_result->mods.contains(chopped_id)) { - m_result->mods[mod.internal_id()] = mod; + m_result->mods[mod->internal_id()] = mod; - auto metadata = m_result->mods[chopped_id].metadata(); + auto metadata = m_result->mods[chopped_id]->metadata(); if (metadata) { - mod.setMetadata(*metadata); + mod->setMetadata(*metadata); - m_result->mods[mod.internal_id()].setStatus(ModStatus::Installed); + m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); m_result->mods.remove(chopped_id); } } else { - m_result->mods[mod.internal_id()] = mod; - m_result->mods[mod.internal_id()].setStatus(ModStatus::NoMetadata); + m_result->mods[mod->internal_id()] = mod; + m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); } } } @@ -97,8 +97,8 @@ void ModFolderLoadTask::getFromMetadata() return; } - Mod mod(m_mods_dir, metadata); - mod.setStatus(ModStatus::NotInstalled); - m_result->mods[mod.internal_id()] = mod; + auto* mod = new Mod(m_mods_dir, metadata); + mod->setStatus(ModStatus::NotInstalled); + m_result->mods[mod->internal_id()] = mod; } } diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h index 088f873e..7568fdf5 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h @@ -48,7 +48,7 @@ class ModFolderLoadTask : public QObject, public QRunnable Q_OBJECT public: struct Result { - QMap mods; + QMap mods; }; using ResultPtr = std::shared_ptr; ResultPtr result() const { -- cgit From 650af5eb64d3c560044cf1e806159f1d64985aa6 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 6 Jul 2022 13:21:06 -0300 Subject: change: use ModStatus as a simple member instead of a pointer Signed-off-by: flow --- launcher/minecraft/mod/Mod.cpp | 9 +++------ launcher/minecraft/mod/Mod.h | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 7227fc94..588d76e3 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -147,10 +147,7 @@ void Mod::setStatus(ModStatus status) if (m_localDetails) { m_localDetails->status = status; } else { - if (!m_temp_status.get()) - m_temp_status.reset(new ModStatus()); - - *m_temp_status = status; + m_temp_status = status; } } void Mod::setMetadata(const Metadata::ModStruct& metadata) @@ -222,7 +219,7 @@ auto Mod::authors() const -> QStringList auto Mod::status() const -> ModStatus { if (!m_localDetails) - return m_temp_status ? *m_temp_status : ModStatus::NoMetadata; + return m_temp_status; return details().status; } @@ -246,7 +243,7 @@ void Mod::finishResolvingWithDetails(std::shared_ptr details) m_resolved = true; m_localDetails = details; - setStatus(m_temp_status ? *m_temp_status : ModStatus::NoMetadata); + setStatus(m_temp_status); if (m_localDetails && m_temp_metadata && m_temp_metadata->isValid()) { setMetadata(*m_temp_metadata); diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 3d3becd7..7a13e44b 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -115,7 +115,7 @@ protected: std::shared_ptr m_temp_metadata; /* Set the mod status while it doesn't have local details just yet */ - std::shared_ptr m_temp_status; + ModStatus m_temp_status = ModStatus::NoMetadata; std::shared_ptr m_localDetails; -- cgit From de9e304236ac0c11dd2b6bfb8b6f55943349c0e9 Mon Sep 17 00:00:00 2001 From: flow Date: Sun, 10 Jul 2022 15:15:25 -0300 Subject: fix: std::list -> QList Qt6 removed Qlist::toStdList() :sob: Signed-off-by: flow --- launcher/minecraft/mod/ModFolderModel.cpp | 4 ++-- launcher/minecraft/mod/ModFolderModel.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index e0391c01..c4449b2a 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -271,9 +271,9 @@ bool ModFolderModel::isValid() return m_dir.exists() && m_dir.isReadable(); } -auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list +auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList { - std::list selected_mods; + QList selected_mods; for (auto i : indexes) { if(i.column() != 0) continue; diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 04681879..a7d3ece0 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -146,7 +146,7 @@ public: return mods; } - auto selectedMods(QModelIndexList& indexes) -> std::list; + auto selectedMods(QModelIndexList& indexes) -> QList; public slots: void disableInteraction(bool disabled); -- cgit From 54b335711acac5e57e94bc9cb81c751c9b2872c5 Mon Sep 17 00:00:00 2001 From: flow Date: Sun, 17 Jul 2022 11:56:23 -0300 Subject: fix: raw-pointers and leaks in ModFolderLoadTask Co-authored-by: timoreo Signed-off-by: flow --- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 3 +-- launcher/minecraft/mod/tasks/ModFolderLoadTask.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'launcher/minecraft/mod') diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index c4449b2a..112d219e 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -143,7 +143,7 @@ void ModFolderModel::finishUpdate() QSet kept = currentSet; kept.intersect(newSet); for(auto& keptMod : kept) { - auto* newMod = newMods[keptMod]; + auto newMod = newMods[keptMod]; auto row = modsIndex[keptMod]; auto currentMod = mods[row]; if(newMod->dateTimeChanged() == currentMod->dateTimeChanged()) { diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 63a6ca90..a2e055ba 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -36,7 +36,6 @@ #include "ModFolderLoadTask.h" -#include "Application.h" #include "minecraft/mod/MetadataHandler.h" ModFolderLoadTask::ModFolderLoadTask(QDir& mods_dir, QDir& index_dir, bool is_indexed) @@ -53,7 +52,7 @@ void ModFolderLoadTask::run() // Read JAR files that don't have metadata m_mods_dir.refresh(); for (auto entry : m_mods_dir.entryInfoList()) { - auto* mod = new Mod(entry); + Mod::Ptr mod(new Mod(entry)); if (mod->enabled()) { if (m_result->mods.contains(mod->internal_id())) { diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h index 7568fdf5..0b6bb6cc 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h @@ -48,7 +48,7 @@ class ModFolderLoadTask : public QObject, public QRunnable Q_OBJECT public: struct Result { - QMap mods; + QMap mods; }; using ResultPtr = std::shared_ptr; ResultPtr result() const { -- cgit