mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-06-12 05:07:46 +02:00
Support for CurseForge recommended memory (#3711)
This commit is contained in:
@ -54,6 +54,7 @@
|
||||
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "tasks/ConcurrentTask.h"
|
||||
#include "ui/dialogs/BlockedModsDialog.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
@ -418,6 +419,24 @@ bool FlameCreationTask::createInstance()
|
||||
}
|
||||
}
|
||||
|
||||
int recommendedRAM = m_pack.minecraft.recommendedRAM;
|
||||
|
||||
// only set memory if this is a fresh instance
|
||||
if (m_instance == nullptr && recommendedRAM > 0) {
|
||||
const uint64_t sysMiB = Sys::getSystemRam() / Sys::mebibyte;
|
||||
const uint64_t max = sysMiB * 0.9;
|
||||
|
||||
if (recommendedRAM > max) {
|
||||
logWarning(tr("The recommended memory of the modpack exceeds 90% of your system RAM—reducing it from %1 MiB to %2 MiB!")
|
||||
.arg(recommendedRAM)
|
||||
.arg(max));
|
||||
recommendedRAM = max;
|
||||
}
|
||||
|
||||
instance.settings()->set("OverrideMemory", true);
|
||||
instance.settings()->set("MaxMemAlloc", recommendedRAM);
|
||||
}
|
||||
|
||||
QString jarmodsPath = FS::PathCombine(m_stagingPath, "minecraft", "jarmods");
|
||||
QFileInfo jarmodsInfo(jarmodsPath);
|
||||
if (jarmodsInfo.isDir()) {
|
||||
|
@ -41,22 +41,8 @@
|
||||
const QString FlamePackExportTask::TEMPLATE = "<li><a href=\"{url}\">{name}{authors}</a></li>\n";
|
||||
const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "zip" });
|
||||
|
||||
FlamePackExportTask::FlamePackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& author,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFileFunction filter)
|
||||
: name(name)
|
||||
, version(version)
|
||||
, author(author)
|
||||
, optionalFiles(optionalFiles)
|
||||
, instance(instance)
|
||||
, mcInstance(dynamic_cast<MinecraftInstance*>(instance.get()))
|
||||
, gameRoot(instance->gameRoot())
|
||||
, output(output)
|
||||
, filter(filter)
|
||||
FlamePackExportTask::FlamePackExportTask(FlamePackExportOptions&& options)
|
||||
: m_options(std::move(options)), m_gameRoot(m_options.instance->gameRoot())
|
||||
{}
|
||||
|
||||
void FlamePackExportTask::executeTask()
|
||||
@ -81,7 +67,7 @@ void FlamePackExportTask::collectFiles()
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
files.clear();
|
||||
if (!MMCZip::collectFileListRecursively(instance->gameRoot(), nullptr, &files, filter)) {
|
||||
if (!MMCZip::collectFileListRecursively(m_options.instance->gameRoot(), nullptr, &files, m_options.filter)) {
|
||||
emitFailed(tr("Could not search for files"));
|
||||
return;
|
||||
}
|
||||
@ -89,11 +75,8 @@ void FlamePackExportTask::collectFiles()
|
||||
pendingHashes.clear();
|
||||
resolvedFiles.clear();
|
||||
|
||||
if (mcInstance != nullptr) {
|
||||
mcInstance->loaderModList()->update();
|
||||
connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes);
|
||||
} else
|
||||
collectHashes();
|
||||
m_options.instance->loaderModList()->update();
|
||||
connect(m_options.instance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes);
|
||||
}
|
||||
|
||||
void FlamePackExportTask::collectHashes()
|
||||
@ -101,11 +84,11 @@ void FlamePackExportTask::collectHashes()
|
||||
setAbortable(true);
|
||||
setStatus(tr("Finding file hashes..."));
|
||||
setProgress(1, 5);
|
||||
auto allMods = mcInstance->loaderModList()->allMods();
|
||||
auto allMods = m_options.instance->loaderModList()->allMods();
|
||||
ConcurrentTask::Ptr hashingTask(new ConcurrentTask("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
|
||||
task.reset(hashingTask);
|
||||
for (const QFileInfo& file : files) {
|
||||
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
|
||||
const QString relative = m_gameRoot.relativeFilePath(file.absoluteFilePath());
|
||||
// require sensible file types
|
||||
if (!std::any_of(FILE_EXTENSIONS.begin(), FILE_EXTENSIONS.end(), [&relative](const QString& extension) {
|
||||
return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled");
|
||||
@ -335,13 +318,13 @@ void FlamePackExportTask::buildZip()
|
||||
setStatus(tr("Adding files..."));
|
||||
setProgress(4, 5);
|
||||
|
||||
auto zipTask = makeShared<MMCZip::ExportToZipTask>(output, gameRoot, files, "overrides/", true, false);
|
||||
auto zipTask = makeShared<MMCZip::ExportToZipTask>(m_options.output, m_gameRoot, files, "overrides/", true, false);
|
||||
zipTask->addExtraFile("manifest.json", generateIndex());
|
||||
zipTask->addExtraFile("modlist.html", generateHTML());
|
||||
|
||||
QStringList exclude;
|
||||
std::transform(resolvedFiles.keyBegin(), resolvedFiles.keyEnd(), std::back_insert_iterator(exclude),
|
||||
[this](QString file) { return gameRoot.relativeFilePath(file); });
|
||||
[this](QString file) { return m_gameRoot.relativeFilePath(file); });
|
||||
zipTask->setExcludeFiles(exclude);
|
||||
|
||||
auto progressStep = std::make_shared<TaskStepProgress>();
|
||||
@ -376,52 +359,56 @@ QByteArray FlamePackExportTask::generateIndex()
|
||||
QJsonObject obj;
|
||||
obj["manifestType"] = "minecraftModpack";
|
||||
obj["manifestVersion"] = 1;
|
||||
obj["name"] = name;
|
||||
obj["version"] = version;
|
||||
obj["author"] = author;
|
||||
obj["name"] = m_options.name;
|
||||
obj["version"] = m_options.version;
|
||||
obj["author"] = m_options.author;
|
||||
obj["overrides"] = "overrides";
|
||||
if (mcInstance) {
|
||||
QJsonObject version;
|
||||
auto profile = mcInstance->getPackProfile();
|
||||
// collect all supported components
|
||||
const ComponentPtr minecraft = profile->getComponent("net.minecraft");
|
||||
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
||||
const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader");
|
||||
const ComponentPtr forge = profile->getComponent("net.minecraftforge");
|
||||
const ComponentPtr neoforge = profile->getComponent("net.neoforged");
|
||||
|
||||
// convert all available components to mrpack dependencies
|
||||
if (minecraft != nullptr)
|
||||
version["version"] = minecraft->m_version;
|
||||
QString id;
|
||||
if (quilt != nullptr)
|
||||
id = "quilt-" + quilt->m_version;
|
||||
else if (fabric != nullptr)
|
||||
id = "fabric-" + fabric->m_version;
|
||||
else if (forge != nullptr)
|
||||
id = "forge-" + forge->m_version;
|
||||
else if (neoforge != nullptr) {
|
||||
id = "neoforge-";
|
||||
if (minecraft->m_version == "1.20.1")
|
||||
id += "1.20.1-";
|
||||
id += neoforge->m_version;
|
||||
}
|
||||
version["modLoaders"] = QJsonArray();
|
||||
if (!id.isEmpty()) {
|
||||
QJsonObject loader;
|
||||
loader["id"] = id;
|
||||
loader["primary"] = true;
|
||||
version["modLoaders"] = QJsonArray({ loader });
|
||||
}
|
||||
obj["minecraft"] = version;
|
||||
QJsonObject version;
|
||||
|
||||
auto profile = m_options.instance->getPackProfile();
|
||||
// collect all supported components
|
||||
const ComponentPtr minecraft = profile->getComponent("net.minecraft");
|
||||
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
||||
const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader");
|
||||
const ComponentPtr forge = profile->getComponent("net.minecraftforge");
|
||||
const ComponentPtr neoforge = profile->getComponent("net.neoforged");
|
||||
|
||||
// convert all available components to mrpack dependencies
|
||||
if (minecraft != nullptr)
|
||||
version["version"] = minecraft->m_version;
|
||||
QString id;
|
||||
if (quilt != nullptr)
|
||||
id = "quilt-" + quilt->m_version;
|
||||
else if (fabric != nullptr)
|
||||
id = "fabric-" + fabric->m_version;
|
||||
else if (forge != nullptr)
|
||||
id = "forge-" + forge->m_version;
|
||||
else if (neoforge != nullptr) {
|
||||
id = "neoforge-";
|
||||
if (minecraft->m_version == "1.20.1")
|
||||
id += "1.20.1-";
|
||||
id += neoforge->m_version;
|
||||
}
|
||||
version["modLoaders"] = QJsonArray();
|
||||
if (!id.isEmpty()) {
|
||||
QJsonObject loader;
|
||||
loader["id"] = id;
|
||||
loader["primary"] = true;
|
||||
version["modLoaders"] = QJsonArray({ loader });
|
||||
}
|
||||
|
||||
if (m_options.recommendedRAM > 0)
|
||||
version["recommendedRam"] = m_options.recommendedRAM;
|
||||
|
||||
obj["minecraft"] = version;
|
||||
|
||||
QJsonArray files;
|
||||
for (auto mod : resolvedFiles) {
|
||||
QJsonObject file;
|
||||
file["projectID"] = mod.addonId;
|
||||
file["fileID"] = mod.version;
|
||||
file["required"] = mod.enabled || !optionalFiles;
|
||||
file["required"] = mod.enabled || !m_options.optionalFiles;
|
||||
files << file;
|
||||
}
|
||||
obj["files"] = files;
|
||||
|
@ -19,22 +19,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseInstance.h"
|
||||
#include "MMCZip.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "modplatform/flame/FlameAPI.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
struct FlamePackExportOptions {
|
||||
QString name;
|
||||
QString version;
|
||||
QString author;
|
||||
bool optionalFiles;
|
||||
MinecraftInstancePtr instance;
|
||||
QString output;
|
||||
MMCZip::FilterFileFunction filter;
|
||||
int recommendedRAM;
|
||||
};
|
||||
|
||||
class FlamePackExportTask : public Task {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FlamePackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& author,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFileFunction filter);
|
||||
FlamePackExportTask(FlamePackExportOptions&& options);
|
||||
|
||||
protected:
|
||||
void executeTask() override;
|
||||
@ -45,13 +49,6 @@ class FlamePackExportTask : public Task {
|
||||
static const QStringList FILE_EXTENSIONS;
|
||||
|
||||
// inputs
|
||||
const QString name, version, author;
|
||||
const bool optionalFiles;
|
||||
const InstancePtr instance;
|
||||
MinecraftInstance* mcInstance;
|
||||
const QDir gameRoot;
|
||||
const QString output;
|
||||
const MMCZip::FilterFileFunction filter;
|
||||
|
||||
struct ResolvedFile {
|
||||
int addonId;
|
||||
@ -70,6 +67,9 @@ class FlamePackExportTask : public Task {
|
||||
bool isMod;
|
||||
};
|
||||
|
||||
FlamePackExportOptions m_options;
|
||||
QDir m_gameRoot;
|
||||
|
||||
FlameAPI api;
|
||||
|
||||
QFileInfoList files;
|
||||
|
@ -27,6 +27,7 @@ static void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft)
|
||||
loadModloaderV1(loader, obj);
|
||||
m.modLoaders.append(loader);
|
||||
}
|
||||
m.recommendedRAM = Json::ensureInteger(minecraft, "recommendedRam", 0);
|
||||
}
|
||||
|
||||
static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest)
|
||||
|
@ -67,6 +67,7 @@ struct Minecraft {
|
||||
QString version;
|
||||
QString libraries;
|
||||
QList<Flame::Modloader> modLoaders;
|
||||
int recommendedRAM;
|
||||
};
|
||||
|
||||
struct Manifest {
|
||||
|
Reference in New Issue
Block a user