aboutsummaryrefslogtreecommitdiff
path: root/api/logic/minecraft
diff options
context:
space:
mode:
Diffstat (limited to 'api/logic/minecraft')
-rw-r--r--api/logic/minecraft/MinecraftInstance.cpp79
-rw-r--r--api/logic/minecraft/MinecraftInstance.h9
-rw-r--r--api/logic/minecraft/VersionFilterData.cpp53
-rw-r--r--api/logic/minecraft/VersionFilterData.h5
-rw-r--r--api/logic/minecraft/launch/CreateGameFolders.cpp2
-rw-r--r--api/logic/minecraft/launch/DirectJavaLaunch.cpp21
-rw-r--r--api/logic/minecraft/launch/DirectJavaLaunch.h9
-rw-r--r--api/logic/minecraft/launch/ExtractNatives.cpp6
-rw-r--r--api/logic/minecraft/launch/LauncherPartLaunch.cpp19
-rw-r--r--api/logic/minecraft/launch/LauncherPartLaunch.h9
-rw-r--r--api/logic/minecraft/launch/MinecraftServerTarget.cpp66
-rw-r--r--api/logic/minecraft/launch/MinecraftServerTarget.h30
-rw-r--r--api/logic/minecraft/launch/PrintInstanceInfo.cpp2
-rw-r--r--api/logic/minecraft/launch/PrintInstanceInfo.h5
-rw-r--r--api/logic/minecraft/launch/VerifyJavaInstall.cpp34
-rw-r--r--api/logic/minecraft/launch/VerifyJavaInstall.h17
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.cpp2
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.h5
-rw-r--r--api/logic/minecraft/mod/LocalModParseTask.cpp171
-rw-r--r--api/logic/minecraft/mod/ResourcePackFolderModel.cpp23
-rw-r--r--api/logic/minecraft/mod/ResourcePackFolderModel.h13
-rw-r--r--api/logic/minecraft/mod/TexturePackFolderModel.cpp23
-rw-r--r--api/logic/minecraft/mod/TexturePackFolderModel.h13
-rw-r--r--api/logic/minecraft/update/FMLLibrariesTask.cpp2
24 files changed, 545 insertions, 73 deletions
diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp
index 37cdece7..dbf9f816 100644
--- a/api/logic/minecraft/MinecraftInstance.cpp
+++ b/api/logic/minecraft/MinecraftInstance.cpp
@@ -12,6 +12,7 @@
#include <java/JavaVersion.h>
#include "launch/LaunchTask.h"
+#include "launch/steps/LookupServerAddress.h"
#include "launch/steps/PostLaunchCommand.h"
#include "launch/steps/Update.h"
#include "launch/steps/PreLaunchCommand.h"
@@ -22,12 +23,15 @@
#include "minecraft/launch/ClaimAccount.h"
#include "minecraft/launch/ReconstructAssets.h"
#include "minecraft/launch/ScanModFolders.h"
+#include "minecraft/launch/VerifyJavaInstall.h"
#include "java/launch/CheckJava.h"
#include "java/JavaUtils.h"
#include "meta/Index.h"
#include "meta/VersionList.h"
#include "mod/ModFolderModel.h"
+#include "mod/ResourcePackFolderModel.h"
+#include "mod/TexturePackFolderModel.h"
#include "WorldList.h"
#include "icons/IIconList.h"
@@ -106,6 +110,15 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
m_settings->registerOverride(globalSettings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride);
m_settings->registerOverride(globalSettings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
+ // Game time
+ auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
+ m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
+ m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), gameTimeOverride);
+
+ // Join server on launch, this does not have a global override
+ m_settings->registerSetting("JoinServerOnLaunch", false);
+ m_settings->registerSetting("JoinServerOnLaunchAddress", "");
+
// DEPRECATED: Read what versions the user configuration thinks should be used
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
m_settings->registerSetting("LWJGLVersion", "");
@@ -390,7 +403,8 @@ static QString replaceTokensIn(QString text, QMap<QString, QString> with)
return result;
}
-QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) const
+QStringList MinecraftInstance::processMinecraftArgs(
+ AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const
{
auto profile = m_components->getProfile();
QString args_pattern = profile->getMinecraftArguments();
@@ -399,6 +413,12 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) cons
args_pattern += " --tweakClass " + tweaker;
}
+ if (serverToJoin && !serverToJoin->address.isEmpty())
+ {
+ args_pattern += " --server " + serverToJoin->address;
+ args_pattern += " --port " + QString::number(serverToJoin->port);
+ }
+
QMap<QString, QString> token_mapping;
// yggdrasil!
if(session)
@@ -435,7 +455,7 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) cons
return parts;
}
-QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
+QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
{
QString launchScript;
@@ -456,8 +476,17 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
launchScript += "appletClass " + appletClass + "\n";
}
+ if (serverToJoin && !serverToJoin->address.isEmpty())
+ {
+ launchScript += "serverAddress " + serverToJoin->address + "\n";
+ launchScript += "serverPort " + QString::number(serverToJoin->port) + "\n";
+ }
+
// generic minecraft params
- for (auto param : processMinecraftArgs(session))
+ for (auto param : processMinecraftArgs(
+ session,
+ nullptr /* When using a launch script, the server parameters are handled by it*/
+ ))
{
launchScript += "param " + param + "\n";
}
@@ -507,7 +536,7 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
return launchScript;
}
-QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
+QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
{
QStringList out;
out << "Main Class:" << " " + getMainClass() << "";
@@ -622,7 +651,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
out << "";
}
- auto params = processMinecraftArgs(nullptr);
+ auto params = processMinecraftArgs(nullptr, serverToJoin);
out << "Params:";
out << " " + params.join(' ');
out << "";
@@ -769,9 +798,15 @@ QString MinecraftInstance::getStatusbarDescription()
QString description;
description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName()));
- if(totalTimePlayed() > 0)
+ if(m_settings->get("ShowGameTime").toBool())
{
- description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
+ if (lastTimePlayed() > 0) {
+ description.append(tr(", last played for %1").arg(prettifyTimeDuration(lastTimePlayed())));
+ }
+
+ if (totalTimePlayed() > 0) {
+ description.append(tr(", total played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
+ }
}
if(hasCrashed())
{
@@ -796,7 +831,7 @@ shared_qobject_ptr<Task> MinecraftInstance::createUpdateTask(Net::Mode mode)
return nullptr;
}
-shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session)
+shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
{
// FIXME: get rid of shared_from_this ...
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this()));
@@ -828,6 +863,21 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
process->appendStep(new CreateGameFolders(pptr));
}
+ if (!serverToJoin && m_settings->get("JoinServerOnLaunch").toBool())
+ {
+ QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString();
+ serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress)));
+ }
+
+ if(serverToJoin && serverToJoin->port == 25565)
+ {
+ // Resolve server address to join on launch
+ auto *step = new LookupServerAddress(pptr);
+ step->setLookupAddress(serverToJoin->address);
+ step->setOutputAddressPtr(serverToJoin);
+ process->appendStep(step);
+ }
+
// run pre-launch command if that's needed
if(getPreLaunchCommand().size())
{
@@ -859,7 +909,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
// print some instance info here...
{
- process->appendStep(new PrintInstanceInfo(pptr, session));
+ process->appendStep(new PrintInstanceInfo(pptr, session, serverToJoin));
}
// extract native jars if needed
@@ -872,6 +922,11 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
process->appendStep(new ReconstructAssets(pptr));
}
+ // verify that minimum Java requirements are met
+ {
+ process->appendStep(new VerifyJavaInstall(pptr));
+ }
+
{
// actually launch the game
auto method = launchMethod();
@@ -880,6 +935,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
auto step = new LauncherPartLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
+ step->setServerToJoin(serverToJoin);
process->appendStep(step);
}
else if (method == "DirectJava")
@@ -887,6 +943,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
auto step = new DirectJavaLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
+ step->setServerToJoin(serverToJoin);
process->appendStep(step);
}
}
@@ -943,7 +1000,7 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::resourcePackList() const
{
if (!m_resource_pack_list)
{
- m_resource_pack_list.reset(new ModFolderModel(resourcePacksDir()));
+ m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir()));
m_resource_pack_list->disableInteraction(isRunning());
connect(this, &BaseInstance::runningStatusChanged, m_resource_pack_list.get(), &ModFolderModel::disableInteraction);
}
@@ -954,7 +1011,7 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::texturePackList() const
{
if (!m_texture_pack_list)
{
- m_texture_pack_list.reset(new ModFolderModel(texturePacksDir()));
+ m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir()));
m_texture_pack_list->disableInteraction(isRunning());
connect(this, &BaseInstance::runningStatusChanged, m_texture_pack_list.get(), &ModFolderModel::disableInteraction);
}
diff --git a/api/logic/minecraft/MinecraftInstance.h b/api/logic/minecraft/MinecraftInstance.h
index 985a8a76..05600797 100644
--- a/api/logic/minecraft/MinecraftInstance.h
+++ b/api/logic/minecraft/MinecraftInstance.h
@@ -5,6 +5,7 @@
#include <QProcess>
#include <QDir>
#include "multimc_logic_export.h"
+#include "minecraft/launch/MinecraftServerTarget.h"
class ModFolderModel;
class WorldList;
@@ -76,11 +77,11 @@ public:
////// Launch stuff //////
shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
- shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
+ shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
QStringList extraArguments() const override;
- QStringList verboseDescription(AuthSessionPtr session) override;
+ QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
QList<Mod> getJarMods() const;
- QString createLaunchScript(AuthSessionPtr session);
+ QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
/// get arguments passed to java
QStringList javaArguments() const;
@@ -107,7 +108,7 @@ public:
virtual QString getMainClass() const;
// FIXME: remove
- virtual QStringList processMinecraftArgs(AuthSessionPtr account) const;
+ virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) const;
virtual JavaVersion getJavaVersion() const;
diff --git a/api/logic/minecraft/VersionFilterData.cpp b/api/logic/minecraft/VersionFilterData.cpp
index 11f7eea9..38e7b60c 100644
--- a/api/logic/minecraft/VersionFilterData.cpp
+++ b/api/logic/minecraft/VersionFilterData.cpp
@@ -7,18 +7,18 @@ VersionFilterData::VersionFilterData()
{
// 1.3.*
auto libs13 =
- QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}};
+ QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b"},
+ {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f"},
+ {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82"}};
fmlLibsMapping["1.3.2"] = libs13;
// 1.4.*
auto libs14 = QList<FMLlib>{
- {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false},
- {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}};
+ {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b"},
+ {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f"},
+ {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82"},
+ {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb"}};
fmlLibsMapping["1.4"] = libs14;
fmlLibsMapping["1.4.1"] = libs14;
@@ -31,30 +31,30 @@ VersionFilterData::VersionFilterData()
// 1.5
fmlLibsMapping["1.5"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"},
+ {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8"},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}};
// 1.5.1
fmlLibsMapping["1.5.1"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"},
+ {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6"},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}};
// 1.5.2
fmlLibsMapping["1.5.2"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"},
+ {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9"},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}};
// don't use installers for those.
forgeInstallerBlacklist = QSet<QString>({"1.5.2"});
@@ -65,4 +65,7 @@ VersionFilterData::VersionFilterData()
QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform",
"net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl",
"org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"};
+
+ java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00");
+ java16BeginsDate = timeFromS3Time("2021-05-12T11:19:15+00:00");
}
diff --git a/api/logic/minecraft/VersionFilterData.h b/api/logic/minecraft/VersionFilterData.h
index 88e91f11..d100acc3 100644
--- a/api/logic/minecraft/VersionFilterData.h
+++ b/api/logic/minecraft/VersionFilterData.h
@@ -10,7 +10,6 @@ struct FMLlib
{
QString filename;
QString checksum;
- bool ours;
};
struct VersionFilterData
@@ -24,5 +23,9 @@ struct VersionFilterData
QDateTime legacyCutoffDate;
// Libraries that belong to LWJGL
QSet<QString> lwjglWhitelist;
+ // release date of first version to require Java 8 (17w13a)
+ QDateTime java8BeginsDate;
+ // release data of first version to require Java 16 (21w19a)
+ QDateTime java16BeginsDate;
};
extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData;
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 speci