feat:added flame install mod metadata

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2023-08-17 00:14:49 +03:00
parent f0da16a758
commit bad44ea264
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
3 changed files with 67 additions and 15 deletions

View File

@ -51,8 +51,13 @@
#include "Application.h" #include "Application.h"
#include "Json.h"
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/LocalModUpdateTask.h"
#include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir) ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir)
: ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed)
@ -309,3 +314,47 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id)
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
} }
static const FlameAPI flameAPI;
bool ModFolderModel::installMod(QString file_path, ModPlatform::IndexedVersion& vers)
{
if (vers.addonId.isValid()) {
ModPlatform::IndexedPack pack{
vers.addonId,
ModPlatform::ResourceProvider::FLAME,
};
QEventLoop loop;
auto response = std::make_shared<QByteArray>();
auto job = flameAPI.getProject(vers.addonId.toString(), response);
QObject::connect(job.get(), &Task::failed, [&loop] { loop.quit(); });
QObject::connect(job.get(), &Task::aborted, &loop, &QEventLoop::quit);
QObject::connect(job.get(), &Task::succeeded, [response, this, &vers, &loop, &pack] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qDebug() << *response;
return;
}
try {
auto obj = Json::requireObject(Json::requireObject(doc), "data");
FlameMod::loadIndexedPack(pack, obj);
} catch (const JSONValidationError& e) {
qDebug() << doc;
qWarning() << "Error while reading mod info: " << e.cause();
}
LocalModUpdateTask update_metadata(indexDir(), pack, vers);
QObject::connect(&update_metadata, &Task::finished, &loop, &QEventLoop::quit);
update_metadata.start();
});
job->start();
loop.exec();
}
return ResourceFolderModel::installResource(file_path);
}

View File

@ -48,6 +48,7 @@
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h"
#include "modplatform/ModIndex.h"
class LegacyInstance; class LegacyInstance;
class BaseInstance; class BaseInstance;
@ -75,6 +76,7 @@ class ModFolderModel : public ResourceFolderModel {
[[nodiscard]] Task* createParseTask(Resource&) override; [[nodiscard]] Task* createParseTask(Resource&) override;
bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); } bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); }
bool installMod(QString file_path, ModPlatform::IndexedVersion& vers);
bool uninstallMod(const QString& filename, bool preserve_metadata = false); bool uninstallMod(const QString& filename, bool preserve_metadata = false);
/// Deletes all the selected mods /// Deletes all the selected mods

View File

