Skip to content

Commit

Permalink
Support for launching from command line in offline mode
Browse files Browse the repository at this point in the history
This allows launching an offline instance with --offline --name=OfflineName. This is useful for playing split screen by creating two side-by-side instances, which is impossible online, unless one is using two separate paid accounts.

With this PR, it makes it possible to launch from a script - otherwise, one has to launch manually, which is a pain, or create offline profiles for each instance, which interferes with some functionality like skins (my autistic son takes great issue with his skin not being visible, when using offline profiles!).

Implementation is based on MultiMC, which supports this feature.

See also #1059 for discussion.

Signed-off-by: Michael Tyson <michael@atastypixel.com>
  • Loading branch information
michaeltyson committed Apr 23, 2024
1 parent 5eeb3b7 commit 835cc29
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 15 deletions.
24 changes: 19 additions & 5 deletions launcher/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
{ { "l", "launch" }, "Launch the specified instance (by instance ID)", "instance" },
{ { "s", "server" }, "Join the specified server on launch (only valid in combination with --launch)", "address" },
{ { "a", "profile" }, "Use the account specified by its profile name (only valid in combination with --launch)", "profile" },
{ { "o", "offline" }, "Launch offline (only valid in combination with --launch)", "offline" },
{ { "n", "name" }, "When launching offline, use specified name (only makes sense in combination with --launch and --offline)", "name" },
{ "alive", "Write a small '" + liveCheckFile + "' file after the launcher starts" },
{ { "I", "import" }, "Import instance or resource from specified local path or URL", "url" },
{ "show", "Opens the window for the specified instance (by instance ID)", "show" } });
Expand All @@ -250,6 +252,10 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_instanceIdToLaunch = parser.value("launch");
m_serverToJoin = parser.value("server");
m_profileToUse = parser.value("profile");
if (parser.isSet("offline")) {
m_offline = true;
m_offlineName = parser.value("name");
}
m_liveCheck = parser.isSet("alive");

m_instanceIdToShowWindowOf = parser.value("show");
Expand All @@ -264,8 +270,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
}

// error if --launch is missing with --server or --profile
if ((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) {
std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl;
if ((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty() || m_offline || !m_offlineName.isEmpty()) && m_instanceIdToLaunch.isEmpty()) {
std::cerr << "--server, --profile, --offline and --name can only be used in combination with --launch!" << std::endl;
m_status = Application::Failed;
return;
}
Expand Down Expand Up @@ -383,6 +389,10 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
if (!m_profileToUse.isEmpty()) {
launch.args["profile"] = m_profileToUse;
}
if (m_offline) {
launch.args["offline_enabled"] = "true";
launch.args["offline_name"] = m_offlineName;
}
m_peerInstance->sendMessage(launch.serialize(), timeout);
}
m_status = Application::Succeeded;
Expand Down Expand Up @@ -1178,7 +1188,7 @@ void Application::performMainStartupAction()
qDebug() << " Launching with account" << m_profileToUse;
}

launch(inst, true, false, serverToJoin, accountToUse);
launch(inst, !m_offline, false, serverToJoin, accountToUse, m_offlineName);
return;
}
}
Expand Down Expand Up @@ -1263,6 +1273,8 @@ void Application::messageReceived(const QByteArray& message)
QString id = received.args["id"];
QString server = received.args["server"];
QString profile = received.args["profile"];
bool offline = received.args["offline_enabled"] == "true";
QString offlineName = received.args["offline_name"];

InstancePtr instance;
if (!id.isEmpty()) {
Expand Down Expand Up @@ -1291,7 +1303,7 @@ void Application::messageReceived(const QByteArray& message)
}
}

launch(instance, true, false, serverObject, accountObject);
launch(instance, !offline, false, serverObject, accountObject, offlineName);
} else {
qWarning() << "Received invalid message" << message;
}
Expand Down Expand Up @@ -1333,7 +1345,8 @@ bool Application::launch(InstancePtr instance,
bool online,
bool demo,
MinecraftServerTargetPtr serverToJoin,
MinecraftAccountPtr accountToUse)
MinecraftAccountPtr accountToUse,
const QString& offlineName)
{
if (m_updateRunning) {
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
Expand All @@ -1353,6 +1366,7 @@ bool Application::launch(InstancePtr instance,
controller->setProfiler(profilers().value(instance->settings()->get("Profiler").toString(), nullptr).get());
controller->setServerToJoin(serverToJoin);
controller->setAccountToUse(accountToUse);
controller->setOfflineName(offlineName);
if (window) {
controller->setParentWidget(window);
} else if (m_mainWindow) {
Expand Down
5 changes: 4 additions & 1 deletion launcher/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ class Application : public QApplication {
bool online = true,
bool demo = false,
MinecraftServerTargetPtr serverToJoin = nullptr,
MinecraftAccountPtr accountToUse = nullptr);
MinecraftAccountPtr accountToUse = nullptr,
const QString &offlineName = QString());
bool kill(InstancePtr instance);
void closeCurrentWindow();

Expand Down Expand Up @@ -290,6 +291,8 @@ class Application : public QApplication {
QString m_instanceIdToLaunch;
QString m_serverToJoin;
QString m_profileToUse;
bool m_offline = false;
QString m_offlineName;
bool m_liveCheck = false;
QList<QUrl> m_urlsToImport;
QString m_instanceIdToShowWindowOf;
Expand Down
24 changes: 15 additions & 9 deletions launcher/LaunchController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,22 @@ void LaunchController::login()
message = tr("Choose your demo mode player name.");
}

QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString();
QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName;
QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), message, QLineEdit::Normal, usedname, &ok);
if (!ok) {
tryagain = false;
break;
QString usedname;
if(m_offlineName.isEmpty()) {
QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString();
QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName;

Check notice

Code scanning / CodeQL

Declaration hides variable Note

Variable usedname hides another variable of the same name (on
line 190
).
QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), message, QLineEdit::Normal, usedname, &ok);
if (!ok) {
tryagain = false;
break;
}
if (name.length()) {
usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname);
}
}
if (name.length()) {
usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname);
else {
usedname = m_offlineName;
}
m_session->MakeOffline(usedname);
// offline flavored game from here :3
Expand Down
3 changes: 3 additions & 0 deletions launcher/LaunchController.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class LaunchController : public Task {

void setOnline(bool online) { m_online = online; }

void setOfflineName(const QString &offlineName) { m_offlineName = offlineName; }

void setDemo(bool demo) { m_demo = demo; }

void setProfiler(BaseProfilerFactory* profiler) { m_profiler = profiler; }
Expand Down Expand Up @@ -85,6 +87,7 @@ class LaunchController : public Task {
private:
BaseProfilerFactory* m_profiler = nullptr;
bool m_online = true;
QString m_offlineName;
bool m_demo = false;
InstancePtr m_instance;
QWidget* m_parentWidget = nullptr;
Expand Down

0 comments on commit 835cc29

Please sign in to comment.