Implement data pack updating

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2025-03-26 01:30:06 +00:00
parent 9c920fbad9
commit 683df62980
No known key found for this signature in database
GPG key ID: 5E39D70B4C93C38E
2 changed files with 184 additions and 6 deletions

View file

@ -17,28 +17,46 @@
*/
#include "DataPackPage.h"
#include <ui/dialogs/ResourceUpdateDialog.h>
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/ResourceDownloadDialog.h"
DataPackPage::DataPackPage(BaseInstance* instance, std::shared_ptr<DataPackFolderModel> model, QWidget* parent)
: ExternalResourcesPage(instance, model, parent)
: ExternalResourcesPage(instance, model, parent), m_model(model)
{
ui->actionDownloadItem->setText(tr("Download packs"));
ui->actionDownloadItem->setToolTip(tr("Download data packs from online platforms"));
ui->actionDownloadItem->setText(tr("Download Packs"));
ui->actionDownloadItem->setToolTip(tr("Download data packs from online mod platforms"));
ui->actionDownloadItem->setEnabled(true);
connect(ui->actionDownloadItem, &QAction::triggered, this, &DataPackPage::downloadDataPacks);
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
ui->actionViewConfigs->setVisible(false);
connect(ui->actionDownloadItem, &QAction::triggered, this, &DataPackPage::downloadDataPacks);
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected data packs (all data packs if none are selected)"));
connect(ui->actionUpdateItem, &QAction::triggered, this, &DataPackPage::updateDataPacks);
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
auto updateMenu = new QMenu(this);
auto update = updateMenu->addAction(ui->actionUpdateItem->text());
connect(update, &QAction::triggered, this, &DataPackPage::updateDataPacks);
updateMenu->addAction(ui->actionResetItemMetadata);
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &DataPackPage::deleteDataPackMetadata);
ui->actionUpdateItem->setMenu(updateMenu);
ui->actionChangeVersion->setToolTip(tr("Change a data pack's version."));
connect(ui->actionChangeVersion, &QAction::triggered, this, &DataPackPage::changeDataPackVersion);
ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, ui->actionChangeVersion);
}
void DataPackPage::updateFrame(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous)
{
auto sourceCurrent = m_filterModel->mapToSource(current);
int row = sourceCurrent.row();
auto& dp = static_cast<DataPack&>(m_model->at(row));
auto& dp = m_model->at(row);
ui->frame->updateWithDataPack(dp);
}
@ -78,6 +96,159 @@ void DataPackPage::downloadDataPacks()
}
}
void DataPackPage::updateDataPacks()
{
if (m_instance->typeName() != "Minecraft")
return; // this is a null instance or a legacy instance
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
QMessageBox::critical(this, tr("Error"), tr("Data pack updates are unavailable when metadata is disabled!"));
return;
}
if (m_instance != nullptr && m_instance->isRunning()) {
auto response = CustomMessageBox::selectable(
this, tr("Confirm Update"),
tr("Updating data packs while the game is running may cause pack duplication and game crashes.\n"
"The old files may not be deleted as they are in use.\n"
"Are you sure you want to do this?"),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
if (response != QMessageBox::Yes)
return;
}
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
auto mods_list = m_model->selectedResources(selection);
bool use_all = mods_list.empty();
if (use_all)
mods_list = m_model->allResources();
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, false, false);
update_dialog.checkCandidates();
if (update_dialog.aborted()) {
CustomMessageBox::selectable(this, tr("Aborted"), tr("The data pack updater was aborted!"), QMessageBox::Warning)->show();
return;
}
if (update_dialog.noUpdates()) {
QString message{ tr("'%1' is up-to-date! :)").arg(mods_list.front()->name()) };
if (mods_list.size() > 1) {
if (use_all) {
message = tr("All data packs are up-to-date! :)");
} else {
message = tr("All selected data packs are up-to-date! :)");
}
}
CustomMessageBox::selectable(this, tr("Update checker"), message)->exec();
return;
}
if (update_dialog.exec()) {
auto tasks = new ConcurrentTask("Download Data Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater();
});
connect(tasks, &Task::aborted, [this, tasks]() {
CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
tasks->deleteLater();
});
connect(tasks, &Task::succeeded, [this, tasks]() {
QStringList warnings = tasks->warnings();
if (warnings.count()) {
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
}
tasks->deleteLater();
});
for (auto task : update_dialog.getTasks()) {
tasks->addTask(task);
}
ProgressDialog loadDialog(this);
loadDialog.setSkipButton(true, tr("Abort"));
loadDialog.execWithTask(tasks);
m_model->update();
}
}
void DataPackPage::deleteDataPackMetadata()
{
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
auto selectionCount = m_model->selectedDataPacks(selection).length();
if (selectionCount == 0)
return;
if (selectionCount > 1) {
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
tr("You are about to remove the metadata for %1 data packs.\n"
"Are you sure?")
.arg(selectionCount),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
if (response != QMessageBox::Yes)
return;
}
m_model->deleteMetadata(selection);
}
void DataPackPage::changeDataPackVersion()
{
if (m_instance->typeName() != "Minecraft")
return; // this is a null instance or a legacy instance
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
QMessageBox::critical(this, tr("Error"), tr("Data pack updates are unavailable when metadata is disabled!"));
return;
}
const QModelIndexList rows = ui->treeView->selectionModel()->selectedRows();
if (rows.count() != 1)
return;
Resource& resource = m_model->at(m_filterModel->mapToSource(rows[0]).row());
if (resource.metadata() == nullptr)
return;
ResourceDownload::DataPackDownloadDialog mdownload(this, m_model, m_instance);
mdownload.setResourceMetadata(resource.metadata());
if (mdownload.exec()) {
auto tasks = new ConcurrentTask("Download Data Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater();
});
connect(tasks, &Task::aborted, [this, tasks]() {
CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
tasks->deleteLater();
});
connect(tasks, &Task::succeeded, [this, tasks]() {
QStringList warnings = tasks->warnings();
if (warnings.count())
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
tasks->deleteLater();
});
for (auto& task : mdownload.getTasks()) {
tasks->addTask(task);
}
ProgressDialog loadDialog(this);
loadDialog.setSkipButton(true, tr("Abort"));
loadDialog.execWithTask(tasks);
m_model->update();
}
}
GlobalDataPackPage::GlobalDataPackPage(MinecraftInstance* instance, QWidget* parent) : QWidget(parent), m_instance(instance)
{
auto layout = new QVBoxLayout(this);