mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 18:09:59 +03:00
Compare commits
23 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a9e8573aa | ||
|
|
399482270f | ||
|
|
50df409b28 | ||
|
|
add3d01f84 | ||
|
|
a71b8d8fe3 | ||
|
|
6d38b34c00 | ||
|
|
85f19da603 | ||
|
|
239be1ec43 | ||
|
|
34349a6810 | ||
|
|
fb7e4da4e6 | ||
|
|
f766cdd847 | ||
|
|
789c656463 | ||
|
|
2d01dfa4f2 | ||
|
|
9231fe8592 | ||
|
|
25fee30f95 | ||
|
|
ec6a173608 | ||
|
|
b7d70dc1c1 | ||
|
|
09f0467e81 | ||
|
|
fe02ad8524 | ||
|
|
f66796e806 | ||
|
|
4cd8c343fe | ||
|
|
960e1bac87 | ||
|
|
838e7fb8d2 |
16 changed files with 330 additions and 280 deletions
2
.github/workflows/nix.yml
vendored
2
.github/workflows/nix.yml
vendored
|
|
@ -88,7 +88,7 @@ jobs:
|
||||||
- os: ubuntu-22.04-arm
|
- os: ubuntu-22.04-arm
|
||||||
system: aarch64-linux
|
system: aarch64-linux
|
||||||
|
|
||||||
- os: macos-14
|
- os: macos-26
|
||||||
system: aarch64-darwin
|
system: aarch64-darwin
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ set(Launcher_LEGACY_FMLLIBS_BASE_URL "https://files.prismlauncher.org/fmllibs/"
|
||||||
######## Set version numbers ########
|
######## Set version numbers ########
|
||||||
set(Launcher_VERSION_MAJOR 11)
|
set(Launcher_VERSION_MAJOR 11)
|
||||||
set(Launcher_VERSION_MINOR 0)
|
set(Launcher_VERSION_MINOR 0)
|
||||||
set(Launcher_VERSION_PATCH 0)
|
set(Launcher_VERSION_PATCH 2)
|
||||||
|
|
||||||
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}")
|
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}")
|
||||||
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}.0")
|
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}.0")
|
||||||
|
|
|
||||||
|
|
@ -735,6 +735,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||||
m_settings->registerSetting({ "MinMemAlloc", "MinMemoryAlloc" }, 512);
|
m_settings->registerSetting({ "MinMemAlloc", "MinMemoryAlloc" }, 512);
|
||||||
m_settings->registerSetting({ "MaxMemAlloc", "MaxMemoryAlloc" }, SysInfo::defaultMaxJvmMem());
|
m_settings->registerSetting({ "MaxMemAlloc", "MaxMemoryAlloc" }, SysInfo::defaultMaxJvmMem());
|
||||||
m_settings->registerSetting("PermGen", 128);
|
m_settings->registerSetting("PermGen", 128);
|
||||||
|
m_settings->registerSetting("LowMemWarning", true);
|
||||||
|
|
||||||
// Java Settings
|
// Java Settings
|
||||||
m_settings->registerSetting("JavaPath", "");
|
m_settings->registerSetting("JavaPath", "");
|
||||||
|
|
|
||||||
|
|
@ -924,23 +924,23 @@ class InstanceStaging : public Task {
|
||||||
connect(child, &Task::progress, this, &InstanceStaging::setProgress);
|
connect(child, &Task::progress, this, &InstanceStaging::setProgress);
|
||||||
connect(child, &Task::stepProgress, this, &InstanceStaging::propagateStepProgress);
|
connect(child, &Task::stepProgress, this, &InstanceStaging::propagateStepProgress);
|
||||||
connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceeded);
|
connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceeded);
|
||||||
m_backoffTimer.setSingleShot(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~InstanceStaging() {}
|
~InstanceStaging() override = default;
|
||||||
|
|
||||||
// FIXME/TODO: add ability to abort during instance commit retries
|
// FIXME/TODO: add ability to abort during instance commit retries
|
||||||
bool abort() override
|
bool abort() override
|
||||||
{
|
{
|
||||||
if (!canAbort())
|
if (!canAbort()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return m_child->abort();
|
return m_child->abort();
|
||||||
}
|
}
|
||||||
bool canAbort() const override { return (m_child && m_child->canAbort()); }
|
bool canAbort() const override { return (m_child && m_child->canAbort()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void executeTask() override
|
void executeTask() override
|
||||||
{
|
{
|
||||||
if (m_stagingPath.isNull()) {
|
if (m_stagingPath.isNull()) {
|
||||||
emitFailed(tr("Could not create staging folder"));
|
emitFailed(tr("Could not create staging folder"));
|
||||||
|
|
@ -954,10 +954,8 @@ class InstanceStaging : public Task {
|
||||||
private slots:
|
private slots:
|
||||||
void childSucceeded()
|
void childSucceeded()
|
||||||
{
|
{
|
||||||
if (!isRunning())
|
|
||||||
return;
|
|
||||||
unsigned sleepTime = backoff();
|
unsigned sleepTime = backoff();
|
||||||
if (m_parent->commitStagedInstance(m_stagingPath, *m_child.get(), m_child->group(), *m_child.get())) {
|
if (m_parent->commitStagedInstance(m_stagingPath, *m_child, m_child->group(), *m_child)) {
|
||||||
m_backoffTimer.stop();
|
m_backoffTimer.stop();
|
||||||
emitSucceeded();
|
emitSucceeded();
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,8 @@ void LaunchProfile::getLibraryFiles(const RuntimeContext& runtimeContext,
|
||||||
QStringList& jars,
|
QStringList& jars,
|
||||||
QStringList& nativeJars,
|
QStringList& nativeJars,
|
||||||
const QString& overridePath,
|
const QString& overridePath,
|
||||||
const QString& tempPath) const
|
const QString& tempPath,
|
||||||
|
bool addJarMods) const
|
||||||
{
|
{
|
||||||
QStringList native32, native64;
|
QStringList native32, native64;
|
||||||
jars.clear();
|
jars.clear();
|
||||||
|
|
@ -360,7 +361,7 @@ void LaunchProfile::getLibraryFiles(const RuntimeContext& runtimeContext,
|
||||||
// NOTE: order is important here, add main jar last to the lists
|
// NOTE: order is important here, add main jar last to the lists
|
||||||
if (m_mainJar) {
|
if (m_mainJar) {
|
||||||
// FIXME: HACK!! jar modding is weird and unsystematic!
|
// FIXME: HACK!! jar modding is weird and unsystematic!
|
||||||
if (m_jarMods.size()) {
|
if (m_jarMods.size() && addJarMods) {
|
||||||
QDir tempDir(tempPath);
|
QDir tempDir(tempPath);
|
||||||
jars.append(tempDir.absoluteFilePath("minecraft.jar"));
|
jars.append(tempDir.absoluteFilePath("minecraft.jar"));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,8 @@ class LaunchProfile : public ProblemProvider {
|
||||||
QStringList& jars,
|
QStringList& jars,
|
||||||
QStringList& nativeJars,
|
QStringList& nativeJars,
|
||||||
const QString& overridePath,
|
const QString& overridePath,
|
||||||
const QString& tempPath) const;
|
const QString& tempPath,
|
||||||
|
bool addJarMods = true) const;
|
||||||
bool hasTrait(const QString& trait) const;
|
bool hasTrait(const QString& trait) const;
|
||||||
ProblemSeverity getProblemSeverity() const override;
|
ProblemSeverity getProblemSeverity() const override;
|
||||||
const QList<PatchProblem> getProblems() const override;
|
const QList<PatchProblem> getProblems() const override;
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,7 @@ void MinecraftInstance::loadSpecificSettings()
|
||||||
m_settings->registerOverride(global_settings->getSetting("MinMemAlloc"), memorySetting);
|
m_settings->registerOverride(global_settings->getSetting("MinMemAlloc"), memorySetting);
|
||||||
m_settings->registerOverride(global_settings->getSetting("MaxMemAlloc"), memorySetting);
|
m_settings->registerOverride(global_settings->getSetting("MaxMemAlloc"), memorySetting);
|
||||||
m_settings->registerOverride(global_settings->getSetting("PermGen"), memorySetting);
|
m_settings->registerOverride(global_settings->getSetting("PermGen"), memorySetting);
|
||||||
|
m_settings->registerOverride(global_settings->getSetting("LowMemWarning"), memorySetting);
|
||||||
|
|
||||||
// Native library workarounds
|
// Native library workarounds
|
||||||
auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false);
|
auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false);
|
||||||
|
|
|
||||||
|
|
@ -30,21 +30,26 @@ void EnsureAvailableMemory::executeTask()
|
||||||
const uint64_t max = m_instance->settings()->get("MaxMemAlloc").toUInt();
|
const uint64_t max = m_instance->settings()->get("MaxMemAlloc").toUInt();
|
||||||
const uint64_t required = std::max(min, max);
|
const uint64_t required = std::max(min, max);
|
||||||
|
|
||||||
if (required > available) {
|
if (static_cast<double>(required) * 0.9 > static_cast<double>(available)) {
|
||||||
auto* dialog = CustomMessageBox::selectable(
|
bool shouldAbort = false;
|
||||||
nullptr, tr("Not enough RAM"),
|
|
||||||
tr("There is not enough RAM available to launch this instance with the current memory settings.\n\n"
|
if (m_instance->settings()->get("LowMemWarning").toBool()) {
|
||||||
"Required: %1 MiB\nAvailable: %2 MiB\n\n"
|
auto* dialog = CustomMessageBox::selectable(
|
||||||
"Continue anyway? This may cause slowdowns in the game and your system.")
|
nullptr, tr("Not enough RAM"),
|
||||||
.arg(required)
|
tr("There is not enough RAM available to launch this instance with the current memory settings.\n\n"
|
||||||
.arg(available),
|
"Required: %1 MiB\nAvailable: %2 MiB\n\n"
|
||||||
QMessageBox::Icon::Warning, QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
|
"Continue anyway? This may cause slowdowns in the game and your system.")
|
||||||
QMessageBox::StandardButton::No);
|
.arg(required)
|
||||||
const auto response = dialog->exec();
|
.arg(available),
|
||||||
dialog->deleteLater();
|
QMessageBox::Icon::Warning, QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
|
||||||
|
QMessageBox::StandardButton::No);
|
||||||
|
|
||||||
|
shouldAbort = dialog->exec() == QMessageBox::No;
|
||||||
|
dialog->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
const auto message = tr("Not enough RAM available to launch this instance");
|
const auto message = tr("Not enough RAM available to launch this instance");
|
||||||
if (response == QMessageBox::No) {
|
if (shouldAbort) {
|
||||||
emit logLine(message, MessageLevel::Fatal);
|
emit logLine(message, MessageLevel::Fatal);
|
||||||
emitFailed(message);
|
emitFailed(message);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,27 @@ void EnsureOfflineLibraries::executeTask()
|
||||||
{
|
{
|
||||||
const auto profile = m_instance->getPackProfile()->getProfile();
|
const auto profile = m_instance->getPackProfile()->getProfile();
|
||||||
QStringList allJars;
|
QStringList allJars;
|
||||||
profile->getLibraryFiles(m_instance->runtimeContext(), allJars, allJars, m_instance->getLocalLibraryPath(), m_instance->binRoot());
|
profile->getLibraryFiles(m_instance->runtimeContext(), allJars, allJars, m_instance->getLocalLibraryPath(), m_instance->binRoot(),
|
||||||
|
false);
|
||||||
|
|
||||||
|
QStringList missing;
|
||||||
for (const auto& jar : allJars) {
|
for (const auto& jar : allJars) {
|
||||||
if (!QFileInfo::exists(jar)) {
|
if (!QFileInfo::exists(jar)) {
|
||||||
emit logLine(tr("This instance cannot be launched because some libraries are missing or have not been downloaded yet. Please "
|
missing.append(jar);
|
||||||
"try again in online mode with a working Internet connection"),
|
|
||||||
MessageLevel::Fatal);
|
|
||||||
emitFailed("Required libraries are missing");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitSucceeded();
|
if (missing.isEmpty()) {
|
||||||
|
emitSucceeded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit logLine("Missing libraries:", MessageLevel::Error);
|
||||||
|
for (const auto& jar : missing) {
|
||||||
|
emit logLine(" " + jar, MessageLevel::Error);
|
||||||
|
}
|
||||||
|
emit logLine(tr("\nThis instance cannot be launched because some libraries are missing or have not been downloaded yet. Please "
|
||||||
|
"try again in online mode with a working Internet connection"),
|
||||||
|
MessageLevel::Fatal);
|
||||||
|
emitFailed("Required libraries are missing");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ void PrintInstanceInfo::executeTask()
|
||||||
auto instance = m_parent->instance();
|
auto instance = m_parent->instance();
|
||||||
QStringList log;
|
QStringList log;
|
||||||
|
|
||||||
|
log << "";
|
||||||
log << "OS: " + QString("%1 | %2 | %3").arg(QSysInfo::prettyProductName(), QSysInfo::kernelType(), QSysInfo::kernelVersion());
|
log << "OS: " + QString("%1 | %2 | %3").arg(QSysInfo::prettyProductName(), QSysInfo::kernelType(), QSysInfo::kernelVersion());
|
||||||
#ifdef Q_OS_FREEBSD
|
#ifdef Q_OS_FREEBSD
|
||||||
::runSysctlHwModel(log);
|
::runSysctlHwModel(log);
|
||||||
|
|
|
||||||
|
|
@ -202,23 +202,24 @@ bool ManagedPackPage::runUpdateTask(InstanceTask* task)
|
||||||
|
|
||||||
unique_qobject_ptr<Task> wrapped_task(APPLICATION->instances()->wrapInstanceTask(task));
|
unique_qobject_ptr<Task> wrapped_task(APPLICATION->instances()->wrapInstanceTask(task));
|
||||||
|
|
||||||
connect(task, &Task::failed,
|
connect(wrapped_task.get(), &Task::failed,
|
||||||
[this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
|
[this](const QString& reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
|
||||||
connect(task, &Task::succeeded, [this, task]() {
|
connect(wrapped_task.get(), &Task::succeeded, [this, task]() {
|
||||||
QStringList warnings = task->warnings();
|
QStringList warnings = task->warnings();
|
||||||
if (warnings.count())
|
if (warnings.count()) {
|
||||||
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
connect(task, &Task::aborted, [this] {
|
connect(wrapped_task.get(), &Task::aborted, [this] {
|
||||||
CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information)
|
CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information)
|
||||||
->show();
|
->show();
|
||||||
});
|
});
|
||||||
|
|
||||||
ProgressDialog loadDialog(this);
|
ProgressDialog loadDialog(this);
|
||||||
loadDialog.setSkipButton(true, tr("Abort"));
|
loadDialog.setSkipButton(true, tr("Abort"));
|
||||||
loadDialog.execWithTask(task);
|
loadDialog.execWithTask(wrapped_task.get());
|
||||||
|
|
||||||
return task->wasSuccessful();
|
return wrapped_task->wasSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedPackPage::suggestVersion()
|
void ManagedPackPage::suggestVersion()
|
||||||
|
|
@ -260,14 +261,16 @@ void ModrinthManagedPackPage::parseManagedPack()
|
||||||
qDebug() << "Parsing Modrinth pack";
|
qDebug() << "Parsing Modrinth pack";
|
||||||
|
|
||||||
// No need for the extra work because we already have everything we need.
|
// No need for the extra work because we already have everything we need.
|
||||||
if (m_loaded)
|
if (m_loaded) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_fetch_job && m_fetch_job->isRunning())
|
if (m_fetch_job && m_fetch_job->isRunning()) {
|
||||||
m_fetch_job->abort();
|
m_fetch_job->abort();
|
||||||
|
}
|
||||||
|
|
||||||
ResourceAPI::Callback<QVector<ModPlatform::IndexedVersion>> callbacks{};
|
ResourceAPI::Callback<QVector<ModPlatform::IndexedVersion>> callbacks{};
|
||||||
m_pack = { m_inst->getManagedPackID() };
|
m_pack = { .addonId = m_inst->getManagedPackID() };
|
||||||
|
|
||||||
// Use default if no callbacks are set
|
// Use default if no callbacks are set
|
||||||
callbacks.on_succeed = [this](auto& doc) {
|
callbacks.on_succeed = [this](auto& doc) {
|
||||||
|
|
@ -284,8 +287,9 @@ void ModrinthManagedPackPage::parseManagedPack()
|
||||||
|
|
||||||
// NOTE: the id from version isn't the same id in the modpack format spec...
|
// NOTE: the id from version isn't the same id in the modpack format spec...
|
||||||
// e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index..............
|
// e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index..............
|
||||||
if (version.version == m_inst->getManagedPackVersionName())
|
if (version.version == m_inst->getManagedPackVersionName()) {
|
||||||
name = tr("%1 (Current)").arg(name);
|
name = tr("%1 (Current)").arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
ui->versionsComboBox->addItem(name, version.fileId);
|
ui->versionsComboBox->addItem(name, version.fileId);
|
||||||
}
|
}
|
||||||
|
|
@ -294,10 +298,14 @@ void ModrinthManagedPackPage::parseManagedPack()
|
||||||
|
|
||||||
m_loaded = true;
|
m_loaded = true;
|
||||||
};
|
};
|
||||||
callbacks.on_fail = [this](QString reason, int) { setFailState(); };
|
callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); };
|
||||||
callbacks.on_abort = [this]() { setFailState(); };
|
callbacks.on_abort = [this]() { setFailState(); };
|
||||||
m_fetch_job = m_api.getProjectVersions(
|
m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
|
||||||
{ std::make_shared<ModPlatform::IndexedPack>(m_pack), {}, {}, ModPlatform::ResourceType::Modpack }, std::move(callbacks));
|
.mcVersions = {},
|
||||||
|
.loaders = {},
|
||||||
|
.resourceType = ModPlatform::ResourceType::Modpack,
|
||||||
|
.includeChangelog = true },
|
||||||
|
std::move(callbacks));
|
||||||
|
|
||||||
ui->changelogTextBrowser->setText(tr("Fetching changelogs..."));
|
ui->changelogTextBrowser->setText(tr("Fetching changelogs..."));
|
||||||
|
|
||||||
|
|
@ -406,14 +414,16 @@ void FlameManagedPackPage::parseManagedPack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need for the extra work because we already have everything we need.
|
// No need for the extra work because we already have everything we need.
|
||||||
if (m_loaded)
|
if (m_loaded) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_fetch_job && m_fetch_job->isRunning())
|
if (m_fetch_job && m_fetch_job->isRunning()) {
|
||||||
m_fetch_job->abort();
|
m_fetch_job->abort();
|
||||||
|
}
|
||||||
|
|
||||||
QString id = m_inst->getManagedPackID();
|
QString id = m_inst->getManagedPackID();
|
||||||
m_pack = { id };
|
m_pack = { .addonId = id };
|
||||||
|
|
||||||
ResourceAPI::Callback<QVector<ModPlatform::IndexedVersion>> callbacks{};
|
ResourceAPI::Callback<QVector<ModPlatform::IndexedVersion>> callbacks{};
|
||||||
|
|
||||||
|
|
@ -430,8 +440,9 @@ void FlameManagedPackPage::parseManagedPack()
|
||||||
for (const auto& version : m_pack.versions) {
|
for (const auto& version : m_pack.versions) {
|
||||||
QString name = version.getVersionDisplayString();
|
QString name = version.getVersionDisplayString();
|
||||||
|
|
||||||
if (version.fileId == m_inst->getManagedPackVersionID().toInt())
|
if (version.fileId == m_inst->getManagedPackVersionID().toInt()) {
|
||||||
name = tr("%1 (Current)").arg(name);
|
name = tr("%1 (Current)").arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
ui->versionsComboBox->addItem(name, QVariant(version.fileId));
|
ui->versionsComboBox->addItem(name, QVariant(version.fileId));
|
||||||
}
|
}
|
||||||
|
|
@ -440,10 +451,14 @@ void FlameManagedPackPage::parseManagedPack()
|
||||||
|
|
||||||
m_loaded = true;
|
m_loaded = true;
|
||||||
};
|
};
|
||||||
callbacks.on_fail = [this](QString reason, int) { setFailState(); };
|
callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); };
|
||||||
callbacks.on_abort = [this]() { setFailState(); };
|
callbacks.on_abort = [this]() { setFailState(); };
|
||||||
m_fetch_job = m_api.getProjectVersions(
|
m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
|
||||||
{ std::make_shared<ModPlatform::IndexedPack>(m_pack), {}, {}, ModPlatform::ResourceType::Modpack }, std::move(callbacks));
|
.mcVersions = {},
|
||||||
|
.loaders = {},
|
||||||
|
.resourceType = ModPlatform::ResourceType::Modpack,
|
||||||
|
.includeChangelog = true },
|
||||||
|
std::move(callbacks));
|
||||||
|
|
||||||
m_fetch_job->start();
|
m_fetch_job->start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
|
#include "McClient.h"
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <Exception.h>
|
#include "Exception.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "McClient.h"
|
|
||||||
|
|
||||||
// 7 first bits
|
McClient::McClient(QObject* parent, QString domain, QString ip, const uint16_t port)
|
||||||
#define SEGMENT_BITS 0x7F
|
: QObject(parent), m_domain(std::move(domain)), m_ip(std::move(ip)), m_port(port)
|
||||||
// last bit
|
{}
|
||||||
#define CONTINUE_BIT 0x80
|
|
||||||
|
|
||||||
McClient::McClient(QObject* parent, QString domain, QString ip, short port) : QObject(parent), m_domain(domain), m_ip(ip), m_port(port) {}
|
|
||||||
|
|
||||||
void McClient::getStatusData()
|
void McClient::getStatusData()
|
||||||
{
|
{
|
||||||
|
|
@ -33,13 +32,12 @@ void McClient::getStatusData()
|
||||||
void McClient::sendRequest()
|
void McClient::sendRequest()
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
writeVarInt(data, 0x00); // packet ID
|
writeVarInt(data, 0x00); // packet ID
|
||||||
writeVarInt(data, 763); // hardcoded protocol version (763 = 1.20.1)
|
writeVarInt(data, 763); // hardcoded protocol version (763 = 1.20.1)
|
||||||
writeVarInt(data, m_domain.size()); // server address length
|
writeString(data, m_domain); // server address
|
||||||
writeString(data, m_domain.toStdString()); // server address
|
writeUInt16(data, m_port); // server port
|
||||||
writeFixedInt(data, m_port, 2); // server port
|
writeVarInt(data, 0x01); // next state
|
||||||
writeVarInt(data, 0x01); // next state
|
writePacketToSocket(data); // send handshake packet
|
||||||
writePacketToSocket(data); // send handshake packet
|
|
||||||
|
|
||||||
writeVarInt(data, 0x00); // packet ID
|
writeVarInt(data, 0x00); // packet ID
|
||||||
writePacketToSocket(data); // send status packet
|
writePacketToSocket(data); // send status packet
|
||||||
|
|
@ -47,17 +45,17 @@ void McClient::sendRequest()
|
||||||
|
|
||||||
void McClient::readRawResponse()
|
void McClient::readRawResponse()
|
||||||
{
|
{
|
||||||
if (m_responseReadState == 2) {
|
if (m_responseReadState == ResponseReadState::Finished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_resp.append(m_socket.readAll());
|
m_resp.append(m_socket.readAll());
|
||||||
if (m_responseReadState == 0 && m_resp.size() >= 5) {
|
if (m_responseReadState == ResponseReadState::Waiting && m_resp.size() >= 5) {
|
||||||
m_wantedRespLength = readVarInt(m_resp);
|
m_wantedRespLength = readVarInt(m_resp);
|
||||||
m_responseReadState = 1;
|
m_responseReadState = ResponseReadState::GotLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_responseReadState == 1 && m_resp.size() >= m_wantedRespLength) {
|
if (m_responseReadState == ResponseReadState::GotLength && m_resp.size() >= m_wantedRespLength) {
|
||||||
if (m_resp.size() > m_wantedRespLength) {
|
if (m_resp.size() > m_wantedRespLength) {
|
||||||
qDebug().nospace() << "Warning: Packet length doesn't match actual packet size (" << m_wantedRespLength << " expected vs "
|
qDebug().nospace() << "Warning: Packet length doesn't match actual packet size (" << m_wantedRespLength << " expected vs "
|
||||||
<< m_resp.size() << " received)";
|
<< m_resp.size() << " received)";
|
||||||
|
|
@ -67,7 +65,7 @@ void McClient::readRawResponse()
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
emitFail(e.cause());
|
emitFail(e.cause());
|
||||||
}
|
}
|
||||||
m_responseReadState = 2;
|
m_responseReadState = ResponseReadState::Finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +73,7 @@ void McClient::parseResponse()
|
||||||
{
|
{
|
||||||
qDebug() << "Received response successfully";
|
qDebug() << "Received response successfully";
|
||||||
|
|
||||||
int packetID = readVarInt(m_resp);
|
const int packetID = readVarInt(m_resp);
|
||||||
if (packetID != 0x00) {
|
if (packetID != 0x00) {
|
||||||
throw Exception(QString("Packet ID doesn't match expected value (0x00 vs 0x%1)").arg(packetID, 0, 16));
|
throw Exception(QString("Packet ID doesn't match expected value (0x00 vs 0x%1)").arg(packetID, 0, 16));
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +82,7 @@ void McClient::parseResponse()
|
||||||
|
|
||||||
// 'resp' should now be the JSON string
|
// 'resp' should now be the JSON string
|
||||||
QJsonParseError parseError;
|
QJsonParseError parseError;
|
||||||
QJsonDocument doc = Json::parseUntilGarbage(m_resp, &parseError);
|
const QJsonDocument doc = Json::parseUntilGarbage(m_resp, &parseError);
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
qDebug() << "Failed to parse JSON:" << parseError.errorString();
|
qDebug() << "Failed to parse JSON:" << parseError.errorString();
|
||||||
emitFail(parseError.errorString());
|
emitFail(parseError.errorString());
|
||||||
|
|
@ -93,18 +91,23 @@ void McClient::parseResponse()
|
||||||
emitSucceed(doc.object());
|
emitSucceed(doc.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOLINTBEGIN(*-signed-bitwise)
|
||||||
|
|
||||||
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
||||||
|
constexpr uint8_t g_varIntValueMask = 0x7F;
|
||||||
|
constexpr uint8_t g_varIntContinue = 0x80;
|
||||||
|
|
||||||
void McClient::writeVarInt(QByteArray& data, int value)
|
void McClient::writeVarInt(QByteArray& data, int value)
|
||||||
{
|
{
|
||||||
while ((value & ~SEGMENT_BITS)) { // check if the value is too big to fit in 7 bits
|
while ((value & ~g_varIntValueMask) != 0) { // check if the value is too big to fit in 7 bits
|
||||||
// Write 7 bits
|
// Write 7 bits
|
||||||
data.append((value & SEGMENT_BITS) | CONTINUE_BIT);
|
data.append(static_cast<uint8_t>((value & ~g_varIntValueMask) | g_varIntContinue)); // NOLINT(*-narrowing-conversions)
|
||||||
|
|
||||||
// Erase theses 7 bits from the value to write
|
// Erase theses 7 bits from the value to write
|
||||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||||
value >>= 7;
|
value >>= 7;
|
||||||
}
|
}
|
||||||
data.append(value);
|
data.append(static_cast<uint8_t>(value)); // NOLINT(*-narrowing-conversions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
||||||
|
|
@ -112,53 +115,56 @@ int McClient::readVarInt(QByteArray& data)
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
char currentByte;
|
|
||||||
|
|
||||||
while (position < 32) {
|
while (position < 32) {
|
||||||
currentByte = readByte(data);
|
const uint8_t currentByte = readByte(data);
|
||||||
value |= (currentByte & SEGMENT_BITS) << position;
|
value |= (currentByte & g_varIntValueMask) << position;
|
||||||
|
|
||||||
if ((currentByte & CONTINUE_BIT) == 0)
|
if ((currentByte & g_varIntContinue) == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
position += 7;
|
position += 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position >= 32)
|
if (position >= 32) {
|
||||||
throw Exception("VarInt is too big");
|
throw Exception("VarInt is too big");
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
char McClient::readByte(QByteArray& data)
|
// NOLINTEND(*-signed-bitwise)
|
||||||
|
|
||||||
|
uint8_t McClient::readByte(QByteArray& data)
|
||||||
{
|
{
|
||||||
if (data.isEmpty()) {
|
if (data.isEmpty()) {
|
||||||
throw Exception("No more bytes to read");
|
throw Exception("No more bytes to read");
|
||||||
}
|
}
|
||||||
|
|
||||||
char byte = data.at(0);
|
const uint8_t byte = data.at(0);
|
||||||
data.remove(0, 1);
|
data.remove(0, 1);
|
||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write number with specified size in big endian format
|
void McClient::writeUInt16(QByteArray& data, const uint16_t value)
|
||||||
void McClient::writeFixedInt(QByteArray& data, int value, int size)
|
|
||||||
{
|
{
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
QDataStream stream(&data, QIODeviceBase::Append);
|
||||||
data.append((value >> (i * 8)) & 0xFF);
|
stream.setByteOrder(QDataStream::BigEndian);
|
||||||
}
|
stream << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void McClient::writeString(QByteArray& data, const std::string& value)
|
void McClient::writeString(QByteArray& data, const QString& value)
|
||||||
{
|
{
|
||||||
data.append(value.c_str());
|
writeVarInt(data, static_cast<int32_t>(value.size()));
|
||||||
|
data.append(value.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void McClient::writePacketToSocket(QByteArray& data)
|
void McClient::writePacketToSocket(QByteArray& data)
|
||||||
{
|
{
|
||||||
// we prefix the packet with its length
|
// we prefix the packet with its length
|
||||||
QByteArray dataWithSize;
|
QByteArray dataWithSize;
|
||||||
writeVarInt(dataWithSize, data.size());
|
writeVarInt(dataWithSize, static_cast<int32_t>(data.size()));
|
||||||
dataWithSize.append(data);
|
dataWithSize.append(data);
|
||||||
|
|
||||||
// write it to the socket
|
// write it to the socket
|
||||||
|
|
@ -168,7 +174,7 @@ void McClient::writePacketToSocket(QByteArray& data)
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void McClient::emitFail(QString error)
|
void McClient::emitFail(const QString& error)
|
||||||
{
|
{
|
||||||
qDebug() << "Minecraft server ping for status error:" << error;
|
qDebug() << "Minecraft server ping for status error:" << error;
|
||||||
emit failed(error);
|
emit failed(error);
|
||||||
|
|
@ -177,6 +183,6 @@ void McClient::emitFail(QString error)
|
||||||
|
|
||||||
void McClient::emitSucceed(QJsonObject data)
|
void McClient::emitSucceed(QJsonObject data)
|
||||||
{
|
{
|
||||||
emit succeeded(data);
|
emit succeeded(std::move(data));
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,54 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
|
||||||
#include <Exception.h>
|
|
||||||
|
|
||||||
// Client for the Minecraft protocol
|
// Client for the Minecraft protocol
|
||||||
class McClient : public QObject {
|
class McClient : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QString m_domain;
|
|
||||||
QString m_ip;
|
|
||||||
short m_port;
|
|
||||||
QTcpSocket m_socket;
|
|
||||||
|
|
||||||
// 0: did not start reading the response yet
|
|
||||||
// 1: read the response length, still reading the response
|
|
||||||
// 2: finished reading the response
|
|
||||||
unsigned m_responseReadState = 0;
|
|
||||||
unsigned m_wantedRespLength = 0;
|
|
||||||
QByteArray m_resp;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit McClient(QObject* parent, QString domain, QString ip, short port);
|
explicit McClient(QObject* parent, QString domain, QString ip, uint16_t port);
|
||||||
//! Read status data of the server, and calls the succeeded() signal with the parsed JSON data
|
//! Read status data of the server, and calls the succeeded() signal with the parsed JSON data
|
||||||
void getStatusData();
|
void getStatusData();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void succeeded(QJsonObject data);
|
||||||
|
void failed(QString error);
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint8_t readByte(QByteArray& data);
|
||||||
|
static int readVarInt(QByteArray& data);
|
||||||
|
static void writeUInt16(QByteArray& data, uint16_t value);
|
||||||
|
static void writeString(QByteArray& data, const QString& value);
|
||||||
|
static void writeVarInt(QByteArray& data, int value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendRequest();
|
void sendRequest();
|
||||||
//! Accumulate data until we have a full response, then call parseResponse() once
|
//! Accumulate data until we have a full response, then call parseResponse() once
|
||||||
void readRawResponse();
|
void readRawResponse();
|
||||||
void parseResponse();
|
void parseResponse();
|
||||||
|
|
||||||
void writeVarInt(QByteArray& data, int value);
|
|
||||||
int readVarInt(QByteArray& data);
|
|
||||||
char readByte(QByteArray& data);
|
|
||||||
//! write number with specified size in big endian format
|
|
||||||
void writeFixedInt(QByteArray& data, int value, int size);
|
|
||||||
void writeString(QByteArray& data, const std::string& value);
|
|
||||||
|
|
||||||
void writePacketToSocket(QByteArray& data);
|
void writePacketToSocket(QByteArray& data);
|
||||||
|
|
||||||
void emitFail(QString error);
|
void emitFail(const QString& error);
|
||||||
void emitSucceed(QJsonObject data);
|
void emitSucceed(QJsonObject data);
|
||||||
|
|
||||||
signals:
|
private:
|
||||||
void succeeded(QJsonObject data);
|
enum class ResponseReadState : uint8_t {
|
||||||
void failed(QString error);
|
Waiting,
|
||||||
void finished();
|
GotLength,
|
||||||
|
Finished
|
||||||
|
};
|
||||||
|
|
||||||
|
QString m_domain;
|
||||||
|
QString m_ip;
|
||||||
|
uint16_t m_port;
|
||||||
|
QTcpSocket m_socket;
|
||||||
|
|
||||||
|
ResponseReadState m_responseReadState = ResponseReadState::Waiting;
|
||||||
|
int32_t m_wantedRespLength = 0;
|
||||||
|
QByteArray m_resp;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ void JavaSettingsWidget::loadSettings()
|
||||||
m_ui->maxMemSpinBox->setValue(min);
|
m_ui->maxMemSpinBox->setValue(min);
|
||||||
}
|
}
|
||||||
m_ui->permGenSpinBox->setValue(settings->get("PermGen").toInt());
|
m_ui->permGenSpinBox->setValue(settings->get("PermGen").toInt());
|
||||||
|
m_ui->lowMemWarningCheckBox->setChecked(settings->get("LowMemWarning").toBool());
|
||||||
|
|
||||||
// Java arguments
|
// Java arguments
|
||||||
m_ui->javaArgumentsGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideJavaArgs").toBool());
|
m_ui->javaArgumentsGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideJavaArgs").toBool());
|
||||||
|
|
@ -205,10 +206,12 @@ void JavaSettingsWidget::saveSettings()
|
||||||
settings->set("MaxMemAlloc", min);
|
settings->set("MaxMemAlloc", min);
|
||||||
}
|
}
|
||||||
settings->set("PermGen", m_ui->permGenSpinBox->value());
|
settings->set("PermGen", m_ui->permGenSpinBox->value());
|
||||||
|
settings->set("LowMemWarning", m_ui->lowMemWarningCheckBox->isChecked());
|
||||||
} else {
|
} else {
|
||||||
settings->reset("MinMemAlloc");
|
settings->reset("MinMemAlloc");
|
||||||
settings->reset("MaxMemAlloc");
|
settings->reset("MaxMemAlloc");
|
||||||
settings->reset("PermGen");
|
settings->reset("PermGen");
|
||||||
|
settings->reset("LowMemWarning");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Java arguments
|
// Java arguments
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -86,7 +86,7 @@
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_7">
|
<spacer name="horizontalSpacer_7">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -101,10 +101,10 @@
|
||||||
<item row="9" column="0">
|
<item row="9" column="0">
|
||||||
<spacer name="verticalSpacer_4">
|
<spacer name="verticalSpacer_4">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -160,10 +160,10 @@
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<spacer name="verticalSpacer_5">
|
<spacer name="verticalSpacer_5">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -190,156 +190,166 @@
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item row="2" column="2">
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="labelMinMem">
|
||||||
|
<property name="text">
|
||||||
|
<string>M&inimum Memory Usage:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>minMemSpinBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="minMemSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The amount of memory Minecraft is started with.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MiB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1048576</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>256</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>(-Xms)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="labelMaxMem">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ma&ximum Memory Usage:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>maxMemSpinBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="maxMemSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The maximum amount of memory Minecraft is allowed to use.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MiB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1048576</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1024</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>(-Xmx)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>&PermGen Size:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>permGenSpinBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="permGenSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The amount of memory available to store loaded Java classes.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MiB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1048576</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>64</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>(-XX:PermSize)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="lowMemWarningCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>(-XX:PermSize)</string>
|
<string>Warn when there is not enough memory available</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item>
|
||||||
<widget class="QSpinBox" name="permGenSpinBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The amount of memory available to store loaded Java classes.</string>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string notr="true"> MiB</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>1048576</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>64</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="maxMemSpinBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The maximum amount of memory Minecraft is allowed to use.</string>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string notr="true"> MiB</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>1048576</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>128</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>1024</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>(-Xmx)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QSpinBox" name="minMemSpinBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The amount of memory Minecraft is started with.</string>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string notr="true"> MiB</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>1048576</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>128</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>256</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>&PermGen Size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>permGenSpinBox</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>(-Xms)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="labelMaxMem">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ma&ximum Memory Usage:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>maxMemSpinBox</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="labelMinMem">
|
|
||||||
<property name="text">
|
|
||||||
<string>M&inimum Memory Usage:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>minMemSpinBox</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="4">
|
|
||||||
<widget class="QLabel" name="labelMaxMemNotice">
|
<widget class="QLabel" name="labelMaxMemNotice">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Memory Notice</string>
|
<string>Memory Notice</string>
|
||||||
|
|
@ -382,9 +392,7 @@
|
||||||
<tabstop>autodownloadJavaCheckBox</tabstop>
|
<tabstop>autodownloadJavaCheckBox</tabstop>
|
||||||
<tabstop>javaTestBtn</tabstop>
|
<tabstop>javaTestBtn</tabstop>
|
||||||
<tabstop>javaDownloadBtn</tabstop>
|
<tabstop>javaDownloadBtn</tabstop>
|
||||||
<tabstop>minMemSpinBox</tabstop>
|
|
||||||
<tabstop>maxMemSpinBox</tabstop>
|
<tabstop>maxMemSpinBox</tabstop>
|
||||||
<tabstop>permGenSpinBox</tabstop>
|
|
||||||
<tabstop>jvmArgsTextBox</tabstop>
|
<tabstop>jvmArgsTextBox</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
|
||||||
|
|
@ -1160,8 +1160,6 @@ void PrismUpdaterApp::downloadReleasePage(const QString& api_url, int page)
|
||||||
m_current_task.reset(download);
|
m_current_task.reset(download);
|
||||||
connect(download.get(), &Net::Download::finished, this, [this]() {
|
connect(download.get(), &Net::Download::finished, this, [this]() {
|
||||||
qDebug() << "Download" << m_current_task->getUid().toString() << "finished";
|
qDebug() << "Download" << m_current_task->getUid().toString() << "finished";
|
||||||
m_current_task.reset();
|
|
||||||
m_current_url = "";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue