From 40ccd1a46910012f80285f7b6982a5919e2a9dcf Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 4 Jun 2022 23:11:25 -0300 Subject: [PATCH] fix: handling of incomplete mods (i.e. mods without ModDetails that may have metadata) --- launcher/minecraft/mod/Mod.cpp | 44 ++++++++++++++++++++++++---------- launcher/minecraft/mod/Mod.h | 8 +++++-- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 71a32d32..39c7efd8 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -58,8 +58,6 @@ Mod::Mod(const QFileInfo& file) Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata) : m_file(mods_dir.absoluteFilePath(metadata.filename)) - // It is weird, but name is not reliable for comparing with the JAR files name - // FIXME: Maybe use hash when implemented? , m_internal_id(metadata.filename) , m_name(metadata.name) { @@ -131,7 +129,7 @@ auto Mod::enable(bool value) -> bool return false; } else { path += ".disabled"; - + if (!file.rename(path)) return false; } @@ -145,16 +143,22 @@ auto Mod::enable(bool value) -> bool void Mod::setStatus(ModStatus status) { - if(m_localDetails.get()) + if (m_localDetails) { m_localDetails->status = status; + } else { + m_temp_status = status; + } } void Mod::setMetadata(Metadata::ModStruct* metadata) { - if(status() == ModStatus::NoMetadata) + if (status() == ModStatus::NoMetadata) setStatus(ModStatus::Installed); - if(m_localDetails.get()) + if (m_localDetails) { m_localDetails->metadata.reset(metadata); + } else { + m_temp_metadata.reset(metadata); + } } auto Mod::destroy(QDir& index_dir) -> bool @@ -205,20 +209,36 @@ auto Mod::authors() const -> QStringList auto Mod::status() const -> ModStatus { + if (!m_localDetails) + return m_temp_status; return details().status; } +auto Mod::metadata() -> std::shared_ptr +{ + if (m_localDetails) + return m_localDetails->metadata; + return m_temp_metadata; +} + +auto Mod::metadata() const -> const std::shared_ptr +{ + if (m_localDetails) + return m_localDetails->metadata; + return m_temp_metadata; +} + void Mod::finishResolvingWithDetails(std::shared_ptr details) { m_resolving = false; m_resolved = true; m_localDetails = details; - if (status() != ModStatus::NoMetadata - && m_temp_metadata.get() - && m_temp_metadata->isValid() && - m_localDetails.get()) { - - m_localDetails->metadata.swap(m_temp_metadata); + if (m_localDetails && m_temp_metadata && m_temp_metadata->isValid()) { + m_localDetails->metadata = m_temp_metadata; + if (status() == ModStatus::NoMetadata) + setStatus(ModStatus::Installed); } + + setStatus(m_temp_status); } diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 96d471b4..5f9c4684 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -73,8 +73,8 @@ public: auto authors() const -> QStringList; auto status() const -> ModStatus; - auto metadata() const -> const std::shared_ptr { return details().metadata; }; - auto metadata() -> std::shared_ptr { return m_localDetails->metadata; }; + auto metadata() -> std::shared_ptr; + auto metadata() const -> const std::shared_ptr; void setStatus(ModStatus status); void setMetadata(Metadata::ModStruct* metadata); @@ -109,6 +109,10 @@ protected: /* If the mod has metadata, this will be filled in the constructor, and passed to * the ModDetails when calling finishResolvingWithDetails */ 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_localDetails; bool m_enabled = true;