From a53f8d506e212f862f54e5a758fb50666ec7c3ba Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Thu, 12 Feb 2015 22:01:20 +0100 Subject: GH-366: Plain and simple modpack export/import/download Also removed the in-source QuaZIP in favour of upstream version --- gui/MainWindow.cpp | 169 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 139 insertions(+), 30 deletions(-) (limited to 'gui/MainWindow.cpp') diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index d605c891..fbb575a0 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -36,6 +36,9 @@ #include #include #include +#include + +#include #include "osutils.h" #include "userutils.h" @@ -106,6 +109,7 @@ #include #include #include +#include "logic/net/CacheDownload.h" #include "logic/tools/BaseProfiler.h" @@ -733,6 +737,25 @@ void MainWindow::setCatBackground(bool enabled) } } +static QFileInfo findRecursive(const QString &dir, const QString &name) +{ + for (const auto info : QDir(dir).entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files, QDir::DirsLast)) + { + if (info.isFile() && info.fileName() == name) + { + return info; + } + else if (info.isDir()) + { + const QFileInfo res = findRecursive(info.absoluteFilePath(), name); + if (res.isFile() && res.exists()) + { + return res; + } + } + } + return QFileInfo(); +} void MainWindow::on_actionAddInstance_triggered() { if (!MMC->minecraftlist()->isLoaded() && m_versionLoadTask && @@ -755,45 +778,104 @@ void MainWindow::on_actionAddInstance_triggered() QString instancesDir = MMC->settings()->get("InstanceDir").toString(); QString instDirName = DirNameFromString(newInstDlg.instName(), instancesDir); QString instDir = PathCombine(instancesDir, instDirName); - auto &loader = InstanceFactory::get(); - auto error = loader.createInstance(newInstance, newInstDlg.selectedVersion(), instDir); - QString errorMsg = tr("Failed to create instance %1: ").arg(instDirName); - switch (error) + const QUrl modpackUrl = newInstDlg.modpackUrl(); + if (modpackUrl.isValid()) { - case InstanceFactory::NoCreateError: - { - newInstance->setName(newInstDlg.instName()); - newInstance->setIconKey(newInstDlg.iconKey()); - newInstance->setGroupInitial(newInstDlg.instGroup()); - MMC->instances()->add(InstancePtr(newInstance)); - stringToIntList(MMC->settings()->get("ShownNotifications").toString()); - break; - } + QString archivePath; + if (modpackUrl.isLocalFile()) + { + archivePath = modpackUrl.toLocalFile(); + } + else + { + const QString path = modpackUrl.host() + '/' + QString::fromUtf8(modpackUrl.toEncoded()); + auto entry = MMC->metacache()->resolveEntry("general", path); + CacheDownloadPtr dl = CacheDownload::make(modpackUrl, entry); + NetJob job(tr("Modpack download")); + job.addNetAction(dl); + + ProgressDialog dlDialog(this); + if (dlDialog.exec(&job) != QDialog::Accepted) + { + return; + } - case InstanceFactory::InstExists: - { - errorMsg += tr("An instance with the given directory name already exists."); - CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); - return; - } + archivePath = entry->getFullPath(); + } - case InstanceFactory::CantCreateDir: - { - errorMsg += tr("Failed to create the instance directory."); - CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); - return; - } - default: - { - errorMsg += tr("Unknown instance loader error %1").arg(error); - CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); - return; + QTemporaryDir extractTmpDir; + QDir extractDir(extractTmpDir.path()); + QLOG_INFO() << "Attempting to create instance from" << archivePath; + if (JlCompress::extractDir(archivePath, extractDir.absolutePath()).isEmpty()) + { + CustomMessageBox::selectable(this, tr("Error"), + tr("Failed to extract modpack"), QMessageBox::Warning)->show(); + return; + } + const QFileInfo instanceCfgFile = findRecursive(extractDir.absolutePath(), "instance.cfg"); + if (!instanceCfgFile.isFile() || !instanceCfgFile.exists()) + { + CustomMessageBox::selectable(this, tr("Error"), tr("Archive does not contain instance.cfg"))->show(); + return; + } + if (!copyPath(instanceCfgFile.absoluteDir().absolutePath(), instDir)) + { + CustomMessageBox::selectable(this, tr("Error"), tr("Unable to copy instance"))->show(); + return; + } + + auto error = loader.loadInstance(newInstance, instDir); + QString errorMsg = tr("Failed to load instance %1: ").arg(instDirName); + switch (error) + { + case InstanceFactory::UnknownLoadError: + errorMsg += tr("Unkown error"); + CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); + return; + case InstanceFactory::NotAnInstance: + errorMsg += tr("Not an instance"); + CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); + return; + } } + else + { + auto error = loader.createInstance(newInstance, newInstDlg.selectedVersion(), instDir); + QString errorMsg = tr("Failed to create instance %1: ").arg(instDirName); + switch (error) + { + case InstanceFactory::NoCreateError: break; + case InstanceFactory::InstExists: + { + errorMsg += tr("An instance with the given directory name already exists."); + CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); + return; + } + + case InstanceFactory::CantCreateDir: + { + errorMsg += tr("Failed to create the instance directory."); + CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); + return; + } + + default: + { + errorMsg += tr("Unknown instance loader error %1").arg(error); + CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); + return; + } + } } + newInstance->setName(newInstDlg.instName()); + newInstance->setIconKey(newInstDlg.iconKey()); + newInstance->setGroupInitial(newInstDlg.instGroup()); + MMC->instances()->add(InstancePtr(newInstance)); + if (MMC->accounts()->anyAccountIsValid()) { ProgressDialog loadDialog(this); @@ -1056,6 +1138,33 @@ void MainWindow::on_actionDeleteInstance_triggered() } } +void MainWindow::on_actionExportInstance_triggered() +{ + if (m_selectedInstance) + { + const QString output = QFileDialog::getSaveFileName(this, tr("Export %1") + .arg(m_selectedInstance->name()), + QDir::homePath(), "Zip (*.zip)"); + if (output.isNull()) + { + return; + } + if (QFile::exists(output)) + { + int ret = QMessageBox::question(this, tr("Overwrite?"), tr("This file already exists. Do you want to overwrite it?"), + QMessageBox::No, QMessageBox::Yes); + if (ret == QMessageBox::No) + { + return; + } + } + if (!JlCompress::compressDir(output, m_selectedInstance->instanceRoot())) + { + QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); + } + } +} + void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) -- cgit v1.2.3