feat: block launch if Java is incompatible
Keep track of compatible Java versions from meta. Launch-step VerifyJavaInstall will check if current instance's Java version is compatible. Also add override option both globally and per-instance in-case the user doesn't care about the requirement.
This commit is contained in:
parent
c7fdfb8116
commit
82c35f2746
@ -682,6 +682,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
||||
m_settings->registerSetting("JavaVendor", "");
|
||||
m_settings->registerSetting("LastHostname", "");
|
||||
m_settings->registerSetting("JvmArgs", "");
|
||||
m_settings->registerSetting("IgnoreJavaCompatibility", false);
|
||||
|
||||
// Native library workarounds
|
||||
m_settings->registerSetting("UseNativeOpenAL", false);
|
||||
|
@ -126,6 +126,11 @@ void LaunchProfile::applyMods(const QList<LibraryPtr>& mods)
|
||||
}
|
||||
}
|
||||
|
||||
void LaunchProfile::applyCompatibleJavaMajors(QList<int>& javaMajor)
|
||||
{
|
||||
m_compatibleJavaMajors.append(javaMajor);
|
||||
}
|
||||
|
||||
void LaunchProfile::applyLibrary(LibraryPtr library)
|
||||
{
|
||||
if(!library->isActive())
|
||||
@ -275,6 +280,11 @@ const QList<LibraryPtr> & LaunchProfile::getMavenFiles() const
|
||||
return m_mavenFiles;
|
||||
}
|
||||
|
||||
const QList<int> & LaunchProfile::getCompatibleJavaMajors() const
|
||||
{
|
||||
return m_compatibleJavaMajors;
|
||||
}
|
||||
|
||||
void LaunchProfile::getLibraryFiles(
|
||||
const QString& architecture,
|
||||
QStringList& jars,
|
||||
|
@ -21,6 +21,7 @@ public: /* application of profile variables from patches */
|
||||
void applyMods(const QList<LibraryPtr> &jarMods);
|
||||
void applyLibrary(LibraryPtr library);
|
||||
void applyMavenFile(LibraryPtr library);
|
||||
void applyCompatibleJavaMajors(QList<int>& javaMajor);
|
||||
void applyMainJar(LibraryPtr jar);
|
||||
void applyProblemSeverity(ProblemSeverity severity);
|
||||
/// clear the profile
|
||||
@ -39,6 +40,7 @@ public: /* getters for profile variables */
|
||||
const QList<LibraryPtr> & getLibraries() const;
|
||||
const QList<LibraryPtr> & getNativeLibraries() const;
|
||||
const QList<LibraryPtr> & getMavenFiles() const;
|
||||
const QList<int> & getCompatibleJavaMajors() const;
|
||||
const LibraryPtr getMainJar() const;
|
||||
void getLibraryFiles(
|
||||
const QString & architecture,
|
||||
@ -99,6 +101,9 @@ private:
|
||||
/// the list of mods
|
||||
QList<LibraryPtr> m_mods;
|
||||
|
||||
/// compatible java major versions
|
||||
QList<int> m_compatibleJavaMajors;
|
||||
|
||||
ProblemSeverity m_problemSeverity = ProblemSeverity::None;
|
||||
|
||||
};
|
||||
|
@ -88,6 +88,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
|
||||
|
||||
m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
|
||||
m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
|
||||
m_settings->registerOverride(globalSettings->getSetting("IgnoreJavaCompatibility"), javaOrLocation);
|
||||
|
||||
// special!
|
||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
|
||||
|
@ -183,6 +183,15 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (in.contains("compatibleJavaMajors"))
|
||||
{
|
||||
for (auto compatible : requireArray(in.value("compatibleJavaMajors")))
|
||||
{
|
||||
out->compatibleJavaMajors.append(requireInteger(compatible));
|
||||
}
|
||||
}
|
||||
|
||||
if(in.contains("downloads"))
|
||||
{
|
||||
auto downloadsObj = requireObject(in, "downloads");
|
||||
|
@ -36,6 +36,7 @@ void VersionFile::applyTo(LaunchProfile *profile)
|
||||
profile->applyJarMods(jarMods);
|
||||
profile->applyMods(mods);
|
||||
profile->applyTraits(traits);
|
||||
profile->applyCompatibleJavaMajors(compatibleJavaMajors);
|
||||
|
||||
for (auto library : libraries)
|
||||
{
|
||||
|
@ -57,6 +57,9 @@ public: /* data */
|
||||
/// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
|
||||
QString minecraftArguments;
|
||||
|
||||
/// Mojang: list of compatible java majors
|
||||
QList<int> compatibleJavaMajors;
|
||||
|
||||
/// Mojang: type of the Minecraft version
|
||||
QString type;
|
||||
|
||||
|
@ -1,50 +1,40 @@
|
||||
#include "VerifyJavaInstall.h"
|
||||
|
||||
#include <launch/LaunchTask.h>
|
||||
#include <minecraft/MinecraftInstance.h>
|
||||
#include <minecraft/PackProfile.h>
|
||||
#include <minecraft/VersionFilterData.h>
|
||||
|
||||
#ifdef major
|
||||
#undef major
|
||||
#endif
|
||||
#ifdef minor
|
||||
#undef minor
|
||||
#endif
|
||||
#include "java/JavaVersion.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
|
||||
void VerifyJavaInstall::executeTask() {
|
||||
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
|
||||
auto instance = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
|
||||
auto packProfile = instance->getPackProfile();
|
||||
auto settings = instance->settings();
|
||||
auto storedVersion = settings->get("JavaVersion").toString();
|
||||
auto ignoreCompatibility = settings->get("IgnoreJavaCompatibility").toBool();
|
||||
|
||||
auto javaVersion = m_inst->getJavaVersion();
|
||||
auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft");
|
||||
auto compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors();
|
||||
|
||||
// Java 17 requirement
|
||||
if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java17BeginsDate) {
|
||||
if (javaVersion.major() < 17) {
|
||||
emit logLine("Minecraft 1.18 Pre Release 2 and above require the use of Java 17",
|
||||
MessageLevel::Fatal);
|
||||
emitFailed(tr("Minecraft 1.18 Pre Release 2 and above require the use of Java 17"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Java 16 requirement
|
||||
else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) {
|
||||
if (javaVersion.major() < 16) {
|
||||
emit logLine("Minecraft 21w19a and above require the use of Java 16",
|
||||
MessageLevel::Fatal);
|
||||
emitFailed(tr("Minecraft 21w19a and above require the use of Java 16"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Java 8 requirement
|
||||
else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java8BeginsDate) {
|
||||
if (javaVersion.major() < 8) {
|
||||
emit logLine("Minecraft 17w13a and above require the use of Java 8",
|
||||
MessageLevel::Fatal);
|
||||
emitFailed(tr("Minecraft 17w13a and above require the use of Java 8"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
JavaVersion javaVersion(storedVersion);
|
||||
|
||||
if (compatibleMajors.isEmpty() || compatibleMajors.contains(javaVersion.major()))
|
||||
{
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ignoreCompatibility)
|
||||
{
|
||||
emit logLine(tr("Java major version is incompatible. Things might break."), MessageLevel::Warning);
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
emit logLine(tr("Instance not compatible with Java major version %1.\n"
|
||||
"Switch the Java version of this instance to one of the following:").arg(javaVersion.major()),
|
||||
MessageLevel::Error);
|
||||
for (auto major: compatibleMajors)
|
||||
{
|
||||
emit logLine(tr("Java %1").arg(major), MessageLevel::Error);
|
||||
}
|
||||
emitFailed(QString("Incompatible Java major version"));
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <launch/LaunchStep.h>
|
||||
#include <launch/LaunchTask.h>
|
||||
|
||||
class VerifyJavaInstall : public LaunchStep {
|
||||
Q_OBJECT
|
||||
|
@ -95,6 +95,7 @@ void JavaPage::applySettings()
|
||||
// Java Settings
|
||||
s->set("JavaPath", ui->javaPathTextBox->text());
|
||||
s->set("JvmArgs", ui->jvmArgsTextBox->text());
|
||||
s->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked());
|
||||
JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget());
|
||||
}
|
||||
void JavaPage::loadSettings()
|
||||
@ -118,6 +119,7 @@ void JavaPage::loadSettings()
|
||||
// Java Settings
|
||||
ui->javaPathTextBox->setText(s->get("JavaPath").toString());
|
||||
ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString());
|
||||
ui->skipCompatibilityCheckbox->setChecked(s->get("IgnoreJavaCompatibility").toBool());
|
||||
}
|
||||
|
||||
void JavaPage::on_javaDetectBtn_clicked()
|
||||
|
@ -222,6 +222,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="skipCompatibilityCheckbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>If enabled, the launcher will not check if an instance is compatible with the selected Java version.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Skip Java compatibility checks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -165,10 +165,12 @@ void InstanceSettingsPage::applySettings()
|
||||
if (javaInstall)
|
||||
{
|
||||
m_settings->set("JavaPath", ui->javaPathTextBox->text());
|
||||
m_settings->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("JavaPath");
|
||||
m_settings->reset("IgnoreJavaCompatibility");
|
||||
}
|
||||
|
||||
// Java arguments
|
||||
@ -286,6 +288,7 @@ void InstanceSettingsPage::loadSettings()
|
||||
|
||||
ui->javaSettingsGroupBox->setChecked(overrideLocation);
|
||||
ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
|
||||
ui->skipCompatibilityCheckbox->setChecked(m_settings->get("IgnoreJavaCompatibility").toBool());
|
||||
|
||||
ui->javaArgumentsGroupBox->setChecked(overrideArgs);
|
||||
ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
|
||||
|
@ -85,6 +85,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="skipCompatibilityCheckbox">
|
||||
<property name="toolTip">
|
||||
<string>If enabled, the launcher will not check if an instance is compatible with the selected Java version.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Skip Java compatibility checks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
Loading…
Reference in New Issue
Block a user