change: make Mod a QObject used as a pointer
Prevents problems when copying it around! Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
fac63541a4
commit
c4316e81e6
@ -127,7 +127,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ours
|
// ours
|
||||||
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
|
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods)
|
||||||
{
|
{
|
||||||
QuaZip zipOut(targetJarPath);
|
QuaZip zipOut(targetJarPath);
|
||||||
if (!zipOut.open(QuaZip::mdCreate))
|
if (!zipOut.open(QuaZip::mdCreate))
|
||||||
@ -141,42 +141,40 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
QSet<QString> addedFiles;
|
QSet<QString> addedFiles;
|
||||||
|
|
||||||
// Modify the jar
|
// Modify the jar
|
||||||
QListIterator<Mod> i(mods);
|
for (auto i = mods.constEnd(); i != mods.constBegin(); --i)
|
||||||
i.toBack();
|
|
||||||
while (i.hasPrevious())
|
|
||||||
{
|
{
|
||||||
const Mod &mod = i.previous();
|
const Mod* mod = *i;
|
||||||
// do not merge disabled mods.
|
// do not merge disabled mods.
|
||||||
if (!mod.enabled())
|
if (!mod->enabled())
|
||||||
continue;
|
continue;
|
||||||
if (mod.type() == Mod::MOD_ZIPFILE)
|
if (mod->type() == Mod::MOD_ZIPFILE)
|
||||||
{
|
{
|
||||||
if (!mergeZipFiles(&zipOut, mod.fileinfo(), addedFiles))
|
if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles))
|
||||||
{
|
{
|
||||||
zipOut.close();
|
zipOut.close();
|
||||||
QFile::remove(targetJarPath);
|
QFile::remove(targetJarPath);
|
||||||
qCritical() << "Failed to add" << mod.fileinfo().fileName() << "to the jar.";
|
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mod.type() == Mod::MOD_SINGLEFILE)
|
else if (mod->type() == Mod::MOD_SINGLEFILE)
|
||||||
{
|
{
|
||||||
// FIXME: buggy - does not work with addedFiles
|
// FIXME: buggy - does not work with addedFiles
|
||||||
auto filename = mod.fileinfo();
|
auto filename = mod->fileinfo();
|
||||||
if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName()))
|
if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName()))
|
||||||
{
|
{
|
||||||
zipOut.close();
|
zipOut.close();
|
||||||
QFile::remove(targetJarPath);
|
QFile::remove(targetJarPath);
|
||||||
qCritical() << "Failed to add" << mod.fileinfo().fileName() << "to the jar.";
|
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
addedFiles.insert(filename.fileName());
|
addedFiles.insert(filename.fileName());
|
||||||
}
|
}
|
||||||
else if (mod.type() == Mod::MOD_FOLDER)
|
else if (mod->type() == Mod::MOD_FOLDER)
|
||||||
{
|
{
|
||||||
// untested, but seems to be unused / not possible to reach
|
// untested, but seems to be unused / not possible to reach
|
||||||
// FIXME: buggy - does not work with addedFiles
|
// FIXME: buggy - does not work with addedFiles
|
||||||
auto filename = mod.fileinfo();
|
auto filename = mod->fileinfo();
|
||||||
QString what_to_zip = filename.absoluteFilePath();
|
QString what_to_zip = filename.absoluteFilePath();
|
||||||
QDir dir(what_to_zip);
|
QDir dir(what_to_zip);
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
@ -193,7 +191,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
{
|
{
|
||||||
zipOut.close();
|
zipOut.close();
|
||||||
QFile::remove(targetJarPath);
|
QFile::remove(targetJarPath);
|
||||||
qCritical() << "Failed to add" << mod.fileinfo().fileName() << "to the jar.";
|
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qDebug() << "Adding folder " << filename.fileName() << " from "
|
qDebug() << "Adding folder " << filename.fileName() << " from "
|
||||||
@ -204,7 +202,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
// Make sure we do not continue launching when something is missing or undefined...
|
// Make sure we do not continue launching when something is missing or undefined...
|
||||||
zipOut.close();
|
zipOut.close();
|
||||||
QFile::remove(targetJarPath);
|
QFile::remove(targetJarPath);
|
||||||
qCritical() << "Failed to add unknown mod type" << mod.fileinfo().fileName() << "to the jar.";
|
qCritical() << "Failed to add unknown mod type" << mod->fileinfo().fileName() << "to the jar.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ namespace MMCZip
|
|||||||
/**
|
/**
|
||||||
* take a source jar, add mods to it, resulting in target jar
|
* take a source jar, add mods to it, resulting in target jar
|
||||||
*/
|
*/
|
||||||
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
|
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a single file in archive by file name (not path)
|
* Find a single file in archive by file name (not path)
|
||||||
|
@ -700,24 +700,24 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
|||||||
{
|
{
|
||||||
out << QString("%1:").arg(label);
|
out << QString("%1:").arg(label);
|
||||||
auto modList = model.allMods();
|
auto modList = model.allMods();
|
||||||
std::sort(modList.begin(), modList.end(), [](Mod &a, Mod &b) {
|
std::sort(modList.begin(), modList.end(), [](Mod::Ptr a, Mod::Ptr b) {
|
||||||
auto aName = a.fileinfo().completeBaseName();
|
auto aName = a->fileinfo().completeBaseName();
|
||||||
auto bName = b.fileinfo().completeBaseName();
|
auto bName = b->fileinfo().completeBaseName();
|
||||||
return aName.localeAwareCompare(bName) < 0;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mod.enabled()) {
|
if(mod->enabled()) {
|
||||||
out << u8" [✔️] " + mod.fileinfo().completeBaseName();
|
out << u8" [✔️]" + mod->fileinfo().completeBaseName();
|
||||||
}
|
}
|
||||||
else {
|
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;
|
return m_game_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< Mod > MinecraftInstance::getJarMods() const
|
QList<Mod*> MinecraftInstance::getJarMods() const
|
||||||
{
|
{
|
||||||
auto profile = m_components->getProfile();
|
auto profile = m_components->getProfile();
|
||||||
QList<Mod> mods;
|
QList<Mod*> mods;
|
||||||
for (auto jarmod : profile->getJarMods())
|
for (auto jarmod : profile->getJarMods())
|
||||||
{
|
{
|
||||||
QStringList jar, temp1, temp2, temp3;
|
QStringList jar, temp1, temp2, temp3;
|
||||||
jarmod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, jarmodsPath().absolutePath());
|
jarmod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, jarmodsPath().absolutePath());
|
||||||
// QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem));
|
// QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem));
|
||||||
mods.push_back(Mod(QFileInfo(jar[0])));
|
mods.push_back(new Mod(QFileInfo(jar[0])));
|
||||||
}
|
}
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
|
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
|
||||||
QStringList extraArguments() const override;
|
QStringList extraArguments() const override;
|
||||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||||
QList<Mod> getJarMods() const;
|
QList<Mod*> getJarMods() const;
|
||||||
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
||||||
/// get arguments passed to java
|
/// get arguments passed to java
|
||||||
QStringList javaArguments() const;
|
QStringList javaArguments() const;
|
||||||
|
@ -39,10 +39,12 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
#include "QObjectPtr.h"
|
||||||
#include "ModDetails.h"
|
#include "ModDetails.h"
|
||||||
|
|
||||||
class Mod
|
class Mod : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum ModType
|
enum ModType
|
||||||
{
|
{
|
||||||
@ -53,6 +55,8 @@ public:
|
|||||||
MOD_LITEMOD, //!< The mod is a litemod
|
MOD_LITEMOD, //!< The mod is a litemod
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Ptr = shared_qobject_ptr<Mod>;
|
||||||
|
|
||||||
Mod() = default;
|
Mod() = default;
|
||||||
Mod(const QFileInfo &file);
|
Mod(const QFileInfo &file);
|
||||||
explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata);
|
explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata);
|
||||||
|
@ -134,7 +134,7 @@ void ModFolderModel::finishUpdate()
|
|||||||
QSet<QString> newSet(newList.begin(), newList.end());
|
QSet<QString> newSet(newList.begin(), newList.end());
|
||||||
#else
|
#else
|
||||||
QSet<QString> currentSet = modsIndex.keys().toSet();
|
QSet<QString> currentSet = modsIndex.keys().toSet();
|
||||||
auto & newMods = m_update->mods;
|
auto& newMods = m_update->mods;
|
||||||
QSet<QString> newSet = newMods.keys().toSet();
|
QSet<QString> newSet = newMods.keys().toSet();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -142,19 +142,20 @@ void ModFolderModel::finishUpdate()
|
|||||||
{
|
{
|
||||||
QSet<QString> kept = currentSet;
|
QSet<QString> kept = currentSet;
|
||||||
kept.intersect(newSet);
|
kept.intersect(newSet);
|
||||||
for(auto & keptMod: kept) {
|
for(auto& keptMod : kept) {
|
||||||
auto & newMod = newMods[keptMod];
|
auto* newMod = newMods[keptMod];
|
||||||
auto row = modsIndex[keptMod];
|
auto row = modsIndex[keptMod];
|
||||||
auto & currentMod = mods[row];
|
auto currentMod = mods[row];
|
||||||
if(newMod.dateTimeChanged() == currentMod.dateTimeChanged()) {
|
if(newMod->dateTimeChanged() == currentMod->dateTimeChanged()) {
|
||||||
// no significant change, ignore...
|
// no significant change, ignore...
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto & oldMod = mods[row];
|
auto oldMod = mods[row];
|
||||||
if(oldMod.isResolving()) {
|
if(oldMod->isResolving()) {
|
||||||
activeTickets.remove(oldMod.resolutionTicket());
|
activeTickets.remove(oldMod->resolutionTicket());
|
||||||
}
|
}
|
||||||
oldMod = newMod;
|
|
||||||
|
mods[row] = newMod;
|
||||||
resolveMod(mods[row]);
|
resolveMod(mods[row]);
|
||||||
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
|
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
|
||||||
}
|
}
|
||||||
@ -173,9 +174,10 @@ void ModFolderModel::finishUpdate()
|
|||||||
int removedIndex = *iter;
|
int removedIndex = *iter;
|
||||||
beginRemoveRows(QModelIndex(), removedIndex, removedIndex);
|
beginRemoveRows(QModelIndex(), removedIndex, removedIndex);
|
||||||
auto removedIter = mods.begin() + removedIndex;
|
auto removedIter = mods.begin() + removedIndex;
|
||||||
if(removedIter->isResolving()) {
|
if((*removedIter)->isResolving()) {
|
||||||
activeTickets.remove(removedIter->resolutionTicket());
|
activeTickets.remove((*removedIter)->resolutionTicket());
|
||||||
}
|
}
|
||||||
|
|
||||||
mods.erase(removedIter);
|
mods.erase(removedIter);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
@ -201,8 +203,8 @@ void ModFolderModel::finishUpdate()
|
|||||||
{
|
{
|
||||||
modsIndex.clear();
|
modsIndex.clear();
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for(auto & mod: mods) {
|
for(auto mod: mods) {
|
||||||
modsIndex[mod.internal_id()] = idx;
|
modsIndex[mod->internal_id()] = idx;
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto task = new LocalModParseTask(nextResolutionTicket, m.type(), m.fileinfo());
|
auto task = new LocalModParseTask(nextResolutionTicket, m->type(), m->fileinfo());
|
||||||
auto result = task->result();
|
auto result = task->result();
|
||||||
result->id = m.internal_id();
|
result->id = m->internal_id();
|
||||||
activeTickets.insert(nextResolutionTicket, result);
|
activeTickets.insert(nextResolutionTicket, result);
|
||||||
m.setResolving(true, nextResolutionTicket);
|
m->setResolving(true, nextResolutionTicket);
|
||||||
nextResolutionTicket++;
|
nextResolutionTicket++;
|
||||||
QThreadPool *threadPool = QThreadPool::globalInstance();
|
QThreadPool *threadPool = QThreadPool::globalInstance();
|
||||||
connect(task, &LocalModParseTask::finished, this, &ModFolderModel::finishModParse);
|
connect(task, &LocalModParseTask::finished, this, &ModFolderModel::finishModParse);
|
||||||
@ -243,8 +245,8 @@ void ModFolderModel::finishModParse(int token)
|
|||||||
auto result = *iter;
|
auto result = *iter;
|
||||||
activeTickets.remove(token);
|
activeTickets.remove(token);
|
||||||
int row = modsIndex[result->id];
|
int row = modsIndex[result->id];
|
||||||
auto & mod = mods[row];
|
auto mod = mods[row];
|
||||||
mod.finishResolvingWithDetails(result->details);
|
mod->finishResolvingWithDetails(result->details);
|
||||||
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,9 +271,9 @@ bool ModFolderModel::isValid()
|
|||||||
return m_dir.exists() && m_dir.isReadable();
|
return m_dir.exists() && m_dir.isReadable();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list<Mod>
|
auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> std::list<Mod::Ptr>
|
||||||
{
|
{
|
||||||
std::list<Mod> selected_mods;
|
std::list<Mod::Ptr> selected_mods;
|
||||||
for (auto i : indexes) {
|
for (auto i : indexes) {
|
||||||
if(i.column() != 0)
|
if(i.column() != 0)
|
||||||
continue;
|
continue;
|
||||||
@ -370,9 +372,9 @@ bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadat
|
|||||||
{
|
{
|
||||||
|
|
||||||
for(auto mod : allMods()){
|
for(auto mod : allMods()){
|
||||||
if(mod.fileinfo().fileName() == filename){
|
if(mod->fileinfo().fileName() == filename){
|
||||||
auto index_dir = indexDir();
|
auto index_dir = indexDir();
|
||||||
mod.destroy(index_dir, preserve_metadata);
|
mod->destroy(index_dir, preserve_metadata);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,9 +415,9 @@ bool ModFolderModel::deleteMods(const QModelIndexList& indexes)
|
|||||||
if(i.column() != 0) {
|
if(i.column() != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Mod &m = mods[i.row()];
|
auto m = mods[i.row()];
|
||||||
auto index_dir = indexDir();
|
auto index_dir = indexDir();
|
||||||
m.destroy(index_dir);
|
m->destroy(index_dir);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -442,9 +444,9 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const
|
|||||||
switch (column)
|
switch (column)
|
||||||
{
|
{
|
||||||
case NameColumn:
|
case NameColumn:
|
||||||
return mods[row].name();
|
return mods[row]->name();
|
||||||
case VersionColumn: {
|
case VersionColumn: {
|
||||||
switch(mods[row].type()) {
|
switch(mods[row]->type()) {
|
||||||
case Mod::MOD_FOLDER:
|
case Mod::MOD_FOLDER:
|
||||||
return tr("Folder");
|
return tr("Folder");
|
||||||
case Mod::MOD_SINGLEFILE:
|
case Mod::MOD_SINGLEFILE:
|
||||||
@ -452,23 +454,23 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return mods[row].version();
|
return mods[row]->version();
|
||||||
}
|
}
|
||||||
case DateColumn:
|
case DateColumn:
|
||||||
return mods[row].dateTimeChanged();
|
return mods[row]->dateTimeChanged();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
return mods[row].internal_id();
|
return mods[row]->internal_id();
|
||||||
|
|
||||||
case Qt::CheckStateRole:
|
case Qt::CheckStateRole:
|
||||||
switch (column)
|
switch (column)
|
||||||
{
|
{
|
||||||
case ActiveColumn:
|
case ActiveColumn:
|
||||||
return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
|
return mods[row]->enabled() ? Qt::Checked : Qt::Unchecked;
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -508,20 +510,20 @@ bool ModFolderModel::setModStatus(int row, ModFolderModel::ModStatusAction actio
|
|||||||
break;
|
break;
|
||||||
case Toggle:
|
case Toggle:
|
||||||
default:
|
default:
|
||||||
desiredStatus = !mod.enabled();
|
desiredStatus = !mod->enabled();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(desiredStatus == mod.enabled()) {
|
if(desiredStatus == mod->enabled()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// preserve the row, but change its ID
|
// preserve the row, but change its ID
|
||||||
auto oldId = mod.internal_id();
|
auto oldId = mod->internal_id();
|
||||||
if(!mod.enable(!mod.enabled())) {
|
if(!mod->enable(!mod->enabled())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto newId = mod.internal_id();
|
auto newId = mod->internal_id();
|
||||||
if(modsIndex.contains(newId)) {
|
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
|
// 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?
|
// But is it necessary?
|
||||||
|
@ -101,13 +101,13 @@ public:
|
|||||||
{
|
{
|
||||||
return size() == 0;
|
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.
|
/// Reloads the mod list and returns true if the list changed.
|
||||||
@ -141,12 +141,12 @@ public:
|
|||||||
return { QString("%1/.index").arg(dir().absolutePath()) };
|
return { QString("%1/.index").arg(dir().absolutePath()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<Mod> & allMods()
|
const QList<Mod::Ptr>& allMods()
|
||||||
{
|
{
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto selectedMods(QModelIndexList& indexes) -> std::list<Mod>;
|
auto selectedMods(QModelIndexList& indexes) -> std::list<Mod::Ptr>;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void disableInteraction(bool disabled);
|
void disableInteraction(bool disabled);
|
||||||
@ -161,7 +161,7 @@ signals:
|
|||||||
void updateFinished();
|
void updateFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resolveMod(Mod& m);
|
void resolveMod(Mod::Ptr m);
|
||||||
bool setModStatus(int index, ModStatusAction action);
|
bool setModStatus(int index, ModStatusAction action);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -175,5 +175,5 @@ protected:
|
|||||||
QMap<QString, int> modsIndex;
|
QMap<QString, int> modsIndex;
|
||||||
QMap<int, LocalModParseTask::ResultPtr> activeTickets;
|
QMap<int, LocalModParseTask::ResultPtr> activeTickets;
|
||||||
int nextResolutionTicket = 0;
|
int nextResolutionTicket = 0;
|
||||||
QList<Mod> mods;
|
QList<Mod::Ptr> mods;
|
||||||
};
|
};
|
||||||
|
@ -53,33 +53,33 @@ void ModFolderLoadTask::run()
|
|||||||
// Read JAR files that don't have metadata
|
// Read JAR files that don't have metadata
|
||||||
m_mods_dir.refresh();
|
m_mods_dir.refresh();
|
||||||
for (auto entry : m_mods_dir.entryInfoList()) {
|
for (auto entry : m_mods_dir.entryInfoList()) {
|
||||||
Mod mod(entry);
|
auto* mod = new Mod(entry);
|
||||||
|
|
||||||
if (mod.enabled()) {
|
if (mod->enabled()) {
|
||||||
if (m_result->mods.contains(mod.internal_id())) {
|
if (m_result->mods.contains(mod->internal_id())) {
|
||||||
m_result->mods[mod.internal_id()].setStatus(ModStatus::Installed);
|
m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_result->mods[mod.internal_id()] = mod;
|
m_result->mods[mod->internal_id()] = mod;
|
||||||
m_result->mods[mod.internal_id()].setStatus(ModStatus::NoMetadata);
|
m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QString chopped_id = mod.internal_id().chopped(9);
|
QString chopped_id = mod->internal_id().chopped(9);
|
||||||
if (m_result->mods.contains(chopped_id)) {
|
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) {
|
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);
|
m_result->mods.remove(chopped_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_result->mods[mod.internal_id()] = mod;
|
m_result->mods[mod->internal_id()] = mod;
|
||||||
m_result->mods[mod.internal_id()].setStatus(ModStatus::NoMetadata);
|
m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,8 +97,8 @@ void ModFolderLoadTask::getFromMetadata()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod mod(m_mods_dir, metadata);
|
auto* mod = new Mod(m_mods_dir, metadata);
|
||||||
mod.setStatus(ModStatus::NotInstalled);
|
mod->setStatus(ModStatus::NotInstalled);
|
||||||
m_result->mods[mod.internal_id()] = mod;
|
m_result->mods[mod->internal_id()] = mod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class ModFolderLoadTask : public QObject, public QRunnable
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
struct Result {
|
struct Result {
|
||||||
QMap<QString, Mod> mods;
|
QMap<QString, Mod*> mods;
|
||||||
};
|
};
|
||||||
using ResultPtr = std::shared_ptr<Result>;
|
using ResultPtr = std::shared_ptr<Result>;
|
||||||
ResultPtr result() const {
|
ResultPtr result() const {
|
||||||
|
@ -12,7 +12,7 @@ class CheckUpdateTask : public Task {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CheckUpdateTask(std::list<Mod>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
CheckUpdateTask(std::list<Mod*>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
||||||
: Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder) {};
|
: Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder) {};
|
||||||
|
|
||||||
struct UpdatableMod {
|
struct UpdatableMod {
|
||||||
@ -39,10 +39,10 @@ class CheckUpdateTask : public Task {
|
|||||||
void executeTask() override = 0;
|
void executeTask() override = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void checkFailed(Mod failed, QString reason, QUrl recover_url = {});
|
void checkFailed(Mod* failed, QString reason, QUrl recover_url = {});
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::list<Mod>& m_mods;
|
std::list<Mod*>& m_mods;
|
||||||
std::list<Version>& m_game_versions;
|
std::list<Version>& m_game_versions;
|
||||||
ModAPI::ModLoaderTypes m_loaders;
|
ModAPI::ModLoaderTypes m_loaders;
|
||||||
std::shared_ptr<ModFolderModel> m_mods_folder;
|
std::shared_ptr<ModFolderModel> m_mods_folder;
|
||||||
|
@ -19,7 +19,7 @@ static ModPlatform::ProviderCapabilities ProviderCaps;
|
|||||||
static ModrinthAPI modrinth_api;
|
static ModrinthAPI modrinth_api;
|
||||||
static FlameAPI flame_api;
|
static FlameAPI flame_api;
|
||||||
|
|
||||||
EnsureMetadataTask::EnsureMetadataTask(Mod& mod, QDir dir, ModPlatform::Provider prov) : Task(nullptr), m_index_dir(dir), m_provider(prov)
|
EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Provider prov) : Task(nullptr), m_index_dir(dir), m_provider(prov)
|
||||||
{
|
{
|
||||||
auto hash = getHash(mod);
|
auto hash = getHash(mod);
|
||||||
if (hash.isEmpty())
|
if (hash.isEmpty())
|
||||||
@ -28,11 +28,11 @@ EnsureMetadataTask::EnsureMetadataTask(Mod& mod, QDir dir, ModPlatform::Provider
|
|||||||
m_mods.insert(hash, mod);
|
m_mods.insert(hash, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureMetadataTask::EnsureMetadataTask(std::list<Mod>& mods, QDir dir, ModPlatform::Provider prov)
|
EnsureMetadataTask::EnsureMetadataTask(std::list<Mod*>& mods, QDir dir, ModPlatform::Provider prov)
|
||||||
: Task(nullptr), m_index_dir(dir), m_provider(prov)
|
: Task(nullptr), m_index_dir(dir), m_provider(prov)
|
||||||
{
|
{
|
||||||
for (auto& mod : mods) {
|
for (auto* mod : mods) {
|
||||||
if (!mod.valid()) {
|
if (!mod->valid()) {
|
||||||
emitFail(mod);
|
emitFail(mod);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -47,14 +47,14 @@ EnsureMetadataTask::EnsureMetadataTask(std::list<Mod>& mods, QDir dir, ModPlatfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EnsureMetadataTask::getHash(Mod& mod)
|
QString EnsureMetadataTask::getHash(Mod* mod)
|
||||||
{
|
{
|
||||||
/* Here we create a mapping hash -> mod, because we need that relationship to parse the API routes */
|
/* Here we create a mapping hash -> mod, because we need that relationship to parse the API routes */
|
||||||
QByteArray jar_data;
|
QByteArray jar_data;
|
||||||
try {
|
try {
|
||||||
jar_data = FS::read(mod.fileinfo().absoluteFilePath());
|
jar_data = FS::read(mod->fileinfo().absoluteFilePath());
|
||||||
} catch (FS::FileSystemException& e) {
|
} catch (FS::FileSystemException& e) {
|
||||||
qCritical() << QString("Failed to open / read JAR file of %1").arg(mod.name());
|
qCritical() << QString("Failed to open / read JAR file of %1").arg(mod->name());
|
||||||
qCritical() << QString("Reason: ") << e.cause();
|
qCritical() << QString("Reason: ") << e.cause();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -95,19 +95,19 @@ void EnsureMetadataTask::executeTask()
|
|||||||
{
|
{
|
||||||
setStatus(tr("Checking if mods have metadata..."));
|
setStatus(tr("Checking if mods have metadata..."));
|
||||||
|
|
||||||
for (auto mod : m_mods) {
|
for (auto* mod : m_mods) {
|
||||||
if (!mod.valid())
|
if (!mod->valid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// They already have the right metadata :o
|
// They already have the right metadata :o
|
||||||
if (mod.status() != ModStatus::NoMetadata && mod.metadata() && mod.metadata()->provider == m_provider) {
|
if (mod->status() != ModStatus::NoMetadata && mod->metadata() && mod->metadata()->provider == m_provider) {
|
||||||
qDebug() << "Mod" << mod.name() << "already has metadata!";
|
qDebug() << "Mod" << mod->name() << "already has metadata!";
|
||||||
emitReady(mod);
|
emitReady(mod);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Folders don't have metadata
|
// Folders don't have metadata
|
||||||
if (mod.type() == Mod::MOD_FOLDER) {
|
if (mod->type() == Mod::MOD_FOLDER) {
|
||||||
emitReady(mod);
|
emitReady(mod);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ void EnsureMetadataTask::executeTask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto invalidade_leftover = [this] {
|
auto invalidade_leftover = [this] {
|
||||||
QMutableHashIterator<QString, Mod> mods_iter(m_mods);
|
QMutableHashIterator<QString, Mod*> mods_iter(m_mods);
|
||||||
while (mods_iter.hasNext()) {
|
while (mods_iter.hasNext()) {
|
||||||
auto mod = mods_iter.next();
|
auto mod = mods_iter.next();
|
||||||
emitFail(mod.value());
|
emitFail(mod.value());
|
||||||
@ -170,23 +170,23 @@ void EnsureMetadataTask::executeTask()
|
|||||||
setStatus(tr("Requesting metadata information from %1...").arg(ProviderCaps.readableName(m_provider)));
|
setStatus(tr("Requesting metadata information from %1...").arg(ProviderCaps.readableName(m_provider)));
|
||||||
else if (!m_mods.empty())
|
else if (!m_mods.empty())
|
||||||
setStatus(tr("Requesting metadata information from %1 for '%2'...")
|
setStatus(tr("Requesting metadata information from %1 for '%2'...")
|
||||||
.arg(ProviderCaps.readableName(m_provider), m_mods.begin().value().name()));
|
.arg(ProviderCaps.readableName(m_provider), m_mods.begin().value()->name()));
|
||||||
|
|
||||||
m_current_task = version_task.get();
|
m_current_task = version_task.get();
|
||||||
version_task->start();
|
version_task->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureMetadataTask::emitReady(Mod& m)
|
void EnsureMetadataTask::emitReady(Mod* m)
|
||||||
{
|
{
|
||||||
qDebug() << QString("Generated metadata for %1").arg(m.name());
|
qDebug() << QString("Generated metadata for %1").arg(m->name());
|
||||||
emit metadataReady(m);
|
emit metadataReady(m);
|
||||||
|
|
||||||
m_mods.remove(getHash(m));
|
m_mods.remove(getHash(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureMetadataTask::emitFail(Mod& m)
|
void EnsureMetadataTask::emitFail(Mod* m)
|
||||||
{
|
{
|
||||||
qDebug() << QString("Failed to generate metadata for %1").arg(m.name());
|
qDebug() << QString("Failed to generate metadata for %1").arg(m->name());
|
||||||
emit metadataFailed(m);
|
emit metadataFailed(m);
|
||||||
|
|
||||||
m_mods.remove(getHash(m));
|
m_mods.remove(getHash(m));
|
||||||
@ -224,8 +224,8 @@ NetJob::Ptr EnsureMetadataTask::modrinthVersionsTask()
|
|||||||
try {
|
try {
|
||||||
auto entry = Json::requireObject(entries, hash);
|
auto entry = Json::requireObject(entries, hash);
|
||||||
|
|
||||||
setStatus(tr("Parsing API response from Modrinth for '%1'...").arg(mod.name()));
|
setStatus(tr("Parsing API response from Modrinth for '%1'...").arg(mod->name()));
|
||||||
qDebug() << "Getting version for" << mod.name() << "from Modrinth";
|
qDebug() << "Getting version for" << mod->name() << "from Modrinth";
|
||||||
|
|
||||||
m_temp_versions.insert(hash, Modrinth::loadIndexedPackVersion(entry));
|
m_temp_versions.insert(hash, Modrinth::loadIndexedPackVersion(entry));
|
||||||
} catch (Json::JsonException& e) {
|
} catch (Json::JsonException& e) {
|
||||||
@ -284,17 +284,22 @@ NetJob::Ptr EnsureMetadataTask::modrinthProjectsTask()
|
|||||||
|
|
||||||
for (auto entry : entries) {
|
for (auto entry : entries) {
|
||||||
auto entry_obj = Json::requireObject(entry);
|
auto entry_obj = Json::requireObject(entry);
|
||||||
auto entry_id = Json::requireString(entry_obj, "id");
|
|
||||||
|
|
||||||
auto hash = addonIds.find(entry_id).value();
|
ModPlatform::IndexedPack pack;
|
||||||
|
Modrinth::loadIndexedPack(pack, entry_obj);
|
||||||
|
|
||||||
auto mod = m_mods.find(hash).value();
|
auto hash = addonIds.find(pack.addonId.toString()).value();
|
||||||
|
|
||||||
|
auto mod_iter = m_mods.find(hash);
|
||||||
|
if (mod_iter == m_mods.end()) {
|
||||||
|
qWarning() << "Invalid project id from the API response.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* mod = mod_iter.value();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setStatus(tr("Parsing API response from Modrinth for '%1'...").arg(mod.name()));
|
setStatus(tr("Parsing API response from Modrinth for '%1'...").arg(mod->name()));
|
||||||
|
|
||||||
ModPlatform::IndexedPack pack;
|
|
||||||
Modrinth::loadIndexedPack(pack, entry_obj);
|
|
||||||
|
|
||||||
modrinthCallback(pack, m_temp_versions.find(hash).value(), mod);
|
modrinthCallback(pack, m_temp_versions.find(hash).value(), mod);
|
||||||
} catch (Json::JsonException& e) {
|
} catch (Json::JsonException& e) {
|
||||||
@ -365,7 +370,7 @@ NetJob::Ptr EnsureMetadataTask::flameVersionsTask()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name()));
|
setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name()));
|
||||||
|
|
||||||
m_temp_versions.insert(fingerprint, FlameMod::loadIndexedPackVersion(file_obj));
|
m_temp_versions.insert(fingerprint, FlameMod::loadIndexedPackVersion(file_obj));
|
||||||
}
|
}
|
||||||
@ -385,7 +390,10 @@ NetJob::Ptr EnsureMetadataTask::flameProjectsTask()
|
|||||||
for (auto const& hash : m_mods.keys()) {
|
for (auto const& hash : m_mods.keys()) {
|
||||||
if (m_temp_versions.contains(hash)) {
|
if (m_temp_versions.contains(hash)) {
|
||||||
auto const& data = m_temp_versions.find(hash).value();
|
auto const& data = m_temp_versions.find(hash).value();
|
||||||
addonIds.insert(data.addonId.toString(), hash);
|
|
||||||
|
auto id_str = data.addonId.toString();
|
||||||
|
if (!id_str.isEmpty())
|
||||||
|
addonIds.insert(data.addonId.toString(), hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +437,7 @@ NetJob::Ptr EnsureMetadataTask::flameProjectsTask()
|
|||||||
auto mod = m_mods.find(hash).value();
|
auto mod = m_mods.find(hash).value();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod.name()));
|
setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name()));
|
||||||
|
|
||||||
ModPlatform::IndexedPack pack;
|
ModPlatform::IndexedPack pack;
|
||||||
FlameMod::loadIndexedPack(pack, entry_obj);
|
FlameMod::loadIndexedPack(pack, entry_obj);
|
||||||
@ -451,10 +459,10 @@ NetJob::Ptr EnsureMetadataTask::flameProjectsTask()
|
|||||||
return proj_task;
|
return proj_task;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureMetadataTask::modrinthCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod& mod)
|
void EnsureMetadataTask::modrinthCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod* mod)
|
||||||
{
|
{
|
||||||
// Prevent file name mismatch
|
// Prevent file name mismatch
|
||||||
ver.fileName = mod.fileinfo().fileName();
|
ver.fileName = mod->fileinfo().fileName();
|
||||||
if (ver.fileName.endsWith(".disabled"))
|
if (ver.fileName.endsWith(".disabled"))
|
||||||
ver.fileName.chop(9);
|
ver.fileName.chop(9);
|
||||||
|
|
||||||
@ -479,16 +487,16 @@ void EnsureMetadataTask::modrinthCallback(ModPlatform::IndexedPack& pack, ModPla
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.setMetadata(metadata);
|
mod->setMetadata(metadata);
|
||||||
|
|
||||||
emitReady(mod);
|
emitReady(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureMetadataTask::flameCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod& mod)
|
void EnsureMetadataTask::flameCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod* mod)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Prevent file name mismatch
|
// Prevent file name mismatch
|
||||||
ver.fileName = mod.fileinfo().fileName();
|
ver.fileName = mod->fileinfo().fileName();
|
||||||
if (ver.fileName.endsWith(".disabled"))
|
if (ver.fileName.endsWith(".disabled"))
|
||||||
ver.fileName.chop(9);
|
ver.fileName.chop(9);
|
||||||
|
|
||||||
@ -513,7 +521,7 @@ void EnsureMetadataTask::flameCallback(ModPlatform::IndexedPack& pack, ModPlatfo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.setMetadata(metadata);
|
mod->setMetadata(metadata);
|
||||||
|
|
||||||
emitReady(mod);
|
emitReady(mod);
|
||||||
} catch (Json::JsonException& e) {
|
} catch (Json::JsonException& e) {
|
||||||
|
@ -12,8 +12,8 @@ class EnsureMetadataTask : public Task {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EnsureMetadataTask(Mod&, QDir, ModPlatform::Provider = ModPlatform::Provider::MODRINTH);
|
EnsureMetadataTask(Mod*, QDir, ModPlatform::Provider = ModPlatform::Provider::MODRINTH);
|
||||||
EnsureMetadataTask(std::list<Mod>&, QDir, ModPlatform::Provider = ModPlatform::Provider::MODRINTH);
|
EnsureMetadataTask(std::list<Mod*>&, QDir, ModPlatform::Provider = ModPlatform::Provider::MODRINTH);
|
||||||
|
|
||||||
~EnsureMetadataTask() = default;
|
~EnsureMetadataTask() = default;
|
||||||
|
|
||||||
@ -31,21 +31,21 @@ class EnsureMetadataTask : public Task {
|
|||||||
auto flameProjectsTask() -> NetJob::Ptr;
|
auto flameProjectsTask() -> NetJob::Ptr;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
void emitReady(Mod&);
|
void emitReady(Mod*);
|
||||||
void emitFail(Mod&);
|
void emitFail(Mod*);
|
||||||
|
|
||||||
auto getHash(Mod&) -> QString;
|
auto getHash(Mod*) -> QString;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void modrinthCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod&);
|
void modrinthCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod*);
|
||||||
void flameCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod&);
|
void flameCallback(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Mod*);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void metadataReady(Mod&);
|
void metadataReady(Mod*);
|
||||||
void metadataFailed(Mod&);
|
void metadataFailed(Mod*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QString, Mod> m_mods;
|
QHash<QString, Mod*> m_mods;
|
||||||
QDir m_index_dir;
|
QDir m_index_dir;
|
||||||
ModPlatform::Provider m_provider;
|
ModPlatform::Provider m_provider;
|
||||||
|
|
||||||
|
@ -117,16 +117,16 @@ void FlameCheckUpdate::executeTask()
|
|||||||
setStatus(tr("Preparing mods for CurseForge..."));
|
setStatus(tr("Preparing mods for CurseForge..."));
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto mod : m_mods) {
|
for (auto* mod : m_mods) {
|
||||||
if (!mod.enabled()) {
|
if (!mod->enabled()) {
|
||||||
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatus(tr("Getting API response from CurseForge for '%1'").arg(mod.name()));
|
setStatus(tr("Getting API response from CurseForge for '%1'").arg(mod->name()));
|
||||||
setProgress(i++, m_mods.size());
|
setProgress(i++, m_mods.size());
|
||||||
|
|
||||||
auto latest_ver = api.getLatestVersion({ mod.metadata()->project_id.toString(), m_game_versions, m_loaders });
|
auto latest_ver = api.getLatestVersion({ mod->metadata()->project_id.toString(), m_game_versions, m_loaders });
|
||||||
|
|
||||||
// Check if we were aborted while getting the latest version
|
// Check if we were aborted while getting the latest version
|
||||||
if (m_was_aborted) {
|
if (m_was_aborted) {
|
||||||
@ -134,7 +134,7 @@ void FlameCheckUpdate::executeTask()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatus(tr("Parsing the API response from CurseForge for '%1'...").arg(mod.name()));
|
setStatus(tr("Parsing the API response from CurseForge for '%1'...").arg(mod->name()));
|
||||||
|
|
||||||
if (!latest_ver.addonId.isValid()) {
|
if (!latest_ver.addonId.isValid()) {
|
||||||
emit checkFailed(mod, tr("No valid version found for this mod. It's probably unavailable for the current game "
|
emit checkFailed(mod, tr("No valid version found for this mod. It's probably unavailable for the current game "
|
||||||
@ -142,7 +142,7 @@ void FlameCheckUpdate::executeTask()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latest_ver.downloadUrl.isEmpty() && latest_ver.fileId != mod.metadata()->file_id) {
|
if (latest_ver.downloadUrl.isEmpty() && latest_ver.fileId != mod->metadata()->file_id) {
|
||||||
auto pack = getProjectInfo(latest_ver);
|
auto pack = getProjectInfo(latest_ver);
|
||||||
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver.fileId.toString());
|
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver.fileId.toString());
|
||||||
emit checkFailed(mod, tr("Mod has a new update available, but is opted-out on CurseForge"), recover_url);
|
emit checkFailed(mod, tr("Mod has a new update available, but is opted-out on CurseForge"), recover_url);
|
||||||
@ -150,26 +150,26 @@ void FlameCheckUpdate::executeTask()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!latest_ver.hash.isEmpty() && (mod.metadata()->hash != latest_ver.hash || mod.status() == ModStatus::NotInstalled)) {
|
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
|
||||||
// Fake pack with the necessary info to pass to the download task :)
|
// Fake pack with the necessary info to pass to the download task :)
|
||||||
ModPlatform::IndexedPack pack;
|
ModPlatform::IndexedPack pack;
|
||||||
pack.name = mod.name();
|
pack.name = mod->name();
|
||||||
pack.slug = mod.metadata()->slug;
|
pack.slug = mod->metadata()->slug;
|
||||||
pack.addonId = mod.metadata()->project_id;
|
pack.addonId = mod->metadata()->project_id;
|
||||||
pack.websiteUrl = mod.homeurl();
|
pack.websiteUrl = mod->homeurl();
|
||||||
for (auto& author : mod.authors())
|
for (auto& author : mod->authors())
|
||||||
pack.authors.append({ author });
|
pack.authors.append({ author });
|
||||||
pack.description = mod.description();
|
pack.description = mod->description();
|
||||||
pack.provider = ModPlatform::Provider::FLAME;
|
pack.provider = ModPlatform::Provider::FLAME;
|
||||||
|
|
||||||
auto old_version = mod.version();
|
auto old_version = mod->version();
|
||||||
if (old_version.isEmpty() && mod.status() != ModStatus::NotInstalled) {
|
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
|
||||||
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod.metadata()->file_id.toInt());
|
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
|
||||||
old_version = current_ver.version;
|
old_version = current_ver.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto download_task = new ModDownloadTask(pack, latest_ver, m_mods_folder);
|
auto download_task = new ModDownloadTask(pack, latest_ver, m_mods_folder);
|
||||||
m_updatable.emplace_back(mod.name(), mod.metadata()->hash, old_version, latest_ver.version,
|
m_updatable.emplace_back(pack.name, mod->metadata()->hash, old_version, latest_ver.version,
|
||||||
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
||||||
ModPlatform::Provider::FLAME, download_task);
|
ModPlatform::Provider::FLAME, download_task);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ class FlameCheckUpdate : public CheckUpdateTask {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FlameCheckUpdate(std::list<Mod>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
FlameCheckUpdate(std::list<Mod*>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
||||||
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -27,29 +27,29 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
setStatus(tr("Preparing mods for Modrinth..."));
|
setStatus(tr("Preparing mods for Modrinth..."));
|
||||||
setProgress(0, 3);
|
setProgress(0, 3);
|
||||||
|
|
||||||
QHash<QString, Mod> mappings;
|
QHash<QString, Mod*> mappings;
|
||||||
|
|
||||||
// Create all hashes
|
// Create all hashes
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
auto best_hash_type = ProviderCaps.hashType(ModPlatform::Provider::MODRINTH).first();
|
auto best_hash_type = ProviderCaps.hashType(ModPlatform::Provider::MODRINTH).first();
|
||||||
for (auto mod : m_mods) {
|
for (auto* mod : m_mods) {
|
||||||
if (!mod.enabled()) {
|
if (!mod->enabled()) {
|
||||||
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hash = mod.metadata()->hash;
|
auto hash = mod->metadata()->hash;
|
||||||
|
|
||||||
// Sadly the API can only handle one hash type per call, se we
|
// Sadly the API can only handle one hash type per call, se we
|
||||||
// need to generate a new hash if the current one is innadequate
|
// need to generate a new hash if the current one is innadequate
|
||||||
// (though it will rarely happen, if at all)
|
// (though it will rarely happen, if at all)
|
||||||
if (mod.metadata()->hash_format != best_hash_type) {
|
if (mod->metadata()->hash_format != best_hash_type) {
|
||||||
QByteArray jar_data;
|
QByteArray jar_data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
jar_data = FS::read(mod.fileinfo().absoluteFilePath());
|
jar_data = FS::read(mod->fileinfo().absoluteFilePath());
|
||||||
} catch (FS::FileSystemException& e) {
|
} catch (FS::FileSystemException& e) {
|
||||||
qCritical() << QString("Failed to open / read JAR file of %1").arg(mod.name());
|
qCritical() << QString("Failed to open / read JAR file of %1").arg(mod->name());
|
||||||
qCritical() << QString("Reason: ") << e.cause();
|
qCritical() << QString("Reason: ") << e.cause();
|
||||||
|
|
||||||
failed(e.what());
|
failed(e.what());
|
||||||
@ -90,7 +90,7 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
// If the returned project is empty, but we have Modrinth metadata,
|
// If the returned project is empty, but we have Modrinth metadata,
|
||||||
// it means this specific version is not available
|
// it means this specific version is not available
|
||||||
if (project_obj.isEmpty()) {
|
if (project_obj.isEmpty()) {
|
||||||
qDebug() << "Mod " << mappings.find(hash).value().name() << " got an empty response.";
|
qDebug() << "Mod " << mappings.find(hash).value()->name() << " got an empty response.";
|
||||||
qDebug() << "Hash: " << hash;
|
qDebug() << "Hash: " << hash;
|
||||||
|
|
||||||
emit checkFailed(
|
emit checkFailed(
|
||||||
@ -134,24 +134,24 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
auto mod = *mod_iter;
|
auto mod = *mod_iter;
|
||||||
|
|
||||||
auto key = project_ver.hash;
|
auto key = project_ver.hash;
|
||||||
if ((key != hash && project_ver.is_preferred) || (mod.status() == ModStatus::NotInstalled)) {
|
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
|
||||||
if (mod.version() == project_ver.version_number)
|
if (mod->version() == project_ver.version_number)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Fake pack with the necessary info to pass to the download task :)
|
// Fake pack with the necessary info to pass to the download task :)
|
||||||
ModPlatform::IndexedPack pack;
|
ModPlatform::IndexedPack pack;
|
||||||
pack.name = mod.name();
|
pack.name = mod->name();
|
||||||
pack.slug = mod.metadata()->slug;
|
pack.slug = mod->metadata()->slug;
|
||||||
pack.addonId = mod.metadata()->project_id;
|
pack.addonId = mod->metadata()->project_id;
|
||||||
pack.websiteUrl = mod.homeurl();
|
pack.websiteUrl = mod->homeurl();
|
||||||
for (auto& author : mod.authors())
|
for (auto& author : mod->authors())
|
||||||
pack.authors.append({ author });
|
pack.authors.append({ author });
|
||||||
pack.description = mod.description();
|
pack.description = mod->description();
|
||||||
pack.provider = ModPlatform::Provider::MODRINTH;
|
pack.provider = ModPlatform::Provider::MODRINTH;
|
||||||
|
|
||||||
auto download_task = new ModDownloadTask(pack, project_ver, m_mods_folder);
|
auto download_task = new ModDownloadTask(pack, project_ver, m_mods_folder);
|
||||||
|
|
||||||
m_updatable.emplace_back(mod.name(), hash, mod.version(), project_ver.version_number, project_ver.changelog,
|
m_updatable.emplace_back(pack.name, hash, mod->version(), project_ver.version_number, project_ver.changelog,
|
||||||
ModPlatform::Provider::MODRINTH, download_task);
|
ModPlatform::Provider::MODRINTH, download_task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ class ModrinthCheckUpdate : public CheckUpdateTask {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModrinthCheckUpdate(std::list<Mod>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
ModrinthCheckUpdate(std::list<Mod*>& mods, std::list<Version>& mcVersions, ModAPI::ModLoaderTypes loaders, std::shared_ptr<ModFolderModel> mods_folder)
|
||||||
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static ModAPI::ModLoaderTypes mcLoaders(BaseInstance* inst)
|
|||||||
ModUpdateDialog::ModUpdateDialog(QWidget* parent,
|
ModUpdateDialog::ModUpdateDialog(QWidget* parent,
|
||||||
BaseInstance* instance,
|
BaseInstance* instance,
|
||||||
const std::shared_ptr<ModFolderModel> mods,
|
const std::shared_ptr<ModFolderModel> mods,
|
||||||
std::list<Mod>& search_for)
|
std::list<Mod::Ptr>& search_for)
|
||||||
: ReviewMessageBox(parent, tr("Confirm mods to update"), "")
|
: ReviewMessageBox(parent, tr("Confirm mods to update"), "")
|
||||||
, m_parent(parent)
|
, m_parent(parent)
|
||||||
, m_mod_model(mods)
|
, m_mod_model(mods)
|
||||||
@ -63,7 +63,7 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
for (const auto& failed : m_failed_metadata) {
|
for (const auto& failed : m_failed_metadata) {
|
||||||
const auto& mod = std::get<0>(failed);
|
const auto& mod = std::get<0>(failed);
|
||||||
const auto& reason = std::get<1>(failed);
|
const auto& reason = std::get<1>(failed);
|
||||||
text += tr("Mod name: %1<br>File name: %2<br>Reason: %3<br><br>").arg(mod.name(), mod.fileinfo().fileName(), reason);
|
text += tr("Mod name: %1<br>File name: %2<br>Reason: %3<br><br>").arg(mod->name(), mod->fileinfo().fileName(), reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollMessageBox message_dialog(m_parent, tr("Metadata generation failed"),
|
ScrollMessageBox message_dialog(m_parent, tr("Metadata generation failed"),
|
||||||
@ -86,14 +86,14 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
if (!m_modrinth_to_update.empty()) {
|
if (!m_modrinth_to_update.empty()) {
|
||||||
m_modrinth_check_task = new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model);
|
m_modrinth_check_task = new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model);
|
||||||
connect(m_modrinth_check_task, &CheckUpdateTask::checkFailed, this,
|
connect(m_modrinth_check_task, &CheckUpdateTask::checkFailed, this,
|
||||||
[this](Mod mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); });
|
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); });
|
||||||
check_task.addTask(m_modrinth_check_task);
|
check_task.addTask(m_modrinth_check_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_flame_to_update.empty()) {
|
if (!m_flame_to_update.empty()) {
|
||||||
m_flame_check_task = new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model);
|
m_flame_check_task = new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model);
|
||||||
connect(m_flame_check_task, &CheckUpdateTask::checkFailed, this,
|
connect(m_flame_check_task, &CheckUpdateTask::checkFailed, this,
|
||||||
[this](Mod mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); });
|
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); });
|
||||||
check_task.addTask(m_flame_check_task);
|
check_task.addTask(m_flame_check_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,9 +152,9 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
const auto& reason = std::get<1>(failed);
|
const auto& reason = std::get<1>(failed);
|
||||||
const auto& recover_url = std::get<2>(failed);
|
const auto& recover_url = std::get<2>(failed);
|
||||||
|
|
||||||
qDebug() << mod.name() << " failed to check for updates!";
|
qDebug() << mod->name() << " failed to check for updates!";
|
||||||
|
|
||||||
text += tr("Mod name: %1").arg(mod.name()) + "<br>";
|
text += tr("Mod name: %1").arg(mod->name()) + "<br>";
|
||||||
if (!reason.isEmpty())
|
if (!reason.isEmpty())
|
||||||
text += tr("Reason: %1").arg(reason) + "<br>";
|
text += tr("Reason: %1").arg(reason) + "<br>";
|
||||||
if (!recover_url.isEmpty())
|
if (!recover_url.isEmpty())
|
||||||
@ -205,15 +205,15 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
|
|
||||||
// A better use of data structures here could remove the need for this QHash
|
// A better use of data structures here could remove the need for this QHash
|
||||||
QHash<QString, bool> should_try_others;
|
QHash<QString, bool> should_try_others;
|
||||||
std::list<Mod> modrinth_tmp;
|
std::list<Mod*> modrinth_tmp;
|
||||||
std::list<Mod> flame_tmp;
|
std::list<Mod*> flame_tmp;
|
||||||
|
|
||||||
bool confirm_rest = false;
|
bool confirm_rest = false;
|
||||||
bool try_others_rest = false;
|
bool try_others_rest = false;
|
||||||
bool skip_rest = false;
|
bool skip_rest = false;
|
||||||
ModPlatform::Provider provider_rest = ModPlatform::Provider::MODRINTH;
|
ModPlatform::Provider provider_rest = ModPlatform::Provider::MODRINTH;
|
||||||
|
|
||||||
auto addToTmp = [&](Mod& m, ModPlatform::Provider p) {
|
auto addToTmp = [&](Mod* m, ModPlatform::Provider p) {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case ModPlatform::Provider::MODRINTH:
|
case ModPlatform::Provider::MODRINTH:
|
||||||
modrinth_tmp.push_back(m);
|
modrinth_tmp.push_back(m);
|
||||||
@ -224,9 +224,10 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto& candidate : m_candidates) {
|
for (auto candidate : m_candidates) {
|
||||||
if (candidate.status() != ModStatus::NoMetadata) {
|
auto* candidate_ptr = candidate.get();
|
||||||
onMetadataEnsured(candidate);
|
if (candidate->status() != ModStatus::NoMetadata) {
|
||||||
|
onMetadataEnsured(candidate_ptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +235,8 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (confirm_rest) {
|
if (confirm_rest) {
|
||||||
addToTmp(candidate, provider_rest);
|
addToTmp(candidate_ptr, provider_rest);
|
||||||
should_try_others.insert(candidate.internal_id(), try_others_rest);
|
should_try_others.insert(candidate->internal_id(), try_others_rest);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +244,7 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
chooser.setDescription(tr("This mod (%1) does not have a metadata yet. We need to create one in order to keep relevant "
|
chooser.setDescription(tr("This mod (%1) does not have a metadata yet. We need to create one in order to keep relevant "
|
||||||
"information on how to update this "
|
"information on how to update this "
|
||||||
"mod. To do this, please select a mod provider from which we can search for updates for %1.")
|
"mod. To do this, please select a mod provider from which we can search for updates for %1.")
|
||||||
.arg(candidate.name()));
|
.arg(candidate->name()));
|
||||||
auto confirmed = chooser.exec() == QDialog::DialogCode::Accepted;
|
auto confirmed = chooser.exec() == QDialog::DialogCode::Accepted;
|
||||||
|
|
||||||
auto response = chooser.getResponse();
|
auto response = chooser.getResponse();
|
||||||
@ -256,26 +257,26 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
try_others_rest = response.try_others;
|
try_others_rest = response.try_others;
|
||||||
}
|
}
|
||||||
|
|
||||||
should_try_others.insert(candidate.internal_id(), response.try_others);
|
should_try_others.insert(candidate->internal_id(), response.try_others);
|
||||||
|
|
||||||
if (confirmed)
|
if (confirmed)
|
||||||
addToTmp(candidate, response.chosen);
|
addToTmp(candidate_ptr, response.chosen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!modrinth_tmp.empty()) {
|
if (!modrinth_tmp.empty()) {
|
||||||
auto* modrinth_task = new EnsureMetadataTask(modrinth_tmp, index_dir, ModPlatform::Provider::MODRINTH);
|
auto* modrinth_task = new EnsureMetadataTask(modrinth_tmp, index_dir, ModPlatform::Provider::MODRINTH);
|
||||||
connect(modrinth_task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); });
|
connect(modrinth_task, &EnsureMetadataTask::metadataReady, [this](Mod* candidate) { onMetadataEnsured(candidate); });
|
||||||
connect(modrinth_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod& candidate) {
|
connect(modrinth_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod* candidate) {
|
||||||
onMetadataFailed(candidate, should_try_others.find(candidate.internal_id()).value(), ModPlatform::Provider::MODRINTH);
|
onMetadataFailed(candidate, should_try_others.find(candidate->internal_id()).value(), ModPlatform::Provider::MODRINTH);
|
||||||
});
|
});
|
||||||
seq.addTask(modrinth_task);
|
seq.addTask(modrinth_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flame_tmp.empty()) {
|
if (!flame_tmp.empty()) {
|
||||||
auto* flame_task = new EnsureMetadataTask(flame_tmp, index_dir, ModPlatform::Provider::FLAME);
|
auto* flame_task = new EnsureMetadataTask(flame_tmp, index_dir, ModPlatform::Provider::FLAME);
|
||||||
connect(flame_task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); });
|
connect(flame_task, &EnsureMetadataTask::metadataReady, [this](Mod* candidate) { onMetadataEnsured(candidate); });
|
||||||
connect(flame_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod& candidate) {
|
connect(flame_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod* candidate) {
|
||||||
onMetadataFailed(candidate, should_try_others.find(candidate.internal_id()).value(), ModPlatform::Provider::FLAME);
|
onMetadataFailed(candidate, should_try_others.find(candidate->internal_id()).value(), ModPlatform::Provider::FLAME);
|
||||||
});
|
});
|
||||||
seq.addTask(flame_task);
|
seq.addTask(flame_task);
|
||||||
}
|
}
|
||||||
@ -290,13 +291,13 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
return (ret_metadata != QDialog::DialogCode::Rejected);
|
return (ret_metadata != QDialog::DialogCode::Rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModUpdateDialog::onMetadataEnsured(Mod& mod)
|
void ModUpdateDialog::onMetadataEnsured(Mod* mod)
|
||||||
{
|
{
|
||||||
// When the mod is a folder, for instance
|
// When the mod is a folder, for instance
|
||||||
if (!mod.metadata())
|
if (!mod->metadata())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (mod.metadata()->provider) {
|
switch (mod->metadata()->provider) {
|
||||||
case ModPlatform::Provider::MODRINTH:
|
case ModPlatform::Provider::MODRINTH:
|
||||||
m_modrinth_to_update.push_back(mod);
|
m_modrinth_to_update.push_back(mod);
|
||||||
break;
|
break;
|
||||||
@ -318,14 +319,14 @@ ModPlatform::Provider next(ModPlatform::Provider p)
|
|||||||
return ModPlatform::Provider::FLAME;
|
return ModPlatform::Provider::FLAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModUpdateDialog::onMetadataFailed(Mod& mod, bool try_others, ModPlatform::Provider first_choice)
|
void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::Provider first_choice)
|
||||||
{
|
{
|
||||||
if (try_others) {
|
if (try_others) {
|
||||||
auto index_dir = indexDir();
|
auto index_dir = indexDir();
|
||||||
|
|
||||||
auto* task = new EnsureMetadataTask(mod, index_dir, next(first_choice));
|
auto* task = new EnsureMetadataTask(mod, index_dir, next(first_choice));
|
||||||
connect(task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); });
|
connect(task, &EnsureMetadataTask::metadataReady, [this](Mod* candidate) { onMetadataEnsured(candidate); });
|
||||||
connect(task, &EnsureMetadataTask::metadataFailed, [this](Mod& candidate) { onMetadataFailed(candidate, false); });
|
connect(task, &EnsureMetadataTask::metadataFailed, [this](Mod* candidate) { onMetadataFailed(candidate, false); });
|
||||||
|
|
||||||
m_second_try_metadata->addTask(task);
|
m_second_try_metadata->addTask(task);
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,7 @@ class ModUpdateDialog final : public ReviewMessageBox {
|
|||||||
explicit ModUpdateDialog(QWidget* parent,
|
explicit ModUpdateDialog(QWidget* parent,
|
||||||
BaseInstance* instance,
|
BaseInstance* instance,
|
||||||
const std::shared_ptr<ModFolderModel> mod_model,
|
const std::shared_ptr<ModFolderModel> mod_model,
|
||||||
std::list<Mod>& search_for);
|
std::list<Mod::Ptr>& search_for);
|
||||||
|
|
||||||
void checkCandidates();
|
void checkCandidates();
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ class ModUpdateDialog final : public ReviewMessageBox {
|
|||||||
auto ensureMetadata() -> bool;
|
auto ensureMetadata() -> bool;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onMetadataEnsured(Mod&);
|
void onMetadataEnsured(Mod*);
|
||||||
void onMetadataFailed(Mod&, bool try_others = false, ModPlatform::Provider first_choice = ModPlatform::Provider::MODRINTH);
|
void onMetadataFailed(Mod*, bool try_others = false, ModPlatform::Provider first_choice = ModPlatform::Provider::MODRINTH);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget* m_parent;
|
QWidget* m_parent;
|
||||||
@ -45,13 +45,13 @@ class ModUpdateDialog final : public ReviewMessageBox {
|
|||||||
|
|
||||||
const std::shared_ptr<ModFolderModel> m_mod_model;
|
const std::shared_ptr<ModFolderModel> m_mod_model;
|
||||||
|
|
||||||
std::list<Mod>& m_candidates;
|
std::list<Mod::Ptr>& m_candidates;
|
||||||
std::list<Mod> m_modrinth_to_update;
|
std::list<Mod*> m_modrinth_to_update;
|
||||||
std::list<Mod> m_flame_to_update;
|
std::list<Mod*> m_flame_to_update;
|
||||||
|
|
||||||
SequentialTask* m_second_try_metadata;
|
SequentialTask* m_second_try_metadata;
|
||||||
std::list<std::tuple<Mod, QString>> m_failed_metadata;
|
std::list<std::tuple<Mod*, QString>> m_failed_metadata;
|
||||||
std::list<std::tuple<Mod, QString, QUrl>> m_failed_check_update;
|
std::list<std::tuple<Mod*, QString, QUrl>> m_failed_check_update;
|
||||||
|
|
||||||
QHash<QString, ModDownloadTask*> m_tasks;
|
QHash<QString, ModDownloadTask*> m_tasks;
|
||||||
BaseInstance* m_instance;
|
BaseInstance* m_instance;
|
||||||
|
@ -192,7 +192,7 @@ void ModFolderPage::updateMods()
|
|||||||
if (update_dialog.noUpdates()) {
|
if (update_dialog.noUpdates()) {
|
||||||
CustomMessageBox::selectable(this, tr("Update checker"),
|
CustomMessageBox::selectable(this, tr("Update checker"),
|
||||||
(mods_list.size() == 1)
|
(mods_list.size() == 1)
|
||||||
? tr("'%1' is up-to-date! :)").arg(mods_list.front().name())
|
? tr("'%1' is up-to-date! :)").arg(mods_list.front()->name())
|
||||||
: tr("All %1mods are up-to-date! :)").arg(use_all ? "" : (tr("selected") + " ")))
|
: tr("All %1mods are up-to-date! :)").arg(use_all ? "" : (tr("selected") + " ")))
|
||||||
->exec();
|
->exec();
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user