aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft
diff options
context:
space:
mode:
authorflow <flowlnlnln@gmail.com>2022-07-18 12:40:25 -0300
committerGitHub <noreply@github.com>2022-07-18 12:40:25 -0300
commitdec81c4f274dd8388d442062cf9fa18600aa850d (patch)
tree11bf89a63035e4bf52b4d875a63cf5872da69bdc /launcher/minecraft
parent56085310cb066c7b3899684c3e3f39fe9fd311c4 (diff)
parent54b335711acac5e57e94bc9cb81c751c9b2872c5 (diff)
downloadPrismLauncher-dec81c4f274dd8388d442062cf9fa18600aa850d.tar.gz
PrismLauncher-dec81c4f274dd8388d442062cf9fa18600aa850d.tar.bz2
PrismLauncher-dec81c4f274dd8388d442062cf9fa18600aa850d.zip
Merge pull request #588 from flowln/mod_update
Implement mod updater (:sunglasses:)
Diffstat (limited to 'launcher/minecraft')
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp24
-rw-r--r--launcher/minecraft/MinecraftInstance.h2
-rw-r--r--launcher/minecraft/mod/MetadataHandler.h22
-rw-r--r--launcher/minecraft/mod/Mod.cpp39
-rw-r--r--launcher/minecraft/mod/Mod.h12
-rw-r--r--launcher/minecraft/mod/ModFolderModel.cpp124
-rw-r--r--launcher/minecraft/mod/ModFolderModel.h18
-rw-r--r--launcher/minecraft/mod/tasks/LocalModParseTask.cpp9
-rw-r--r--launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp17
-rw-r--r--launcher/minecraft/mod/tasks/LocalModUpdateTask.h3
-rw-r--r--launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp33
-rw-r--r--launcher/minecraft/mod/tasks/ModFolderLoadTask.h2
12 files changed, 194 insertions, 111 deletions
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index abc022b6..360e754d 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -700,24 +700,24 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
{
out << QString("%1:").arg(label);
auto modList = model.allMods();
- std::sort(modList.begin(), modList.end(), [](Mod &a, Mod &b) {
- auto aName = a.fileinfo().completeBaseName();
- auto bName = b.fileinfo().completeBaseName();
+ std::sort(modList.begin(), modList.end(), [](Mod::Ptr a, Mod::Ptr b) {
+ auto aName = a->fileinfo().completeBaseName();
+ auto bName = b->fileinfo().completeBaseName();
return aName.localeAwareCompare(bName) < 0;
});
- for(auto & mod: modList)
+ for(auto mod: modList)
{
- if(mod.type() == Mod::MOD_FOLDER)
+ if(mod->type() == Mod::MOD_FOLDER)
{
- out << u8" [📁] " + mod.fileinfo().completeBaseName() + " (folder)";
+ out << u8" [📁] " + mod->fileinfo().completeBaseName() + " (folder)";
continue;
}
- if(mod.enabled()) {
- out << u8" [✔️] " + mod.fileinfo().completeBaseName();
+ if(mod->enabled()) {
+ out << u8" [✔️]" + mod->fileinfo().completeBaseName();
}
else {
- out << u8" [❌] " + mod.fileinfo().completeBaseName() + " (disabled)";
+ out << u8" [❌] " + mod->fileinfo().completeBaseName() + " (disabled)";
}
}
@@ -1136,16 +1136,16 @@ std::shared_ptr<GameOptions> MinecraftInstance::gameOptionsModel() const
return m_game_options;
}
-QList< Mod > MinecraftInstance::getJarMods() const
+QList<Mod*> MinecraftInstance::getJarMods() const
{
auto profile = m_components->getProfile();
- QList<Mod> mods;
+ QList<Mod*> mods;
for (auto jarmod : profile->getJarMods())
{
QStringList jar, temp1, temp2, temp3;
jarmod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, jarmodsPath().absolutePath());
// QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem));
- mods.push_back(Mod(QFileInfo(jar[0])));
+ mods.push_back(new Mod(QFileInfo(jar[0])));
}
return mods;
}
diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h
index 05450d41..8e1c67f2 100644
--- a/launcher/minecraft/MinecraftInstance.h
+++ b/launcher/minecraft/MinecraftInstance.h
@@ -81,7 +81,7 @@ public:
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
QStringList extraArguments() const override;
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
- QList<Mod> getJarMods() const;
+ QList<Mod*> getJarMods() const;
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
/// get arguments passed to java
QStringList javaArguments() const;
diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h
index 56962818..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,13 +47,23 @@ 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 auto get(QDir& index_dir, QString& mod_name) -> ModStruct
+ static void remove(QDir& index_dir, QVariant& mod_id)
{
- return Packwiz::V1::getIndexForMod(index_dir, mod_name);
+ Packwiz::V1::deleteModIndex(index_dir, mod_id);
+ }
+
+ static auto get(QDir& index_dir, QString mod_slug) -> ModStruct
+ {
+ return Packwiz::V1::getIndexForMod(index_dir, mod_slug);
+ }
+
+ 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 742709e3..588d76e3 100644
--- a/launcher/minecraft/mod/Mod.cpp
+++ b/launcher/minecraft/mod/Mod.cpp
@@ -150,25 +150,30 @@ void Mod::setStatus(ModStatus status)
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<Metadata::ModStruct>(std::move(metadata));
} else {
- m_temp_metadata.reset(metadata);
+ m_temp_metadata = std::make_shared<Metadata::ModStruct>(std::move(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) {
+ 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,9 +187,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 (metadata())
+ return metadata()->name;
+
return m_name;
}
@@ -235,11 +243,10 @@ void Mod::finishResolvingWithDetails(std::shared_ptr<ModDetails> details)
m_resolved = true;
m_localDetails = details;
+ setStatus(m_temp_status);
+
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 5f9c4684..7a13e44b 100644
--- a/launcher/minecraft/mod/Mod.h
+++ b/launcher/minecraft/mod/Mod.h
@@ -39,10 +39,12 @@
#include <QFileInfo>
#include <QList>
+#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>;
+
Mod() = default;
Mod(const QFileInfo &file);
explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata);
@@ -77,12 +81,12 @@ public:
auto metadata() const -> const std::shared_ptr<Metadata::ModStruct>;
void setStatus(ModStatus status);
- void setMetadata(Metadata::ModStruct* metadata);
+ void setMetadata(const Metadata::ModStruct& metadata);
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);
@@ -111,7 +115,7 @@ protected:
std::shared_ptr<Metadata::ModStruct> m_temp_metadata;
/* Set the mod status while it doesn't have local details just yet */
- ModStatus m_temp_status = ModStatus::NotInstalled;
+ ModStatus m_temp_status = ModStatus::NoMetadata;
std::shared_ptr<ModDetails> m_localDetails;
diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp
index 5ee08cbf..112d219e 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()
@@ -124,7 +134,7 @@ void ModFolderModel::finishUpdate()
QSet<QString> newSet(newList.begin(), newList.end());
#else
QSet<QString> currentSet = modsIndex.keys().toSet();
- auto & newMods = m_update->mods;
+ auto& newMods = m_update->mods;
QSet<QString> newSet = newMods.keys().toSet();
#endif
@@ -132,19 +142,20 @@ void ModFolderModel::finishUpdate()
{
QSet<QString> 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));
}
@@ -163,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();
}
@@ -191,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++;
}
}
@@ -207,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);
@@ -233,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));
}
@@ -259,6 +271,18 @@ bool ModFolderModel::isValid()
return m_dir.exists() && m_dir.isReadable();
}
+auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList<Mod::Ptr>
+{
+ QList<Mod::Ptr> 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)
{
@@ -344,6 +368,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) {
@@ -377,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;
}
@@ -406,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:
@@ -416,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();
}
@@ -472,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 24b4d358..a7d3ece0 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.
@@ -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);
@@ -139,11 +141,13 @@ public:
return { QString("%1/.index").arg(dir().absolutePath()) };
}
- const QList<Mod> & allMods()
+ const QList<Mod::Ptr>& allMods()
{
return mods;
}
+ auto selectedMods(QModelIndexList& indexes) -> QList<Mod::Ptr>;
+
public slots:
void disableInteraction(bool disabled);
@@ -157,7 +161,7 @@ signals:
void updateFinished();
private:
- void resolveMod(Mod& m);
+ void resolveMod(Mod::Ptr m);
bool setModStatus(int index, ModStatusAction action);
protected:
@@ -171,5 +175,5 @@ protected:
QMap<QString, int> modsIndex;
QMap<int, LocalModParseTask::ResultPtr> activeTickets;
int nextResolutionTicket = 0;
- QList<Mod> mods;
+ QList<Mod::Ptr> mods;
};
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 <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
+#include <QString>
#include <quazip/quazip.h>
#include <quazip/quazipfile.h>
#include <toml.h>
@@ -71,7 +72,13 @@ std::shared_ptr<ModDetails> 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:";
diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
index 1bdecb8c..4b878918 100644
--- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
@@ -44,10 +44,21 @@ void LocalModUpdateTask::executeTask()
{
setStatus(tr("Updating index for mod:\n%1").arg(m_mod.name));
- auto pw_mod = Metadata::create(m_index_dir, m_mod, m_mod_version);
- Metadata::update(m_index_dir, pw_mod);
+ 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;
+ }
- emitSucceeded();
+ auto pw_mod = Metadata::create(m_index_dir, m_mod, m_mod_version);
+ 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/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;
diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp
index 276414e4..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,33 +52,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);
+ Mod::Ptr 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(new Metadata::ModStruct(*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 +96,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..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<QString, Mod> mods;
+ QMap<QString, Mod::Ptr> mods;
};
using ResultPtr = std::shared_ptr<Result>;
ResultPtr result() const {