Merge pull request #27 from flowln/ftb_install_improve
This commit is contained in:
commit
46c57e120f
@ -9,9 +9,10 @@ Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr<QNetworkAcc
|
||||
|
||||
bool Flame::FileResolvingTask::abort()
|
||||
{
|
||||
bool aborted = true;
|
||||
if (m_dljob)
|
||||
return m_dljob->abort();
|
||||
return true;
|
||||
aborted &= m_dljob->abort();
|
||||
return aborted ? Task::abort() : false;
|
||||
}
|
||||
|
||||
void Flame::FileResolvingTask::executeTask()
|
||||
|
@ -65,48 +65,42 @@ void PackInstallTask::executeTask()
|
||||
void PackInstallTask::downloadPack()
|
||||
{
|
||||
setStatus(tr("Downloading zip for %1").arg(m_pack.name));
|
||||
setAbortable(false);
|
||||
|
||||
archivePath = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
|
||||
|
||||
auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
|
||||
auto entry = APPLICATION->metacache()->resolveEntry("FTBPacks", packoffset);
|
||||
netJobContainer = new NetJob("Download FTB Pack", m_network);
|
||||
|
||||
entry->setStale(true);
|
||||
QString url;
|
||||
if(m_pack.type == PackType::Private)
|
||||
{
|
||||
url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "privatepacks/%1").arg(packoffset);
|
||||
if (m_pack.type == PackType::Private) {
|
||||
url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "privatepacks/%1").arg(archivePath);
|
||||
} else {
|
||||
url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(archivePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(packoffset);
|
||||
}
|
||||
netJobContainer->addNetAction(Net::Download::makeCached(url, entry));
|
||||
archivePath = entry->getFullPath();
|
||||
netJobContainer->addNetAction(Net::Download::makeFile(url, archivePath));
|
||||
|
||||
connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
|
||||
connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
|
||||
connect(netJobContainer.get(), &NetJob::progress, this, &PackInstallTask::onDownloadProgress);
|
||||
connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::onDownloadAborted);
|
||||
|
||||
netJobContainer->start();
|
||||
|
||||
setAbortable(true);
|
||||
progress(1, 4);
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadSucceeded()
|
||||
{
|
||||
abortable = false;
|
||||
unzip();
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadFailed(QString reason)
|
||||
{
|
||||
abortable = false;
|
||||
emitFailed(reason);
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadProgress(qint64 current, qint64 total)
|
||||
{
|
||||
abortable = true;
|
||||
progress(current, total * 4);
|
||||
setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10));
|
||||
}
|
||||
@ -118,8 +112,10 @@ void PackInstallTask::onDownloadAborted()
|
||||
|
||||
void PackInstallTask::unzip()
|
||||
{
|
||||
progress(2, 4);
|
||||
setStatus(tr("Extracting modpack"));
|
||||
setAbortable(false);
|
||||
progress(2, 4);
|
||||
|
||||
QDir extractDir(m_stagingPath);
|
||||
|
||||
m_packZip.reset(new QuaZip(archivePath));
|
||||
@ -151,8 +147,8 @@ void PackInstallTask::onUnzipCanceled()
|
||||
|
||||
void PackInstallTask::install()
|
||||
{
|
||||
progress(3, 4);
|
||||
setStatus(tr("Installing modpack"));
|
||||
progress(3, 4);
|
||||
QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
|
||||
if(unzipMcDir.exists())
|
||||
{
|
||||
@ -247,11 +243,12 @@ void PackInstallTask::install()
|
||||
|
||||
bool PackInstallTask::abort()
|
||||
{
|
||||
if(abortable)
|
||||
{
|
||||
return netJobContainer->abort();
|
||||
if (!canAbort()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
netJobContainer->abort();
|
||||
return InstanceTask::abort();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,6 +58,9 @@ PackInstallTask::PackInstallTask(Modpack pack, QString version, QWidget* parent)
|
||||
|
||||
bool PackInstallTask::abort()
|
||||
{
|
||||
if (!canAbort())
|
||||
return false;
|
||||
|
||||
bool aborted = true;
|
||||
|
||||
if (m_net_job)
|
||||
@ -65,15 +68,13 @@ bool PackInstallTask::abort()
|
||||
if (m_mod_id_resolver_task)
|
||||
aborted &= m_mod_id_resolver_task->abort();
|
||||
|
||||
if (aborted)
|
||||
emitAborted();
|
||||
|
||||
return aborted;
|
||||
return aborted ? InstanceTask::abort() : false;
|
||||
}
|
||||
|
||||
void PackInstallTask::executeTask()
|
||||
{
|
||||
setStatus(tr("Getting the manifest..."));
|
||||
setAbortable(false);
|
||||
|
||||
// Find pack version
|
||||
auto version_it = std::find_if(m_pack.versions.constBegin(), m_pack.versions.constEnd(),
|
||||
@ -93,10 +94,12 @@ void PackInstallTask::executeTask()
|
||||
|
||||
QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onManifestDownloadSucceeded);
|
||||
QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onManifestDownloadFailed);
|
||||
QObject::connect(netJob, &NetJob::aborted, this, &PackInstallTask::abort);
|
||||
QObject::connect(netJob, &NetJob::progress, this, &PackInstallTask::setProgress);
|
||||
|
||||
m_net_job = netJob;
|
||||
|
||||
setAbortable(true);
|
||||
netJob->start();
|
||||
}
|
||||
|
||||
@ -130,6 +133,7 @@ void PackInstallTask::onManifestDownloadSucceeded()
|
||||
void PackInstallTask::resolveMods()
|
||||
{
|
||||
setStatus(tr("Resolving mods..."));
|
||||
setAbortable(false);
|
||||
setProgress(0, 100);
|
||||
|
||||
m_file_id_map.clear();
|
||||
@ -162,15 +166,16 @@ void PackInstallTask::resolveMods()
|
||||
|
||||
connect(m_mod_id_resolver_task.get(), &Flame::FileResolvingTask::succeeded, this, &PackInstallTask::onResolveModsSucceeded);
|
||||
connect(m_mod_id_resolver_task.get(), &Flame::FileResolvingTask::failed, this, &PackInstallTask::onResolveModsFailed);
|
||||
connect(m_mod_id_resolver_task.get(), &Flame::FileResolvingTask::aborted, this, &PackInstallTask::abort);
|
||||
connect(m_mod_id_resolver_task.get(), &Flame::FileResolvingTask::progress, this, &PackInstallTask::setProgress);
|
||||
|
||||
setAbortable(true);
|
||||
|
||||
m_mod_id_resolver_task->start();
|
||||
}
|
||||
|
||||
void PackInstallTask::onResolveModsSucceeded()
|
||||
{
|
||||
m_abortable = false;
|
||||
|
||||
QString text;
|
||||
QList<QUrl> urls;
|
||||
auto anyBlocked = false;
|
||||
@ -209,94 +214,23 @@ void PackInstallTask::onResolveModsSucceeded()
|
||||
urls);
|
||||
|
||||
if (message_dialog->exec() == QDialog::Accepted)
|
||||
downloadPack();
|
||||
createInstance();
|
||||
else
|
||||
abort();
|
||||
} else {
|
||||
downloadPack();
|
||||
createInstance();
|
||||
}
|
||||
}
|
||||
|
||||
void PackInstallTask::downloadPack()
|
||||
void PackInstallTask::createInstance()
|
||||
{
|
||||
setStatus(tr("Downloading mods..."));
|
||||
setAbortable(false);
|
||||
|
||||
auto* jobPtr = new NetJob(tr("Mod download"), APPLICATION->network());
|
||||
for (auto const& file : m_version.files) {
|
||||
if (file.serverOnly || file.url.isEmpty())
|
||||
continue;
|
||||
|
||||
QFileInfo file_info(file.name);
|
||||
auto cacheName = file_info.completeBaseName() + "-" + file.sha1 + "." + file_info.suffix();
|
||||
|
||||
auto entry = APPLICATION->metacache()->resolveEntry("ModpacksCHPacks", cacheName);
|
||||
entry->setStale(true);
|
||||
|
||||
auto relpath = FS::PathCombine("minecraft", file.path, file.name);
|
||||
auto path = FS::PathCombine(m_stagingPath, relpath);
|
||||
|
||||
if (m_files_to_copy.contains(path)) {
|
||||
qWarning() << "Ignoring" << file.url << "as a file of that path is already downloading.";
|
||||
continue;
|
||||
}
|
||||
|
||||
qDebug() << "Will download" << file.url << "to" << path;
|
||||
m_files_to_copy[path] = entry->getFullPath();
|
||||
|
||||
auto dl = Net::Download::makeCached(file.url, entry);
|
||||
if (!file.sha1.isEmpty()) {
|
||||
auto rawSha1 = QByteArray::fromHex(file.sha1.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
|
||||
}
|
||||
|
||||
jobPtr->addNetAction(dl);
|
||||
}
|
||||
|
||||
connect(jobPtr, &NetJob::succeeded, this, &PackInstallTask::onModDownloadSucceeded);
|
||||
connect(jobPtr, &NetJob::failed, this, &PackInstallTask::onModDownloadFailed);
|
||||
connect(jobPtr, &NetJob::progress, this, &PackInstallTask::setProgress);
|
||||
|
||||
m_net_job = jobPtr;
|
||||
jobPtr->start();
|
||||
|
||||
m_abortable = true;
|
||||
}
|
||||
|
||||
void PackInstallTask::onModDownloadSucceeded()
|
||||
{
|
||||
m_net_job.reset();
|
||||
install();
|
||||
}
|
||||
|
||||
void PackInstallTask::install()
|
||||
{
|
||||
setStatus(tr("Copying modpack files..."));
|
||||
setProgress(0, m_files_to_copy.size());
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
m_abortable = false;
|
||||
|
||||
int i = 0;
|
||||
for (auto iter = m_files_to_copy.constBegin(); iter != m_files_to_copy.constEnd(); iter++) {
|
||||
auto& to = iter.key();
|
||||
auto& from = iter.value();
|
||||
FS::copy fileCopyOperation(from, to);
|
||||
if (!fileCopyOperation()) {
|
||||
qWarning() << "Failed to copy" << from << "to" << to;
|
||||
emitFailed(tr("Failed to copy files"));
|
||||
return;
|
||||
}
|
||||
|
||||
setProgress(i++, m_files_to_copy.size());
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
setStatus(tr("Installing modpack..."));
|
||||
setStatus(tr("Creating the instance..."));
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
|
||||
auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
|
||||
instanceSettings->suspendSave();
|
||||
|
||||
MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
|
||||
auto components = instance.getPackProfile();
|
||||
@ -337,8 +271,55 @@ void PackInstallTask::install()
|
||||
instance.setName(name());
|
||||
instance.setIconKey(m_instIcon);
|
||||
instance.setManagedPack("modpacksch", QString::number(m_pack.id), m_pack.name, QString::number(m_version.id), m_version.name);
|
||||
instanceSettings->resumeSave();
|
||||
|
||||
instance.saveNow();
|
||||
|
||||
onCreateInstanceSucceeded();
|
||||
}
|
||||
|
||||
void PackInstallTask::onCreateInstanceSucceeded()
|
||||
{
|
||||
downloadPack();
|
||||
}
|
||||
|
||||
void PackInstallTask::downloadPack()
|
||||
{
|
||||
setStatus(tr("Downloading mods..."));
|
||||
setAbortable(false);
|
||||
|
||||
auto* jobPtr = new NetJob(tr("Mod download"), APPLICATION->network());
|
||||
for (auto const& file : m_version.files) {
|
||||
if (file.serverOnly || file.url.isEmpty())
|
||||
continue;
|
||||
|
||||
auto path = FS::PathCombine(m_stagingPath, ".minecraft", file.path, file.name);
|
||||
qDebug() << "Will try to download" << file.url << "to" << path;
|
||||
|
||||
QFileInfo file_info(file.name);
|
||||
|
||||
auto dl = Net::Download::makeFile(file.url, path);
|
||||
if (!file.sha1.isEmpty()) {
|
||||
auto rawSha1 = QByteArray::fromHex(file.sha1.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
|
||||
}
|
||||
|
||||
jobPtr->addNetAction(dl);
|
||||
}
|
||||
|
||||
connect(jobPtr, &NetJob::succeeded, this, &PackInstallTask::onModDownloadSucceeded);
|
||||
connect(jobPtr, &NetJob::failed, this, &PackInstallTask::onModDownloadFailed);
|
||||
connect(jobPtr, &NetJob::aborted, this, &PackInstallTask::abort);
|
||||
connect(jobPtr, &NetJob::progress, this, &PackInstallTask::setProgress);
|
||||
|
||||
m_net_job = jobPtr;
|
||||
|
||||
setAbortable(true);
|
||||
jobPtr->start();
|
||||
}
|
||||
|
||||
void PackInstallTask::onModDownloadSucceeded()
|
||||
{
|
||||
m_net_job.reset();
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
@ -352,6 +333,10 @@ void PackInstallTask::onResolveModsFailed(QString reason)
|
||||
m_net_job.reset();
|
||||
emitFailed(reason);
|
||||
}
|
||||
void PackInstallTask::onCreateInstanceFailed(QString reason)
|
||||
{
|
||||
emitFailed(reason);
|
||||
}
|
||||
void PackInstallTask::onModDownloadFailed(QString reason)
|
||||
{
|
||||
m_net_job.reset();
|
||||
|
@ -56,7 +56,6 @@ public:
|
||||
explicit PackInstallTask(Modpack pack, QString version, QWidget* parent = nullptr);
|
||||
~PackInstallTask() override = default;
|
||||
|
||||
bool canAbort() const override { return m_abortable; }
|
||||
bool abort() override;
|
||||
|
||||
protected:
|
||||
@ -65,20 +64,20 @@ protected:
|
||||
private slots:
|
||||
void onManifestDownloadSucceeded();
|
||||
void onResolveModsSucceeded();
|
||||
void onCreateInstanceSucceeded();
|
||||
void onModDownloadSucceeded();
|
||||
|
||||
void onManifestDownloadFailed(QString reason);
|
||||
void onResolveModsFailed(QString reason);
|
||||
void onCreateInstanceFailed(QString reason);
|
||||
void onModDownloadFailed(QString reason);
|
||||
|
||||
private:
|
||||
void resolveMods();
|
||||
void createInstance();
|
||||
void downloadPack();
|
||||
void install();
|
||||
|
||||
private:
|
||||
bool m_abortable = true;
|
||||
|
||||
NetJob::Ptr m_net_job = nullptr;
|
||||
shared_qobject_ptr<Flame::FileResolvingTask> m_mod_id_resolver_task = nullptr;
|
||||
|
||||
|
@ -139,6 +139,10 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
|
||||
void NewInstanceDialog::reject()
|
||||
{
|
||||
APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
|
||||
|
||||
// This is just so that the pages get the close() call and can react to it, if needed.
|
||||
m_container->prepareToClose();
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
@ -146,6 +150,10 @@ void NewInstanceDialog::accept()
|
||||
{
|
||||
APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
|
||||
importIconNow();
|
||||
|
||||
// This is just so that the pages get the close() call and can react to it, if needed.
|
||||
m_container->prepareToClose();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Pr
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setAttribute(Qt::WidgetAttribute::WA_QuitOnClose, true);
|
||||
setSkipButton(false);
|
||||
changeProgress(0, 100);
|
||||
}
|
||||
@ -67,7 +68,7 @@ int ProgressDialog::execWithTask(Task* task)
|
||||
return QDialog::DialogCode::Accepted;
|
||||
}
|
||||
|
||||
QDialog::DialogCode result;
|
||||
QDialog::DialogCode result {};
|
||||
if (handleImmediateResult(result)) {
|
||||
return result;
|
||||
}
|
||||
@ -80,7 +81,7 @@ int ProgressDialog::execWithTask(Task* task)
|
||||
connect(task, &Task::stepStatus, this, &ProgressDialog::changeStatus);
|
||||
connect(task, &Task::progress, this, &ProgressDialog::changeProgress);
|
||||
|
||||
connect(task, &Task::aborted, [this] { QDialog::reject(); });
|
||||
connect(task, &Task::aborted, this, &ProgressDialog::hide);
|
||||
connect(task, &Task::abortStatusChanged, ui->skipButton, &QPushButton::setEnabled);
|
||||
|
||||
m_is_multi_step = task->isMultiStep();
|
||||
|
@ -103,6 +103,8 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac
|
||||
|
||||
void ListModel::request()
|
||||
{
|
||||
m_aborted = false;
|
||||
|
||||
beginResetModel();
|
||||
modpacks.clear();
|
||||
endResetModel();
|
||||
@ -117,6 +119,12 @@ void ListModel::request()
|
||||
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
|
||||
}
|
||||
|
||||
void ListModel::abortRequest()
|
||||
{
|
||||
m_aborted = jobPtr->abort();
|
||||
jobPtr.reset();
|
||||
}
|
||||
|
||||
void ListModel::requestFinished()
|
||||
{
|
||||
jobPtr.reset();
|
||||
@ -162,6 +170,9 @@ void ListModel::requestPack()
|
||||
|
||||
void ListModel::packRequestFinished()
|
||||
{
|
||||
if (!jobPtr || m_aborted)
|
||||
return;
|
||||
|
||||
jobPtr.reset();
|
||||
remainingPacks.removeOne(currentPack);
|
||||
|
||||
|
@ -47,9 +47,13 @@ public:
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
void request();
|
||||
void abortRequest();
|
||||
|
||||
void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
|
||||
|
||||
[[nodiscard]] bool isMakingRequest() const { return jobPtr.get(); }
|
||||
[[nodiscard]] bool wasAborted() const { return m_aborted; }
|
||||
|
||||
private slots:
|
||||
void requestFinished();
|
||||
void requestFailed(QString reason);
|
||||
@ -65,6 +69,8 @@ private:
|
||||
void requestLogo(QString file, QString url);
|
||||
|
||||
private:
|
||||
bool m_aborted = false;
|
||||
|
||||
QList<ModpacksCH::Modpack> modpacks;
|
||||
LogoMap m_logoMap;
|
||||
|
||||
|
@ -105,7 +105,7 @@ void FtbPage::retranslate()
|
||||
|
||||
void FtbPage::openedImpl()
|
||||
{
|
||||
if(!initialised)
|
||||
if(!initialised || listModel->wasAborted())
|
||||
{
|
||||
listModel->request();
|
||||
initialised = true;
|
||||
@ -114,6 +114,12 @@ void FtbPage::openedImpl()
|
||||
suggestCurrent();
|
||||
}
|
||||
|
||||
void FtbPage::closedImpl()
|
||||
{
|
||||
if (listModel->isMakingRequest())
|
||||
listModel->abortRequest();
|
||||
}
|
||||
|
||||
void FtbPage::suggestCurrent()
|
||||
{
|
||||
if(!isOpened)
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
void retranslate() override;
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
bool eventFilter(QObject * watched, QEvent * event) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user