@ -43,6 +43,8 @@
#include "FileSystem.h" #include "FileSystem.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameModIndex.h"
#include "ui/dialogs/ExportToModListDialog.h" #include "ui/dialogs/ExportToModListDialog.h"
#include "ui_MainWindow.h" #include "ui_MainWindow.h"
@ -980,11 +982,12 @@ void MainWindow::processURLs(QList<QUrl> urls)
if (url.scheme().isEmpty()) if (url.scheme().isEmpty())
url.setScheme("file"); url.setScheme("file");
ModPlatform::IndexedVersion version;
QMap<QString, QString> extra_info; QMap<QString, QString> extra_info;
QUrl local_url; QUrl local_url;
if (!url.isLocalFile()) { // download the remote resource and identify if (!url.isLocalFile()) { // download the remote resource and identify
QUrl dl_url; QUrl dl_url;
if(url.scheme() == "curseforge") { if (url.scheme() == "curseforge") {
// need to find the download link for the modpack / resource // need to find the download link for the modpack / resource
// format of url curseforge://install?addonId=IDHERE&fileId=IDHERE // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE
QUrlQuery query(url); QUrlQuery query(url);
@ -1000,20 +1003,19 @@ void MainWindow::processURLs(QList<QUrl> urls)
auto api = FlameAPI(); auto api = FlameAPI();
auto job = api.getFile(addonId, fileId, array); auto job = api.getFile(addonId, fileId, array);
QString resource_name;
connect(job.get(), &Task::failed, this, connect(job.get(), &Task::failed, this,
[this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &resource_name] { connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &version] {
qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str();
auto doc = Json::requireDocument(*array); auto doc = Json::requireDocument(*array);
auto data = Json::ensureObject(Json::ensureObject(doc.object()), "data"); auto data = Json::ensureObject(Json::ensureObject(doc.object()), "data");
// No way to find out if it's a mod or a modpack before here // No way to find out if it's a mod or a modpack before here
// And also we need to check if it ends with .zip, instead of any better way // And also we need to check if it ends with .zip, instead of any better way
auto fileName = Json::ensureString(data, "fileName"); version = FlameMod::loadIndexedPackVersion(data);
auto fileName = version.fileName;
// Have to use ensureString then use QUrl to get proper url encoding // Have to use ensureString then use QUrl to get proper url encoding
dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); dl_url = QUrl(version.downloadUrl);
if (!dl_url.isValid()) { if (!dl_url.isValid()) {
CustomMessageBox::selectable( CustomMessageBox::selectable(
this, tr("Error"), this, tr("Error"),
@ -1024,22 +1026,20 @@ void MainWindow::processURLs(QList<QUrl> urls)
} }
QFileInfo dl_file(dl_url.fileName()); QFileInfo dl_file(dl_url.fileName());
resource_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName");
}); });
{ // drop stack { // drop stack
ProgressDialog dlUrlDialod(this); ProgressDialog dlUrlDialod(this);
dlUrlDialod.setSkipButton(true, tr("Abort")); dlUrlDialod.setSkipButton(true, tr("Abort"));
dlUrlDialod.execWithTask(job.get()); dlUrlDialod.execWithTask(job.get());
} }
} else { } else {
dl_url = url; dl_url = url;
} }
if (!dl_url.isValid()) { if (!dl_url.isValid()) {
continue; // no valid url to download this resource continue; // no valid url to download this resource
} }
const QString path = dl_url.host() + '/' + dl_url.path(); const QString path = dl_url.host() + '/' + dl_url.path();
@ -1050,17 +1050,18 @@ void MainWindow::processURLs(QList<QUrl> urls)
auto archivePath = entry->getFullPath(); auto archivePath = entry->getFullPath();
bool dl_success = false; bool dl_success = false;
connect(dl_job.get(), &Task::failed, this, [this](QString reason){CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); connect(dl_job.get(), &Task::failed, this,
connect(dl_job.get(), &Task::succeeded, this, [&dl_success]{dl_success = true;}); [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
connect(dl_job.get(), &Task::succeeded, this, [&dl_success] { dl_success = true; });
{ // drop stack { // drop stack
ProgressDialog dlUrlDialod(this); ProgressDialog dlUrlDialod(this);
dlUrlDialod.setSkipButton(true, tr("Abort")); dlUrlDialod.setSkipButton(true, tr("Abort"));
dlUrlDialod.execWithTask(dl_job.get()); dlUrlDialod.execWithTask(dl_job.get());
} }
if (!dl_success) { if (!dl_success) {
continue; // no local file to identify continue; // no local file to identify
} }
local_url = QUrl::fromLocalFile(archivePath); local_url = QUrl::fromLocalFile(archivePath);
@ -1099,7 +1100,7 @@ void MainWindow::processURLs(QList<QUrl> urls)
qWarning() << "Importing of Data Packs not supported at this time. Ignoring" << localFileName; qWarning() << "Importing of Data Packs not supported at this time. Ignoring" << localFileName;
break; break;
case PackedResourceType::Mod: case PackedResourceType::Mod:
minecraftInst->loaderModList()->installMod(localFileName); minecraftInst->loaderModList()->installMod(localFileName, version);
break; break;
case PackedResourceType::ShaderPack: case PackedResourceType::ShaderPack:
minecraftInst->shaderPackList()->installResource(localFileName); minecraftInst->shaderPackList()->installResource(localFileName);