diff options
Diffstat (limited to 'api/logic/launch/LaunchTask.cpp')
-rw-r--r-- | api/logic/launch/LaunchTask.cpp | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/api/logic/launch/LaunchTask.cpp b/api/logic/launch/LaunchTask.cpp new file mode 100644 index 00000000..5b7ff182 --- /dev/null +++ b/api/logic/launch/LaunchTask.cpp @@ -0,0 +1,228 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Authors: Orochimarufan <orochimarufan.x3@gmail.com> + * + * 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 "launch/LaunchTask.h" +#include "MessageLevel.h" +#include "MMCStrings.h" +#include "java/JavaChecker.h" +#include "tasks/Task.h" +#include <QDebug> +#include <QDir> +#include <QEventLoop> +#include <QRegularExpression> +#include <QCoreApplication> +#include <QStandardPaths> +#include <assert.h> + +void LaunchTask::init() +{ + m_instance->setRunning(true); +} + +std::shared_ptr<LaunchTask> LaunchTask::create(InstancePtr inst) +{ + std::shared_ptr<LaunchTask> proc(new LaunchTask(inst)); + proc->init(); + return proc; +} + +LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance) +{ +} + +void LaunchTask::appendStep(std::shared_ptr<LaunchStep> step) +{ + m_steps.append(step); +} + +void LaunchTask::prependStep(std::shared_ptr<LaunchStep> step) +{ + m_steps.prepend(step); +} + +void LaunchTask::executeTask() +{ + if(!m_steps.size()) + { + state = LaunchTask::Finished; + emitSucceeded(); + } + state = LaunchTask::Running; + onStepFinished(); +} + +void LaunchTask::onReadyForLaunch() +{ + state = LaunchTask::Waiting; + emit readyForLaunch(); +} + +void LaunchTask::onStepFinished() +{ + // initial -> just start the first step + if(currentStep == -1) + { + currentStep ++; + m_steps[currentStep]->start(); + return; + } + + auto step = m_steps[currentStep]; + if(step->successful()) + { + // end? + if(currentStep == m_steps.size() - 1) + { + emitSucceeded(); + } + else + { + currentStep ++; + step = m_steps[currentStep]; + step->start(); + } + } + else + { + emitFailed(step->failReason()); + } +} + +void LaunchTask::onProgressReportingRequested() +{ + state = LaunchTask::Waiting; + emit requestProgress(m_steps[currentStep].get()); +} + +void LaunchTask::setCensorFilter(QMap<QString, QString> filter) +{ + m_censorFilter = filter; +} + +QString LaunchTask::censorPrivateInfo(QString in) +{ + auto iter = m_censorFilter.begin(); + while (iter != m_censorFilter.end()) + { + in.replace(iter.key(), iter.value()); + iter++; + } + return in; +} + +void LaunchTask::proceed() +{ + if(state != LaunchTask::Waiting) + { + return; + } + m_steps[currentStep]->proceed(); +} + +bool LaunchTask::abort() +{ + switch(state) + { + case LaunchTask::Aborted: + case LaunchTask::Failed: + case LaunchTask::Finished: + return true; + case LaunchTask::NotStarted: + { + state = LaunchTask::Aborted; + emitFailed("Aborted"); + return true; + } + case LaunchTask::Running: + case LaunchTask::Waiting: + { + auto step = m_steps[currentStep]; + if(!step->canAbort()) + { + return false; + } + if(step->abort()) + { + state = LaunchTask::Aborted; + return true; + } + } + default: + break; + } + return false; +} + +void LaunchTask::onLogLines(const QStringList &lines, MessageLevel::Enum defaultLevel) +{ + for (auto & line: lines) + { + onLogLine(line, defaultLevel); + } +} + +void LaunchTask::onLogLine(QString line, MessageLevel::Enum level) +{ + // if the launcher part set a log level, use it + auto innerLevel = MessageLevel::fromLine(line); + if(innerLevel != MessageLevel::Unknown) + { + level = innerLevel; + } + + // If the level is still undetermined, guess level + if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) + { + level = m_instance->guessLevel(line, level); + } + + // censor private user info + line = censorPrivateInfo(line); + + emit log(line, level); +} + +void LaunchTask::emitSucceeded() +{ + m_instance->cleanupAfterRun(); + m_instance->setRunning(false); + Task::emitSucceeded(); +} + +void LaunchTask::emitFailed(QString reason) +{ + m_instance->cleanupAfterRun(); + m_instance->setRunning(false); + Task::emitFailed(reason); +} + +QString LaunchTask::substituteVariables(const QString &cmd) const +{ + QString out = cmd; + auto variables = m_instance->getVariables(); + for (auto it = variables.begin(); it != variables.end(); ++it) + { + out.replace("$" + it.key(), it.value()); + } + auto env = QProcessEnvironment::systemEnvironment(); + for (auto var : env.keys()) + { + out.replace("$" + var, env.value(var)); + } + return out; +} + |