NOISSUE Add support for launching worlds directly via Quick Play

This commit is contained in:
arthomnix
2023-04-08 18:03:20 +01:00
parent 22f82c34bf
commit 71cf4f8d18
30 changed files with 306 additions and 103 deletions

View File

@@ -122,8 +122,11 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), gameTimeOverride);
// Join server on launch, this does not have a global override
m_settings->registerSetting("JoinWorldOnLaunch", false);
m_settings->registerSetting("JoinServerOnLaunch", false);
m_settings->registerSetting("JoinServerOnLaunchAddress", "");
m_settings->registerSetting("JoinSingleplayerWorldOnLaunch", false);
m_settings->registerSetting("JoinSingleplayerWorldOnLaunchName", "");
// DEPRECATED: Read what versions the user configuration thinks should be used
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
@@ -415,7 +418,7 @@ static QString replaceTokensIn(QString text, QMap<QString, QString> with)
}
QStringList MinecraftInstance::processMinecraftArgs(
AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const
AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget) const
{
auto profile = m_components->getProfile();
QString args_pattern = profile->getMinecraftArguments();
@@ -424,18 +427,23 @@ QStringList MinecraftInstance::processMinecraftArgs(
args_pattern += " --tweakClass " + tweaker;
}
if (serverToJoin && !serverToJoin->address.isEmpty())
if (quickPlayTarget && !quickPlayTarget->address.isEmpty())
{
if (m_components->getComponent("net.minecraft")->getReleaseDateTime() >= g_VersionFilterData.quickPlayBeginsDate)
{
args_pattern += " --quickPlayMultiplayer " + serverToJoin->address + ":" + QString::number(serverToJoin->port);
args_pattern += " --quickPlayMultiplayer " + quickPlayTarget->address + ":" + QString::number(quickPlayTarget->port);
}
else
{
args_pattern += " --server " + serverToJoin->address;
args_pattern += " --port " + QString::number(serverToJoin->port);
args_pattern += " --server " + quickPlayTarget->address;
args_pattern += " --port " + QString::number(quickPlayTarget->port);
}
}
if (quickPlayTarget && quickPlayTarget->world.isEmpty())
{
args_pattern += " --quickPlaySingleplayer \"" + quickPlayTarget->world + "\"";
}
QMap<QString, QString> token_mapping;
// yggdrasil!
@@ -474,7 +482,7 @@ QStringList MinecraftInstance::processMinecraftArgs(
return parts;
}
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget)
{
QString launchScript;
@@ -495,17 +503,22 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
launchScript += "appletClass " + appletClass + "\n";
}
if (serverToJoin && !serverToJoin->address.isEmpty())
if (quickPlayTarget && !quickPlayTarget->address.isEmpty())
{
launchScript += "useQuickPlay " + QString::number(m_components->getComponent("net.minecraft")->getReleaseDateTime() >= g_VersionFilterData.quickPlayBeginsDate) + "\n";
launchScript += "serverAddress " + serverToJoin->address + "\n";
launchScript += "serverPort " + QString::number(serverToJoin->port) + "\n";
launchScript += "serverAddress " + quickPlayTarget->address + "\n";
launchScript += "serverPort " + QString::number(quickPlayTarget->port) + "\n";
}
if (quickPlayTarget && !quickPlayTarget->world.isEmpty())
{
launchScript += "joinWorld " + quickPlayTarget->world + "\n";
}
// generic minecraft params
for (auto param : processMinecraftArgs(
session,
nullptr /* When using a launch script, the server parameters are handled by it*/
nullptr /* When using a launch script, the server and world parameters are handled by it*/
))
{
launchScript += "param " + param + "\n";
@@ -558,7 +571,7 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
return launchScript;
}
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget)
{
QStringList out;
out << "Main Class:" << " " + getMainClass() << "";
@@ -673,7 +686,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
out << "";
}
auto params = processMinecraftArgs(nullptr, serverToJoin);
auto params = processMinecraftArgs(nullptr, quickPlayTarget);
out << "Params:";
out << " " + params.join(' ');
out << "";
@@ -834,7 +847,7 @@ Task::Ptr MinecraftInstance::createUpdateTask(Net::Mode mode)
return nullptr;
}
shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget)
{
// FIXME: get rid of shared_from_this ...
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this()));
@@ -866,18 +879,26 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
process->appendStep(new CreateGameFolders(pptr));
}
if (!serverToJoin && m_settings->get("JoinServerOnLaunch").toBool())
if (!quickPlayTarget && m_settings->get("JoinWorldOnLaunch").toBool())
{
QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString();
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress)));
if (m_settings->get("JoinServerOnLaunch").toBool())
{
QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString();
quickPlayTarget.reset(new QuickPlayTarget(QuickPlayTarget::parseMultiplayer(fullAddress)));
}
else if (m_settings->get("JoinSingleplayerWorldOnLaunch").toBool())
{
QString worldName = m_settings->get("JoinSingleplayerWorldOnLaunchName").toString();
quickPlayTarget.reset(new QuickPlayTarget(QuickPlayTarget::parseSingleplayer(worldName)));
}
}
if(serverToJoin && serverToJoin->port == 25565)
if(quickPlayTarget && quickPlayTarget->port == 25565)
{
// Resolve server address to join on launch
auto *step = new LookupServerAddress(pptr);
step->setLookupAddress(serverToJoin->address);
step->setOutputAddressPtr(serverToJoin);
step->setLookupAddress(quickPlayTarget->address);
step->setOutputAddressPtr(quickPlayTarget);
process->appendStep(step);
}
@@ -914,7 +935,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
// print some instance info here...
{
process->appendStep(new PrintInstanceInfo(pptr, session, serverToJoin));
process->appendStep(new PrintInstanceInfo(pptr, session, quickPlayTarget));
}
// extract native jars if needed
@@ -940,7 +961,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
auto step = new LauncherPartLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
step->setServerToJoin(serverToJoin);
step->setQuickPlayTarget(quickPlayTarget);
process->appendStep(step);
}
else if (method == "DirectJava")
@@ -948,7 +969,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
auto step = new DirectJavaLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
step->setServerToJoin(serverToJoin);
step->setQuickPlayTarget(quickPlayTarget);
process->appendStep(step);
}
}

