diff options
Diffstat (limited to 'meshmc/launcher/launch/steps')
| -rw-r--r-- | meshmc/launcher/launch/steps/CheckJava.cpp | 173 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/CheckJava.h | 69 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/LookupServerAddress.cpp | 125 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/LookupServerAddress.h | 73 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/PostLaunchCommand.cpp | 104 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/PostLaunchCommand.h | 64 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/PreLaunchCommand.cpp | 104 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/PreLaunchCommand.h | 64 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/TextPrint.cpp | 54 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/TextPrint.h | 66 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/Update.cpp | 96 | ||||
| -rw-r--r-- | meshmc/launcher/launch/steps/Update.h | 70 |
12 files changed, 1062 insertions, 0 deletions
diff --git a/meshmc/launcher/launch/steps/CheckJava.cpp b/meshmc/launcher/launch/steps/CheckJava.cpp new file mode 100644 index 0000000000..715e721b4c --- /dev/null +++ b/meshmc/launcher/launch/steps/CheckJava.cpp @@ -0,0 +1,173 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "CheckJava.h" +#include <launch/LaunchTask.h> +#include <FileSystem.h> +#include <QStandardPaths> +#include <QFileInfo> +#include <sys.h> + +void CheckJava::executeTask() +{ + auto instance = m_parent->instance(); + auto settings = instance->settings(); + m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString()); + bool perInstance = settings->get("OverrideJava").toBool() || + settings->get("OverrideJavaLocation").toBool(); + + auto realJavaPath = QStandardPaths::findExecutable(m_javaPath); + if (realJavaPath.isEmpty()) { + if (perInstance) { + emit logLine( + QString("The java binary \"%1\" couldn't be found. Please fix " + "the java path " + "override in the instance's settings or disable it.") + .arg(m_javaPath), + MessageLevel::Warning); + } else { + emit logLine(QString("The java binary \"%1\" couldn't be found. " + "Please set up java in " + "the settings.") + .arg(m_javaPath), + MessageLevel::Warning); + } + emitFailed(QString("Java path is not valid.")); + return; + } else { + emit logLine("Java path is:\n" + m_javaPath + "\n\n", + MessageLevel::MeshMC); + } + + QFileInfo javaInfo(realJavaPath); + qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch(); + auto storedUnixTime = settings->get("JavaTimestamp").toLongLong(); + auto storedArchitecture = settings->get("JavaArchitecture").toString(); + auto storedVersion = settings->get("JavaVersion").toString(); + auto storedVendor = settings->get("JavaVendor").toString(); + m_javaUnixTime = javaUnixTime; + // if timestamps are not the same, or something is missing, check! + if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || + storedArchitecture.size() == 0 || storedVendor.size() == 0) { + m_JavaChecker = new JavaChecker(); + emit logLine(QString("Checking Java version..."), MessageLevel::MeshMC); + connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, + &CheckJava::checkJavaFinished); + m_JavaChecker->m_path = realJavaPath; + m_JavaChecker->performCheck(); + return; + } else { + auto verString = instance->settings()->get("JavaVersion").toString(); + auto archString = + instance->settings()->get("JavaArchitecture").toString(); + auto vendorString = instance->settings()->get("JavaVendor").toString(); + printJavaInfo(verString, archString, vendorString); + } + emitSucceeded(); +} + +void CheckJava::checkJavaFinished(JavaCheckResult result) +{ + switch (result.validity) { + case JavaCheckResult::Validity::Errored: { + // Error message displayed if java can't start + emit logLine(QString("Could not start java:"), MessageLevel::Error); + emit logLines(result.errorLog.split('\n'), MessageLevel::Error); + emit logLine("\nCheck your MeshMC Java settings.", + MessageLevel::MeshMC); + printSystemInfo(false, false); + emitFailed(QString("Could not start java!")); + return; + } + case JavaCheckResult::Validity::ReturnedInvalidData: { + emit logLine(QString("Java checker returned some invalid data " + "MeshMC doesn't understand:"), + MessageLevel::Error); + emit logLines(result.outLog.split('\n'), MessageLevel::Warning); + emit logLine("\nMinecraft might not start properly.", + MessageLevel::MeshMC); + printSystemInfo(false, false); + emitSucceeded(); + return; + } + case JavaCheckResult::Validity::Valid: { + auto instance = m_parent->instance(); + printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, + result.javaVendor); + instance->settings()->set("JavaVersion", + result.javaVersion.toString()); + instance->settings()->set("JavaArchitecture", + result.mojangPlatform); + instance->settings()->set("JavaVendor", result.javaVendor); + instance->settings()->set("JavaTimestamp", m_javaUnixTime); + emitSucceeded(); + return; + } + } +} + +void CheckJava::printJavaInfo(const QString& version, + const QString& architecture, + const QString& vendor) +{ + emit logLine( + QString("Java is version %1, using %2-bit architecture, from %3.\n\n") + .arg(version, architecture, vendor), + MessageLevel::MeshMC); + printSystemInfo(true, architecture == "64"); +} + +void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit) +{ + auto cpu64 = Sys::isCPU64bit(); + auto system64 = Sys::isSystem64bit(); + if (cpu64 != system64) { + emit logLine(QString("Your CPU architecture is not matching your " + "system architecture. You might want to install a " + "64bit Operating System.\n\n"), + MessageLevel::Error); + } + if (javaIsKnown) { + if (javaIs64bit != system64) { + emit logLine(QString("Your Java architecture is not matching your " + "system architecture. You might want to " + "install a 64bit Java version.\n\n"), + MessageLevel::Error); + } + } +} diff --git a/meshmc/launcher/launch/steps/CheckJava.h b/meshmc/launcher/launch/steps/CheckJava.h new file mode 100644 index 0000000000..8de2d7da5a --- /dev/null +++ b/meshmc/launcher/launch/steps/CheckJava.h @@ -0,0 +1,69 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include <launch/LaunchStep.h> +#include <LoggedProcess.h> +#include <java/JavaChecker.h> + +class CheckJava : public LaunchStep +{ + Q_OBJECT + public: + explicit CheckJava(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~CheckJava() {}; + + virtual void executeTask(); + virtual bool canAbort() const + { + return false; + } + private slots: + void checkJavaFinished(JavaCheckResult result); + + private: + void printJavaInfo(const QString& version, const QString& architecture, + const QString& vendor); + void printSystemInfo(bool javaIsKnown, bool javaIs64bit); + + private: + QString m_javaPath; + qlonglong m_javaUnixTime; + JavaCheckerPtr m_JavaChecker; +}; diff --git a/meshmc/launcher/launch/steps/LookupServerAddress.cpp b/meshmc/launcher/launch/steps/LookupServerAddress.cpp new file mode 100644 index 0000000000..f88b8f8812 --- /dev/null +++ b/meshmc/launcher/launch/steps/LookupServerAddress.cpp @@ -0,0 +1,125 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "LookupServerAddress.h" + +#include <launch/LaunchTask.h> + +LookupServerAddress::LookupServerAddress(LaunchTask* parent) + : LaunchStep(parent), m_dnsLookup(new QDnsLookup(this)) +{ + connect(m_dnsLookup, &QDnsLookup::finished, this, + &LookupServerAddress::on_dnsLookupFinished); + + m_dnsLookup->setType(QDnsLookup::SRV); +} + +void LookupServerAddress::setLookupAddress(const QString& lookupAddress) +{ + m_lookupAddress = lookupAddress; + m_dnsLookup->setName(QString("_minecraft._tcp.%1").arg(lookupAddress)); +} + +void LookupServerAddress::setOutputAddressPtr(MinecraftServerTargetPtr output) +{ + m_output = std::move(output); +} + +bool LookupServerAddress::abort() +{ + m_dnsLookup->abort(); + emitFailed("Aborted"); + return true; +} + +void LookupServerAddress::executeTask() +{ + m_dnsLookup->lookup(); +} + +void LookupServerAddress::on_dnsLookupFinished() +{ + if (isFinished()) { + // Aborted + return; + } + + if (m_dnsLookup->error() != QDnsLookup::NoError) { + emit logLine(QString("Failed to resolve server address (this is NOT an " + "error!) %1: %2\n") + .arg(m_dnsLookup->name(), m_dnsLookup->errorString()), + MessageLevel::MeshMC); + resolve(m_lookupAddress, + 25565); // Technically the task failed, however, we don't abort + // the launch and leave it up to minecraft to fail (or + // maybe not) when connecting + return; + } + + const auto records = m_dnsLookup->serviceRecords(); + if (records.empty()) { + emit logLine( + QString("Failed to resolve server address %1: the DNS lookup " + "succeeded, but no records were returned.\n") + .arg(m_dnsLookup->name()), + MessageLevel::Warning); + resolve(m_lookupAddress, + 25565); // Technically the task failed, however, we don't abort + // the launch and leave it up to minecraft to fail (or + // maybe not) when connecting + return; + } + + const auto& firstRecord = records.at(0); + quint16 port = firstRecord.port(); + + emit logLine(QString("Resolved server address %1 to %2 with port %3\n") + .arg(m_dnsLookup->name(), firstRecord.target(), + QString::number(port)), + MessageLevel::MeshMC); + resolve(firstRecord.target(), port); +} + +void LookupServerAddress::resolve(const QString& address, quint16 port) +{ + m_output->address = address; + m_output->port = port; + + emitSucceeded(); + m_dnsLookup->deleteLater(); +} diff --git a/meshmc/launcher/launch/steps/LookupServerAddress.h b/meshmc/launcher/launch/steps/LookupServerAddress.h new file mode 100644 index 0000000000..1625875c69 --- /dev/null +++ b/meshmc/launcher/launch/steps/LookupServerAddress.h @@ -0,0 +1,73 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include <launch/LaunchStep.h> +#include <QObjectPtr.h> +#include <QDnsLookup> + +#include "minecraft/launch/MinecraftServerTarget.h" + +class LookupServerAddress : public LaunchStep +{ + Q_OBJECT + public: + explicit LookupServerAddress(LaunchTask* parent); + virtual ~LookupServerAddress() {}; + + virtual void executeTask(); + virtual bool abort(); + virtual bool canAbort() const + { + return true; + } + + void setLookupAddress(const QString& lookupAddress); + void setOutputAddressPtr(MinecraftServerTargetPtr output); + + private slots: + void on_dnsLookupFinished(); + + private: + void resolve(const QString& address, quint16 port); + + QDnsLookup* m_dnsLookup; + QString m_lookupAddress; + MinecraftServerTargetPtr m_output; +}; diff --git a/meshmc/launcher/launch/steps/PostLaunchCommand.cpp b/meshmc/launcher/launch/steps/PostLaunchCommand.cpp new file mode 100644 index 0000000000..db1df3bbb4 --- /dev/null +++ b/meshmc/launcher/launch/steps/PostLaunchCommand.cpp @@ -0,0 +1,104 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "PostLaunchCommand.h" +#include <launch/LaunchTask.h> + +PostLaunchCommand::PostLaunchCommand(LaunchTask* parent) : LaunchStep(parent) +{ + auto instance = m_parent->instance(); + m_command = instance->getPostExitCommand(); + m_process.setProcessEnvironment(instance->createEnvironment()); + connect(&m_process, &LoggedProcess::log, this, + &PostLaunchCommand::logLines); + connect(&m_process, &LoggedProcess::stateChanged, this, + &PostLaunchCommand::on_state); +} + +void PostLaunchCommand::executeTask() +{ + QString postlaunch_cmd = m_parent->substituteVariables(m_command); + emit logLine(tr("Running Post-Launch command: %1").arg(postlaunch_cmd), + MessageLevel::MeshMC); + m_process.start(postlaunch_cmd); +} + +void PostLaunchCommand::on_state(LoggedProcess::State state) +{ + auto getError = [&]() { + return tr("Post-Launch command failed with code %1.\n\n") + .arg(m_process.exitCode()); + }; + switch (state) { + case LoggedProcess::Aborted: + case LoggedProcess::Crashed: + case LoggedProcess::FailedToStart: { + auto error = getError(); + emit logLine(error, MessageLevel::Fatal); + emitFailed(error); + return; + } + case LoggedProcess::Finished: { + if (m_process.exitCode() != 0) { + auto error = getError(); + emit logLine(error, MessageLevel::Fatal); + emitFailed(error); + } else { + emit logLine(tr("Post-Launch command ran successfully.\n\n"), + MessageLevel::MeshMC); + emitSucceeded(); + } + } + default: + break; + } +} + +void PostLaunchCommand::setWorkingDirectory(const QString& wd) +{ + m_process.setWorkingDirectory(wd); +} + +bool PostLaunchCommand::abort() +{ + auto state = m_process.state(); + if (state == LoggedProcess::Running || state == LoggedProcess::Starting) { + m_process.kill(); + } + return true; +} diff --git a/meshmc/launcher/launch/steps/PostLaunchCommand.h b/meshmc/launcher/launch/steps/PostLaunchCommand.h new file mode 100644 index 0000000000..3e87dd4dfd --- /dev/null +++ b/meshmc/launcher/launch/steps/PostLaunchCommand.h @@ -0,0 +1,64 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include <launch/LaunchStep.h> +#include <LoggedProcess.h> + +class PostLaunchCommand : public LaunchStep +{ + Q_OBJECT + public: + explicit PostLaunchCommand(LaunchTask* parent); + virtual ~PostLaunchCommand() {}; + + virtual void executeTask(); + virtual bool abort(); + virtual bool canAbort() const + { + return true; + } + void setWorkingDirectory(const QString& wd); + private slots: + void on_state(LoggedProcess::State state); + + private: + LoggedProcess m_process; + QString m_command; +}; diff --git a/meshmc/launcher/launch/steps/PreLaunchCommand.cpp b/meshmc/launcher/launch/steps/PreLaunchCommand.cpp new file mode 100644 index 0000000000..fdaf2c0fbf --- /dev/null +++ b/meshmc/launcher/launch/steps/PreLaunchCommand.cpp @@ -0,0 +1,104 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "PreLaunchCommand.h" +#include <launch/LaunchTask.h> + +PreLaunchCommand::PreLaunchCommand(LaunchTask* parent) : LaunchStep(parent) +{ + auto instance = m_parent->instance(); + m_command = instance->getPreLaunchCommand(); + m_process.setProcessEnvironment(instance->createEnvironment()); + connect(&m_process, &LoggedProcess::log, this, &PreLaunchCommand::logLines); + connect(&m_process, &LoggedProcess::stateChanged, this, + &PreLaunchCommand::on_state); +} + +void PreLaunchCommand::executeTask() +{ + // FIXME: where to put this? + QString prelaunch_cmd = m_parent->substituteVariables(m_command); + emit logLine(tr("Running Pre-Launch command: %1").arg(prelaunch_cmd), + MessageLevel::MeshMC); + m_process.start(prelaunch_cmd); +} + +void PreLaunchCommand::on_state(LoggedProcess::State state) +{ + auto getError = [&]() { + return tr("Pre-Launch command failed with code %1.\n\n") + .arg(m_process.exitCode()); + }; + switch (state) { + case LoggedProcess::Aborted: + case LoggedProcess::Crashed: + case LoggedProcess::FailedToStart: { + auto error = getError(); + emit logLine(error, MessageLevel::Fatal); + emitFailed(error); + return; + } + case LoggedProcess::Finished: { + if (m_process.exitCode() != 0) { + auto error = getError(); + emit logLine(error, MessageLevel::Fatal); + emitFailed(error); + } else { + emit logLine(tr("Pre-Launch command ran successfully.\n\n"), + MessageLevel::MeshMC); + emitSucceeded(); + } + } + default: + break; + } +} + +void PreLaunchCommand::setWorkingDirectory(const QString& wd) +{ + m_process.setWorkingDirectory(wd); +} + +bool PreLaunchCommand::abort() +{ + auto state = m_process.state(); + if (state == LoggedProcess::Running || state == LoggedProcess::Starting) { + m_process.kill(); + } + return true; +} diff --git a/meshmc/launcher/launch/steps/PreLaunchCommand.h b/meshmc/launcher/launch/steps/PreLaunchCommand.h new file mode 100644 index 0000000000..22c489d2d5 --- /dev/null +++ b/meshmc/launcher/launch/steps/PreLaunchCommand.h @@ -0,0 +1,64 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include "launch/LaunchStep.h" +#include "LoggedProcess.h" + +class PreLaunchCommand : public LaunchStep +{ + Q_OBJECT + public: + explicit PreLaunchCommand(LaunchTask* parent); + virtual ~PreLaunchCommand() {}; + + virtual void executeTask(); + virtual bool abort(); + virtual bool canAbort() const + { + return true; + } + void setWorkingDirectory(const QString& wd); + private slots: + void on_state(LoggedProcess::State state); + + private: + LoggedProcess m_process; + QString m_command; +}; diff --git a/meshmc/launcher/launch/steps/TextPrint.cpp b/meshmc/launcher/launch/steps/TextPrint.cpp new file mode 100644 index 0000000000..0110bc7908 --- /dev/null +++ b/meshmc/launcher/launch/steps/TextPrint.cpp @@ -0,0 +1,54 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "TextPrint.h" + +TextPrint::TextPrint(LaunchTask* parent, const QStringList& lines, + MessageLevel::Enum level) + : LaunchStep(parent) +{ + m_lines = lines; + m_level = level; +} +TextPrint::TextPrint(LaunchTask* parent, const QString& line, + MessageLevel::Enum level) + : LaunchStep(parent) +{ + m_lines.append(line); + m_level = level; +} + +void TextPrint::executeTask() +{ + emit logLines(m_lines, m_level); + emitSucceeded(); +} + +bool TextPrint::canAbort() const +{ + return true; +} + +bool TextPrint::abort() +{ + emitFailed("Aborted."); + return true; +} diff --git a/meshmc/launcher/launch/steps/TextPrint.h b/meshmc/launcher/launch/steps/TextPrint.h new file mode 100644 index 0000000000..4bf8ca5579 --- /dev/null +++ b/meshmc/launcher/launch/steps/TextPrint.h @@ -0,0 +1,66 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include <launch/LaunchStep.h> +#include <LoggedProcess.h> +#include <java/JavaChecker.h> + +/* + * FIXME: maybe do not export + */ + +class TextPrint : public LaunchStep +{ + Q_OBJECT + public: + explicit TextPrint(LaunchTask* parent, const QStringList& lines, + MessageLevel::Enum level); + explicit TextPrint(LaunchTask* parent, const QString& line, + MessageLevel::Enum level); + virtual ~TextPrint() {}; + + virtual void executeTask(); + virtual bool canAbort() const; + virtual bool abort(); + + private: + QStringList m_lines; + MessageLevel::Enum m_level; +}; diff --git a/meshmc/launcher/launch/steps/Update.cpp b/meshmc/launcher/launch/steps/Update.cpp new file mode 100644 index 0000000000..f1efc8db51 --- /dev/null +++ b/meshmc/launcher/launch/steps/Update.cpp @@ -0,0 +1,96 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "Update.h" +#include <launch/LaunchTask.h> + +void Update::executeTask() +{ + if (m_aborted) { + emitFailed(tr("Task aborted.")); + return; + } + m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode)); + if (m_updateTask) { + connect(m_updateTask.get(), SIGNAL(finished()), this, + SLOT(updateFinished())); + connect(m_updateTask.get(), &Task::progress, this, &Task::setProgress); + connect(m_updateTask.get(), &Task::status, this, &Task::setStatus); + emit progressReportingRequest(); + return; + } + emitSucceeded(); +} + +void Update::proceed() +{ + m_updateTask->start(); +} + +void Update::updateFinished() +{ + if (m_updateTask->wasSuccessful()) { + emitSucceeded(); + m_updateTask.reset(); + } else { + QString reason = tr("Instance update failed because: %1\n\n") + .arg(m_updateTask->failReason()); + emit logLine(reason, MessageLevel::Fatal); + emitFailed(reason); + m_updateTask.reset(); + } +} + +bool Update::canAbort() const +{ + if (m_updateTask) { + return m_updateTask->canAbort(); + } + return true; +} + +bool Update::abort() +{ + m_aborted = true; + if (m_updateTask) { + if (m_updateTask->canAbort()) { + return m_updateTask->abort(); + } + } + return true; +} diff --git a/meshmc/launcher/launch/steps/Update.h b/meshmc/launcher/launch/steps/Update.h new file mode 100644 index 0000000000..4d6b2ac000 --- /dev/null +++ b/meshmc/launcher/launch/steps/Update.h @@ -0,0 +1,70 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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. + */ + +#pragma once + +#include <launch/LaunchStep.h> +#include <QObjectPtr.h> +#include <LoggedProcess.h> +#include <java/JavaChecker.h> +#include <net/Mode.h> + +// FIXME: stupid. should be defined by the instance type? or even completely +// abstracted away... +class Update : public LaunchStep +{ + Q_OBJECT + public: + explicit Update(LaunchTask* parent, Net::Mode mode) + : LaunchStep(parent), m_mode(mode) {}; + virtual ~Update() {}; + + void executeTask() override; + bool canAbort() const override; + void proceed() override; + public slots: + bool abort() override; + + private slots: + void updateFinished(); + + private: + Task::Ptr m_updateTask; + bool m_aborted = false; + Net::Mode m_mode = Net::Mode::Offline; +}; |
