NOISSUE Allow joining servers from the servers page

This commit is contained in:
Janrupf 2021-05-22 18:07:08 +02:00
parent f33fe05e5f
commit ea6c42a93c
17 changed files with 132 additions and 72 deletions

View File

@ -147,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();

View File

@ -238,6 +238,7 @@ 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/MinecraftServerTarget.h
minecraft/launch/PrintInstanceInfo.cpp minecraft/launch/PrintInstanceInfo.cpp
minecraft/launch/PrintInstanceInfo.h minecraft/launch/PrintInstanceInfo.h

View File

@ -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;
} }

View File

@ -822,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()));
@ -854,66 +854,19 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
process->appendStep(new CreateGameFolders(pptr)); process->appendStep(new CreateGameFolders(pptr));
} }
MinecraftServerTargetPtr serverToJoin = std::make_shared<MinecraftServerTarget>(); if (!serverToJoin && m_settings->get("JoinServerOnLaunch").toBool())
if (m_settings->get("JoinServerOnLaunch").toBool())
{ {
QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString(); QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString();
QStringList split = fullAddress.split(":"); serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress)));
}
// The logic below replicates the exact logic minecraft uses for parsing server addresses. if(serverToJoin && serverToJoin->port == 25565)
// While the conversion is not lossless and eats errors, it ensures the same behavior {
// within Minecraft and MultiMC when entering server addresses. // Resolve server address to join on launch
if (fullAddress.startsWith("[")) auto *step = new LookupServerAddress(pptr);
{ step->setLookupAddress(serverToJoin->address);
int bracket = fullAddress.indexOf("]"); step->setOutputAddressPtr(serverToJoin);
if (bracket > 0) process->appendStep(step);
{
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;
}
}
serverToJoin->port = realPort;
serverToJoin->address = realAddress;
if(realPort == 25565)
{
// Resolve server address to join on launch
auto *step = new LookupServerAddress(pptr);
step->setLookupAddress(realAddress);
step->setOutputAddressPtr(serverToJoin);
process->appendStep(step);
}
} }
// run pre-launch command if that's needed // run pre-launch command if that's needed

View File

@ -77,7 +77,7 @@ 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, MinecraftServerTargetPtr serverToJoin) override; QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
QList<Mod> getJarMods() const; QList<Mod> getJarMods() const;

View 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 };
}

View File

@ -17,9 +17,14 @@
#include <memory> #include <memory>
#include <QString>
#include <multimc_logic_export.h>
struct MinecraftServerTarget { struct MinecraftServerTarget {
QString address; QString address;
quint16 port; quint16 port;
static MULTIMC_LOGIC_EXPORT MinecraftServerTarget parse(const QString &fullAddress);
}; };
typedef std::shared_ptr<MinecraftServerTarget> MinecraftServerTargetPtr; typedef std::shared_ptr<MinecraftServerTarget> MinecraftServerTargetPtr;

View File

@ -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;
} }

View File

@ -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()));

View File

@ -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."));

View File

@ -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;
}; };

View File

@ -1014,8 +1014,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 +1040,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);

View File

@ -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:

View File

@ -39,7 +39,7 @@
<enum>QTabWidget::Rounded</enum> <enum>QTabWidget::Rounded</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>4</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="minecraftTab"> <widget class="QWidget" name="minecraftTab">
<attribute name="title"> <attribute name="title">

View File

@ -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"

View File

@ -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;
}; };

View File

@ -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>