From 20b9f2b42a3b58b6081af271774fbcc34025dccb Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Sun, 25 Jul 2021 19:11:59 +0200 Subject: NOISSUE Flatten gui and logic libraries into MultiMC --- launcher/minecraft/MinecraftUpdate.cpp | 182 +++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 launcher/minecraft/MinecraftUpdate.cpp (limited to 'launcher/minecraft/MinecraftUpdate.cpp') diff --git a/launcher/minecraft/MinecraftUpdate.cpp b/launcher/minecraft/MinecraftUpdate.cpp new file mode 100644 index 00000000..8f1565b0 --- /dev/null +++ b/launcher/minecraft/MinecraftUpdate.cpp @@ -0,0 +1,182 @@ +/* Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Env.h" +#include "MinecraftUpdate.h" +#include "MinecraftInstance.h" + +#include +#include +#include +#include + +#include "BaseInstance.h" +#include "minecraft/PackProfile.h" +#include "minecraft/Library.h" +#include + +#include "update/FoldersTask.h" +#include "update/LibrariesTask.h" +#include "update/FMLLibrariesTask.h" +#include "update/AssetUpdateTask.h" + +#include +#include + +MinecraftUpdate::MinecraftUpdate(MinecraftInstance *inst, QObject *parent) : Task(parent), m_inst(inst) +{ +} + +void MinecraftUpdate::executeTask() +{ + m_tasks.clear(); + // create folders + { + m_tasks.append(std::make_shared(m_inst)); + } + + // add metadata update task if necessary + { + auto components = m_inst->getPackProfile(); + components->reload(Net::Mode::Online); + auto task = components->getCurrentTask(); + if(task) + { + m_tasks.append(task.unwrap()); + } + } + + // libraries download + { + m_tasks.append(std::make_shared(m_inst)); + } + + // FML libraries download and copy into the instance + { + m_tasks.append(std::make_shared(m_inst)); + } + + // assets update + { + m_tasks.append(std::make_shared(m_inst)); + } + + if(!m_preFailure.isEmpty()) + { + emitFailed(m_preFailure); + return; + } + next(); +} + +void MinecraftUpdate::next() +{ + if(m_abort) + { + emitFailed(tr("Aborted by user.")); + return; + } + if(m_failed_out_of_order) + { + emitFailed(m_fail_reason); + return; + } + m_currentTask ++; + if(m_currentTask > 0) + { + auto task = m_tasks[m_currentTask - 1]; + disconnect(task.get(), &Task::succeeded, this, &MinecraftUpdate::subtaskSucceeded); + disconnect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed); + disconnect(task.get(), &Task::progress, this, &MinecraftUpdate::progress); + disconnect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); + } + if(m_currentTask == m_tasks.size()) + { + emitSucceeded(); + return; + } + auto task = m_tasks[m_currentTask]; + // if the task is already finished by the time we look at it, skip it + if(task->isFinished()) + { + qCritical() << "MinecraftUpdate: Skipping finished subtask" << m_currentTask << ":" << task.get(); + next(); + } + connect(task.get(), &Task::succeeded, this, &MinecraftUpdate::subtaskSucceeded); + connect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed); + connect(task.get(), &Task::progress, this, &MinecraftUpdate::progress); + connect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); + // if the task is already running, do not start it again + if(!task->isRunning()) + { + task->start(); + } +} + +void MinecraftUpdate::subtaskSucceeded() +{ + if(isFinished()) + { + qCritical() << "MinecraftUpdate: Subtask" << sender() << "succeeded, but work was already done!"; + return; + } + auto senderTask = QObject::sender(); + auto currentTask = m_tasks[m_currentTask].get(); + if(senderTask != currentTask) + { + qDebug() << "MinecraftUpdate: Subtask" << sender() << "succeeded out of order."; + return; + } + next(); +} + +void MinecraftUpdate::subtaskFailed(QString error) +{ + if(isFinished()) + { + qCritical() << "MinecraftUpdate: Subtask" << sender() << "failed, but work was already done!"; + return; + } + auto senderTask = QObject::sender(); + auto currentTask = m_tasks[m_currentTask].get(); + if(senderTask != currentTask) + { + qDebug() << "MinecraftUpdate: Subtask" << sender() << "failed out of order."; + m_failed_out_of_order = true; + m_fail_reason = error; + return; + } + emitFailed(error); +} + + +bool MinecraftUpdate::abort() +{ + if(!m_abort) + { + m_abort = true; + auto task = m_tasks[m_currentTask]; + if(task->canAbort()) + { + return task->abort(); + } + } + return true; +} + +bool MinecraftUpdate::canAbort() const +{ + return true; +} -- cgit