View File

@@ -4,7 +4,7 @@
#include "minecraft/mod/Mod.h"
#include <QProcess>
#include <QDir>
#include "minecraft/launch/MinecraftServerTarget.h"
#include "minecraft/launch/QuickPlayTarget.h"
class ModFolderModel;
class WorldList;
@@ -78,11 +78,11 @@ public:
////// Launch stuff //////
Task::Ptr createUpdateTask(Net::Mode mode) override;
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, QuickPlayTargetPtr quickPlayTarget) override;
QStringList extraArguments() const override;
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
QStringList verboseDescription(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget) override;
QList<Mod> getJarMods() const;
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
QString createLaunchScript(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget);
/// get arguments passed to java
QStringList javaArguments() const;
@@ -109,7 +109,7 @@ public:
virtual QString getMainClass() const;
// FIXME: remove
virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) const;
virtual QStringList processMinecraftArgs(AuthSessionPtr account, QuickPlayTargetPtr quickPlayTarget) const;
virtual JavaVersion getJavaVersion() const;

View File

@@ -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, m_serverToJoin);
auto mcArgs = minecraftInstance->processMinecraftArgs(m_session, m_quickPlayTarget);
args.append(mcArgs);
QString wrapperCommandStr = instance->getWrapperCommand().trimmed();

View File

@@ -19,7 +19,7 @@
#include <LoggedProcess.h>
#include <minecraft/auth/AuthSession.h>
#include "MinecraftServerTarget.h"
#include "QuickPlayTarget.h"
class DirectJavaLaunch: public LaunchStep
{
@@ -41,9 +41,9 @@ public:
m_session = session;
}
void setServerToJoin(MinecraftServerTargetPtr serverToJoin)
void setQuickPlayTarget(QuickPlayTargetPtr quickPlayTarget)
{
m_serverToJoin = std::move(serverToJoin);
m_quickPlayTarget = std::move(quickPlayTarget);
}
private slots:
@@ -53,6 +53,6 @@ private:
LoggedProcess m_process;
QString m_command;
AuthSessionPtr m_session;
MinecraftServerTargetPtr m_serverToJoin;
QuickPlayTargetPtr m_quickPlayTarget;
};

View File

@@ -60,7 +60,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_serverToJoin);
m_launchScript = minecraftInstance->createLaunchScript(m_session, m_quickPlayTarget);
QStringList args = minecraftInstance->javaArguments();
QString allArgs = args.join(", ");
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::Launcher);

View File

