From c77f5285e3ff3d19d0546419ef9300da8932402f Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Wed, 23 Jun 2021 15:49:31 +0100 Subject: [PATCH 1/3] NOISSUE Close optional mod dialog with Install button This was a silly ommision I made. --- .../pages/modplatform/atlauncher/AtlOptionalModDialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index cffe5d55e..14bbd18b6 100644 --- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -200,6 +200,8 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVectorclearAllButton, &QPushButton::pressed, listModel, &AtlOptionalModListModel::clearAll); + connect(ui->installButton, &QPushButton::pressed, + this, &QDialog::close); } AtlOptionalModDialog::~AtlOptionalModDialog() { From 7c0fdaa7303125b26d0a6882d4616016c3923bca Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Wed, 23 Jun 2021 18:19:48 +0100 Subject: [PATCH 2/3] NOISSUE Check mod and config checksums for ATLauncher --- .../atlauncher/ATLPackInstallTask.cpp | 20 ++++++++++++++++++- .../atlauncher/ATLPackManifest.cpp | 11 +++++++++- .../modplatform/atlauncher/ATLPackManifest.h | 7 +++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp index 89829c051..dac80e8c9 100644 --- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "ATLPackInstallTask.h" #include "BuildConfig.h" @@ -407,7 +408,12 @@ void PackInstallTask::installConfigs() auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", path); entry->setStale(true); - jobPtr->addNetAction(Net::Download::makeCached(url, entry)); + auto dl = Net::Download::makeCached(url, entry); + if (!m_version.configs.sha1.isEmpty()) { + auto rawSha1 = QByteArray::fromHex(m_version.configs.sha1.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + } + jobPtr->addNetAction(dl); archivePath = entry->getFullPath(); connect(jobPtr.get(), &NetJob::succeeded, this, [&]() @@ -508,6 +514,10 @@ void PackInstallTask::downloadMods() modsToExtract.insert(entry->getFullPath(), mod); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); } else if(mod.type == ModType::Decomp) { @@ -516,6 +526,10 @@ void PackInstallTask::downloadMods() modsToDecomp.insert(entry->getFullPath(), mod); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); } else { @@ -526,6 +540,10 @@ void PackInstallTask::downloadMods() entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file); diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp index f28fd35cd..e25d8346c 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp @@ -109,6 +109,11 @@ static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj p.server = Json::ensureString(obj, "server", ""); } +static void loadVersionConfigs(ATLauncher::VersionConfigs & p, QJsonObject & obj) { + p.filesize = Json::requireInteger(obj, "filesize"); + p.sha1 = Json::requireString(obj, "sha1"); +} + static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { p.name = Json::requireString(obj, "name"); p.version = Json::requireString(obj, "version"); @@ -195,7 +200,6 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) } } - if(obj.contains("mods")) { auto mods = Json::requireArray(obj, "mods"); for (const auto modRaw : mods) @@ -206,4 +210,9 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) v.mods.append(mod); } } + + if(obj.contains("configs")) { + auto configsObj = Json::requireObject(obj, "configs"); + loadVersionConfigs(v.configs, configsObj); + } } diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h index 376587b05..17821e4ce 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.h +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.h @@ -101,6 +101,12 @@ struct VersionMod bool effectively_hidden; }; +struct VersionConfigs +{ + int filesize; + QString sha1; +}; + struct PackVersion { QString version; @@ -112,6 +118,7 @@ struct PackVersion VersionLoader loader; QVector libraries; QVector mods; + VersionConfigs configs; }; MULTIMC_LOGIC_EXPORT void loadVersion(PackVersion & v, QJsonObject & obj); From a20a7e987fcc6e2d43a1686a175447495245615c Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Wed, 23 Jun 2021 21:24:25 +0100 Subject: [PATCH 3/3] NOISSUE Fail launch if minimum Java requirement is not met This will fail launch in the following conditions: 1. A version greater than or equal to Minecraft 17w13a, and less than 21w19a - and the Java version is less than 8. 2. A version greater than or equal to Minecraft 21w19a - and the Java version is less than 16. --- api/logic/CMakeLists.txt | 2 ++ api/logic/minecraft/MinecraftInstance.cpp | 6 ++++ api/logic/minecraft/VersionFilterData.cpp | 3 ++ api/logic/minecraft/VersionFilterData.h | 4 +++ .../minecraft/launch/VerifyJavaInstall.cpp | 34 +++++++++++++++++++ .../minecraft/launch/VerifyJavaInstall.h | 17 ++++++++++ 6 files changed, 66 insertions(+) create mode 100644 api/logic/minecraft/launch/VerifyJavaInstall.cpp create mode 100644 api/logic/minecraft/launch/VerifyJavaInstall.h diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 17e224580..6d269714a 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -246,6 +246,8 @@ set(MINECRAFT_SOURCES minecraft/launch/ReconstructAssets.h minecraft/launch/ScanModFolders.cpp minecraft/launch/ScanModFolders.h + minecraft/launch/VerifyJavaInstall.cpp + minecraft/launch/VerifyJavaInstall.h minecraft/legacy/LegacyModList.h minecraft/legacy/LegacyModList.cpp diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index fdf9bd61c..ea1e47b6c 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -23,6 +23,7 @@ #include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/ReconstructAssets.h" #include "minecraft/launch/ScanModFolders.h" +#include "minecraft/launch/VerifyJavaInstall.h" #include "java/launch/CheckJava.h" #include "java/JavaUtils.h" #include "meta/Index.h" @@ -915,6 +916,11 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(new ReconstructAssets(pptr)); } + // verify that minimum Java requirements are met + { + process->appendStep(new VerifyJavaInstall(pptr)); + } + { // actually launch the game auto method = launchMethod(); diff --git a/api/logic/minecraft/VersionFilterData.cpp b/api/logic/minecraft/VersionFilterData.cpp index a47fc0a0b..38e7b60c8 100644 --- a/api/logic/minecraft/VersionFilterData.cpp +++ b/api/logic/minecraft/VersionFilterData.cpp @@ -65,4 +65,7 @@ VersionFilterData::VersionFilterData() QSet{"net.java.jinput:jinput", "net.java.jinput:jinput-platform", "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl", "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"}; + + java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00"); + java16BeginsDate = timeFromS3Time("2021-05-12T11:19:15+00:00"); } diff --git a/api/logic/minecraft/VersionFilterData.h b/api/logic/minecraft/VersionFilterData.h index afd4502bc..d100acc3d 100644 --- a/api/logic/minecraft/VersionFilterData.h +++ b/api/logic/minecraft/VersionFilterData.h @@ -23,5 +23,9 @@ struct VersionFilterData QDateTime legacyCutoffDate; // Libraries that belong to LWJGL QSet lwjglWhitelist; + // release date of first version to require Java 8 (17w13a) + QDateTime java8BeginsDate; + // release data of first version to require Java 16 (21w19a) + QDateTime java16BeginsDate; }; extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData; diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.cpp b/api/logic/minecraft/launch/VerifyJavaInstall.cpp new file mode 100644 index 000000000..657669af0 --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.cpp @@ -0,0 +1,34 @@ +#include "VerifyJavaInstall.h" + +#include +#include +#include +#include + +void VerifyJavaInstall::executeTask() { + auto m_inst = std::dynamic_pointer_cast(m_parent->instance()); + + auto javaVersion = m_inst->getJavaVersion(); + auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft"); + + // Java 16 requirement + 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; + } + } + + emitSucceeded(); +} diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.h b/api/logic/minecraft/launch/VerifyJavaInstall.h new file mode 100644 index 000000000..a553106d1 --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +class VerifyJavaInstall : public LaunchStep { + Q_OBJECT + +public: + explicit VerifyJavaInstall(LaunchTask *parent) : LaunchStep(parent) { + }; + ~VerifyJavaInstall() override = default; + + void executeTask() override; + bool canAbort() const override { + return false; + } +};