diff options
Diffstat (limited to 'api/logic/minecraft/launch')
| -rw-r--r-- | api/logic/minecraft/launch/CreateGameFolders.cpp | 2 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/DirectJavaLaunch.cpp | 21 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/DirectJavaLaunch.h | 9 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/ExtractNatives.cpp | 6 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/LauncherPartLaunch.cpp | 19 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/LauncherPartLaunch.h | 9 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/MinecraftServerTarget.cpp | 66 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/MinecraftServerTarget.h | 30 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/PrintInstanceInfo.cpp | 2 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/PrintInstanceInfo.h | 5 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/VerifyJavaInstall.cpp | 34 | ||||
| -rw-r--r-- | api/logic/minecraft/launch/VerifyJavaInstall.h | 17 |
12 files changed, 193 insertions, 27 deletions
diff --git a/api/logic/minecraft/launch/CreateGameFolders.cpp b/api/logic/minecraft/launch/CreateGameFolders.cpp index 415b7e23..4081e72e 100644 --- a/api/logic/minecraft/launch/CreateGameFolders.cpp +++ b/api/logic/minecraft/launch/CreateGameFolders.cpp @@ -15,7 +15,7 @@ void CreateGameFolders::executeTask() if(!FS::ensureFolderPathExists(minecraftInstance->gameRoot())) { emit logLine("Couldn't create the main game folder", MessageLevel::Error); - emitFailed("Couldn't create the main game folder"); + emitFailed(tr("Couldn't create the main game folder")); return; } diff --git a/api/logic/minecraft/launch/DirectJavaLaunch.cpp b/api/logic/minecraft/launch/DirectJavaLaunch.cpp index d9841a43..2110384f 100644 --- a/api/logic/minecraft/launch/DirectJavaLaunch.cpp +++ b/api/logic/minecraft/launch/DirectJavaLaunch.cpp @@ -55,7 +55,7 @@ void DirectJavaLaunch::executeTask() // make detachable - this will keep the process running even if the object is destroyed m_process.setDetachable(true); - auto mcArgs = minecraftInstance->processMinecraftArgs(m_session); + auto mcArgs = minecraftInstance->processMinecraftArgs(m_session, m_serverToJoin); args.append(mcArgs); QString wrapperCommandStr = instance->getWrapperCommand().trimmed(); @@ -66,9 +66,9 @@ void DirectJavaLaunch::executeTask() auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); if (realWrapperCommand.isEmpty()) { - QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); + emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); + emitFailed(tr(reason).arg(wrapperCommand)); return; } emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC); @@ -87,18 +87,17 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) { case LoggedProcess::FailedToStart: { - //: Error message displayed if instace can't start - QString reason = tr("Could not launch minecraft!"); + //: Error message displayed if instance can't start + const char *reason = QT_TR_NOOP("Could not launch minecraft!"); emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + emitFailed(tr(reason)); return; } case LoggedProcess::Aborted: case LoggedProcess::Crashed: - { m_parent->setPid(-1); - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } case LoggedProcess::Finished: @@ -108,7 +107,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) auto exitCode = m_process.exitCode(); if(exitCode != 0) { - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } //FIXME: make this work again @@ -118,7 +117,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) break; } case LoggedProcess::Running: - emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); + emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); m_parent->setPid(m_process.processId()); m_parent->instance()->setLastLaunch(); break; diff --git a/api/logic/minecraft/launch/DirectJavaLaunch.h b/api/logic/minecraft/launch/DirectJavaLaunch.h index d9d9bdc2..58b119b8 100644 --- a/api/logic/minecraft/launch/DirectJavaLaunch.h +++ b/api/logic/minecraft/launch/DirectJavaLaunch.h @@ -19,6 +19,8 @@ #include <LoggedProcess.h> #include <minecraft/auth/AuthSession.h> +#include "MinecraftServerTarget.h" + class DirectJavaLaunch: public LaunchStep { Q_OBJECT @@ -38,6 +40,12 @@ public: { m_session = session; } + + void setServerToJoin(MinecraftServerTargetPtr serverToJoin) + { + m_serverToJoin = std::move(serverToJoin); + } + private slots: void on_state(LoggedProcess::State state); @@ -45,5 +53,6 @@ private: LoggedProcess m_process; QString m_command; AuthSessionPtr m_session; + MinecraftServerTargetPtr m_serverToJoin; }; diff --git a/api/logic/minecraft/launch/ExtractNatives.cpp b/api/logic/minecraft/launch/ExtractNatives.cpp index d41cb8fd..d57499aa 100644 --- a/api/logic/minecraft/launch/ExtractNatives.cpp +++ b/api/logic/minecraft/launch/ExtractNatives.cpp @@ -94,9 +94,9 @@ void ExtractNatives::executeTask() { if(!unzipNatives(source, outputPath, jniHackEnabled, nativeOpenAL, nativeGLFW)) { - auto reason = tr("Couldn't extract native jar '%1' to destination '%2'").arg(source, outputPath); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("Couldn't extract native jar '%1' to destination '%2'"); + emit logLine(QString(reason).arg(source, outputPath), MessageLevel::Fatal); + emitFailed(tr(reason).arg(source, outputPath)); } } emitSucceeded(); diff --git a/api/logic/minecraft/launch/LauncherPartLaunch.cpp b/api/logic/minecraft/launch/LauncherPartLaunch.cpp index 1408e6ad..ee469770 100644 --- a/api/logic/minecraft/launch/LauncherPartLaunch.cpp +++ b/api/logic/minecraft/launch/LauncherPartLaunch.cpp @@ -59,7 +59,7 @@ void LauncherPartLaunch::executeTask() auto instance = m_parent->instance(); std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance); - m_launchScript = minecraftInstance->createLaunchScript(m_session); + m_launchScript = minecraftInstance->createLaunchScript(m_session, m_serverToJoin); QStringList args = minecraftInstance->javaArguments(); QString allArgs = args.join(", "); emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC); @@ -118,9 +118,9 @@ void LauncherPartLaunch::executeTask() auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); if (realWrapperCommand.isEmpty()) { - QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); + emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); + emitFailed(tr(reason).arg(wrapperCommand)); return; } emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC); @@ -140,17 +140,16 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) case LoggedProcess::FailedToStart: { //: Error message displayed if instace can't start - QString reason = tr("Could not launch minecraft!"); + const char *reason = QT_TR_NOOP("Could not launch minecraft!"); emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + emitFailed(tr(reason)); return; } case LoggedProcess::Aborted: case LoggedProcess::Crashed: - { m_parent->setPid(-1); - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } case LoggedProcess::Finished: @@ -160,7 +159,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) auto exitCode = m_process.exitCode(); if(exitCode != 0) { - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } //FIXME: make this work again @@ -170,7 +169,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) break; } case LoggedProcess::Running: - emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); + emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); m_parent->setPid(m_process.processId()); m_parent->instance()->setLastLaunch(); // send the launch script to the launcher part diff --git a/api/logic/minecraft/launch/LauncherPartLaunch.h b/api/logic/minecraft/launch/LauncherPartLaunch.h index 9e951849..6a7ee0e5 100644 --- a/api/logic/minecraft/launch/LauncherPartLaunch.h +++ b/api/logic/minecraft/launch/LauncherPartLaunch.h @@ -19,6 +19,8 @@ #include <LoggedProcess.h> #include <minecraft/auth/AuthSession.h> +#include "MinecraftServerTarget.h" + class LauncherPartLaunch: public LaunchStep { Q_OBJECT @@ -39,6 +41,11 @@ public: m_session = session; } + void setServerToJoin(MinecraftServerTargetPtr serverToJoin) + { + m_serverToJoin = std::move(serverToJoin); + } + private slots: void on_state(LoggedProcess::State state); @@ -47,5 +54,7 @@ private: QString m_command; AuthSessionPtr m_session; QString m_launchScript; + MinecraftServerTargetPtr m_serverToJoin; + bool mayProceed = false; }; diff --git a/api/logic/minecraft/launch/MinecraftServerTarget.cpp b/api/logic/minecraft/launch/MinecraftServerTarget.cpp new file mode 100644 index 00000000..569273b6 --- /dev/null +++ b/api/logic/minecraft/launch/MinecraftServerTarget.cpp @@ -0,0 +1,66 @@ +/* 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 "MinecraftServerTarget.h" + +#include <QStringList> + +MinecraftServerTarget MinecraftServerTarget::parse(const QString &fullAddress) { + QStringList split = fullAddress.split(":"); + + // The logic below replicates the exact logic minecraft uses for parsing server addresses. + // While the conversion is not lossless and eats errors, it ensures the same behavior + // within Minecraft and MultiMC when entering server addresses. + if (fullAddress.startsWith("[")) + { + int bracket = fullAddress.indexOf("]"); + if (bracket > 0) + { + QString ipv6 = fullAddress.mid(1, bracket - 1); + QString port = fullAddress.mid(bracket + 1).trimmed(); + + if (port.startsWith(":") && !ipv6.isEmpty()) + { + port = port.mid(1); + split = QStringList({ ipv6, port }); + } + else + { + split = QStringList({ipv6}); + } + } + } + + if (split.size() > 2) + { + split = QStringList({fullAddress}); + } + + QString realAddress = split[0]; + + quint16 realPort = 25565; + if (split.size() > 1) + { + bool ok; + realPort = split[1].toUInt(&ok); + + if (!ok) + { + realPort = 25565; + } + } + + return MinecraftServerTarget { realAddress, realPort }; +} diff --git a/api/logic/minecraft/launch/MinecraftServerTarget.h b/api/logic/minecraft/launch/MinecraftServerTarget.h new file mode 100644 index 00000000..3c5786f4 --- /dev/null +++ b/api/logic/minecraft/launch/MinecraftServerTarget.h @@ -0,0 +1,30 @@ +/* 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 <memory> + +#include <QString> +#include <multimc_logic_export.h> + +struct MinecraftServerTarget { + QString address; + quint16 port; + + static MULTIMC_LOGIC_EXPORT MinecraftServerTarget parse(const QString &fullAddress); +}; + +typedef std::shared_ptr<MinecraftServerTarget> MinecraftServerTargetPtr; diff --git a/api/logic/minecraft/launch/PrintInstanceInfo.cpp b/api/logic/minecraft/launch/PrintInstanceInfo.cpp index af0b5bbf..0b9611ad 100644 --- a/api/logic/minecraft/launch/PrintInstanceInfo.cpp +++ b/api/logic/minecraft/launch/PrintInstanceInfo.cpp @@ -101,6 +101,6 @@ void PrintInstanceInfo::executeTask() #endif logLines(log, MessageLevel::MultiMC); - logLines(instance->verboseDescription(m_session), MessageLevel::MultiMC); + logLines(instance->verboseDescription(m_session, m_serverToJoin), MessageLevel::MultiMC); emitSucceeded(); } diff --git a/api/logic/minecraft/launch/PrintInstanceInfo.h b/api/logic/minecraft/launch/PrintInstanceInfo.h index 168eff9d..fdc30f31 100644 --- a/api/logic/minecraft/launch/PrintInstanceInfo.h +++ b/api/logic/minecraft/launch/PrintInstanceInfo.h @@ -18,13 +18,15 @@ #include <launch/LaunchStep.h> #include <memory> #include "minecraft/auth/AuthSession.h" +#include "minecraft/launch/MinecraftServerTarget.h" // FIXME: temporary wrapper for existing task. class PrintInstanceInfo: public LaunchStep { Q_OBJECT public: - explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session) : LaunchStep(parent), m_session(session) {}; + explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) : + LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin) {}; virtual ~PrintInstanceInfo(){}; virtual void executeTask(); @@ -34,5 +36,6 @@ public: } private: AuthSessionPtr m_session; + MinecraftServerTargetPtr m_serverToJoin; }; diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.cpp b/api/logic/minecraft/launch/VerifyJavaInstall.cpp new file mode 100644 index 00000000..657669af --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.cpp @@ -0,0 +1,34 @@ +#include "VerifyJavaInstall.h" + +#include <launch/LaunchTask.h> +#include <minecraft/MinecraftInstance.h> +#include <minecraft/PackProfile.h> +#include <minecraft/VersionFilterData.h> + +void VerifyJavaInstall::executeTask() { + auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance()); + + auto javaVersion = m_inst->getJavaVersion(); + auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft"); + + // Java 16 requirement + if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) { + if (javaVersion.major() < 16) { + emit logLine("Minecraft 21w19a and above require the use of Java 16", + MessageLevel::Fatal); + emitFailed(tr("Minecraft 21w19a and above require the use of Java 16")); + return; + } + } + // Java 8 requirement + else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java8BeginsDate) { + if (javaVersion.major() < 8) { + emit logLine("Minecraft 17w13a and above require the use of Java 8", + MessageLevel::Fatal); + emitFailed(tr("Minecraft 17w13a and above require the use of Java 8")); + return; + } + } + + emitSucceeded(); +} diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.h b/api/logic/minecraft/launch/VerifyJavaInstall.h new file mode 100644 index 00000000..a553106d --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.h @@ -0,0 +1,17 @@ +#pragma once + +#include <launch/LaunchStep.h> + +class VerifyJavaInstall : public LaunchStep { + Q_OBJECT + +public: + explicit VerifyJavaInstall(LaunchTask *parent) : LaunchStep(parent) { + }; + ~VerifyJavaInstall() override = default; + + void executeTask() override; + bool canAbort() const override { + return false; + } +}; |