@@ -19,7 +19,7 @@
#include <LoggedProcess.h>
#include <minecraft/auth/AuthSession.h>
#include "MinecraftServerTarget.h"
#include "QuickPlayTarget.h"
class LauncherPartLaunch: public LaunchStep
{
@@ -41,9 +41,9 @@ public:
m_session = session;
}
void setServerToJoin(MinecraftServerTargetPtr serverToJoin)
void setQuickPlayTarget(QuickPlayTargetPtr quickPlayTarget)
{
m_serverToJoin = std::move(serverToJoin);
m_quickPlayTarget = std::move(quickPlayTarget);
}
private slots:
@@ -54,7 +54,7 @@ private:
QString m_command;
AuthSessionPtr m_session;
QString m_launchScript;
MinecraftServerTargetPtr m_serverToJoin;
QuickPlayTargetPtr m_quickPlayTarget;
bool mayProceed = false;
};

View File

@@ -142,6 +142,6 @@ void PrintInstanceInfo::executeTask()
#endif
logLines(log, MessageLevel::Launcher);
logLines(instance->verboseDescription(m_session, m_serverToJoin), MessageLevel::Launcher);
logLines(instance->verboseDescription(m_session, m_quickPlayTarget), MessageLevel::Launcher);
emitSucceeded();
}

View File

@@ -18,15 +18,15 @@
#include <launch/LaunchStep.h>
#include <memory>
#include "minecraft/auth/AuthSession.h"
#include "minecraft/launch/MinecraftServerTarget.h"
#include "minecraft/launch/QuickPlayTarget.h"
// FIXME: temporary wrapper for existing task.
class PrintInstanceInfo: public LaunchStep
{
Q_OBJECT
public:
explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) :
LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin) {};
explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget) :
LaunchStep(parent), m_session(session), m_quickPlayTarget(quickPlayTarget) {};
virtual ~PrintInstanceInfo(){};
virtual void executeTask();
@@ -36,6 +36,6 @@ public:
}
private:
AuthSessionPtr m_session;
MinecraftServerTargetPtr m_serverToJoin;
QuickPlayTargetPtr m_quickPlayTarget;
};

View File

@@ -13,12 +13,12 @@
* limitations under the License.
*/
#include "MinecraftServerTarget.h"
#include "QuickPlayTarget.h"
#include <QStringList>
// FIXME: the way this is written, it can't ever do any sort of validation and can accept total junk
MinecraftServerTarget MinecraftServerTarget::parse(const QString &fullAddress) {
QuickPlayTarget QuickPlayTarget::parseMultiplayer(const QString &fullAddress) {
QStringList split = fullAddress.split(":");
// The logic below replicates the exact logic minecraft uses for parsing server addresses.
@@ -63,5 +63,12 @@ MinecraftServerTarget MinecraftServerTarget::parse(const QString &fullAddress) {
}
}
return MinecraftServerTarget { realAddress, realPort };
return QuickPlayTarget {realAddress, realPort };
}
QuickPlayTarget QuickPlayTarget::parseSingleplayer(const QString &worldName)
{
QuickPlayTarget target;
target.world = worldName;
return target;
}

View File

@@ -19,11 +19,16 @@
#include <QString>
struct MinecraftServerTarget {
struct QuickPlayTarget {
// Multiplayer
QString address;
quint16 port;
static MinecraftServerTarget parse(const QString &fullAddress);
// Singleplayer
QString world;
static QuickPlayTarget parseMultiplayer(const QString &fullAddress);
static QuickPlayTarget parseSingleplayer(const QString &worldName);
};
typedef std::shared_ptr<MinecraftServerTarget> MinecraftServerTargetPtr;
typedef std::shared_ptr<QuickPlayTarget> QuickPlayTargetPtr;

View File

@@ -225,7 +225,7 @@ QString LegacyInstance::getStatusbarDescription()
return tr("Instance from previous versions.");
}
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget)
{
QStringList out;

View File

@@ -112,7 +112,7 @@ public:
return false;
}
shared_qobject_ptr<LaunchTask> createLaunchTask(
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override
AuthSessionPtr account, QuickPlayTargetPtr quickPlayTarget) override
{
return nullptr;
}
@@ -126,7 +126,7 @@ public:
}
QString getStatusbarDescription() override;
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
QStringList verboseDescription(AuthSessionPtr session, QuickPlayTargetPtr quickPlayTarget) override;
QProcessEnvironment createEnvironment() override
{