Merge pull request #3804 from Janrupf/feature/default-server
Add ability to select a server to join in the instance settings
This commit is contained in:
commit
60b686f014
@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
#include "multimc_logic_export.h"
|
#include "multimc_logic_export.h"
|
||||||
|
|
||||||
|
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||||
|
|
||||||
class QDir;
|
class QDir;
|
||||||
class Task;
|
class Task;
|
||||||
class LaunchTask;
|
class LaunchTask;
|
||||||
@ -145,7 +147,8 @@ public:
|
|||||||
virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0;
|
virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0;
|
||||||
|
|
||||||
/// returns a valid launcher (task container)
|
/// returns a valid launcher (task container)
|
||||||
virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
|
virtual shared_qobject_ptr<LaunchTask> createLaunchTask(
|
||||||
|
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
|
||||||
|
|
||||||
/// returns the current launch task (if any)
|
/// returns the current launch task (if any)
|
||||||
shared_qobject_ptr<LaunchTask> getLaunchTask();
|
shared_qobject_ptr<LaunchTask> getLaunchTask();
|
||||||
@ -221,9 +224,9 @@ public:
|
|||||||
bool reloadSettings();
|
bool reloadSettings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'print' a verbose desription of the instance into a QStringList
|
* 'print' a verbose description of the instance into a QStringList
|
||||||
*/
|
*/
|
||||||
virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
|
virtual QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) = 0;
|
||||||
|
|
||||||
Status currentStatus() const;
|
Status currentStatus() const;
|
||||||
|
|
||||||
|
@ -124,6 +124,8 @@ set(NET_SOURCES
|
|||||||
|
|
||||||
# Game launch logic
|
# Game launch logic
|
||||||
set(LAUNCH_SOURCES
|
set(LAUNCH_SOURCES
|
||||||
|
launch/steps/LookupServerAddress.cpp
|
||||||
|
launch/steps/LookupServerAddress.h
|
||||||
launch/steps/PostLaunchCommand.cpp
|
launch/steps/PostLaunchCommand.cpp
|
||||||
launch/steps/PostLaunchCommand.h
|
launch/steps/PostLaunchCommand.h
|
||||||
launch/steps/PreLaunchCommand.cpp
|
launch/steps/PreLaunchCommand.cpp
|
||||||
@ -236,6 +238,8 @@ set(MINECRAFT_SOURCES
|
|||||||
minecraft/launch/ExtractNatives.h
|
minecraft/launch/ExtractNatives.h
|
||||||
minecraft/launch/LauncherPartLaunch.cpp
|
minecraft/launch/LauncherPartLaunch.cpp
|
||||||
minecraft/launch/LauncherPartLaunch.h
|
minecraft/launch/LauncherPartLaunch.h
|
||||||
|
minecraft/launch/MinecraftServerTarget.cpp
|
||||||
|
minecraft/launch/MinecraftServerTarget.h
|
||||||
minecraft/launch/PrintInstanceInfo.cpp
|
minecraft/launch/PrintInstanceInfo.cpp
|
||||||
minecraft/launch/PrintInstanceInfo.h
|
minecraft/launch/PrintInstanceInfo.h
|
||||||
minecraft/launch/ReconstructAssets.cpp
|
minecraft/launch/ReconstructAssets.cpp
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
{
|
{
|
||||||
return instanceRoot();
|
return instanceRoot();
|
||||||
};
|
};
|
||||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
|
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QStringList verboseDescription(AuthSessionPtr session) override
|
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override
|
||||||
{
|
{
|
||||||
QStringList out;
|
QStringList out;
|
||||||
out << "Null instance - placeholder.";
|
out << "Null instance - placeholder.";
|
||||||
|
95
api/logic/launch/steps/LookupServerAddress.cpp
Normal file
95
api/logic/launch/steps/LookupServerAddress.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* 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::MultiMC);
|
||||||
|
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::MultiMC);
|
||||||
|
resolve(firstRecord.target(), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LookupServerAddress::resolve(const QString &address, quint16 port)
|
||||||
|
{
|
||||||
|
m_output->address = address;
|
||||||
|
m_output->port = port;
|
||||||
|
|
||||||
|
emitSucceeded();
|
||||||
|
m_dnsLookup->deleteLater();
|
||||||
|
}
|
49
api/logic/launch/steps/LookupServerAddress.h
Normal file
49
api/logic/launch/steps/LookupServerAddress.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* 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;
|
||||||
|
};
|
@ -12,6 +12,7 @@
|
|||||||
#include <java/JavaVersion.h>
|
#include <java/JavaVersion.h>
|
||||||
|
|
||||||
#include "launch/LaunchTask.h"
|
#include "launch/LaunchTask.h"
|
||||||
|
#include "launch/steps/LookupServerAddress.h"
|
||||||
#include "launch/steps/PostLaunchCommand.h"
|
#include "launch/steps/PostLaunchCommand.h"
|
||||||
#include "launch/steps/Update.h"
|
#include "launch/steps/Update.h"
|
||||||
#include "launch/steps/PreLaunchCommand.h"
|
#include "launch/steps/PreLaunchCommand.h"
|
||||||
@ -111,6 +112,10 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
|
|||||||
m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
|
m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
|
||||||
m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), 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
|
// DEPRECATED: Read what versions the user configuration thinks should be used
|
||||||
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
|
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
|
||||||
m_settings->registerSetting("LWJGLVersion", "");
|
m_settings->registerSetting("LWJGLVersion", "");
|
||||||
@ -395,7 +400,8 @@ static QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) const
|
QStringList MinecraftInstance::processMinecraftArgs(
|
||||||
|
AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const
|
||||||
{
|
{
|
||||||
auto profile = m_components->getProfile();
|
auto profile = m_components->getProfile();
|
||||||
QString args_pattern = profile->getMinecraftArguments();
|
QString args_pattern = profile->getMinecraftArguments();
|
||||||
@ -404,6 +410,12 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) cons
|
|||||||
args_pattern += " --tweakClass " + tweaker;
|
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;
|
QMap<QString, QString> token_mapping;
|
||||||
// yggdrasil!
|
// yggdrasil!
|
||||||
if(session)
|
if(session)
|
||||||
@ -440,7 +452,7 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) cons
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
|
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||||
{
|
{
|
||||||
QString launchScript;
|
QString launchScript;
|
||||||
|
|
||||||
@ -461,8 +473,17 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
launchScript += "appletClass " + appletClass + "\n";
|
launchScript += "appletClass " + appletClass + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serverToJoin && !serverToJoin->address.isEmpty())
|
||||||
|
{
|
||||||
|
launchScript += "serverAddress " + serverToJoin->address + "\n";
|
||||||
|
launchScript += "serverPort " + QString::number(serverToJoin->port) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// generic minecraft params
|
// 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";
|
launchScript += "param " + param + "\n";
|
||||||
}
|
}
|
||||||
@ -512,7 +533,7 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
return launchScript;
|
return launchScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
|
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||||
{
|
{
|
||||||
QStringList out;
|
QStringList out;
|
||||||
out << "Main Class:" << " " + getMainClass() << "";
|
out << "Main Class:" << " " + getMainClass() << "";
|
||||||
@ -627,7 +648,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
|
|||||||
out << "";
|
out << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto params = processMinecraftArgs(nullptr);
|
auto params = processMinecraftArgs(nullptr, serverToJoin);
|
||||||
out << "Params:";
|
out << "Params:";
|
||||||
out << " " + params.join(' ');
|
out << " " + params.join(' ');
|
||||||
out << "";
|
out << "";
|
||||||
@ -801,7 +822,7 @@ shared_qobject_ptr<Task> MinecraftInstance::createUpdateTask(Net::Mode mode)
|
|||||||
return nullptr;
|
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 ...
|
// FIXME: get rid of shared_from_this ...
|
||||||
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this()));
|
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this()));
|
||||||
@ -833,6 +854,21 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
|||||||
process->appendStep(new CreateGameFolders(pptr));
|
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
|
// run pre-launch command if that's needed
|
||||||
if(getPreLaunchCommand().size())
|
if(getPreLaunchCommand().size())
|
||||||
{
|
{
|
||||||
@ -864,7 +900,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
|||||||
|
|
||||||
// print some instance info here...
|
// print some instance info here...
|
||||||
{
|
{
|
||||||
process->appendStep(new PrintInstanceInfo(pptr, session));
|
process->appendStep(new PrintInstanceInfo(pptr, session, serverToJoin));
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract native jars if needed
|
// extract native jars if needed
|
||||||
@ -885,6 +921,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
|||||||
auto step = new LauncherPartLaunch(pptr);
|
auto step = new LauncherPartLaunch(pptr);
|
||||||
step->setWorkingDirectory(gameRoot());
|
step->setWorkingDirectory(gameRoot());
|
||||||
step->setAuthSession(session);
|
step->setAuthSession(session);
|
||||||
|
step->setServerToJoin(serverToJoin);
|
||||||
process->appendStep(step);
|
process->appendStep(step);
|
||||||
}
|
}
|
||||||
else if (method == "DirectJava")
|
else if (method == "DirectJava")
|
||||||
@ -892,6 +929,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
|||||||
auto step = new DirectJavaLaunch(pptr);
|
auto step = new DirectJavaLaunch(pptr);
|
||||||
step->setWorkingDirectory(gameRoot());
|
step->setWorkingDirectory(gameRoot());
|
||||||
step->setAuthSession(session);
|
step->setAuthSession(session);
|
||||||
|
step->setServerToJoin(serverToJoin);
|
||||||
process->appendStep(step);
|
process->appendStep(step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include "multimc_logic_export.h"
|
#include "multimc_logic_export.h"
|
||||||
|
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||||
|
|
||||||
class ModFolderModel;
|
class ModFolderModel;
|
||||||
class WorldList;
|
class WorldList;
|
||||||
@ -76,11 +77,11 @@ public:
|
|||||||
|
|
||||||
////// Launch stuff //////
|
////// Launch stuff //////
|
||||||
shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
|
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 extraArguments() const override;
|
||||||
QStringList verboseDescription(AuthSessionPtr session) override;
|
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||||
QList<Mod> getJarMods() const;
|
QList<Mod> getJarMods() const;
|
||||||
QString createLaunchScript(AuthSessionPtr session);
|
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
||||||
/// get arguments passed to java
|
/// get arguments passed to java
|
||||||
QStringList javaArguments() const;
|
QStringList javaArguments() const;
|
||||||
|
|
||||||
@ -107,7 +108,7 @@ public:
|
|||||||
virtual QString getMainClass() const;
|
virtual QString getMainClass() const;
|
||||||
|
|
||||||
// FIXME: remove
|
// FIXME: remove
|
||||||
virtual QStringList processMinecraftArgs(AuthSessionPtr account) const;
|
virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) const;
|
||||||
|
|
||||||
virtual JavaVersion getJavaVersion() const;
|
virtual JavaVersion getJavaVersion() const;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ void DirectJavaLaunch::executeTask()
|
|||||||
// make detachable - this will keep the process running even if the object is destroyed
|
// make detachable - this will keep the process running even if the object is destroyed
|
||||||
m_process.setDetachable(true);
|
m_process.setDetachable(true);
|
||||||
|
|
||||||
auto mcArgs = minecraftInstance->processMinecraftArgs(m_session);
|
auto mcArgs = minecraftInstance->processMinecraftArgs(m_session, m_serverToJoin);
|
||||||
args.append(mcArgs);
|
args.append(mcArgs);
|
||||||
|
|
||||||
QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
|
QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <LoggedProcess.h>
|
#include <LoggedProcess.h>
|
||||||
#include <minecraft/auth/AuthSession.h>
|
#include <minecraft/auth/AuthSession.h>
|
||||||
|
|
||||||
|
#include "MinecraftServerTarget.h"
|
||||||
|
|
||||||
class DirectJavaLaunch: public LaunchStep
|
class DirectJavaLaunch: public LaunchStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -38,6 +40,12 @@ public:
|
|||||||
{
|
{
|
||||||
m_session = session;
|
m_session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setServerToJoin(MinecraftServerTargetPtr serverToJoin)
|
||||||
|
{
|
||||||
|
m_serverToJoin = std::move(serverToJoin);
|
||||||
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_state(LoggedProcess::State state);
|
void on_state(LoggedProcess::State state);
|
||||||
|
|
||||||
@ -45,5 +53,6 @@ private:
|
|||||||
LoggedProcess m_process;
|
LoggedProcess m_process;
|
||||||
QString m_command;
|
QString m_command;
|
||||||
AuthSessionPtr m_session;
|
AuthSessionPtr m_session;
|
||||||
|
MinecraftServerTargetPtr m_serverToJoin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ void LauncherPartLaunch::executeTask()
|
|||||||
auto instance = m_parent->instance();
|
auto instance = m_parent->instance();
|
||||||
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(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();
|
QStringList args = minecraftInstance->javaArguments();
|
||||||
QString allArgs = args.join(", ");
|
QString allArgs = args.join(", ");
|
||||||
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
|
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <LoggedProcess.h>
|
#include <LoggedProcess.h>
|
||||||
#include <minecraft/auth/AuthSession.h>
|
#include <minecraft/auth/AuthSession.h>
|
||||||
|
|
||||||
|
#include "MinecraftServerTarget.h"
|
||||||
|
|
||||||
class LauncherPartLaunch: public LaunchStep
|
class LauncherPartLaunch: public LaunchStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -39,6 +41,11 @@ public:
|
|||||||
m_session = session;
|
m_session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setServerToJoin(MinecraftServerTargetPtr serverToJoin)
|
||||||
|
{
|
||||||
|
m_serverToJoin = std::move(serverToJoin);
|
||||||
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_state(LoggedProcess::State state);
|
void on_state(LoggedProcess::State state);
|
||||||
|
|
||||||
@ -47,5 +54,7 @@ private:
|
|||||||
QString m_command;
|
QString m_command;
|
||||||
AuthSessionPtr m_session;
|
AuthSessionPtr m_session;
|
||||||
QString m_launchScript;
|
QString m_launchScript;
|
||||||
|
MinecraftServerTargetPtr m_serverToJoin;
|
||||||
|
|
||||||
bool mayProceed = false;
|
bool mayProceed = false;
|
||||||
};
|
};
|
||||||
|
66
api/logic/minecraft/launch/MinecraftServerTarget.cpp
Normal file
66
api/logic/minecraft/launch/MinecraftServerTarget.cpp
Normal file
@ -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 };
|
||||||
|
}
|
30
api/logic/minecraft/launch/MinecraftServerTarget.h
Normal file
30
api/logic/minecraft/launch/MinecraftServerTarget.h
Normal file
@ -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;
|
@ -101,6 +101,6 @@ void PrintInstanceInfo::executeTask()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
logLines(log, MessageLevel::MultiMC);
|
logLines(log, MessageLevel::MultiMC);
|
||||||
logLines(instance->verboseDescription(m_session), MessageLevel::MultiMC);
|
logLines(instance->verboseDescription(m_session, m_serverToJoin), MessageLevel::MultiMC);
|
||||||
emitSucceeded();
|
emitSucceeded();
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,15 @@
|
|||||||
#include <launch/LaunchStep.h>
|
#include <launch/LaunchStep.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "minecraft/auth/AuthSession.h"
|
#include "minecraft/auth/AuthSession.h"
|
||||||
|
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||||
|
|
||||||
// FIXME: temporary wrapper for existing task.
|
// FIXME: temporary wrapper for existing task.
|
||||||
class PrintInstanceInfo: public LaunchStep
|
class PrintInstanceInfo: public LaunchStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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 ~PrintInstanceInfo(){};
|
||||||
|
|
||||||
virtual void executeTask();
|
virtual void executeTask();
|
||||||
@ -34,5 +36,6 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
AuthSessionPtr m_session;
|
AuthSessionPtr m_session;
|
||||||
|
MinecraftServerTargetPtr m_serverToJoin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ QString LegacyInstance::getStatusbarDescription()
|
|||||||
return tr("Instance from previous versions.");
|
return tr("Instance from previous versions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session)
|
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||||
{
|
{
|
||||||
QStringList out;
|
QStringList out;
|
||||||
|
|
||||||
|
@ -111,7 +111,8 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override
|
shared_qobject_ptr<LaunchTask> createLaunchTask(
|
||||||
|
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString getStatusbarDescription() override;
|
QString getStatusbarDescription() override;
|
||||||
QStringList verboseDescription(AuthSessionPtr session) override;
|
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||||
|
|
||||||
QProcessEnvironment createEnvironment() override
|
QProcessEnvironment createEnvironment() override
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
values.append(new TexturePackPage(onesix.get()));
|
values.append(new TexturePackPage(onesix.get()));
|
||||||
values.append(new NotesPage(onesix.get()));
|
values.append(new NotesPage(onesix.get()));
|
||||||
values.append(new WorldListPage(onesix.get(), onesix->worldList()));
|
values.append(new WorldListPage(onesix.get(), onesix->worldList()));
|
||||||
values.append(new ServersPage(onesix.get()));
|
values.append(new ServersPage(onesix));
|
||||||
// values.append(new GameOptionsPage(onesix.get()));
|
// values.append(new GameOptionsPage(onesix.get()));
|
||||||
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
|
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
|
||||||
values.append(new InstanceSettingsPage(onesix.get()));
|
values.append(new InstanceSettingsPage(onesix.get()));
|
||||||
|
@ -197,7 +197,7 @@ void LaunchController::launchInstance()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_launcher = m_instance->createLaunchTask(m_session);
|
m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin);
|
||||||
if (!m_launcher)
|
if (!m_launcher)
|
||||||
{
|
{
|
||||||
emitFailed(tr("Couldn't instantiate a launcher."));
|
emitFailed(tr("Couldn't instantiate a launcher."));
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <BaseInstance.h>
|
#include <BaseInstance.h>
|
||||||
#include <tools/BaseProfiler.h>
|
#include <tools/BaseProfiler.h>
|
||||||
|
|
||||||
|
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||||
|
|
||||||
class InstanceWindow;
|
class InstanceWindow;
|
||||||
class LaunchController: public Task
|
class LaunchController: public Task
|
||||||
{
|
{
|
||||||
@ -33,6 +35,10 @@ public:
|
|||||||
{
|
{
|
||||||
m_parentWidget = widget;
|
m_parentWidget = widget;
|
||||||
}
|
}
|
||||||
|
void setServerToJoin(MinecraftServerTargetPtr serverToJoin)
|
||||||
|
{
|
||||||
|
m_serverToJoin = std::move(serverToJoin);
|
||||||
|
}
|
||||||
QString id()
|
QString id()
|
||||||
{
|
{
|
||||||
return m_instance->id();
|
return m_instance->id();
|
||||||
@ -58,4 +64,5 @@ private:
|
|||||||
InstanceWindow *m_console = nullptr;
|
InstanceWindow *m_console = nullptr;
|
||||||
AuthSessionPtr m_session;
|
AuthSessionPtr m_session;
|
||||||
shared_qobject_ptr<LaunchTask> m_launcher;
|
shared_qobject_ptr<LaunchTask> m_launcher;
|
||||||
|
MinecraftServerTargetPtr m_serverToJoin;
|
||||||
};
|
};
|
||||||
|
@ -191,6 +191,11 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
parser.addOption("launch");
|
parser.addOption("launch");
|
||||||
parser.addShortOpt("launch", 'l');
|
parser.addShortOpt("launch", 'l');
|
||||||
parser.addDocumentation("launch", "Launch the specified instance (by instance ID)");
|
parser.addDocumentation("launch", "Launch the specified instance (by instance ID)");
|
||||||
|
// --server
|
||||||
|
parser.addOption("server");
|
||||||
|
parser.addShortOpt("server", 's');
|
||||||
|
parser.addDocumentation("server", "Join the specified server on launch "
|
||||||
|
"(only valid in combination with --launch)");
|
||||||
// --alive
|
// --alive
|
||||||
parser.addSwitch("alive");
|
parser.addSwitch("alive");
|
||||||
parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after MultiMC starts");
|
parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after MultiMC starts");
|
||||||
@ -232,6 +237,7 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_instanceIdToLaunch = args["launch"].toString();
|
m_instanceIdToLaunch = args["launch"].toString();
|
||||||
|
m_serverToJoin = args["server"].toString();
|
||||||
m_liveCheck = args["alive"].toBool();
|
m_liveCheck = args["alive"].toBool();
|
||||||
m_zipToImport = args["import"].toUrl();
|
m_zipToImport = args["import"].toUrl();
|
||||||
|
|
||||||
@ -293,6 +299,13 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "--server can only be used in combination with --launch!" << std::endl;
|
||||||
|
m_status = MultiMC::Failed;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Establish the mechanism for communication with an already running MultiMC that uses the same data path.
|
* Establish the mechanism for communication with an already running MultiMC that uses the same data path.
|
||||||
* If there is one, tell it what the user actually wanted to do and exit.
|
* If there is one, tell it what the user actually wanted to do and exit.
|
||||||
@ -318,7 +331,15 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_peerInstance->sendMessage("launch " + m_instanceIdToLaunch, timeout);
|
if(!m_serverToJoin.isEmpty())
|
||||||
|
{
|
||||||
|
m_peerInstance->sendMessage(
|
||||||
|
"launch-with-server " + m_instanceIdToLaunch + " " + m_serverToJoin, timeout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_peerInstance->sendMessage("launch " + m_instanceIdToLaunch, timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_status = MultiMC::Succeeded;
|
m_status = MultiMC::Succeeded;
|
||||||
return;
|
return;
|
||||||
@ -399,6 +420,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
{
|
{
|
||||||
qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
|
qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
|
||||||
}
|
}
|
||||||
|
if(!m_serverToJoin.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "Address of server to join :" << m_serverToJoin;
|
||||||
|
}
|
||||||
qDebug() << "<> Paths set.";
|
qDebug() << "<> Paths set.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,8 +869,19 @@ void MultiMC::performMainStartupAction()
|
|||||||
auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
|
auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
|
||||||
if(inst)
|
if(inst)
|
||||||
{
|
{
|
||||||
qDebug() << "<> Instance launching:" << m_instanceIdToLaunch;
|
MinecraftServerTargetPtr serverToJoin = nullptr;
|
||||||
launch(inst, true, nullptr);
|
|
||||||
|
if(!m_serverToJoin.isEmpty())
|
||||||
|
{
|
||||||
|
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin)));
|
||||||
|
qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching with server" << m_serverToJoin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching";
|
||||||
|
}
|
||||||
|
|
||||||
|
launch(inst, true, nullptr, serverToJoin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -927,6 +963,31 @@ void MultiMC::messageReceived(const QString& message)
|
|||||||
launch(inst, true, nullptr);
|
launch(inst, true, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(command == "launch-with-server")
|
||||||
|
{
|
||||||
|
QString instanceID = message.section(' ', 1, 1);
|
||||||
|
QString serverToJoin = message.section(' ', 2, 2);
|
||||||
|
if(instanceID.isEmpty())
|
||||||
|
{
|
||||||
|
qWarning() << "Received" << command << "message without an instance ID.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(serverToJoin.isEmpty())
|
||||||
|
{
|
||||||
|
qWarning() << "Received" << command << "message without a server to join.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto inst = instances()->getInstanceById(instanceID);
|
||||||
|
if(inst)
|
||||||
|
{
|
||||||
|
launch(
|
||||||
|
inst,
|
||||||
|
true,
|
||||||
|
nullptr,
|
||||||
|
std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(serverToJoin))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning() << "Received invalid message" << message;
|
qWarning() << "Received invalid message" << message;
|
||||||
@ -1014,8 +1075,12 @@ bool MultiMC::openJsonEditor(const QString &filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *profiler)
|
bool MultiMC::launch(
|
||||||
{
|
InstancePtr instance,
|
||||||
|
bool online,
|
||||||
|
BaseProfilerFactory *profiler,
|
||||||
|
MinecraftServerTargetPtr serverToJoin
|
||||||
|
) {
|
||||||
if(m_updateRunning)
|
if(m_updateRunning)
|
||||||
{
|
{
|
||||||
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
|
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
|
||||||
@ -1036,6 +1101,7 @@ bool MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *pro
|
|||||||
controller->setInstance(instance);
|
controller->setInstance(instance);
|
||||||
controller->setOnline(online);
|
controller->setOnline(online);
|
||||||
controller->setProfiler(profiler);
|
controller->setProfiler(profiler);
|
||||||
|
controller->setServerToJoin(serverToJoin);
|
||||||
if(window)
|
if(window)
|
||||||
{
|
{
|
||||||
controller->setParentWidget(window);
|
controller->setParentWidget(window);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <BaseInstance.h>
|
#include <BaseInstance.h>
|
||||||
|
|
||||||
|
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||||
|
|
||||||
class LaunchController;
|
class LaunchController;
|
||||||
class LocalPeer;
|
class LocalPeer;
|
||||||
class InstanceWindow;
|
class InstanceWindow;
|
||||||
@ -150,7 +152,12 @@ signals:
|
|||||||
void globalSettingsClosed();
|
void globalSettingsClosed();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool launch(InstancePtr instance, bool online = true, BaseProfilerFactory *profiler = nullptr);
|
bool launch(
|
||||||
|
InstancePtr instance,
|
||||||
|
bool online = true,
|
||||||
|
BaseProfilerFactory *profiler = nullptr,
|
||||||
|
MinecraftServerTargetPtr serverToJoin = nullptr
|
||||||
|
);
|
||||||
bool kill(InstancePtr instance);
|
bool kill(InstancePtr instance);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -221,6 +228,7 @@ private:
|
|||||||
SetupWizard * m_setupWizard = nullptr;
|
SetupWizard * m_setupWizard = nullptr;
|
||||||
public:
|
public:
|
||||||
QString m_instanceIdToLaunch;
|
QString m_instanceIdToLaunch;
|
||||||
|
QString m_serverToJoin;
|
||||||
bool m_liveCheck = false;
|
bool m_liveCheck = false;
|
||||||
QUrl m_zipToImport;
|
QUrl m_zipToImport;
|
||||||
std::unique_ptr<QFile> logFile;
|
std::unique_ptr<QFile> logFile;
|
||||||
|
@ -191,6 +191,18 @@ void InstanceSettingsPage::applySettings()
|
|||||||
m_settings->reset("ShowGameTime");
|
m_settings->reset("ShowGameTime");
|
||||||
m_settings->reset("RecordGameTime");
|
m_settings->reset("RecordGameTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Join server on launch
|
||||||
|
bool joinServerOnLaunch = ui->serverJoinGroupBox->isChecked();
|
||||||
|
m_settings->set("JoinServerOnLaunch", joinServerOnLaunch);
|
||||||
|
if (joinServerOnLaunch)
|
||||||
|
{
|
||||||
|
m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_settings->reset("JoinServerOnLaunchAddress");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSettingsPage::loadSettings()
|
void InstanceSettingsPage::loadSettings()
|
||||||
@ -257,6 +269,9 @@ void InstanceSettingsPage::loadSettings()
|
|||||||
ui->gameTimeGroupBox->setChecked(m_settings->get("OverrideGameTime").toBool());
|
ui->gameTimeGroupBox->setChecked(m_settings->get("OverrideGameTime").toBool());
|
||||||
ui->showGameTime->setChecked(m_settings->get("ShowGameTime").toBool());
|
ui->showGameTime->setChecked(m_settings->get("ShowGameTime").toBool());
|
||||||
ui->recordGameTime->setChecked(m_settings->get("RecordGameTime").toBool());
|
ui->recordGameTime->setChecked(m_settings->get("RecordGameTime").toBool());
|
||||||
|
|
||||||
|
ui->serverJoinGroupBox->setChecked(m_settings->get("JoinServerOnLaunch").toBool());
|
||||||
|
ui->serverJoinAddress->setText(m_settings->get("JoinServerOnLaunchAddress").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSettingsPage::on_javaDetectBtn_clicked()
|
void InstanceSettingsPage::on_javaDetectBtn_clicked()
|
||||||
|
@ -453,6 +453,41 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="serverJoinGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Set a server to join on launch</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="serverJoinLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="serverJoinAddressLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Server address:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="serverJoinAddress"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacerMiscellanous">
|
<spacer name="verticalSpacerMiscellanous">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -556,7 +556,7 @@ private:
|
|||||||
QTimer m_saveTimer;
|
QTimer m_saveTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
ServersPage::ServersPage(MinecraftInstance * inst, QWidget* parent)
|
ServersPage::ServersPage(InstancePtr inst, QWidget* parent)
|
||||||
: QMainWindow(parent), ui(new Ui::ServersPage)
|
: QMainWindow(parent), ui(new Ui::ServersPage)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -579,7 +579,7 @@ ServersPage::ServersPage(MinecraftInstance * inst, QWidget* parent)
|
|||||||
|
|
||||||
auto selectionModel = ui->serversView->selectionModel();
|
auto selectionModel = ui->serversView->selectionModel();
|
||||||
connect(selectionModel, &QItemSelectionModel::currentChanged, this, &ServersPage::currentChanged);
|
connect(selectionModel, &QItemSelectionModel::currentChanged, this, &ServersPage::currentChanged);
|
||||||
connect(m_inst, &MinecraftInstance::runningStatusChanged, this, &ServersPage::on_RunningState_changed);
|
connect(m_inst.get(), &MinecraftInstance::runningStatusChanged, this, &ServersPage::on_RunningState_changed);
|
||||||
connect(ui->nameLine, &QLineEdit::textEdited, this, &ServersPage::nameEdited);
|
connect(ui->nameLine, &QLineEdit::textEdited, this, &ServersPage::nameEdited);
|
||||||
connect(ui->addressLine, &QLineEdit::textEdited, this, &ServersPage::addressEdited);
|
connect(ui->addressLine, &QLineEdit::textEdited, this, &ServersPage::addressEdited);
|
||||||
connect(ui->resourceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resourceIndexChanged(int)));
|
connect(ui->resourceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resourceIndexChanged(int)));
|
||||||
@ -695,6 +695,7 @@ void ServersPage::updateState()
|
|||||||
ui->actionMove_Down->setEnabled(serverEditEnabled);
|
ui->actionMove_Down->setEnabled(serverEditEnabled);
|
||||||
ui->actionMove_Up->setEnabled(serverEditEnabled);
|
ui->actionMove_Up->setEnabled(serverEditEnabled);
|
||||||
ui->actionRemove->setEnabled(serverEditEnabled);
|
ui->actionRemove->setEnabled(serverEditEnabled);
|
||||||
|
ui->actionJoin->setEnabled(serverEditEnabled);
|
||||||
|
|
||||||
if(server)
|
if(server)
|
||||||
{
|
{
|
||||||
@ -758,4 +759,10 @@ void ServersPage::on_actionMove_Down_triggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServersPage::on_actionJoin_triggered()
|
||||||
|
{
|
||||||
|
const auto &address = m_model->at(currentServer)->m_address;
|
||||||
|
MMC->launch(m_inst, true, nullptr, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address)));
|
||||||
|
}
|
||||||
|
|
||||||
#include "ServersPage.moc"
|
#include "ServersPage.moc"
|
||||||
|
@ -35,7 +35,7 @@ class ServersPage : public QMainWindow, public BasePage
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ServersPage(MinecraftInstance *inst, QWidget *parent = 0);
|
explicit ServersPage(InstancePtr inst, QWidget *parent = 0);
|
||||||
virtual ~ServersPage();
|
virtual ~ServersPage();
|
||||||
|
|
||||||
void openedImpl() override;
|
void openedImpl() override;
|
||||||
@ -74,6 +74,7 @@ private slots:
|
|||||||
void on_actionRemove_triggered();
|
void on_actionRemove_triggered();
|
||||||
void on_actionMove_Up_triggered();
|
void on_actionMove_Up_triggered();
|
||||||
void on_actionMove_Down_triggered();
|
void on_actionMove_Down_triggered();
|
||||||
|
void on_actionJoin_triggered();
|
||||||
|
|
||||||
void on_RunningState_changed(bool running);
|
void on_RunningState_changed(bool running);
|
||||||
|
|
||||||
@ -88,6 +89,6 @@ private: // data
|
|||||||
bool m_locked = true;
|
bool m_locked = true;
|
||||||
Ui::ServersPage *ui = nullptr;
|
Ui::ServersPage *ui = nullptr;
|
||||||
ServersModel * m_model = nullptr;
|
ServersModel * m_model = nullptr;
|
||||||
MinecraftInstance * m_inst = nullptr;
|
InstancePtr m_inst = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@
|
|||||||
<addaction name="actionRemove"/>
|
<addaction name="actionRemove"/>
|
||||||
<addaction name="actionMove_Up"/>
|
<addaction name="actionMove_Up"/>
|
||||||
<addaction name="actionMove_Down"/>
|
<addaction name="actionMove_Down"/>
|
||||||
|
<addaction name="actionJoin"/>
|
||||||
</widget>
|
</widget>
|
||||||
<action name="actionAdd">
|
<action name="actionAdd">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -169,6 +170,11 @@
|
|||||||
<string>Move Down</string>
|
<string>Move Down</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionJoin">
|
||||||
|
<property name="text">
|
||||||
|
<string>Join</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -46,7 +46,16 @@ public class LegacyFrame extends Frame implements WindowListener
|
|||||||
this.addWindowListener ( this );
|
this.addWindowListener ( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start ( Applet mcApplet, String user, String session, int winSizeW, int winSizeH, boolean maximize )
|
public void start (
|
||||||
|
Applet mcApplet,
|
||||||
|
String user,
|
||||||
|
String session,
|
||||||
|
int winSizeW,
|
||||||
|
int winSizeH,
|
||||||
|
boolean maximize,
|
||||||
|
String serverAddress,
|
||||||
|
String serverPort
|
||||||
|
)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
appletWrap = new Launcher( mcApplet, new URL ( "http://www.minecraft.net/game" ) );
|
appletWrap = new Launcher( mcApplet, new URL ( "http://www.minecraft.net/game" ) );
|
||||||
@ -95,6 +104,13 @@ public class LegacyFrame extends Frame implements WindowListener
|
|||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serverAddress != null)
|
||||||
|
{
|
||||||
|
appletWrap.setParameter("server", serverAddress);
|
||||||
|
appletWrap.setParameter("port", serverPort);
|
||||||
|
}
|
||||||
|
|
||||||
appletWrap.setParameter ( "username", user );
|
appletWrap.setParameter ( "username", user );
|
||||||
appletWrap.setParameter ( "sessionid", session );
|
appletWrap.setParameter ( "sessionid", session );
|
||||||
appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button.
|
appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button.
|
||||||
|
@ -47,6 +47,9 @@ public class OneSixLauncher implements Launcher
|
|||||||
private boolean maximize;
|
private boolean maximize;
|
||||||
private String cwd;
|
private String cwd;
|
||||||
|
|
||||||
|
private String serverAddress;
|
||||||
|
private String serverPort;
|
||||||
|
|
||||||
// the much abused system classloader, for convenience (for further abuse)
|
// the much abused system classloader, for convenience (for further abuse)
|
||||||
private ClassLoader cl;
|
private ClassLoader cl;
|
||||||
|
|
||||||
@ -64,6 +67,9 @@ public class OneSixLauncher implements Launcher
|
|||||||
windowTitle = params.firstSafe("windowTitle", "Minecraft");
|
windowTitle = params.firstSafe("windowTitle", "Minecraft");
|
||||||
windowParams = params.firstSafe("windowParams", "854x480");
|
windowParams = params.firstSafe("windowParams", "854x480");
|
||||||
|
|
||||||
|
serverAddress = params.firstSafe("serverAddress", null);
|
||||||
|
serverPort = params.firstSafe("serverPort", null);
|
||||||
|
|
||||||
cwd = System.getProperty("user.dir");
|
cwd = System.getProperty("user.dir");
|
||||||
|
|
||||||
winSizeW = 854;
|
winSizeW = 854;
|
||||||
@ -122,7 +128,7 @@ public class OneSixLauncher implements Launcher
|
|||||||
Class<?> MCAppletClass = cl.loadClass(appletClass);
|
Class<?> MCAppletClass = cl.loadClass(appletClass);
|
||||||
Applet mcappl = (Applet) MCAppletClass.newInstance();
|
Applet mcappl = (Applet) MCAppletClass.newInstance();
|
||||||
LegacyFrame mcWindow = new LegacyFrame(windowTitle);
|
LegacyFrame mcWindow = new LegacyFrame(windowTitle);
|
||||||
mcWindow.start(mcappl, userName, sessionId, winSizeW, winSizeH, maximize);
|
mcWindow.start(mcappl, userName, sessionId, winSizeW, winSizeH, maximize, serverAddress, serverPort);
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -164,6 +170,14 @@ public class OneSixLauncher implements Launcher
|
|||||||
mcparams.add(Integer.toString(winSizeH));
|
mcparams.add(Integer.toString(winSizeH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serverAddress != null)
|
||||||
|
{
|
||||||
|
mcparams.add("--server");
|
||||||
|
mcparams.add(serverAddress);
|
||||||
|
mcparams.add("--port");
|
||||||
|
mcparams.add(serverPort);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the Minecraft Class.
|
// Get the Minecraft Class.
|
||||||
Class<?> mc;
|
Class<?> mc;
|
||||||
try
|
try
|
||||||
|
Loading…
Reference in New Issue
Block a user