diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 62f6f3f34..c2f5e70cf 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -260,6 +260,8 @@ set(MINECRAFT_SOURCES minecraft/launch/ClaimAccount.h minecraft/launch/CreateGameFolders.cpp minecraft/launch/CreateGameFolders.h + minecraft/launch/EnsureAvailableMemory.cpp + minecraft/launch/EnsureAvailableMemory.h minecraft/launch/EnsureOfflineLibraries.cpp minecraft/launch/EnsureOfflineLibraries.h minecraft/launch/ModMinecraftJar.cpp diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 249ca6dae..2848f1e99 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -59,6 +59,7 @@ #include "minecraft/launch/AutoInstallJava.h" #include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/CreateGameFolders.h" +#include "minecraft/launch/EnsureAvailableMemory.h" #include "minecraft/launch/EnsureOfflineLibraries.h" #include "minecraft/launch/ExtractNatives.h" #include "minecraft/launch/LauncherPartLaunch.h" @@ -1191,6 +1192,11 @@ LaunchTask* MinecraftInstance::createLaunchTask(AuthSessionPtr session, Minecraf process->appendStep(makeShared(pptr)); } + // make sure we have enough RAM, warn the user if we don't + { + process->appendStep(makeShared(pptr, this)); + } + // print some instance info here... { process->appendStep(makeShared(pptr, session, targetToJoin)); diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.cpp b/launcher/minecraft/launch/EnsureAvailableMemory.cpp new file mode 100644 index 000000000..8a436a6f6 --- /dev/null +++ b/launcher/minecraft/launch/EnsureAvailableMemory.cpp @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2026 Octol1ttle + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "EnsureAvailableMemory.h" + +#include "HardwareInfo.h" +#include "ui/dialogs/CustomMessageBox.h" + +EnsureAvailableMemory::EnsureAvailableMemory(LaunchTask* parent, MinecraftInstance* instance) : LaunchStep(parent), m_instance(instance) {} + +void EnsureAvailableMemory::executeTask() +{ + const uint64_t available = HardwareInfo::availableRamMiB(); + const uint64_t min = m_instance->settings()->get("MinMemAlloc").toUInt(); + const uint64_t max = m_instance->settings()->get("MaxMemAlloc").toUInt(); + const uint64_t required = std::max(min, max); + + if (required > available) { + auto* dialog = CustomMessageBox::selectable( + nullptr, tr("Not enough RAM"), + tr("There is not enough RAM available to launch this instance with the current memory settings.\n\n" + "Required: %1 MiB\nAvailable: %2 MiB\n\n" + "Continue anyway? This may cause slowdowns in the game and your system.") + .arg(required) + .arg(available), + QMessageBox::Icon::Warning, QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, + QMessageBox::StandardButton::No); + const auto response = dialog->exec(); + dialog->deleteLater(); + + const auto message = tr("Not enough RAM available to launch this instance"); + if (response == QMessageBox::No) { + emit logLine(message, MessageLevel::Fatal); + emitFailed(message); + return; + } + + emit logLine(message, MessageLevel::Warning); + } + + emitSucceeded(); +} diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.h b/launcher/minecraft/launch/EnsureAvailableMemory.h new file mode 100644 index 000000000..3074a3f9a --- /dev/null +++ b/launcher/minecraft/launch/EnsureAvailableMemory.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2026 Octol1ttle + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "launch/LaunchStep.h" +#include "minecraft/MinecraftInstance.h" + +class EnsureAvailableMemory : public LaunchStep { + Q_OBJECT + + public: + explicit EnsureAvailableMemory(LaunchTask* parent, MinecraftInstance* instance); + ~EnsureAvailableMemory() override = default; + + void executeTask() override; + bool canAbort() const override { return false; } + + private: + MinecraftInstance* m_instance; +};