From f95856d06285a65caf0da7377f42f45c33d9603f Mon Sep 17 00:00:00 2001 From: timoreo Date: Thu, 30 Jun 2022 18:07:08 +0200 Subject: [PATCH 01/83] Add the base of java downloading Signed-off-by: timoreo --- launcher/CMakeLists.txt | 2 + launcher/JavaDownloader.cpp | 165 ++++++++++++++++++++++++++++++++++++ launcher/JavaDownloader.h | 8 ++ 3 files changed, 175 insertions(+) create mode 100644 launcher/JavaDownloader.cpp create mode 100644 launcher/JavaDownloader.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 79ac49c76e..4e55085798 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -881,6 +881,8 @@ SET(LAUNCHER_SOURCES ui/instanceview/InstanceDelegate.h ui/instanceview/VisualGroup.cpp ui/instanceview/VisualGroup.h + JavaDownloader.cpp + JavaDownloader.h ) if(WIN32) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp new file mode 100644 index 0000000000..43da2df01c --- /dev/null +++ b/launcher/JavaDownloader.cpp @@ -0,0 +1,165 @@ +#include "JavaDownloader.h" +#include "net/NetJob.h" +#include "Application.h" +#include "FileSystem.h" +#include "quazip.h" +#include "MMCZip.h" +#include "net/ChecksumValidator.h" + +//Quick & dirty struct to store files +struct File{ + QString path; + QString url; + QByteArray hash; +}; + +void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) { + //Query the adoptium API to get a good version + auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); + auto response = new QByteArray(); + netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://launchermeta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); + QObject::connect(netJob, &NetJob::finished,[netJob, response]{ + netJob->deleteLater(); + delete response; + }); + QObject::connect(netJob, &NetJob::succeeded,[response, &OS, isLegacy] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + auto versionArray = doc.object()[OS].toObject()[isLegacy ? "jre-legacy" : "java-runtime-gamma"].toArray(); + if(!versionArray.empty()){ + auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); + auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); + auto files = new QByteArray(); + + download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); + + QObject::connect(download, &NetJob::finished,[download, files]{ + download->deleteLater(); + delete files; + }); + QObject::connect(download, &NetJob::succeeded,[files, isLegacy] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *files; + return; + } + + //valid json doc, begin making jre spot + auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java/") + (isLegacy ? "java-legacy" : "java-current")); + FS::ensureFolderPathExists(output); + std::vector toDownload; + auto list = doc.object()["files"].toObject(); + for(auto element : list){ + auto obj = element.toObject(); + for(const auto& paths : obj.keys()){ + auto file = FS::PathCombine(output,paths); + + auto type = obj[paths].toObject()["type"].toString(); + if(type == "directory"){ + FS::ensureFolderPathExists(file); + }else if(type == "link"){ + //this is linux only ! + auto target = FS::PathCombine(file,"../"+obj[paths].toObject()["target"].toString()); + QFile(target).link(file); + }else if(type == "file"){ + //TODO download compressed version if it exists ? + auto raw = obj[paths].toObject()["downloads"].toObject()["raw"].toObject(); + auto f = File{file,raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1())}; + toDownload.push_back(f); + } + } + } + auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); + for(const auto& file : toDownload){ + auto dl = Net::Download::makeFile(file.url,file.path); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + elementDownload->addNetAction(dl); + } + QObject::connect(elementDownload, &NetJob::finished,[elementDownload]{ + elementDownload->deleteLater(); + }); + elementDownload->start(); + }); + download->start(); + }else{ + //mojang does not have a JRE for us, let's get azul zulu + QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); + QString azulOS; + QString arch; + QString bitness; + + if(OS == "mac-os-arm64"){ + //macos arm64 + azulOS = "macos"; + arch = "arm"; + bitness = "64"; + }else if(OS == "linux-aarch64"){ + //linux aarch64 + azulOS = "linux"; + arch = "arm"; + bitness = "64"; + } + auto metaResponse = new QByteArray(); + auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); + downloadJob->addNetAction(Net::Download::makeByteArray(QString( + "https://api.azul.com/zulu/download/community/v1.0/bundles/?" + "java_version=%1" + "&os=%2" + "&arch=%3" + "&hw_bitness=%4" + "&ext=zip" //as a zip for all os, even linux + "&bundle_type=jre" //jre only + "&latest=true" //only get the one latest entry + ).arg(javaVersion,azulOS,arch,bitness), metaResponse)); + QObject::connect(downloadJob, &NetJob::finished,[downloadJob, metaResponse]{ + downloadJob->deleteLater(); + delete metaResponse; + }); + + QObject::connect(downloadJob, &NetJob::succeeded,[metaResponse, isLegacy] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *metaResponse; + return; + } + auto array = doc.array(); + if(!array.empty()){ + //JRE found ! download the zip + auto downloadURL = QUrl(array[0].toObject()["url"].toString()); + auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); + const QString path = downloadURL.host() + '/' + downloadURL.path(); + auto entry = APPLICATION->metacache()->resolveEntry("general", path); + entry->setStale(true); + download->addNetAction(Net::Download::makeCached(downloadURL,entry)); + auto zippath = entry->getFullPath(); + QObject::connect(download, &NetJob::finished,[download]{ + download->deleteLater(); + + }); + QObject::connect(download, &NetJob::succeeded,[isLegacy, zippath]{ + auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"),isLegacy ? "java-legacy" : "java-current"); + //This should do all of the extracting and creating folders + MMCZip::extractDir(zippath, output); + }); + }else{ + qWarning() << "No suitable JRE found !!"; + } + }); + } + }); + + netJob->start(); + +} \ No newline at end of file diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h new file mode 100644 index 0000000000..cc073b54cc --- /dev/null +++ b/launcher/JavaDownloader.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace JavaDownloader { + /*Downloads the java to the runtimes folder*/ + void downloadJava(bool isLegacy, const QString& OS); +} From 3433c102b70c1c74c882dd2fa19242725676ffe5 Mon Sep 17 00:00:00 2001 From: timoreo Date: Thu, 30 Jun 2022 18:13:52 +0200 Subject: [PATCH 02/83] Remove old comment and change to piston-meta Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 43da2df01c..f1a24a68cc 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -14,10 +14,9 @@ struct File{ }; void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) { - //Query the adoptium API to get a good version auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); auto response = new QByteArray(); - netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://launchermeta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); QObject::connect(netJob, &NetJob::finished,[netJob, response]{ netJob->deleteLater(); delete response; From 9a4a92de4f90334a9dcf1b7b7712f628b232d480 Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 1 Jul 2022 08:52:56 +0200 Subject: [PATCH 03/83] Clang format Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 124 +++++++++++++++++------------------- launcher/JavaDownloader.h | 6 +- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index f1a24a68cc..5c3d04a6df 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -1,158 +1,155 @@ #include "JavaDownloader.h" -#include "net/NetJob.h" #include "Application.h" #include "FileSystem.h" -#include "quazip.h" #include "MMCZip.h" #include "net/ChecksumValidator.h" +#include "net/NetJob.h" +#include "quazip.h" -//Quick & dirty struct to store files -struct File{ +// Quick & dirty struct to store files +struct File { QString path; QString url; QByteArray hash; }; -void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) { +void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) +{ auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); auto response = new QByteArray(); - netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - QObject::connect(netJob, &NetJob::finished,[netJob, response]{ + netJob->addNetAction(Net::Download::makeByteArray( + QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); + QObject::connect(netJob, &NetJob::finished, [netJob, response] { netJob->deleteLater(); delete response; }); - QObject::connect(netJob, &NetJob::succeeded,[response, &OS, isLegacy] { + QObject::connect(netJob, &NetJob::succeeded, [response, &OS, isLegacy] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset - << " reason: " << parse_error.errorString(); + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; return; } auto versionArray = doc.object()[OS].toObject()[isLegacy ? "jre-legacy" : "java-runtime-gamma"].toArray(); - if(!versionArray.empty()){ + if (!versionArray.empty()) { auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = new QByteArray(); download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); - QObject::connect(download, &NetJob::finished,[download, files]{ + QObject::connect(download, &NetJob::finished, [download, files] { download->deleteLater(); delete files; }); - QObject::connect(download, &NetJob::succeeded,[files, isLegacy] { + QObject::connect(download, &NetJob::succeeded, [files, isLegacy] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset - << " reason: " << parse_error.errorString(); + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *files; return; } - //valid json doc, begin making jre spot - auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java/") + (isLegacy ? "java-legacy" : "java-current")); + // valid json doc, begin making jre spot + auto output = + FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java/") + (isLegacy ? "java-legacy" : "java-current")); FS::ensureFolderPathExists(output); std::vector toDownload; auto list = doc.object()["files"].toObject(); - for(auto element : list){ + for (auto element : list) { auto obj = element.toObject(); - for(const auto& paths : obj.keys()){ - auto file = FS::PathCombine(output,paths); + for (const auto& paths : obj.keys()) { + auto file = FS::PathCombine(output, paths); auto type = obj[paths].toObject()["type"].toString(); - if(type == "directory"){ + if (type == "directory") { FS::ensureFolderPathExists(file); - }else if(type == "link"){ - //this is linux only ! - auto target = FS::PathCombine(file,"../"+obj[paths].toObject()["target"].toString()); + } else if (type == "link") { + // this is linux only ! + auto target = FS::PathCombine(file, "../" + obj[paths].toObject()["target"].toString()); QFile(target).link(file); - }else if(type == "file"){ - //TODO download compressed version if it exists ? + } else if (type == "file") { + // TODO download compressed version if it exists ? auto raw = obj[paths].toObject()["downloads"].toObject()["raw"].toObject(); - auto f = File{file,raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1())}; + auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()) }; toDownload.push_back(f); } } } auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); - for(const auto& file : toDownload){ - auto dl = Net::Download::makeFile(file.url,file.path); + for (const auto& file : toDownload) { + auto dl = Net::Download::makeFile(file.url, file.path); dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); elementDownload->addNetAction(dl); } - QObject::connect(elementDownload, &NetJob::finished,[elementDownload]{ - elementDownload->deleteLater(); - }); + QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); elementDownload->start(); }); download->start(); - }else{ - //mojang does not have a JRE for us, let's get azul zulu + } else { + // mojang does not have a JRE for us, let's get azul zulu QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); QString azulOS; QString arch; QString bitness; - if(OS == "mac-os-arm64"){ - //macos arm64 + if (OS == "mac-os-arm64") { + // macos arm64 azulOS = "macos"; arch = "arm"; bitness = "64"; - }else if(OS == "linux-aarch64"){ - //linux aarch64 + } else if (OS == "linux-aarch64") { + // linux aarch64 azulOS = "linux"; arch = "arm"; bitness = "64"; } auto metaResponse = new QByteArray(); auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); - downloadJob->addNetAction(Net::Download::makeByteArray(QString( - "https://api.azul.com/zulu/download/community/v1.0/bundles/?" - "java_version=%1" - "&os=%2" - "&arch=%3" - "&hw_bitness=%4" - "&ext=zip" //as a zip for all os, even linux - "&bundle_type=jre" //jre only - "&latest=true" //only get the one latest entry - ).arg(javaVersion,azulOS,arch,bitness), metaResponse)); - QObject::connect(downloadJob, &NetJob::finished,[downloadJob, metaResponse]{ + downloadJob->addNetAction(Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" + "java_version=%1" + "&os=%2" + "&arch=%3" + "&hw_bitness=%4" + "&ext=zip" // as a zip for all os, even linux + "&bundle_type=jre" // jre only + "&latest=true" // only get the one latest entry + ) + .arg(javaVersion, azulOS, arch, bitness), + metaResponse)); + QObject::connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse] { downloadJob->deleteLater(); delete metaResponse; }); - QObject::connect(downloadJob, &NetJob::succeeded,[metaResponse, isLegacy] { + QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset - << " reason: " << parse_error.errorString(); + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *metaResponse; return; } auto array = doc.array(); - if(!array.empty()){ - //JRE found ! download the zip + if (!array.empty()) { + // JRE found ! download the zip auto downloadURL = QUrl(array[0].toObject()["url"].toString()); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); const QString path = downloadURL.host() + '/' + downloadURL.path(); auto entry = APPLICATION->metacache()->resolveEntry("general", path); entry->setStale(true); - download->addNetAction(Net::Download::makeCached(downloadURL,entry)); + download->addNetAction(Net::Download::makeCached(downloadURL, entry)); auto zippath = entry->getFullPath(); - QObject::connect(download, &NetJob::finished,[download]{ - download->deleteLater(); - - }); - QObject::connect(download, &NetJob::succeeded,[isLegacy, zippath]{ - auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"),isLegacy ? "java-legacy" : "java-current"); - //This should do all of the extracting and creating folders + QObject::connect(download, &NetJob::finished, [download] { download->deleteLater(); }); + QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath] { + auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), + isLegacy ? "java-legacy" : "java-current"); + // This should do all of the extracting and creating folders MMCZip::extractDir(zippath, output); }); - }else{ + } else { qWarning() << "No suitable JRE found !!"; } }); @@ -160,5 +157,4 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) { }); netJob->start(); - } \ No newline at end of file diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h index cc073b54cc..3dd57eebe6 100644 --- a/launcher/JavaDownloader.h +++ b/launcher/JavaDownloader.h @@ -3,6 +3,6 @@ #include namespace JavaDownloader { - /*Downloads the java to the runtimes folder*/ - void downloadJava(bool isLegacy, const QString& OS); -} +/*Downloads the java to the runtimes folder*/ +void downloadJava(bool isLegacy, const QString& OS); +} // namespace JavaDownloader From a97387b692456cae3b13b48ea9e5901712334f4c Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 1 Jul 2022 09:37:23 +0200 Subject: [PATCH 04/83] Cherry-pick SysInfo from #680 Signed-off-by: timoreo --- launcher/CMakeLists.txt | 2 + launcher/SysInfo.cpp | 155 ++++++++++++++++++++++++++++++++++++++++ launcher/SysInfo.h | 13 ++++ 3 files changed, 170 insertions(+) create mode 100644 launcher/SysInfo.cpp create mode 100644 launcher/SysInfo.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 4e55085798..c4d9cb74f3 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -580,6 +580,8 @@ SET(LAUNCHER_SOURCES UpdateController.h ApplicationMessage.h ApplicationMessage.cpp + SysInfo.h + SysInfo.cpp # GUI - general utilities DesktopServices.h diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp new file mode 100644 index 0000000000..4abf39301d --- /dev/null +++ b/launcher/SysInfo.cpp @@ -0,0 +1,155 @@ +#include +#include +#include "settings/SettingsObject.h" +#ifdef Q_OS_MACOS +#include +#endif +#include +#include +#include +#include "MessageLevel.h" +#include +#include +#include +#include "java/JavaUtils.h" +#include "FileSystem.h" +#include "Commandline.h" +#include "Application.h" + +#ifdef Q_OS_MACOS +bool rosettaDetect() { + int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) + { + return false; + } + if(ret == 0) + { + return false; + } + if(ret == 1) + { + return true; + } + return false; +} +#endif + +namespace SysInfo { +QString currentSystem() { +#if defined(Q_OS_LINUX) + return "linux"; +#elif defined(Q_OS_MACOS) + return "osx"; +#elif defined(Q_OS_WINDOWS) + return "windows"; +#elif defined(Q_OS_FREEBSD) + return "freebsd"; +#elif defined(Q_OS_OPENBSD) + return "openbsd"; +#else + return "unknown"; +#endif +} + +QString useQTForArch(){ + auto qtArch = QSysInfo::currentCpuArchitecture(); +#if defined(Q_OS_MACOS) && !defined(Q_PROCESSOR_ARM) + if(rosettaDetect()) + { + return "arm64"; + } + else + { + return "x86_64"; + } +#endif + return qtArch; +} + +QString runCheckerForArch(const SettingsObjectPtr& settingsObj){ + QString checkerJar = FS::PathCombine(APPLICATION->getJarsPath(), "JavaCheck.jar"); + + QStringList args; + + QProcessPtr process = new QProcess(); + args.append({"-jar", checkerJar}); + process->setArguments(args); + process->setProgram(settingsObj->get("JavaPath").toString()); + process->setProcessChannelMode(QProcess::SeparateChannels); + process->setProcessEnvironment(CleanEnviroment()); + qDebug() << "Running java checker: " + settingsObj->get("JavaPath").toString() + args.join(" ");; + + process->start(); + if(!process->waitForFinished(15000)){ + // we've been waiting for 15 seconds! wtf! OR... it already finished. But HOW WOULD THAT HAPPEN? + process->kill(); // die. BUUURNNNN + // fallback to using polymc arch + return useQTForArch(); + } else { + // yay we can use the java arch + QString stdout_javaChecker; + QString stderr_javaChecker; + + // process stdout + QByteArray data = process->readAllStandardOutput(); + QString added = QString::fromLocal8Bit(data); + added.remove('\r'); + stdout_javaChecker += added; + + // process stderr + data = process->readAllStandardError(); + added = QString::fromLocal8Bit(data); + added.remove('\r'); + stderr_javaChecker += added; + + QMap results; + QStringList lines = stdout_javaChecker.split("\n", QString::SkipEmptyParts); + for(QString line : lines) + { + line = line.trimmed(); + // NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux + if (line.contains("/bedrock/strata")) { + continue; + } + + auto parts = line.split('=', QString::SkipEmptyParts); + if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) + { + continue; + } + else + { + results.insert(parts[0], parts[1]); + } + } + + if(!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor")) + { + // wtf man why + // fallback to using polymc arch + return useQTForArch(); + } + + return results["os.arch"]; + } +} + +QString currentArch(const SettingsObjectPtr& settingsObj) { + auto realJavaArchitecture = settingsObj->get("JavaRealArchitecture").toString(); + if(realJavaArchitecture == ""){ + //BRO WHY NOW I HAVE TO USE A JAVA CHECKER >:( + qDebug() << "SysInfo: BRO I HAVE TO USE A JAVA CHECKER WHY IS JAVA ARCH BORKED"; + settingsObj->set("JavaRealArchitecture", runCheckerForArch(settingsObj)); + realJavaArchitecture = settingsObj->get("JavaRealArchitecture").toString(); + } + //qDebug() << "SysInfo: realJavaArch = " << realJavaArchitecture; + if(realJavaArchitecture == "aarch64"){ + return "arm64"; + } else { + return realJavaArchitecture; + } +} +} + diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h new file mode 100644 index 0000000000..a4e41e674a --- /dev/null +++ b/launcher/SysInfo.h @@ -0,0 +1,13 @@ +#include +#include "settings/SettingsObject.h" +#ifdef Q_OS_MACOS +#include +#endif + +namespace SysInfo { +QString currentSystem(); +QString currentArch(const SettingsObjectPtr& settingsObj); +QString runCheckerForArch(const SettingsObjectPtr& settingsObj); +QString useQTForArch(); +} + From 98a82cd4847160f41e728403efee51ebc4d2b60a Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 1 Jul 2022 14:03:45 +0200 Subject: [PATCH 05/83] Fix MMCZip bugs Signed-off-by: timoreo --- launcher/MMCZip.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 9f4e968f77..3b5c444252 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -300,6 +300,11 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su name.remove(0, subdir.size()); auto original_name = name; + // Fix subdirs/files ending with a / getting transformed into absolute paths + if(name.startsWith('/')){ + name = name.mid(1); + } + // Fix weird "folders with a single file get squashed" thing QString path; if(name.contains('/') && !name.endsWith('/')){ @@ -319,6 +324,11 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su absFilePath = directory.absoluteFilePath(path + name); } + //Block potential file traversal issues + if(!absFilePath.startsWith(directory.absolutePath())){ + qWarning() << "Potential file traversal issue, for path " << absFilePath << " with base name as " << directory.absolutePath(); + continue; + } if (!JlCompress::extractFile(zip, "", absFilePath)) { qWarning() << "Failed to extract file" << original_name << "to" << absFilePath; From 89ce80b27960e66efccfaee20b3baf1596a8ba53 Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 1 Jul 2022 14:05:14 +0200 Subject: [PATCH 06/83] Fix Java downloader bugs + Add a test button in JavaPage Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 63 ++++++++++++++++----------- launcher/ui/pages/global/JavaPage.cpp | 41 +++++++++++++++++ launcher/ui/pages/global/JavaPage.h | 1 + launcher/ui/pages/global/JavaPage.ui | 11 ++++- 4 files changed, 88 insertions(+), 28 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 5c3d04a6df..3af69f025c 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -1,6 +1,7 @@ #include "JavaDownloader.h" #include "Application.h" #include "FileSystem.h" +#include "Json.h" #include "MMCZip.h" #include "net/ChecksumValidator.h" #include "net/NetJob.h" @@ -11,6 +12,7 @@ struct File { QString path; QString url; QByteArray hash; + bool isExec; }; void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) @@ -23,7 +25,7 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) netJob->deleteLater(); delete response; }); - QObject::connect(netJob, &NetJob::succeeded, [response, &OS, isLegacy] { + QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -31,7 +33,7 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) qWarning() << *response; return; } - auto versionArray = doc.object()[OS].toObject()[isLegacy ? "jre-legacy" : "java-runtime-gamma"].toArray(); + auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), OS), isLegacy ? "jre-legacy" : "java-runtime-gamma"); if (!versionArray.empty()) { auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); @@ -53,35 +55,37 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) } // valid json doc, begin making jre spot - auto output = - FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java/") + (isLegacy ? "java-legacy" : "java-current")); + auto output = FS::PathCombine(QString("java"), (isLegacy ? "java-legacy" : "java-current")); FS::ensureFolderPathExists(output); std::vector toDownload; auto list = doc.object()["files"].toObject(); - for (auto element : list) { - auto obj = element.toObject(); - for (const auto& paths : obj.keys()) { - auto file = FS::PathCombine(output, paths); + for (const auto& paths : list.keys()) { + auto file = FS::PathCombine(output, paths); - auto type = obj[paths].toObject()["type"].toString(); - if (type == "directory") { - FS::ensureFolderPathExists(file); - } else if (type == "link") { - // this is linux only ! - auto target = FS::PathCombine(file, "../" + obj[paths].toObject()["target"].toString()); - QFile(target).link(file); - } else if (type == "file") { - // TODO download compressed version if it exists ? - auto raw = obj[paths].toObject()["downloads"].toObject()["raw"].toObject(); - auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()) }; - toDownload.push_back(f); - } + auto type = list[paths].toObject()["type"].toString(); + if (type == "directory") { + FS::ensureFolderPathExists(file); + } else if (type == "link") { + // this is linux only ! + auto target = FS::PathCombine(file, "../" + list[paths].toObject()["target"].toString()); + QFile(target).link(file); + } else if (type == "file") { + // TODO download compressed version if it exists ? + auto raw = list[paths].toObject()["downloads"].toObject()["raw"].toObject(); + auto isExec = list[paths].toObject()["executable"].toBool(); + auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()), isExec }; + toDownload.push_back(f); } } auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); for (const auto& file : toDownload) { auto dl = Net::Download::makeFile(file.url, file.path); dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + if (file.isExec) { + QObject::connect(dl.get(), &Net::Download::succeeded, [file] { + QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); + }); + } elementDownload->addNetAction(dl); } QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); @@ -90,7 +94,7 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) download->start(); } else { // mojang does not have a JRE for us, let's get azul zulu - QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); + QString javaVersion = isLegacy ? QString("8.0") : QString("18.0"); QString azulOS; QString arch; QString bitness; @@ -100,11 +104,16 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) azulOS = "macos"; arch = "arm"; bitness = "64"; - } else if (OS == "linux-aarch64") { - // linux aarch64 + } else if (OS == "linux-arm64") { + // linux arm64 azulOS = "linux"; arch = "arm"; bitness = "64"; + } else if (OS == "linux-arm") { + // linux arm (32) + azulOS = "linux"; + arch = "arm"; + bitness = "32"; } auto metaResponse = new QByteArray(); auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); @@ -143,16 +152,18 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) download->addNetAction(Net::Download::makeCached(downloadURL, entry)); auto zippath = entry->getFullPath(); QObject::connect(download, &NetJob::finished, [download] { download->deleteLater(); }); - QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath] { + QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath, downloadURL] { auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), isLegacy ? "java-legacy" : "java-current"); // This should do all of the extracting and creating folders - MMCZip::extractDir(zippath, output); + MMCZip::extractDir(zippath, downloadURL.fileName().chopped(4), output); }); + download->start(); } else { qWarning() << "No suitable JRE found !!"; } }); + downloadJob->start(); } }); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 2cee15bf1b..a57a8ee068 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -52,6 +52,9 @@ #include #include "Application.h" #include +#include "SysInfo.h" +#include "JavaDownloader.h" + JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) { @@ -177,6 +180,44 @@ void JavaPage::on_javaTestBtn_clicked() checker->run(); } +void JavaPage::on_javaDownloadBtn_clicked(){ + QString sys = SysInfo::currentSystem(); + if(sys == "osx"){ + sys = "mac-os"; + } + QString arch = SysInfo::useQTForArch(); + QString version; + if(sys == "windows"){ + if(arch == "x86_64"){ + version = "windows-x64"; + }else if(arch == "i386"){ + version = "windows-x86"; + }else{ + //Unknown, maybe arm, appending arch for downloader + version = "windows-"+arch; + } + }else if(sys == "mac-os"){ + if(arch == "arm64"){ + version = "mac-os-arm64"; + }else{ + version = "mac-os"; + } + }else if(sys == "linux"){ + if(arch == "x86_64"){ + version = "linux"; + }else { + // will work for i386, and arm(64) + version = "linux-" + arch; + } + }else{ + // ? ? ? ? ? unknown os, at least it won't have a java version on mojang or azul, display warning + QMessageBox::warning(this, tr("Unknown OS"), tr("The OS you are running is not supported by Mojang or Azul. Please install Java manually.")); + return; + } + //TODO display a selection for java 8 or 18 + JavaDownloader::downloadJava(false, version); +} + void JavaPage::checkerFinished() { checker.reset(); diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 64d4098e5e..aa06dc0be0 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -85,6 +85,7 @@ private void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); + void on_javaDownloadBtn_clicked(); void checkerFinished(); private: diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 6ccffed4da..c109efbfc0 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -6,8 +6,8 @@ 0 0 - 545 - 580 + 559 + 659 @@ -279,6 +279,13 @@ + + + + Download Java + + + From 54ad91c3b79dbd3379e6f0e1c7bc76f149fc6794 Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 1 Jul 2022 14:18:34 +0200 Subject: [PATCH 07/83] Anti-scrumped Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 3af69f025c..09aeed5de9 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -168,4 +168,4 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) }); netJob->start(); -} \ No newline at end of file +} From 53ddba80778e7c232cd778c1eabc0bc36c3f6414 Mon Sep 17 00:00:00 2001 From: timoreo Date: Sun, 10 Jul 2022 19:56:52 +0200 Subject: [PATCH 08/83] Made JavaDownloader a task and added some quick UI Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 51 +++++++++++++++++---------- launcher/JavaDownloader.h | 17 ++++++--- launcher/ui/pages/global/JavaPage.cpp | 28 +++++++++++---- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 09aeed5de9..d72f66f36b 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -15,17 +15,21 @@ struct File { bool isExec; }; -void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) +void JavaDownloader::executeTask() { + auto OS = m_OS; + auto isLegacy = m_isLegacy; auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); auto response = new QByteArray(); + setStatus(tr("Querying mojang meta")); netJob->addNetAction(Net::Download::makeByteArray( QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); QObject::connect(netJob, &NetJob::finished, [netJob, response] { netJob->deleteLater(); delete response; }); - QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy] { + QObject::connect(netJob, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -35,6 +39,7 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) } auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), OS), isLegacy ? "jre-legacy" : "java-runtime-gamma"); if (!versionArray.empty()) { + setStatus(tr("Downloading java from Mojang")); auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = new QByteArray(); @@ -45,7 +50,8 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) download->deleteLater(); delete files; }); - QObject::connect(download, &NetJob::succeeded, [files, isLegacy] { + QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(download, &NetJob::succeeded, [files, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -89,12 +95,14 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) elementDownload->addNetAction(dl); } QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); + QObject::connect(elementDownload, &NetJob::succeeded, [this]{emitSucceeded();}); elementDownload->start(); }); download->start(); } else { // mojang does not have a JRE for us, let's get azul zulu - QString javaVersion = isLegacy ? QString("8.0") : QString("18.0"); + setStatus(tr("Querying Azul meta")); + QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); QString azulOS; QString arch; QString bitness; @@ -117,23 +125,24 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) } auto metaResponse = new QByteArray(); auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); - downloadJob->addNetAction(Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" - "java_version=%1" - "&os=%2" - "&arch=%3" - "&hw_bitness=%4" - "&ext=zip" // as a zip for all os, even linux - "&bundle_type=jre" // jre only - "&latest=true" // only get the one latest entry - ) - .arg(javaVersion, azulOS, arch, bitness), - metaResponse)); + downloadJob->addNetAction( + Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" + "java_version=%1" + "&os=%2" + "&arch=%3" + "&hw_bitness=%4" + "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb only !! + "&bundle_type=jre" // jre only + "&latest=true" // only get the one latest entry + ) + .arg(javaVersion, azulOS, arch, bitness), + metaResponse)); QObject::connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse] { downloadJob->deleteLater(); delete metaResponse; }); - - QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy] { + QObject::connect(downloadJob, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -144,6 +153,7 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) auto array = doc.array(); if (!array.empty()) { // JRE found ! download the zip + setStatus(tr("Downloading java from Azul")); auto downloadURL = QUrl(array[0].toObject()["url"].toString()); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); const QString path = downloadURL.host() + '/' + downloadURL.path(); @@ -152,15 +162,18 @@ void JavaDownloader::downloadJava(bool isLegacy, const QString& OS) download->addNetAction(Net::Download::makeCached(downloadURL, entry)); auto zippath = entry->getFullPath(); QObject::connect(download, &NetJob::finished, [download] { download->deleteLater(); }); - QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath, downloadURL] { + QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath, downloadURL, this] { + setStatus(tr("Extracting java")); auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), isLegacy ? "java-legacy" : "java-current"); // This should do all of the extracting and creating folders MMCZip::extractDir(zippath, downloadURL.fileName().chopped(4), output); + emitSucceeded(); }); download->start(); } else { - qWarning() << "No suitable JRE found !!"; + emitFailed(tr("No suitable JRE found")); } }); downloadJob->start(); diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h index 3dd57eebe6..3b7a7c425d 100644 --- a/launcher/JavaDownloader.h +++ b/launcher/JavaDownloader.h @@ -1,8 +1,17 @@ #pragma once #include +#include "tasks/Task.h" -namespace JavaDownloader { -/*Downloads the java to the runtimes folder*/ -void downloadJava(bool isLegacy, const QString& OS); -} // namespace JavaDownloader +class JavaDownloader : public Task { + Q_OBJECT + public: + /*Downloads the java to the runtimes folder*/ + explicit JavaDownloader(bool isLegacy, const QString& OS) : m_isLegacy(isLegacy), m_OS(OS) {} + + void executeTask() override; + + private: + bool m_isLegacy; + const QString& m_OS; +}; diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index a57a8ee068..2cc627b7d5 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -48,13 +48,14 @@ #include "java/JavaUtils.h" #include "java/JavaInstallList.h" -#include "settings/SettingsObject.h" #include -#include "Application.h" #include -#include "SysInfo.h" +#include "Application.h" #include "JavaDownloader.h" - +#include "SysInfo.h" +#include "settings/SettingsObject.h" +#include "ui/dialogs/ProgressDialog.h" +#include JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) { @@ -214,8 +215,23 @@ void JavaPage::on_javaDownloadBtn_clicked(){ QMessageBox::warning(this, tr("Unknown OS"), tr("The OS you are running is not supported by Mojang or Azul. Please install Java manually.")); return; } - //TODO display a selection for java 8 or 18 - JavaDownloader::downloadJava(false, version); + //Selection using QMessageBox for java 8 or 17 + QMessageBox box(QMessageBox::Icon::Question, tr("Java version"), tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for minecraft versions below 1.17\n Java 17 is recommended for minecraft versions above or equal to 1.17"), + QMessageBox::NoButton, this); + box.addButton("Java 17", QMessageBox::YesRole); + auto no = box.addButton("Java 8", QMessageBox::NoRole); + auto cancel = box.addButton(tr("Download both"), QMessageBox::AcceptRole); + box.exec(); + bool isLegacy = box.clickedButton() == no; + + auto down = new JavaDownloader(isLegacy, version); + ProgressDialog dialog(this); + dialog.execWithTask(down); + if(box.clickedButton() == cancel) { + auto dwn = new JavaDownloader(false, version); + ProgressDialog dg(this); + dg.execWithTask(dwn); + } } void JavaPage::checkerFinished() From f946964490c181700cbc0b1b479fd6089f4ba02e Mon Sep 17 00:00:00 2001 From: timoreo Date: Sun, 10 Jul 2022 20:21:52 +0200 Subject: [PATCH 09/83] Regrab a few changes on SysInfo Signed-off-by: timoreo --- launcher/CMakeLists.txt | 2 ++ launcher/SysInfo.cpp | 32 ++++++++++++++++------- launcher/SysInfo.h | 9 +++---- launcher/minecraft/LaunchContext.cpp | 39 ++++++++++++++++++++++++++++ launcher/minecraft/LaunchContext.h | 34 ++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 launcher/minecraft/LaunchContext.cpp create mode 100644 launcher/minecraft/LaunchContext.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c4d9cb74f3..c467957a89 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -271,6 +271,8 @@ set(MINECRAFT_SOURCES minecraft/GradleSpecifier.h minecraft/MinecraftInstance.cpp minecraft/MinecraftInstance.h + minecraft/LaunchContext.cpp + minecraft/LaunchContext.h minecraft/LaunchProfile.cpp minecraft/LaunchProfile.h minecraft/Component.cpp diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp index 4abf39301d..010eb84c8d 100644 --- a/launcher/SysInfo.cpp +++ b/launcher/SysInfo.cpp @@ -1,6 +1,6 @@ #include #include -#include "settings/SettingsObject.h" +#include "minecraft/LaunchContext.h" #ifdef Q_OS_MACOS #include #endif @@ -68,18 +68,24 @@ QString useQTForArch(){ return qtArch; } -QString runCheckerForArch(const SettingsObjectPtr& settingsObj){ - QString checkerJar = FS::PathCombine(APPLICATION->getJarsPath(), "JavaCheck.jar"); +QString runCheckerForArch(LaunchContext launchContext){ + QString checkerJar = JavaUtils::getJavaCheckPath(); + + if (checkerJar.isEmpty()) + { + qDebug() << "Java checker library could not be found. Please check your installation."; + return useQTForArch(); + } QStringList args; QProcessPtr process = new QProcess(); args.append({"-jar", checkerJar}); process->setArguments(args); - process->setProgram(settingsObj->get("JavaPath").toString()); + process->setProgram(launchContext.getJavaPath().toString()); process->setProcessChannelMode(QProcess::SeparateChannels); process->setProcessEnvironment(CleanEnviroment()); - qDebug() << "Running java checker: " + settingsObj->get("JavaPath").toString() + args.join(" ");; + qDebug() << "Running java checker: " + launchContext.getJavaPath().toString() + args.join(" ");; process->start(); if(!process->waitForFinished(15000)){ @@ -105,7 +111,11 @@ QString runCheckerForArch(const SettingsObjectPtr& settingsObj){ stderr_javaChecker += added; QMap results; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + QStringList lines = stdout_javaChecker.split("\n", Qt::SkipEmptyParts); +#else QStringList lines = stdout_javaChecker.split("\n", QString::SkipEmptyParts); +#endif for(QString line : lines) { line = line.trimmed(); @@ -114,7 +124,11 @@ QString runCheckerForArch(const SettingsObjectPtr& settingsObj){ continue; } +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + auto parts = line.split('=', Qt::SkipEmptyParts); +#else auto parts = line.split('=', QString::SkipEmptyParts); +#endif if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) { continue; @@ -136,13 +150,13 @@ QString runCheckerForArch(const SettingsObjectPtr& settingsObj){ } } -QString currentArch(const SettingsObjectPtr& settingsObj) { - auto realJavaArchitecture = settingsObj->get("JavaRealArchitecture").toString(); +QString currentArch(LaunchContext launchContext) { + auto realJavaArchitecture = launchContext.getRealJavaArch().toString(); if(realJavaArchitecture == ""){ //BRO WHY NOW I HAVE TO USE A JAVA CHECKER >:( qDebug() << "SysInfo: BRO I HAVE TO USE A JAVA CHECKER WHY IS JAVA ARCH BORKED"; - settingsObj->set("JavaRealArchitecture", runCheckerForArch(settingsObj)); - realJavaArchitecture = settingsObj->get("JavaRealArchitecture").toString(); + launchContext.setRealJavaArch(runCheckerForArch(launchContext)); + realJavaArchitecture = launchContext.getRealJavaArch().toString(); } //qDebug() << "SysInfo: realJavaArch = " << realJavaArchitecture; if(realJavaArchitecture == "aarch64"){ diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h index a4e41e674a..2807576743 100644 --- a/launcher/SysInfo.h +++ b/launcher/SysInfo.h @@ -1,13 +1,12 @@ #include -#include "settings/SettingsObject.h" +#include "minecraft/LaunchContext.h" #ifdef Q_OS_MACOS #include #endif namespace SysInfo { QString currentSystem(); -QString currentArch(const SettingsObjectPtr& settingsObj); -QString runCheckerForArch(const SettingsObjectPtr& settingsObj); +QString currentArch(LaunchContext launchContext); +QString runCheckerForArch(LaunchContext launchContext); QString useQTForArch(); -} - +} \ No newline at end of file diff --git a/launcher/minecraft/LaunchContext.cpp b/launcher/minecraft/LaunchContext.cpp new file mode 100644 index 0000000000..b445d9ae17 --- /dev/null +++ b/launcher/minecraft/LaunchContext.cpp @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Toshit Chawda + * + * 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 "LaunchContext.h" + +LaunchContext::LaunchContext(SettingsObjectPtr instanceSettings){ + m_instanceSettings = instanceSettings; +} + +void LaunchContext::setRealJavaArch(QVariant realJavaArch) +{ + m_instanceSettings->set("JavaRealArchitecture", realJavaArch); +} + +QVariant LaunchContext::getRealJavaArch() +{ + return m_instanceSettings->get("JavaRealArchitecture"); +} + +QVariant LaunchContext::getJavaPath() +{ + return m_instanceSettings->get("JavaPath"); +} \ No newline at end of file diff --git a/launcher/minecraft/LaunchContext.h b/launcher/minecraft/LaunchContext.h new file mode 100644 index 0000000000..0d322a2eab --- /dev/null +++ b/launcher/minecraft/LaunchContext.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Toshit Chawda + * + * 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 +#include "settings/SettingsObject.h" + +#pragma once + +class LaunchContext +{ + public: + LaunchContext(SettingsObjectPtr instanceSettings); + void setRealJavaArch(QVariant realJavaArch); + QVariant getRealJavaArch(); + QVariant getJavaPath(); + private: + SettingsObjectPtr m_instanceSettings; +}; \ No newline at end of file From 68446c2a5442d568a75229d63d6addc502237b4a Mon Sep 17 00:00:00 2001 From: timoreo Date: Sun, 10 Jul 2022 20:34:29 +0200 Subject: [PATCH 10/83] Obligatory formatting fix commit Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 2 +- launcher/SysInfo.h | 2 +- launcher/minecraft/LaunchContext.cpp | 2 +- launcher/minecraft/LaunchContext.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index d72f66f36b..2cca83a9b6 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -95,7 +95,7 @@ void JavaDownloader::executeTask() elementDownload->addNetAction(dl); } QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); - QObject::connect(elementDownload, &NetJob::succeeded, [this]{emitSucceeded();}); + QObject::connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); }); download->start(); diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h index 2807576743..9107cacb8b 100644 --- a/launcher/SysInfo.h +++ b/launcher/SysInfo.h @@ -9,4 +9,4 @@ QString currentSystem(); QString currentArch(LaunchContext launchContext); QString runCheckerForArch(LaunchContext launchContext); QString useQTForArch(); -} \ No newline at end of file +} diff --git a/launcher/minecraft/LaunchContext.cpp b/launcher/minecraft/LaunchContext.cpp index b445d9ae17..ea6a549f0e 100644 --- a/launcher/minecraft/LaunchContext.cpp +++ b/launcher/minecraft/LaunchContext.cpp @@ -36,4 +36,4 @@ QVariant LaunchContext::getRealJavaArch() QVariant LaunchContext::getJavaPath() { return m_instanceSettings->get("JavaPath"); -} \ No newline at end of file +} diff --git a/launcher/minecraft/LaunchContext.h b/launcher/minecraft/LaunchContext.h index 0d322a2eab..2c6e1307f8 100644 --- a/launcher/minecraft/LaunchContext.h +++ b/launcher/minecraft/LaunchContext.h @@ -31,4 +31,4 @@ class LaunchContext QVariant getJavaPath(); private: SettingsObjectPtr m_instanceSettings; -}; \ No newline at end of file +}; From 24dc154856cc45b78404b47fa085f8ea0a1adeb0 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 11 Jul 2022 15:11:08 +0200 Subject: [PATCH 11/83] Add download button to more pages + UI fixes Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 79 +++++++++++++++++++ launcher/JavaDownloader.h | 1 + launcher/ui/pages/global/JavaPage.cpp | 57 +------------ .../pages/instance/InstanceSettingsPage.cpp | 6 ++ .../ui/pages/instance/InstanceSettingsPage.h | 1 + .../ui/pages/instance/InstanceSettingsPage.ui | 7 ++ launcher/ui/widgets/JavaSettingsWidget.cpp | 11 +++ launcher/ui/widgets/JavaSettingsWidget.h | 3 + 8 files changed, 111 insertions(+), 54 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 2cca83a9b6..cb8fd11167 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -1,11 +1,15 @@ #include "JavaDownloader.h" +#include +#include #include "Application.h" #include "FileSystem.h" #include "Json.h" #include "MMCZip.h" +#include "SysInfo.h" #include "net/ChecksumValidator.h" #include "net/NetJob.h" #include "quazip.h" +#include "ui/dialogs/ProgressDialog.h" // Quick & dirty struct to store files struct File { @@ -95,6 +99,7 @@ void JavaDownloader::executeTask() elementDownload->addNetAction(dl); } QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); + QObject::connect(elementDownload, &NetJob::progress, this, &JavaDownloader::progress); QObject::connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); }); @@ -182,3 +187,77 @@ void JavaDownloader::executeTask() netJob->start(); } +void JavaDownloader::showPrompts(QWidget* parent) +{ + QString sys = SysInfo::currentSystem(); + if (sys == "osx") { + sys = "mac-os"; + } + QString arch = SysInfo::useQTForArch(); + QString version; + if (sys == "windows") { + if (arch == "x86_64") { + version = "windows-x64"; + } else if (arch == "i386") { + version = "windows-x86"; + } else { + // Unknown, maybe arm, appending arch for downloader + version = "windows-" + arch; + } + } else if (sys == "mac-os") { + if (arch == "arm64") { + version = "mac-os-arm64"; + } else { + version = "mac-os"; + } + } else if (sys == "linux") { + if (arch == "x86_64") { + version = "linux"; + } else { + // will work for i386, and arm(64) + version = "linux-" + arch; + } + } else { + // ? ? ? ? ? unknown os, at least it won't have a java version on mojang or azul, display warning + QMessageBox::warning(parent, tr("Unknown OS"), + tr("The OS you are running is not supported by Mojang or Azul. Please install Java manually.")); + return; + } + // Selection using QMessageBox for java 8 or 17 + QMessageBox box(QMessageBox::Icon::Question, tr("Java version"), + tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for minecraft versions below 1.17\n Java 17 " + "is recommended for minecraft versions above or equal to 1.17"), + QMessageBox::NoButton, parent); + auto yes = box.addButton("Java 17", QMessageBox::AcceptRole); + auto no = box.addButton("Java 8", QMessageBox::AcceptRole); + auto both = box.addButton(tr("Download both"), QMessageBox::AcceptRole); + auto cancel = box.addButton(QMessageBox::Cancel); + + if (QFileInfo::exists(FS::PathCombine(QString("java"), "java-legacy"))) { + no->setEnabled(false); + } + if (QFileInfo::exists(FS::PathCombine(QString("java"), "java-current"))) { + yes->setEnabled(false); + } + if (!yes->isEnabled() || !no->isEnabled()) { + both->setEnabled(false); + } + if (!yes->isEnabled() && !no->isEnabled()) { + QMessageBox::warning(parent, tr("Already installed !"), tr("Both versions of java are already installed !")); + return; + } + box.exec(); + if (box.clickedButton() == nullptr || box.clickedButton() == cancel) { + return; + } + bool isLegacy = box.clickedButton() == no; + + auto down = new JavaDownloader(isLegacy, version); + ProgressDialog dialog(parent); + dialog.execWithTask(down); + if (box.clickedButton() == both) { + auto dwn = new JavaDownloader(false, version); + ProgressDialog dg(parent); + dg.execWithTask(dwn); + } +} diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h index 3b7a7c425d..274a95e49f 100644 --- a/launcher/JavaDownloader.h +++ b/launcher/JavaDownloader.h @@ -10,6 +10,7 @@ class JavaDownloader : public Task { explicit JavaDownloader(bool isLegacy, const QString& OS) : m_isLegacy(isLegacy), m_OS(OS) {} void executeTask() override; + static void showPrompts(QWidget* parent = nullptr); private: bool m_isLegacy; diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 2cc627b7d5..d7f48f552b 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -52,10 +52,7 @@ #include #include "Application.h" #include "JavaDownloader.h" -#include "SysInfo.h" #include "settings/SettingsObject.h" -#include "ui/dialogs/ProgressDialog.h" -#include JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) { @@ -181,57 +178,9 @@ void JavaPage::on_javaTestBtn_clicked() checker->run(); } -void JavaPage::on_javaDownloadBtn_clicked(){ - QString sys = SysInfo::currentSystem(); - if(sys == "osx"){ - sys = "mac-os"; - } - QString arch = SysInfo::useQTForArch(); - QString version; - if(sys == "windows"){ - if(arch == "x86_64"){ - version = "windows-x64"; - }else if(arch == "i386"){ - version = "windows-x86"; - }else{ - //Unknown, maybe arm, appending arch for downloader - version = "windows-"+arch; - } - }else if(sys == "mac-os"){ - if(arch == "arm64"){ - version = "mac-os-arm64"; - }else{ - version = "mac-os"; - } - }else if(sys == "linux"){ - if(arch == "x86_64"){ - version = "linux"; - }else { - // will work for i386, and arm(64) - version = "linux-" + arch; - } - }else{ - // ? ? ? ? ? unknown os, at least it won't have a java version on mojang or azul, display warning - QMessageBox::warning(this, tr("Unknown OS"), tr("The OS you are running is not supported by Mojang or Azul. Please install Java manually.")); - return; - } - //Selection using QMessageBox for java 8 or 17 - QMessageBox box(QMessageBox::Icon::Question, tr("Java version"), tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for minecraft versions below 1.17\n Java 17 is recommended for minecraft versions above or equal to 1.17"), - QMessageBox::NoButton, this); - box.addButton("Java 17", QMessageBox::YesRole); - auto no = box.addButton("Java 8", QMessageBox::NoRole); - auto cancel = box.addButton(tr("Download both"), QMessageBox::AcceptRole); - box.exec(); - bool isLegacy = box.clickedButton() == no; - - auto down = new JavaDownloader(isLegacy, version); - ProgressDialog dialog(this); - dialog.execWithTask(down); - if(box.clickedButton() == cancel) { - auto dwn = new JavaDownloader(false, version); - ProgressDialog dg(this); - dg.execWithTask(dwn); - } +void JavaPage::on_javaDownloadBtn_clicked() +{ + JavaDownloader::showPrompts(this); } void JavaPage::checkerFinished() diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 5da7f19f56..62e780ce82 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -49,6 +49,7 @@ #include "JavaCommon.h" #include "Application.h" +#include "JavaDownloader.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" #include "FileSystem.h" @@ -374,6 +375,11 @@ void InstanceSettingsPage::loadSettings() ui->serverJoinAddress->setText(m_settings->get("JoinServerOnLaunchAddress").toString()); } +void InstanceSettingsPage::on_javaDownloadBtn_clicked() +{ + JavaDownloader::showPrompts(this); +} + void InstanceSettingsPage::on_javaDetectBtn_clicked() { if (JavaUtils::getJavaCheckPath().isEmpty()) { diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 97d1296fe7..ffb226781a 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -81,6 +81,7 @@ private slots: void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); + void on_javaDownloadBtn_clicked(); void applySettings(); void loadSettings(); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 8b3c337026..4ce59a0aec 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -95,6 +95,13 @@ + + + + Download Java... + + + diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 314a126e45..e62cdd1f07 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -14,6 +14,7 @@ #include "JavaCommon.h" #include "java/JavaInstall.h" #include "java/JavaUtils.h" +#include "JavaDownloader.h" #include "FileSystem.h" #include "ui/dialogs/CustomMessageBox.h" @@ -38,6 +39,8 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked); connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); + connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); + } void JavaSettingsWidget::setupUi() @@ -115,6 +118,10 @@ void JavaSettingsWidget::setupUi() m_verticalLayout->addWidget(m_memoryGroupBox); + m_javaDownloadBtn = new QPushButton("Download Java",this); + + m_verticalLayout->addWidget(m_javaDownloadBtn); + retranslate(); } @@ -276,7 +283,11 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() m_javaPathTextBox->setText(cooked_path); checkJavaPath(cooked_path); } +void JavaSettingsWidget::on_javaDownloadBtn_clicked() +{ + JavaDownloader::showPrompts(this); +} void JavaSettingsWidget::on_javaStatusBtn_clicked() { QString text; diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 0d280daf3d..fe6ee2f584 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -63,6 +63,7 @@ protected slots: void javaVersionSelected(BaseVersionPtr version); void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); + void on_javaDownloadBtn_clicked(); void checkFinished(JavaCheckResult result); protected: /* methods */ @@ -88,6 +89,8 @@ protected slots: QSpinBox *m_minMemSpinBox = nullptr; QLabel *m_labelPermGen = nullptr; QSpinBox *m_permGenSpinBox = nullptr; + + QPushButton *m_javaDownloadBtn = nullptr; QIcon goodIcon; QIcon yellowIcon; QIcon badIcon; From a902f29ccff347f1c51ab95330748cb6e71d1539 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 08:19:42 +0200 Subject: [PATCH 12/83] Changed to a temporary file Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 21 ++++++++++++++------- launcher/ui/widgets/JavaSettingsWidget.cpp | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index cb8fd11167..e56a87d0c0 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -1,6 +1,7 @@ #include "JavaDownloader.h" #include #include +#include #include "Application.h" #include "FileSystem.h" #include "Json.h" @@ -127,6 +128,11 @@ void JavaDownloader::executeTask() azulOS = "linux"; arch = "arm"; bitness = "32"; + } else if (OS == "linux"){ + // linux x86 64 (used for debugging, should never reach here) + azulOS = "linux"; + arch = "x86"; + bitness = "64"; } auto metaResponse = new QByteArray(); auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); @@ -161,19 +167,20 @@ void JavaDownloader::executeTask() setStatus(tr("Downloading java from Azul")); auto downloadURL = QUrl(array[0].toObject()["url"].toString()); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - const QString path = downloadURL.host() + '/' + downloadURL.path(); - auto entry = APPLICATION->metacache()->resolveEntry("general", path); - entry->setStale(true); - download->addNetAction(Net::Download::makeCached(downloadURL, entry)); - auto zippath = entry->getFullPath(); + auto temp = std::make_unique(FS::PathCombine(APPLICATION->root(), "temp", "XXXXXX.zip")); + FS::ensureFolderPathExists(FS::PathCombine(APPLICATION->root(),"temp")); + // Have to open at least once to generate path + temp->open(); + temp->close(); + download->addNetAction(Net::Download::makeFile(downloadURL, temp->fileName())); QObject::connect(download, &NetJob::finished, [download] { download->deleteLater(); }); QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(download, &NetJob::succeeded, [isLegacy, zippath, downloadURL, this] { + QObject::connect(download, &NetJob::succeeded, [isLegacy, file = std::move(temp), downloadURL, this] { setStatus(tr("Extracting java")); auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), isLegacy ? "java-legacy" : "java-current"); // This should do all of the extracting and creating folders - MMCZip::extractDir(zippath, downloadURL.fileName().chopped(4), output); + MMCZip::extractDir(file->fileName(), downloadURL.fileName().chopped(4), output); emitSucceeded(); }); download->start(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index e62cdd1f07..6494b79fd4 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -118,7 +118,7 @@ void JavaSettingsWidget::setupUi() m_verticalLayout->addWidget(m_memoryGroupBox); - m_javaDownloadBtn = new QPushButton("Download Java",this); + m_javaDownloadBtn = new QPushButton(tr("Download Java"), this); m_verticalLayout->addWidget(m_javaDownloadBtn); From dc84a6199932fed417796ec1183598669b4dde2f Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 14:17:41 +0200 Subject: [PATCH 13/83] Added failed and aborted handlers Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 61 +++++++++++++++++++++++++++++++------ launcher/JavaDownloader.h | 3 ++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index e56a87d0c0..b0cde7d986 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -24,17 +24,29 @@ void JavaDownloader::executeTask() { auto OS = m_OS; auto isLegacy = m_isLegacy; + auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); auto response = new QByteArray(); setStatus(tr("Querying mojang meta")); netJob->addNetAction(Net::Download::makeByteArray( QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - QObject::connect(netJob, &NetJob::finished, [netJob, response] { + + QObject::connect(this, &Task::aborted, [isLegacy]{ + QDir(FS::PathCombine("java",(isLegacy ? "java-legacy" : "java-current"))).removeRecursively(); + }); + + QObject::connect(netJob, &NetJob::finished, [netJob, response, this] { + //delete so that it's not called on a deleted job + QObject::disconnect(this, &Task::aborted, netJob, &NetJob::abort); netJob->deleteLater(); delete response; }); QObject::connect(netJob, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this] { + QObject::connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); + + QObject::connect(this, &Task::aborted, netJob, &NetJob::abort); + + QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -51,12 +63,16 @@ void JavaDownloader::executeTask() download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); - QObject::connect(download, &NetJob::finished, [download, files] { + QObject::connect(download, &NetJob::finished, [download, files, this] { + QObject::disconnect(this, &Task::aborted, download, &NetJob::abort); download->deleteLater(); delete files; }); QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(download, &NetJob::succeeded, [files, isLegacy, this] { + QObject::connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); + QObject::connect(this, &Task::aborted, download, &NetJob::abort); + + QObject::connect(download, &NetJob::succeeded, [download, files, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -99,8 +115,15 @@ void JavaDownloader::executeTask() } elementDownload->addNetAction(dl); } - QObject::connect(elementDownload, &NetJob::finished, [elementDownload] { elementDownload->deleteLater(); }); + QObject::connect(elementDownload, &NetJob::finished, [elementDownload, this] { + QObject::disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); + elementDownload->deleteLater(); + }); QObject::connect(elementDownload, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(elementDownload, &NetJob::failed, this, &JavaDownloader::emitFailed); + + + QObject::connect(this, &Task::aborted, elementDownload, &NetJob::abort); QObject::connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); }); @@ -148,12 +171,15 @@ void JavaDownloader::executeTask() ) .arg(javaVersion, azulOS, arch, bitness), metaResponse)); - QObject::connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse] { + QObject::connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse, this] { + QObject::disconnect(this, &Task::aborted, downloadJob, &NetJob::abort); downloadJob->deleteLater(); delete metaResponse; }); + QObject::connect(this, &Task::aborted, downloadJob, &NetJob::abort); + QObject::connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); QObject::connect(downloadJob, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this] { + QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this, downloadJob] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -173,8 +199,13 @@ void JavaDownloader::executeTask() temp->open(); temp->close(); download->addNetAction(Net::Download::makeFile(downloadURL, temp->fileName())); - QObject::connect(download, &NetJob::finished, [download] { download->deleteLater(); }); + QObject::connect(download, &NetJob::finished, [download, this] { + QObject::disconnect(this, &Task::aborted, download, &NetJob::abort); + download->deleteLater(); + }); QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); + QObject::connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); + QObject::connect(this, &Task::aborted, download, &NetJob::abort); QObject::connect(download, &NetJob::succeeded, [isLegacy, file = std::move(temp), downloadURL, this] { setStatus(tr("Extracting java")); auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), @@ -194,6 +225,14 @@ void JavaDownloader::executeTask() netJob->start(); } +void JavaDownloader::abortNetJob(NetJob* elementDownload) +{ + if(elementDownload->isRunning()){ + elementDownload->abort(); + }else{ + emit elementDownload->aborted(); + } +} void JavaDownloader::showPrompts(QWidget* parent) { QString sys = SysInfo::currentSystem(); @@ -261,10 +300,12 @@ void JavaDownloader::showPrompts(QWidget* parent) auto down = new JavaDownloader(isLegacy, version); ProgressDialog dialog(parent); - dialog.execWithTask(down); - if (box.clickedButton() == both) { + dialog.setSkipButton(true, tr("Abort")); + + if (dialog.execWithTask(down) && box.clickedButton() == both) { auto dwn = new JavaDownloader(false, version); ProgressDialog dg(parent); + dg.setSkipButton(true, tr("Abort")); dg.execWithTask(dwn); } } diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h index 274a95e49f..00ccdf2bc2 100644 --- a/launcher/JavaDownloader.h +++ b/launcher/JavaDownloader.h @@ -1,6 +1,7 @@ #pragma once #include +#include "net/NetJob.h" #include "tasks/Task.h" class JavaDownloader : public Task { @@ -10,9 +11,11 @@ class JavaDownloader : public Task { explicit JavaDownloader(bool isLegacy, const QString& OS) : m_isLegacy(isLegacy), m_OS(OS) {} void executeTask() override; + [[nodiscard]] bool canAbort() const override { return true; } static void showPrompts(QWidget* parent = nullptr); private: bool m_isLegacy; const QString& m_OS; + static void abortNetJob(NetJob* elementDownload); }; From 89f1b60538068ac033f7ca1899b4d310eb43f8c2 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 15:00:31 +0200 Subject: [PATCH 14/83] Delete out non-needed functions from SysInfo Delete LaunchContext Signed-off-by: timoreo --- launcher/CMakeLists.txt | 4 +- launcher/SysInfo.cpp | 103 --------------------------- launcher/SysInfo.h | 6 -- launcher/minecraft/LaunchContext.cpp | 39 ---------- launcher/minecraft/LaunchContext.h | 34 --------- 5 files changed, 1 insertion(+), 185 deletions(-) delete mode 100644 launcher/minecraft/LaunchContext.cpp delete mode 100644 launcher/minecraft/LaunchContext.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c467957a89..4bb686106d 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -271,9 +271,7 @@ set(MINECRAFT_SOURCES minecraft/GradleSpecifier.h minecraft/MinecraftInstance.cpp minecraft/MinecraftInstance.h - minecraft/LaunchContext.cpp - minecraft/LaunchContext.h - minecraft/LaunchProfile.cpp + minecraft/LaunchProfile.cpp minecraft/LaunchProfile.h minecraft/Component.cpp minecraft/Component.h diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp index 010eb84c8d..f3ff200fca 100644 --- a/launcher/SysInfo.cpp +++ b/launcher/SysInfo.cpp @@ -1,18 +1,13 @@ #include #include -#include "minecraft/LaunchContext.h" #ifdef Q_OS_MACOS #include #endif -#include #include -#include -#include "MessageLevel.h" #include #include #include #include "java/JavaUtils.h" -#include "FileSystem.h" #include "Commandline.h" #include "Application.h" @@ -67,103 +62,5 @@ QString useQTForArch(){ #endif return qtArch; } - -QString runCheckerForArch(LaunchContext launchContext){ - QString checkerJar = JavaUtils::getJavaCheckPath(); - - if (checkerJar.isEmpty()) - { - qDebug() << "Java checker library could not be found. Please check your installation."; - return useQTForArch(); - } - - QStringList args; - - QProcessPtr process = new QProcess(); - args.append({"-jar", checkerJar}); - process->setArguments(args); - process->setProgram(launchContext.getJavaPath().toString()); - process->setProcessChannelMode(QProcess::SeparateChannels); - process->setProcessEnvironment(CleanEnviroment()); - qDebug() << "Running java checker: " + launchContext.getJavaPath().toString() + args.join(" ");; - - process->start(); - if(!process->waitForFinished(15000)){ - // we've been waiting for 15 seconds! wtf! OR... it already finished. But HOW WOULD THAT HAPPEN? - process->kill(); // die. BUUURNNNN - // fallback to using polymc arch - return useQTForArch(); - } else { - // yay we can use the java arch - QString stdout_javaChecker; - QString stderr_javaChecker; - - // process stdout - QByteArray data = process->readAllStandardOutput(); - QString added = QString::fromLocal8Bit(data); - added.remove('\r'); - stdout_javaChecker += added; - - // process stderr - data = process->readAllStandardError(); - added = QString::fromLocal8Bit(data); - added.remove('\r'); - stderr_javaChecker += added; - - QMap results; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QStringList lines = stdout_javaChecker.split("\n", Qt::SkipEmptyParts); -#else - QStringList lines = stdout_javaChecker.split("\n", QString::SkipEmptyParts); -#endif - for(QString line : lines) - { - line = line.trimmed(); - // NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux - if (line.contains("/bedrock/strata")) { - continue; - } - -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - auto parts = line.split('=', Qt::SkipEmptyParts); -#else - auto parts = line.split('=', QString::SkipEmptyParts); -#endif - if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) - { - continue; - } - else - { - results.insert(parts[0], parts[1]); - } - } - - if(!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor")) - { - // wtf man why - // fallback to using polymc arch - return useQTForArch(); - } - - return results["os.arch"]; - } -} - -QString currentArch(LaunchContext launchContext) { - auto realJavaArchitecture = launchContext.getRealJavaArch().toString(); - if(realJavaArchitecture == ""){ - //BRO WHY NOW I HAVE TO USE A JAVA CHECKER >:( - qDebug() << "SysInfo: BRO I HAVE TO USE A JAVA CHECKER WHY IS JAVA ARCH BORKED"; - launchContext.setRealJavaArch(runCheckerForArch(launchContext)); - realJavaArchitecture = launchContext.getRealJavaArch().toString(); - } - //qDebug() << "SysInfo: realJavaArch = " << realJavaArchitecture; - if(realJavaArchitecture == "aarch64"){ - return "arm64"; - } else { - return realJavaArchitecture; - } -} } diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h index 9107cacb8b..3cb1c8de69 100644 --- a/launcher/SysInfo.h +++ b/launcher/SysInfo.h @@ -1,12 +1,6 @@ #include -#include "minecraft/LaunchContext.h" -#ifdef Q_OS_MACOS -#include -#endif namespace SysInfo { QString currentSystem(); -QString currentArch(LaunchContext launchContext); -QString runCheckerForArch(LaunchContext launchContext); QString useQTForArch(); } diff --git a/launcher/minecraft/LaunchContext.cpp b/launcher/minecraft/LaunchContext.cpp deleted file mode 100644 index ea6a549f0e..0000000000 --- a/launcher/minecraft/LaunchContext.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (C) 2022 Toshit Chawda - * - * 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 "LaunchContext.h" - -LaunchContext::LaunchContext(SettingsObjectPtr instanceSettings){ - m_instanceSettings = instanceSettings; -} - -void LaunchContext::setRealJavaArch(QVariant realJavaArch) -{ - m_instanceSettings->set("JavaRealArchitecture", realJavaArch); -} - -QVariant LaunchContext::getRealJavaArch() -{ - return m_instanceSettings->get("JavaRealArchitecture"); -} - -QVariant LaunchContext::getJavaPath() -{ - return m_instanceSettings->get("JavaPath"); -} diff --git a/launcher/minecraft/LaunchContext.h b/launcher/minecraft/LaunchContext.h deleted file mode 100644 index 2c6e1307f8..0000000000 --- a/launcher/minecraft/LaunchContext.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (C) 2022 Toshit Chawda - * - * 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 -#include "settings/SettingsObject.h" - -#pragma once - -class LaunchContext -{ - public: - LaunchContext(SettingsObjectPtr instanceSettings); - void setRealJavaArch(QVariant realJavaArch); - QVariant getRealJavaArch(); - QVariant getJavaPath(); - private: - SettingsObjectPtr m_instanceSettings; -}; From 86e3518430917483f35777a25a76159274e72d38 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 16:34:37 +0200 Subject: [PATCH 15/83] Apply most of the suggestions from @flowln Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 360 ++++++++++++++++++------------------ launcher/JavaDownloader.h | 10 +- 2 files changed, 194 insertions(+), 176 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index b0cde7d986..425a7d4705 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -9,7 +9,6 @@ #include "SysInfo.h" #include "net/ChecksumValidator.h" #include "net/NetJob.h" -#include "quazip.h" #include "ui/dialogs/ProgressDialog.h" // Quick & dirty struct to store files @@ -25,28 +24,31 @@ void JavaDownloader::executeTask() auto OS = m_OS; auto isLegacy = m_isLegacy; + downloadMojangJavaList(OS, isLegacy); +} +void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) +{ auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); auto response = new QByteArray(); setStatus(tr("Querying mojang meta")); netJob->addNetAction(Net::Download::makeByteArray( QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - QObject::connect(this, &Task::aborted, [isLegacy]{ - QDir(FS::PathCombine("java",(isLegacy ? "java-legacy" : "java-current"))).removeRecursively(); - }); + connect(this, &Task::aborted, + [isLegacy] { QDir(FS::PathCombine("java", (isLegacy ? "java-legacy" : "java-current"))).removeRecursively(); }); - QObject::connect(netJob, &NetJob::finished, [netJob, response, this] { - //delete so that it's not called on a deleted job - QObject::disconnect(this, &Task::aborted, netJob, &NetJob::abort); + connect(netJob, &NetJob::finished, [netJob, response, this] { + // delete so that it's not called on a deleted job + disconnect(this, &Task::aborted, netJob, &NetJob::abort); netJob->deleteLater(); delete response; }); - QObject::connect(netJob, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(netJob, &NetJob::progress, this, &JavaDownloader::progress); + connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); - QObject::connect(this, &Task::aborted, netJob, &NetJob::abort); + connect(this, &Task::aborted, netJob, &NetJob::abort); - QObject::connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { + connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -56,183 +58,191 @@ void JavaDownloader::executeTask() } auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), OS), isLegacy ? "jre-legacy" : "java-runtime-gamma"); if (!versionArray.empty()) { - setStatus(tr("Downloading java from Mojang")); - auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); - auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - auto files = new QByteArray(); + parseMojangManifest(isLegacy, versionArray); + + } else { + // mojang does not have a JRE for us, let's get azul zulu + downloadAzulMeta(OS, isLegacy, netJob); + } + }); + + netJob->start(); +} +void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versionArray) +{ + setStatus(tr("Downloading java from Mojang")); + auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); + auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); + auto files = new QByteArray(); - download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); + download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); - QObject::connect(download, &NetJob::finished, [download, files, this] { - QObject::disconnect(this, &Task::aborted, download, &NetJob::abort); - download->deleteLater(); - delete files; - }); - QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); - QObject::connect(this, &Task::aborted, download, &NetJob::abort); + connect(download, &NetJob::finished, [download, files, this] { + disconnect(this, &Task::aborted, download, &NetJob::abort); + download->deleteLater(); + delete files; + }); + connect(download, &NetJob::progress, this, &JavaDownloader::progress); + connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(this, &Task::aborted, download, &NetJob::abort); - QObject::connect(download, &NetJob::succeeded, [download, files, isLegacy, this] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *files; - return; - } + connect(download, &NetJob::succeeded, [files, isLegacy, this] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << *files; + return; + } + downloadMojangJava(isLegacy, doc); + }); + download->start(); +} +void JavaDownloader::downloadMojangJava(bool isLegacy, const QJsonDocument& doc) +{ // valid json doc, begin making jre spot + auto output = FS::PathCombine(QString("java"), (isLegacy ? "java-legacy" : "java-current")); + FS::ensureFolderPathExists(output); + std::vector toDownload; + auto list = doc.object()["files"].toObject(); + for (const auto& paths : list.keys()) { + auto file = FS::PathCombine(output, paths); - // valid json doc, begin making jre spot - auto output = FS::PathCombine(QString("java"), (isLegacy ? "java-legacy" : "java-current")); - FS::ensureFolderPathExists(output); - std::vector toDownload; - auto list = doc.object()["files"].toObject(); - for (const auto& paths : list.keys()) { - auto file = FS::PathCombine(output, paths); + auto type = list[paths].toObject()["type"].toString(); + if (type == "directory") { + FS::ensureFolderPathExists(file); + } else if (type == "link") { + // this is linux only ! + auto target = FS::PathCombine(file, "../" + list[paths].toObject()["target"].toString()); + QFile(target).link(file); + } else if (type == "file") { + // TODO download compressed version if it exists ? + auto raw = list[paths].toObject()["downloads"].toObject()["raw"].toObject(); + auto isExec = list[paths].toObject()["executable"].toBool(); + auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()), isExec }; + toDownload.push_back(f); + } + } + auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); + for (const auto& file : toDownload) { + auto dl = Net::Download::makeFile(file.url, file.path); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + if (file.isExec) { + connect(dl.get(), &Net::Download::succeeded, + [file] { QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); }); + } + elementDownload->addNetAction(dl); + } + connect(elementDownload, &NetJob::finished, [elementDownload, this] { + disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); + elementDownload->deleteLater(); + }); + connect(elementDownload, &NetJob::progress, this, &JavaDownloader::progress); + connect(elementDownload, &NetJob::failed, this, &JavaDownloader::emitFailed); - auto type = list[paths].toObject()["type"].toString(); - if (type == "directory") { - FS::ensureFolderPathExists(file); - } else if (type == "link") { - // this is linux only ! - auto target = FS::PathCombine(file, "../" + list[paths].toObject()["target"].toString()); - QFile(target).link(file); - } else if (type == "file") { - // TODO download compressed version if it exists ? - auto raw = list[paths].toObject()["downloads"].toObject()["raw"].toObject(); - auto isExec = list[paths].toObject()["executable"].toBool(); - auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()), isExec }; - toDownload.push_back(f); - } - } - auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); - for (const auto& file : toDownload) { - auto dl = Net::Download::makeFile(file.url, file.path); - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); - if (file.isExec) { - QObject::connect(dl.get(), &Net::Download::succeeded, [file] { - QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); - }); - } - elementDownload->addNetAction(dl); - } - QObject::connect(elementDownload, &NetJob::finished, [elementDownload, this] { - QObject::disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); - elementDownload->deleteLater(); - }); - QObject::connect(elementDownload, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(elementDownload, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(this, &Task::aborted, elementDownload, &NetJob::abort); + connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); + elementDownload->start(); +} +void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const NetJob* netJob) +{ + setStatus(tr("Querying Azul meta")); + QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); + QString azulOS; + QString arch; + QString bitness; - QObject::connect(this, &Task::aborted, elementDownload, &NetJob::abort); - QObject::connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); - elementDownload->start(); - }); - download->start(); + mojangOStoAzul(OS, azulOS, arch, bitness); + auto metaResponse = new QByteArray(); + auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); + downloadJob->addNetAction( + Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" + "java_version=%1" + "&os=%2" + "&arch=%3" + "&hw_bitness=%4" + "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb only !! + "&bundle_type=jre" // jre only + "&latest=true" // only get the one latest entry + ) + .arg(javaVersion, azulOS, arch, bitness), + metaResponse)); + connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse, this] { + disconnect(this, &Task::aborted, downloadJob, &NetJob::abort); + downloadJob->deleteLater(); + delete metaResponse; + }); + connect(this, &Task::aborted, downloadJob, &NetJob::abort); + connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(downloadJob, &NetJob::progress, this, &JavaDownloader::progress); + connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << *metaResponse; + return; + } + auto array = doc.array(); + if (!array.empty()) { + downloadAzulJava(isLegacy, array); } else { - // mojang does not have a JRE for us, let's get azul zulu - setStatus(tr("Querying Azul meta")); - QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); - QString azulOS; - QString arch; - QString bitness; - - if (OS == "mac-os-arm64") { - // macos arm64 - azulOS = "macos"; - arch = "arm"; - bitness = "64"; - } else if (OS == "linux-arm64") { - // linux arm64 - azulOS = "linux"; - arch = "arm"; - bitness = "64"; - } else if (OS == "linux-arm") { - // linux arm (32) - azulOS = "linux"; - arch = "arm"; - bitness = "32"; - } else if (OS == "linux"){ - // linux x86 64 (used for debugging, should never reach here) - azulOS = "linux"; - arch = "x86"; - bitness = "64"; - } - auto metaResponse = new QByteArray(); - auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); - downloadJob->addNetAction( - Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" - "java_version=%1" - "&os=%2" - "&arch=%3" - "&hw_bitness=%4" - "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb only !! - "&bundle_type=jre" // jre only - "&latest=true" // only get the one latest entry - ) - .arg(javaVersion, azulOS, arch, bitness), - metaResponse)); - QObject::connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse, this] { - QObject::disconnect(this, &Task::aborted, downloadJob, &NetJob::abort); - downloadJob->deleteLater(); - delete metaResponse; - }); - QObject::connect(this, &Task::aborted, downloadJob, &NetJob::abort); - QObject::connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); - QObject::connect(downloadJob, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this, downloadJob] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *metaResponse; - return; - } - auto array = doc.array(); - if (!array.empty()) { - // JRE found ! download the zip - setStatus(tr("Downloading java from Azul")); - auto downloadURL = QUrl(array[0].toObject()["url"].toString()); - auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - auto temp = std::make_unique(FS::PathCombine(APPLICATION->root(), "temp", "XXXXXX.zip")); - FS::ensureFolderPathExists(FS::PathCombine(APPLICATION->root(),"temp")); - // Have to open at least once to generate path - temp->open(); - temp->close(); - download->addNetAction(Net::Download::makeFile(downloadURL, temp->fileName())); - QObject::connect(download, &NetJob::finished, [download, this] { - QObject::disconnect(this, &Task::aborted, download, &NetJob::abort); - download->deleteLater(); - }); - QObject::connect(download, &NetJob::progress, this, &JavaDownloader::progress); - QObject::connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); - QObject::connect(this, &Task::aborted, download, &NetJob::abort); - QObject::connect(download, &NetJob::succeeded, [isLegacy, file = std::move(temp), downloadURL, this] { - setStatus(tr("Extracting java")); - auto output = FS::PathCombine(FS::PathCombine(QCoreApplication::applicationDirPath(), "java"), - isLegacy ? "java-legacy" : "java-current"); - // This should do all of the extracting and creating folders - MMCZip::extractDir(file->fileName(), downloadURL.fileName().chopped(4), output); - emitSucceeded(); - }); - download->start(); - } else { - emitFailed(tr("No suitable JRE found")); - } - }); - downloadJob->start(); + emitFailed(tr("No suitable JRE found")); } }); - - netJob->start(); + downloadJob->start(); } -void JavaDownloader::abortNetJob(NetJob* elementDownload) +void JavaDownloader::mojangOStoAzul(const QString& OS, QString& azulOS, QString& arch, QString& bitness) { - if(elementDownload->isRunning()){ - elementDownload->abort(); - }else{ - emit elementDownload->aborted(); + if (OS == "mac-os-arm64") { + // macos arm64 + azulOS = "macos"; + arch = "arm"; + bitness = "64"; + } else if (OS == "linux-arm64") { + // linux arm64 + azulOS = "linux"; + arch = "arm"; + bitness = "64"; + } else if (OS == "linux-arm") { + // linux arm (32) + azulOS = "linux"; + arch = "arm"; + bitness = "32"; + } else if (OS == "linux") { + // linux x86 64 (used for debugging, should never reach here) + azulOS = "linux"; + arch = "x86"; + bitness = "64"; } } +void JavaDownloader::downloadAzulJava(bool isLegacy, const QJsonArray& array) +{ // JRE found ! download the zip + setStatus(tr("Downloading java from Azul")); + auto downloadURL = QUrl(array[0].toObject()["url"].toString()); + auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); + auto temp = std::make_unique(FS::PathCombine(APPLICATION->root(), "temp", "XXXXXX.zip")); + FS::ensureFolderPathExists(FS::PathCombine(APPLICATION->root(), "temp")); + // Have to open at least once to generate path + temp->open(); + temp->close(); + download->addNetAction(Net::Download::makeFile(downloadURL, temp->fileName())); + connect(download, &NetJob::finished, [download, this] { + disconnect(this, &Task::aborted, download, &NetJob::abort); + download->deleteLater(); + }); + connect(download, &NetJob::progress, this, &JavaDownloader::progress); + connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(this, &Task::aborted, download, &NetJob::abort); + connect(download, &NetJob::succeeded, [isLegacy, file = std::move(temp), downloadURL, this] { + setStatus(tr("Extracting java")); + auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), "java", isLegacy ? "java-legacy" : "java-current"); + // This should do all of the extracting and creating folders + MMCZip::extractDir(file->fileName(), downloadURL.fileName().chopped(4), output); + emitSucceeded(); + }); + download->start(); +} void JavaDownloader::showPrompts(QWidget* parent) { QString sys = SysInfo::currentSystem(); @@ -289,7 +299,7 @@ void JavaDownloader::showPrompts(QWidget* parent) both->setEnabled(false); } if (!yes->isEnabled() && !no->isEnabled()) { - QMessageBox::warning(parent, tr("Already installed !"), tr("Both versions of java are already installed !")); + QMessageBox::warning(parent, tr("Already installed!"), tr("Both versions of java are already installed!")); return; } box.exec(); diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h index 00ccdf2bc2..6ed67263a1 100644 --- a/launcher/JavaDownloader.h +++ b/launcher/JavaDownloader.h @@ -17,5 +17,13 @@ class JavaDownloader : public Task { private: bool m_isLegacy; const QString& m_OS; - static void abortNetJob(NetJob* elementDownload); + + void downloadMojangJavaList(const QString& OS, bool isLegacy); + void parseMojangManifest(bool isLegacy, const QJsonArray& versionArray); + void downloadMojangJava(bool isLegacy, const QJsonDocument& doc); + + static void mojangOStoAzul(const QString& OS, QString& azulOS, QString& arch, QString& bitness) ; + void downloadAzulMeta(const QString& OS, bool isLegacy, const NetJob* netJob); + void downloadAzulJava(bool isLegacy, const QJsonArray& array); + }; From a65f20a78920efdb974b78f0c72df95d401ad337 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 17:21:55 +0200 Subject: [PATCH 16/83] Fix a tiny formatting issue Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: timoreo --- launcher/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 4bb686106d..c4d9cb74f3 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -271,7 +271,7 @@ set(MINECRAFT_SOURCES minecraft/GradleSpecifier.h minecraft/MinecraftInstance.cpp minecraft/MinecraftInstance.h - minecraft/LaunchProfile.cpp + minecraft/LaunchProfile.cpp minecraft/LaunchProfile.h minecraft/Component.cpp minecraft/Component.h From dcbd6cc1afe3495908511fb9179dd27fe8a70c98 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 12 Sep 2022 19:31:07 +0200 Subject: [PATCH 17/83] More Json:: everywhere ! Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 425a7d4705..d0b8c5240c 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -71,7 +71,7 @@ void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versionArray) { setStatus(tr("Downloading java from Mojang")); - auto url = versionArray[0].toObject()["manifest"].toObject()["url"].toString(); + auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = new QByteArray(); @@ -103,22 +103,22 @@ void JavaDownloader::downloadMojangJava(bool isLegacy, const QJsonDocument& doc) auto output = FS::PathCombine(QString("java"), (isLegacy ? "java-legacy" : "java-current")); FS::ensureFolderPathExists(output); std::vector toDownload; - auto list = doc.object()["files"].toObject(); + auto list = Json::ensureObject(Json::ensureObject(doc.object()), "files"); for (const auto& paths : list.keys()) { auto file = FS::PathCombine(output, paths); - auto type = list[paths].toObject()["type"].toString(); + auto type = Json::requireString(Json::requireObject(list, paths), "type"); if (type == "directory") { FS::ensureFolderPathExists(file); } else if (type == "link") { // this is linux only ! - auto target = FS::PathCombine(file, "../" + list[paths].toObject()["target"].toString()); + auto target = FS::PathCombine(file, "../" + Json::requireString(Json::requireObject(list, paths), "target")); QFile(target).link(file); } else if (type == "file") { // TODO download compressed version if it exists ? - auto raw = list[paths].toObject()["downloads"].toObject()["raw"].toObject(); - auto isExec = list[paths].toObject()["executable"].toBool(); - auto f = File{ file, raw["url"].toString(), QByteArray::fromHex(raw["sha1"].toString().toLatin1()), isExec }; + auto raw = Json::requireObject(Json::requireObject(Json::requireObject(list, paths), "downloads"), "raw"); + auto isExec = Json::ensureBoolean(Json::requireObject(list, paths), "executable", false); + auto f = File{ file, Json::requireString(raw, "url"), QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec }; toDownload.push_back(f); } } @@ -183,7 +183,7 @@ void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const Ne qWarning() << *metaResponse; return; } - auto array = doc.array(); + auto array = Json::ensureArray(doc.array()); if (!array.empty()) { downloadAzulJava(isLegacy, array); } else { From 6a5db12c6a3350b74eb9cd75a526881bc5b68572 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 24 Oct 2022 14:55:51 +0200 Subject: [PATCH 18/83] Apply some more suggestions from @flowln Co-authored-by: flow Signed-off-by: timoreo --- launcher/JavaDownloader.cpp | 82 +++++++++++-------- .../ui/pages/instance/InstanceSettingsPage.ui | 34 ++++---- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index d0b8c5240c..165573599d 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -2,8 +2,10 @@ #include #include #include +#include #include "Application.h" #include "FileSystem.h" +#include "InstanceList.h" #include "Json.h" #include "MMCZip.h" #include "SysInfo.h" @@ -34,8 +36,10 @@ void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) netJob->addNetAction(Net::Download::makeByteArray( QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - connect(this, &Task::aborted, - [isLegacy] { QDir(FS::PathCombine("java", (isLegacy ? "java-legacy" : "java-current"))).removeRecursively(); }); + connect(this, &Task::aborted, [isLegacy] { + QDir(FS::PathCombine(QCoreApplication::applicationDirPath(), "java", (isLegacy ? "java-legacy" : "java-current"))) + .removeRecursively(); + }); connect(netJob, &NetJob::finished, [netJob, response, this] { // delete so that it's not called on a deleted job @@ -70,7 +74,7 @@ void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) } void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versionArray) { - setStatus(tr("Downloading java from Mojang")); + setStatus(tr("Downloading Java from Mojang")); auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = new QByteArray(); @@ -100,32 +104,41 @@ void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versio } void JavaDownloader::downloadMojangJava(bool isLegacy, const QJsonDocument& doc) { // valid json doc, begin making jre spot - auto output = FS::PathCombine(QString("java"), (isLegacy ? "java-legacy" : "java-current")); + auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), (isLegacy ? "java-legacy" : "java-current")); FS::ensureFolderPathExists(output); std::vector toDownload; auto list = Json::ensureObject(Json::ensureObject(doc.object()), "files"); for (const auto& paths : list.keys()) { auto file = FS::PathCombine(output, paths); - auto type = Json::requireString(Json::requireObject(list, paths), "type"); + const QJsonObject& meta = Json::ensureObject(list, paths); + auto type = Json::ensureString(meta, "type"); if (type == "directory") { FS::ensureFolderPathExists(file); } else if (type == "link") { // this is linux only ! - auto target = FS::PathCombine(file, "../" + Json::requireString(Json::requireObject(list, paths), "target")); - QFile(target).link(file); + auto path = Json::ensureString(meta, "target"); + if (!path.isEmpty()) { + auto target = FS::PathCombine(file, "../" + path); + QFile(target).link(file); + } } else if (type == "file") { // TODO download compressed version if it exists ? - auto raw = Json::requireObject(Json::requireObject(Json::requireObject(list, paths), "downloads"), "raw"); - auto isExec = Json::ensureBoolean(Json::requireObject(list, paths), "executable", false); - auto f = File{ file, Json::requireString(raw, "url"), QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec }; - toDownload.push_back(f); + auto raw = Json::ensureObject(Json::ensureObject(meta, "downloads"), "raw"); + auto isExec = Json::ensureBoolean(meta, "executable", false); + auto url = Json::ensureString(raw, "url"); + if (!url.isEmpty() && QUrl(url).isValid()) { + auto f = File{ file, url, QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec }; + toDownload.push_back(f); + } } } auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); for (const auto& file : toDownload) { auto dl = Net::Download::makeFile(file.url, file.path); - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + if (!file.hash.isEmpty()) { + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + } if (file.isExec) { connect(dl.get(), &Net::Download::succeeded, [file] { QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); }); @@ -161,7 +174,7 @@ void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const Ne "&os=%2" "&arch=%3" "&hw_bitness=%4" - "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb only !! + "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb or .tar.gz only !! "&bundle_type=jre" // jre only "&latest=true" // only get the one latest entry ) @@ -218,27 +231,30 @@ void JavaDownloader::mojangOStoAzul(const QString& OS, QString& azulOS, QString& } void JavaDownloader::downloadAzulJava(bool isLegacy, const QJsonArray& array) { // JRE found ! download the zip - setStatus(tr("Downloading java from Azul")); + setStatus(tr("Downloading Java from Azul")); auto downloadURL = QUrl(array[0].toObject()["url"].toString()); auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - auto temp = std::make_unique(FS::PathCombine(APPLICATION->root(), "temp", "XXXXXX.zip")); - FS::ensureFolderPathExists(FS::PathCombine(APPLICATION->root(), "temp")); - // Have to open at least once to generate path - temp->open(); - temp->close(); - download->addNetAction(Net::Download::makeFile(downloadURL, temp->fileName())); + auto path = APPLICATION->instances()->getStagedInstancePath(); + auto temp = FS::PathCombine(path, "azulJRE.zip"); + + download->addNetAction(Net::Download::makeFile(downloadURL, temp)); connect(download, &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download, &NetJob::abort); download->deleteLater(); }); + connect(download, &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); connect(download, &NetJob::progress, this, &JavaDownloader::progress); - connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(download, &NetJob::failed, this, [this, path](QString reason) { + APPLICATION->instances()->destroyStagingPath(path); + emitFailed(std::move(reason)); + }); connect(this, &Task::aborted, download, &NetJob::abort); - connect(download, &NetJob::succeeded, [isLegacy, file = std::move(temp), downloadURL, this] { + connect(download, &NetJob::succeeded, [isLegacy, temp, downloadURL, path, this] { setStatus(tr("Extracting java")); auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), "java", isLegacy ? "java-legacy" : "java-current"); // This should do all of the extracting and creating folders - MMCZip::extractDir(file->fileName(), downloadURL.fileName().chopped(4), output); + MMCZip::extractDir(temp, downloadURL.fileName().chopped(4), output); + APPLICATION->instances()->destroyStagingPath(path); emitSucceeded(); }); download->start(); @@ -280,26 +296,27 @@ void JavaDownloader::showPrompts(QWidget* parent) return; } // Selection using QMessageBox for java 8 or 17 - QMessageBox box(QMessageBox::Icon::Question, tr("Java version"), - tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for minecraft versions below 1.17\n Java 17 " - "is recommended for minecraft versions above or equal to 1.17"), - QMessageBox::NoButton, parent); + QMessageBox box( + QMessageBox::Icon::Question, tr("Java version"), + tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for older Minecraft versions, below 1.17\n Java 17 " + "is recommended for newer Minecraft versions, starting from 1.17"), + QMessageBox::NoButton, parent); auto yes = box.addButton("Java 17", QMessageBox::AcceptRole); auto no = box.addButton("Java 8", QMessageBox::AcceptRole); auto both = box.addButton(tr("Download both"), QMessageBox::AcceptRole); auto cancel = box.addButton(QMessageBox::Cancel); - if (QFileInfo::exists(FS::PathCombine(QString("java"), "java-legacy"))) { + if (QFileInfo::exists(FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), "java-legacy"))) { no->setEnabled(false); } - if (QFileInfo::exists(FS::PathCombine(QString("java"), "java-current"))) { + if (QFileInfo::exists(FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), "java-current"))) { yes->setEnabled(false); } if (!yes->isEnabled() || !no->isEnabled()) { both->setEnabled(false); } if (!yes->isEnabled() && !no->isEnabled()) { - QMessageBox::warning(parent, tr("Already installed!"), tr("Both versions of java are already installed!")); + QMessageBox::information(parent, tr("Already installed!"), tr("Both versions of Java are already installed!")); return; } box.exec(); @@ -311,8 +328,9 @@ void JavaDownloader::showPrompts(QWidget* parent) auto down = new JavaDownloader(isLegacy, version); ProgressDialog dialog(parent); dialog.setSkipButton(true, tr("Abort")); - - if (dialog.execWithTask(down) && box.clickedButton() == both) { + bool finished_successfully = dialog.execWithTask(down); + // Run another download task for the other option as well! + if (finished_successfully && box.clickedButton() == both) { auto dwn = new JavaDownloader(false, version); ProgressDialog dg(parent); dg.setSkipButton(true, tr("Abort")); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 4ce59a0aec..a28332d5af 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -61,9 +61,6 @@ false - - - @@ -71,31 +68,34 @@ - - + + + + If enabled, the launcher will not check if an instance is compatible with the selected Java version. + - Browse... + Skip Java compatibility checks - - + + + + + - Test + Browse... - - - - If enabled, the launcher will not check if an instance is compatible with the selected Java version. - + + - Skip Java compatibility checks + Test - + Download Java... @@ -635,8 +635,6 @@ javaSettingsGroupBox javaPathTextBox javaDetectBtn - javaBrowseBtn - javaTestBtn memoryGroupBox minMemSpinBox maxMemSpinBox From ce6a36c8b57fb9eb0a22c4f70b74e8fa200a88ad Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 28 Jul 2023 14:31:53 +0100 Subject: [PATCH 19/83] Deduplicate fix Signed-off-by: TheKodeToad --- launcher/MMCZip.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 49fd0e707d..1a336375b0 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -315,11 +315,6 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su if (relative_file_name.startsWith('/')) relative_file_name = relative_file_name.mid(1); - // Fix subdirs/files ending with a / getting transformed into absolute paths - if(name.startsWith('/')){ - name = name.mid(1); - } - // Fix weird "folders with a single file get squashed" thing QString sub_path; if (relative_file_name.contains('/') && !relative_file_name.endsWith('/')) { From 5538c1d0afba06d1a639dca45e88b0e94a3742f0 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 28 Jul 2023 15:11:24 +0100 Subject: [PATCH 20/83] Fix compilation (actually this time!), incorporating new changes Signed-off-by: TheKodeToad --- launcher/JavaDownloader.cpp | 55 +++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp index 165573599d..f5960bbe93 100644 --- a/launcher/JavaDownloader.cpp +++ b/launcher/JavaDownloader.cpp @@ -30,8 +30,8 @@ void JavaDownloader::executeTask() } void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) { - auto netJob = new NetJob(QString("JRE::QueryVersions"), APPLICATION->network()); - auto response = new QByteArray(); + auto netJob = makeShared(QString("JRE::QueryVersions"), APPLICATION->network()); + auto response = std::make_shared(); setStatus(tr("Querying mojang meta")); netJob->addNetAction(Net::Download::makeByteArray( QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); @@ -41,18 +41,17 @@ void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) .removeRecursively(); }); - connect(netJob, &NetJob::finished, [netJob, response, this] { + connect(netJob.get(), &NetJob::finished, [netJob, response, this] { // delete so that it's not called on a deleted job - disconnect(this, &Task::aborted, netJob, &NetJob::abort); - netJob->deleteLater(); - delete response; + // FIXME: is this needed? qt should handle this + disconnect(this, &Task::aborted, netJob.get(), &NetJob::abort); }); - connect(netJob, &NetJob::progress, this, &JavaDownloader::progress); - connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(netJob.get(), &NetJob::progress, this, &JavaDownloader::progress); + connect(netJob.get(), &NetJob::failed, this, &JavaDownloader::emitFailed); - connect(this, &Task::aborted, netJob, &NetJob::abort); + connect(this, &Task::aborted, netJob.get(), &NetJob::abort); - connect(netJob, &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { + connect(netJob.get(), &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -66,7 +65,7 @@ void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) } else { // mojang does not have a JRE for us, let's get azul zulu - downloadAzulMeta(OS, isLegacy, netJob); + downloadAzulMeta(OS, isLegacy, netJob.get()); } }); @@ -76,21 +75,19 @@ void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versio { setStatus(tr("Downloading Java from Mojang")); auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); - auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - auto files = new QByteArray(); + auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); + auto files = std::make_shared(); download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); - connect(download, &NetJob::finished, [download, files, this] { - disconnect(this, &Task::aborted, download, &NetJob::abort); - download->deleteLater(); - delete files; + connect(download.get(), &NetJob::finished, [download, files, this] { + disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download, &NetJob::progress, this, &JavaDownloader::progress); - connect(download, &NetJob::failed, this, &JavaDownloader::emitFailed); - connect(this, &Task::aborted, download, &NetJob::abort); + connect(download.get(), &NetJob::progress, this, &JavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &JavaDownloader::emitFailed); + connect(this, &Task::aborted, download.get(), &NetJob::abort); - connect(download, &NetJob::succeeded, [files, isLegacy, this] { + connect(download.get(), &NetJob::succeeded, [files, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -166,8 +163,8 @@ void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const Ne QString bitness; mojangOStoAzul(OS, azulOS, arch, bitness); - auto metaResponse = new QByteArray(); - auto downloadJob = new NetJob(QString("JRE::QueryAzulMeta"), APPLICATION->network()); + auto metaResponse = std::make_shared(); + auto downloadJob = makeShared(QString("JRE::QueryAzulMeta"), APPLICATION->network()); downloadJob->addNetAction( Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" "java_version=%1" @@ -180,15 +177,13 @@ void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const Ne ) .arg(javaVersion, azulOS, arch, bitness), metaResponse)); - connect(downloadJob, &NetJob::finished, [downloadJob, metaResponse, this] { - disconnect(this, &Task::aborted, downloadJob, &NetJob::abort); - downloadJob->deleteLater(); - delete metaResponse; + connect(downloadJob.get(), &NetJob::finished, [downloadJob, metaResponse, this] { + disconnect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); }); - connect(this, &Task::aborted, downloadJob, &NetJob::abort); + connect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); - connect(downloadJob, &NetJob::progress, this, &JavaDownloader::progress); - connect(downloadJob, &NetJob::succeeded, [metaResponse, isLegacy, this] { + connect(downloadJob.get(), &NetJob::progress, this, &JavaDownloader::progress); + connect(downloadJob.get(), &NetJob::succeeded, [metaResponse, isLegacy, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); if (parse_error.error != QJsonParseError::NoError) { From f3baa420b2154c37a8f418a090c4392d526482c2 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 16 Aug 2023 13:43:07 +0100 Subject: [PATCH 21/83] Fix broken tab order Signed-off-by: TheKodeToad --- launcher/ui/pages/global/JavaPage.ui | 8 +++++++- launcher/ui/pages/instance/InstanceSettingsPage.ui | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 44289eb86c..0bf27fef1c 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -320,8 +320,14 @@ minMemSpinBox maxMemSpinBox permGenSpinBox - javaBrowseBtn javaPathTextBox + javaBrowseBtn + javaDownloadBtn + javaDetectBtn + javaTestBtn + skipCompatibilityCheckbox + skipJavaWizardCheckbox + jvmArgsTextBox tabWidget diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index f9e679b2eb..08a74671c6 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -714,6 +714,12 @@ openGlobalJavaSettingsButton settingsTabs javaSettingsGroupBox + javaPathTextBox + javaBrowseBtn + javaDownloadBtn + javaDetectBtn + javaTestBtn + skipCompatibilityCheckbox memoryGroupBox minMemSpinBox maxMemSpinBox @@ -733,12 +739,6 @@ useNativeOpenALCheck showGameTime recordGameTime - skipCompatibilityCheckbox - javaPathTextBox - javaBrowseBtn - javaDownloadBtn - javaDetectBtn - javaTestBtn miscellaneousSettingsBox closeAfterLaunchCheck quitAfterGameStopCheck From 33cf7066b403e1438fd3c9dd36e33bf5e84c5f29 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 27 Oct 2023 21:51:35 +0300 Subject: [PATCH 22/83] formated the code Signed-off-by: Trial97 --- launcher/ui/widgets/JavaSettingsWidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 3c0352b13b..63d7aa57ca 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -40,7 +40,6 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); - } void JavaSettingsWidget::setupUi() @@ -274,7 +273,6 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() void JavaSettingsWidget::on_javaDownloadBtn_clicked() { JavaDownloader::showPrompts(this); - } void JavaSettingsWidget::on_javaStatusBtn_clicked() { From a0e7729aa62a5bb6a83e401dd863e69cbd886edc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 24 Jan 2024 18:26:43 +0200 Subject: [PATCH 23/83] Started workin on stuff Signed-off-by: Trial97 --- launcher/Application.cpp | 18 +- launcher/Application.h | 2 - launcher/CMakeLists.txt | 2 - launcher/JavaCommon.cpp | 30 ++- launcher/JavaCommon.h | 12 +- launcher/MMCZip.cpp | 106 ++++++++++ launcher/MMCZip.h | 28 +++ launcher/SysInfo.cpp | 18 +- launcher/SysInfo.h | 1 + launcher/java/JavaChecker.cpp | 39 ++-- launcher/java/JavaChecker.h | 64 +++--- launcher/java/JavaCheckerJob.cpp | 41 ---- launcher/java/JavaCheckerJob.h | 56 ------ launcher/java/JavaInstallList.cpp | 37 ++-- launcher/java/JavaInstallList.h | 12 +- launcher/java/JavaUtils.h | 5 +- .../java/providers/AdoptiumJavaDownloader.cpp | 119 +++++++++++ .../java/providers/AdoptiumJavaDownloader.h | 36 ++++ .../java/providers/AzulJavaDownloader.cpp | 159 +++++++++++++++ launcher/java/providers/AzulJavaDownloader.h | 37 ++++ .../java/providers/BasicJavaDownloader.cpp | 29 +++ launcher/java/providers/BasicJavaDownloader.h | 41 ++++ .../java/providers/MojangJavaDownloader.cpp | 185 ++++++++++++++++++ .../java/providers/MojanglJavaDownloader.h | 37 ++++ launcher/launch/steps/CheckJava.cpp | 14 +- launcher/launch/steps/CheckJava.h | 4 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 21 +- launcher/ui/widgets/JavaSettingsWidget.h | 4 +- 28 files changed, 909 insertions(+), 248 deletions(-) delete mode 100644 launcher/java/JavaCheckerJob.cpp delete mode 100644 launcher/java/JavaCheckerJob.h create mode 100644 launcher/java/providers/AdoptiumJavaDownloader.cpp create mode 100644 launcher/java/providers/AdoptiumJavaDownloader.h create mode 100644 launcher/java/providers/AzulJavaDownloader.cpp create mode 100644 launcher/java/providers/AzulJavaDownloader.h create mode 100644 launcher/java/providers/BasicJavaDownloader.cpp create mode 100644 launcher/java/providers/BasicJavaDownloader.h create mode 100644 launcher/java/providers/MojangJavaDownloader.cpp create mode 100644 launcher/java/providers/MojanglJavaDownloader.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 661c6c5be3..aa702aa7ea 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -44,6 +44,7 @@ #include "BuildConfig.h" #include "DataMigrationTask.h" +#include "java/JavaInstallList.h" #include "net/PasteUpload.h" #include "pathmatcher/MultiMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h" @@ -125,6 +126,7 @@ #include #include +#include "SysInfo.h" #ifdef Q_OS_LINUX #include @@ -607,7 +609,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) // Memory m_settings->registerSetting({ "MinMemAlloc", "MinMemoryAlloc" }, 512); - m_settings->registerSetting({ "MaxMemAlloc", "MaxMemoryAlloc" }, suitableMaxMem()); + m_settings->registerSetting({ "MaxMemAlloc", "MaxMemoryAlloc" }, SysInfo::suitableMaxMem()); m_settings->registerSetting("PermGen", 128); // Java Settings @@ -1667,20 +1669,6 @@ QString Application::getUserAgentUncached() return BuildConfig.USER_AGENT_UNCACHED; } -int Application::suitableMaxMem() -{ - float totalRAM = (float)Sys::getSystemRam() / (float)Sys::mebibyte; - int maxMemoryAlloc; - - // If totalRAM < 6GB, use (totalRAM / 1.5), else 4GB - if (totalRAM < (4096 * 1.5)) - maxMemoryAlloc = (int)(totalRAM / 1.5); - else - maxMemoryAlloc = 4096; - - return maxMemoryAlloc; -} - bool Application::handleDataMigration(const QString& currentData, const QString& oldData, const QString& name, diff --git a/launcher/Application.h b/launcher/Application.h index 7669e08ec3..85bf2dff44 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -180,8 +180,6 @@ class Application : public QApplication { void ShowGlobalSettings(class QWidget* parent, QString open_page = QString()); - int suitableMaxMem(); - bool updaterEnabled(); QString updaterBinaryName(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 48ca8f0851..e735f20817 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -422,8 +422,6 @@ set(SETTINGS_SOURCES set(JAVA_SOURCES java/JavaChecker.h java/JavaChecker.cpp - java/JavaCheckerJob.h - java/JavaCheckerJob.cpp java/JavaInstall.h java/JavaInstall.cpp java/JavaInstallList.h diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index e16ac92556..cfc3cfe424 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -63,7 +63,7 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget* parent) return true; } -void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result) +void JavaCommon::javaWasOk(QWidget* parent, const JavaChecker::Result& result) { QString text; text += QObject::tr( @@ -79,7 +79,7 @@ void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result) CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show(); } -void JavaCommon::javaArgsWereBad(QWidget* parent, const JavaCheckResult& result) +void JavaCommon::javaArgsWereBad(QWidget* parent, const JavaChecker::Result& result) { auto htmlError = result.errorLog; QString text; @@ -89,7 +89,7 @@ void JavaCommon::javaArgsWereBad(QWidget* parent, const JavaCheckResult& result) CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); } -void JavaCommon::javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result) +void JavaCommon::javaBinaryWasBad(QWidget* parent, const JavaChecker::Result& result) { QString text; text += QObject::tr( @@ -116,34 +116,26 @@ void JavaCommon::TestCheck::run() emit finished(); return; } - checker.reset(new JavaChecker()); + checker.reset(new JavaChecker(m_path, "", 0, 0, 0, 0, this)); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinished); - checker->m_path = m_path; - checker->performCheck(); + checker->start(); } -void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) +void JavaCommon::TestCheck::checkFinished(JavaChecker::Result result) { - if (result.validity != JavaCheckResult::Validity::Valid) { + if (result.validity != JavaChecker::Result::Validity::Valid) { javaBinaryWasBad(m_parent, result); emit finished(); return; } - checker.reset(new JavaChecker()); + checker.reset(new JavaChecker(m_path, m_args, m_maxMem, m_maxMem, result.javaVersion.requiresPermGen() ? m_permGen : 0, 0, this)); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinishedWithArgs); - checker->m_path = m_path; - checker->m_args = m_args; - checker->m_minMem = m_minMem; - checker->m_maxMem = m_maxMem; - if (result.javaVersion.requiresPermGen()) { - checker->m_permGen = m_permGen; - } - checker->performCheck(); + checker->start(); } -void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result) +void JavaCommon::TestCheck::checkFinishedWithArgs(JavaChecker::Result result) { - if (result.validity == JavaCheckResult::Validity::Valid) { + if (result.validity == JavaChecker::Result::Validity::Valid) { javaWasOk(m_parent, result); emit finished(); return; diff --git a/launcher/JavaCommon.h b/launcher/JavaCommon.h index c96f7a9858..7c5510efc3 100644 --- a/launcher/JavaCommon.h +++ b/launcher/JavaCommon.h @@ -10,11 +10,11 @@ namespace JavaCommon { bool checkJVMArgs(QString args, QWidget* parent); // Show a dialog saying that the Java binary was usable -void javaWasOk(QWidget* parent, const JavaCheckResult& result); +void javaWasOk(QWidget* parent, const JavaChecker::Result& result); // Show a dialog saying that the Java binary was not usable because of bad options -void javaArgsWereBad(QWidget* parent, const JavaCheckResult& result); +void javaArgsWereBad(QWidget* parent, const JavaChecker::Result& result); // Show a dialog saying that the Java binary was not usable -void javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result); +void javaBinaryWasBad(QWidget* parent, const JavaChecker::Result& result); // Show a dialog if we couldn't find Java Checker void javaCheckNotFound(QWidget* parent); @@ -32,11 +32,11 @@ class TestCheck : public QObject { void finished(); private slots: - void checkFinished(JavaCheckResult result); - void checkFinishedWithArgs(JavaCheckResult result); + void checkFinished(JavaChecker::Result result); + void checkFinishedWithArgs(JavaChecker::Result result); private: - std::shared_ptr checker; + JavaChecker::Ptr checker; QWidget* m_parent = nullptr; QString m_path; QString m_args; diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 3bfe16ab5c..78a3b290de 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -507,6 +507,112 @@ bool ExportToZipTask::abort() } return false; } + +void ExtractZipTask::executeTask() +{ + m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return extractZip(); }); + connect(&m_zip_watcher, &QFutureWatcher::finished, this, &ExtractZipTask::finish); + m_zip_watcher.setFuture(m_zip_future); +} + +auto ExtractZipTask::extractZip() -> ZipResult +{ + auto target = m_output_dir.absolutePath(); + auto target_top_dir = QUrl::fromLocalFile(target); + + QStringList extracted; + + qDebug() << "Extracting subdir" << m_subdirectory << "from" << m_input->getZipName() << "to" << target; + auto numEntries = m_input->getEntriesCount(); + if (numEntries < 0) { + return ZipResult(tr("Failed to enumerate files in archive")); + } + if (numEntries == 0) { + logWarning(tr("Extracting empty archives seems odd...")); + return ZipResult(); + } + if (!m_input->goToFirstFile()) { + return ZipResult(tr("Failed to seek to first file in zip")); + } + + setStatus("Extracting files..."); + setProgress(0, numEntries); + do { + if (m_zip_future.isCanceled()) + return ZipResult(); + setProgress(m_progress + 1, m_progressTotal); + QString file_name = m_input->getCurrentFileName(); + if (!file_name.startsWith(m_subdirectory)) + continue; + + auto relative_file_name = QDir::fromNativeSeparators(file_name.remove(0, m_subdirectory.size())); + auto original_name = relative_file_name; + setStatus("Unziping: " + relative_file_name); + + // Fix subdirs/files ending with a / getting transformed into absolute paths + if (relative_file_name.startsWith('/')) + relative_file_name = relative_file_name.mid(1); + + // Fix weird "folders with a single file get squashed" thing + QString sub_path; + if (relative_file_name.contains('/') && !relative_file_name.endsWith('/')) { + sub_path = relative_file_name.section('/', 0, -2) + '/'; + FS::ensureFolderPathExists(FS::PathCombine(target, sub_path)); + + relative_file_name = relative_file_name.split('/').last(); + } + + QString target_file_path; + if (relative_file_name.isEmpty()) { + target_file_path = target + '/'; + } else { + target_file_path = FS::PathCombine(target_top_dir.toLocalFile(), sub_path, relative_file_name); + if (relative_file_name.endsWith('/') && !target_file_path.endsWith('/')) + target_file_path += '/'; + } + + if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) { + return ZipResult(tr("Extracting %1 was cancelled, because it was effectively outside of the target path %2") + .arg(relative_file_name, target)); + } + + if (!JlCompress::extractFile(m_input.get(), "", target_file_path)) { + JlCompress::removeFile(extracted); + return ZipResult(tr("Failed to extract file %1 to %2").arg(original_name, target_file_path)); + } + + extracted.append(target_file_path); + QFile::setPermissions(target_file_path, + QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); + + qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path; + } while (m_input->goToNextFile()); + + return ZipResult(); +} + +void ExtractZipTask::finish() +{ + if (m_zip_future.isCanceled()) { + emitAborted(); + } else if (auto result = m_zip_future.result(); result.has_value()) { + emitFailed(result.value()); + } else { + emitSucceeded(); + } +} + +bool ExtractZipTask::abort() +{ + if (m_zip_future.isRunning()) { + m_zip_future.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not occur + // immediately. + return true; + } + return false; +} + #endif } // namespace MMCZip diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 45b1df0b33..2b396eb9c8 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -194,5 +194,33 @@ class ExportToZipTask : public Task { QFuture m_build_zip_future; QFutureWatcher m_build_zip_watcher; }; + +class ExtractZipTask : public Task { + public: + ExtractZipTask(QString input, QDir outputDir, QString subdirectory = "") + : ExtractZipTask(std::make_shared(input), outputDir, subdirectory) + {} + ExtractZipTask(std::shared_ptr input, QDir outputDir, QString subdirectory = "") + : m_input(input), m_output_dir(outputDir), m_subdirectory(subdirectory) + {} + virtual ~ExtractZipTask() = default; + + typedef std::optional ZipResult; + + protected: + virtual void executeTask() override; + bool abort() override; + + ZipResult extractZip(); + void finish(); + + private: + std::shared_ptr m_input; + QDir m_output_dir; + QString m_subdirectory; + + QFuture m_zip_future; + QFutureWatcher m_zip_watcher; +}; #endif } // namespace MMCZip diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp index ad251e29ff..f15dde0e4f 100644 --- a/launcher/SysInfo.cpp +++ b/launcher/SysInfo.cpp @@ -1,5 +1,6 @@ #include #include +#include "sys.h" #ifdef Q_OS_MACOS #include #endif @@ -7,9 +8,6 @@ #include #include #include -#include "Application.h" -#include "Commandline.h" -#include "java/JavaUtils.h" #ifdef Q_OS_MACOS bool rosettaDetect() @@ -59,4 +57,18 @@ QString useQTForArch() #endif return qtArch; } + +int suitableMaxMem() +{ + float totalRAM = (float)Sys::getSystemRam() / (float)Sys::mebibyte; + int maxMemoryAlloc; + + // If totalRAM < 6GB, use (totalRAM / 1.5), else 4GB + if (totalRAM < (4096 * 1.5)) + maxMemoryAlloc = (int)(totalRAM / 1.5); + else + maxMemoryAlloc = 4096; + + return maxMemoryAlloc; +} } // namespace SysInfo diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h index 3650bf008e..499c3b1dd1 100644 --- a/launcher/SysInfo.h +++ b/launcher/SysInfo.h @@ -3,4 +3,5 @@ namespace SysInfo { QString currentSystem(); QString useQTForArch(); +int suitableMaxMem(); } // namespace SysInfo diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 20caba189e..7271c0d093 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -40,14 +40,13 @@ #include #include -#include "Application.h" #include "Commandline.h" -#include "FileSystem.h" -#include "JavaUtils.h" +#include "java/JavaUtils.h" -JavaChecker::JavaChecker(QObject* parent) : QObject(parent) {} +JavaChecker::JavaChecker(QString path, QString args, int minMem, int maxMem, int permGen, int id, QObject* parent) + : Task(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen), m_id(id){}; -void JavaChecker::performCheck() +void JavaChecker::executeTask() { QString checkerJar = JavaUtils::getJavaCheckPath(); @@ -69,7 +68,7 @@ void JavaChecker::performCheck() if (m_maxMem != 0) { args << QString("-Xmx%1m").arg(m_maxMem); } - if (m_permGen != 64) { + if (m_permGen != 64 && m_permGen != 0) { args << QString("-XX:PermSize=%1m").arg(m_permGen); } @@ -112,11 +111,10 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) QProcessPtr _process = process; process.reset(); - JavaCheckResult result; - { - result.path = m_path; - result.id = m_id; - } + Result result = { + m_path, + m_id, + }; result.errorLog = m_stderr; result.outLog = m_stdout; qDebug() << "STDOUT" << m_stdout; @@ -124,8 +122,9 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) qDebug() << "Java checker finished with status" << status << "exit code" << exitcode; if (status == QProcess::CrashExit || exitcode == 1) { - result.validity = JavaCheckResult::Validity::Errored; + result.validity = Result::Validity::Errored; emit checkFinished(result); + emitSucceeded(); return; } @@ -158,8 +157,9 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) } if (!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success) { - result.validity = JavaCheckResult::Validity::ReturnedInvalidData; + result.validity = Result::Validity::ReturnedInvalidData; emit checkFinished(result); + emitSucceeded(); return; } @@ -168,7 +168,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) auto java_vendor = results["java.vendor"]; bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64"; - result.validity = JavaCheckResult::Validity::Valid; + result.validity = Result::Validity::Valid; result.is_64bit = is_64; result.mojangPlatform = is_64 ? "64" : "32"; result.realPlatform = os_arch; @@ -176,6 +176,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) result.javaVendor = java_vendor; qDebug() << "Java checker succeeded."; emit checkFinished(result); + emitSucceeded(); } void JavaChecker::error(QProcess::ProcessError err) @@ -187,15 +188,9 @@ void JavaChecker::error(QProcess::ProcessError err) qDebug() << "Native environment:"; qDebug() << QProcessEnvironment::systemEnvironment().toStringList(); killTimer.stop(); - JavaCheckResult result; - { - result.path = m_path; - result.id = m_id; - } - - emit checkFinished(result); - return; + emit checkFinished({ m_path, m_id }); } + emitSucceeded(); } void JavaChecker::timeout() diff --git a/launcher/java/JavaChecker.h b/launcher/java/JavaChecker.h index 7111f85227..0c6191c21b 100644 --- a/launcher/java/JavaChecker.h +++ b/launcher/java/JavaChecker.h @@ -3,49 +3,51 @@ #include #include -#include "QObjectPtr.h" - #include "JavaVersion.h" +#include "QObjectPtr.h" +#include "tasks/Task.h" -class JavaChecker; - -struct JavaCheckResult { - QString path; - QString mojangPlatform; - QString realPlatform; - JavaVersion javaVersion; - QString javaVendor; - QString outLog; - QString errorLog; - bool is_64bit = false; - int id; - enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored; -}; - -using QProcessPtr = shared_qobject_ptr; -using JavaCheckerPtr = shared_qobject_ptr; -class JavaChecker : public QObject { +class JavaChecker : public Task { Q_OBJECT public: - explicit JavaChecker(QObject* parent = 0); - void performCheck(); - - QString m_path; - QString m_args; - int m_id = 0; - int m_minMem = 0; - int m_maxMem = 0; - int m_permGen = 64; + using QProcessPtr = shared_qobject_ptr; + using Ptr = shared_qobject_ptr; + + struct Result { + QString path; + int id; + QString mojangPlatform; + QString realPlatform; + JavaVersion javaVersion; + QString javaVendor; + QString outLog; + QString errorLog; + bool is_64bit = false; + enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored; + }; + + explicit JavaChecker(QString path, QString args, int minMem = 0, int maxMem = 0, int permGen = 0, int id = 0, QObject* parent = 0); signals: - void checkFinished(JavaCheckResult result); + void checkFinished(Result result); + + protected: + virtual void executeTask() override; private: QProcessPtr process; QTimer killTimer; QString m_stdout; QString m_stderr; - public slots: + + QString m_path; + QString m_args; + int m_minMem = 0; + int m_maxMem = 0; + int m_permGen = 64; + int m_id = 0; + + private slots: void timeout(); void finished(int exitcode, QProcess::ExitStatus); void error(QProcess::ProcessError); diff --git a/launcher/java/JavaCheckerJob.cpp b/launcher/java/JavaCheckerJob.cpp deleted file mode 100644 index 870e2a09ad..0000000000 --- a/launcher/java/JavaCheckerJob.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2013-2021 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "JavaCheckerJob.h" - -#include - -void JavaCheckerJob::partFinished(JavaCheckResult result) -{ - num_finished++; - qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" << javacheckers.size(); - setProgress(num_finished, javacheckers.size()); - - javaresults.replace(result.id, result); - - if (num_finished == javacheckers.size()) { - emitSucceeded(); - } -} - -void JavaCheckerJob::executeTask() -{ - qDebug() << m_job_name.toLocal8Bit() << " started."; - for (auto iter : javacheckers) { - javaresults.append(JavaCheckResult()); - connect(iter.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); - iter->performCheck(); - } -} diff --git a/launcher/java/JavaCheckerJob.h b/launcher/java/JavaCheckerJob.h deleted file mode 100644 index ddf8279683..0000000000 --- a/launcher/java/JavaCheckerJob.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2013-2021 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include "JavaChecker.h" -#include "tasks/Task.h" - -class JavaCheckerJob; -using JavaCheckerJobPtr = shared_qobject_ptr; - -// FIXME: this just seems horribly redundant -class JavaCheckerJob : public Task { - Q_OBJECT - public: - explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name){}; - virtual ~JavaCheckerJob(){}; - - bool addJavaCheckerAction(JavaCheckerPtr base) - { - javacheckers.append(base); - // if this is already running, the action needs to be started right away! - if (isRunning()) { - setProgress(num_finished, javacheckers.size()); - connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); - base->performCheck(); - } - return true; - } - QList getResults() { return javaresults; } - - private slots: - void partFinished(JavaCheckResult result); - - protected: - virtual void executeTask() override; - - private: - QString m_job_name; - QList javacheckers; - QList javaresults; - int num_finished = 0; -}; diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index d8be4963f5..ef99d6853e 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -38,11 +38,13 @@ #include #include +#include -#include "java/JavaCheckerJob.h" +#include "Application.h" +#include "java/JavaChecker.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" -#include "minecraft/VersionFilterData.h" +#include "tasks/ConcurrentTask.h" JavaInstallList::JavaInstallList(QObject* parent) : BaseVersionList(parent) {} @@ -55,7 +57,7 @@ Task::Ptr JavaInstallList::getLoadTask() Task::Ptr JavaInstallList::getCurrentTask() { if (m_status == Status::InProgress) { - return m_loadTask; + return m_load_task; } return nullptr; } @@ -64,8 +66,8 @@ void JavaInstallList::load() { if (m_status != Status::InProgress) { m_status = Status::InProgress; - m_loadTask.reset(new JavaListLoadTask(this)); - m_loadTask->start(); + m_load_task.reset(new JavaListLoadTask(this)); + m_load_task->start(); } } @@ -129,7 +131,7 @@ void JavaInstallList::updateListData(QList versions) } endResetModel(); m_status = Status::Done; - m_loadTask.reset(); + m_load_task.reset(); } bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) @@ -149,11 +151,9 @@ void JavaInstallList::sortVersions() JavaListLoadTask::JavaListLoadTask(JavaInstallList* vlist) : Task() { m_list = vlist; - m_currentRecommended = NULL; + m_current_recommended = NULL; } -JavaListLoadTask::~JavaListLoadTask() {} - void JavaListLoadTask::executeTask() { setStatus(tr("Detecting Java installations...")); @@ -161,20 +161,17 @@ void JavaListLoadTask::executeTask() JavaUtils ju; QList candidate_paths = ju.FindJavaPaths(); - m_job.reset(new JavaCheckerJob("Java detection")); + ConcurrentTask::Ptr job(new ConcurrentTask(this, "Java detection", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())); + m_job.reset(job); connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished); connect(m_job.get(), &Task::progress, this, &Task::setProgress); qDebug() << "Probing the following Java paths: "; int id = 0; for (QString candidate : candidate_paths) { - qDebug() << " " << candidate; - - auto candidate_checker = new JavaChecker(); - candidate_checker->m_path = candidate; - candidate_checker->m_id = id; - m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker)); - + auto checker = new JavaChecker(candidate, "", 0, 0, 0, id, this); + connect(checker, &JavaChecker::checkFinished, [this](JavaChecker::Result result) { m_results << result; }); + job->addTask(Task::Ptr(checker)); id++; } @@ -184,11 +181,11 @@ void JavaListLoadTask::executeTask() void JavaListLoadTask::javaCheckerFinished() { QList candidates; - auto results = m_job->getResults(); + std::sort(m_results.begin(), m_results.end(), [](JavaChecker::Result a, JavaChecker::Result b) { return a.id < b.id; }); qDebug() << "Found the following valid Java installations:"; - for (JavaCheckResult result : results) { - if (result.validity == JavaCheckResult::Validity::Valid) { + for (auto result : m_results) { + if (result.validity == JavaChecker::Result::Validity::Valid) { JavaInstallPtr javaVersion(new JavaInstall()); javaVersion->id = result.javaVersion; diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h index 1eebadf234..08f0b310df 100644 --- a/launcher/java/JavaInstallList.h +++ b/launcher/java/JavaInstallList.h @@ -19,9 +19,9 @@ #include #include "BaseVersionList.h" +#include "java/JavaChecker.h" #include "tasks/Task.h" -#include "JavaCheckerJob.h" #include "JavaInstall.h" #include "QObjectPtr.h" @@ -53,7 +53,7 @@ class JavaInstallList : public BaseVersionList { protected: Status m_status = Status::NotDone; - shared_qobject_ptr m_loadTask; + shared_qobject_ptr m_load_task; QList m_vlist; }; @@ -62,14 +62,16 @@ class JavaListLoadTask : public Task { public: explicit JavaListLoadTask(JavaInstallList* vlist); - virtual ~JavaListLoadTask(); + virtual ~JavaListLoadTask() = default; + protected: void executeTask() override; public slots: void javaCheckerFinished(); protected: - shared_qobject_ptr m_job; + Task::Ptr m_job; JavaInstallList* m_list; - JavaInstall* m_currentRecommended; + JavaInstall* m_current_recommended; + QList m_results; }; diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index 6161797068..c052ca325c 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -15,10 +15,9 @@ #pragma once +#include #include - -#include "JavaChecker.h" -#include "JavaInstallList.h" +#include "java/JavaInstall.h" #ifdef Q_OS_WIN #include diff --git a/launcher/java/providers/AdoptiumJavaDownloader.cpp b/launcher/java/providers/AdoptiumJavaDownloader.cpp new file mode 100644 index 0000000000..4f8499d4a8 --- /dev/null +++ b/launcher/java/providers/AdoptiumJavaDownloader.cpp @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/AdoptiumJavaDownloader.h" +#include +#include +#include "MMCZip.h" + +#include "Application.h" +#include "net/NetJob.h" +#include "tasks/Task.h" + +void AdoptiumJavaDownloader::executeTask() +{ + downloadJava(); +}; + +QString AdoptiumJavaDownloader::getArch() const +{ + if (m_os_arch == "arm64") + return "aarch64"; + if (m_os_arch.isEmpty()) + return "x86"; + return m_os_arch; +} + +void AdoptiumJavaDownloader::downloadJava() +{ + // JRE found ! download the zip + setStatus(tr("Downloading Java from Adoptium")); + + auto javaVersion = m_is_legacy ? QString("8") : QString("17"); + auto azulOS = m_os_name == "osx" ? "mac" : m_os_name; + auto arch = getArch(); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", "adoptiumJRE.zip"); + + auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); + download->addNetAction(Net::Download::makeCached( + QString("https://api.adoptium.net/v3/binary/latest/%1/ga/%2/%3/jre/hotspot/normal/eclipse").arg(javaVersion, azulOS, arch), entry)); + auto fullPath = entry->getFullPath(); + + connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); + // connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); + connect(download.get(), &NetJob::progress, this, &AdoptiumJavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &AdoptiumJavaDownloader::emitFailed); + connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &NetJob::succeeded, [this, fullPath] { + // This should do all of the extracting and creating folders + extractJava(fullPath); + }); + download->start(); +}; + +void AdoptiumJavaDownloader::extractJava(QString input) +{ + setStatus(tr("Extracting java")); + auto zip = std::make_shared(input); + auto files = zip->getFileNameList(); + if (files.isEmpty()) { + emitFailed("Empty archive"); + return; + } + auto zipTask = makeShared(input, m_final_path, files[0]); + + auto progressStep = std::make_shared(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); + }); + + connect(this, &Task::aborted, zipTask.get(), &Task::abort); + connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); + + connect(zipTask.get(), &Task::succeeded, this, &AdoptiumJavaDownloader::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &AdoptiumJavaDownloader::emitAborted); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); + }); + connect(zipTask.get(), &Task::stepProgress, this, &AdoptiumJavaDownloader::propagateStepProgress); + + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + zipTask->start(); +}; + +static const QStringList supportedOs = { + "linux", "windows", "mac", "solaris", "aix", "alpine-linux", +}; + +static const QStringList supportedArch = { + "x64", "x86", "x32", "ppc64", "ppc64le", "s390x", "aarch64", "arm", "sparcv9", "riscv64", +}; + +bool AdoptiumJavaDownloader::isSupported() const +{ + return supportedOs.contains(m_os_name == "osx" ? "mac" : m_os_name) && supportedArch.contains(getArch()); +}; \ No newline at end of file diff --git a/launcher/java/providers/AdoptiumJavaDownloader.h b/launcher/java/providers/AdoptiumJavaDownloader.h new file mode 100644 index 0000000000..f0ae6239b3 --- /dev/null +++ b/launcher/java/providers/AdoptiumJavaDownloader.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/BasicJavaDownloader.h" + +class AdoptiumJavaDownloader : public BasicJavaDownloader { + Q_OBJECT + public: + void executeTask() override; + + virtual QString name() const override { return "Adoptium"; }; + virtual bool isSupported() const override; + private slots: + void downloadJava(); + void extractJava(QString input); + + private: + QString getArch() const; +}; \ No newline at end of file diff --git a/launcher/java/providers/AzulJavaDownloader.cpp b/launcher/java/providers/AzulJavaDownloader.cpp new file mode 100644 index 0000000000..674da592ec --- /dev/null +++ b/launcher/java/providers/AzulJavaDownloader.cpp @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/AzulJavaDownloader.h" +#include +#include "MMCZip.h" + +#include "Application.h" +#include "Json.h" +#include "net/NetJob.h" +#include "tasks/Task.h" + +void AzulJavaDownloader::executeTask() +{ + downloadJavaList(); +}; + +void AzulJavaDownloader::downloadJavaList() +{ + setStatus(tr("Querying Azul meta")); + + auto javaVersion = m_is_legacy ? QString("8.0") : QString("17.0"); + auto azulOS = m_os_name == "osx" ? "macos" : m_os_name; + auto arch = getArch(); + auto metaResponse = std::make_shared(); + auto downloadJob = makeShared(QString("JRE::QueryAzulMeta"), APPLICATION->network()); + downloadJob->addNetAction(Net::Download::makeByteArray(QString("https://api.azul.com/metadata/v1/zulu/packages/?" + "java_version=%1" + "&os=%2" + "&arch=%3" + "&archive_type=zip" + "&java_package_type=jre" + "&support_term=lts" + "&latest=true" + "status=ga" + "&availability_types=CA" + "&page=1" + "&page_size=1") + .arg(javaVersion, azulOS, arch), + metaResponse)); + connect(downloadJob.get(), &NetJob::finished, + [downloadJob, metaResponse, this] { disconnect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); }); + connect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); + connect(downloadJob.get(), &NetJob::failed, this, &AzulJavaDownloader::emitFailed); + connect(downloadJob.get(), &NetJob::progress, this, &AzulJavaDownloader::progress); + connect(downloadJob.get(), &NetJob::succeeded, [metaResponse, this] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << *metaResponse; + return; + } + auto array = Json::ensureArray(doc.array()); + if (!array.empty()) { + downloadJava(array); + } else { + emitFailed(tr("No suitable JRE found")); + } + }); + downloadJob->start(); +}; + +QString AzulJavaDownloader::getArch() const +{ + if (m_os_arch == "arm64") + return "aarch64"; + if (m_os_arch == "arm") + return "aarch32"; + if (m_os_arch.isEmpty()) + return "x86"; + return m_os_arch; +} + +void AzulJavaDownloader::downloadJava(const QJsonArray& array) +{ + // JRE found ! download the zip + setStatus(tr("Downloading Java from Azul")); + + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", "azulJRE.zip"); + + auto downloadURL = QUrl(array[0].toObject()["url"].toString()); + auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); + download->addNetAction(Net::Download::makeCached(downloadURL, entry)); + auto fullPath = entry->getFullPath(); + + connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); + // connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); + connect(download.get(), &NetJob::progress, this, &AzulJavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &AzulJavaDownloader::emitFailed); + connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &NetJob::succeeded, [downloadURL, this, fullPath] { + // This should do all of the extracting and creating folders + extractJava(fullPath, downloadURL.fileName().chopped(4)); + }); + download->start(); +}; + +void AzulJavaDownloader::extractJava(QString input, QString subdirectory) +{ + setStatus(tr("Extracting java")); + auto zipTask = makeShared(input, m_final_path, subdirectory); + + auto progressStep = std::make_shared(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); + }); + + connect(this, &Task::aborted, zipTask.get(), &Task::abort); + connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); + + connect(zipTask.get(), &Task::succeeded, this, &AzulJavaDownloader::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &AzulJavaDownloader::emitAborted); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); + }); + connect(zipTask.get(), &Task::stepProgress, this, &AzulJavaDownloader::propagateStepProgress); + + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + zipTask->start(); +}; + +static const QStringList supportedOs = { + "macos", "linux", "windows", "linux-musl", "linux-glibc", "qnx", "solaris", "aix", +}; + +static const QStringList supportedArch = { + "x86", "x64", "amd64", "i686", "arm", "aarch64", "aarch32", "aarch32sf", "aarch32hf", "ppc", + "ppc64", "ppc32", "ppc32hf", "ppc32spe", "sparc", "sparc64", "sparc32", "sparcv9", "sparcv9-64", "sparcv9-32", +}; + +bool AzulJavaDownloader::isSupported() const +{ + return supportedOs.contains(m_os_name == "osx" ? "macos" : m_os_name) && supportedArch.contains(getArch()); +}; \ No newline at end of file diff --git a/launcher/java/providers/AzulJavaDownloader.h b/launcher/java/providers/AzulJavaDownloader.h new file mode 100644 index 0000000000..c4bc8c7613 --- /dev/null +++ b/launcher/java/providers/AzulJavaDownloader.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/BasicJavaDownloader.h" + +class AzulJavaDownloader : public BasicJavaDownloader { + Q_OBJECT + public: + void executeTask() override; + + virtual QString name() const override { return "Azul"; }; + virtual bool isSupported() const override; + private slots: + void downloadJavaList(); + void downloadJava(const QJsonArray& doc); + void extractJava(QString input, QString subdirectory); + + private: + QString getArch() const; +}; \ No newline at end of file diff --git a/launcher/java/providers/BasicJavaDownloader.cpp b/launcher/java/providers/BasicJavaDownloader.cpp new file mode 100644 index 0000000000..9f353d9c19 --- /dev/null +++ b/launcher/java/providers/BasicJavaDownloader.cpp @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/BasicJavaDownloader.h" + +#include "SysInfo.h" +#include "tasks/Task.h" + +BasicJavaDownloader::BasicJavaDownloader(QString final_path, bool m_is_legacy, QObject* parent) + : Task(parent) + , m_os_name(SysInfo::currentSystem()) + , m_os_arch(SysInfo::useQTForArch()) + , m_final_path(final_path) + , m_is_legacy(m_is_legacy) +{} diff --git a/launcher/java/providers/BasicJavaDownloader.h b/launcher/java/providers/BasicJavaDownloader.h new file mode 100644 index 0000000000..34c944ec89 --- /dev/null +++ b/launcher/java/providers/BasicJavaDownloader.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "tasks/Task.h" + +class BasicJavaDownloader : public Task { + Q_OBJECT + public: + BasicJavaDownloader(QString final_path, bool m_is_legacy = false, QObject* parent = nullptr); + virtual ~BasicJavaDownloader() = default; + + [[nodiscard]] bool canAbort() const override { return true; } + + virtual QString name() const = 0; + virtual bool isSupported() const = 0; + + protected: + QString m_os_name; + QString m_os_arch; + QString m_final_path; + bool m_is_legacy; + + Task::Ptr m_current_task; +}; \ No newline at end of file diff --git a/launcher/java/providers/MojangJavaDownloader.cpp b/launcher/java/providers/MojangJavaDownloader.cpp new file mode 100644 index 0000000000..fc2a17e94a --- /dev/null +++ b/launcher/java/providers/MojangJavaDownloader.cpp @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/MojanglJavaDownloader.h" + +#include "Application.h" +#include "FileSystem.h" +#include "Json.h" +#include "net/ChecksumValidator.h" +#include "net/NetJob.h" + +struct File { + QString path; + QString url; + QByteArray hash; + bool isExec; +}; + +void MojangJavaDownloader::executeTask() +{ + downloadJavaList(); +}; + +void MojangJavaDownloader::downloadJavaList() +{ + auto netJob = makeShared(QString("JRE::QueryVersions"), APPLICATION->network()); + auto response = std::make_shared(); + setStatus(tr("Querying mojang meta")); + netJob->addNetAction(Net::Download::makeByteArray( + QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); + + connect(netJob.get(), &NetJob::finished, [netJob, this] { + // delete so that it's not called on a deleted job + // FIXME: is this needed? qt should handle this + disconnect(this, &Task::aborted, netJob.get(), &NetJob::abort); + }); + connect(this, &Task::aborted, netJob.get(), &NetJob::abort); + + connect(netJob.get(), &NetJob::progress, this, &MojangJavaDownloader::progress); + connect(netJob.get(), &NetJob::failed, this, &MojangJavaDownloader::emitFailed); + connect(netJob.get(), &NetJob::succeeded, [response, this, netJob] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << *response; + emitFailed(parse_error.errorString()); + return; + } + auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), getOS()), m_is_legacy ? "jre-legacy" : "java-runtime-gamma"); + if (!versionArray.empty()) { + parseManifest(versionArray); + + } else { + // mojang does not have a JRE for us, so fail + emitFailed("No suitable JRE found"); + } + }); + + netJob->start(); +}; + +QString MojangJavaDownloader::getOS() const +{ + if (m_os_name == "windows") { + if (m_os_arch == "x86_64") { + return "windows-x64"; + } + if (m_os_arch == "i386") { + return "windows-x86"; + } + // Unknown, maybe arm, appending arch for downloader + return "windows-" + m_os_arch; + } + if (m_os_name == "osx") { + if (m_os_arch == "arm64") { + return "mac-os-arm64"; + } + return "mac-os"; + } + if (m_os_name == "linux") { + if (m_os_arch == "x86_64") { + return "linux"; + } + // will work for i386, and arm(64) + return "linux-" + m_os_arch; + } + return {}; +} +void MojangJavaDownloader::parseManifest(const QJsonArray& versionArray) +{ + setStatus(tr("Downloading Java from Mojang")); + auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); + auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); + auto files = std::make_shared(); + + download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); + + connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); + connect(download.get(), &NetJob::progress, this, &MojangJavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &MojangJavaDownloader::emitFailed); + connect(this, &Task::aborted, download.get(), &NetJob::abort); + + connect(download.get(), &NetJob::succeeded, [files, this] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << *files; + emitFailed(parse_error.errorString()); + return; + } + downloadJava(doc); + }); + download->start(); +}; + +void MojangJavaDownloader::downloadJava(const QJsonDocument& doc) +{ + // valid json doc, begin making jre spot + FS::ensureFolderPathExists(m_final_path); + std::vector toDownload; + auto list = Json::ensureObject(Json::ensureObject(doc.object()), "files"); + for (const auto& paths : list.keys()) { + auto file = FS::PathCombine(m_final_path, paths); + + const QJsonObject& meta = Json::ensureObject(list, paths); + auto type = Json::ensureString(meta, "type"); + if (type == "directory") { + FS::ensureFolderPathExists(file); + } else if (type == "link") { + // this is linux only ! + auto path = Json::ensureString(meta, "target"); + if (!path.isEmpty()) { + auto target = FS::PathCombine(file, "../" + path); + QFile(target).link(file); + } + } else if (type == "file") { + // TODO download compressed version if it exists ? + auto raw = Json::ensureObject(Json::ensureObject(meta, "downloads"), "raw"); + auto isExec = Json::ensureBoolean(meta, "executable", false); + auto url = Json::ensureString(raw, "url"); + if (!url.isEmpty() && QUrl(url).isValid()) { + auto f = File{ file, url, QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec }; + toDownload.push_back(f); + } + } + } + auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); + for (const auto& file : toDownload) { + auto dl = Net::Download::makeFile(file.url, file.path); + if (!file.hash.isEmpty()) { + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); + } + if (file.isExec) { + connect(dl.get(), &Net::Download::succeeded, + [file] { QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); }); + } + elementDownload->addNetAction(dl); + } + connect(elementDownload, &NetJob::finished, [elementDownload, this] { + disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); + elementDownload->deleteLater(); + }); + connect(elementDownload, &NetJob::progress, this, &MojangJavaDownloader::progress); + connect(elementDownload, &NetJob::failed, this, &MojangJavaDownloader::emitFailed); + + connect(this, &Task::aborted, elementDownload, &NetJob::abort); + connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); + elementDownload->start(); +}; diff --git a/launcher/java/providers/MojanglJavaDownloader.h b/launcher/java/providers/MojanglJavaDownloader.h new file mode 100644 index 0000000000..a1b5b17657 --- /dev/null +++ b/launcher/java/providers/MojanglJavaDownloader.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/providers/BasicJavaDownloader.h" + +class MojangJavaDownloader : public BasicJavaDownloader { + Q_OBJECT + public: + void executeTask() override; + + virtual QString name() const override { return "Mojang"; }; + virtual bool isSupported() const override { return !getOS().isEmpty(); }; + private slots: + void downloadJavaList(); + void parseManifest(const QJsonArray& versionArray); + void downloadJava(const QJsonDocument& doc); + + private: + QString getOS() const; +}; \ No newline at end of file diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index 81337a88e2..c776092fe6 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include "java/JavaUtils.h" @@ -90,11 +91,10 @@ void CheckJava::executeTask() // if timestamps are not the same, or something is missing, check! if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0 || storedVendor.size() == 0) { - m_JavaChecker.reset(new JavaChecker); + m_JavaChecker.reset(new JavaChecker(realJavaPath, "", 0, 0, 0, 0, this)); emit logLine(QString("Checking Java version..."), MessageLevel::Launcher); connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished); - m_JavaChecker->m_path = realJavaPath; - m_JavaChecker->performCheck(); + m_JavaChecker->start(); return; } else { auto verString = instance->settings()->get("JavaVersion").toString(); @@ -106,10 +106,10 @@ void CheckJava::executeTask() emitSucceeded(); } -void CheckJava::checkJavaFinished(JavaCheckResult result) +void CheckJava::checkJavaFinished(JavaChecker::Result result) { switch (result.validity) { - case JavaCheckResult::Validity::Errored: { + case JavaChecker::Result::Validity::Errored: { // Error message displayed if java can't start emit logLine(QString("Could not start java:"), MessageLevel::Error); emit logLines(result.errorLog.split('\n'), MessageLevel::Error); @@ -117,14 +117,14 @@ void CheckJava::checkJavaFinished(JavaCheckResult result) emitFailed(QString("Could not start java!")); return; } - case JavaCheckResult::Validity::ReturnedInvalidData: { + case JavaChecker::Result::Validity::ReturnedInvalidData: { emit logLine(QString("Java checker returned some invalid data we don't understand:"), MessageLevel::Error); emit logLines(result.outLog.split('\n'), MessageLevel::Warning); emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher); emitSucceeded(); return; } - case JavaCheckResult::Validity::Valid: { + case JavaChecker::Result::Validity::Valid: { auto instance = m_parent->instance(); printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.realPlatform, result.javaVendor); instance->settings()->set("JavaVersion", result.javaVersion.toString()); diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index 4436e2a551..5ba9e4018a 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -28,7 +28,7 @@ class CheckJava : public LaunchStep { virtual void executeTask(); virtual bool canAbort() const { return false; } private slots: - void checkJavaFinished(JavaCheckResult result); + void checkJavaFinished(JavaChecker::Result result); private: void printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor); @@ -37,5 +37,5 @@ class CheckJava : public LaunchStep { private: QString m_javaPath; QString m_javaSignature; - JavaCheckerPtr m_JavaChecker; + JavaChecker::Ptr m_JavaChecker; }; diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 63d7aa57ca..be6b195dcc 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -14,7 +14,9 @@ #include "FileSystem.h" #include "JavaCommon.h" #include "JavaDownloader.h" +#include "java/JavaChecker.h" #include "java/JavaInstall.h" +#include "java/JavaInstallList.h" #include "java/JavaUtils.h" #include "ui/dialogs/CustomMessageBox.h" @@ -368,30 +370,25 @@ void JavaSettingsWidget::checkJavaPath(const QString& path) return; } setJavaStatus(JavaStatus::Pending); - m_checker.reset(new JavaChecker()); - m_checker->m_path = path; - m_checker->m_minMem = minHeapSize(); - m_checker->m_maxMem = maxHeapSize(); - if (m_permGenSpinBox->isVisible()) { - m_checker->m_permGen = m_permGenSpinBox->value(); - } + m_checker.reset( + new JavaChecker(path, "", minHeapSize(), maxHeapSize(), m_permGenSpinBox->isVisible() ? m_permGenSpinBox->value() : 0, 0, this)); connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished); - m_checker->performCheck(); + m_checker->start(); } -void JavaSettingsWidget::checkFinished(JavaCheckResult result) +void JavaSettingsWidget::checkFinished(JavaChecker::Result result) { m_result = result; switch (result.validity) { - case JavaCheckResult::Validity::Valid: { + case JavaChecker::Result::Validity::Valid: { setJavaStatus(JavaStatus::Good); break; } - case JavaCheckResult::Validity::ReturnedInvalidData: { + case JavaChecker::Result::Validity::ReturnedInvalidData: { setJavaStatus(JavaStatus::ReturnedInvalidData); break; } - case JavaCheckResult::Validity::Errored: { + case JavaChecker::Result::Validity::Errored: { setJavaStatus(JavaStatus::DoesNotStart); break; } diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 0e05bf3414..d3cd2c5a70 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -51,7 +51,7 @@ class JavaSettingsWidget : public QWidget { void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void on_javaDownloadBtn_clicked(); - void checkFinished(JavaCheckResult result); + void checkFinished(JavaChecker::Result result); protected: /* methods */ void checkJavaPathOnEdit(const QString& path); @@ -89,5 +89,5 @@ class JavaSettingsWidget : public QWidget { QString queuedCheck; uint64_t m_availableMemory = 0ull; shared_qobject_ptr m_checker; - JavaCheckResult m_result; + JavaChecker::Result m_result; }; From e89703238365cbcca8cce19b923a28bbb2057516 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 25 Jan 2024 22:22:21 +0200 Subject: [PATCH 24/83] Added java metadata Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 +++ launcher/java/JavaVersion.cpp | 20 +++++++++++++++++++ launcher/java/JavaVersion.h | 4 ++++ launcher/minecraft/MojangVersionFormat.cpp | 6 ++++++ launcher/minecraft/OneSixVersionFormat.cpp | 14 +++++++++++++ launcher/minecraft/VersionFile.h | 8 ++++++++ .../ui/pages/instance/InstanceSettingsPage.ui | 2 -- 7 files changed, 55 insertions(+), 2 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index e735f20817..2af33178d8 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -430,6 +430,9 @@ set(JAVA_SOURCES java/JavaUtils.cpp java/JavaVersion.h java/JavaVersion.cpp + + java/JavaRuntime.h + java/JavaRuntime.cpp ) set(TRANSLATIONS_SOURCES diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index b77bf2adfe..3de6f5ad6a 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -109,3 +109,23 @@ bool JavaVersion::operator>(const JavaVersion& rhs) { return (!operator<(rhs)) && (!operator==(rhs)); } + +JavaVersion::JavaVersion(int major, int minor, int security, int build, QString name) + : m_major(major), m_minor(minor), m_security(security), m_name(name), m_parseable(true) +{ + if (build != 0) { + m_prerelease = QString::number(build); + m_string = m_prerelease; + } + if (m_security != 0) + m_string = QString::number(m_security) + "." + m_string; + else if (!m_string.isEmpty()) { + m_string = "0." + m_string; + } + if (m_minor != 0) + m_string = QString::number(m_minor) + "." + m_string; + else if (!m_string.isEmpty()) { + m_string = "0." + m_string; + } + m_string = QString::number(m_major) + "." + m_string; +} diff --git a/launcher/java/JavaVersion.h b/launcher/java/JavaVersion.h index 421578ea1a..eee992346d 100644 --- a/launcher/java/JavaVersion.h +++ b/launcher/java/JavaVersion.h @@ -16,6 +16,7 @@ class JavaVersion { public: JavaVersion() {} JavaVersion(const QString& rhs); + JavaVersion(int major, int minor, int security, int build = 0, QString name = ""); JavaVersion& operator=(const QString& rhs); @@ -32,12 +33,15 @@ class JavaVersion { int major() { return m_major; } int minor() { return m_minor; } int security() { return m_security; } + QString build() { return m_prerelease; } + QString name() { return m_name; } private: QString m_string; int m_major = 0; int m_minor = 0; int m_security = 0; + QString m_name = ""; bool m_parseable = false; QString m_prerelease; }; diff --git a/launcher/minecraft/MojangVersionFormat.cpp b/launcher/minecraft/MojangVersionFormat.cpp index bb782e47fe..d17a3a21f0 100644 --- a/launcher/minecraft/MojangVersionFormat.cpp +++ b/launcher/minecraft/MojangVersionFormat.cpp @@ -185,6 +185,9 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject& in, VersionFi out->compatibleJavaMajors.append(requireInteger(compatible)); } } + if (in.contains("compatibleJavaName")) { + out->compatibleJavaName = requireString(in.value("compatibleJavaName")); + } if (in.contains("downloads")) { auto downloadsObj = requireObject(in, "downloads"); @@ -259,6 +262,9 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj } out.insert("compatibleJavaMajors", compatibleJavaMajorsOut); } + if (!in->compatibleJavaName.isEmpty()) { + writeString(out, "compatibleJavaName", in->compatibleJavaName); + } } QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr& patch) diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 306c95a6ae..5f3b4f2a2f 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -36,6 +36,8 @@ #include "OneSixVersionFormat.h" #include #include +#include +#include "java/JavaRuntime.h" #include "minecraft/Agent.h" #include "minecraft/ParseUtils.h" @@ -255,6 +257,18 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument& doc out->m_volatile = requireBoolean(root, "volatile"); } + if (root.contains("runtimes")) { + auto runtimes = requireObject(root, "runtimes"); + out->runtimes = {}; + for (auto key : runtimes.keys()) { + QList list; + for (auto runtime : ensureArray(runtimes, key)) { + list.append(JavaRuntime::parseJavaMeta(ensureObject(runtime))); + } + out->runtimes[key] = list; + } + } + /* removed features that shouldn't be used */ if (root.contains("tweakers")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element 'tweakers'")); diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index 280e35ee34..297c19709b 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -36,6 +36,8 @@ #pragma once #include +#include +#include #include #include #include @@ -45,6 +47,7 @@ #include "Agent.h" #include "Library.h" #include "ProblemProvider.h" +#include "java/JavaRuntime.h" #include "minecraft/Rule.h" class PackProfile; @@ -98,6 +101,9 @@ class VersionFile : public ProblemContainer { /// Mojang: list of compatible java majors QList compatibleJavaMajors; + /// Mojang: the name of recomended java version + QString compatibleJavaName; + /// Mojang: type of the Minecraft version QString type; @@ -149,6 +155,8 @@ class VersionFile : public ProblemContainer { /// is volatile -- may be removed as soon as it is no longer needed by something else bool m_volatile = false; + QHash> runtimes; + public: // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more. QMap> mojangDownloads; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index cb37366ccb..7762ca8a7e 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -796,8 +796,6 @@ enableFeralGamemodeCheck enableMangoHud useDiscreteGpuCheck - modLoaderSettingsGroupBox - disableQuiltBeaconCheckBox gameTimeGroupBox serverJoinGroupBox serverJoinAddress From f36be3f0e3a32cb5f5711a727ecd07cf1c28b8dd Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 25 Jan 2024 22:58:12 +0200 Subject: [PATCH 25/83] Cleanup downloaders Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 4 + launcher/java/JavaRuntime.cpp | 56 ++++++ launcher/java/JavaRuntime.h | 30 ++++ .../ArchiveJavaDownloader.cpp} | 53 ++---- .../ArchiveJavaDownloader.h} | 16 +- .../ManifestJavaDownloader.cpp} | 93 ++-------- .../ManifestJavaDownloader.h} | 20 ++- .../java/providers/AdoptiumJavaDownloader.h | 36 ---- .../java/providers/AzulJavaDownloader.cpp | 159 ------------------ launcher/java/providers/AzulJavaDownloader.h | 37 ---- .../java/providers/BasicJavaDownloader.cpp | 29 ---- 11 files changed, 132 insertions(+), 401 deletions(-) create mode 100644 launcher/java/JavaRuntime.cpp create mode 100644 launcher/java/JavaRuntime.h rename launcher/java/{providers/AdoptiumJavaDownloader.cpp => download/ArchiveJavaDownloader.cpp} (63%) rename launcher/java/{providers/BasicJavaDownloader.h => download/ArchiveJavaDownloader.h} (73%) rename launcher/java/{providers/MojangJavaDownloader.cpp => download/ManifestJavaDownloader.cpp} (55%) rename launcher/java/{providers/MojanglJavaDownloader.h => download/ManifestJavaDownloader.h} (70%) delete mode 100644 launcher/java/providers/AdoptiumJavaDownloader.h delete mode 100644 launcher/java/providers/AzulJavaDownloader.cpp delete mode 100644 launcher/java/providers/AzulJavaDownloader.h delete mode 100644 launcher/java/providers/BasicJavaDownloader.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 2af33178d8..ac3f8eb68a 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -433,6 +433,10 @@ set(JAVA_SOURCES java/JavaRuntime.h java/JavaRuntime.cpp + java/download/ArchiveJavaDownloader.cpp + java/download/ArchiveJavaDownloader.h + java/download/ManifestJavaDownloader.cpp + java/download/ManifestJavaDownloader.h ) set(TRANSLATIONS_SOURCES diff --git a/launcher/java/JavaRuntime.cpp b/launcher/java/JavaRuntime.cpp new file mode 100644 index 0000000000..0de8c839bf --- /dev/null +++ b/launcher/java/JavaRuntime.cpp @@ -0,0 +1,56 @@ +#include "java/JavaRuntime.h" + +#include + +#include "Json.h" +#include "java/JavaVersion.h" +#include "minecraft/ParseUtils.h" + +namespace JavaRuntime { + +DownloadType parseDownloadType(QString javaDownload) +{ + if (javaDownload == "manifest") + return DownloadType::Manifest; + // if (javaDownload == "archive") + return DownloadType::Archive; +} +QString downloadTypeToString(DownloadType javaDownload) +{ + switch (javaDownload) { + case DownloadType::Manifest: + return "manifest"; + case DownloadType::Archive: + return "archive"; + } +} +MetaPtr parseJavaMeta(const QJsonObject& in) +{ + auto meta = std::make_shared(); + + meta->name = Json::ensureString(in, "name", ""); + meta->vendor = Json::ensureString(in, "vendor", ""); + meta->url = Json::ensureString(in, "url", ""); + meta->releaseTime = timeFromS3Time(Json::ensureString(in, "releaseTime", "")); + meta->recommended = Json::ensureBoolean(in, "recommended", false); + meta->downloadType = parseDownloadType(Json::ensureString(in, "downloadType", "")); + meta->packageType = Json::ensureString(in, "packageType", ""); + + if (in.contains("checksum")) { + auto obj = Json::requireObject(in, "checksum"); + meta->checksumHash = Json::ensureString(obj, "hash", ""); + meta->checksumType = Json::ensureString(obj, "type", ""); + } + + if (in.contains("version")) { + auto obj = Json::requireObject(in, "checksum"); + auto name = Json::ensureString(obj, "name", ""); + auto major = Json::ensureInteger(obj, "major", 0); + auto minor = Json::ensureInteger(obj, "minor", 0); + auto security = Json::ensureInteger(obj, "security", 0); + auto build = Json::ensureInteger(obj, "build", 0); + meta->version = JavaVersion(major, minor, security, build, name); + } + return meta; +} +} // namespace JavaRuntime diff --git a/launcher/java/JavaRuntime.h b/launcher/java/JavaRuntime.h new file mode 100644 index 0000000000..1ea5d2e48c --- /dev/null +++ b/launcher/java/JavaRuntime.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#include "java/JavaVersion.h" + +namespace JavaRuntime { + +enum class DownloadType { Manifest, Archive }; + +struct Meta { + QString name; + QString vendor; + QString url; + QDateTime releaseTime; + QString checksumType; + QString checksumHash; + bool recommended; + DownloadType downloadType; + QString packageType; + JavaVersion version; +}; +using MetaPtr = std::shared_ptr; + +DownloadType parseDownloadType(QString javaDownload); +QString downloadTypeToString(DownloadType javaDownload); +MetaPtr parseJavaMeta(const QJsonObject& libObj); + +} // namespace JavaRuntime \ No newline at end of file diff --git a/launcher/java/providers/AdoptiumJavaDownloader.cpp b/launcher/java/download/ArchiveJavaDownloader.cpp similarity index 63% rename from launcher/java/providers/AdoptiumJavaDownloader.cpp rename to launcher/java/download/ArchiveJavaDownloader.cpp index 4f8499d4a8..844be1dce9 100644 --- a/launcher/java/providers/AdoptiumJavaDownloader.cpp +++ b/launcher/java/download/ArchiveJavaDownloader.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "java/providers/AdoptiumJavaDownloader.h" +#include "java/download/ArchiveJavaDownloader.h" #include #include #include "MMCZip.h" @@ -24,39 +24,21 @@ #include "net/NetJob.h" #include "tasks/Task.h" -void AdoptiumJavaDownloader::executeTask() -{ - downloadJava(); -}; - -QString AdoptiumJavaDownloader::getArch() const -{ - if (m_os_arch == "arm64") - return "aarch64"; - if (m_os_arch.isEmpty()) - return "x86"; - return m_os_arch; -} - -void AdoptiumJavaDownloader::downloadJava() +void ArchiveJavaDownloader::executeTask() { // JRE found ! download the zip - setStatus(tr("Downloading Java from Adoptium")); + setStatus(tr("Downloading Java")); - auto javaVersion = m_is_legacy ? QString("8") : QString("17"); - auto azulOS = m_os_name == "osx" ? "mac" : m_os_name; - auto arch = getArch(); - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", "adoptiumJRE.zip"); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", m_url.toLocalFile()); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); - download->addNetAction(Net::Download::makeCached( - QString("https://api.adoptium.net/v3/binary/latest/%1/ga/%2/%3/jre/hotspot/normal/eclipse").arg(javaVersion, azulOS, arch), entry)); + download->addNetAction(Net::Download::makeCached(m_url, entry)); auto fullPath = entry->getFullPath(); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); // connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); - connect(download.get(), &NetJob::progress, this, &AdoptiumJavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &AdoptiumJavaDownloader::emitFailed); + connect(download.get(), &NetJob::progress, this, &ArchiveJavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &ArchiveJavaDownloader::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &NetJob::succeeded, [this, fullPath] { // This should do all of the extracting and creating folders @@ -65,7 +47,7 @@ void AdoptiumJavaDownloader::downloadJava() download->start(); }; -void AdoptiumJavaDownloader::extractJava(QString input) +void ArchiveJavaDownloader::extractJava(QString input) { setStatus(tr("Extracting java")); auto zip = std::make_shared(input); @@ -85,14 +67,14 @@ void AdoptiumJavaDownloader::extractJava(QString input) connect(this, &Task::aborted, zipTask.get(), &Task::abort); connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); - connect(zipTask.get(), &Task::succeeded, this, &AdoptiumJavaDownloader::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, &AdoptiumJavaDownloader::emitAborted); + connect(zipTask.get(), &Task::succeeded, this, &ArchiveJavaDownloader::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &ArchiveJavaDownloader::emitAborted); connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { progressStep->state = TaskStepState::Failed; stepProgress(*progressStep); emitFailed(reason); }); - connect(zipTask.get(), &Task::stepProgress, this, &AdoptiumJavaDownloader::propagateStepProgress); + connect(zipTask.get(), &Task::stepProgress, this, &ArchiveJavaDownloader::propagateStepProgress); connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); @@ -104,16 +86,3 @@ void AdoptiumJavaDownloader::extractJava(QString input) }); zipTask->start(); }; - -static const QStringList supportedOs = { - "linux", "windows", "mac", "solaris", "aix", "alpine-linux", -}; - -static const QStringList supportedArch = { - "x64", "x86", "x32", "ppc64", "ppc64le", "s390x", "aarch64", "arm", "sparcv9", "riscv64", -}; - -bool AdoptiumJavaDownloader::isSupported() const -{ - return supportedOs.contains(m_os_name == "osx" ? "mac" : m_os_name) && supportedArch.contains(getArch()); -}; \ No newline at end of file diff --git a/launcher/java/providers/BasicJavaDownloader.h b/launcher/java/download/ArchiveJavaDownloader.h similarity index 73% rename from launcher/java/providers/BasicJavaDownloader.h rename to launcher/java/download/ArchiveJavaDownloader.h index 34c944ec89..d176570864 100644 --- a/launcher/java/providers/BasicJavaDownloader.h +++ b/launcher/java/download/ArchiveJavaDownloader.h @@ -18,24 +18,24 @@ #pragma once +#include #include "tasks/Task.h" -class BasicJavaDownloader : public Task { +class ArchiveJavaDownloader : public Task { Q_OBJECT public: - BasicJavaDownloader(QString final_path, bool m_is_legacy = false, QObject* parent = nullptr); - virtual ~BasicJavaDownloader() = default; + ArchiveJavaDownloader(QUrl url, QString final_path); + virtual ~ArchiveJavaDownloader() = default; [[nodiscard]] bool canAbort() const override { return true; } + void executeTask() override; - virtual QString name() const = 0; - virtual bool isSupported() const = 0; + private slots: + void extractJava(QString input); protected: - QString m_os_name; - QString m_os_arch; + QUrl m_url; QString m_final_path; - bool m_is_legacy; Task::Ptr m_current_task; }; \ No newline at end of file diff --git a/launcher/java/providers/MojangJavaDownloader.cpp b/launcher/java/download/ManifestJavaDownloader.cpp similarity index 55% rename from launcher/java/providers/MojangJavaDownloader.cpp rename to launcher/java/download/ManifestJavaDownloader.cpp index fc2a17e94a..4f7dab94e5 100644 --- a/launcher/java/providers/MojangJavaDownloader.cpp +++ b/launcher/java/download/ManifestJavaDownloader.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "java/providers/MojanglJavaDownloader.h" +#include "java/download/ManifestJavaDownloader.h" #include "Application.h" #include "FileSystem.h" @@ -30,89 +30,18 @@ struct File { bool isExec; }; -void MojangJavaDownloader::executeTask() +ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path) : m_url(url), m_final_path(final_path){}; +void ManifestJavaDownloader::executeTask() { - downloadJavaList(); -}; - -void MojangJavaDownloader::downloadJavaList() -{ - auto netJob = makeShared(QString("JRE::QueryVersions"), APPLICATION->network()); - auto response = std::make_shared(); - setStatus(tr("Querying mojang meta")); - netJob->addNetAction(Net::Download::makeByteArray( - QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - - connect(netJob.get(), &NetJob::finished, [netJob, this] { - // delete so that it's not called on a deleted job - // FIXME: is this needed? qt should handle this - disconnect(this, &Task::aborted, netJob.get(), &NetJob::abort); - }); - connect(this, &Task::aborted, netJob.get(), &NetJob::abort); - - connect(netJob.get(), &NetJob::progress, this, &MojangJavaDownloader::progress); - connect(netJob.get(), &NetJob::failed, this, &MojangJavaDownloader::emitFailed); - connect(netJob.get(), &NetJob::succeeded, [response, this, netJob] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *response; - emitFailed(parse_error.errorString()); - return; - } - auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), getOS()), m_is_legacy ? "jre-legacy" : "java-runtime-gamma"); - if (!versionArray.empty()) { - parseManifest(versionArray); - - } else { - // mojang does not have a JRE for us, so fail - emitFailed("No suitable JRE found"); - } - }); - - netJob->start(); -}; - -QString MojangJavaDownloader::getOS() const -{ - if (m_os_name == "windows") { - if (m_os_arch == "x86_64") { - return "windows-x64"; - } - if (m_os_arch == "i386") { - return "windows-x86"; - } - // Unknown, maybe arm, appending arch for downloader - return "windows-" + m_os_arch; - } - if (m_os_name == "osx") { - if (m_os_arch == "arm64") { - return "mac-os-arm64"; - } - return "mac-os"; - } - if (m_os_name == "linux") { - if (m_os_arch == "x86_64") { - return "linux"; - } - // will work for i386, and arm(64) - return "linux-" + m_os_arch; - } - return {}; -} -void MojangJavaDownloader::parseManifest(const QJsonArray& versionArray) -{ - setStatus(tr("Downloading Java from Mojang")); - auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); + setStatus(tr("Downloading Java")); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = std::make_shared(); - download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); + download->addNetAction(Net::Download::makeByteArray(m_url, files)); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &MojangJavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &MojangJavaDownloader::emitFailed); + connect(download.get(), &NetJob::progress, this, &ManifestJavaDownloader::progress); + connect(download.get(), &NetJob::failed, this, &ManifestJavaDownloader::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &NetJob::succeeded, [files, this] { @@ -129,7 +58,7 @@ void MojangJavaDownloader::parseManifest(const QJsonArray& versionArray) download->start(); }; -void MojangJavaDownloader::downloadJava(const QJsonDocument& doc) +void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc) { // valid json doc, begin making jre spot FS::ensureFolderPathExists(m_final_path); @@ -176,10 +105,10 @@ void MojangJavaDownloader::downloadJava(const QJsonDocument& doc) disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); elementDownload->deleteLater(); }); - connect(elementDownload, &NetJob::progress, this, &MojangJavaDownloader::progress); - connect(elementDownload, &NetJob::failed, this, &MojangJavaDownloader::emitFailed); + connect(elementDownload, &NetJob::progress, this, &ManifestJavaDownloader::progress); + connect(elementDownload, &NetJob::failed, this, &ManifestJavaDownloader::emitFailed); connect(this, &Task::aborted, elementDownload, &NetJob::abort); connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); -}; +}; \ No newline at end of file diff --git a/launcher/java/providers/MojanglJavaDownloader.h b/launcher/java/download/ManifestJavaDownloader.h similarity index 70% rename from launcher/java/providers/MojanglJavaDownloader.h rename to launcher/java/download/ManifestJavaDownloader.h index a1b5b17657..44e9ed9de4 100644 --- a/launcher/java/providers/MojanglJavaDownloader.h +++ b/launcher/java/download/ManifestJavaDownloader.h @@ -18,20 +18,24 @@ #pragma once -#include "java/providers/BasicJavaDownloader.h" +#include +#include "tasks/Task.h" -class MojangJavaDownloader : public BasicJavaDownloader { +class ManifestJavaDownloader : public Task { Q_OBJECT public: + ManifestJavaDownloader(QUrl url, QString final_path); + virtual ~ManifestJavaDownloader() = default; + + [[nodiscard]] bool canAbort() const override { return true; } void executeTask() override; - virtual QString name() const override { return "Mojang"; }; - virtual bool isSupported() const override { return !getOS().isEmpty(); }; private slots: - void downloadJavaList(); - void parseManifest(const QJsonArray& versionArray); void downloadJava(const QJsonDocument& doc); - private: - QString getOS() const; + protected: + QUrl m_url; + QString m_final_path; + + Task::Ptr m_current_task; }; \ No newline at end of file diff --git a/launcher/java/providers/AdoptiumJavaDownloader.h b/launcher/java/providers/AdoptiumJavaDownloader.h deleted file mode 100644 index f0ae6239b3..0000000000 --- a/launcher/java/providers/AdoptiumJavaDownloader.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 "java/providers/BasicJavaDownloader.h" - -class AdoptiumJavaDownloader : public BasicJavaDownloader { - Q_OBJECT - public: - void executeTask() override; - - virtual QString name() const override { return "Adoptium"; }; - virtual bool isSupported() const override; - private slots: - void downloadJava(); - void extractJava(QString input); - - private: - QString getArch() const; -}; \ No newline at end of file diff --git a/launcher/java/providers/AzulJavaDownloader.cpp b/launcher/java/providers/AzulJavaDownloader.cpp deleted file mode 100644 index 674da592ec..0000000000 --- a/launcher/java/providers/AzulJavaDownloader.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 "java/providers/AzulJavaDownloader.h" -#include -#include "MMCZip.h" - -#include "Application.h" -#include "Json.h" -#include "net/NetJob.h" -#include "tasks/Task.h" - -void AzulJavaDownloader::executeTask() -{ - downloadJavaList(); -}; - -void AzulJavaDownloader::downloadJavaList() -{ - setStatus(tr("Querying Azul meta")); - - auto javaVersion = m_is_legacy ? QString("8.0") : QString("17.0"); - auto azulOS = m_os_name == "osx" ? "macos" : m_os_name; - auto arch = getArch(); - auto metaResponse = std::make_shared(); - auto downloadJob = makeShared(QString("JRE::QueryAzulMeta"), APPLICATION->network()); - downloadJob->addNetAction(Net::Download::makeByteArray(QString("https://api.azul.com/metadata/v1/zulu/packages/?" - "java_version=%1" - "&os=%2" - "&arch=%3" - "&archive_type=zip" - "&java_package_type=jre" - "&support_term=lts" - "&latest=true" - "status=ga" - "&availability_types=CA" - "&page=1" - "&page_size=1") - .arg(javaVersion, azulOS, arch), - metaResponse)); - connect(downloadJob.get(), &NetJob::finished, - [downloadJob, metaResponse, this] { disconnect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); }); - connect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); - connect(downloadJob.get(), &NetJob::failed, this, &AzulJavaDownloader::emitFailed); - connect(downloadJob.get(), &NetJob::progress, this, &AzulJavaDownloader::progress); - connect(downloadJob.get(), &NetJob::succeeded, [metaResponse, this] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *metaResponse; - return; - } - auto array = Json::ensureArray(doc.array()); - if (!array.empty()) { - downloadJava(array); - } else { - emitFailed(tr("No suitable JRE found")); - } - }); - downloadJob->start(); -}; - -QString AzulJavaDownloader::getArch() const -{ - if (m_os_arch == "arm64") - return "aarch64"; - if (m_os_arch == "arm") - return "aarch32"; - if (m_os_arch.isEmpty()) - return "x86"; - return m_os_arch; -} - -void AzulJavaDownloader::downloadJava(const QJsonArray& array) -{ - // JRE found ! download the zip - setStatus(tr("Downloading Java from Azul")); - - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", "azulJRE.zip"); - - auto downloadURL = QUrl(array[0].toObject()["url"].toString()); - auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); - download->addNetAction(Net::Download::makeCached(downloadURL, entry)); - auto fullPath = entry->getFullPath(); - - connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - // connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); - connect(download.get(), &NetJob::progress, this, &AzulJavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &AzulJavaDownloader::emitFailed); - connect(this, &Task::aborted, download.get(), &NetJob::abort); - connect(download.get(), &NetJob::succeeded, [downloadURL, this, fullPath] { - // This should do all of the extracting and creating folders - extractJava(fullPath, downloadURL.fileName().chopped(4)); - }); - download->start(); -}; - -void AzulJavaDownloader::extractJava(QString input, QString subdirectory) -{ - setStatus(tr("Extracting java")); - auto zipTask = makeShared(input, m_final_path, subdirectory); - - auto progressStep = std::make_shared(); - connect(zipTask.get(), &Task::finished, this, [this, progressStep] { - progressStep->state = TaskStepState::Succeeded; - stepProgress(*progressStep); - }); - - connect(this, &Task::aborted, zipTask.get(), &Task::abort); - connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); - - connect(zipTask.get(), &Task::succeeded, this, &AzulJavaDownloader::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, &AzulJavaDownloader::emitAborted); - connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - emitFailed(reason); - }); - connect(zipTask.get(), &Task::stepProgress, this, &AzulJavaDownloader::propagateStepProgress); - - connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { - progressStep->update(current, total); - stepProgress(*progressStep); - }); - connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { - progressStep->status = status; - stepProgress(*progressStep); - }); - zipTask->start(); -}; - -static const QStringList supportedOs = { - "macos", "linux", "windows", "linux-musl", "linux-glibc", "qnx", "solaris", "aix", -}; - -static const QStringList supportedArch = { - "x86", "x64", "amd64", "i686", "arm", "aarch64", "aarch32", "aarch32sf", "aarch32hf", "ppc", - "ppc64", "ppc32", "ppc32hf", "ppc32spe", "sparc", "sparc64", "sparc32", "sparcv9", "sparcv9-64", "sparcv9-32", -}; - -bool AzulJavaDownloader::isSupported() const -{ - return supportedOs.contains(m_os_name == "osx" ? "macos" : m_os_name) && supportedArch.contains(getArch()); -}; \ No newline at end of file diff --git a/launcher/java/providers/AzulJavaDownloader.h b/launcher/java/providers/AzulJavaDownloader.h deleted file mode 100644 index c4bc8c7613..0000000000 --- a/launcher/java/providers/AzulJavaDownloader.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 "java/providers/BasicJavaDownloader.h" - -class AzulJavaDownloader : public BasicJavaDownloader { - Q_OBJECT - public: - void executeTask() override; - - virtual QString name() const override { return "Azul"; }; - virtual bool isSupported() const override; - private slots: - void downloadJavaList(); - void downloadJava(const QJsonArray& doc); - void extractJava(QString input, QString subdirectory); - - private: - QString getArch() const; -}; \ No newline at end of file diff --git a/launcher/java/providers/BasicJavaDownloader.cpp b/launcher/java/providers/BasicJavaDownloader.cpp deleted file mode 100644 index 9f353d9c19..0000000000 --- a/launcher/java/providers/BasicJavaDownloader.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 "java/providers/BasicJavaDownloader.h" - -#include "SysInfo.h" -#include "tasks/Task.h" - -BasicJavaDownloader::BasicJavaDownloader(QString final_path, bool m_is_legacy, QObject* parent) - : Task(parent) - , m_os_name(SysInfo::currentSystem()) - , m_os_arch(SysInfo::useQTForArch()) - , m_final_path(final_path) - , m_is_legacy(m_is_legacy) -{} From 81282bf7e0189ede29d2db14f85ef2c886d8b583 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 26 Jan 2024 00:22:05 +0200 Subject: [PATCH 26/83] Autodetect Java? Signed-off-by: Trial97 --- launcher/java/JavaRuntime.cpp | 19 +++++++ launcher/java/JavaRuntime.h | 19 +++++++ launcher/java/JavaUtils.cpp | 1 + .../java/download/ArchiveJavaDownloader.cpp | 18 +++++-- .../java/download/ArchiveJavaDownloader.h | 4 +- .../java/download/ManifestJavaDownloader.cpp | 18 +++++-- .../java/download/ManifestJavaDownloader.h | 4 +- .../minecraft/launch/VerifyJavaInstall.cpp | 49 ++++++++++++++----- 8 files changed, 112 insertions(+), 20 deletions(-) diff --git a/launcher/java/JavaRuntime.cpp b/launcher/java/JavaRuntime.cpp index 0de8c839bf..78651e9911 100644 --- a/launcher/java/JavaRuntime.cpp +++ b/launcher/java/JavaRuntime.cpp @@ -1,3 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 "java/JavaRuntime.h" #include @@ -23,6 +41,7 @@ QString downloadTypeToString(DownloadType javaDownload) case DownloadType::Archive: return "archive"; } + return ""; } MetaPtr parseJavaMeta(const QJsonObject& in) { diff --git a/launcher/java/JavaRuntime.h b/launcher/java/JavaRuntime.h index 1ea5d2e48c..b44b546b6d 100644 --- a/launcher/java/JavaRuntime.h +++ b/launcher/java/JavaRuntime.h @@ -1,8 +1,27 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 #include +#include + #include "java/JavaVersion.h" namespace JavaRuntime { diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 074bf54df1..67f1fd3a77 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -393,6 +393,7 @@ QList JavaUtils::FindJavaPaths() scanJavaDir(snap + dirPath); } }; + scanJavaDir(FS::PathCombine(APPLICATION->dataRoot(), "java")); // oracle RPMs scanJavaDirs("/usr/java"); // general locations used by distro packaging diff --git a/launcher/java/download/ArchiveJavaDownloader.cpp b/launcher/java/download/ArchiveJavaDownloader.cpp index 844be1dce9..32a3c39d27 100644 --- a/launcher/java/download/ArchiveJavaDownloader.cpp +++ b/launcher/java/download/ArchiveJavaDownloader.cpp @@ -21,9 +21,13 @@ #include "MMCZip.h" #include "Application.h" +#include "net/ChecksumValidator.h" #include "net/NetJob.h" #include "tasks/Task.h" +ArchiveJavaDownloader::ArchiveJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) + : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash){}; + void ArchiveJavaDownloader::executeTask() { // JRE found ! download the zip @@ -32,7 +36,15 @@ void ArchiveJavaDownloader::executeTask() MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", m_url.toLocalFile()); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); - download->addNetAction(Net::Download::makeCached(m_url, entry)); + auto action = Net::Download::makeCached(m_url, entry); + if (!m_checksum_hash.isEmpty() && !m_checksum_type.isEmpty()) { + auto hashType = QCryptographicHash::Algorithm::Sha1; + if (m_checksum_type == "sha256") { + hashType = QCryptographicHash::Algorithm::Sha256; + } + action->addValidator(new Net::ChecksumValidator(hashType, m_checksum_hash.toLatin1())); + } + download->addNetAction(action); auto fullPath = entry->getFullPath(); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); @@ -45,7 +57,7 @@ void ArchiveJavaDownloader::executeTask() extractJava(fullPath); }); download->start(); -}; +} void ArchiveJavaDownloader::extractJava(QString input) { @@ -85,4 +97,4 @@ void ArchiveJavaDownloader::extractJava(QString input) stepProgress(*progressStep); }); zipTask->start(); -}; +} \ No newline at end of file diff --git a/launcher/java/download/ArchiveJavaDownloader.h b/launcher/java/download/ArchiveJavaDownloader.h index d176570864..230f62b4d2 100644 --- a/launcher/java/download/ArchiveJavaDownloader.h +++ b/launcher/java/download/ArchiveJavaDownloader.h @@ -24,7 +24,7 @@ class ArchiveJavaDownloader : public Task { Q_OBJECT public: - ArchiveJavaDownloader(QUrl url, QString final_path); + ArchiveJavaDownloader(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); virtual ~ArchiveJavaDownloader() = default; [[nodiscard]] bool canAbort() const override { return true; } @@ -36,6 +36,8 @@ class ArchiveJavaDownloader : public Task { protected: QUrl m_url; QString m_final_path; + QString m_checksum_type; + QString m_checksum_hash; Task::Ptr m_current_task; }; \ No newline at end of file diff --git a/launcher/java/download/ManifestJavaDownloader.cpp b/launcher/java/download/ManifestJavaDownloader.cpp index 4f7dab94e5..08321ca7f6 100644 --- a/launcher/java/download/ManifestJavaDownloader.cpp +++ b/launcher/java/download/ManifestJavaDownloader.cpp @@ -30,14 +30,24 @@ struct File { bool isExec; }; -ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path) : m_url(url), m_final_path(final_path){}; +ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) + : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash){}; + void ManifestJavaDownloader::executeTask() { setStatus(tr("Downloading Java")); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); auto files = std::make_shared(); - download->addNetAction(Net::Download::makeByteArray(m_url, files)); + auto action = Net::Download::makeByteArray(m_url, files); + if (!m_checksum_hash.isEmpty() && !m_checksum_type.isEmpty()) { + auto hashType = QCryptographicHash::Algorithm::Sha1; + if (m_checksum_type == "sha256") { + hashType = QCryptographicHash::Algorithm::Sha256; + } + action->addValidator(new Net::ChecksumValidator(hashType, m_checksum_hash.toLatin1())); + } + download->addNetAction(action); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); connect(download.get(), &NetJob::progress, this, &ManifestJavaDownloader::progress); @@ -56,7 +66,7 @@ void ManifestJavaDownloader::executeTask() downloadJava(doc); }); download->start(); -}; +} void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc) { @@ -111,4 +121,4 @@ void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc) connect(this, &Task::aborted, elementDownload, &NetJob::abort); connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); -}; \ No newline at end of file +} \ No newline at end of file diff --git a/launcher/java/download/ManifestJavaDownloader.h b/launcher/java/download/ManifestJavaDownloader.h index 44e9ed9de4..d7114f4bd5 100644 --- a/launcher/java/download/ManifestJavaDownloader.h +++ b/launcher/java/download/ManifestJavaDownloader.h @@ -24,7 +24,7 @@ class ManifestJavaDownloader : public Task { Q_OBJECT public: - ManifestJavaDownloader(QUrl url, QString final_path); + ManifestJavaDownloader(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); virtual ~ManifestJavaDownloader() = default; [[nodiscard]] bool canAbort() const override { return true; } @@ -36,6 +36,8 @@ class ManifestJavaDownloader : public Task { protected: QUrl m_url; QString m_final_path; + QString m_checksum_type; + QString m_checksum_hash; Task::Ptr m_current_task; }; \ No newline at end of file diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index cdd1f7fd1f..2188112902 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -34,7 +34,11 @@ */ #include "VerifyJavaInstall.h" +#include +#include "Application.h" +#include "java/JavaInstall.h" +#include "java/JavaInstallList.h" #include "java/JavaVersion.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" @@ -46,6 +50,7 @@ void VerifyJavaInstall::executeTask() auto settings = instance->settings(); auto storedVersion = settings->get("JavaVersion").toString(); auto ignoreCompatibility = settings->get("IgnoreJavaCompatibility").toBool(); + auto automaticJavaSwitch = settings->get("AutomaticJavaSwitch").toBool(); auto compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors(); @@ -62,16 +67,38 @@ void VerifyJavaInstall::executeTask() return; } - emit logLine(tr("This instance is not compatible with Java version %1.\n" - "Please switch to one of the following Java versions for this instance:") - .arg(javaVersion.major()), - MessageLevel::Error); - for (auto major : compatibleMajors) { - emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); - } - emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what " - "you're doing."), - MessageLevel::Error); + auto logFail = [this, &javaVersion, compatibleMajors] { + emit logLine(tr("This instance is not compatible with Java version %1.\n" + "Please switch to one of the following Java versions for this instance:") + .arg(javaVersion.major()), + MessageLevel::Error); + for (auto major : compatibleMajors) { + emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); + } + emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what " + "you're doing."), + MessageLevel::Error); + + emitFailed(QString("Incompatible Java major version")); + }; - emitFailed(QString("Incompatible Java major version")); + if (automaticJavaSwitch || true) { + settings->set("OverrideJava", true); + auto javas = APPLICATION->javalist().get(); + auto task = javas->getLoadTask(); + connect(task.get(), &Task::finished, this, [this, javas, compatibleMajors, settings, &logFail] { + for (auto i = 0; i < javas->count(); i++) { + auto java = std::dynamic_pointer_cast(javas->at(i)); + if (java && compatibleMajors.contains(java->id.major())) { + settings->set("OverrideJavaLocation", true); + settings->set("JavaPath", java->path); + emitSucceeded(); + return; + } + } + logFail(); + }); + } else { + logFail(); + } } From 4cd236ed807e44666e6775126d27fef237eef168 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 26 Jan 2024 00:31:43 +0200 Subject: [PATCH 27/83] missing header Signed-off-by: Trial97 --- launcher/java/JavaChecker.cpp | 3 ++- launcher/java/JavaRuntime.h | 1 + launcher/java/download/ArchiveJavaDownloader.cpp | 3 ++- launcher/java/download/ManifestJavaDownloader.cpp | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 7271c0d093..18f93d256a 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -44,7 +44,8 @@ #include "java/JavaUtils.h" JavaChecker::JavaChecker(QString path, QString args, int minMem, int maxMem, int permGen, int id, QObject* parent) - : Task(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen), m_id(id){}; + : Task(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen), m_id(id) +{} void JavaChecker::executeTask() { diff --git a/launcher/java/JavaRuntime.h b/launcher/java/JavaRuntime.h index b44b546b6d..4c4efa2886 100644 --- a/launcher/java/JavaRuntime.h +++ b/launcher/java/JavaRuntime.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include diff --git a/launcher/java/download/ArchiveJavaDownloader.cpp b/launcher/java/download/ArchiveJavaDownloader.cpp index 32a3c39d27..5350fc4e6e 100644 --- a/launcher/java/download/ArchiveJavaDownloader.cpp +++ b/launcher/java/download/ArchiveJavaDownloader.cpp @@ -26,7 +26,8 @@ #include "tasks/Task.h" ArchiveJavaDownloader::ArchiveJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) - : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash){}; + : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash) +{} void ArchiveJavaDownloader::executeTask() { diff --git a/launcher/java/download/ManifestJavaDownloader.cpp b/launcher/java/download/ManifestJavaDownloader.cpp index 08321ca7f6..368d6431c3 100644 --- a/launcher/java/download/ManifestJavaDownloader.cpp +++ b/launcher/java/download/ManifestJavaDownloader.cpp @@ -31,7 +31,8 @@ struct File { }; ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) - : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash){}; + : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash) +{} void ManifestJavaDownloader::executeTask() { From 7317105e4d8c7a65f4a722dbebf8d5e3247f80dc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 27 Jan 2024 22:47:28 +0200 Subject: [PATCH 28/83] Code spaghetti and more chaos Signed-off-by: Trial97 --- launcher/BaseVersionList.cpp | 1 + launcher/BaseVersionList.h | 1 + launcher/CMakeLists.txt | 8 +- launcher/JavaDownloader.cpp | 332 ------------------ launcher/JavaDownloader.h | 28 -- launcher/SysInfo.cpp | 43 ++- launcher/SysInfo.h | 1 + launcher/VersionProxyModel.cpp | 9 + launcher/VersionProxyModel.h | 2 +- launcher/java/JavaRuntime.cpp | 2 +- launcher/java/JavaVersion.cpp | 21 +- .../java/download/ArchiveJavaDownloader.cpp | 2 +- .../java/download/ManifestJavaDownloader.cpp | 2 +- launcher/ui/java/JavaDownload.cpp | 103 ++++++ launcher/ui/java/JavaDownload.h | 48 +++ launcher/ui/java/JavaDownload.ui | 100 ++++++ launcher/ui/java/ListModel.cpp | 154 ++++++++ launcher/ui/java/ListModel.h | 132 +++++++ launcher/ui/pages/global/JavaPage.cpp | 5 +- .../pages/instance/InstanceSettingsPage.cpp | 5 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 5 +- 21 files changed, 613 insertions(+), 391 deletions(-) delete mode 100644 launcher/JavaDownloader.cpp delete mode 100644 launcher/JavaDownloader.h create mode 100644 launcher/ui/java/JavaDownload.cpp create mode 100644 launcher/ui/java/JavaDownload.h create mode 100644 launcher/ui/java/JavaDownload.ui create mode 100644 launcher/ui/java/ListModel.cpp create mode 100644 launcher/ui/java/ListModel.h diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index e11560d5ec..576c3a413d 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -110,6 +110,7 @@ QHash BaseVersionList::roleNames() const roles.insert(TypeRole, "type"); roles.insert(BranchRole, "branch"); roles.insert(PathRole, "path"); + roles.insert(AliasRole, "alias"); roles.insert(ArchitectureRole, "architecture"); return roles; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index 231887c4ea..c59d705707 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -48,6 +48,7 @@ class BaseVersionList : public QAbstractListModel { TypeRole, BranchRole, PathRole, + AliasRole, ArchitectureRole, SortRole }; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ac3f8eb68a..d703b82637 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -437,6 +437,11 @@ set(JAVA_SOURCES java/download/ArchiveJavaDownloader.h java/download/ManifestJavaDownloader.cpp java/download/ManifestJavaDownloader.h + + ui/java/JavaDownload.h + ui/java/JavaDownload.cpp + ui/java/ListModel.h + ui/java/ListModel.cpp ) set(TRANSLATIONS_SOURCES @@ -1107,8 +1112,6 @@ SET(LAUNCHER_SOURCES ui/instanceview/InstanceDelegate.h ui/instanceview/VisualGroup.cpp ui/instanceview/VisualGroup.h - JavaDownloader.cpp - JavaDownloader.h ) if (NOT Apple) @@ -1189,6 +1192,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ScrollMessageBox.ui ui/dialogs/BlockedModsDialog.ui ui/dialogs/ChooseProviderDialog.ui + ui/java/JavaDownload.ui ) qt_wrap_ui(PRISM_UPDATE_UI diff --git a/launcher/JavaDownloader.cpp b/launcher/JavaDownloader.cpp deleted file mode 100644 index e4f4b5f09f..0000000000 --- a/launcher/JavaDownloader.cpp +++ /dev/null @@ -1,332 +0,0 @@ -#include "JavaDownloader.h" -#include -#include -#include -#include -#include "Application.h" -#include "FileSystem.h" -#include "InstanceList.h" -#include "Json.h" -#include "MMCZip.h" -#include "SysInfo.h" -#include "net/ChecksumValidator.h" -#include "net/NetJob.h" -#include "ui/dialogs/ProgressDialog.h" - -// Quick & dirty struct to store files -struct File { - QString path; - QString url; - QByteArray hash; - bool isExec; -}; - -void JavaDownloader::executeTask() -{ - auto OS = m_OS; - auto isLegacy = m_isLegacy; - - downloadMojangJavaList(OS, isLegacy); -} -void JavaDownloader::downloadMojangJavaList(const QString& OS, bool isLegacy) -{ - auto netJob = makeShared(QString("JRE::QueryVersions"), APPLICATION->network()); - auto response = std::make_shared(); - setStatus(tr("Querying mojang meta")); - netJob->addNetAction(Net::Download::makeByteArray( - QUrl("https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"), response)); - - connect(this, &Task::aborted, [isLegacy] { - QDir(FS::PathCombine(QCoreApplication::applicationDirPath(), "java", (isLegacy ? "java-legacy" : "java-current"))) - .removeRecursively(); - }); - - connect(netJob.get(), &NetJob::finished, [netJob, response, this] { - // delete so that it's not called on a deleted job - // FIXME: is this needed? qt should handle this - disconnect(this, &Task::aborted, netJob.get(), &NetJob::abort); - }); - connect(netJob.get(), &NetJob::progress, this, &JavaDownloader::progress); - connect(netJob.get(), &NetJob::failed, this, &JavaDownloader::emitFailed); - - connect(this, &Task::aborted, netJob.get(), &NetJob::abort); - - connect(netJob.get(), &NetJob::succeeded, [response, OS, isLegacy, this, netJob] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *response; - return; - } - auto versionArray = Json::ensureArray(Json::ensureObject(doc.object(), OS), isLegacy ? "jre-legacy" : "java-runtime-gamma"); - if (!versionArray.empty()) { - parseMojangManifest(isLegacy, versionArray); - - } else { - // mojang does not have a JRE for us, let's get azul zulu - downloadAzulMeta(OS, isLegacy, netJob.get()); - } - }); - - netJob->start(); -} -void JavaDownloader::parseMojangManifest(bool isLegacy, const QJsonArray& versionArray) -{ - setStatus(tr("Downloading Java from Mojang")); - auto url = Json::ensureString(Json::ensureObject(Json::ensureObject(versionArray[0]), "manifest"), "url"); - auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); - auto files = std::make_shared(); - - download->addNetAction(Net::Download::makeByteArray(QUrl(url), files)); - - connect(download.get(), &NetJob::finished, - [download, files, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &JavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &JavaDownloader::emitFailed); - connect(this, &Task::aborted, download.get(), &NetJob::abort); - - connect(download.get(), &NetJob::succeeded, [files, isLegacy, this] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *files; - return; - } - downloadMojangJava(isLegacy, doc); - }); - download->start(); -} -void JavaDownloader::downloadMojangJava(bool isLegacy, const QJsonDocument& doc) -{ // valid json doc, begin making jre spot - auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), (isLegacy ? "java-legacy" : "java-current")); - FS::ensureFolderPathExists(output); - std::vector toDownload; - auto list = Json::ensureObject(Json::ensureObject(doc.object()), "files"); - for (const auto& paths : list.keys()) { - auto file = FS::PathCombine(output, paths); - - const QJsonObject& meta = Json::ensureObject(list, paths); - auto type = Json::ensureString(meta, "type"); - if (type == "directory") { - FS::ensureFolderPathExists(file); - } else if (type == "link") { - // this is linux only ! - auto path = Json::ensureString(meta, "target"); - if (!path.isEmpty()) { - auto target = FS::PathCombine(file, "../" + path); - QFile(target).link(file); - } - } else if (type == "file") { - // TODO download compressed version if it exists ? - auto raw = Json::ensureObject(Json::ensureObject(meta, "downloads"), "raw"); - auto isExec = Json::ensureBoolean(meta, "executable", false); - auto url = Json::ensureString(raw, "url"); - if (!url.isEmpty() && QUrl(url).isValid()) { - auto f = File{ file, url, QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec }; - toDownload.push_back(f); - } - } - } - auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); - for (const auto& file : toDownload) { - auto dl = Net::Download::makeFile(file.url, file.path); - if (!file.hash.isEmpty()) { - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash)); - } - if (file.isExec) { - connect(dl.get(), &Net::Download::succeeded, - [file] { QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); }); - } - elementDownload->addNetAction(dl); - } - connect(elementDownload, &NetJob::finished, [elementDownload, this] { - disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); - elementDownload->deleteLater(); - }); - connect(elementDownload, &NetJob::progress, this, &JavaDownloader::progress); - connect(elementDownload, &NetJob::failed, this, &JavaDownloader::emitFailed); - - connect(this, &Task::aborted, elementDownload, &NetJob::abort); - connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); - elementDownload->start(); -} -void JavaDownloader::downloadAzulMeta(const QString& OS, bool isLegacy, const NetJob* netJob) -{ - setStatus(tr("Querying Azul meta")); - QString javaVersion = isLegacy ? QString("8.0") : QString("17.0"); - - QString azulOS; - QString arch; - QString bitness; - - mojangOStoAzul(OS, azulOS, arch, bitness); - auto metaResponse = std::make_shared(); - auto downloadJob = makeShared(QString("JRE::QueryAzulMeta"), APPLICATION->network()); - downloadJob->addNetAction( - Net::Download::makeByteArray(QString("https://api.azul.com/zulu/download/community/v1.0/bundles/?" - "java_version=%1" - "&os=%2" - "&arch=%3" - "&hw_bitness=%4" - "&ext=zip" // as a zip for all os, even linux NOTE !! Linux ARM is .deb or .tar.gz only !! - "&bundle_type=jre" // jre only - "&latest=true" // only get the one latest entry - ) - .arg(javaVersion, azulOS, arch, bitness), - metaResponse)); - connect(downloadJob.get(), &NetJob::finished, - [downloadJob, metaResponse, this] { disconnect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); }); - connect(this, &Task::aborted, downloadJob.get(), &NetJob::abort); - connect(netJob, &NetJob::failed, this, &JavaDownloader::emitFailed); - connect(downloadJob.get(), &NetJob::progress, this, &JavaDownloader::progress); - connect(downloadJob.get(), &NetJob::succeeded, [metaResponse, isLegacy, this] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*metaResponse, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *metaResponse; - return; - } - auto array = Json::ensureArray(doc.array()); - if (!array.empty()) { - downloadAzulJava(isLegacy, array); - } else { - emitFailed(tr("No suitable JRE found")); - } - }); - downloadJob->start(); -} -void JavaDownloader::mojangOStoAzul(const QString& OS, QString& azulOS, QString& arch, QString& bitness) -{ - if (OS == "mac-os-arm64") { - // macos arm64 - azulOS = "macos"; - arch = "arm"; - bitness = "64"; - } else if (OS == "linux-arm64") { - // linux arm64 - azulOS = "linux"; - arch = "arm"; - bitness = "64"; - } else if (OS == "linux-arm") { - // linux arm (32) - azulOS = "linux"; - arch = "arm"; - bitness = "32"; - } else if (OS == "linux") { - // linux x86 64 (used for debugging, should never reach here) - azulOS = "linux"; - arch = "x86"; - bitness = "64"; - } -} -void JavaDownloader::downloadAzulJava(bool isLegacy, const QJsonArray& array) -{ // JRE found ! download the zip - setStatus(tr("Downloading Java from Azul")); - auto downloadURL = QUrl(array[0].toObject()["url"].toString()); - auto download = new NetJob(QString("JRE::DownloadJava"), APPLICATION->network()); - auto path = APPLICATION->instances()->getStagedInstancePath(); - auto temp = FS::PathCombine(path, "azulJRE.zip"); - - download->addNetAction(Net::Download::makeFile(downloadURL, temp)); - connect(download, &NetJob::finished, [download, this] { - disconnect(this, &Task::aborted, download, &NetJob::abort); - download->deleteLater(); - }); - connect(download, &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); - connect(download, &NetJob::progress, this, &JavaDownloader::progress); - connect(download, &NetJob::failed, this, [this, path](QString reason) { - APPLICATION->instances()->destroyStagingPath(path); - emitFailed(std::move(reason)); - }); - connect(this, &Task::aborted, download, &NetJob::abort); - connect(download, &NetJob::succeeded, [isLegacy, temp, downloadURL, path, this] { - setStatus(tr("Extracting java")); - auto output = FS::PathCombine(QCoreApplication::applicationDirPath(), "java", isLegacy ? "java-legacy" : "java-current"); - // This should do all of the extracting and creating folders - MMCZip::extractDir(temp, downloadURL.fileName().chopped(4), output); - APPLICATION->instances()->destroyStagingPath(path); - emitSucceeded(); - }); - download->start(); -} -void JavaDownloader::showPrompts(QWidget* parent) -{ - QString sys = SysInfo::currentSystem(); - if (sys == "osx") { - sys = "mac-os"; - } - QString arch = SysInfo::useQTForArch(); - QString version; - if (sys == "windows") { - if (arch == "x86_64") { - version = "windows-x64"; - } else if (arch == "i386") { - version = "windows-x86"; - } else { - // Unknown, maybe arm, appending arch for downloader - version = "windows-" + arch; - } - } else if (sys == "mac-os") { - if (arch == "arm64") { - version = "mac-os-arm64"; - } else { - version = "mac-os"; - } - } else if (sys == "linux") { - if (arch == "x86_64") { - version = "linux"; - } else { - // will work for i386, and arm(64) - version = "linux-" + arch; - } - } else { - // ? ? ? ? ? unknown os, at least it won't have a java version on mojang or azul, display warning - QMessageBox::warning(parent, tr("Unknown OS"), - tr("The OS you are running is not supported by Mojang or Azul. Please install Java manually.")); - return; - } - // Selection using QMessageBox for java 8 or 17 - QMessageBox box( - QMessageBox::Icon::Question, tr("Java version"), - tr("Do you want to download Java version 8 or 17?\n Java 8 is recommended for older Minecraft versions, below 1.17\n Java 17 " - "is recommended for newer Minecraft versions, starting from 1.17"), - QMessageBox::NoButton, parent); - auto yes = box.addButton("Java 17", QMessageBox::AcceptRole); - auto no = box.addButton("Java 8", QMessageBox::AcceptRole); - auto both = box.addButton(tr("Download both"), QMessageBox::AcceptRole); - auto cancel = box.addButton(QMessageBox::Cancel); - - if (QFileInfo::exists(FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), "java-legacy"))) { - no->setEnabled(false); - } - if (QFileInfo::exists(FS::PathCombine(QCoreApplication::applicationDirPath(), QString("java"), "java-current"))) { - yes->setEnabled(false); - } - if (!yes->isEnabled() || !no->isEnabled()) { - both->setEnabled(false); - } - if (!yes->isEnabled() && !no->isEnabled()) { - QMessageBox::information(parent, tr("Already installed!"), tr("Both versions of Java are already installed!")); - return; - } - box.exec(); - if (box.clickedButton() == nullptr || box.clickedButton() == cancel) { - return; - } - bool isLegacy = box.clickedButton() == no; - - auto down = new JavaDownloader(isLegacy, version); - ProgressDialog dialog(parent); - dialog.setSkipButton(true, tr("Abort")); - bool finished_successfully = dialog.execWithTask(down); - // Run another download task for the other option as well! - if (finished_successfully && box.clickedButton() == both) { - auto dwn = new JavaDownloader(false, version); - ProgressDialog dg(parent); - dg.setSkipButton(true, tr("Abort")); - dg.execWithTask(dwn); - } -} diff --git a/launcher/JavaDownloader.h b/launcher/JavaDownloader.h deleted file mode 100644 index 54f058970d..0000000000 --- a/launcher/JavaDownloader.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include "net/NetJob.h" -#include "tasks/Task.h" - -class JavaDownloader : public Task { - Q_OBJECT - public: - /*Downloads the java to the runtimes folder*/ - explicit JavaDownloader(bool isLegacy, const QString& OS) : m_isLegacy(isLegacy), m_OS(OS) {} - - void executeTask() override; - [[nodiscard]] bool canAbort() const override { return true; } - static void showPrompts(QWidget* parent = nullptr); - - private: - bool m_isLegacy; - const QString& m_OS; - - void downloadMojangJavaList(const QString& OS, bool isLegacy); - void parseMojangManifest(bool isLegacy, const QJsonArray& versionArray); - void downloadMojangJava(bool isLegacy, const QJsonDocument& doc); - - static void mojangOStoAzul(const QString& OS, QString& azulOS, QString& arch, QString& bitness); - void downloadAzulMeta(const QString& OS, bool isLegacy, const NetJob* netJob); - void downloadAzulJava(bool isLegacy, const QJsonArray& array); -}; diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp index f15dde0e4f..0dfa74de7f 100644 --- a/launcher/SysInfo.cpp +++ b/launcher/SysInfo.cpp @@ -17,13 +17,7 @@ bool rosettaDetect() if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) { return false; } - if (ret == 0) { - return false; - } - if (ret == 1) { - return true; - } - return false; + return ret == 1; } #endif @@ -47,7 +41,6 @@ QString currentSystem() QString useQTForArch() { - auto qtArch = QSysInfo::currentCpuArchitecture(); #if defined(Q_OS_MACOS) && !defined(Q_PROCESSOR_ARM) if (rosettaDetect()) { return "arm64"; @@ -55,7 +48,7 @@ QString useQTForArch() return "x86_64"; } #endif - return qtArch; + return QSysInfo::currentCpuArchitecture(); } int suitableMaxMem() @@ -71,4 +64,36 @@ int suitableMaxMem() return maxMemoryAlloc; } + +QString getSupportedJavaArchitecture() +{ + auto sys = currentSystem(); + auto arch = useQTForArch(); + if (sys == "windows") { + if (arch == "x86_64") + return "windows-x64"; + if (arch == "i386") + return "windows-x86"; + // Unknown, maybe arm, appending arch + return "windows-" + arch; + } + if (sys == "osx") { + if (arch == "arm64") + return "mac-os-arm64"; + if (arch.contains("64")) + return "mac-os-64"; + if (arch.contains("86")) + return "mac-os-86"; + // Unknown, maybe something new, appending arch + return "mac-os-" + arch; + } else if (sys == "linux") { + if (arch == "x86_64") + return "linux-x64"; + if (arch == "i386") + return "linux-x86"; + // will work for arm32 arm(64) + return "linux-" + arch; + } + return {}; +} } // namespace SysInfo diff --git a/launcher/SysInfo.h b/launcher/SysInfo.h index 499c3b1dd1..f3688d60d6 100644 --- a/launcher/SysInfo.h +++ b/launcher/SysInfo.h @@ -3,5 +3,6 @@ namespace SysInfo { QString currentSystem(); QString useQTForArch(); +QString getSupportedJavaArchitecture(); int suitableMaxMem(); } // namespace SysInfo diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 0ab9ae2c3b..f1218f162d 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -118,6 +118,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Architecture"); case Path: return tr("Path"); + case Alias: + return tr("Alias"); case Time: return tr("Released"); } @@ -135,6 +137,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("CPU Architecture"); case Path: return tr("Filesystem path to this version"); + case Alias: + return tr("The alternative name of the java version"); case Time: return tr("Release date of this version"); } @@ -169,6 +173,8 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::ArchitectureRole); case Path: return sourceModel()->data(parentIndex, BaseVersionList::PathRole); + case Alias: + return sourceModel()->data(parentIndex, BaseVersionList::AliasRole); case Time: return sourceModel()->data(parentIndex, Meta::VersionList::TimeRole).toDate(); default: @@ -314,6 +320,9 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) if (roles.contains(BaseVersionList::PathRole)) { m_columns.push_back(Path); } + if (roles.contains(BaseVersionList::AliasRole)) { + m_columns.push_back(Alias); + } if (roles.contains(Meta::VersionList::TimeRole)) { m_columns.push_back(Time); } diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 0863a7c800..2dc35a6253 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -9,7 +9,7 @@ class VersionFilterModel; class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT public: - enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time }; + enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time, Alias }; using FilterMap = QHash>; public: diff --git a/launcher/java/JavaRuntime.cpp b/launcher/java/JavaRuntime.cpp index 78651e9911..be13f47e43 100644 --- a/launcher/java/JavaRuntime.cpp +++ b/launcher/java/JavaRuntime.cpp @@ -62,7 +62,7 @@ MetaPtr parseJavaMeta(const QJsonObject& in) } if (in.contains("version")) { - auto obj = Json::requireObject(in, "checksum"); + auto obj = Json::requireObject(in, "version"); auto name = Json::ensureString(obj, "name", ""); auto major = Json::ensureInteger(obj, "major", 0); auto minor = Json::ensureInteger(obj, "minor", 0); diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index 3de6f5ad6a..f3ded97099 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -113,19 +113,20 @@ bool JavaVersion::operator>(const JavaVersion& rhs) JavaVersion::JavaVersion(int major, int minor, int security, int build, QString name) : m_major(major), m_minor(minor), m_security(security), m_name(name), m_parseable(true) { + QStringList versions; if (build != 0) { m_prerelease = QString::number(build); - m_string = m_prerelease; + versions.push_front(m_prerelease); } if (m_security != 0) - m_string = QString::number(m_security) + "." + m_string; - else if (!m_string.isEmpty()) { - m_string = "0." + m_string; - } + versions.push_front(QString::number(m_security)); + else if (!versions.isEmpty()) + versions.push_front("0"); + if (m_minor != 0) - m_string = QString::number(m_minor) + "." + m_string; - else if (!m_string.isEmpty()) { - m_string = "0." + m_string; - } - m_string = QString::number(m_major) + "." + m_string; + versions.push_front(QString::number(m_minor)); + else if (!versions.isEmpty()) + versions.push_front("0"); + versions.push_front(QString::number(m_major)); + m_string = versions.join("."); } diff --git a/launcher/java/download/ArchiveJavaDownloader.cpp b/launcher/java/download/ArchiveJavaDownloader.cpp index 5350fc4e6e..bee65cf913 100644 --- a/launcher/java/download/ArchiveJavaDownloader.cpp +++ b/launcher/java/download/ArchiveJavaDownloader.cpp @@ -43,7 +43,7 @@ void ArchiveJavaDownloader::executeTask() if (m_checksum_type == "sha256") { hashType = QCryptographicHash::Algorithm::Sha256; } - action->addValidator(new Net::ChecksumValidator(hashType, m_checksum_hash.toLatin1())); + action->addValidator(new Net::ChecksumValidator(hashType, QByteArray::fromHex(m_checksum_hash.toUtf8()))); } download->addNetAction(action); auto fullPath = entry->getFullPath(); diff --git a/launcher/java/download/ManifestJavaDownloader.cpp b/launcher/java/download/ManifestJavaDownloader.cpp index 368d6431c3..c0b7942a7c 100644 --- a/launcher/java/download/ManifestJavaDownloader.cpp +++ b/launcher/java/download/ManifestJavaDownloader.cpp @@ -46,7 +46,7 @@ void ManifestJavaDownloader::executeTask() if (m_checksum_type == "sha256") { hashType = QCryptographicHash::Algorithm::Sha256; } - action->addValidator(new Net::ChecksumValidator(hashType, m_checksum_hash.toLatin1())); + action->addValidator(new Net::ChecksumValidator(hashType, QByteArray::fromHex(m_checksum_hash.toUtf8()))); } download->addNetAction(action); diff --git a/launcher/ui/java/JavaDownload.cpp b/launcher/ui/java/JavaDownload.cpp new file mode 100644 index 0000000000..c03fb10e81 --- /dev/null +++ b/launcher/ui/java/JavaDownload.cpp @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 "JavaDownload.h" +#include +#include +#include +#include +#include +#include "Application.h" +#include "BaseVersionList.h" +#include "FileSystem.h" +#include "QObjectPtr.h" +#include "SysInfo.h" +#include "java/JavaInstallList.h" +#include "java/download/ArchiveJavaDownloader.h" +#include "java/download/ManifestJavaDownloader.h" +#include "meta/Index.h" +#include "meta/Version.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/java/ListModel.h" +#include "ui_JavaDownload.h" + +JavaDownload::JavaDownload(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownload) +{ + ui->setupUi(this); + ui->widget->initialize(new Java::JavaBaseVersionList("net.minecraft.java")); + ui->widget->selectCurrent(); + connect(ui->widget, &VersionSelectWidget::selectedVersionChanged, this, &JavaDownload::setSelectedVersion); + auto reset = ui->buttonBox->button(QDialogButtonBox::Reset); + connect(reset, &QPushButton::clicked, this, &JavaDownload::refresh); + connect(ui->widget_2, &VersionSelectWidget::selectedVersionChanged, this, &JavaDownload::setSelectedVersion2); +} + +JavaDownload::~JavaDownload() +{ + delete ui; +} + +void JavaDownload::setSelectedVersion(BaseVersion::Ptr version) +{ + if (!version) + return; + auto dcast = std::dynamic_pointer_cast(version); + if (!dcast) { + return; + } + ui->widget_2->initialize(new Java::InstallList(dcast, this)); + ui->widget_2->selectCurrent(); +} + +void JavaDownload::setSelectedVersion2(BaseVersion::Ptr version) +{ + if (!version) + return; + m_selectedVersion = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); +} +void JavaDownload::accept() +{ + if (!m_selectedVersion) { + m_selectedVersion = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); + qDebug() << "=========?" << (ui->widget_2->selectedVersion() != nullptr); + } + if (!m_selectedVersion) { + qDebug() << "faillllllllllllllllllllllllllll"; + return; + } + auto meta = m_selectedVersion->meta; + Task::Ptr task; + auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->name); + qDebug() << "===============>>=>>" << meta->checksumType << meta->checksumHash; + switch (meta->downloadType) { + case JavaRuntime::DownloadType::Manifest: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + case JavaRuntime::DownloadType::Archive: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + } + ProgressDialog pg(this); + pg.execWithTask(task.get()); + QDialog::accept(); +} + +void JavaDownload::refresh() +{ + ui->widget->loadList(); +} diff --git a/launcher/ui/java/JavaDownload.h b/launcher/ui/java/JavaDownload.h new file mode 100644 index 0000000000..916d6b4952 --- /dev/null +++ b/launcher/ui/java/JavaDownload.h @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 +#include "BaseVersion.h" +#include "ui/java/ListModel.h" + +namespace Ui { +class JavaDownload; +} + +class JavaDownload : public QDialog { + Q_OBJECT + + public: + explicit JavaDownload(QWidget* parent = 0); + ~JavaDownload(); + + void accept(); + + public slots: + void refresh(); + + protected slots: + void setSelectedVersion(BaseVersion::Ptr version); + void setSelectedVersion2(BaseVersion::Ptr version); + + private: + Ui::JavaDownload* ui; + Java::JavaRuntimePtr m_selectedVersion; +}; diff --git a/launcher/ui/java/JavaDownload.ui b/launcher/ui/java/JavaDownload.ui new file mode 100644 index 0000000000..bbc638e9bb --- /dev/null +++ b/launcher/ui/java/JavaDownload.ui @@ -0,0 +1,100 @@ + + + JavaDownload + + + + 0 + 0 + 821 + 593 + + + + Dialog + + + + + + + + Major + + + + + + + + + + + + Runtime + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry + + + + + + + + VersionSelectWidget + QWidget +
ui/widgets/VersionSelectWidget.h
+ 1 +
+
+ + + + buttonBox + accepted() + JavaDownload + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + JavaDownload + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/launcher/ui/java/ListModel.cpp b/launcher/ui/java/ListModel.cpp new file mode 100644 index 0000000000..71f8765eb0 --- /dev/null +++ b/launcher/ui/java/ListModel.cpp @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 "ListModel.h" +#include +#include +#include "BaseVersionList.h" +#include "StringUtils.h" +#include "SysInfo.h" + +namespace Java { + +InstallList::InstallList(Meta::Version::Ptr version, QObject* parent) : BaseVersionList(parent), m_version(version) +{ + if (version->isLoaded()) + sortVersions(); +} + +Task::Ptr InstallList::getLoadTask() +{ + m_version->load(Net::Mode::Online); + auto task = m_version->getCurrentTask(); + connect(task.get(), &Task::finished, this, &InstallList::sortVersions); + return task; +} + +const BaseVersion::Ptr InstallList::at(int i) const +{ + return m_vlist.at(i); +} + +bool InstallList::isLoaded() +{ + return m_version->isLoaded(); +} + +int InstallList::count() const +{ + return m_vlist.count(); +} + +QVariant InstallList::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() > count()) + return QVariant(); + + auto version = (m_vlist[index.row()]); + switch (role) { + case SortRole: + return -index.row(); + case VersionPointerRole: + return QVariant::fromValue(std::dynamic_pointer_cast(m_vlist[index.row()])); + case VersionIdRole: + return version->descriptor(); + case VersionRole: + return version->meta->version.toString(); + case RecommendedRole: + return version->meta->recommended; + case AliasRole: + return version->meta->name; + case ArchitectureRole: + return version->meta->vendor; + default: + return QVariant(); + } +} + +BaseVersionList::RoleList InstallList::providesRoles() const +{ + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, AliasRole, ArchitectureRole }; +} + +bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) +{ + auto rleft = std::dynamic_pointer_cast(right); + auto rright = std::dynamic_pointer_cast(left); + return (*rleft) > (*rright); +} + +void InstallList::sortVersions() +{ + QString versionStr = SysInfo::getSupportedJavaArchitecture(); + beginResetModel(); + auto runtimes = m_version->data()->runtimes; + if (versionStr.isEmpty() || !runtimes.contains(versionStr)) { + return; + } + auto javaruntimes = runtimes.value(versionStr); + for (auto v : javaruntimes) { + m_vlist.append(std::make_shared(v)); + } + std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); + endResetModel(); +} + +bool JavaRuntime2::operator<(const JavaRuntime2& rhs) +{ + auto id = meta->version; + if (id < rhs.meta->version) { + return true; + } + if (id > rhs.meta->version) { + return false; + } + return StringUtils::naturalCompare(meta->name, rhs.meta->name, Qt::CaseInsensitive) < 0; +} + +bool JavaRuntime2::operator==(const JavaRuntime2& rhs) +{ + return meta->version == rhs.meta->version && meta->name == rhs.meta->name; +} + +bool JavaRuntime2::operator>(const JavaRuntime2& rhs) +{ + return (!operator<(rhs)) && (!operator==(rhs)); +} + +bool JavaRuntime2::operator<(BaseVersion& a) +{ + try { + return operator<(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator<(a); + } +} + +bool JavaRuntime2::operator>(BaseVersion& a) +{ + try { + return operator>(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator>(a); + } +} + +} // namespace Java diff --git a/launcher/ui/java/ListModel.h b/launcher/ui/java/ListModel.h new file mode 100644 index 0000000000..3685d611d8 --- /dev/null +++ b/launcher/ui/java/ListModel.h @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 +#include +#include +#include "java/JavaRuntime.h" +#include "meta/VersionList.h" + +namespace Java { + +class JavaBaseVersionList : public Meta::VersionList { + Q_OBJECT + public: + explicit JavaBaseVersionList(const QString& uid, QObject* parent = nullptr) : VersionList(uid, parent) {} + BaseVersionList::RoleList providesRoles() const { return { VersionRole, RecommendedRole, VersionPointerRole }; } +}; + +struct JavaRuntime2 : public BaseVersion { + JavaRuntime2() {} + JavaRuntime2(JavaRuntime::MetaPtr m) : meta(m) {} + virtual QString descriptor() override { return meta->version.toString(); } + + virtual QString name() override { return meta->name; } + + virtual QString typeString() const override { return meta->vendor; } + + virtual bool operator<(BaseVersion& a) override; + virtual bool operator>(BaseVersion& a) override; + bool operator<(const JavaRuntime2& rhs); + bool operator==(const JavaRuntime2& rhs); + bool operator>(const JavaRuntime2& rhs); + + JavaRuntime::MetaPtr meta; +}; + +using JavaRuntimePtr = std::shared_ptr; + +class InstallList : public BaseVersionList { + Q_OBJECT + + public: + explicit InstallList(Meta::Version::Ptr m_version, QObject* parent = 0); + + Task::Ptr getLoadTask() override; + bool isLoaded() override; + const BaseVersion::Ptr at(int i) const override; + int count() const override; + void sortVersions() override; + + QVariant data(const QModelIndex& index, int role) const override; + RoleList providesRoles() const override; + + protected slots: + void updateListData(QList) override {} + + protected: + Meta::Version::Ptr m_version; + QList m_vlist; +}; + +} // namespace Java +// class FilterModel : public QSortFilterProxyModel { +// Q_OBJECT +// public: +// FilterModel(QObject* parent = Q_NULLPTR); +// enum Sorting { ByName, ByGameVersion }; +// const QMap getAvailableSortings(); +// QString translateCurrentSorting(); +// void setSorting(Sorting sorting); +// Sorting getCurrentSorting(); +// void setSearchTerm(QString term); + +// protected: +// bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; +// bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; + +// private: +// QMap sortings; +// Sorting currentSorting; +// QString searchTerm; +// }; + +// class ListModel : public QAbstractListModel { +// Q_OBJECT +// private: +// ModpackList modpacks; +// QStringList m_failedLogos; +// QStringList m_loadingLogos; +// FTBLogoMap m_logoMap; +// QMap waitingCallbacks; + +// void requestLogo(QString file); +// QString translatePackType(PackType type) const; + +// private slots: +// void logoFailed(QString logo); +// void logoLoaded(QString logo, QIcon out); + +// public: +// ListModel(QObject* parent); +// ~ListModel(); +// int rowCount(const QModelIndex& parent) const override; +// int columnCount(const QModelIndex& parent) const override; +// QVariant data(const QModelIndex& index, int role) const override; +// Qt::ItemFlags flags(const QModelIndex& index) const override; + +// void fill(ModpackList modpacks); +// void addPack(Modpack modpack); +// void clear(); +// void remove(int row); + +// Modpack at(int row); +// void getLogo(const QString& logo, LogoCallback callback); +// }; diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 0f05b6c8f0..09c951a3cc 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -36,6 +36,7 @@ #include "JavaPage.h" #include "JavaCommon.h" +#include "ui/java/JavaDownload.h" #include "ui_JavaPage.h" #include @@ -51,7 +52,6 @@ #include #include #include "Application.h" -#include "JavaDownloader.h" #include "settings/SettingsObject.h" JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) @@ -169,7 +169,8 @@ void JavaPage::on_javaTestBtn_clicked() void JavaPage::on_javaDownloadBtn_clicked() { - JavaDownloader::showPrompts(this); + auto jdialog = new JavaDownload(this); + jdialog->exec(); } void JavaPage::on_maxMemSpinBox_valueChanged([[maybe_unused]] int i) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index a386a3bfe3..df380bfb3e 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -36,6 +36,7 @@ */ #include "InstanceSettingsPage.h" +#include "ui/java/JavaDownload.h" #include "ui_InstanceSettingsPage.h" #include @@ -53,7 +54,6 @@ #include "minecraft/auth/AccountList.h" #include "FileSystem.h" -#include "JavaDownloader.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" @@ -387,7 +387,8 @@ void InstanceSettingsPage::loadSettings() void InstanceSettingsPage::on_javaDownloadBtn_clicked() { - JavaDownloader::showPrompts(this); + auto jdialog = new JavaDownload(this); + jdialog->exec(); } void InstanceSettingsPage::on_javaDetectBtn_clicked() diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 909ad7a017..7405ad1147 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -13,13 +13,13 @@ #include "FileSystem.h" #include "JavaCommon.h" -#include "JavaDownloader.h" #include "java/JavaChecker.h" #include "java/JavaInstall.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" #include "ui/dialogs/CustomMessageBox.h" +#include "ui/java/JavaDownload.h" #include "ui/widgets/VersionSelectWidget.h" #include "Application.h" @@ -274,7 +274,8 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() } void JavaSettingsWidget::on_javaDownloadBtn_clicked() { - JavaDownloader::showPrompts(this); + auto jdialog = new JavaDownload(this); + jdialog->exec(); } void JavaSettingsWidget::on_javaStatusBtn_clicked() { From 5afe75e821516dbbde60d1b2d3a627a0d243b1fe Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 30 Jan 2024 12:37:34 +0200 Subject: [PATCH 29/83] Fixed some codeql warnings Signed-off-by: Trial97 --- launcher/JavaCommon.cpp | 4 ++-- launcher/JavaCommon.h | 4 ++-- launcher/java/JavaChecker.h | 2 +- launcher/java/JavaInstallList.cpp | 4 ++-- launcher/java/JavaVersion.cpp | 4 ++-- launcher/java/JavaVersion.h | 4 ++-- launcher/java/download/ArchiveJavaDownloader.cpp | 1 - launcher/launch/steps/CheckJava.cpp | 2 +- launcher/launch/steps/CheckJava.h | 2 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 2 +- launcher/ui/widgets/JavaSettingsWidget.h | 2 +- 11 files changed, 15 insertions(+), 16 deletions(-) diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index cfc3cfe424..3cbf9f9d54 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -121,7 +121,7 @@ void JavaCommon::TestCheck::run() checker->start(); } -void JavaCommon::TestCheck::checkFinished(JavaChecker::Result result) +void JavaCommon::TestCheck::checkFinished(const JavaChecker::Result& result) { if (result.validity != JavaChecker::Result::Validity::Valid) { javaBinaryWasBad(m_parent, result); @@ -133,7 +133,7 @@ void JavaCommon::TestCheck::checkFinished(JavaChecker::Result result) checker->start(); } -void JavaCommon::TestCheck::checkFinishedWithArgs(JavaChecker::Result result) +void JavaCommon::TestCheck::checkFinishedWithArgs(const JavaChecker::Result& result) { if (result.validity == JavaChecker::Result::Validity::Valid) { javaWasOk(m_parent, result); diff --git a/launcher/JavaCommon.h b/launcher/JavaCommon.h index 7c5510efc3..ca208b5933 100644 --- a/launcher/JavaCommon.h +++ b/launcher/JavaCommon.h @@ -32,8 +32,8 @@ class TestCheck : public QObject { void finished(); private slots: - void checkFinished(JavaChecker::Result result); - void checkFinishedWithArgs(JavaChecker::Result result); + void checkFinished(const JavaChecker::Result& result); + void checkFinishedWithArgs(const JavaChecker::Result& result); private: JavaChecker::Ptr checker; diff --git a/launcher/java/JavaChecker.h b/launcher/java/JavaChecker.h index 0c6191c21b..171a18b763 100644 --- a/launcher/java/JavaChecker.h +++ b/launcher/java/JavaChecker.h @@ -29,7 +29,7 @@ class JavaChecker : public Task { explicit JavaChecker(QString path, QString args, int minMem = 0, int maxMem = 0, int permGen = 0, int id = 0, QObject* parent = 0); signals: - void checkFinished(Result result); + void checkFinished(const Result& result); protected: virtual void executeTask() override; diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index ef99d6853e..c140569646 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -170,7 +170,7 @@ void JavaListLoadTask::executeTask() int id = 0; for (QString candidate : candidate_paths) { auto checker = new JavaChecker(candidate, "", 0, 0, 0, id, this); - connect(checker, &JavaChecker::checkFinished, [this](JavaChecker::Result result) { m_results << result; }); + connect(checker, &JavaChecker::checkFinished, [this](const JavaChecker::Result& result) { m_results << result; }); job->addTask(Task::Ptr(checker)); id++; } @@ -181,7 +181,7 @@ void JavaListLoadTask::executeTask() void JavaListLoadTask::javaCheckerFinished() { QList candidates; - std::sort(m_results.begin(), m_results.end(), [](JavaChecker::Result a, JavaChecker::Result b) { return a.id < b.id; }); + std::sort(m_results.begin(), m_results.end(), [](const JavaChecker::Result& a, const JavaChecker::Result& b) { return a.id < b.id; }); qDebug() << "Found the following valid Java installations:"; for (auto result : m_results) { diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index f3ded97099..2dc23472e2 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -43,12 +43,12 @@ QString JavaVersion::toString() const return m_string; } -bool JavaVersion::requiresPermGen() +bool JavaVersion::requiresPermGen() const { return !m_parseable || m_major < 8; } -bool JavaVersion::isModular() +bool JavaVersion::isModular() const { return m_parseable && m_major >= 9; } diff --git a/launcher/java/JavaVersion.h b/launcher/java/JavaVersion.h index eee992346d..92c743bfb8 100644 --- a/launcher/java/JavaVersion.h +++ b/launcher/java/JavaVersion.h @@ -24,9 +24,9 @@ class JavaVersion { bool operator==(const JavaVersion& rhs); bool operator>(const JavaVersion& rhs); - bool requiresPermGen(); + bool requiresPermGen() const; - bool isModular(); + bool isModular() const; QString toString() const; diff --git a/launcher/java/download/ArchiveJavaDownloader.cpp b/launcher/java/download/ArchiveJavaDownloader.cpp index bee65cf913..cb642357a0 100644 --- a/launcher/java/download/ArchiveJavaDownloader.cpp +++ b/launcher/java/download/ArchiveJavaDownloader.cpp @@ -49,7 +49,6 @@ void ArchiveJavaDownloader::executeTask() auto fullPath = entry->getFullPath(); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - // connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); }); connect(download.get(), &NetJob::progress, this, &ArchiveJavaDownloader::progress); connect(download.get(), &NetJob::failed, this, &ArchiveJavaDownloader::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index c776092fe6..a8c7305abc 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -106,7 +106,7 @@ void CheckJava::executeTask() emitSucceeded(); } -void CheckJava::checkJavaFinished(JavaChecker::Result result) +void CheckJava::checkJavaFinished(const JavaChecker::Result& result) { switch (result.validity) { case JavaChecker::Result::Validity::Errored: { diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index 5ba9e4018a..62b0c6bbbd 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -28,7 +28,7 @@ class CheckJava : public LaunchStep { virtual void executeTask(); virtual bool canAbort() const { return false; } private slots: - void checkJavaFinished(JavaChecker::Result result); + void checkJavaFinished(const JavaChecker::Result& result); private: void printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 7405ad1147..d6fbf00a3c 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -377,7 +377,7 @@ void JavaSettingsWidget::checkJavaPath(const QString& path) m_checker->start(); } -void JavaSettingsWidget::checkFinished(JavaChecker::Result result) +void JavaSettingsWidget::checkFinished(const JavaChecker::Result& result) { m_result = result; switch (result.validity) { diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index d3cd2c5a70..b7db955a4d 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -51,7 +51,7 @@ class JavaSettingsWidget : public QWidget { void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void on_javaDownloadBtn_clicked(); - void checkFinished(JavaChecker::Result result); + void checkFinished(const JavaChecker::Result& result); protected: /* methods */ void checkJavaPathOnEdit(const QString& path); From 6c5bb3817bfe1a51924127f77965ea72506452aa Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 31 Jan 2024 18:07:28 +0200 Subject: [PATCH 30/83] Cleaned some code Signed-off-by: Trial97 --- launcher/java/JavaRuntime.cpp | 44 ++++++++++++++++- launcher/java/JavaRuntime.h | 18 ++++++- launcher/ui/java/JavaDownload.cpp | 35 +++++--------- launcher/ui/java/JavaDownload.h | 3 -- launcher/ui/java/ListModel.cpp | 69 ++++++--------------------- launcher/ui/java/ListModel.h | 78 +------------------------------ 6 files changed, 85 insertions(+), 162 deletions(-) diff --git a/launcher/java/JavaRuntime.cpp b/launcher/java/JavaRuntime.cpp index be13f47e43..e889557723 100644 --- a/launcher/java/JavaRuntime.cpp +++ b/launcher/java/JavaRuntime.cpp @@ -21,6 +21,7 @@ #include #include "Json.h" +#include "StringUtils.h" #include "java/JavaVersion.h" #include "minecraft/ParseUtils.h" @@ -47,7 +48,7 @@ MetaPtr parseJavaMeta(const QJsonObject& in) { auto meta = std::make_shared(); - meta->name = Json::ensureString(in, "name", ""); + meta->m_name = Json::ensureString(in, "name", ""); meta->vendor = Json::ensureString(in, "vendor", ""); meta->url = Json::ensureString(in, "url", ""); meta->releaseTime = timeFromS3Time(Json::ensureString(in, "releaseTime", "")); @@ -72,4 +73,45 @@ MetaPtr parseJavaMeta(const QJsonObject& in) } return meta; } + +bool Meta::operator<(const Meta& rhs) +{ + auto id = version; + if (id < rhs.version) { + return true; + } + if (id > rhs.version) { + return false; + } + return StringUtils::naturalCompare(m_name, rhs.m_name, Qt::CaseInsensitive) < 0; +} + +bool Meta::operator==(const Meta& rhs) +{ + return version == rhs.version && m_name == rhs.m_name; +} + +bool Meta::operator>(const Meta& rhs) +{ + return (!operator<(rhs)) && (!operator==(rhs)); +} + +bool Meta::operator<(BaseVersion& a) +{ + try { + return operator<(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator<(a); + } +} + +bool Meta::operator>(BaseVersion& a) +{ + try { + return operator>(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator>(a); + } +} + } // namespace JavaRuntime diff --git a/launcher/java/JavaRuntime.h b/launcher/java/JavaRuntime.h index 4c4efa2886..654ba030ae 100644 --- a/launcher/java/JavaRuntime.h +++ b/launcher/java/JavaRuntime.h @@ -23,14 +23,28 @@ #include +#include "BaseVersion.h" #include "java/JavaVersion.h" namespace JavaRuntime { enum class DownloadType { Manifest, Archive }; -struct Meta { - QString name; +class Meta : public BaseVersion { + public: + virtual QString descriptor() override { return version.toString(); } + + virtual QString name() override { return m_name; } + + virtual QString typeString() const override { return vendor; } + + virtual bool operator<(BaseVersion& a) override; + virtual bool operator>(BaseVersion& a) override; + bool operator<(const Meta& rhs); + bool operator==(const Meta& rhs); + bool operator>(const Meta& rhs); + + QString m_name; QString vendor; QString url; QDateTime releaseTime; diff --git a/launcher/ui/java/JavaDownload.cpp b/launcher/ui/java/JavaDownload.cpp index c03fb10e81..bae61a0605 100644 --- a/launcher/ui/java/JavaDownload.cpp +++ b/launcher/ui/java/JavaDownload.cpp @@ -17,21 +17,23 @@ */ #include "JavaDownload.h" -#include -#include -#include -#include + +#include + #include + #include "Application.h" -#include "BaseVersionList.h" #include "FileSystem.h" #include "QObjectPtr.h" #include "SysInfo.h" -#include "java/JavaInstallList.h" + +#include "java/JavaRuntime.h" #include "java/download/ArchiveJavaDownloader.h" #include "java/download/ManifestJavaDownloader.h" + #include "meta/Index.h" #include "meta/Version.h" + #include "ui/dialogs/ProgressDialog.h" #include "ui/java/ListModel.h" #include "ui_JavaDownload.h" @@ -44,7 +46,6 @@ JavaDownload::JavaDownload(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDo connect(ui->widget, &VersionSelectWidget::selectedVersionChanged, this, &JavaDownload::setSelectedVersion); auto reset = ui->buttonBox->button(QDialogButtonBox::Reset); connect(reset, &QPushButton::clicked, this, &JavaDownload::refresh); - connect(ui->widget_2, &VersionSelectWidget::selectedVersionChanged, this, &JavaDownload::setSelectedVersion2); } JavaDownload::~JavaDownload() @@ -54,8 +55,6 @@ JavaDownload::~JavaDownload() void JavaDownload::setSelectedVersion(BaseVersion::Ptr version) { - if (!version) - return; auto dcast = std::dynamic_pointer_cast(version); if (!dcast) { return; @@ -64,26 +63,14 @@ void JavaDownload::setSelectedVersion(BaseVersion::Ptr version) ui->widget_2->selectCurrent(); } -void JavaDownload::setSelectedVersion2(BaseVersion::Ptr version) -{ - if (!version) - return; - m_selectedVersion = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); -} void JavaDownload::accept() { - if (!m_selectedVersion) { - m_selectedVersion = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); - qDebug() << "=========?" << (ui->widget_2->selectedVersion() != nullptr); - } - if (!m_selectedVersion) { - qDebug() << "faillllllllllllllllllllllllllll"; + auto meta = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); + if (!meta) { return; } - auto meta = m_selectedVersion->meta; Task::Ptr task; - auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->name); - qDebug() << "===============>>=>>" << meta->checksumType << meta->checksumHash; + auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->m_name); switch (meta->downloadType) { case JavaRuntime::DownloadType::Manifest: task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); diff --git a/launcher/ui/java/JavaDownload.h b/launcher/ui/java/JavaDownload.h index 916d6b4952..de0916ae5e 100644 --- a/launcher/ui/java/JavaDownload.h +++ b/launcher/ui/java/JavaDownload.h @@ -20,7 +20,6 @@ #include #include "BaseVersion.h" -#include "ui/java/ListModel.h" namespace Ui { class JavaDownload; @@ -40,9 +39,7 @@ class JavaDownload : public QDialog { protected slots: void setSelectedVersion(BaseVersion::Ptr version); - void setSelectedVersion2(BaseVersion::Ptr version); private: Ui::JavaDownload* ui; - Java::JavaRuntimePtr m_selectedVersion; }; diff --git a/launcher/ui/java/ListModel.cpp b/launcher/ui/java/ListModel.cpp index 71f8765eb0..11cd01130d 100644 --- a/launcher/ui/java/ListModel.cpp +++ b/launcher/ui/java/ListModel.cpp @@ -17,11 +17,12 @@ */ #include "ListModel.h" -#include + #include + #include "BaseVersionList.h" -#include "StringUtils.h" #include "SysInfo.h" +#include "java/JavaRuntime.h" namespace Java { @@ -71,13 +72,13 @@ QVariant InstallList::data(const QModelIndex& index, int role) const case VersionIdRole: return version->descriptor(); case VersionRole: - return version->meta->version.toString(); + return version->version.toString(); case RecommendedRole: - return version->meta->recommended; + return version->recommended; case AliasRole: - return version->meta->name; + return version->name(); case ArchitectureRole: - return version->meta->vendor; + return version->vendor; default: return QVariant(); } @@ -90,8 +91,8 @@ BaseVersionList::RoleList InstallList::providesRoles() const bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) { - auto rleft = std::dynamic_pointer_cast(right); - auto rright = std::dynamic_pointer_cast(left); + auto rleft = std::dynamic_pointer_cast(right); + auto rright = std::dynamic_pointer_cast(left); return (*rleft) > (*rright); } @@ -100,55 +101,13 @@ void InstallList::sortVersions() QString versionStr = SysInfo::getSupportedJavaArchitecture(); beginResetModel(); auto runtimes = m_version->data()->runtimes; - if (versionStr.isEmpty() || !runtimes.contains(versionStr)) { - return; - } - auto javaruntimes = runtimes.value(versionStr); - for (auto v : javaruntimes) { - m_vlist.append(std::make_shared(v)); + if (!versionStr.isEmpty() && runtimes.contains(versionStr)) { + m_vlist = runtimes.value(versionStr); + std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); + } else { + m_vlist = {}; } - std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); endResetModel(); } -bool JavaRuntime2::operator<(const JavaRuntime2& rhs) -{ - auto id = meta->version; - if (id < rhs.meta->version) { - return true; - } - if (id > rhs.meta->version) { - return false; - } - return StringUtils::naturalCompare(meta->name, rhs.meta->name, Qt::CaseInsensitive) < 0; -} - -bool JavaRuntime2::operator==(const JavaRuntime2& rhs) -{ - return meta->version == rhs.meta->version && meta->name == rhs.meta->name; -} - -bool JavaRuntime2::operator>(const JavaRuntime2& rhs) -{ - return (!operator<(rhs)) && (!operator==(rhs)); -} - -bool JavaRuntime2::operator<(BaseVersion& a) -{ - try { - return operator<(dynamic_cast(a)); - } catch (const std::bad_cast& e) { - return BaseVersion::operator<(a); - } -} - -bool JavaRuntime2::operator>(BaseVersion& a) -{ - try { - return operator>(dynamic_cast(a)); - } catch (const std::bad_cast& e) { - return BaseVersion::operator>(a); - } -} - } // namespace Java diff --git a/launcher/ui/java/ListModel.h b/launcher/ui/java/ListModel.h index 3685d611d8..a157e0e8d3 100644 --- a/launcher/ui/java/ListModel.h +++ b/launcher/ui/java/ListModel.h @@ -18,9 +18,6 @@ #pragma once -#include -#include -#include #include "java/JavaRuntime.h" #include "meta/VersionList.h" @@ -33,26 +30,6 @@ class JavaBaseVersionList : public Meta::VersionList { BaseVersionList::RoleList providesRoles() const { return { VersionRole, RecommendedRole, VersionPointerRole }; } }; -struct JavaRuntime2 : public BaseVersion { - JavaRuntime2() {} - JavaRuntime2(JavaRuntime::MetaPtr m) : meta(m) {} - virtual QString descriptor() override { return meta->version.toString(); } - - virtual QString name() override { return meta->name; } - - virtual QString typeString() const override { return meta->vendor; } - - virtual bool operator<(BaseVersion& a) override; - virtual bool operator>(BaseVersion& a) override; - bool operator<(const JavaRuntime2& rhs); - bool operator==(const JavaRuntime2& rhs); - bool operator>(const JavaRuntime2& rhs); - - JavaRuntime::MetaPtr meta; -}; - -using JavaRuntimePtr = std::shared_ptr; - class InstallList : public BaseVersionList { Q_OBJECT @@ -73,60 +50,7 @@ class InstallList : public BaseVersionList { protected: Meta::Version::Ptr m_version; - QList m_vlist; + QList m_vlist; }; } // namespace Java -// class FilterModel : public QSortFilterProxyModel { -// Q_OBJECT -// public: -// FilterModel(QObject* parent = Q_NULLPTR); -// enum Sorting { ByName, ByGameVersion }; -// const QMap getAvailableSortings(); -// QString translateCurrentSorting(); -// void setSorting(Sorting sorting); -// Sorting getCurrentSorting(); -// void setSearchTerm(QString term); - -// protected: -// bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; -// bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; - -// private: -// QMap sortings; -// Sorting currentSorting; -// QString searchTerm; -// }; - -// class ListModel : public QAbstractListModel { -// Q_OBJECT -// private: -// ModpackList modpacks; -// QStringList m_failedLogos; -// QStringList m_loadingLogos; -// FTBLogoMap m_logoMap; -// QMap waitingCallbacks; - -// void requestLogo(QString file); -// QString translatePackType(PackType type) const; - -// private slots: -// void logoFailed(QString logo); -// void logoLoaded(QString logo, QIcon out); - -// public: -// ListModel(QObject* parent); -// ~ListModel(); -// int rowCount(const QModelIndex& parent) const override; -// int columnCount(const QModelIndex& parent) const override; -// QVariant data(const QModelIndex& index, int role) const override; -// Qt::ItemFlags flags(const QModelIndex& index) const override; - -// void fill(ModpackList modpacks); -// void addPack(Modpack modpack); -// void clear(); -// void remove(int row); - -// Modpack at(int row); -// void getLogo(const QString& logo, LogoCallback callback); -// }; From 3c58fb06776000808029e8cc4d5207bfd0f57321 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 2 Feb 2024 15:51:32 +0200 Subject: [PATCH 31/83] Moving files around Signed-off-by: Trial97 --- launcher/BaseVersionList.cpp | 4 +- launcher/BaseVersionList.h | 4 +- launcher/CMakeLists.txt | 24 ++-- launcher/VersionProxyModel.cpp | 26 ++--- launcher/VersionProxyModel.h | 2 +- launcher/java/JavaInstallList.cpp | 4 +- .../{JavaRuntime.cpp => JavaMetadata.cpp} | 24 ++-- .../java/{JavaRuntime.h => JavaMetadata.h} | 16 +-- ...Downloader.cpp => ArchiveDownloadTask.cpp} | 22 ++-- ...JavaDownloader.h => ArchiveDownloadTask.h} | 12 +- ...ownloader.cpp => ManifestDownloadTask.cpp} | 20 ++-- ...avaDownloader.h => ManifestDownloadTask.h} | 13 ++- launcher/meta/VersionList.cpp | 8 +- launcher/meta/VersionList.h | 5 + launcher/minecraft/OneSixVersionFormat.cpp | 6 +- launcher/minecraft/VersionFile.h | 4 +- launcher/ui/java/JavaDownload.cpp | 90 --------------- launcher/ui/java/JavaDownloader.cpp | 109 ++++++++++++++++++ .../java/{JavaDownload.h => JavaDownloader.h} | 13 ++- .../{JavaDownload.ui => JavaDownloader.ui} | 12 +- .../java/{ListModel.cpp => VersionList.cpp} | 32 ++--- .../ui/java/{ListModel.h => VersionList.h} | 18 +-- launcher/ui/pages/global/JavaPage.cpp | 4 +- .../pages/instance/InstanceSettingsPage.cpp | 4 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 4 +- 25 files changed, 255 insertions(+), 225 deletions(-) rename launcher/java/{JavaRuntime.cpp => JavaMetadata.cpp} (86%) rename launcher/java/{JavaRuntime.h => JavaMetadata.h} (84%) rename launcher/java/download/{ArchiveJavaDownloader.cpp => ArchiveDownloadTask.cpp} (82%) rename launcher/java/download/{ArchiveJavaDownloader.h => ArchiveDownloadTask.h} (82%) rename launcher/java/download/{ManifestJavaDownloader.cpp => ManifestDownloadTask.cpp} (87%) rename launcher/java/download/{ManifestJavaDownloader.h => ManifestDownloadTask.h} (82%) delete mode 100644 launcher/ui/java/JavaDownload.cpp create mode 100644 launcher/ui/java/JavaDownloader.cpp rename launcher/ui/java/{JavaDownload.h => JavaDownloader.h} (84%) rename launcher/ui/java/{JavaDownload.ui => JavaDownloader.ui} (86%) rename launcher/ui/java/{ListModel.cpp => VersionList.cpp} (76%) rename launcher/ui/java/{ListModel.h => VersionList.h} (71%) diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index 576c3a413d..afee8388a1 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -110,7 +110,7 @@ QHash BaseVersionList::roleNames() const roles.insert(TypeRole, "type"); roles.insert(BranchRole, "branch"); roles.insert(PathRole, "path"); - roles.insert(AliasRole, "alias"); - roles.insert(ArchitectureRole, "architecture"); + roles.insert(JavaNameRole, "javaName"); + roles.insert(CPUArchitectureRole, "architecture"); return roles; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index c59d705707..bc37e9e53e 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -48,8 +48,8 @@ class BaseVersionList : public QAbstractListModel { TypeRole, BranchRole, PathRole, - AliasRole, - ArchitectureRole, + JavaNameRole, + CPUArchitectureRole, SortRole }; using RoleList = QList; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index d703b82637..c7945d1b84 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -431,17 +431,17 @@ set(JAVA_SOURCES java/JavaVersion.h java/JavaVersion.cpp - java/JavaRuntime.h - java/JavaRuntime.cpp - java/download/ArchiveJavaDownloader.cpp - java/download/ArchiveJavaDownloader.h - java/download/ManifestJavaDownloader.cpp - java/download/ManifestJavaDownloader.h - - ui/java/JavaDownload.h - ui/java/JavaDownload.cpp - ui/java/ListModel.h - ui/java/ListModel.cpp + java/JavaMetadata.h + java/JavaMetadata.cpp + java/download/ArchiveDownloadTask.cpp + java/download/ArchiveDownloadTask.h + java/download/ManifestDownloadTask.cpp + java/download/ManifestDownloadTask.h + + ui/java/JavaDownloader.h + ui/java/JavaDownloader.cpp + ui/java/VersionList.h + ui/java/VersionList.cpp ) set(TRANSLATIONS_SOURCES @@ -1192,7 +1192,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ScrollMessageBox.ui ui/dialogs/BlockedModsDialog.ui ui/dialogs/ChooseProviderDialog.ui - ui/java/JavaDownload.ui + ui/java/JavaDownloader.ui ) qt_wrap_ui(PRISM_UPDATE_UI diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index f1218f162d..070e952a4a 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -114,12 +114,12 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Branch"); case Type: return tr("Type"); - case Architecture: + case CPUArchitecture: return tr("Architecture"); case Path: return tr("Path"); - case Alias: - return tr("Alias"); + case JavaName: + return tr("Java Name"); case Time: return tr("Released"); } @@ -133,11 +133,11 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("The version's branch"); case Type: return tr("The version's type"); - case Architecture: + case CPUArchitecture: return tr("CPU Architecture"); case Path: return tr("Filesystem path to this version"); - case Alias: + case JavaName: return tr("The alternative name of the java version"); case Time: return tr("Release date of this version"); @@ -169,12 +169,12 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::BranchRole); case Type: return sourceModel()->data(parentIndex, BaseVersionList::TypeRole); - case Architecture: - return sourceModel()->data(parentIndex, BaseVersionList::ArchitectureRole); + case CPUArchitecture: + return sourceModel()->data(parentIndex, BaseVersionList::CPUArchitectureRole); case Path: return sourceModel()->data(parentIndex, BaseVersionList::PathRole); - case Alias: - return sourceModel()->data(parentIndex, BaseVersionList::AliasRole); + case JavaName: + return sourceModel()->data(parentIndex, BaseVersionList::JavaNameRole); case Time: return sourceModel()->data(parentIndex, Meta::VersionList::TimeRole).toDate(); default: @@ -314,14 +314,14 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) m_columns.push_back(ParentVersion); } */ - if (roles.contains(BaseVersionList::ArchitectureRole)) { - m_columns.push_back(Architecture); + if (roles.contains(BaseVersionList::CPUArchitectureRole)) { + m_columns.push_back(CPUArchitecture); } if (roles.contains(BaseVersionList::PathRole)) { m_columns.push_back(Path); } - if (roles.contains(BaseVersionList::AliasRole)) { - m_columns.push_back(Alias); + if (roles.contains(BaseVersionList::JavaNameRole)) { + m_columns.push_back(JavaName); } if (roles.contains(Meta::VersionList::TimeRole)) { m_columns.push_back(Time); diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 2dc35a6253..cb55b7f14a 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -9,7 +9,7 @@ class VersionFilterModel; class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT public: - enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time, Alias }; + enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName }; using FilterMap = QHash>; public: diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index c140569646..d99201f24d 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -108,7 +108,7 @@ QVariant JavaInstallList::data(const QModelIndex& index, int role) const return version->recommended; case PathRole: return version->path; - case ArchitectureRole: + case CPUArchitectureRole: return version->arch; default: return QVariant(); @@ -117,7 +117,7 @@ QVariant JavaInstallList::data(const QModelIndex& index, int role) const BaseVersionList::RoleList JavaInstallList::providesRoles() const { - return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole }; + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, CPUArchitectureRole }; } void JavaInstallList::updateListData(QList versions) diff --git a/launcher/java/JavaRuntime.cpp b/launcher/java/JavaMetadata.cpp similarity index 86% rename from launcher/java/JavaRuntime.cpp rename to launcher/java/JavaMetadata.cpp index e889557723..b261122dc0 100644 --- a/launcher/java/JavaRuntime.cpp +++ b/launcher/java/JavaMetadata.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include "java/JavaRuntime.h" +#include "java/JavaMetadata.h" #include @@ -25,7 +25,7 @@ #include "java/JavaVersion.h" #include "minecraft/ParseUtils.h" -namespace JavaRuntime { +namespace Java { DownloadType parseDownloadType(QString javaDownload) { @@ -44,9 +44,9 @@ QString downloadTypeToString(DownloadType javaDownload) } return ""; } -MetaPtr parseJavaMeta(const QJsonObject& in) +MetadataPtr parseJavaMeta(const QJsonObject& in) { - auto meta = std::make_shared(); + auto meta = std::make_shared(); meta->m_name = Json::ensureString(in, "name", ""); meta->vendor = Json::ensureString(in, "vendor", ""); @@ -74,7 +74,7 @@ MetaPtr parseJavaMeta(const QJsonObject& in) return meta; } -bool Meta::operator<(const Meta& rhs) +bool Metadata::operator<(const Metadata& rhs) { auto id = version; if (id < rhs.version) { @@ -86,32 +86,32 @@ bool Meta::operator<(const Meta& rhs) return StringUtils::naturalCompare(m_name, rhs.m_name, Qt::CaseInsensitive) < 0; } -bool Meta::operator==(const Meta& rhs) +bool Metadata::operator==(const Metadata& rhs) { return version == rhs.version && m_name == rhs.m_name; } -bool Meta::operator>(const Meta& rhs) +bool Metadata::operator>(const Metadata& rhs) { return (!operator<(rhs)) && (!operator==(rhs)); } -bool Meta::operator<(BaseVersion& a) +bool Metadata::operator<(BaseVersion& a) { try { - return operator<(dynamic_cast(a)); + return operator<(dynamic_cast(a)); } catch (const std::bad_cast& e) { return BaseVersion::operator<(a); } } -bool Meta::operator>(BaseVersion& a) +bool Metadata::operator>(BaseVersion& a) { try { - return operator>(dynamic_cast(a)); + return operator>(dynamic_cast(a)); } catch (const std::bad_cast& e) { return BaseVersion::operator>(a); } } -} // namespace JavaRuntime +} // namespace Java diff --git a/launcher/java/JavaRuntime.h b/launcher/java/JavaMetadata.h similarity index 84% rename from launcher/java/JavaRuntime.h rename to launcher/java/JavaMetadata.h index 654ba030ae..dd3ae865c4 100644 --- a/launcher/java/JavaRuntime.h +++ b/launcher/java/JavaMetadata.h @@ -26,11 +26,11 @@ #include "BaseVersion.h" #include "java/JavaVersion.h" -namespace JavaRuntime { +namespace Java { enum class DownloadType { Manifest, Archive }; -class Meta : public BaseVersion { +class Metadata : public BaseVersion { public: virtual QString descriptor() override { return version.toString(); } @@ -40,9 +40,9 @@ class Meta : public BaseVersion { virtual bool operator<(BaseVersion& a) override; virtual bool operator>(BaseVersion& a) override; - bool operator<(const Meta& rhs); - bool operator==(const Meta& rhs); - bool operator>(const Meta& rhs); + bool operator<(const Metadata& rhs); + bool operator==(const Metadata& rhs); + bool operator>(const Metadata& rhs); QString m_name; QString vendor; @@ -55,10 +55,10 @@ class Meta : public BaseVersion { QString packageType; JavaVersion version; }; -using MetaPtr = std::shared_ptr; +using MetadataPtr = std::shared_ptr; DownloadType parseDownloadType(QString javaDownload); QString downloadTypeToString(DownloadType javaDownload); -MetaPtr parseJavaMeta(const QJsonObject& libObj); +MetadataPtr parseJavaMeta(const QJsonObject& libObj); -} // namespace JavaRuntime \ No newline at end of file +} // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ArchiveJavaDownloader.cpp b/launcher/java/download/ArchiveDownloadTask.cpp similarity index 82% rename from launcher/java/download/ArchiveJavaDownloader.cpp rename to launcher/java/download/ArchiveDownloadTask.cpp index cb642357a0..847f3f3649 100644 --- a/launcher/java/download/ArchiveJavaDownloader.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "java/download/ArchiveJavaDownloader.h" +#include "java/download/ArchiveDownloadTask.h" #include #include #include "MMCZip.h" @@ -25,11 +25,12 @@ #include "net/NetJob.h" #include "tasks/Task.h" -ArchiveJavaDownloader::ArchiveJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) +namespace Java { +ArchiveDownloadTask::ArchiveDownloadTask(QUrl url, QString final_path, QString checksumType, QString checksumHash) : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash) {} -void ArchiveJavaDownloader::executeTask() +void ArchiveDownloadTask::executeTask() { // JRE found ! download the zip setStatus(tr("Downloading Java")); @@ -49,8 +50,8 @@ void ArchiveJavaDownloader::executeTask() auto fullPath = entry->getFullPath(); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &ArchiveJavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &ArchiveJavaDownloader::emitFailed); + connect(download.get(), &NetJob::progress, this, &ArchiveDownloadTask::progress); + connect(download.get(), &NetJob::failed, this, &ArchiveDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &NetJob::succeeded, [this, fullPath] { // This should do all of the extracting and creating folders @@ -59,7 +60,7 @@ void ArchiveJavaDownloader::executeTask() download->start(); } -void ArchiveJavaDownloader::extractJava(QString input) +void ArchiveDownloadTask::extractJava(QString input) { setStatus(tr("Extracting java")); auto zip = std::make_shared(input); @@ -79,14 +80,14 @@ void ArchiveJavaDownloader::extractJava(QString input) connect(this, &Task::aborted, zipTask.get(), &Task::abort); connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); - connect(zipTask.get(), &Task::succeeded, this, &ArchiveJavaDownloader::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, &ArchiveJavaDownloader::emitAborted); + connect(zipTask.get(), &Task::succeeded, this, &ArchiveDownloadTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &ArchiveDownloadTask::emitAborted); connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { progressStep->state = TaskStepState::Failed; stepProgress(*progressStep); emitFailed(reason); }); - connect(zipTask.get(), &Task::stepProgress, this, &ArchiveJavaDownloader::propagateStepProgress); + connect(zipTask.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); @@ -97,4 +98,5 @@ void ArchiveJavaDownloader::extractJava(QString input) stepProgress(*progressStep); }); zipTask->start(); -} \ No newline at end of file +} +} // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ArchiveJavaDownloader.h b/launcher/java/download/ArchiveDownloadTask.h similarity index 82% rename from launcher/java/download/ArchiveJavaDownloader.h rename to launcher/java/download/ArchiveDownloadTask.h index 230f62b4d2..88c0223d5a 100644 --- a/launcher/java/download/ArchiveJavaDownloader.h +++ b/launcher/java/download/ArchiveDownloadTask.h @@ -21,11 +21,12 @@ #include #include "tasks/Task.h" -class ArchiveJavaDownloader : public Task { +namespace Java { +class ArchiveDownloadTask : public Task { Q_OBJECT public: - ArchiveJavaDownloader(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); - virtual ~ArchiveJavaDownloader() = default; + ArchiveDownloadTask(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); + virtual ~ArchiveDownloadTask() = default; [[nodiscard]] bool canAbort() const override { return true; } void executeTask() override; @@ -38,6 +39,5 @@ class ArchiveJavaDownloader : public Task { QString m_final_path; QString m_checksum_type; QString m_checksum_hash; - - Task::Ptr m_current_task; -}; \ No newline at end of file +}; +} // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ManifestJavaDownloader.cpp b/launcher/java/download/ManifestDownloadTask.cpp similarity index 87% rename from launcher/java/download/ManifestJavaDownloader.cpp rename to launcher/java/download/ManifestDownloadTask.cpp index c0b7942a7c..1a30715301 100644 --- a/launcher/java/download/ManifestJavaDownloader.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "java/download/ManifestJavaDownloader.h" +#include "java/download/ManifestDownloadTask.h" #include "Application.h" #include "FileSystem.h" @@ -30,11 +30,12 @@ struct File { bool isExec; }; -ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path, QString checksumType, QString checksumHash) +namespace Java { +ManifestDownloadTask::ManifestDownloadTask(QUrl url, QString final_path, QString checksumType, QString checksumHash) : m_url(url), m_final_path(final_path), m_checksum_type(checksumType), m_checksum_hash(checksumHash) {} -void ManifestJavaDownloader::executeTask() +void ManifestDownloadTask::executeTask() { setStatus(tr("Downloading Java")); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); @@ -51,8 +52,8 @@ void ManifestJavaDownloader::executeTask() download->addNetAction(action); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &ManifestJavaDownloader::progress); - connect(download.get(), &NetJob::failed, this, &ManifestJavaDownloader::emitFailed); + connect(download.get(), &NetJob::progress, this, &ManifestDownloadTask::progress); + connect(download.get(), &NetJob::failed, this, &ManifestDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &NetJob::succeeded, [files, this] { @@ -69,7 +70,7 @@ void ManifestJavaDownloader::executeTask() download->start(); } -void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc) +void ManifestDownloadTask::downloadJava(const QJsonDocument& doc) { // valid json doc, begin making jre spot FS::ensureFolderPathExists(m_final_path); @@ -116,10 +117,11 @@ void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc) disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); elementDownload->deleteLater(); }); - connect(elementDownload, &NetJob::progress, this, &ManifestJavaDownloader::progress); - connect(elementDownload, &NetJob::failed, this, &ManifestJavaDownloader::emitFailed); + connect(elementDownload, &NetJob::progress, this, &ManifestDownloadTask::progress); + connect(elementDownload, &NetJob::failed, this, &ManifestDownloadTask::emitFailed); connect(this, &Task::aborted, elementDownload, &NetJob::abort); connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); elementDownload->start(); -} \ No newline at end of file +} +} // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ManifestJavaDownloader.h b/launcher/java/download/ManifestDownloadTask.h similarity index 82% rename from launcher/java/download/ManifestJavaDownloader.h rename to launcher/java/download/ManifestDownloadTask.h index d7114f4bd5..dcfee4d4da 100644 --- a/launcher/java/download/ManifestJavaDownloader.h +++ b/launcher/java/download/ManifestDownloadTask.h @@ -21,11 +21,13 @@ #include #include "tasks/Task.h" -class ManifestJavaDownloader : public Task { +namespace Java { + +class ManifestDownloadTask : public Task { Q_OBJECT public: - ManifestJavaDownloader(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); - virtual ~ManifestJavaDownloader() = default; + ManifestDownloadTask(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = ""); + virtual ~ManifestDownloadTask() = default; [[nodiscard]] bool canAbort() const override { return true; } void executeTask() override; @@ -38,6 +40,5 @@ class ManifestJavaDownloader : public Task { QString m_final_path; QString m_checksum_type; QString m_checksum_hash; - - Task::Ptr m_current_task; -}; \ No newline at end of file +}; +} // namespace Java \ No newline at end of file diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index 7b7ae1fa32..76b914b6a3 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -101,10 +101,14 @@ QVariant VersionList::data(const QModelIndex& index, int role) const BaseVersionList::RoleList VersionList::providesRoles() const { - return { VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole, TypeRole, UidRole, - TimeRole, RequiresRole, SortRole, RecommendedRole, LatestRole, VersionPtrRole }; + return m_provided_roles; } +void VersionList::setProvidedRoles(RoleList roles) +{ + m_provided_roles = roles; +}; + QHash VersionList::roleNames() const { QHash roles = BaseVersionList::roleNames(); diff --git a/launcher/meta/VersionList.h b/launcher/meta/VersionList.h index 2c5624701b..0890caf60a 100644 --- a/launcher/meta/VersionList.h +++ b/launcher/meta/VersionList.h @@ -47,6 +47,8 @@ class VersionList : public BaseVersionList, public BaseEntity { RoleList providesRoles() const override; QHash roleNames() const override; + void setProvidedRoles(RoleList roles); + QString localFilename() const override; QString uid() const { return m_uid; } @@ -79,6 +81,9 @@ class VersionList : public BaseVersionList, public BaseEntity { Version::Ptr m_recommended; + RoleList m_provided_roles = { VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole, TypeRole, UidRole, + TimeRole, RequiresRole, SortRole, RecommendedRole, LatestRole, VersionPtrRole }; + void setupAddedVersion(int row, const Version::Ptr& version); }; } // namespace Meta diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 5f3b4f2a2f..56e9c8ca25 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -37,7 +37,7 @@ #include #include #include -#include "java/JavaRuntime.h" +#include "java/JavaMetadata.h" #include "minecraft/Agent.h" #include "minecraft/ParseUtils.h" @@ -261,9 +261,9 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument& doc auto runtimes = requireObject(root, "runtimes"); out->runtimes = {}; for (auto key : runtimes.keys()) { - QList list; + QList list; for (auto runtime : ensureArray(runtimes, key)) { - list.append(JavaRuntime::parseJavaMeta(ensureObject(runtime))); + list.append(Java::parseJavaMeta(ensureObject(runtime))); } out->runtimes[key] = list; } diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index 297c19709b..a9c1473d20 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -47,7 +47,7 @@ #include "Agent.h" #include "Library.h" #include "ProblemProvider.h" -#include "java/JavaRuntime.h" +#include "java/JavaMetadata.h" #include "minecraft/Rule.h" class PackProfile; @@ -155,7 +155,7 @@ class VersionFile : public ProblemContainer { /// is volatile -- may be removed as soon as it is no longer needed by something else bool m_volatile = false; - QHash> runtimes; + QHash> runtimes; public: // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more. diff --git a/launcher/ui/java/JavaDownload.cpp b/launcher/ui/java/JavaDownload.cpp deleted file mode 100644 index bae61a0605..0000000000 --- a/launcher/ui/java/JavaDownload.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2024 Trial97 - * - * 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 "JavaDownload.h" - -#include - -#include - -#include "Application.h" -#include "FileSystem.h" -#include "QObjectPtr.h" -#include "SysInfo.h" - -#include "java/JavaRuntime.h" -#include "java/download/ArchiveJavaDownloader.h" -#include "java/download/ManifestJavaDownloader.h" - -#include "meta/Index.h" -#include "meta/Version.h" - -#include "ui/dialogs/ProgressDialog.h" -#include "ui/java/ListModel.h" -#include "ui_JavaDownload.h" - -JavaDownload::JavaDownload(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownload) -{ - ui->setupUi(this); - ui->widget->initialize(new Java::JavaBaseVersionList("net.minecraft.java")); - ui->widget->selectCurrent(); - connect(ui->widget, &VersionSelectWidget::selectedVersionChanged, this, &JavaDownload::setSelectedVersion); - auto reset = ui->buttonBox->button(QDialogButtonBox::Reset); - connect(reset, &QPushButton::clicked, this, &JavaDownload::refresh); -} - -JavaDownload::~JavaDownload() -{ - delete ui; -} - -void JavaDownload::setSelectedVersion(BaseVersion::Ptr version) -{ - auto dcast = std::dynamic_pointer_cast(version); - if (!dcast) { - return; - } - ui->widget_2->initialize(new Java::InstallList(dcast, this)); - ui->widget_2->selectCurrent(); -} - -void JavaDownload::accept() -{ - auto meta = std::dynamic_pointer_cast(ui->widget_2->selectedVersion()); - if (!meta) { - return; - } - Task::Ptr task; - auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->m_name); - switch (meta->downloadType) { - case JavaRuntime::DownloadType::Manifest: - task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); - break; - case JavaRuntime::DownloadType::Archive: - task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); - break; - } - ProgressDialog pg(this); - pg.execWithTask(task.get()); - QDialog::accept(); -} - -void JavaDownload::refresh() -{ - ui->widget->loadList(); -} diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp new file mode 100644 index 0000000000..9121988da9 --- /dev/null +++ b/launcher/ui/java/JavaDownloader.cpp @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 "JavaDownloader.h" + +#include + +#include + +#include "Application.h" +#include "BaseVersionList.h" +#include "FileSystem.h" +#include "QObjectPtr.h" +#include "SysInfo.h" + +#include "java/JavaMetadata.h" +#include "java/download/ArchiveDownloadTask.h" +#include "java/download/ManifestDownloadTask.h" + +#include "meta/Index.h" +#include "meta/Version.h" + +#include "meta/VersionList.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/java/VersionList.h" +#include "ui_JavaDownloader.h" + +namespace Java { + +Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownloader) +{ + ui->setupUi(this); + auto versionList = new Meta::VersionList("net.minecraft.java", this); + versionList->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); + ui->majorVersionSelect->initialize(versionList); + ui->majorVersionSelect->selectCurrent(); + ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta")); + ui->majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + + ui->javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); + ui->javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + + ui->buttonBox->button(QDialogButtonBox::Retry)->setText(tr("Refresh")); + ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Download")); + + connect(ui->majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &Downloader::setSelectedVersion); + auto reset = ui->buttonBox->button(QDialogButtonBox::Reset); + connect(reset, &QPushButton::clicked, this, &Downloader::refresh); +} + +Downloader::~Downloader() +{ + delete ui; +} + +void Downloader::setSelectedVersion(BaseVersion::Ptr version) +{ + auto dcast = std::dynamic_pointer_cast(version); + if (!dcast) { + return; + } + ui->javaVersionSelect->initialize(new Java::VersionList(dcast, this)); + ui->javaVersionSelect->selectCurrent(); +} + +void Downloader::accept() +{ + auto meta = std::dynamic_pointer_cast(ui->javaVersionSelect->selectedVersion()); + if (!meta) { + return; + } + Task::Ptr task; + auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->m_name); + switch (meta->downloadType) { + case Java::DownloadType::Manifest: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + case Java::DownloadType::Archive: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + } + auto deletePath = [final_path] { FS::deletePath(final_path); }; + connect(task.get(), &Task::failed, this, deletePath); + connect(task.get(), &Task::aborted, this, deletePath); + ProgressDialog pg(this); + pg.execWithTask(task.get()); + QDialog::accept(); +} + +void Downloader::refresh() +{ + ui->majorVersionSelect->loadList(); +} +} // namespace Java diff --git a/launcher/ui/java/JavaDownload.h b/launcher/ui/java/JavaDownloader.h similarity index 84% rename from launcher/ui/java/JavaDownload.h rename to launcher/ui/java/JavaDownloader.h index de0916ae5e..b8bdde41a4 100644 --- a/launcher/ui/java/JavaDownload.h +++ b/launcher/ui/java/JavaDownloader.h @@ -22,15 +22,17 @@ #include "BaseVersion.h" namespace Ui { -class JavaDownload; +class JavaDownloader; } -class JavaDownload : public QDialog { +namespace Java { + +class Downloader : public QDialog { Q_OBJECT public: - explicit JavaDownload(QWidget* parent = 0); - ~JavaDownload(); + explicit Downloader(QWidget* parent = 0); + ~Downloader(); void accept(); @@ -41,5 +43,6 @@ class JavaDownload : public QDialog { void setSelectedVersion(BaseVersion::Ptr version); private: - Ui::JavaDownload* ui; + Ui::JavaDownloader* ui; }; +} // namespace Java diff --git a/launcher/ui/java/JavaDownload.ui b/launcher/ui/java/JavaDownloader.ui similarity index 86% rename from launcher/ui/java/JavaDownload.ui rename to launcher/ui/java/JavaDownloader.ui index bbc638e9bb..0eeabb26db 100644 --- a/launcher/ui/java/JavaDownload.ui +++ b/launcher/ui/java/JavaDownloader.ui @@ -1,7 +1,7 @@ - JavaDownload - + JavaDownloader + 0 @@ -23,7 +23,7 @@ - + @@ -35,7 +35,7 @@
- +
@@ -67,7 +67,7 @@ buttonBox accepted() - JavaDownload + JavaDownloader accept() @@ -83,7 +83,7 @@ buttonBox rejected() - JavaDownload + JavaDownloader reject() diff --git a/launcher/ui/java/ListModel.cpp b/launcher/ui/java/VersionList.cpp similarity index 76% rename from launcher/ui/java/ListModel.cpp rename to launcher/ui/java/VersionList.cpp index 11cd01130d..31353f2f70 100644 --- a/launcher/ui/java/ListModel.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -16,46 +16,46 @@ * along with this program. If not, see . */ -#include "ListModel.h" +#include "VersionList.h" #include #include "BaseVersionList.h" #include "SysInfo.h" -#include "java/JavaRuntime.h" +#include "java/JavaMetadata.h" namespace Java { -InstallList::InstallList(Meta::Version::Ptr version, QObject* parent) : BaseVersionList(parent), m_version(version) +VersionList::VersionList(Meta::Version::Ptr version, QObject* parent) : BaseVersionList(parent), m_version(version) { if (version->isLoaded()) sortVersions(); } -Task::Ptr InstallList::getLoadTask() +Task::Ptr VersionList::getLoadTask() { m_version->load(Net::Mode::Online); auto task = m_version->getCurrentTask(); - connect(task.get(), &Task::finished, this, &InstallList::sortVersions); + connect(task.get(), &Task::finished, this, &VersionList::sortVersions); return task; } -const BaseVersion::Ptr InstallList::at(int i) const +const BaseVersion::Ptr VersionList::at(int i) const { return m_vlist.at(i); } -bool InstallList::isLoaded() +bool VersionList::isLoaded() { return m_version->isLoaded(); } -int InstallList::count() const +int VersionList::count() const { return m_vlist.count(); } -QVariant InstallList::data(const QModelIndex& index, int role) const +QVariant VersionList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -75,28 +75,28 @@ QVariant InstallList::data(const QModelIndex& index, int role) const return version->version.toString(); case RecommendedRole: return version->recommended; - case AliasRole: + case JavaNameRole: return version->name(); - case ArchitectureRole: + case CPUArchitectureRole: return version->vendor; default: return QVariant(); } } -BaseVersionList::RoleList InstallList::providesRoles() const +BaseVersionList::RoleList VersionList::providesRoles() const { - return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, AliasRole, ArchitectureRole }; + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, JavaNameRole, CPUArchitectureRole }; } bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) { - auto rleft = std::dynamic_pointer_cast(right); - auto rright = std::dynamic_pointer_cast(left); + auto rleft = std::dynamic_pointer_cast(right); + auto rright = std::dynamic_pointer_cast(left); return (*rleft) > (*rright); } -void InstallList::sortVersions() +void VersionList::sortVersions() { QString versionStr = SysInfo::getSupportedJavaArchitecture(); beginResetModel(); diff --git a/launcher/ui/java/ListModel.h b/launcher/ui/java/VersionList.h similarity index 71% rename from launcher/ui/java/ListModel.h rename to launcher/ui/java/VersionList.h index a157e0e8d3..d334ed5648 100644 --- a/launcher/ui/java/ListModel.h +++ b/launcher/ui/java/VersionList.h @@ -18,23 +18,17 @@ #pragma once -#include "java/JavaRuntime.h" -#include "meta/VersionList.h" +#include "BaseVersionList.h" +#include "java/JavaMetadata.h" +#include "meta/Version.h" namespace Java { -class JavaBaseVersionList : public Meta::VersionList { - Q_OBJECT - public: - explicit JavaBaseVersionList(const QString& uid, QObject* parent = nullptr) : VersionList(uid, parent) {} - BaseVersionList::RoleList providesRoles() const { return { VersionRole, RecommendedRole, VersionPointerRole }; } -}; - -class InstallList : public BaseVersionList { +class VersionList : public BaseVersionList { Q_OBJECT public: - explicit InstallList(Meta::Version::Ptr m_version, QObject* parent = 0); + explicit VersionList(Meta::Version::Ptr m_version, QObject* parent = 0); Task::Ptr getLoadTask() override; bool isLoaded() override; @@ -50,7 +44,7 @@ class InstallList : public BaseVersionList { protected: Meta::Version::Ptr m_version; - QList m_vlist; + QList m_vlist; }; } // namespace Java diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 09c951a3cc..9b21aad724 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -36,7 +36,7 @@ #include "JavaPage.h" #include "JavaCommon.h" -#include "ui/java/JavaDownload.h" +#include "ui/java/JavaDownloader.h" #include "ui_JavaPage.h" #include @@ -169,7 +169,7 @@ void JavaPage::on_javaTestBtn_clicked() void JavaPage::on_javaDownloadBtn_clicked() { - auto jdialog = new JavaDownload(this); + auto jdialog = new Java::Downloader(this); jdialog->exec(); } diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index df380bfb3e..b962406d1a 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -36,7 +36,7 @@ */ #include "InstanceSettingsPage.h" -#include "ui/java/JavaDownload.h" +#include "ui/java/JavaDownloader.h" #include "ui_InstanceSettingsPage.h" #include @@ -387,7 +387,7 @@ void InstanceSettingsPage::loadSettings() void InstanceSettingsPage::on_javaDownloadBtn_clicked() { - auto jdialog = new JavaDownload(this); + auto jdialog = new Java::Downloader(this); jdialog->exec(); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index d6fbf00a3c..3f4fe08ea4 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -19,7 +19,7 @@ #include "java/JavaUtils.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/java/JavaDownload.h" +#include "ui/java/JavaDownloader.h" #include "ui/widgets/VersionSelectWidget.h" #include "Application.h" @@ -274,7 +274,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() } void JavaSettingsWidget::on_javaDownloadBtn_clicked() { - auto jdialog = new JavaDownload(this); + auto jdialog = new Java::Downloader(this); jdialog->exec(); } void JavaSettingsWidget::on_javaStatusBtn_clicked() From 0384e652fb42ea18526a168a2370f8431cdcbc0f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 2 Feb 2024 22:42:42 +0200 Subject: [PATCH 32/83] Finished up the download dialog Signed-off-by: Trial97 --- launcher/BaseVersionList.cpp | 1 + launcher/BaseVersionList.h | 1 + launcher/VersionProxyModel.cpp | 9 +++++++++ launcher/VersionProxyModel.h | 2 +- launcher/ui/java/VersionList.cpp | 11 +++++++++-- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index afee8388a1..1456a17bd9 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -112,5 +112,6 @@ QHash BaseVersionList::roleNames() const roles.insert(PathRole, "path"); roles.insert(JavaNameRole, "javaName"); roles.insert(CPUArchitectureRole, "architecture"); + roles.insert(JavaVendorRole, "javaVendor"); return roles; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index bc37e9e53e..7517c71b47 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -50,6 +50,7 @@ class BaseVersionList : public QAbstractListModel { PathRole, JavaNameRole, CPUArchitectureRole, + JavaVendorRole, SortRole }; using RoleList = QList; diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 070e952a4a..ed4c0767d6 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -116,6 +116,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Type"); case CPUArchitecture: return tr("Architecture"); + case JavaVendor: + return tr("Vendor"); case Path: return tr("Path"); case JavaName: @@ -135,6 +137,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("The version's type"); case CPUArchitecture: return tr("CPU Architecture"); + case JavaVendor: + return tr("Java vendor"); case Path: return tr("Filesystem path to this version"); case JavaName: @@ -171,6 +175,8 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::TypeRole); case CPUArchitecture: return sourceModel()->data(parentIndex, BaseVersionList::CPUArchitectureRole); + case JavaVendor: + return sourceModel()->data(parentIndex, BaseVersionList::JavaVendorRole); case Path: return sourceModel()->data(parentIndex, BaseVersionList::PathRole); case JavaName: @@ -317,6 +323,9 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) if (roles.contains(BaseVersionList::CPUArchitectureRole)) { m_columns.push_back(CPUArchitecture); } + if (roles.contains(BaseVersionList::JavaVendorRole)) { + m_columns.push_back(JavaVendor); + } if (roles.contains(BaseVersionList::PathRole)) { m_columns.push_back(Path); } diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index cb55b7f14a..5a1017bee3 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -9,7 +9,7 @@ class VersionFilterModel; class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT public: - enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName }; + enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaVendor }; using FilterMap = QHash>; public: diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index 31353f2f70..7c5668d206 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -23,6 +23,7 @@ #include "BaseVersionList.h" #include "SysInfo.h" #include "java/JavaMetadata.h" +#include "meta/VersionList.h" namespace Java { @@ -77,8 +78,12 @@ QVariant VersionList::data(const QModelIndex& index, int role) const return version->recommended; case JavaNameRole: return version->name(); - case CPUArchitectureRole: + case JavaVendorRole: return version->vendor; + case TypeRole: + return version->packageType; + case Meta::VersionList::TimeRole: + return version->releaseTime; default: return QVariant(); } @@ -86,7 +91,8 @@ QVariant VersionList::data(const QModelIndex& index, int role) const BaseVersionList::RoleList VersionList::providesRoles() const { - return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, JavaNameRole, CPUArchitectureRole }; + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, + JavaNameRole, JavaVendorRole, TypeRole, Meta::VersionList::TimeRole }; } bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) @@ -106,6 +112,7 @@ void VersionList::sortVersions() std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); } else { m_vlist = {}; + qWarning() << "Your operating system is not yet supported: " << SysInfo::currentSystem() << " " << SysInfo::useQTForArch(); } endResetModel(); } From 82b15268bc8566be4b320c24b41113f8f25c2204 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 3 Feb 2024 00:11:05 +0200 Subject: [PATCH 33/83] preparing java autodownload Signed-off-by: Trial97 --- launcher/java/JavaVersion.h | 10 +++++----- launcher/minecraft/LaunchProfile.cpp | 9 +++++++++ launcher/minecraft/LaunchProfile.h | 4 ++++ launcher/minecraft/VersionFile.cpp | 1 + launcher/ui/java/JavaDownloader.cpp | 6 +++--- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/launcher/java/JavaVersion.h b/launcher/java/JavaVersion.h index 92c743bfb8..dfb4770da5 100644 --- a/launcher/java/JavaVersion.h +++ b/launcher/java/JavaVersion.h @@ -30,11 +30,11 @@ class JavaVersion { QString toString() const; - int major() { return m_major; } - int minor() { return m_minor; } - int security() { return m_security; } - QString build() { return m_prerelease; } - QString name() { return m_name; } + int major() const { return m_major; } + int minor() const { return m_minor; } + int security() const { return m_security; } + QString build() const { return m_prerelease; } + QString name() const { return m_name; } private: QString m_string; diff --git a/launcher/minecraft/LaunchProfile.cpp b/launcher/minecraft/LaunchProfile.cpp index cf819b411c..77072472c2 100644 --- a/launcher/minecraft/LaunchProfile.cpp +++ b/launcher/minecraft/LaunchProfile.cpp @@ -164,6 +164,10 @@ void LaunchProfile::applyCompatibleJavaMajors(QList& javaMajor) { m_compatibleJavaMajors.append(javaMajor); } +void LaunchProfile::applyCompatibleJavaName(QString javaName) +{ + m_compatibleJavaName = javaName; +} void LaunchProfile::applyLibrary(LibraryPtr library, const RuntimeContext& runtimeContext) { @@ -334,6 +338,11 @@ const QList& LaunchProfile::getCompatibleJavaMajors() const return m_compatibleJavaMajors; } +const QString LaunchProfile::getCompatibleJavaName() const +{ + return m_compatibleJavaName; +} + void LaunchProfile::getLibraryFiles(const RuntimeContext& runtimeContext, QStringList& jars, QStringList& nativeJars, diff --git a/launcher/minecraft/LaunchProfile.h b/launcher/minecraft/LaunchProfile.h index 12b312383a..f1be6fee0b 100644 --- a/launcher/minecraft/LaunchProfile.h +++ b/launcher/minecraft/LaunchProfile.h @@ -59,6 +59,7 @@ class LaunchProfile : public ProblemProvider { void applyMavenFile(LibraryPtr library, const RuntimeContext& runtimeContext); void applyAgent(AgentPtr agent, const RuntimeContext& runtimeContext); void applyCompatibleJavaMajors(QList& javaMajor); + void applyCompatibleJavaName(QString javaName); void applyMainJar(LibraryPtr jar); void applyProblemSeverity(ProblemSeverity severity); /// clear the profile @@ -80,6 +81,7 @@ class LaunchProfile : public ProblemProvider { const QList& getMavenFiles() const; const QList& getAgents() const; const QList& getCompatibleJavaMajors() const; + const QString getCompatibleJavaName() const; const LibraryPtr getMainJar() const; void getLibraryFiles(const RuntimeContext& runtimeContext, QStringList& jars, @@ -150,5 +152,7 @@ class LaunchProfile : public ProblemProvider { /// compatible java major versions QList m_compatibleJavaMajors; + QString m_compatibleJavaName; + ProblemSeverity m_problemSeverity = ProblemSeverity::None; }; diff --git a/launcher/minecraft/VersionFile.cpp b/launcher/minecraft/VersionFile.cpp index 6632bb8bf6..8ee61128f4 100644 --- a/launcher/minecraft/VersionFile.cpp +++ b/launcher/minecraft/VersionFile.cpp @@ -73,6 +73,7 @@ void VersionFile::applyTo(LaunchProfile* profile, const RuntimeContext& runtimeC profile->applyMods(mods); profile->applyTraits(traits); profile->applyCompatibleJavaMajors(compatibleJavaMajors); + profile->applyCompatibleJavaName(compatibleJavaName); for (auto library : libraries) { profile->applyLibrary(library, runtimeContext); diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp index 9121988da9..3552f0ef5f 100644 --- a/launcher/ui/java/JavaDownloader.cpp +++ b/launcher/ui/java/JavaDownloader.cpp @@ -45,9 +45,9 @@ namespace Java { Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownloader) { ui->setupUi(this); - auto versionList = new Meta::VersionList("net.minecraft.java", this); + auto versionList = APPLICATION->metadataIndex()->get("net.minecraft.java"); versionList->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); - ui->majorVersionSelect->initialize(versionList); + ui->majorVersionSelect->initialize(versionList.get()); ui->majorVersionSelect->selectCurrent(); ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta")); ui->majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); @@ -85,7 +85,7 @@ void Downloader::accept() return; } Task::Ptr task; - auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->m_name); + auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->vendor, meta->m_name); switch (meta->downloadType) { case Java::DownloadType::Manifest: task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); From ba990e075bc9bea8b03857a643005f6fe9301a34 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Feb 2024 19:45:46 +0200 Subject: [PATCH 34/83] Added JavaPath function Signed-off-by: Trial97 --- launcher/Application.cpp | 7 ++++--- launcher/Application.h | 3 +++ launcher/java/JavaUtils.cpp | 28 +++++++++++++++++++++++++++- launcher/java/JavaUtils.h | 1 + launcher/ui/java/JavaDownloader.cpp | 2 +- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 679de711e3..20da461878 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -48,7 +48,6 @@ #include "net/PasteUpload.h" #include "pathmatcher/MultiMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h" -#include "settings/INIFile.h" #include "ui/InstanceWindow.h" #include "ui/MainWindow.h" @@ -106,8 +105,6 @@ #include "icons/IconList.h" #include "net/HttpMetaCache.h" -#include "java/JavaUtils.h" - #include "updater/ExternalUpdater.h" #include "tools/JProfiler.h" @@ -1833,3 +1830,7 @@ QUrl Application::normalizeImportUrl(QString const& url) return QUrl::fromUserInput(url); } } +const QString Application::javaPath() +{ + return FS::PathCombine(m_dataPath, "java"); +} diff --git a/launcher/Application.h b/launcher/Application.h index 85bf2dff44..ba65edd821 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -162,6 +162,9 @@ class Application : public QApplication { /// the data path the application is using const QString& dataRoot() { return m_dataPath; } + /// the java installed path the application is using + const QString javaPath(); + bool isPortable() { return m_portable; } const Capabilities capabilities() { return m_capabilities; } diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 67f1fd3a77..ff5ba5efe5 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -337,6 +337,7 @@ QList JavaUtils::FindJavaPaths() } candidates.append(getMinecraftJavaBundle()); + candidates.append(getPrismJavaBundle()); candidates = addJavasFromEnv(candidates); candidates.removeDuplicates(); return candidates; @@ -363,6 +364,7 @@ QList JavaUtils::FindJavaPaths() javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); } javas.append(getMinecraftJavaBundle()); + javas.append(getPrismJavaBundle()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -393,7 +395,6 @@ QList JavaUtils::FindJavaPaths() scanJavaDir(snap + dirPath); } }; - scanJavaDir(FS::PathCombine(APPLICATION->dataRoot(), "java")); // oracle RPMs scanJavaDirs("/usr/java"); // general locations used by distro packaging @@ -416,6 +417,7 @@ QList JavaUtils::FindJavaPaths() scanJavaDirs(FS::PathCombine(home, ".sdkman/candidates/java")); javas.append(getMinecraftJavaBundle()); + javas.append(getPrismJavaBundle()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -429,6 +431,8 @@ QList JavaUtils::FindJavaPaths() javas.append(this->GetDefaultJava()->path); javas.append(getMinecraftJavaBundle()); + javas.append(getPrismJavaBundle()); + javas.removeDuplicates(); return addJavasFromEnv(javas); } #endif @@ -484,3 +488,25 @@ QStringList getMinecraftJavaBundle() } return javas; } + +QStringList getPrismJavaBundle() +{ + QList javas; + QDir dir(APPLICATION->javaPath()); + if (!dir.exists()) + return javas; + + QString executable = "java"; +#if defined(Q_OS_WIN32) + executable += "w.exe"; +#endif + + auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for (auto& entry : entries) { + QString prefix; + prefix = entry.canonicalFilePath(); + javas.append(FS::PathCombine(prefix, "jre", "bin", executable)); + javas.append(FS::PathCombine(prefix, "bin", executable)); + } + return javas; +} diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index 0beb8c67a7..aa5315a194 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -26,6 +26,7 @@ QString stripVariableEntries(QString name, QString target, QString remove); QProcessEnvironment CleanEnviroment(); QStringList getMinecraftJavaBundle(); +QStringList getPrismJavaBundle(); class JavaUtils : public QObject { Q_OBJECT diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp index 3552f0ef5f..4495210c37 100644 --- a/launcher/ui/java/JavaDownloader.cpp +++ b/launcher/ui/java/JavaDownloader.cpp @@ -85,7 +85,7 @@ void Downloader::accept() return; } Task::Ptr task; - auto final_path = FS::PathCombine(APPLICATION->dataRoot(), "java", meta->vendor, meta->m_name); + auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name); switch (meta->downloadType) { case Java::DownloadType::Manifest: task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); From 3d29da916ded28e320eda2654ba42f529e682019 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Feb 2024 20:15:19 +0200 Subject: [PATCH 35/83] Made Java path configurable Signed-off-by: Trial97 --- launcher/Application.cpp | 3 +- launcher/ui/pages/global/LauncherPage.cpp | 12 +++ launcher/ui/pages/global/LauncherPage.h | 1 + launcher/ui/pages/global/LauncherPage.ui | 89 ++++++++++++++--------- 4 files changed, 68 insertions(+), 37 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 20da461878..cc4fc6b1c8 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -586,6 +586,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("IconsDir", "icons"); m_settings->registerSetting("DownloadsDir", QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); m_settings->registerSetting("DownloadsDirWatchRecursive", false); + m_settings->registerSetting("JavaDir", "java"); // Editors m_settings->registerSetting("JsonEditor", QString()); @@ -1832,5 +1833,5 @@ QUrl Application::normalizeImportUrl(QString const& url) } const QString Application::javaPath() { - return FS::PathCombine(m_dataPath, "java"); + return m_settings->get("JavaDir").toString(); } diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 78c44380a0..99a80d98c5 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -173,6 +173,16 @@ void LauncherPage::on_downloadsDirBrowseBtn_clicked() } } +void LauncherPage::on_javaDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Java Folder"), ui->javaDirTextBox->text()); + + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { + QString cooked_dir = FS::NormalizePath(raw_dir); + ui->javaDirTextBox->setText(cooked_dir); + } +} + void LauncherPage::on_metadataDisableBtn_clicked() { ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked()); @@ -208,6 +218,7 @@ void LauncherPage::applySettings() s->set("CentralModsDir", ui->modsDirTextBox->text()); s->set("IconsDir", ui->iconsDirTextBox->text()); s->set("DownloadsDir", ui->downloadsDirTextBox->text()); + s->set("JavaDir", ui->javaDirTextBox->text()); s->set("DownloadsDirWatchRecursive", ui->downloadsDirWatchRecursiveCheckBox->isChecked()); auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); @@ -269,6 +280,7 @@ void LauncherPage::loadSettings() ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); ui->iconsDirTextBox->setText(s->get("IconsDir").toString()); ui->downloadsDirTextBox->setText(s->get("DownloadsDir").toString()); + ui->javaDirTextBox->setText(s->get("JavaDir").toString()); ui->downloadsDirWatchRecursiveCheckBox->setChecked(s->get("DownloadsDirWatchRecursive").toBool()); QString sortMode = s->get("InstSortMode").toString(); diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index e733224d24..32945626fb 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -74,6 +74,7 @@ class LauncherPage : public QWidget, public BasePage { void on_modsDirBrowseBtn_clicked(); void on_iconsDirBrowseBtn_clicked(); void on_downloadsDirBrowseBtn_clicked(); + void on_javaDirBrowseBtn_clicked(); void on_metadataDisableBtn_clicked(); /*! diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 18b52e1b86..81acb0a177 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -7,7 +7,7 @@ 0 0 511 - 629 + 654 @@ -67,13 +67,20 @@ Folders - - + + - &Downloads: + Browse - - downloadsDirTextBox + + + + + + When enabled, in addition to the downloads folder, its sub folders will also be searched when looking for resources (e.g. when looking for blocked mods on CurseForge). + + + Check downloads folder recursively @@ -87,73 +94,83 @@ - - - - - - - - - - + Browse + + + - - + + Browse - - + + + + + + + + - &Mods: + &Icons: - modsDirTextBox + iconsDirTextBox - - + + - Browse + &Downloads: + + + downloadsDirTextBox - - + + Browse - - + + - &Icons: + &Mods: - iconsDirTextBox + modsDirTextBox - - - - When enabled, in addition to the downloads folder, its sub folders will also be searched when looking for resources (e.g. when looking for blocked mods on CurseForge). + + + + Java: + + + + + + + - Check downloads folder recursively + Browse From b3fc07d44478aa7fc841c88fe9160c462b05577a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Feb 2024 21:47:59 +0200 Subject: [PATCH 36/83] Added extra java search paths Signed-off-by: Trial97 --- launcher/Application.cpp | 1 + launcher/java/JavaUtils.cpp | 27 ++++++++--- launcher/ui/pages/global/JavaPage.cpp | 29 ++++++++++- launcher/ui/pages/global/JavaPage.h | 5 +- launcher/ui/pages/global/JavaPage.ui | 69 +++++++++++++++++++++++++-- 5 files changed, 119 insertions(+), 12 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index cc4fc6b1c8..d9abccfdc1 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -629,6 +629,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("JvmArgs", ""); m_settings->registerSetting("IgnoreJavaCompatibility", false); m_settings->registerSetting("IgnoreJavaWizard", false); + m_settings->registerSetting("JavaExtraSearchPaths", QStringList()); // Legacy settings m_settings->registerSetting("OnlineFixes", false); diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index ff5ba5efe5..cd95939809 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -492,21 +492,34 @@ QStringList getMinecraftJavaBundle() QStringList getPrismJavaBundle() { QList javas; - QDir dir(APPLICATION->javaPath()); - if (!dir.exists()) - return javas; QString executable = "java"; #if defined(Q_OS_WIN32) executable += "w.exe"; #endif - auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for (auto& entry : entries) { - QString prefix; - prefix = entry.canonicalFilePath(); + auto scanDir = [&](QString prefix) { javas.append(FS::PathCombine(prefix, "jre", "bin", executable)); javas.append(FS::PathCombine(prefix, "bin", executable)); + javas.append(FS::PathCombine(prefix, executable)); + }; + auto scanJavaDir = [&](const QString& dirPath) { + QDir dir(dirPath); + if (!dir.exists()) + return; + auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for (auto& entry : entries) { + scanDir(entry.canonicalFilePath()); + } + }; + + scanJavaDir(APPLICATION->javaPath()); + + auto extra_paths = APPLICATION->settings()->get("JavaExtraSearchPaths").toStringList(); + for (auto& entry : extra_paths) { + scanDir(entry); + scanJavaDir(entry); } + return javas; } diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 9b21aad724..6d278983de 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "ui/dialogs/VersionSelectDialog.h" @@ -57,7 +58,6 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) { ui->setupUi(this); - ui->tabWidget->tabBar()->hide(); loadSettings(); updateThresholds(); @@ -95,6 +95,7 @@ void JavaPage::applySettings() s->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " ")); s->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked()); s->set("IgnoreJavaWizard", ui->skipJavaWizardCheckbox->isChecked()); + s->set("JavaExtraSearchPaths", m_extra_paths->stringList()); JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); } void JavaPage::loadSettings() @@ -117,6 +118,8 @@ void JavaPage::loadSettings() ui->jvmArgsTextBox->setPlainText(s->get("JvmArgs").toString()); ui->skipCompatibilityCheckbox->setChecked(s->get("IgnoreJavaCompatibility").toBool()); ui->skipJavaWizardCheckbox->setChecked(s->get("IgnoreJavaWizard").toBool()); + m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList()); + ui->extraJavaPathsList->setModel(m_extra_paths); } void JavaPage::on_javaDetectBtn_clicked() @@ -217,3 +220,27 @@ void JavaPage::updateThresholds() ui->labelMaxMemIcon->setPixmap(pix); } } + +void JavaPage::on_addExtraPathButton_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Add Extra Java Folder")); + + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { + QString cooked_dir = FS::NormalizePath(raw_dir); + auto currentList = m_extra_paths->stringList(); + if (!currentList.contains(cooked_dir)) { + currentList << cooked_dir; + m_extra_paths->setStringList(currentList); + } + } + APPLICATION->settings()->set("JavaExtraSearchPaths", m_extra_paths->stringList()); +} + +void JavaPage::on_removeExtraPathButton_clicked() +{ + auto indexes = ui->extraJavaPathsList->selectionModel()->selectedIndexes(); + if (indexes.size()) { + m_extra_paths->removeRow(indexes.first().row()); + } + APPLICATION->settings()->set("JavaExtraSearchPaths", m_extra_paths->stringList()); +} diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 2bbfdf6bf8..d1315db64d 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include "JavaCommon.h" #include "ui/pages/BasePage.h" @@ -73,10 +73,13 @@ class JavaPage : public QWidget, public BasePage { void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); void on_javaDownloadBtn_clicked(); + void on_addExtraPathButton_clicked(); + void on_removeExtraPathButton_clicked(); void on_maxMemSpinBox_valueChanged(int i); void checkerFinished(); private: Ui::JavaPage* ui; unique_qobject_ptr checker; + QStringListModel* m_extra_paths; }; diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 382c183c96..d57e2e5488 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -32,11 +32,11 @@ - 0 + 1 - + - Tab 1 + General @@ -312,6 +312,69 @@ + + + Management + + + + + + Java extra paths + + + + + + + + + + + Add + + + + + + + Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + From 379f1a70e99a9a629c3cb174a1ad596fcb79a3cb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Feb 2024 22:37:57 +0200 Subject: [PATCH 37/83] Leave headers alone Signed-off-by: Trial97 --- launcher/Application.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index d9abccfdc1..4984278562 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -48,6 +48,7 @@ #include "net/PasteUpload.h" #include "pathmatcher/MultiMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h" +#include "settings/INIFile.h" #include "ui/InstanceWindow.h" #include "ui/MainWindow.h" @@ -105,6 +106,8 @@ #include "icons/IconList.h" #include "net/HttpMetaCache.h" +#include "java/JavaUtils.h" + #include "updater/ExternalUpdater.h" #include "tools/JProfiler.h" From 0a3303bcbdabbc2e5e1338dabfb3b8cf518d29e4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 9 Feb 2024 21:07:12 +0200 Subject: [PATCH 38/83] Added button to add extra java path to the Java Wizzard Signed-off-by: Trial97 --- launcher/ui/dialogs/VersionSelectDialog.h | 4 ---- launcher/ui/widgets/JavaSettingsWidget.cpp | 25 +++++++++++++++++++++- launcher/ui/widgets/JavaSettingsWidget.h | 5 ++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/launcher/ui/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h index 0ccd45e745..17efc1b93f 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.h +++ b/launcher/ui/dialogs/VersionSelectDialog.h @@ -26,10 +26,6 @@ class QDialogButtonBox; class VersionSelectWidget; class QPushButton; -namespace Ui { -class VersionSelectDialog; -} - class VersionProxyModel; class VersionSelectDialog : public QDialog { diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 3f4fe08ea4..bb57e5da74 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -42,6 +42,7 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); + connect(m_addJavaPathBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_addJavaPathBtn_clicked); } void JavaSettingsWidget::setupUi() @@ -124,9 +125,16 @@ void JavaSettingsWidget::setupUi() m_verticalLayout->addWidget(m_memoryGroupBox); + m_horizontalBtnLayout = new QHBoxLayout(); + m_horizontalBtnLayout->setObjectName(QStringLiteral("horizontalBtnLayout")); + m_javaDownloadBtn = new QPushButton(tr("Download Java"), this); + m_horizontalBtnLayout->addWidget(m_javaDownloadBtn); + + m_addJavaPathBtn = new QPushButton(tr("Add extra Java path"), this); + m_horizontalBtnLayout->addWidget(m_addJavaPathBtn); - m_verticalLayout->addWidget(m_javaDownloadBtn); + m_verticalLayout->addLayout(m_horizontalBtnLayout); retranslate(); } @@ -437,3 +445,18 @@ void JavaSettingsWidget::updateThresholds() m_labelMaxMemIcon->setPixmap(pix); } } + +void JavaSettingsWidget::on_addJavaPathBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Add Extra Java Folder")); + + auto currentList = APPLICATION->settings()->get("JavaExtraSearchPaths").toStringList(); + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { + QString cooked_dir = FS::NormalizePath(raw_dir); + if (!currentList.contains(cooked_dir)) { + currentList << cooked_dir; + } + } + APPLICATION->settings()->set("JavaExtraSearchPaths", currentList); + refresh(); +} diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index b7db955a4d..385a9256a3 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -25,7 +25,7 @@ class JavaSettingsWidget : public QWidget { public: explicit JavaSettingsWidget(QWidget* parent); - virtual ~JavaSettingsWidget(){}; + virtual ~JavaSettingsWidget() = default; enum class JavaStatus { NotSet, Pending, Good, DoesNotExist, DoesNotStart, ReturnedInvalidData } javaStatus = JavaStatus::NotSet; @@ -51,6 +51,7 @@ class JavaSettingsWidget : public QWidget { void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void on_javaDownloadBtn_clicked(); + void on_addJavaPathBtn_clicked(); void checkFinished(const JavaChecker::Result& result); protected: /* methods */ @@ -78,7 +79,9 @@ class JavaSettingsWidget : public QWidget { QLabel* m_labelPermGen = nullptr; QSpinBox* m_permGenSpinBox = nullptr; + QHBoxLayout* m_horizontalBtnLayout = nullptr; QPushButton* m_javaDownloadBtn = nullptr; + QPushButton* m_addJavaPathBtn = nullptr; QIcon goodIcon; QIcon yellowIcon; QIcon badIcon; From 27d662e64241a75eee963048a669398a5083f7ed Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 9 Feb 2024 22:47:39 +0200 Subject: [PATCH 39/83] Added management for downloaded javas from prism Signed-off-by: Trial97 --- launcher/java/JavaInstallList.cpp | 10 +++-- launcher/java/JavaInstallList.h | 6 ++- launcher/java/JavaUtils.cpp | 31 ++++++++++++++ launcher/java/JavaUtils.h | 1 + launcher/ui/pages/global/JavaPage.cpp | 40 ++++++++++++++++++ launcher/ui/pages/global/JavaPage.h | 2 + launcher/ui/pages/global/JavaPage.ui | 60 ++++++++++++++++++++++++++- 7 files changed, 143 insertions(+), 7 deletions(-) diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index d99201f24d..4172ba2cfa 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -46,7 +46,9 @@ #include "java/JavaUtils.h" #include "tasks/ConcurrentTask.h" -JavaInstallList::JavaInstallList(QObject* parent) : BaseVersionList(parent) {} +JavaInstallList::JavaInstallList(QObject* parent, bool onlyManagedVersions) + : BaseVersionList(parent), m_only_managed_versions(onlyManagedVersions) +{} Task::Ptr JavaInstallList::getLoadTask() { @@ -66,7 +68,7 @@ void JavaInstallList::load() { if (m_status != Status::InProgress) { m_status = Status::InProgress; - m_load_task.reset(new JavaListLoadTask(this)); + m_load_task.reset(new JavaListLoadTask(this, m_only_managed_versions)); m_load_task->start(); } } @@ -148,7 +150,7 @@ void JavaInstallList::sortVersions() endResetModel(); } -JavaListLoadTask::JavaListLoadTask(JavaInstallList* vlist) : Task() +JavaListLoadTask::JavaListLoadTask(JavaInstallList* vlist, bool onlyManagedVersions) : Task(), m_only_managed_versions(onlyManagedVersions) { m_list = vlist; m_current_recommended = NULL; @@ -159,7 +161,7 @@ void JavaListLoadTask::executeTask() setStatus(tr("Detecting Java installations...")); JavaUtils ju; - QList candidate_paths = ju.FindJavaPaths(); + QList candidate_paths = m_only_managed_versions ? getPrismJavaBundle() : ju.FindJavaPaths(); ConcurrentTask::Ptr job(new ConcurrentTask(this, "Java detection", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())); m_job.reset(job); diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h index 08f0b310df..c68c2a3be0 100644 --- a/launcher/java/JavaInstallList.h +++ b/launcher/java/JavaInstallList.h @@ -33,7 +33,7 @@ class JavaInstallList : public BaseVersionList { enum class Status { NotDone, InProgress, Done }; public: - explicit JavaInstallList(QObject* parent = 0); + explicit JavaInstallList(QObject* parent = 0, bool onlyManagedVersions = false); Task::Ptr getLoadTask() override; bool isLoaded() override; @@ -55,13 +55,14 @@ class JavaInstallList : public BaseVersionList { Status m_status = Status::NotDone; shared_qobject_ptr m_load_task; QList m_vlist; + bool m_only_managed_versions; }; class JavaListLoadTask : public Task { Q_OBJECT public: - explicit JavaListLoadTask(JavaInstallList* vlist); + explicit JavaListLoadTask(JavaInstallList* vlist, bool onlyManagedVersions = false); virtual ~JavaListLoadTask() = default; protected: @@ -74,4 +75,5 @@ class JavaListLoadTask : public Task { JavaInstallList* m_list; JavaInstall* m_current_recommended; QList m_results; + bool m_only_managed_versions; }; diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index cd95939809..1d254e4057 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -338,6 +338,7 @@ QList JavaUtils::FindJavaPaths() candidates.append(getMinecraftJavaBundle()); candidates.append(getPrismJavaBundle()); + candidates.append(getPrismExtraJavaPaths()); candidates = addJavasFromEnv(candidates); candidates.removeDuplicates(); return candidates; @@ -365,6 +366,7 @@ QList JavaUtils::FindJavaPaths() } javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); + javas.append(getPrismExtraJavaPaths()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -418,6 +420,7 @@ QList JavaUtils::FindJavaPaths() javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); + javas.append(getPrismExtraJavaPaths()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -432,6 +435,7 @@ QList JavaUtils::FindJavaPaths() javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); + javas.append(getPrismExtraJavaPaths()); javas.removeDuplicates(); return addJavasFromEnv(javas); } @@ -515,6 +519,33 @@ QStringList getPrismJavaBundle() scanJavaDir(APPLICATION->javaPath()); + return javas; +} + +QStringList getPrismExtraJavaPaths() +{ + QList javas; + + QString executable = "java"; +#if defined(Q_OS_WIN32) + executable += "w.exe"; +#endif + + auto scanDir = [&](QString prefix) { + javas.append(FS::PathCombine(prefix, "jre", "bin", executable)); + javas.append(FS::PathCombine(prefix, "bin", executable)); + javas.append(FS::PathCombine(prefix, executable)); + }; + auto scanJavaDir = [&](const QString& dirPath) { + QDir dir(dirPath); + if (!dir.exists()) + return; + auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for (auto& entry : entries) { + scanDir(entry.canonicalFilePath()); + } + }; + auto extra_paths = APPLICATION->settings()->get("JavaExtraSearchPaths").toStringList(); for (auto& entry : extra_paths) { scanDir(entry); diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index aa5315a194..66e4398340 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -27,6 +27,7 @@ QString stripVariableEntries(QString name, QString target, QString remove); QProcessEnvironment CleanEnviroment(); QStringList getMinecraftJavaBundle(); QStringList getPrismJavaBundle(); +QStringList getPrismExtraJavaPaths(); class JavaUtils : public QObject { Q_OBJECT diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 6d278983de..7d7530e353 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -36,6 +36,8 @@ #include "JavaPage.h" #include "JavaCommon.h" +#include "java/JavaInstall.h" +#include "ui/dialogs/CustomMessageBox.h" #include "ui/java/JavaDownloader.h" #include "ui_JavaPage.h" @@ -59,6 +61,11 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) { ui->setupUi(this); + ui->managedJavaList->initialize(new JavaInstallList(this, true)); + ui->managedJavaList->selectCurrent(); + ui->managedJavaList->setEmptyString(tr("No java versions are currently available in the meta")); + ui->managedJavaList->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + loadSettings(); updateThresholds(); } @@ -244,3 +251,36 @@ void JavaPage::on_removeExtraPathButton_clicked() } APPLICATION->settings()->set("JavaExtraSearchPaths", m_extra_paths->stringList()); } + +void JavaPage::on_downloadJavaButton_clicked() +{ + on_javaDownloadBtn_clicked(); +} + +void JavaPage::on_removeJavaButton_clicked() +{ + auto version = ui->managedJavaList->selectedVersion(); + auto dcast = std::dynamic_pointer_cast(version); + if (!dcast) { + return; + } + QDir dir(APPLICATION->javaPath()); + + auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for (auto& entry : entries) { + if (dcast->path.startsWith(entry.canonicalFilePath())) { + auto response = CustomMessageBox::selectable(this, tr("Confirm Deletion"), + tr("You are about to remove \"%1\" java version.\n" + "Are you sure?") + .arg(entry.fileName()), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response == QMessageBox::Yes) { + FS::deletePath(entry.canonicalFilePath()); + ui->managedJavaList->loadList(); + } + break; + } + } +} diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index d1315db64d..03d14b8246 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -75,6 +75,8 @@ class JavaPage : public QWidget, public BasePage { void on_javaDownloadBtn_clicked(); void on_addExtraPathButton_clicked(); void on_removeExtraPathButton_clicked(); + void on_downloadJavaButton_clicked(); + void on_removeJavaButton_clicked(); void on_maxMemSpinBox_valueChanged(int i); void checkerFinished(); diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index d57e2e5488..a518b0b149 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -32,7 +32,7 @@ - 1 + 0 @@ -317,6 +317,56 @@ Management + + + + Downloaded Java Versions + + + + + + + 0 + 0 + + + + + + + + + + Download + + + + + + + Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + @@ -379,6 +429,14 @@ + + + VersionSelectWidget + QWidget +
ui/widgets/VersionSelectWidget.h
+ 1 +
+
minMemSpinBox maxMemSpinBox From c0fb053ccc966045df42e8b218a994cfcfdef986 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 9 Feb 2024 23:14:49 +0200 Subject: [PATCH 40/83] Added warning for x86 java Signed-off-by: Trial97 --- launcher/java/JavaInstall.h | 1 + launcher/java/JavaInstallList.cpp | 1 + launcher/ui/pages/global/JavaPage.cpp | 8 ++++++++ launcher/ui/pages/instance/InstanceSettingsPage.cpp | 10 ++++++++++ launcher/ui/widgets/JavaSettingsWidget.cpp | 4 ++++ 5 files changed, 24 insertions(+) diff --git a/launcher/java/JavaInstall.h b/launcher/java/JavaInstall.h index 8c2743a00e..6890264f33 100644 --- a/launcher/java/JavaInstall.h +++ b/launcher/java/JavaInstall.h @@ -40,6 +40,7 @@ struct JavaInstall : public BaseVersion { QString arch; QString path; bool recommended = false; + bool is_64bit = false; }; using JavaInstallPtr = std::shared_ptr; diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 4172ba2cfa..569fda306b 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -193,6 +193,7 @@ void JavaListLoadTask::javaCheckerFinished() javaVersion->id = result.javaVersion; javaVersion->arch = result.realPlatform; javaVersion->path = result.path; + javaVersion->is_64bit = result.is_64bit; candidates.append(javaVersion); qDebug() << " " << javaVersion->id.toString() << javaVersion->arch << javaVersion->path; diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 7d7530e353..9b2aa7637a 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -145,6 +145,14 @@ void JavaPage::on_javaDetectBtn_clicked() if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) { java = std::dynamic_pointer_cast(vselect.selectedVersion()); ui->javaPathTextBox->setText(java->path); + if (!java->is_64bit && APPLICATION->settings()->get("MaxMemAlloc").toInt() > 2048) { + CustomMessageBox::selectable(this, tr("Confirm Selection"), + tr("You selected an x86 java version.\n" + "This means that will not support more than 2Gb(2048Mb) of ram.\n" + "Please make sure that the maximum memory value is lower."), + QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) + ->exec(); + } } } diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index b962406d1a..926e48952d 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -36,6 +36,7 @@ */ #include "InstanceSettingsPage.h" +#include "ui/dialogs/CustomMessageBox.h" #include "ui/java/JavaDownloader.h" #include "ui_InstanceSettingsPage.h" @@ -412,6 +413,15 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() ui->labelPermGen->setVisible(visible); ui->labelPermgenNote->setVisible(visible); m_settings->set("PermGenVisible", visible); + + if (!java->is_64bit && m_settings->get("MaxMemAlloc").toInt() > 2048) { + CustomMessageBox::selectable(this, tr("Confirm Selection"), + tr("You selected an x86 java version.\n" + "This means that will not support more than 2Gb(2048Mb) of ram.\n" + "Please make sure that the maximum memory value is lower."), + QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) + ->exec(); + } } } diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index bb57e5da74..507c632d53 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -433,6 +433,10 @@ void JavaSettingsWidget::updateThresholds() } else if (observedMaxMemory < observedMinMemory) { iconName = "status-yellow"; m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value")); + } else if (observedMaxMemory > 2048 && m_result.is_64bit) { + iconName = "status-bad"; + m_labelMaxMemIcon->setToolTip( + tr("Your maximum memory allocation exceeds selected java posible memory(due to x86 applicatiion limitations).")); } else { iconName = "status-good"; m_labelMaxMemIcon->setToolTip(""); From 2941307581114c435a2950df59e8ddc2c3c7c0c4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 16 Feb 2024 23:42:39 +0200 Subject: [PATCH 41/83] Added basic java auto-detect and auto-download Signed-off-by: Trial97 --- launcher/Application.cpp | 2 + launcher/CMakeLists.txt | 2 + launcher/minecraft/MinecraftInstance.cpp | 12 +- launcher/minecraft/launch/AutoInstallJava.cpp | 192 ++++++++++++++++++ launcher/minecraft/launch/AutoInstallJava.h | 67 ++++++ .../minecraft/launch/VerifyJavaInstall.cpp | 45 +--- launcher/ui/pages/global/JavaPage.cpp | 4 + launcher/ui/pages/global/JavaPage.ui | 66 +++--- 8 files changed, 325 insertions(+), 65 deletions(-) create mode 100644 launcher/minecraft/launch/AutoInstallJava.cpp create mode 100644 launcher/minecraft/launch/AutoInstallJava.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 4984278562..6b7333972f 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -633,6 +633,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("IgnoreJavaCompatibility", false); m_settings->registerSetting("IgnoreJavaWizard", false); m_settings->registerSetting("JavaExtraSearchPaths", QStringList()); + m_settings->registerSetting("AutomaticJavaSwitch", false); + m_settings->registerSetting("AutomaticJavaDownload", false); // Legacy settings m_settings->registerSetting("OnlineFixes", false); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c7945d1b84..fcc3c2f3a5 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -281,6 +281,8 @@ set(MINECRAFT_SOURCES minecraft/launch/ScanModFolders.h minecraft/launch/VerifyJavaInstall.cpp minecraft/launch/VerifyJavaInstall.h + minecraft/launch/AutoInstallJava.cpp + minecraft/launch/AutoInstallJava.h minecraft/GradleSpecifier.h minecraft/MinecraftInstance.cpp diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 4229f73eb8..00ce405aa8 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -38,6 +38,8 @@ #include "MinecraftInstance.h" #include "Application.h" #include "BuildConfig.h" +#include "QObjectPtr.h" +#include "minecraft/launch/AutoInstallJava.h" #include "minecraft/launch/CreateGameFolders.h" #include "minecraft/launch/ExtractNatives.h" #include "minecraft/launch/PrintInstanceInfo.h" @@ -1041,11 +1043,6 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(makeShared(pptr, "Minecraft folder is:\n" + gameRoot() + "\n\n", MessageLevel::Launcher)); } - // check java - { - process->appendStep(makeShared(pptr)); - } - // create the .minecraft folder and server-resource-packs (workaround for Minecraft bug MCL-3732) { process->appendStep(makeShared(pptr)); @@ -1105,6 +1102,11 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt { process->appendStep(makeShared(pptr)); } + // check java + { + process->appendStep(makeShared(pptr)); + process->appendStep(makeShared(pptr)); + } // verify that minimum Java requirements are met { diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp new file mode 100644 index 0000000000..0d3740c932 --- /dev/null +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AutoInstallJava.h" +#include +#include +#include + +#include "Application.h" +#include "FileSystem.h" +#include "MessageLevel.h" +#include "SysInfo.h" +#include "java/JavaInstall.h" +#include "java/JavaInstallList.h" +#include "java/JavaVersion.h" +#include "java/download/ArchiveDownloadTask.h" +#include "java/download/ManifestDownloadTask.h" +#include "meta/Index.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" +#include "net/Mode.h" + +AutoInstallJava::AutoInstallJava(LaunchTask* parent) + : LaunchStep(parent) + , m_instance(std::dynamic_pointer_cast(m_parent->instance())) + , m_supported_arch(SysInfo::getSupportedJavaArchitecture()){}; + +void AutoInstallJava::executeTask() +{ + auto settings = m_instance->settings(); + if (!APPLICATION->settings()->get("AutomaticJavaSwitch").toBool() || + (settings->get("OverrideJava").toBool() && settings->get("OverrideJavaLocation").toBool())) { + emitSucceeded(); + return; + } + auto packProfile = m_instance->getPackProfile(); + if (!APPLICATION->settings()->get("AutomaticJavaDownload").toBool()) { + auto javas = APPLICATION->javalist().get(); + m_current_task = javas->getLoadTask(); + connect(m_current_task.get(), &Task::finished, this, [this, javas, packProfile] { + for (auto i = 0; i < javas->count(); i++) { + auto java = std::dynamic_pointer_cast(javas->at(i)); + if (java && packProfile->getProfile()->getCompatibleJavaMajors().contains(java->id.major())) { + setJavaPath(java->path); + return; + } + } + emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emitSucceeded(); + }); + return; + } + auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); + QDir javaDir(APPLICATION->javaPath()); + auto wantedJavaPath = javaDir.absoluteFilePath(wantedJavaName); + if (QFileInfo::exists(wantedJavaPath)) { + setJavaPathFromPartial(); + return; + } + auto versionList = APPLICATION->metadataIndex()->get("net.minecraft.java"); + m_current_task = versionList->getLoadTask(); + connect(m_current_task.get(), &Task::succeeded, this, &AutoInstallJava::tryNextMajorJava); + connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::emitFailed); +} + +void AutoInstallJava::setJavaPath(QString path) +{ + auto settings = m_instance->settings(); + settings->set("OverrideJava", true); + settings->set("OverrideJavaLocation", true); + settings->set("JavaPath", path); + emit logLine(tr("Compatible java found at: %1.").arg(path), MessageLevel::Info); + emitSucceeded(); +} + +void AutoInstallJava::setJavaPathFromPartial() +{ + QString executable = "java"; +#if defined(Q_OS_WIN32) + executable += "w.exe"; +#endif + auto packProfile = m_instance->getPackProfile(); + auto javaName = packProfile->getProfile()->getCompatibleJavaName(); + QDir javaDir(APPLICATION->javaPath()); + // just checking if the executable is there should suffice + // but if needed this can be achieved through refreshing the javalist + // and retrieving the path that contains the java name + auto relativeBinary = FS::PathCombine(javaName, "bin", executable); + auto finalPath = javaDir.absoluteFilePath(relativeBinary); + if (QFileInfo::exists(finalPath)) { + setJavaPath(finalPath); + } else { + emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emitSucceeded(); + } + return; +} + +void AutoInstallJava::downloadJava(Meta::Version::Ptr version, QString javaName) +{ + auto runtimes = version->data()->runtimes; + if (runtimes.contains(m_supported_arch)) { + for (auto java : runtimes.value(m_supported_arch)) { + if (java->name() == javaName) { + Task::Ptr task; + QDir javaDir(APPLICATION->javaPath()); + auto final_path = javaDir.absoluteFilePath(java->m_name); + switch (java->downloadType) { + case Java::DownloadType::Manifest: + task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + break; + case Java::DownloadType::Archive: + task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + break; + } + QEventLoop loop; + auto deletePath = [final_path] { FS::deletePath(final_path); }; + connect(task.get(), &Task::failed, this, [this, deletePath](QString reason) { + deletePath(); + emitFailed(reason); + }); + connect(this, &Task::aborted, this, [task, deletePath] { + task->abort(); + deletePath(); + }); + connect(task.get(), &Task::succeeded, this, &AutoInstallJava::setJavaPathFromPartial); + task->start(); + return; + } + } + } + tryNextMajorJava(); +} + +void AutoInstallJava::tryNextMajorJava() +{ + if (!isRunning()) + return; + auto versionList = APPLICATION->metadataIndex()->get("net.minecraft.java"); + auto packProfile = m_instance->getPackProfile(); + auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); + auto majorJavaVersions = packProfile->getProfile()->getCompatibleJavaMajors(); + if (m_majorJavaVersionIndex >= majorJavaVersions.length()) { + emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emitSucceeded(); + return; + } + auto majorJavaVersion = majorJavaVersions[m_majorJavaVersionIndex]; + m_majorJavaVersionIndex++; + + auto javaMajor = versionList->getVersion(QString("java%1").arg(majorJavaVersion)); + javaMajor->load(Net::Mode::Online); + auto task = javaMajor->getCurrentTask(); + if (javaMajor->isLoaded() || !task) { + downloadJava(javaMajor, wantedJavaName); + } else { + connect(task.get(), &Task::succeeded, this, [this, javaMajor, wantedJavaName] { downloadJava(javaMajor, wantedJavaName); }); + connect(task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); + } +} diff --git a/launcher/minecraft/launch/AutoInstallJava.h b/launcher/minecraft/launch/AutoInstallJava.h new file mode 100644 index 0000000000..4dcd3796af --- /dev/null +++ b/launcher/minecraft/launch/AutoInstallJava.h @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include "java/JavaMetadata.h" +#include "meta/Version.h" +#include "minecraft/MinecraftInstance.h" +#include "tasks/Task.h" + +class AutoInstallJava : public LaunchStep { + Q_OBJECT + + public: + explicit AutoInstallJava(LaunchTask* parent); + ~AutoInstallJava() override = default; + + void executeTask() override; + bool canAbort() const override { return m_current_task ? m_current_task->canAbort() : false; } + + protected: + void setJavaPath(QString path); + void setJavaPathFromPartial(); + void downloadJava(Meta::Version::Ptr version, QString javaName); + void tryNextMajorJava(); + + private: + MinecraftInstancePtr m_instance; + Task::Ptr m_current_task; + + qsizetype m_majorJavaVersionIndex = 0; + const QString m_supported_arch; +}; diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 2188112902..279545fed5 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -50,7 +50,6 @@ void VerifyJavaInstall::executeTask() auto settings = instance->settings(); auto storedVersion = settings->get("JavaVersion").toString(); auto ignoreCompatibility = settings->get("IgnoreJavaCompatibility").toBool(); - auto automaticJavaSwitch = settings->get("AutomaticJavaSwitch").toBool(); auto compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors(); @@ -67,38 +66,16 @@ void VerifyJavaInstall::executeTask() return; } - auto logFail = [this, &javaVersion, compatibleMajors] { - emit logLine(tr("This instance is not compatible with Java version %1.\n" - "Please switch to one of the following Java versions for this instance:") - .arg(javaVersion.major()), - MessageLevel::Error); - for (auto major : compatibleMajors) { - emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); - } - emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what " - "you're doing."), - MessageLevel::Error); - - emitFailed(QString("Incompatible Java major version")); - }; - - if (automaticJavaSwitch || true) { - settings->set("OverrideJava", true); - auto javas = APPLICATION->javalist().get(); - auto task = javas->getLoadTask(); - connect(task.get(), &Task::finished, this, [this, javas, compatibleMajors, settings, &logFail] { - for (auto i = 0; i < javas->count(); i++) { - auto java = std::dynamic_pointer_cast(javas->at(i)); - if (java && compatibleMajors.contains(java->id.major())) { - settings->set("OverrideJavaLocation", true); - settings->set("JavaPath", java->path); - emitSucceeded(); - return; - } - } - logFail(); - }); - } else { - logFail(); + emit logLine(tr("This instance is not compatible with Java version %1.\n" + "Please switch to one of the following Java versions for this instance:") + .arg(javaVersion.major()), + MessageLevel::Error); + for (auto major : compatibleMajors) { + emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } + emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what " + "you're doing."), + MessageLevel::Error); + + emitFailed(QString("Incompatible Java major version")); } diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 9b2aa7637a..496cb69a70 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -102,6 +102,8 @@ void JavaPage::applySettings() s->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " ")); s->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked()); s->set("IgnoreJavaWizard", ui->skipJavaWizardCheckbox->isChecked()); + s->set("AutomaticJavaSwitch", ui->autodetectJavaCheckBox->isChecked()); + s->set("AutomaticJavaDownload", ui->autodownloadCheckBox->isChecked()); s->set("JavaExtraSearchPaths", m_extra_paths->stringList()); JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); } @@ -125,6 +127,8 @@ void JavaPage::loadSettings() ui->jvmArgsTextBox->setPlainText(s->get("JvmArgs").toString()); ui->skipCompatibilityCheckbox->setChecked(s->get("IgnoreJavaCompatibility").toBool()); ui->skipJavaWizardCheckbox->setChecked(s->get("IgnoreJavaWizard").toBool()); + ui->autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); + ui->autodownloadCheckBox->setChecked(s->get("AutomaticJavaDownload").toBool()); m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList()); ui->extraJavaPathsList->setModel(m_extra_paths); } diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index a518b0b149..d135adc9a1 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -160,25 +160,6 @@ Java Runtime - - - - true - - - - 0 - 0 - - - - - 16777215 - 100 - - - - @@ -232,7 +213,7 @@
- + @@ -248,6 +229,42 @@ + + + + If enabled, the launcher will not prompt you to choose a Java version if one isn't found. + + + Skip Java &Wizard + + + + + + + true + + + + 0 + 0 + + + + + 16777215 + 100 + + + + + + + + Autodetect Java version + + + @@ -284,13 +301,10 @@ - - - - If enabled, the launcher will not prompt you to choose a Java version if one isn't found. - + + - Skip Java &Wizard + Autodownload Mojang Java From ea2adf909dfe10c0adaf53ef2fabbd94ee7ae8cd Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 17 Feb 2024 11:14:32 +0200 Subject: [PATCH 42/83] Added progeess dialog to autodownload java Signed-off-by: Trial97 --- .../java/download/ArchiveDownloadTask.cpp | 5 +- .../java/download/ManifestDownloadTask.cpp | 10 +++- launcher/minecraft/launch/AutoInstallJava.cpp | 59 ++++++++++++++----- launcher/minecraft/launch/AutoInstallJava.h | 1 + 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 847f3f3649..9f8dc05438 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -50,9 +50,12 @@ void ArchiveDownloadTask::executeTask() auto fullPath = entry->getFullPath(); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &ArchiveDownloadTask::progress); connect(download.get(), &NetJob::failed, this, &ArchiveDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &Task::progress, this, &ArchiveDownloadTask::setProgress); + connect(download.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); + connect(download.get(), &Task::status, this, &ArchiveDownloadTask::setStatus); + connect(download.get(), &Task::details, this, &ArchiveDownloadTask::setDetails); connect(download.get(), &NetJob::succeeded, [this, fullPath] { // This should do all of the extracting and creating folders extractJava(fullPath); diff --git a/launcher/java/download/ManifestDownloadTask.cpp b/launcher/java/download/ManifestDownloadTask.cpp index 1a30715301..0c2eee0c85 100644 --- a/launcher/java/download/ManifestDownloadTask.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -52,9 +52,12 @@ void ManifestDownloadTask::executeTask() download->addNetAction(action); connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); - connect(download.get(), &NetJob::progress, this, &ManifestDownloadTask::progress); connect(download.get(), &NetJob::failed, this, &ManifestDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &Task::progress, this, &ManifestDownloadTask::setProgress); + connect(download.get(), &Task::stepProgress, this, &ManifestDownloadTask::propagateStepProgress); + connect(download.get(), &Task::status, this, &ManifestDownloadTask::setStatus); + connect(download.get(), &Task::details, this, &ManifestDownloadTask::setDetails); connect(download.get(), &NetJob::succeeded, [files, this] { QJsonParseError parse_error{}; @@ -117,8 +120,11 @@ void ManifestDownloadTask::downloadJava(const QJsonDocument& doc) disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); elementDownload->deleteLater(); }); - connect(elementDownload, &NetJob::progress, this, &ManifestDownloadTask::progress); connect(elementDownload, &NetJob::failed, this, &ManifestDownloadTask::emitFailed); + connect(elementDownload, &Task::progress, this, &ManifestDownloadTask::setProgress); + connect(elementDownload, &Task::stepProgress, this, &ManifestDownloadTask::propagateStepProgress); + connect(elementDownload, &Task::status, this, &ManifestDownloadTask::setStatus); + connect(elementDownload, &Task::details, this, &ManifestDownloadTask::setDetails); connect(this, &Task::aborted, elementDownload, &NetJob::abort); connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 0d3740c932..d93276432e 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -34,8 +34,8 @@ */ #include "AutoInstallJava.h" -#include -#include +#include +#include #include #include "Application.h" @@ -61,7 +61,8 @@ void AutoInstallJava::executeTask() { auto settings = m_instance->settings(); if (!APPLICATION->settings()->get("AutomaticJavaSwitch").toBool() || - (settings->get("OverrideJava").toBool() && settings->get("OverrideJavaLocation").toBool())) { + (settings->get("OverrideJava").toBool() && settings->get("OverrideJavaLocation").toBool() && + QFileInfo::exists(settings->get("JavaPath").toString()))) { emitSucceeded(); return; } @@ -80,6 +81,11 @@ void AutoInstallJava::executeTask() emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); }); + connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); + connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); + connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); + connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); + emit progressReportingRequest(); return; } auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); @@ -93,6 +99,11 @@ void AutoInstallJava::executeTask() m_current_task = versionList->getLoadTask(); connect(m_current_task.get(), &Task::succeeded, this, &AutoInstallJava::tryNextMajorJava); connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::emitFailed); + connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); + connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); + connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); + connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); + emit progressReportingRequest(); } void AutoInstallJava::setJavaPath(QString path) @@ -134,29 +145,34 @@ void AutoInstallJava::downloadJava(Meta::Version::Ptr version, QString javaName) if (runtimes.contains(m_supported_arch)) { for (auto java : runtimes.value(m_supported_arch)) { if (java->name() == javaName) { - Task::Ptr task; QDir javaDir(APPLICATION->javaPath()); auto final_path = javaDir.absoluteFilePath(java->m_name); switch (java->downloadType) { case Java::DownloadType::Manifest: - task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + m_current_task = + makeShared(java->url, final_path, java->checksumType, java->checksumHash); break; case Java::DownloadType::Archive: - task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + m_current_task = + makeShared(java->url, final_path, java->checksumType, java->checksumHash); break; } - QEventLoop loop; auto deletePath = [final_path] { FS::deletePath(final_path); }; - connect(task.get(), &Task::failed, this, [this, deletePath](QString reason) { + connect(m_current_task.get(), &Task::failed, this, [this, deletePath](QString reason) { deletePath(); emitFailed(reason); }); - connect(this, &Task::aborted, this, [task, deletePath] { - task->abort(); + connect(this, &Task::aborted, this, [this, deletePath] { + m_current_task->abort(); deletePath(); }); - connect(task.get(), &Task::succeeded, this, &AutoInstallJava::setJavaPathFromPartial); - task->start(); + connect(m_current_task.get(), &Task::succeeded, this, &AutoInstallJava::setJavaPathFromPartial); + connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); + connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); + connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); + connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); + connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); + m_current_task->start(); return; } } @@ -182,11 +198,22 @@ void AutoInstallJava::tryNextMajorJava() auto javaMajor = versionList->getVersion(QString("java%1").arg(majorJavaVersion)); javaMajor->load(Net::Mode::Online); - auto task = javaMajor->getCurrentTask(); - if (javaMajor->isLoaded() || !task) { + m_current_task = javaMajor->getCurrentTask(); + if (javaMajor->isLoaded() || !m_current_task) { downloadJava(javaMajor, wantedJavaName); } else { - connect(task.get(), &Task::succeeded, this, [this, javaMajor, wantedJavaName] { downloadJava(javaMajor, wantedJavaName); }); - connect(task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); + connect(m_current_task.get(), &Task::succeeded, this, + [this, javaMajor, wantedJavaName] { downloadJava(javaMajor, wantedJavaName); }); + connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); + connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); + connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); + connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); + connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); } } +bool AutoInstallJava::abort() +{ + if (m_current_task && m_current_task->canAbort()) + return m_current_task->abort(); + return true; +} diff --git a/launcher/minecraft/launch/AutoInstallJava.h b/launcher/minecraft/launch/AutoInstallJava.h index 4dcd3796af..45d0f870e1 100644 --- a/launcher/minecraft/launch/AutoInstallJava.h +++ b/launcher/minecraft/launch/AutoInstallJava.h @@ -51,6 +51,7 @@ class AutoInstallJava : public LaunchStep { void executeTask() override; bool canAbort() const override { return m_current_task ? m_current_task->canAbort() : false; } + bool abort() override; protected: void setJavaPath(QString path); From 5232b3cd89ce70722865bc1ad6d96d8f52db1789 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 17 Feb 2024 12:17:00 +0200 Subject: [PATCH 43/83] Added some logs and fixed natives extraction Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 11 ++++++----- launcher/minecraft/launch/AutoInstallJava.cpp | 5 ++++- launcher/minecraft/launch/VerifyJavaInstall.cpp | 11 +++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 00ce405aa8..cfc65428cb 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1078,6 +1078,12 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(makeShared(pptr, Net::Mode::Offline)); } + // check java + { + process->appendStep(makeShared(pptr)); + process->appendStep(makeShared(pptr)); + } + // if there are any jar mods { process->appendStep(makeShared(pptr)); @@ -1102,11 +1108,6 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt { process->appendStep(makeShared(pptr)); } - // check java - { - process->appendStep(makeShared(pptr)); - process->appendStep(makeShared(pptr)); - } // verify that minimum Java requirements are met { diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index d93276432e..7905689da8 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -68,12 +68,15 @@ void AutoInstallJava::executeTask() } auto packProfile = m_instance->getPackProfile(); if (!APPLICATION->settings()->get("AutomaticJavaDownload").toBool()) { - auto javas = APPLICATION->javalist().get(); + auto javas = APPLICATION->javalist(); m_current_task = javas->getLoadTask(); connect(m_current_task.get(), &Task::finished, this, [this, javas, packProfile] { for (auto i = 0; i < javas->count(); i++) { auto java = std::dynamic_pointer_cast(javas->at(i)); if (java && packProfile->getProfile()->getCompatibleJavaMajors().contains(java->id.major())) { + if (!java->is_64bit) { + emit logLine(tr("The automatic Java mechanism detected a x32 java."), MessageLevel::Info); + } setJavaPath(java->path); return; } diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 279545fed5..536384f126 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -37,6 +37,7 @@ #include #include "Application.h" +#include "MessageLevel.h" #include "java/JavaInstall.h" #include "java/JavaInstallList.h" #include "java/JavaVersion.h" @@ -50,6 +51,16 @@ void VerifyJavaInstall::executeTask() auto settings = instance->settings(); auto storedVersion = settings->get("JavaVersion").toString(); auto ignoreCompatibility = settings->get("IgnoreJavaCompatibility").toBool(); + auto javaArchitecture = settings->get("JavaArchitecture").toString(); + auto maxMemAlloc = settings->get("MaxMemAlloc").toInt(); + + emit logLine(tr("Java architecture is x%1.").arg(javaArchitecture), MessageLevel::Info); + if (javaArchitecture == "32" && maxMemAlloc > 2048) { + emit logLine(tr("Max memory allocation exceeds the supported value.\n" + "The selected java is 32 bit and doesn't support more than 2GB of ram.\n" + "The instance may not start due to this."), + MessageLevel::Error); + } auto compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors(); From a7dad96a701100ab583b4c9ca00a7c9b979fcf84 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 09:32:31 +0200 Subject: [PATCH 44/83] Added refresh button on managed java list Signed-off-by: Trial97 --- launcher/ui/pages/global/JavaPage.cpp | 4 ++++ launcher/ui/pages/global/JavaPage.h | 1 + launcher/ui/pages/global/JavaPage.ui | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 496cb69a70..e967204c8d 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -296,3 +296,7 @@ void JavaPage::on_removeJavaButton_clicked() } } } +void JavaPage::on_refreshJavaButton_clicked() +{ + ui->managedJavaList->loadList(); +} diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 03d14b8246..1a521e2db9 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -77,6 +77,7 @@ class JavaPage : public QWidget, public BasePage { void on_removeExtraPathButton_clicked(); void on_downloadJavaButton_clicked(); void on_removeJavaButton_clicked(); + void on_refreshJavaButton_clicked(); void on_maxMemSpinBox_valueChanged(int i); void checkerFinished(); diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index d135adc9a1..80be81fb4d 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -376,6 +376,13 @@ + + + + Refresh + + +
From 4c76f7afe0a1ea015d7c0eac7a1a6b1c8a1a760a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 09:46:44 +0200 Subject: [PATCH 45/83] Made auto java checkbox dependent Signed-off-by: Trial97 --- launcher/ui/pages/global/JavaPage.cpp | 8 +++++++- launcher/ui/pages/global/JavaPage.ui | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index e967204c8d..0e97211d96 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -41,6 +41,7 @@ #include "ui/java/JavaDownloader.h" #include "ui_JavaPage.h" +#include #include #include #include @@ -65,6 +66,11 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) ui->managedJavaList->selectCurrent(); ui->managedJavaList->setEmptyString(tr("No java versions are currently available in the meta")); ui->managedJavaList->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + connect(ui->autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { + ui->autodownloadCheckBox->setEnabled(ui->autodetectJavaCheckBox->isChecked()); + if (!ui->autodetectJavaCheckBox->isChecked()) + ui->autodownloadCheckBox->setChecked(false); + }); loadSettings(); updateThresholds(); @@ -128,7 +134,7 @@ void JavaPage::loadSettings() ui->skipCompatibilityCheckbox->setChecked(s->get("IgnoreJavaCompatibility").toBool()); ui->skipJavaWizardCheckbox->setChecked(s->get("IgnoreJavaWizard").toBool()); ui->autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); - ui->autodownloadCheckBox->setChecked(s->get("AutomaticJavaDownload").toBool()); + ui->autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList()); ui->extraJavaPathsList->setModel(m_extra_paths); } diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 80be81fb4d..43843017c4 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -303,6 +303,9 @@ + + false + Autodownload Mojang Java From 2f489d1aec120274b3e98187bf8326c8990bca12 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 11:34:54 +0200 Subject: [PATCH 46/83] Added auto java options to the java wizzard page Signed-off-by: Trial97 --- launcher/ui/setupwizard/JavaWizardPage.cpp | 2 ++ launcher/ui/widgets/JavaSettingsWidget.cpp | 38 ++++++++++++++++++++++ launcher/ui/widgets/JavaSettingsWidget.h | 8 +++++ 3 files changed, 48 insertions(+) diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index abe4860da4..d537580fcd 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -57,6 +57,8 @@ bool JavaWizardPage::validatePage() { auto settings = APPLICATION->settings(); auto result = m_java_widget->validate(); + settings->set("AutomaticJavaSwitch", m_java_widget->autodetectJava()); + settings->set("AutomaticJavaDownload", m_java_widget->autodownloadJava()); switch (result) { default: case JavaSettingsWidget::ValidationStatus::Bad: { diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 507c632d53..c15f7bf429 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -136,6 +136,26 @@ void JavaSettingsWidget::setupUi() m_verticalLayout->addLayout(m_horizontalBtnLayout); + m_autoJavaGroupBox = new QGroupBox(this); + m_autoJavaGroupBox->setObjectName(QStringLiteral("autoJavaGroupBox")); + m_veriticalJavaLayout = new QVBoxLayout(m_autoJavaGroupBox); + m_veriticalJavaLayout->setObjectName(QStringLiteral("veriticalJavaLayout")); + + m_autodetectJavaCheckBox = new QCheckBox(m_autoJavaGroupBox); + m_autodetectJavaCheckBox->setObjectName("autodetectJavaCheckBox"); + m_veriticalJavaLayout->addWidget(m_autodetectJavaCheckBox); + + m_autodownloadCheckBox = new QCheckBox(m_autoJavaGroupBox); + m_autodownloadCheckBox->setObjectName("autodownloadCheckBox"); + m_autodownloadCheckBox->setEnabled(false); + m_veriticalJavaLayout->addWidget(m_autodownloadCheckBox); + connect(m_autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { + m_autodownloadCheckBox->setEnabled(m_autodetectJavaCheckBox->isChecked()); + if (!m_autodetectJavaCheckBox->isChecked()) + m_autodownloadCheckBox->setChecked(false); + }); + m_verticalLayout->addWidget(m_autoJavaGroupBox); + retranslate(); } @@ -153,6 +173,9 @@ void JavaSettingsWidget::initialize() m_maxMemSpinBox->setValue(observedMaxMemory); m_permGenSpinBox->setValue(observedPermGenMemory); updateThresholds(); + + m_autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); + m_autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); } void JavaSettingsWidget::refresh() @@ -280,11 +303,13 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() m_javaPathTextBox->setText(cooked_path); checkJavaPath(cooked_path); } + void JavaSettingsWidget::on_javaDownloadBtn_clicked() { auto jdialog = new Java::Downloader(this); jdialog->exec(); } + void JavaSettingsWidget::on_javaStatusBtn_clicked() { QString text; @@ -418,6 +443,9 @@ void JavaSettingsWidget::retranslate() m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with.")); m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes.")); m_javaBrowseBtn->setText(tr("Browse")); + m_autodownloadCheckBox->setText(tr("Autodownload Mojang Java")); + m_autodetectJavaCheckBox->setText(tr("Autodetect Java version")); + m_autoJavaGroupBox->setTitle(tr("Autodetect Java")); } void JavaSettingsWidget::updateThresholds() @@ -464,3 +492,13 @@ void JavaSettingsWidget::on_addJavaPathBtn_clicked() APPLICATION->settings()->set("JavaExtraSearchPaths", currentList); refresh(); } + +bool JavaSettingsWidget::autodownloadJava() const +{ + return m_autodetectJavaCheckBox->isChecked(); +} + +bool JavaSettingsWidget::autodetectJava() const +{ + return m_autodownloadCheckBox->isChecked(); +} diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 385a9256a3..205b83d8c7 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -4,6 +4,7 @@ #include #include #include +#include #include class QLineEdit; @@ -41,6 +42,8 @@ class JavaSettingsWidget : public QWidget { int minHeapSize() const; int maxHeapSize() const; QString javaPath() const; + bool autodetectJava() const; + bool autodownloadJava() const; void updateThresholds(); @@ -86,6 +89,11 @@ class JavaSettingsWidget : public QWidget { QIcon yellowIcon; QIcon badIcon; + QGroupBox* m_autoJavaGroupBox = nullptr; + QVBoxLayout* m_veriticalJavaLayout = nullptr; + QCheckBox* m_autodetectJavaCheckBox = nullptr; + QCheckBox* m_autodownloadCheckBox = nullptr; + unsigned int observedMinMemory = 0; unsigned int observedMaxMemory = 0; unsigned int observedPermGenMemory = 0; From 4aafa98852ec1f89cc765def26ab9e4174b8af3b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 12:58:34 +0200 Subject: [PATCH 47/83] Improved the message boxes for java wizzard Signed-off-by: Trial97 --- launcher/ui/widgets/JavaSettingsWidget.cpp | 71 ++++++++++++++++++---- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index c15f7bf429..66278abb0f 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -11,6 +12,7 @@ #include +#include "DesktopServices.h" #include "FileSystem.h" #include "JavaCommon.h" #include "java/JavaChecker.h" @@ -174,8 +176,19 @@ void JavaSettingsWidget::initialize() m_permGenSpinBox->setValue(observedPermGenMemory); updateThresholds(); - m_autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); - m_autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); + auto button = CustomMessageBox::selectable(this, tr("Auto Java Download"), + tr("%1 has now the ability to auto downloand the correct java for each minecraft version.\n" + "Do you want to enable java auto-download?\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) + ->exec(); + if (button == QMessageBox::Yes) { + m_autodetectJavaCheckBox->setChecked(true); + m_autodownloadCheckBox->setChecked(true); + } else { + m_autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); + m_autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); + } } void JavaSettingsWidget::refresh() @@ -192,20 +205,52 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() switch (javaStatus) { default: case JavaStatus::NotSet: + /* fallthrough */ case JavaStatus::DoesNotExist: + /* fallthrough */ case JavaStatus::DoesNotStart: + /* fallthrough */ case JavaStatus::ReturnedInvalidData: { - int button = CustomMessageBox::selectable(this, tr("No Java version selected"), - tr("You didn't select a Java version or selected something that doesn't work.\n" - "%1 will not be able to start Minecraft.\n" - "Do you wish to proceed without any Java?" - "\n\n" - "You can change the Java version in the settings later.\n") - .arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton) - ->exec(); - if (button == QMessageBox::No) { - return ValidationStatus::Bad; + if (!m_autodownloadCheckBox->isChecked()) { // the java will not be autodownloaded + int button = QMessageBox::No; + if (m_result.mojangPlatform == "32" && maxHeapSize() > 2048) { + button = CustomMessageBox::selectable( + this, tr("Java x32 detected"), + tr("You selected a 32 bit java, but allocated more than 2048MiB as maximum memory.\n" + "%1 will not be able to start Minecraft.\n" + "Do you wish to proceed?" + "\n\n" + "You can change the Java version in the settings later.\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::NoButton) + ->exec(); + + } else { + button = CustomMessageBox::selectable(this, tr("No Java version selected"), + tr("You didn't select a Java version or selected something that doesn't work.\n" + "%1 will not be able to start Minecraft.\n" + "Do you wish to proceed without any Java?" + "\n\n" + "You can change the Java version in the settings later.\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, + QMessageBox::NoButton) + ->exec(); + } + switch (button) { + case QMessageBox::Yes: + return ValidationStatus::JavaBad; + case QMessageBox::Help: + DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("java-wizzard"))); + /* fallthrough */ + case QMessageBox::No: + /* fallthrough */ + default: + return ValidationStatus::Bad; + } + if (button == QMessageBox::No) { + return ValidationStatus::Bad; + } } return ValidationStatus::JavaBad; } break; From b4f3a969b3fd2f96675d25e3c8726c76395b3d7e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 14:30:38 +0200 Subject: [PATCH 48/83] Updated strings that are displayed to user Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 2 +- launcher/MMCZip.h | 2 +- launcher/java/JavaInstall.cpp | 2 +- launcher/java/JavaInstall.h | 2 +- launcher/java/JavaMetadata.cpp | 2 +- launcher/java/JavaMetadata.h | 2 +- launcher/java/download/ArchiveDownloadTask.cpp | 2 +- launcher/java/download/ArchiveDownloadTask.h | 2 +- launcher/java/download/ManifestDownloadTask.cpp | 2 +- launcher/java/download/ManifestDownloadTask.h | 2 +- launcher/minecraft/launch/AutoInstallJava.cpp | 10 +++++----- launcher/minecraft/launch/AutoInstallJava.h | 2 +- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 +- launcher/ui/java/JavaDownloader.cpp | 2 +- launcher/ui/pages/global/JavaPage.cpp | 2 +- launcher/ui/pages/global/JavaPage.ui | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.ui | 3 --- launcher/ui/widgets/JavaSettingsWidget.cpp | 6 +++--- 19 files changed, 24 insertions(+), 27 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 9e26c5eda5..8273acbb68 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index db6a7421a8..e2987badd5 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/JavaInstall.cpp b/launcher/java/JavaInstall.cpp index cfa471402f..8e97e0e144 100644 --- a/launcher/java/JavaInstall.cpp +++ b/launcher/java/JavaInstall.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/JavaInstall.h b/launcher/java/JavaInstall.h index 6890264f33..7d8d392fab 100644 --- a/launcher/java/JavaInstall.h +++ b/launcher/java/JavaInstall.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/JavaMetadata.cpp b/launcher/java/JavaMetadata.cpp index b261122dc0..b73c54fe6c 100644 --- a/launcher/java/JavaMetadata.cpp +++ b/launcher/java/JavaMetadata.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/JavaMetadata.h b/launcher/java/JavaMetadata.h index dd3ae865c4..640a412f11 100644 --- a/launcher/java/JavaMetadata.h +++ b/launcher/java/JavaMetadata.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 9f8dc05438..e3db77d2cc 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/download/ArchiveDownloadTask.h b/launcher/java/download/ArchiveDownloadTask.h index 88c0223d5a..c656567fe1 100644 --- a/launcher/java/download/ArchiveDownloadTask.h +++ b/launcher/java/download/ArchiveDownloadTask.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/download/ManifestDownloadTask.cpp b/launcher/java/download/ManifestDownloadTask.cpp index 0c2eee0c85..ba5ff2cc05 100644 --- a/launcher/java/download/ManifestDownloadTask.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/java/download/ManifestDownloadTask.h b/launcher/java/download/ManifestDownloadTask.h index dcfee4d4da..f0eaf95a61 100644 --- a/launcher/java/download/ManifestDownloadTask.h +++ b/launcher/java/download/ManifestDownloadTask.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 7905689da8..ab68910a77 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023-2024 Trial97 * * 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 @@ -75,13 +75,13 @@ void AutoInstallJava::executeTask() auto java = std::dynamic_pointer_cast(javas->at(i)); if (java && packProfile->getProfile()->getCompatibleJavaMajors().contains(java->id.major())) { if (!java->is_64bit) { - emit logLine(tr("The automatic Java mechanism detected a x32 java."), MessageLevel::Info); + emit logLine(tr("The automatic Java mechanism detected an x32 java."), MessageLevel::Info); } setJavaPath(java->path); return; } } - emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); }); connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); @@ -136,7 +136,7 @@ void AutoInstallJava::setJavaPathFromPartial() if (QFileInfo::exists(finalPath)) { setJavaPath(finalPath); } else { - emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); } return; @@ -192,7 +192,7 @@ void AutoInstallJava::tryNextMajorJava() auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); auto majorJavaVersions = packProfile->getProfile()->getCompatibleJavaMajors(); if (m_majorJavaVersionIndex >= majorJavaVersions.length()) { - emit logLine(tr("No comptatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); return; } diff --git a/launcher/minecraft/launch/AutoInstallJava.h b/launcher/minecraft/launch/AutoInstallJava.h index 45d0f870e1..7e4efc50cf 100644 --- a/launcher/minecraft/launch/AutoInstallJava.h +++ b/launcher/minecraft/launch/AutoInstallJava.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023-2024 Trial97 * * 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 diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 536384f126..f26b850ebd 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -57,7 +57,7 @@ void VerifyJavaInstall::executeTask() emit logLine(tr("Java architecture is x%1.").arg(javaArchitecture), MessageLevel::Info); if (javaArchitecture == "32" && maxMemAlloc > 2048) { emit logLine(tr("Max memory allocation exceeds the supported value.\n" - "The selected java is 32 bit and doesn't support more than 2GB of ram.\n" + "The selected java is 32-bit and doesn't support more than 2048MiB of RAM.\n" "The instance may not start due to this."), MessageLevel::Error); } diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp index 4495210c37..7417a4ea8c 100644 --- a/launcher/ui/java/JavaDownloader.cpp +++ b/launcher/ui/java/JavaDownloader.cpp @@ -49,7 +49,7 @@ Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownlo versionList->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); ui->majorVersionSelect->initialize(versionList.get()); ui->majorVersionSelect->selectCurrent(); - ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta")); + ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta.")); ui->majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); ui->javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 0e97211d96..524165e62c 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -158,7 +158,7 @@ void JavaPage::on_javaDetectBtn_clicked() if (!java->is_64bit && APPLICATION->settings()->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), tr("You selected an x86 java version.\n" - "This means that will not support more than 2Gb(2048Mb) of ram.\n" + "This means that will not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) ->exec(); diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 43843017c4..3f763f8d29 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -307,7 +307,7 @@ false - Autodownload Mojang Java + Auto-download Mojang Java diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 926e48952d..8a63aab22e 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -417,7 +417,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() if (!java->is_64bit && m_settings->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), tr("You selected an x86 java version.\n" - "This means that will not support more than 2Gb(2048Mb) of ram.\n" + "This means that will not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) ->exec(); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 7762ca8a7e..94464064ee 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -617,9 +617,6 @@ Enable online fixes (experimental) - - Disable Quilt Loader Beacon - diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 66278abb0f..91fd6ff03e 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -216,7 +216,7 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() if (m_result.mojangPlatform == "32" && maxHeapSize() > 2048) { button = CustomMessageBox::selectable( this, tr("Java x32 detected"), - tr("You selected a 32 bit java, but allocated more than 2048MiB as maximum memory.\n" + tr("You selected an 32-bit java, but allocated more than 2048MiB as maximum memory.\n" "%1 will not be able to start Minecraft.\n" "Do you wish to proceed?" "\n\n" @@ -488,7 +488,7 @@ void JavaSettingsWidget::retranslate() m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with.")); m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes.")); m_javaBrowseBtn->setText(tr("Browse")); - m_autodownloadCheckBox->setText(tr("Autodownload Mojang Java")); + m_autodownloadCheckBox->setText(tr("Auto-download Mojang Java")); m_autodetectJavaCheckBox->setText(tr("Autodetect Java version")); m_autoJavaGroupBox->setTitle(tr("Autodetect Java")); } @@ -509,7 +509,7 @@ void JavaSettingsWidget::updateThresholds() } else if (observedMaxMemory > 2048 && m_result.is_64bit) { iconName = "status-bad"; m_labelMaxMemIcon->setToolTip( - tr("Your maximum memory allocation exceeds selected java posible memory(due to x86 applicatiion limitations).")); + tr("Your maximum memory allocation exceeds selected java possible memory(due to x86 application limitations).")); } else { iconName = "status-good"; m_labelMaxMemIcon->setToolTip(""); From 038d3e4596586718ca6982c68a17c36723561a42 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 16:49:10 +0200 Subject: [PATCH 49/83] Fixed asan complains Signed-off-by: Trial97 --- launcher/java/download/ArchiveDownloadTask.cpp | 5 ++++- launcher/java/download/ManifestDownloadTask.cpp | 5 ++++- launcher/ui/pages/global/JavaPage.cpp | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index e3db77d2cc..34f60260ed 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -49,7 +49,10 @@ void ArchiveDownloadTask::executeTask() download->addNetAction(action); auto fullPath = entry->getFullPath(); - connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); + connect(download.get(), &NetJob::finished, [download, this] { + disconnect(this, &Task::aborted, download.get(), &NetJob::abort); + download->deleteLater(); + }); connect(download.get(), &NetJob::failed, this, &ArchiveDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &Task::progress, this, &ArchiveDownloadTask::setProgress); diff --git a/launcher/java/download/ManifestDownloadTask.cpp b/launcher/java/download/ManifestDownloadTask.cpp index ba5ff2cc05..5551c75d56 100644 --- a/launcher/java/download/ManifestDownloadTask.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -51,7 +51,10 @@ void ManifestDownloadTask::executeTask() } download->addNetAction(action); - connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); }); + connect(download.get(), &NetJob::finished, [download, this] { + disconnect(this, &Task::aborted, download.get(), &NetJob::abort); + download->deleteLater(); + }); connect(download.get(), &NetJob::failed, this, &ManifestDownloadTask::emitFailed); connect(this, &Task::aborted, download.get(), &NetJob::abort); connect(download.get(), &Task::progress, this, &ManifestDownloadTask::setProgress); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 524165e62c..deb085f93f 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -135,7 +135,7 @@ void JavaPage::loadSettings() ui->skipJavaWizardCheckbox->setChecked(s->get("IgnoreJavaWizard").toBool()); ui->autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); ui->autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); - m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList()); + m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList(), this); ui->extraJavaPathsList->setModel(m_extra_paths); } @@ -199,6 +199,7 @@ void JavaPage::on_javaDownloadBtn_clicked() { auto jdialog = new Java::Downloader(this); jdialog->exec(); + ui->managedJavaList->loadList(); } void JavaPage::on_maxMemSpinBox_valueChanged([[maybe_unused]] int i) From 889f604a415fd01150868090a1d47b7c408104d5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 21:38:31 +0200 Subject: [PATCH 50/83] Removed JavaExtraSearchPaths Signed-off-by: Trial97 --- launcher/Application.cpp | 1 - launcher/java/JavaUtils.cpp | 37 ------------------- launcher/java/JavaUtils.h | 1 - launcher/ui/pages/global/JavaPage.cpp | 27 -------------- launcher/ui/pages/global/JavaPage.h | 3 -- launcher/ui/pages/global/JavaPage.ui | 43 ---------------------- launcher/ui/widgets/JavaSettingsWidget.cpp | 19 ---------- launcher/ui/widgets/JavaSettingsWidget.h | 2 - 8 files changed, 133 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 6b7333972f..31950a8135 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -632,7 +632,6 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("JvmArgs", ""); m_settings->registerSetting("IgnoreJavaCompatibility", false); m_settings->registerSetting("IgnoreJavaWizard", false); - m_settings->registerSetting("JavaExtraSearchPaths", QStringList()); m_settings->registerSetting("AutomaticJavaSwitch", false); m_settings->registerSetting("AutomaticJavaDownload", false); diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 1d254e4057..57e381e1dd 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -338,7 +338,6 @@ QList JavaUtils::FindJavaPaths() candidates.append(getMinecraftJavaBundle()); candidates.append(getPrismJavaBundle()); - candidates.append(getPrismExtraJavaPaths()); candidates = addJavasFromEnv(candidates); candidates.removeDuplicates(); return candidates; @@ -366,7 +365,6 @@ QList JavaUtils::FindJavaPaths() } javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); - javas.append(getPrismExtraJavaPaths()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -420,7 +418,6 @@ QList JavaUtils::FindJavaPaths() javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); - javas.append(getPrismExtraJavaPaths()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); return javas; @@ -435,7 +432,6 @@ QList JavaUtils::FindJavaPaths() javas.append(getMinecraftJavaBundle()); javas.append(getPrismJavaBundle()); - javas.append(getPrismExtraJavaPaths()); javas.removeDuplicates(); return addJavasFromEnv(javas); } @@ -521,36 +517,3 @@ QStringList getPrismJavaBundle() return javas; } - -QStringList getPrismExtraJavaPaths() -{ - QList javas; - - QString executable = "java"; -#if defined(Q_OS_WIN32) - executable += "w.exe"; -#endif - - auto scanDir = [&](QString prefix) { - javas.append(FS::PathCombine(prefix, "jre", "bin", executable)); - javas.append(FS::PathCombine(prefix, "bin", executable)); - javas.append(FS::PathCombine(prefix, executable)); - }; - auto scanJavaDir = [&](const QString& dirPath) { - QDir dir(dirPath); - if (!dir.exists()) - return; - auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for (auto& entry : entries) { - scanDir(entry.canonicalFilePath()); - } - }; - - auto extra_paths = APPLICATION->settings()->get("JavaExtraSearchPaths").toStringList(); - for (auto& entry : extra_paths) { - scanDir(entry); - scanJavaDir(entry); - } - - return javas; -} diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index 66e4398340..aa5315a194 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -27,7 +27,6 @@ QString stripVariableEntries(QString name, QString target, QString remove); QProcessEnvironment CleanEnviroment(); QStringList getMinecraftJavaBundle(); QStringList getPrismJavaBundle(); -QStringList getPrismExtraJavaPaths(); class JavaUtils : public QObject { Q_OBJECT diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index deb085f93f..cb2a8b90b5 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -110,7 +110,6 @@ void JavaPage::applySettings() s->set("IgnoreJavaWizard", ui->skipJavaWizardCheckbox->isChecked()); s->set("AutomaticJavaSwitch", ui->autodetectJavaCheckBox->isChecked()); s->set("AutomaticJavaDownload", ui->autodownloadCheckBox->isChecked()); - s->set("JavaExtraSearchPaths", m_extra_paths->stringList()); JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); } void JavaPage::loadSettings() @@ -135,8 +134,6 @@ void JavaPage::loadSettings() ui->skipJavaWizardCheckbox->setChecked(s->get("IgnoreJavaWizard").toBool()); ui->autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); ui->autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); - m_extra_paths = new QStringListModel(s->get("JavaExtraSearchPaths").toStringList(), this); - ui->extraJavaPathsList->setModel(m_extra_paths); } void JavaPage::on_javaDetectBtn_clicked() @@ -247,30 +244,6 @@ void JavaPage::updateThresholds() } } -void JavaPage::on_addExtraPathButton_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Add Extra Java Folder")); - - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { - QString cooked_dir = FS::NormalizePath(raw_dir); - auto currentList = m_extra_paths->stringList(); - if (!currentList.contains(cooked_dir)) { - currentList << cooked_dir; - m_extra_paths->setStringList(currentList); - } - } - APPLICATION->settings()->set("JavaExtraSearchPaths", m_extra_paths->stringList()); -} - -void JavaPage::on_removeExtraPathButton_clicked() -{ - auto indexes = ui->extraJavaPathsList->selectionModel()->selectedIndexes(); - if (indexes.size()) { - m_extra_paths->removeRow(indexes.first().row()); - } - APPLICATION->settings()->set("JavaExtraSearchPaths", m_extra_paths->stringList()); -} - void JavaPage::on_downloadJavaButton_clicked() { on_javaDownloadBtn_clicked(); diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 1a521e2db9..48e5577408 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -73,8 +73,6 @@ class JavaPage : public QWidget, public BasePage { void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); void on_javaDownloadBtn_clicked(); - void on_addExtraPathButton_clicked(); - void on_removeExtraPathButton_clicked(); void on_downloadJavaButton_clicked(); void on_removeJavaButton_clicked(); void on_refreshJavaButton_clicked(); @@ -84,5 +82,4 @@ class JavaPage : public QWidget, public BasePage { private: Ui::JavaPage* ui; unique_qobject_ptr checker; - QStringListModel* m_extra_paths; }; diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 3f763f8d29..dc1668ee3d 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -391,49 +391,6 @@ - - - - Java extra paths - - - - - - - - - - - Add - - - - - - - Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 91fd6ff03e..4b58192881 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -44,7 +44,6 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); - connect(m_addJavaPathBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_addJavaPathBtn_clicked); } void JavaSettingsWidget::setupUi() @@ -133,9 +132,6 @@ void JavaSettingsWidget::setupUi() m_javaDownloadBtn = new QPushButton(tr("Download Java"), this); m_horizontalBtnLayout->addWidget(m_javaDownloadBtn); - m_addJavaPathBtn = new QPushButton(tr("Add extra Java path"), this); - m_horizontalBtnLayout->addWidget(m_addJavaPathBtn); - m_verticalLayout->addLayout(m_horizontalBtnLayout); m_autoJavaGroupBox = new QGroupBox(this); @@ -523,21 +519,6 @@ void JavaSettingsWidget::updateThresholds() } } -void JavaSettingsWidget::on_addJavaPathBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Add Extra Java Folder")); - - auto currentList = APPLICATION->settings()->get("JavaExtraSearchPaths").toStringList(); - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { - QString cooked_dir = FS::NormalizePath(raw_dir); - if (!currentList.contains(cooked_dir)) { - currentList << cooked_dir; - } - } - APPLICATION->settings()->set("JavaExtraSearchPaths", currentList); - refresh(); -} - bool JavaSettingsWidget::autodownloadJava() const { return m_autodetectJavaCheckBox->isChecked(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 205b83d8c7..c8b6953df6 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -54,7 +54,6 @@ class JavaSettingsWidget : public QWidget { void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void on_javaDownloadBtn_clicked(); - void on_addJavaPathBtn_clicked(); void checkFinished(const JavaChecker::Result& result); protected: /* methods */ @@ -84,7 +83,6 @@ class JavaSettingsWidget : public QWidget { QHBoxLayout* m_horizontalBtnLayout = nullptr; QPushButton* m_javaDownloadBtn = nullptr; - QPushButton* m_addJavaPathBtn = nullptr; QIcon goodIcon; QIcon yellowIcon; QIcon badIcon; From 1c96ae58077cae7a8d5b8f851d5ede385811f6ea Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Feb 2024 22:32:54 +0200 Subject: [PATCH 51/83] Fixed java refresh button Signed-off-by: Trial97 --- launcher/ui/java/JavaDownloader.cpp | 3 ++- launcher/ui/java/JavaDownloader.ui | 10 +++++----- launcher/ui/java/VersionList.cpp | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp index 7417a4ea8c..24918dd763 100644 --- a/launcher/ui/java/JavaDownloader.cpp +++ b/launcher/ui/java/JavaDownloader.cpp @@ -55,7 +55,7 @@ Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownlo ui->javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); ui->javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); - ui->buttonBox->button(QDialogButtonBox::Retry)->setText(tr("Refresh")); + ui->buttonBox->button(QDialogButtonBox::Reset)->setText(tr("Refresh")); ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Download")); connect(ui->majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &Downloader::setSelectedVersion); @@ -98,6 +98,7 @@ void Downloader::accept() connect(task.get(), &Task::failed, this, deletePath); connect(task.get(), &Task::aborted, this, deletePath); ProgressDialog pg(this); + pg.setSkipButton(true, tr("Abort")); pg.execWithTask(task.get()); QDialog::accept(); } diff --git a/launcher/ui/java/JavaDownloader.ui b/launcher/ui/java/JavaDownloader.ui index 0eeabb26db..3f6a8adc6d 100644 --- a/launcher/ui/java/JavaDownloader.ui +++ b/launcher/ui/java/JavaDownloader.ui @@ -48,7 +48,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset @@ -71,8 +71,8 @@ accept() - 248 - 254 + 257 + 583 157 @@ -87,8 +87,8 @@ reject() - 316 - 260 + 325 + 583 286 diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index 7c5668d206..4bf04224a2 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -104,10 +104,12 @@ bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) void VersionList::sortVersions() { + if (!m_version || !m_version->data()) + return; QString versionStr = SysInfo::getSupportedJavaArchitecture(); beginResetModel(); auto runtimes = m_version->data()->runtimes; - if (!versionStr.isEmpty() && runtimes.contains(versionStr)) { + if (!versionStr.isEmpty() && !runtimes.isEmpty() && runtimes.contains(versionStr)) { m_vlist = runtimes.value(versionStr); std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); } else { From da96172b0b8835df8591368e96d20464a3a4eb41 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Feb 2024 22:00:40 +0200 Subject: [PATCH 52/83] Apply suggestions from code review Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/java/VersionList.cpp | 2 +- launcher/ui/pages/global/JavaPage.cpp | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index 4bf04224a2..dc454f2645 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -114,7 +114,7 @@ void VersionList::sortVersions() std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); } else { m_vlist = {}; - qWarning() << "Your operating system is not yet supported: " << SysInfo::currentSystem() << " " << SysInfo::useQTForArch(); + qWarning() << "No Java versions found for your operating system." << SysInfo::currentSystem() << " " << SysInfo::useQTForArch(); } endResetModel(); } diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index cb2a8b90b5..95d5f581e1 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -154,7 +154,7 @@ void JavaPage::on_javaDetectBtn_clicked() ui->javaPathTextBox->setText(java->path); if (!java->is_64bit && APPLICATION->settings()->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), - tr("You selected an x86 java version.\n" + tr("You selected a 32 bit java version.\n" "This means that will not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 8a63aab22e..50cffc9a7f 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -416,7 +416,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() if (!java->is_64bit && m_settings->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), - tr("You selected an x86 java version.\n" + tr("You selected a 32 bit java version.\n" "This means that will not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 4b58192881..f8031687b2 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -173,8 +173,8 @@ void JavaSettingsWidget::initialize() updateThresholds(); auto button = CustomMessageBox::selectable(this, tr("Auto Java Download"), - tr("%1 has now the ability to auto downloand the correct java for each minecraft version.\n" - "Do you want to enable java auto-download?\n") + tr("%1 can automatically download the correct Java version for each version of Minecraft..\n" + "Do you want to enable Java auto-download?\n") .arg(BuildConfig.LAUNCHER_DISPLAYNAME), QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) ->exec(); @@ -505,7 +505,7 @@ void JavaSettingsWidget::updateThresholds() } else if (observedMaxMemory > 2048 && m_result.is_64bit) { iconName = "status-bad"; m_labelMaxMemIcon->setToolTip( - tr("Your maximum memory allocation exceeds selected java possible memory(due to x86 application limitations).")); + tr("Because you're using 32 bit Java, you're exceeding the maximum possible allocation.")); } else { iconName = "status-good"; m_labelMaxMemIcon->setToolTip(""); From 24fd07861b797fb845217c04b9ad5267edcc4470 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 26 Feb 2024 22:25:14 +0200 Subject: [PATCH 53/83] format code Signed-off-by: Trial97 --- launcher/ui/widgets/JavaSettingsWidget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index f8031687b2..29357bdab2 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -504,8 +504,7 @@ void JavaSettingsWidget::updateThresholds() m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value")); } else if (observedMaxMemory > 2048 && m_result.is_64bit) { iconName = "status-bad"; - m_labelMaxMemIcon->setToolTip( - tr("Because you're using 32 bit Java, you're exceeding the maximum possible allocation.")); + m_labelMaxMemIcon->setToolTip(tr("Because you're using 32 bit Java, you're exceeding the maximum possible allocation.")); } else { iconName = "status-good"; m_labelMaxMemIcon->setToolTip(""); From 9120848278f8709525b574e92a4e602c593e1f4c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 6 Mar 2024 19:33:14 +0200 Subject: [PATCH 54/83] Made java downloader as a build option Signed-off-by: Trial97 --- CMakeLists.txt | 3 +++ buildconfig/BuildConfig.cpp.in | 4 +++ buildconfig/BuildConfig.h | 1 + launcher/CMakeLists.txt | 4 +++ launcher/ui/pages/global/JavaPage.cpp | 25 +++++++++++------- .../pages/instance/InstanceSettingsPage.cpp | 2 ++ launcher/ui/widgets/JavaSettingsWidget.cpp | 26 +++++++++++-------- 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cceb2599c..9b71044787 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,6 +219,9 @@ set(Launcher_SUBREDDIT_URL "https://prismlauncher.org/reddit" CACHE STRING "URL set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, if they are available as submodules") set(Launcher_QT_VERSION_MAJOR "6" CACHE STRING "Major Qt version to build against") +# Java downloader +option(ENABLE_JAVA_DOWNLOADER "Build the java downloader feature" ON) + # Native libraries if(UNIX AND APPLE) set(Launcher_GLFW_LIBRARY_NAME "libglfw.dylib" CACHE STRING "Name of native glfw library") diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index b40cacb0f3..cdf3cbffc2 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -81,6 +81,10 @@ Config::Config() UPDATER_ENABLED = true; } +#if ENABLE_JAVA_DOWNLOADER + JAVA_DOWNLOADER_ENABLED = true; +#endif + GIT_COMMIT = "@Launcher_GIT_COMMIT@"; GIT_TAG = "@Launcher_GIT_TAG@"; GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 77b6eef549..e3beb8dbe6 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -67,6 +67,7 @@ class Config { QString VERSION_CHANNEL; bool UPDATER_ENABLED = false; + bool JAVA_DOWNLOADER_ENABLED = false; /// A short string identifying this build's platform or distribution. QString BUILD_PLATFORM; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index fcc3c2f3a5..f620388dca 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1320,6 +1320,10 @@ if(DEFINED Launcher_APP_BINARY_DEFS) target_compile_definitions(Launcher_logic PRIVATE ${Launcher_APP_BINARY_DEFS}) endif() +if(ENABLE_JAVA_DOWNLOADER) + target_compile_definitions(Launcher_logic PUBLIC ENABLE_JAVA_DOWNLOADER) +endif() + install(TARGETS ${Launcher_Name} BUNDLE DESTINATION "." COMPONENT Runtime LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 95d5f581e1..0276daed59 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -35,6 +35,7 @@ */ #include "JavaPage.h" +#include "BuildConfig.h" #include "JavaCommon.h" #include "java/JavaInstall.h" #include "ui/dialogs/CustomMessageBox.h" @@ -62,15 +63,21 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) { ui->setupUi(this); - ui->managedJavaList->initialize(new JavaInstallList(this, true)); - ui->managedJavaList->selectCurrent(); - ui->managedJavaList->setEmptyString(tr("No java versions are currently available in the meta")); - ui->managedJavaList->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); - connect(ui->autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { - ui->autodownloadCheckBox->setEnabled(ui->autodetectJavaCheckBox->isChecked()); - if (!ui->autodetectJavaCheckBox->isChecked()) - ui->autodownloadCheckBox->setChecked(false); - }); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + ui->managedJavaList->initialize(new JavaInstallList(this, true)); + ui->managedJavaList->selectCurrent(); + ui->managedJavaList->setEmptyString(tr("No java versions are currently available in the meta")); + ui->managedJavaList->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + connect(ui->autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { + ui->autodownloadCheckBox->setEnabled(ui->autodetectJavaCheckBox->isChecked()); + if (!ui->autodetectJavaCheckBox->isChecked()) + ui->autodownloadCheckBox->setChecked(false); + }); + } else { + ui->autodownloadCheckBox->setHidden(true); + ui->javaDownloadBtn->setHidden(true); + ui->tabWidget->tabBar()->hide(); + } loadSettings(); updateThresholds(); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 50cffc9a7f..f2a723b81d 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -64,6 +64,8 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance* inst, QWidget* parent) m_settings = inst->settings(); ui->setupUi(this); + ui->javaDownloadBtn->setHidden(!BuildConfig.JAVA_DOWNLOADER_ENABLED); + connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 29357bdab2..866d4c1824 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -129,8 +129,10 @@ void JavaSettingsWidget::setupUi() m_horizontalBtnLayout = new QHBoxLayout(); m_horizontalBtnLayout->setObjectName(QStringLiteral("horizontalBtnLayout")); - m_javaDownloadBtn = new QPushButton(tr("Download Java"), this); - m_horizontalBtnLayout->addWidget(m_javaDownloadBtn); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + m_javaDownloadBtn = new QPushButton(tr("Download Java"), this); + m_horizontalBtnLayout->addWidget(m_javaDownloadBtn); + } m_verticalLayout->addLayout(m_horizontalBtnLayout); @@ -143,15 +145,17 @@ void JavaSettingsWidget::setupUi() m_autodetectJavaCheckBox->setObjectName("autodetectJavaCheckBox"); m_veriticalJavaLayout->addWidget(m_autodetectJavaCheckBox); - m_autodownloadCheckBox = new QCheckBox(m_autoJavaGroupBox); - m_autodownloadCheckBox->setObjectName("autodownloadCheckBox"); - m_autodownloadCheckBox->setEnabled(false); - m_veriticalJavaLayout->addWidget(m_autodownloadCheckBox); - connect(m_autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { - m_autodownloadCheckBox->setEnabled(m_autodetectJavaCheckBox->isChecked()); - if (!m_autodetectJavaCheckBox->isChecked()) - m_autodownloadCheckBox->setChecked(false); - }); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + m_autodownloadCheckBox = new QCheckBox(m_autoJavaGroupBox); + m_autodownloadCheckBox->setObjectName("autodownloadCheckBox"); + m_autodownloadCheckBox->setEnabled(false); + m_veriticalJavaLayout->addWidget(m_autodownloadCheckBox); + connect(m_autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { + m_autodownloadCheckBox->setEnabled(m_autodetectJavaCheckBox->isChecked()); + if (!m_autodetectJavaCheckBox->isChecked()) + m_autodownloadCheckBox->setChecked(false); + }); + } m_verticalLayout->addWidget(m_autoJavaGroupBox); retranslate(); From ef4e5eb3cf726e3b59f202d6eceee6f53450743e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 18 Mar 2024 19:15:36 +0200 Subject: [PATCH 55/83] fixed java build option Signed-off-by: Trial97 --- buildconfig/BuildConfig.cpp.in | 5 ++--- launcher/CMakeLists.txt | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index cdf3cbffc2..a2b5c21871 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -81,9 +81,8 @@ Config::Config() UPDATER_ENABLED = true; } -#if ENABLE_JAVA_DOWNLOADER - JAVA_DOWNLOADER_ENABLED = true; -#endif + #cmakedefine01 ENABLE_JAVA_DOWNLOADER + JAVA_DOWNLOADER_ENABLED = ENABLE_JAVA_DOWNLOADER; GIT_COMMIT = "@Launcher_GIT_COMMIT@"; GIT_TAG = "@Launcher_GIT_TAG@"; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index f620388dca..fcc3c2f3a5 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1320,10 +1320,6 @@ if(DEFINED Launcher_APP_BINARY_DEFS) target_compile_definitions(Launcher_logic PRIVATE ${Launcher_APP_BINARY_DEFS}) endif() -if(ENABLE_JAVA_DOWNLOADER) - target_compile_definitions(Launcher_logic PUBLIC ENABLE_JAVA_DOWNLOADER) -endif() - install(TARGETS ${Launcher_Name} BUNDLE DESTINATION "." COMPONENT Runtime LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime From 09c2c6793b52639f86f2edead268b51ad4b5fffc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 20 Mar 2024 00:15:02 +0200 Subject: [PATCH 56/83] Improve UI Signed-off-by: Trial97 --- launcher/BaseVersionList.cpp | 1 - launcher/BaseVersionList.h | 1 - launcher/CMakeLists.txt | 5 +- launcher/VersionProxyModel.cpp | 9 - launcher/VersionProxyModel.h | 2 +- launcher/java/JavaMetadata.cpp | 2 +- launcher/java/JavaMetadata.h | 2 +- launcher/minecraft/OneSixVersionFormat.cpp | 9 +- launcher/minecraft/VersionFile.h | 2 +- launcher/minecraft/launch/AutoInstallJava.cpp | 60 +++-- launcher/ui/java/InstallJavaDialog.cpp | 234 ++++++++++++++++++ .../{JavaDownloader.h => InstallJavaDialog.h} | 28 +-- launcher/ui/java/JavaDownloader.cpp | 110 -------- launcher/ui/java/JavaDownloader.ui | 100 -------- launcher/ui/java/VersionList.cpp | 14 +- launcher/ui/pages/global/JavaPage.cpp | 4 +- .../pages/instance/InstanceSettingsPage.cpp | 4 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 4 +- 18 files changed, 295 insertions(+), 296 deletions(-) create mode 100644 launcher/ui/java/InstallJavaDialog.cpp rename launcher/ui/java/{JavaDownloader.h => InstallJavaDialog.h} (63%) delete mode 100644 launcher/ui/java/JavaDownloader.cpp delete mode 100644 launcher/ui/java/JavaDownloader.ui diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index 1456a17bd9..afee8388a1 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -112,6 +112,5 @@ QHash BaseVersionList::roleNames() const roles.insert(PathRole, "path"); roles.insert(JavaNameRole, "javaName"); roles.insert(CPUArchitectureRole, "architecture"); - roles.insert(JavaVendorRole, "javaVendor"); return roles; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index 7517c71b47..bc37e9e53e 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -50,7 +50,6 @@ class BaseVersionList : public QAbstractListModel { PathRole, JavaNameRole, CPUArchitectureRole, - JavaVendorRole, SortRole }; using RoleList = QList; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index fcc3c2f3a5..dd493682eb 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -440,8 +440,8 @@ set(JAVA_SOURCES java/download/ManifestDownloadTask.cpp java/download/ManifestDownloadTask.h - ui/java/JavaDownloader.h - ui/java/JavaDownloader.cpp + ui/java/InstallJavaDialog.h + ui/java/InstallJavaDialog.cpp ui/java/VersionList.h ui/java/VersionList.cpp ) @@ -1194,7 +1194,6 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ScrollMessageBox.ui ui/dialogs/BlockedModsDialog.ui ui/dialogs/ChooseProviderDialog.ui - ui/java/JavaDownloader.ui ) qt_wrap_ui(PRISM_UPDATE_UI diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index ed4c0767d6..070e952a4a 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -116,8 +116,6 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Type"); case CPUArchitecture: return tr("Architecture"); - case JavaVendor: - return tr("Vendor"); case Path: return tr("Path"); case JavaName: @@ -137,8 +135,6 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("The version's type"); case CPUArchitecture: return tr("CPU Architecture"); - case JavaVendor: - return tr("Java vendor"); case Path: return tr("Filesystem path to this version"); case JavaName: @@ -175,8 +171,6 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::TypeRole); case CPUArchitecture: return sourceModel()->data(parentIndex, BaseVersionList::CPUArchitectureRole); - case JavaVendor: - return sourceModel()->data(parentIndex, BaseVersionList::JavaVendorRole); case Path: return sourceModel()->data(parentIndex, BaseVersionList::PathRole); case JavaName: @@ -323,9 +317,6 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) if (roles.contains(BaseVersionList::CPUArchitectureRole)) { m_columns.push_back(CPUArchitecture); } - if (roles.contains(BaseVersionList::JavaVendorRole)) { - m_columns.push_back(JavaVendor); - } if (roles.contains(BaseVersionList::PathRole)) { m_columns.push_back(Path); } diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 5a1017bee3..cb55b7f14a 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -9,7 +9,7 @@ class VersionFilterModel; class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT public: - enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaVendor }; + enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName }; using FilterMap = QHash>; public: diff --git a/launcher/java/JavaMetadata.cpp b/launcher/java/JavaMetadata.cpp index b73c54fe6c..e721947a75 100644 --- a/launcher/java/JavaMetadata.cpp +++ b/launcher/java/JavaMetadata.cpp @@ -52,9 +52,9 @@ MetadataPtr parseJavaMeta(const QJsonObject& in) meta->vendor = Json::ensureString(in, "vendor", ""); meta->url = Json::ensureString(in, "url", ""); meta->releaseTime = timeFromS3Time(Json::ensureString(in, "releaseTime", "")); - meta->recommended = Json::ensureBoolean(in, "recommended", false); meta->downloadType = parseDownloadType(Json::ensureString(in, "downloadType", "")); meta->packageType = Json::ensureString(in, "packageType", ""); + meta->runtimeOS = Json::ensureString(in, "runtimeOS", "unknown"); if (in.contains("checksum")) { auto obj = Json::requireObject(in, "checksum"); diff --git a/launcher/java/JavaMetadata.h b/launcher/java/JavaMetadata.h index 640a412f11..5281f2e27c 100644 --- a/launcher/java/JavaMetadata.h +++ b/launcher/java/JavaMetadata.h @@ -50,10 +50,10 @@ class Metadata : public BaseVersion { QDateTime releaseTime; QString checksumType; QString checksumHash; - bool recommended; DownloadType downloadType; QString packageType; JavaVersion version; + QString runtimeOS; }; using MetadataPtr = std::shared_ptr; diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 56e9c8ca25..bd587beb27 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -258,14 +258,9 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument& doc } if (root.contains("runtimes")) { - auto runtimes = requireObject(root, "runtimes"); out->runtimes = {}; - for (auto key : runtimes.keys()) { - QList list; - for (auto runtime : ensureArray(runtimes, key)) { - list.append(Java::parseJavaMeta(ensureObject(runtime))); - } - out->runtimes[key] = list; + for (auto runtime : ensureArray(root, "runtimes")) { + out->runtimes.append(Java::parseJavaMeta(ensureObject(runtime))); } } diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index a9c1473d20..85ac554267 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -155,7 +155,7 @@ class VersionFile : public ProblemContainer { /// is volatile -- may be removed as soon as it is no longer needed by something else bool m_volatile = false; - QHash> runtimes; + QList runtimes; public: // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more. diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index ab68910a77..3ae6ffa88a 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -145,39 +145,35 @@ void AutoInstallJava::setJavaPathFromPartial() void AutoInstallJava::downloadJava(Meta::Version::Ptr version, QString javaName) { auto runtimes = version->data()->runtimes; - if (runtimes.contains(m_supported_arch)) { - for (auto java : runtimes.value(m_supported_arch)) { - if (java->name() == javaName) { - QDir javaDir(APPLICATION->javaPath()); - auto final_path = javaDir.absoluteFilePath(java->m_name); - switch (java->downloadType) { - case Java::DownloadType::Manifest: - m_current_task = - makeShared(java->url, final_path, java->checksumType, java->checksumHash); - break; - case Java::DownloadType::Archive: - m_current_task = - makeShared(java->url, final_path, java->checksumType, java->checksumHash); - break; - } - auto deletePath = [final_path] { FS::deletePath(final_path); }; - connect(m_current_task.get(), &Task::failed, this, [this, deletePath](QString reason) { - deletePath(); - emitFailed(reason); - }); - connect(this, &Task::aborted, this, [this, deletePath] { - m_current_task->abort(); - deletePath(); - }); - connect(m_current_task.get(), &Task::succeeded, this, &AutoInstallJava::setJavaPathFromPartial); - connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); - connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); - connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); - connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); - connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); - m_current_task->start(); - return; + for (auto java : runtimes) { + if (java->runtimeOS == m_supported_arch && java->name() == javaName) { + QDir javaDir(APPLICATION->javaPath()); + auto final_path = javaDir.absoluteFilePath(java->m_name); + switch (java->downloadType) { + case Java::DownloadType::Manifest: + m_current_task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + break; + case Java::DownloadType::Archive: + m_current_task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); + break; } + auto deletePath = [final_path] { FS::deletePath(final_path); }; + connect(m_current_task.get(), &Task::failed, this, [this, deletePath](QString reason) { + deletePath(); + emitFailed(reason); + }); + connect(this, &Task::aborted, this, [this, deletePath] { + m_current_task->abort(); + deletePath(); + }); + connect(m_current_task.get(), &Task::succeeded, this, &AutoInstallJava::setJavaPathFromPartial); + connect(m_current_task.get(), &Task::failed, this, &AutoInstallJava::tryNextMajorJava); + connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); + connect(m_current_task.get(), &Task::stepProgress, this, &AutoInstallJava::propagateStepProgress); + connect(m_current_task.get(), &Task::status, this, &AutoInstallJava::setStatus); + connect(m_current_task.get(), &Task::details, this, &AutoInstallJava::setDetails); + m_current_task->start(); + return; } } tryNextMajorJava(); diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp new file mode 100644 index 0000000000..054e5cece0 --- /dev/null +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Trial97 + * + * 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 "InstallJavaDialog.h" + +#include +#include +#include +#include + +#include "Application.h" +#include "FileSystem.h" +#include "java/download/ArchiveDownloadTask.h" +#include "java/download/ManifestDownloadTask.h" +#include "meta/Index.h" +#include "meta/VersionList.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/java/VersionList.h" +#include "ui/widgets/PageContainer.h" +#include "ui/widgets/VersionSelectWidget.h" + +class InstallLoaderPage : public QWidget, public BasePage { + public: + Q_OBJECT + public: + explicit InstallLoaderPage(const QString& id, const QString& iconName, const QString& name, QWidget* parent = nullptr) + : QWidget(parent), uid(id), iconName(iconName), name(name) + { + setObjectName(QStringLiteral("VersionSelectWidget")); + horizontalLayout = new QHBoxLayout(this); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + + majorVersionSelect = new VersionSelectWidget(this); + majorVersionSelect->selectCurrent(); + majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta.")); + majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + horizontalLayout->addWidget(majorVersionSelect, 1); + + javaVersionSelect = new VersionSelectWidget(this); + javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); + javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + horizontalLayout->addWidget(javaVersionSelect, 4); + connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::setSelectedVersion); + connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::selectedVersionChanged); + + QMetaObject::connectSlotsByName(this); + } + ~InstallLoaderPage() + { + delete horizontalLayout; + delete majorVersionSelect; + delete javaVersionSelect; + } + + //! loads the list if needed. + void initialize(Meta::VersionList::Ptr vlist) + { + vlist->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); + majorVersionSelect->initialize(vlist.get()); + } + + void setSelectedVersion(BaseVersion::Ptr version) + { + auto dcast = std::dynamic_pointer_cast(version); + if (!dcast) { + return; + } + javaVersionSelect->initialize(new Java::VersionList(dcast, this)); + javaVersionSelect->selectCurrent(); + } + + QString id() const override { return uid; } + QString displayName() const override { return name; } + QIcon icon() const override { return APPLICATION->getThemedIcon(iconName); } + + void openedImpl() override + { + if (loaded) + return; + + const auto versions = APPLICATION->metadataIndex()->get(uid); + if (!versions) + return; + + initialize(versions); + loaded = true; + } + + void setParentContainer(BasePageContainer* container) override + { + auto dialog = dynamic_cast(dynamic_cast(container)->parent()); + connect(javaVersionSelect->view(), &QAbstractItemView::doubleClicked, dialog, &QDialog::accept); + } + + BaseVersion::Ptr selectedVersion() const { return javaVersionSelect->selectedVersion(); } + void selectSearch() { javaVersionSelect->selectSearch(); } + void loadList() + { + majorVersionSelect->loadList(); + javaVersionSelect->loadList(); + } + signals: + void selectedVersionChanged(BaseVersion::Ptr version); + + private: + const QString uid; + const QString iconName; + const QString name; + bool loaded = false; + + QHBoxLayout* horizontalLayout = nullptr; + VersionSelectWidget* majorVersionSelect = nullptr; + VersionSelectWidget* javaVersionSelect = nullptr; +}; + +static InstallLoaderPage* pageCast(BasePage* page) +{ + auto result = dynamic_cast(page); + Q_ASSERT(result != nullptr); + return result; +} +namespace Java { + +InstallDialog::InstallDialog(const QString& uid, QWidget* parent) + : QDialog(parent), container(new PageContainer(this, QString(), this)), buttons(new QDialogButtonBox(this)) +{ + auto layout = new QVBoxLayout(this); + + container->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + layout->addWidget(container); + + auto buttonLayout = new QHBoxLayout(this); + + auto refreshButton = new QPushButton(tr("&Refresh"), this); + connect(refreshButton, &QPushButton::clicked, this, [this] { pageCast(container->selectedPage())->loadList(); }); + buttonLayout->addWidget(refreshButton); + + buttons->setOrientation(Qt::Horizontal); + buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); + buttons->button(QDialogButtonBox::Ok)->setText(tr("Download")); + connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); + buttonLayout->addWidget(buttons); + + layout->addLayout(buttonLayout); + + setWindowTitle(dialogTitle()); + setWindowModality(Qt::WindowModal); + resize(840, 480); + + for (BasePage* page : container->getPages()) { + if (page->id() == uid) + container->selectPage(page->id()); + + connect(pageCast(page), &InstallLoaderPage::selectedVersionChanged, this, [this, page] { + if (page->id() == container->selectedPage()->id()) + validate(container->selectedPage()); + }); + } + connect(container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* current) { validate(current); }); + pageCast(container->selectedPage())->selectSearch(); + validate(container->selectedPage()); +} + +QList InstallDialog::getPages() +{ + return { + // NeoForge + new InstallLoaderPage("net.minecraft.java", "", tr("Mojang")), + // Forge + new InstallLoaderPage("net.adoptium.java", "", tr("Adoptium")), + // Fabric + new InstallLoaderPage("com.azul.java", "", tr("Azul")), + }; +} + +QString InstallDialog::dialogTitle() +{ + return tr("Install Loader"); +} + +void InstallDialog::validate(BasePage* page) +{ + buttons->button(QDialogButtonBox::Ok)->setEnabled(pageCast(page)->selectedVersion() != nullptr); +} + +void InstallDialog::done(int result) +{ + if (result == Accepted) { + auto* page = pageCast(container->selectedPage()); + if (page->selectedVersion()) { + auto meta = std::dynamic_pointer_cast(page->selectedVersion()); + if (meta) { + Task::Ptr task; + auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name); + switch (meta->downloadType) { + case Java::DownloadType::Manifest: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + case Java::DownloadType::Archive: + task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); + break; + } + auto deletePath = [final_path] { FS::deletePath(final_path); }; + connect(task.get(), &Task::failed, this, deletePath); + connect(task.get(), &Task::aborted, this, deletePath); + ProgressDialog pg(this); + pg.setSkipButton(true, tr("Abort")); + pg.execWithTask(task.get()); + } + } + } + + QDialog::done(result); +} +} // namespace Java + +#include "InstallJavaDialog.moc" \ No newline at end of file diff --git a/launcher/ui/java/JavaDownloader.h b/launcher/ui/java/InstallJavaDialog.h similarity index 63% rename from launcher/ui/java/JavaDownloader.h rename to launcher/ui/java/InstallJavaDialog.h index b8bdde41a4..e228adf21e 100644 --- a/launcher/ui/java/JavaDownloader.h +++ b/launcher/ui/java/InstallJavaDialog.h @@ -19,30 +19,28 @@ #pragma once #include -#include "BaseVersion.h" +#include "ui/pages/BasePageProvider.h" -namespace Ui { -class JavaDownloader; -} +class MinecraftInstance; +class PageContainer; +class PackProfile; +class QDialogButtonBox; namespace Java { - -class Downloader : public QDialog { +class InstallDialog final : public QDialog, protected BasePageProvider { Q_OBJECT public: - explicit Downloader(QWidget* parent = 0); - ~Downloader(); - - void accept(); + explicit InstallDialog(const QString& uid = QString(), QWidget* parent = nullptr); - public slots: - void refresh(); + QList getPages() override; + QString dialogTitle() override; - protected slots: - void setSelectedVersion(BaseVersion::Ptr version); + void validate(BasePage* page); + void done(int result) override; private: - Ui::JavaDownloader* ui; + PageContainer* container; + QDialogButtonBox* buttons; }; } // namespace Java diff --git a/launcher/ui/java/JavaDownloader.cpp b/launcher/ui/java/JavaDownloader.cpp deleted file mode 100644 index 24918dd763..0000000000 --- a/launcher/ui/java/JavaDownloader.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2024 Trial97 - * - * 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 "JavaDownloader.h" - -#include - -#include - -#include "Application.h" -#include "BaseVersionList.h" -#include "FileSystem.h" -#include "QObjectPtr.h" -#include "SysInfo.h" - -#include "java/JavaMetadata.h" -#include "java/download/ArchiveDownloadTask.h" -#include "java/download/ManifestDownloadTask.h" - -#include "meta/Index.h" -#include "meta/Version.h" - -#include "meta/VersionList.h" -#include "ui/dialogs/ProgressDialog.h" -#include "ui/java/VersionList.h" -#include "ui_JavaDownloader.h" - -namespace Java { - -Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownloader) -{ - ui->setupUi(this); - auto versionList = APPLICATION->metadataIndex()->get("net.minecraft.java"); - versionList->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); - ui->majorVersionSelect->initialize(versionList.get()); - ui->majorVersionSelect->selectCurrent(); - ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta.")); - ui->majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); - - ui->javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); - ui->javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); - - ui->buttonBox->button(QDialogButtonBox::Reset)->setText(tr("Refresh")); - ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Download")); - - connect(ui->majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &Downloader::setSelectedVersion); - auto reset = ui->buttonBox->button(QDialogButtonBox::Reset); - connect(reset, &QPushButton::clicked, this, &Downloader::refresh); -} - -Downloader::~Downloader() -{ - delete ui; -} - -void Downloader::setSelectedVersion(BaseVersion::Ptr version) -{ - auto dcast = std::dynamic_pointer_cast(version); - if (!dcast) { - return; - } - ui->javaVersionSelect->initialize(new Java::VersionList(dcast, this)); - ui->javaVersionSelect->selectCurrent(); -} - -void Downloader::accept() -{ - auto meta = std::dynamic_pointer_cast(ui->javaVersionSelect->selectedVersion()); - if (!meta) { - return; - } - Task::Ptr task; - auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name); - switch (meta->downloadType) { - case Java::DownloadType::Manifest: - task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); - break; - case Java::DownloadType::Archive: - task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); - break; - } - auto deletePath = [final_path] { FS::deletePath(final_path); }; - connect(task.get(), &Task::failed, this, deletePath); - connect(task.get(), &Task::aborted, this, deletePath); - ProgressDialog pg(this); - pg.setSkipButton(true, tr("Abort")); - pg.execWithTask(task.get()); - QDialog::accept(); -} - -void Downloader::refresh() -{ - ui->majorVersionSelect->loadList(); -} -} // namespace Java diff --git a/launcher/ui/java/JavaDownloader.ui b/launcher/ui/java/JavaDownloader.ui deleted file mode 100644 index 3f6a8adc6d..0000000000 --- a/launcher/ui/java/JavaDownloader.ui +++ /dev/null @@ -1,100 +0,0 @@ - - - JavaDownloader - - - - 0 - 0 - 821 - 593 - - - - Dialog - - - - - - - - Major - - - - - - - - - - - - Runtime - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset - - - - - - - - VersionSelectWidget - QWidget -
ui/widgets/VersionSelectWidget.h
- 1 -
-
- - - - buttonBox - accepted() - JavaDownloader - accept() - - - 257 - 583 - - - 157 - 274 - - - - - buttonBox - rejected() - JavaDownloader - reject() - - - 325 - 583 - - - 286 - 274 - - - - -
diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index dc454f2645..78448ddafe 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -75,11 +75,9 @@ QVariant VersionList::data(const QModelIndex& index, int role) const case VersionRole: return version->version.toString(); case RecommendedRole: - return version->recommended; + return false; // do not recommend any version case JavaNameRole: return version->name(); - case JavaVendorRole: - return version->vendor; case TypeRole: return version->packageType; case Meta::VersionList::TimeRole: @@ -91,8 +89,7 @@ QVariant VersionList::data(const QModelIndex& index, int role) const BaseVersionList::RoleList VersionList::providesRoles() const { - return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, - JavaNameRole, JavaVendorRole, TypeRole, Meta::VersionList::TimeRole }; + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, JavaNameRole, TypeRole, Meta::VersionList::TimeRole }; } bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) @@ -109,11 +106,12 @@ void VersionList::sortVersions() QString versionStr = SysInfo::getSupportedJavaArchitecture(); beginResetModel(); auto runtimes = m_version->data()->runtimes; - if (!versionStr.isEmpty() && !runtimes.isEmpty() && runtimes.contains(versionStr)) { - m_vlist = runtimes.value(versionStr); + m_vlist = {}; + if (!versionStr.isEmpty() && !runtimes.isEmpty()) { + std::copy_if(runtimes.begin(), runtimes.end(), std::back_inserter(m_vlist), + [versionStr](Java::MetadataPtr val) { return val->runtimeOS == versionStr; }); std::sort(m_vlist.begin(), m_vlist.end(), sortJavas); } else { - m_vlist = {}; qWarning() << "No Java versions found for your operating system." << SysInfo::currentSystem() << " " << SysInfo::useQTForArch(); } endResetModel(); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 0276daed59..41a666cf26 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -39,7 +39,7 @@ #include "JavaCommon.h" #include "java/JavaInstall.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/java/JavaDownloader.h" +#include "ui/java/InstallJavaDialog.h" #include "ui_JavaPage.h" #include @@ -201,7 +201,7 @@ void JavaPage::on_javaTestBtn_clicked() void JavaPage::on_javaDownloadBtn_clicked() { - auto jdialog = new Java::Downloader(this); + auto jdialog = new Java::InstallDialog({}, this); jdialog->exec(); ui->managedJavaList->loadList(); } diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 0b731e64ff..c248a47f72 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -37,7 +37,7 @@ #include "InstanceSettingsPage.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/java/JavaDownloader.h" +#include "ui/java/InstallJavaDialog.h" #include "ui_InstanceSettingsPage.h" #include @@ -394,7 +394,7 @@ void InstanceSettingsPage::loadSettings() void InstanceSettingsPage::on_javaDownloadBtn_clicked() { - auto jdialog = new Java::Downloader(this); + auto jdialog = new Java::InstallDialog({}, this); jdialog->exec(); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 866d4c1824..e2e4980678 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -21,7 +21,7 @@ #include "java/JavaUtils.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/java/JavaDownloader.h" +#include "ui/java/InstallJavaDialog.h" #include "ui/widgets/VersionSelectWidget.h" #include "Application.h" @@ -351,7 +351,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() void JavaSettingsWidget::on_javaDownloadBtn_clicked() { - auto jdialog = new Java::Downloader(this); + auto jdialog = new Java::InstallDialog({}, this); jdialog->exec(); } From 5f8269f5e1ac41b29ed386e1a675e972c8d5624e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 20 Mar 2024 00:29:46 +0200 Subject: [PATCH 57/83] Small class rename Signed-off-by: Trial97 --- launcher/ui/java/InstallJavaDialog.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 054e5cece0..40616aafee 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -34,11 +34,11 @@ #include "ui/widgets/PageContainer.h" #include "ui/widgets/VersionSelectWidget.h" -class InstallLoaderPage : public QWidget, public BasePage { +class InstallJavaPage : public QWidget, public BasePage { public: Q_OBJECT public: - explicit InstallLoaderPage(const QString& id, const QString& iconName, const QString& name, QWidget* parent = nullptr) + explicit InstallJavaPage(const QString& id, const QString& iconName, const QString& name, QWidget* parent = nullptr) : QWidget(parent), uid(id), iconName(iconName), name(name) { setObjectName(QStringLiteral("VersionSelectWidget")); @@ -56,12 +56,12 @@ class InstallLoaderPage : public QWidget, public BasePage { javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS.")); javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); horizontalLayout->addWidget(javaVersionSelect, 4); - connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::setSelectedVersion); - connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::selectedVersionChanged); + connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::setSelectedVersion); + connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::selectedVersionChanged); QMetaObject::connectSlotsByName(this); } - ~InstallLoaderPage() + ~InstallJavaPage() { delete horizontalLayout; delete majorVersionSelect; @@ -129,9 +129,9 @@ class InstallLoaderPage : public QWidget, public BasePage { VersionSelectWidget* javaVersionSelect = nullptr; }; -static InstallLoaderPage* pageCast(BasePage* page) +static InstallJavaPage* pageCast(BasePage* page) { - auto result = dynamic_cast(page); + auto result = dynamic_cast(page); Q_ASSERT(result != nullptr); return result; } @@ -168,7 +168,7 @@ InstallDialog::InstallDialog(const QString& uid, QWidget* parent) if (page->id() == uid) container->selectPage(page->id()); - connect(pageCast(page), &InstallLoaderPage::selectedVersionChanged, this, [this, page] { + connect(pageCast(page), &InstallJavaPage::selectedVersionChanged, this, [this, page] { if (page->id() == container->selectedPage()->id()) validate(container->selectedPage()); }); @@ -182,11 +182,11 @@ QList InstallDialog::getPages() { return { // NeoForge - new InstallLoaderPage("net.minecraft.java", "", tr("Mojang")), + new InstallJavaPage("net.minecraft.java", "", tr("Mojang")), // Forge - new InstallLoaderPage("net.adoptium.java", "", tr("Adoptium")), + new InstallJavaPage("net.adoptium.java", "", tr("Adoptium")), // Fabric - new InstallLoaderPage("com.azul.java", "", tr("Azul")), + new InstallJavaPage("com.azul.java", "", tr("Azul")), }; } From 703470e57d615b1bb1998a253865c8fe7fadcccd Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 20 Mar 2024 08:24:40 +0200 Subject: [PATCH 58/83] Hopefully fix codeql Signed-off-by: Trial97 --- launcher/ui/java/InstallJavaDialog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/java/InstallJavaDialog.h b/launcher/ui/java/InstallJavaDialog.h index e228adf21e..c98c1deae3 100644 --- a/launcher/ui/java/InstallJavaDialog.h +++ b/launcher/ui/java/InstallJavaDialog.h @@ -27,7 +27,7 @@ class PackProfile; class QDialogButtonBox; namespace Java { -class InstallDialog final : public QDialog, protected BasePageProvider { +class InstallDialog final : public QDialog, public BasePageProvider { Q_OBJECT public: From 1c809f0fb1ef477d0315a7d1af174852b3b831e8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 20 Mar 2024 17:39:10 +0200 Subject: [PATCH 59/83] Added more logs for auto java install Signed-off-by: Trial97 --- launcher/minecraft/launch/AutoInstallJava.cpp | 19 ++++++++++++++++++- launcher/ui/java/InstallJavaDialog.cpp | 1 + launcher/ui/java/InstallJavaDialog.h | 2 +- launcher/ui/pages/global/JavaPage.cpp | 5 ++--- launcher/ui/pages/global/JavaPage.ui | 8 -------- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 3ae6ffa88a..1dc91003f8 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -91,7 +91,21 @@ void AutoInstallJava::executeTask() emit progressReportingRequest(); return; } + if (m_supported_arch.isEmpty()) { + emit logLine(tr("Your system(%1 %2) is not compatible with auto java download. Using the default java path.") + .arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), + MessageLevel::Warning); + emitSucceeded(); + return; + } auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); + if (wantedJavaName.isEmpty()) { + emit logLine(tr("Your meta informtation is old or doesn't have the information necesary to determine what java should be used. " + "Using the default java path."), + MessageLevel::Warning); + emitSucceeded(); + return; + } QDir javaDir(APPLICATION->javaPath()); auto wantedJavaPath = javaDir.absoluteFilePath(wantedJavaName); if (QFileInfo::exists(wantedJavaPath)) { @@ -136,7 +150,8 @@ void AutoInstallJava::setJavaPathFromPartial() if (QFileInfo::exists(finalPath)) { setJavaPath(finalPath); } else { - emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible java version was found(the binary file doesn't exists). Using the default one."), + MessageLevel::Warning); emitSucceeded(); } return; @@ -188,6 +203,8 @@ void AutoInstallJava::tryNextMajorJava() auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); auto majorJavaVersions = packProfile->getProfile()->getCompatibleJavaMajors(); if (m_majorJavaVersionIndex >= majorJavaVersions.length()) { + emit logLine(tr("No Java versions found for your operating system: %1 %2").arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), + MessageLevel::Warning); emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); return; diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 40616aafee..874fc9133d 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -72,6 +72,7 @@ class InstallJavaPage : public QWidget, public BasePage { void initialize(Meta::VersionList::Ptr vlist) { vlist->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); + vlist->sort(1); majorVersionSelect->initialize(vlist.get()); } diff --git a/launcher/ui/java/InstallJavaDialog.h b/launcher/ui/java/InstallJavaDialog.h index c98c1deae3..525e750aa7 100644 --- a/launcher/ui/java/InstallJavaDialog.h +++ b/launcher/ui/java/InstallJavaDialog.h @@ -27,7 +27,7 @@ class PackProfile; class QDialogButtonBox; namespace Java { -class InstallDialog final : public QDialog, public BasePageProvider { +class InstallDialog final : public QDialog, private BasePageProvider { Q_OBJECT public: diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 41a666cf26..6d8b95c24b 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -66,8 +66,8 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { ui->managedJavaList->initialize(new JavaInstallList(this, true)); ui->managedJavaList->selectCurrent(); - ui->managedJavaList->setEmptyString(tr("No java versions are currently available in the meta")); - ui->managedJavaList->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); + ui->managedJavaList->setEmptyString(tr("No managed java versions are installed")); + ui->managedJavaList->setEmptyErrorString(tr("Couldn't load the managed java list!")); connect(ui->autodetectJavaCheckBox, &QCheckBox::stateChanged, this, [this] { ui->autodownloadCheckBox->setEnabled(ui->autodetectJavaCheckBox->isChecked()); if (!ui->autodetectJavaCheckBox->isChecked()) @@ -75,7 +75,6 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) }); } else { ui->autodownloadCheckBox->setHidden(true); - ui->javaDownloadBtn->setHidden(true); ui->tabWidget->tabBar()->hide(); } diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index dc1668ee3d..c8f62e0757 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -178,13 +178,6 @@ - - - - Download Java - - - @@ -424,7 +417,6 @@ permGenSpinBox javaPathTextBox javaBrowseBtn - javaDownloadBtn javaDetectBtn javaTestBtn skipCompatibilityCheckbox From ab7fc2e46cd1ebe3d29436c8939de57d681a24a2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 21 Mar 2024 00:42:04 +0200 Subject: [PATCH 60/83] Fixed archive java download Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 4 ++++ launcher/java/download/ArchiveDownloadTask.cpp | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 265eb8b7a5..33f5f88fcb 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -510,6 +510,10 @@ bool ExportToZipTask::abort() void ExtractZipTask::executeTask() { + if (!m_input->isOpen() && !m_input->open(QuaZip::mdUnzip)) { + emitFailed(tr("Unable to open supplied zip file.")); + return; + } m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return extractZip(); }); connect(&m_zip_watcher, &QFutureWatcher::finished, this, &ExtractZipTask::finish); m_zip_watcher.setFuture(m_zip_future); diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 34f60260ed..d62d4d8e2f 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -35,7 +35,7 @@ void ArchiveDownloadTask::executeTask() // JRE found ! download the zip setStatus(tr("Downloading Java")); - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", m_url.toLocalFile()); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", m_url.fileName()); auto download = makeShared(QString("JRE::DownloadJava"), APPLICATION->network()); auto action = Net::Download::makeCached(m_url, entry); @@ -70,12 +70,16 @@ void ArchiveDownloadTask::extractJava(QString input) { setStatus(tr("Extracting java")); auto zip = std::make_shared(input); + if (!zip->open(QuaZip::mdUnzip)) { + emitFailed(tr("Unable to open supplied zip file.")); + return; + } auto files = zip->getFileNameList(); if (files.isEmpty()) { emitFailed("Empty archive"); return; } - auto zipTask = makeShared(input, m_final_path, files[0]); + auto zipTask = makeShared(zip, m_final_path, files[0]); auto progressStep = std::make_shared(); connect(zipTask.get(), &Task::finished, this, [this, progressStep] { From 1a6dfd04d66edb667f2ceb6646620b219dc17daf Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 21 Mar 2024 19:46:57 +0200 Subject: [PATCH 61/83] Made tar.gz parser Signed-off-by: Trial97 --- launcher/Application.cpp | 1 + launcher/BaseVersionList.cpp | 9 + launcher/BaseVersionList.h | 1 + launcher/CMakeLists.txt | 2 + launcher/FileSystem.cpp | 3 + launcher/Untar.cpp | 262 ++++++++++++++++++ launcher/Untar.h | 46 +++ launcher/VersionProxyModel.cpp | 9 + launcher/VersionProxyModel.h | 2 +- .../java/download/ArchiveDownloadTask.cpp | 23 ++ launcher/meta/VersionList.cpp | 7 + .../minecraft/launch/VerifyJavaInstall.cpp | 1 - launcher/ui/java/InstallJavaDialog.cpp | 12 +- launcher/ui/java/VersionList.cpp | 7 + launcher/ui/widgets/JavaSettingsWidget.cpp | 2 +- 15 files changed, 381 insertions(+), 6 deletions(-) create mode 100644 launcher/Untar.cpp create mode 100644 launcher/Untar.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index b0929a0ae4..f7fa3aedd6 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -869,6 +869,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_metacache->addBase("translations", QDir("translations").absolutePath()); m_metacache->addBase("icons", QDir("cache/icons").absolutePath()); m_metacache->addBase("meta", QDir("meta").absolutePath()); + m_metacache->addBase("java", QDir("cache/java").absolutePath()); m_metacache->Load(); qDebug() << "<> Cache initialized."; } diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index afee8388a1..22077c9623 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -78,6 +78,14 @@ QVariant BaseVersionList::data(const QModelIndex& index, int role) const case TypeRole: return version->typeString(); + case JavaMajorRole: { + auto major = version->name(); + if (major.startsWith("java")) { + major = "Java " + major.mid(4); + } + return major; + } + default: return QVariant(); } @@ -112,5 +120,6 @@ QHash BaseVersionList::roleNames() const roles.insert(PathRole, "path"); roles.insert(JavaNameRole, "javaName"); roles.insert(CPUArchitectureRole, "architecture"); + roles.insert(JavaMajorRole, "javaMajor"); return roles; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index bc37e9e53e..673d135628 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -49,6 +49,7 @@ class BaseVersionList : public QAbstractListModel { BranchRole, PathRole, JavaNameRole, + JavaMajorRole, CPUArchitectureRole, SortRole }; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index dd493682eb..4f8ab598ef 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -24,6 +24,8 @@ set(CORE_SOURCES NullInstance.h MMCZip.h MMCZip.cpp + Untar.h + Untar.cpp StringUtils.h StringUtils.cpp QVariantUtils.h diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index f9be91a2ae..8320dfe408 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -276,6 +276,9 @@ bool ensureFolderPathExists(const QFileInfo folderPath) { QDir dir; QString ensuredPath = folderPath.filePath(); + if (folderPath.exists()) + return true; + bool success = dir.mkpath(ensuredPath); return success; } diff --git a/launcher/Untar.cpp b/launcher/Untar.cpp new file mode 100644 index 0000000000..521c504a6e --- /dev/null +++ b/launcher/Untar.cpp @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023-2024 Trial97 + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "Untar.h" +#include +#include +#include +#include +#include +#include +#include +#include "FileSystem.h" + +// adaptation of the: +// - https://github.com/madler/zlib/blob/develop/contrib/untgz/untgz.c +// - https://en.wikipedia.org/wiki/Tar_(computing) +// - https://github.com/euroelessar/cutereader/blob/master/karchive/src/ktar.cpp + +#define BLOCKSIZE 512 +#define SHORTNAMESIZE 100 + +enum class TypeFlag : char { + Regular = '0', // regular file + ARegular = 0, // regular file + Link = '1', // link + Symlink = '2', // reserved + Character = '3', // character special + Block = '4', // block special + Directory = '5', // directory + FIFO = '6', // FIFO special + Contiguous = '7', // reserved + // Posix stuff + GlobalPosixHeader = 'g', + ExtendedPosixHeader = 'x', + // 'A'– 'Z' Vendor specific extensions(POSIX .1 - 1988) + // GNU + GNULongLink = 'K', /* long link name */ + GNULongName = 'L', /* long file name */ +}; + +struct Header { /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + TypeFlag typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union Buffer { + char buffer[BLOCKSIZE]; + struct Header header; +}; + +bool readLonglink(QIODevice* in, Buffer buffer, QByteArray& longlink) +{ + qint64 n = 0; + qint64 size = strtoll(buffer.header.size, NULL, 8); + size--; // ignore trailing null + if (errno == ERANGE) { + qCritical() << "The filename size can't be read"; + return false; + } + if (size < 0) { + qCritical() << "The filename size is negative"; + return false; + } + longlink.resize(size + (BLOCKSIZE - size % BLOCKSIZE)); // make the size divisible by BLOCKSIZE + for (qint64 offset = 0; offset < longlink.size(); offset += BLOCKSIZE) { + n = in->read(longlink.data() + offset, BLOCKSIZE); + if (n != BLOCKSIZE) { + qCritical() << "The expected blocksize was not respected for the name"; + return false; + } + } + longlink.truncate(qstrlen(longlink.constData())); + return true; +} + +bool Tar::extract(QIODevice* in, QString dst) +{ + Buffer buffer; + QString name, symlink, firstFolderName; + bool doNotReset = false; + while (true) { + auto n = in->read(buffer.buffer, BLOCKSIZE); + if (n != BLOCKSIZE) { // allways expect complete blocks + qCritical() << "The expected blocksize was not respected"; + return false; + } + if (buffer.header.name[0] == 0) { // end of archive + return true; + } + int mode = strtol(buffer.header.mode, NULL, 8) | QFile::ReadUser | QFile::WriteUser; // hack to ensure write and read permisions + if (errno == ERANGE) { + qCritical() << "The file mode can't be read"; + return false; + } + // there are names that are exactly 100 bytes long + // and neither longlink nor \0 terminated (bug:101472) + if (name.isEmpty()) { + name = QFile::decodeName(QByteArray(buffer.header.name, qstrnlen(buffer.header.name, 100))); + if (!firstFolderName.isEmpty() && name.startsWith(firstFolderName)) { + name = name.mid(firstFolderName.size()); + } + } + if (symlink.isEmpty()) + symlink = QFile::decodeName(QByteArray(buffer.header.linkname, qstrnlen(buffer.header.linkname, 100))); + switch (buffer.header.typeflag) { + case TypeFlag::Regular: + /* fallthrough */ + case TypeFlag::ARegular: { + auto fileName = FS::PathCombine(dst, name); + if (!FS::ensureFilePathExists(fileName)) { + qCritical() << "Can't ensure the file path to exist: " << fileName; + return false; + } + QFile out(fileName); + if (!out.open(QFile::WriteOnly, QFile::Permission(mode))) { + qCritical() << "Can't open file:" << fileName; + return false; + } + qint64 size = strtoll(buffer.header.size, NULL, 8); + if (errno == ERANGE) { + qCritical() << "The file size can't be read"; + return false; + } + while (size > 0) { + QByteArray tmp(BLOCKSIZE, 0); + n = in->read(tmp.data(), BLOCKSIZE); + if (n != BLOCKSIZE) { + qCritical() << "The expected blocksize was not respected when reading file"; + return false; + } + tmp.truncate(qMin(BLOCKSIZE, size)); + out.write(tmp); + size -= BLOCKSIZE; + } + QFile::setPermissions(fileName, QFile::Permissions(mode)); + break; + } + case TypeFlag::Directory: { + if (firstFolderName.isEmpty()) { + firstFolderName = name; + break; + } + auto folderPath = FS::PathCombine(dst, name); + if (!FS::ensureFolderPathExists(folderPath)) { + qCritical() << "Can't ensure that folder exists: " << folderPath; + return false; + } + break; + } + case TypeFlag::GNULongLink: { + doNotReset = true; + QByteArray longlink; + if (readLonglink(in, buffer, longlink)) { + symlink = QFile::decodeName(longlink.constData()); + } else { + qCritical() << "Failed to read long link"; + return false; + } + break; + } + case TypeFlag::GNULongName: { + doNotReset = true; + QByteArray longlink; + if (readLonglink(in, buffer, longlink)) { + name = QFile::decodeName(longlink.constData()); + } else { + qCritical() << "Failed to read long name"; + return false; + } + break; + } + case TypeFlag::Link: + /* fallthrough */ + case TypeFlag::Symlink: { + auto fileName = FS::PathCombine(dst, name); + if (!FS::create_link(FS::PathCombine(QFileInfo(fileName).path(), symlink), fileName)()) { // do not use symlinks + qCritical() << "Can't create link for:" << fileName << " to:" << FS::PathCombine(QFileInfo(fileName).path(), symlink); + return false; + } + FS::ensureFilePathExists(fileName); + QFile::setPermissions(fileName, QFile::Permissions(mode)); + break; + } + case TypeFlag::Character: + /* fallthrough */ + case TypeFlag::Block: + /* fallthrough */ + case TypeFlag::FIFO: + /* fallthrough */ + case TypeFlag::Contiguous: + /* fallthrough */ + case TypeFlag::GlobalPosixHeader: + /* fallthrough */ + case TypeFlag::ExtendedPosixHeader: + /* fallthrough */ + default: + break; + } + if (!doNotReset) { + name.truncate(0); + symlink.truncate(0); + } + doNotReset = false; + } + return true; +} + +bool GZTar::extract(QString src, QString dst) +{ + QuaGzipFile a(src); + if (!a.open(QIODevice::ReadOnly)) { + qCritical() << "Can't open tar file:" << src; + return false; + } + return Tar::extract(&a, dst); +} \ No newline at end of file diff --git a/launcher/Untar.h b/launcher/Untar.h new file mode 100644 index 0000000000..54010e085f --- /dev/null +++ b/launcher/Untar.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023-2024 Trial97 + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once +#include + +// this is a hack used for the java downloader (feel free to remove it in favor of a library) +// both extract functions will extract the first folder inside dest(disregarding the prefix) +namespace Tar { +bool extract(QIODevice* in, QString dst); +}; + +namespace GZTar { +bool extract(QString src, QString dst); +}; \ No newline at end of file diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 070e952a4a..62cf4c2215 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -120,6 +120,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Path"); case JavaName: return tr("Java Name"); + case JavaMajor: + return tr("Major"); case Time: return tr("Released"); } @@ -139,6 +141,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return tr("Filesystem path to this version"); case JavaName: return tr("The alternative name of the java version"); + case JavaMajor: + return tr("The java major version"); case Time: return tr("Release date of this version"); } @@ -175,6 +179,8 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::PathRole); case JavaName: return sourceModel()->data(parentIndex, BaseVersionList::JavaNameRole); + case JavaMajor: + return sourceModel()->data(parentIndex, BaseVersionList::JavaMajorRole); case Time: return sourceModel()->data(parentIndex, Meta::VersionList::TimeRole).toDate(); default: @@ -323,6 +329,9 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) if (roles.contains(BaseVersionList::JavaNameRole)) { m_columns.push_back(JavaName); } + if (roles.contains(BaseVersionList::JavaMajorRole)) { + m_columns.push_back(JavaMajor); + } if (roles.contains(Meta::VersionList::TimeRole)) { m_columns.push_back(Time); } diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index cb55b7f14a..8aea257954 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -9,7 +9,7 @@ class VersionFilterModel; class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT public: - enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName }; + enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaMajor }; using FilterMap = QHash>; public: diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index d62d4d8e2f..3588606104 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -21,6 +21,7 @@ #include "MMCZip.h" #include "Application.h" +#include "Untar.h" #include "net/ChecksumValidator.h" #include "net/NetJob.h" #include "tasks/Task.h" @@ -69,6 +70,28 @@ void ArchiveDownloadTask::executeTask() void ArchiveDownloadTask::extractJava(QString input) { setStatus(tr("Extracting java")); + if (input.endsWith("tar")) { + setStatus(tr("Extracting java(the progress will not be reported for tar)")); + QFile in(input); + if (!in.open(QFile::ReadOnly)) { + emitFailed(tr("Unable to open supplied tar file.")); + return; + } + if (!Tar::extract(&in, QDir(m_final_path).absolutePath())) { + emitFailed(tr("Unable to extract supplied tar file.")); + return; + } + emitSucceeded(); + return; + } else if (input.endsWith("tar.gz") || input.endsWith("taz") || input.endsWith("tgz")) { + setStatus(tr("Extracting java(the progress will not be reported for tar)")); + if (!GZTar::extract(input, QDir(m_final_path).absolutePath())) { + emitFailed(tr("Unable to extract supplied tar file.")); + return; + } + emitSucceeded(); + return; + } auto zip = std::make_shared(input); if (!zip->open(QuaZip::mdUnzip)) { emitFailed(tr("Unable to open supplied zip file.")); diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index 76b914b6a3..66412d6a40 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -92,6 +92,13 @@ QVariant VersionList::data(const QModelIndex& index, int role) const return QVariant::fromValue(version); case RecommendedRole: return version->isRecommended(); + case JavaMajorRole: { + auto major = version->version(); + if (major.startsWith("java")) { + major = "Java " + major.mid(4); + } + return major; + } // FIXME: this should be determined in whatever view/proxy is used... // case LatestRole: return version == getLatestStable(); default: diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index f26b850ebd..5f8b35b02c 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -54,7 +54,6 @@ void VerifyJavaInstall::executeTask() auto javaArchitecture = settings->get("JavaArchitecture").toString(); auto maxMemAlloc = settings->get("MaxMemAlloc").toInt(); - emit logLine(tr("Java architecture is x%1.").arg(javaArchitecture), MessageLevel::Info); if (javaArchitecture == "32" && maxMemAlloc > 2048) { emit logLine(tr("Max memory allocation exceeds the supported value.\n" "The selected java is 32-bit and doesn't support more than 2048MiB of RAM.\n" diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 874fc9133d..78de3e20a0 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -19,16 +19,19 @@ #include "InstallJavaDialog.h" #include +#include #include #include #include #include "Application.h" +#include "BaseVersionList.h" #include "FileSystem.h" #include "java/download/ArchiveDownloadTask.h" #include "java/download/ManifestDownloadTask.h" #include "meta/Index.h" #include "meta/VersionList.h" +#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" #include "ui/java/VersionList.h" #include "ui/widgets/PageContainer.h" @@ -71,8 +74,7 @@ class InstallJavaPage : public QWidget, public BasePage { //! loads the list if needed. void initialize(Meta::VersionList::Ptr vlist) { - vlist->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); - vlist->sort(1); + vlist->setProvidedRoles({ BaseVersionList::JavaMajorRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole }); majorVersionSelect->initialize(vlist.get()); } @@ -219,7 +221,11 @@ void InstallDialog::done(int result) break; } auto deletePath = [final_path] { FS::deletePath(final_path); }; - connect(task.get(), &Task::failed, this, deletePath); + connect(task.get(), &Task::failed, this, [this, &deletePath](QString reason) { + QString error = QString("Java download failed: %1").arg(reason); + CustomMessageBox::selectable(this, tr("Error"), error, QMessageBox::Warning)->show(); + deletePath(); + }); connect(task.get(), &Task::aborted, this, deletePath); ProgressDialog pg(this); pg.setSkipButton(true, tr("Abort")); diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index 78448ddafe..5e385604d6 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -78,6 +78,13 @@ QVariant VersionList::data(const QModelIndex& index, int role) const return false; // do not recommend any version case JavaNameRole: return version->name(); + case JavaMajorRole: { + auto major = version->version.toString(); + if (major.startsWith("java")) { + major = "Java " + major.mid(4); + } + return major; + } case TypeRole: return version->packageType; case Meta::VersionList::TimeRole: diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index e2e4980678..1645f2b5f6 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -180,7 +180,7 @@ void JavaSettingsWidget::initialize() tr("%1 can automatically download the correct Java version for each version of Minecraft..\n" "Do you want to enable Java auto-download?\n") .arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) ->exec(); if (button == QMessageBox::Yes) { m_autodetectJavaCheckBox->setChecked(true); From 3046822272ee97a831667db1c8a222eb304c259e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 21 Mar 2024 19:53:52 +0200 Subject: [PATCH 62/83] Fixed buid Signed-off-by: Trial97 --- launcher/Untar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/Untar.cpp b/launcher/Untar.cpp index 521c504a6e..b2f05038c3 100644 --- a/launcher/Untar.cpp +++ b/launcher/Untar.cpp @@ -158,10 +158,11 @@ bool Tar::extract(QIODevice* in, QString dst) return false; } QFile out(fileName); - if (!out.open(QFile::WriteOnly, QFile::Permission(mode))) { + if (!out.open(QFile::WriteOnly)) { qCritical() << "Can't open file:" << fileName; return false; } + out.setPermissions(QFile::Permissions(mode)); qint64 size = strtoll(buffer.header.size, NULL, 8); if (errno == ERANGE) { qCritical() << "The file size can't be read"; @@ -178,7 +179,6 @@ bool Tar::extract(QIODevice* in, QString dst) out.write(tmp); size -= BLOCKSIZE; } - QFile::setPermissions(fileName, QFile::Permissions(mode)); break; } case TypeFlag::Directory: { From a7029a9e53cd3d9a2371cd26c257beb898251667 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 21 Mar 2024 20:01:40 +0200 Subject: [PATCH 63/83] Fixed qMin Signed-off-by: Trial97 --- launcher/Untar.cpp | 2 +- launcher/Untar.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/Untar.cpp b/launcher/Untar.cpp index b2f05038c3..bae6c5d17f 100644 --- a/launcher/Untar.cpp +++ b/launcher/Untar.cpp @@ -175,7 +175,7 @@ bool Tar::extract(QIODevice* in, QString dst) qCritical() << "The expected blocksize was not respected when reading file"; return false; } - tmp.truncate(qMin(BLOCKSIZE, size)); + tmp.truncate(qMin(qint64(BLOCKSIZE), size)); out.write(tmp); size -= BLOCKSIZE; } diff --git a/launcher/Untar.h b/launcher/Untar.h index 54010e085f..50e3a16e32 100644 --- a/launcher/Untar.h +++ b/launcher/Untar.h @@ -39,8 +39,8 @@ // both extract functions will extract the first folder inside dest(disregarding the prefix) namespace Tar { bool extract(QIODevice* in, QString dst); -}; +} namespace GZTar { bool extract(QString src, QString dst); -}; \ No newline at end of file +} \ No newline at end of file From 0b87e4c03b55c96966255eb8440b0c4e7b182c63 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 22 Mar 2024 12:29:15 +0200 Subject: [PATCH 64/83] Fiexed codeql warning Signed-off-by: Trial97 --- launcher/Untar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Untar.cpp b/launcher/Untar.cpp index bae6c5d17f..1d11dfd60b 100644 --- a/launcher/Untar.cpp +++ b/launcher/Untar.cpp @@ -94,7 +94,7 @@ union Buffer { struct Header header; }; -bool readLonglink(QIODevice* in, Buffer buffer, QByteArray& longlink) +bool readLonglink(QIODevice* in, Buffer& buffer, QByteArray& longlink) { qint64 n = 0; qint64 size = strtoll(buffer.header.size, NULL, 8); From c0754b80a2b8612ce2874888c0f40b41b2eac765 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 22 Mar 2024 22:17:58 +0200 Subject: [PATCH 65/83] Add resize to last column Signed-off-by: Trial97 --- launcher/ui/pages/global/JavaPage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 6d8b95c24b..fda4f87052 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -65,6 +65,7 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { ui->managedJavaList->initialize(new JavaInstallList(this, true)); + ui->managedJavaList->setResizeOn(2); ui->managedJavaList->selectCurrent(); ui->managedJavaList->setEmptyString(tr("No managed java versions are installed")); ui->managedJavaList->setEmptyErrorString(tr("Couldn't load the managed java list!")); From 93f6315b16de3b2170d0263d7befcac5dcfaa01d Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Wed, 27 Mar 2024 19:34:04 +0200 Subject: [PATCH 66/83] Update CMakeLists.txt Co-authored-by: seth Signed-off-by: Alexandru Ionut Tripon --- CMakeLists.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40ccff5957..f4298aedba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,17 @@ set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, set(Launcher_QT_VERSION_MAJOR "6" CACHE STRING "Major Qt version to build against") # Java downloader -option(ENABLE_JAVA_DOWNLOADER "Build the java downloader feature" ON) +set(ENABLE_JAVA_DOWNLOADER_DEFAULT ON) + +# Although we recommend enabling this, we cannot guarantee binary compatibility on +# differing Linux/BSD/etc distributions. Downstream packagers should be explicitly opt-ing into this +# feature if they know it will work with their distribution. +if(UNIX AND NOT APPLE) + set(ENABLE_JAVA_DOWNLOADER_DEFAULT OFF) +endif() + +# Java downloader +option(ENABLE_JAVA_DOWNLOADER "Build the java downloader feature" ${ENABLE_JAVA_DOWNLOADER_DEFAULT}) # Native libraries if(UNIX AND APPLE) From 45028ddc6142b019d28dadd31b8c87433adea312 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 28 Mar 2024 14:58:05 +0200 Subject: [PATCH 67/83] Added java downloader to CI build Signed-off-by: Trial97 --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9cb737df6e..500aca5cb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -274,23 +274,23 @@ jobs: - name: Configure CMake (macOS) if: runner.os == 'macOS' && matrix.qt_ver == 6 run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja - name: Configure CMake (macOS-Legacy) if: runner.os == 'macOS' && matrix.qt_ver == 5 run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja - name: Configure CMake (Windows MinGW-w64) if: runner.os == 'Windows' && matrix.msystem != '' shell: msys2 {0} run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }} -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }} -G Ninja - name: Configure CMake (Windows MSVC) if: runner.os == 'Windows' && matrix.msystem == '' run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }} + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }} # https://github.com/ccache/ccache/wiki/MS-Visual-Studio (I coudn't figure out the compiler prefix) if ("${{ env.CCACHE_VAR }}") { @@ -305,7 +305,7 @@ jobs: - name: Configure CMake (Linux) if: runner.os == 'Linux' run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DLauncher_BUILD_ARTIFACT=Linux-Qt${{ matrix.qt_ver }} -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DLauncher_BUILD_ARTIFACT=Linux-Qt${{ matrix.qt_ver }} -G Ninja ## # BUILD From 81874f22f74e3d254e16c3054abb28881b50d01a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 29 Mar 2024 00:10:59 +0200 Subject: [PATCH 68/83] Fixed tar extract Signed-off-by: Trial97 --- launcher/Untar.cpp | 96 +++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/launcher/Untar.cpp b/launcher/Untar.cpp index 1d11dfd60b..f1963e7aaf 100644 --- a/launcher/Untar.cpp +++ b/launcher/Untar.cpp @@ -33,13 +33,11 @@ * limitations under the License. */ #include "Untar.h" -#include -#include #include #include +#include #include #include -#include #include "FileSystem.h" // adaptation of the: @@ -69,40 +67,30 @@ enum class TypeFlag : char { GNULongName = 'L', /* long file name */ }; -struct Header { /* byte offset */ - char name[100]; /* 0 */ - char mode[8]; /* 100 */ - char uid[8]; /* 108 */ - char gid[8]; /* 116 */ - char size[12]; /* 124 */ - char mtime[12]; /* 136 */ - char chksum[8]; /* 148 */ - TypeFlag typeflag; /* 156 */ - char linkname[100]; /* 157 */ - char magic[6]; /* 257 */ - char version[2]; /* 263 */ - char uname[32]; /* 265 */ - char gname[32]; /* 297 */ - char devmajor[8]; /* 329 */ - char devminor[8]; /* 337 */ - char prefix[155]; /* 345 */ - /* 500 */ -}; +// struct Header { /* byte offset */ +// char name[100]; /* 0 */ +// char mode[8]; /* 100 */ +// char uid[8]; /* 108 */ +// char gid[8]; /* 116 */ +// char size[12]; /* 124 */ +// char mtime[12]; /* 136 */ +// char chksum[8]; /* 148 */ +// TypeFlag typeflag; /* 156 */ +// char linkname[100]; /* 157 */ +// char magic[6]; /* 257 */ +// char version[2]; /* 263 */ +// char uname[32]; /* 265 */ +// char gname[32]; /* 297 */ +// char devmajor[8]; /* 329 */ +// char devminor[8]; /* 337 */ +// char prefix[155]; /* 345 */ +// /* 500 */ +// }; -union Buffer { - char buffer[BLOCKSIZE]; - struct Header header; -}; - -bool readLonglink(QIODevice* in, Buffer& buffer, QByteArray& longlink) +bool readLonglink(QIODevice* in, qint64 size, QByteArray& longlink) { qint64 n = 0; - qint64 size = strtoll(buffer.header.size, NULL, 8); size--; // ignore trailing null - if (errno == ERANGE) { - qCritical() << "The filename size can't be read"; - return false; - } if (size < 0) { qCritical() << "The filename size is negative"; return false; @@ -119,36 +107,51 @@ bool readLonglink(QIODevice* in, Buffer& buffer, QByteArray& longlink) return true; } +int getOctal(char* buffer, int maxlenght, bool* ok) +{ + return QByteArray(buffer, qstrnlen(buffer, maxlenght)).toInt(ok, 8); +} + +QString decodeName(char* name) +{ + return QFile::decodeName(QByteArray(name, qstrnlen(name, 100))); +} bool Tar::extract(QIODevice* in, QString dst) { - Buffer buffer; + char buffer[BLOCKSIZE]; QString name, symlink, firstFolderName; - bool doNotReset = false; + bool doNotReset = false, ok; while (true) { - auto n = in->read(buffer.buffer, BLOCKSIZE); + auto n = in->read(buffer, BLOCKSIZE); if (n != BLOCKSIZE) { // allways expect complete blocks qCritical() << "The expected blocksize was not respected"; return false; } - if (buffer.header.name[0] == 0) { // end of archive + if (buffer[0] == 0) { // end of archive return true; } - int mode = strtol(buffer.header.mode, NULL, 8) | QFile::ReadUser | QFile::WriteUser; // hack to ensure write and read permisions - if (errno == ERANGE) { + int mode = getOctal(buffer + 100, 8, &ok) | QFile::ReadUser | QFile::WriteUser; // hack to ensure write and read permisions + if (!ok) { qCritical() << "The file mode can't be read"; return false; } // there are names that are exactly 100 bytes long // and neither longlink nor \0 terminated (bug:101472) + if (name.isEmpty()) { - name = QFile::decodeName(QByteArray(buffer.header.name, qstrnlen(buffer.header.name, 100))); + name = decodeName(buffer); if (!firstFolderName.isEmpty() && name.startsWith(firstFolderName)) { name = name.mid(firstFolderName.size()); } } if (symlink.isEmpty()) - symlink = QFile::decodeName(QByteArray(buffer.header.linkname, qstrnlen(buffer.header.linkname, 100))); - switch (buffer.header.typeflag) { + symlink = decodeName(buffer); + qint64 size = getOctal(buffer + 124, 12, &ok); + if (!ok) { + qCritical() << "The file size can't be read"; + return false; + } + switch (TypeFlag(buffer[156])) { case TypeFlag::Regular: /* fallthrough */ case TypeFlag::ARegular: { @@ -163,11 +166,6 @@ bool Tar::extract(QIODevice* in, QString dst) return false; } out.setPermissions(QFile::Permissions(mode)); - qint64 size = strtoll(buffer.header.size, NULL, 8); - if (errno == ERANGE) { - qCritical() << "The file size can't be read"; - return false; - } while (size > 0) { QByteArray tmp(BLOCKSIZE, 0); n = in->read(tmp.data(), BLOCKSIZE); @@ -196,7 +194,7 @@ bool Tar::extract(QIODevice* in, QString dst) case TypeFlag::GNULongLink: { doNotReset = true; QByteArray longlink; - if (readLonglink(in, buffer, longlink)) { + if (readLonglink(in, size, longlink)) { symlink = QFile::decodeName(longlink.constData()); } else { qCritical() << "Failed to read long link"; @@ -207,7 +205,7 @@ bool Tar::extract(QIODevice* in, QString dst) case TypeFlag::GNULongName: { doNotReset = true; QByteArray longlink; - if (readLonglink(in, buffer, longlink)) { + if (readLonglink(in, size, longlink)) { name = QFile::decodeName(longlink.constData()); } else { qCritical() << "Failed to read long name"; From b23b53d98d5c99353a79355371a7eb7a8537df0c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 18 May 2024 14:43:58 +0300 Subject: [PATCH 69/83] Add missing header Signed-off-by: Trial97 --- launcher/java/JavaChecker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 678c98cd47..c54a5b04b9 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -41,6 +41,7 @@ #include #include "Commandline.h" +#include "FileSystem.h" #include "java/JavaUtils.h" JavaChecker::JavaChecker(QString path, QString args, int minMem, int maxMem, int permGen, int id, QObject* parent) From abb628edb36a7e3e433dee93a224dbd4329acc24 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 May 2024 18:23:43 +0300 Subject: [PATCH 70/83] remove OverrideJava Signed-off-by: Trial97 --- launcher/launch/steps/CheckJava.cpp | 2 +- launcher/minecraft/MinecraftInstance.cpp | 21 +++++++------------ launcher/minecraft/launch/AutoInstallJava.cpp | 4 +--- .../pages/instance/InstanceSettingsPage.cpp | 8 ++----- 4 files changed, 12 insertions(+), 23 deletions(-) diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index a8c7305abc..b5b85563ae 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -47,7 +47,7 @@ void CheckJava::executeTask() auto instance = m_parent->instance(); auto settings = instance->settings(); m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString()); - bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool(); + bool perInstance = settings->get("OverrideJavaLocation").toBool(); auto realJavaPath = QStandardPaths::findExecutable(m_javaPath); if (realJavaPath.isEmpty()) { diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 9fa3138439..0b0a279a54 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -136,25 +136,20 @@ void MinecraftInstance::loadSpecificSettings() return; // Java Settings - auto javaOverride = m_settings->registerSetting("OverrideJava", false); auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false); auto argsOverride = m_settings->registerSetting("OverrideJavaArgs", false); - // combinations - auto javaOrLocation = std::make_shared("JavaOrLocationOverride", javaOverride, locationOverride); - auto javaOrArgs = std::make_shared("JavaOrArgsOverride", javaOverride, argsOverride); - if (auto global_settings = globalSettings()) { - m_settings->registerOverride(global_settings->getSetting("JavaPath"), javaOrLocation); - m_settings->registerOverride(global_settings->getSetting("JvmArgs"), javaOrArgs); - m_settings->registerOverride(global_settings->getSetting("IgnoreJavaCompatibility"), javaOrLocation); + m_settings->registerOverride(global_settings->getSetting("JavaPath"), locationOverride); + m_settings->registerOverride(global_settings->getSetting("JvmArgs"), argsOverride); + m_settings->registerOverride(global_settings->getSetting("IgnoreJavaCompatibility"), locationOverride); // special! - m_settings->registerPassthrough(global_settings->getSetting("JavaSignature"), javaOrLocation); - m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), javaOrLocation); - m_settings->registerPassthrough(global_settings->getSetting("JavaRealArchitecture"), javaOrLocation); - m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation); - m_settings->registerPassthrough(global_settings->getSetting("JavaVendor"), javaOrLocation); + m_settings->registerPassthrough(global_settings->getSetting("JavaSignature"), locationOverride); + m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), locationOverride); + m_settings->registerPassthrough(global_settings->getSetting("JavaRealArchitecture"), locationOverride); + m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), locationOverride); + m_settings->registerPassthrough(global_settings->getSetting("JavaVendor"), locationOverride); // Window Size auto windowSetting = m_settings->registerSetting("OverrideWindow", false); diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 1dc91003f8..95bfa1dec7 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -61,8 +61,7 @@ void AutoInstallJava::executeTask() { auto settings = m_instance->settings(); if (!APPLICATION->settings()->get("AutomaticJavaSwitch").toBool() || - (settings->get("OverrideJava").toBool() && settings->get("OverrideJavaLocation").toBool() && - QFileInfo::exists(settings->get("JavaPath").toString()))) { + (settings->get("OverrideJavaLocation").toBool() && QFileInfo::exists(settings->get("JavaPath").toString()))) { emitSucceeded(); return; } @@ -126,7 +125,6 @@ void AutoInstallJava::executeTask() void AutoInstallJava::setJavaPath(QString path) { auto settings = m_instance->settings(); - settings->set("OverrideJava", true); settings->set("OverrideJavaLocation", true); settings->set("JavaPath", path); emit logLine(tr("Compatible java found at: %1.").arg(path), MessageLevel::Info); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index c248a47f72..fa52f2c51c 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -190,9 +190,6 @@ void InstanceSettingsPage::applySettings() m_settings->reset("JvmArgs"); } - // old generic 'override both' is removed. - m_settings->reset("OverrideJava"); - // Custom Commands bool custcmd = ui->customCommands->checked(); m_settings->set("OverrideCommands", custcmd); @@ -321,9 +318,8 @@ void InstanceSettingsPage::loadSettings() ui->labelPermgenNote->setVisible(permGenVisible); // Java Settings - bool overrideJava = m_settings->get("OverrideJava").toBool(); - bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava; - bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava; + bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool(); + bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool(); ui->javaSettingsGroupBox->setChecked(overrideLocation); ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString()); From 0e239dfb2a85c947d656764fa0036965eb040b40 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 May 2024 18:24:19 +0300 Subject: [PATCH 71/83] fix crash on first display with java downloader off Signed-off-by: Trial97 --- launcher/ui/setupwizard/JavaWizardPage.cpp | 8 +--- launcher/ui/widgets/JavaSettingsWidget.cpp | 45 +++++++++++++--------- launcher/ui/widgets/JavaSettingsWidget.h | 4 +- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index d537580fcd..a47cebcaa8 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -12,12 +12,8 @@ #include -#include "FileSystem.h" #include "JavaCommon.h" -#include "java/JavaInstall.h" -#include "java/JavaUtils.h" -#include "ui/dialogs/CustomMessageBox.h" #include "ui/widgets/JavaSettingsWidget.h" #include "ui/widgets/VersionSelectWidget.h" @@ -57,8 +53,8 @@ bool JavaWizardPage::validatePage() { auto settings = APPLICATION->settings(); auto result = m_java_widget->validate(); - settings->set("AutomaticJavaSwitch", m_java_widget->autodetectJava()); - settings->set("AutomaticJavaDownload", m_java_widget->autodownloadJava()); + settings->set("AutomaticJavaSwitch", m_java_widget->autoDetectJava()); + settings->set("AutomaticJavaDownload", m_java_widget->autoDownloadJava()); switch (result) { default: case JavaSettingsWidget::ValidationStatus::Bad: { diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 1645f2b5f6..34cd70f353 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -43,7 +43,9 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked); connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); - connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); + } } void JavaSettingsWidget::setupUi() @@ -176,18 +178,21 @@ void JavaSettingsWidget::initialize() m_permGenSpinBox->setValue(observedPermGenMemory); updateThresholds(); - auto button = CustomMessageBox::selectable(this, tr("Auto Java Download"), - tr("%1 can automatically download the correct Java version for each version of Minecraft..\n" - "Do you want to enable Java auto-download?\n") - .arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) - ->exec(); - if (button == QMessageBox::Yes) { - m_autodetectJavaCheckBox->setChecked(true); - m_autodownloadCheckBox->setChecked(true); - } else { - m_autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); - m_autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + auto button = + CustomMessageBox::selectable(this, tr("Auto Java Download"), + tr("%1 can automatically download the correct Java version for each version of Minecraft..\n" + "Do you want to enable Java auto-download?\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) + ->exec(); + if (button == QMessageBox::Yes) { + m_autodetectJavaCheckBox->setChecked(true); + m_autodownloadCheckBox->setChecked(true); + } else { + m_autodetectJavaCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool()); + m_autodownloadCheckBox->setChecked(s->get("AutomaticJavaSwitch").toBool() && s->get("AutomaticJavaDownload").toBool()); + } } } @@ -211,7 +216,7 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() case JavaStatus::DoesNotStart: /* fallthrough */ case JavaStatus::ReturnedInvalidData: { - if (!m_autodownloadCheckBox->isChecked()) { // the java will not be autodownloaded + if (!(BuildConfig.JAVA_DOWNLOADER_ENABLED && m_autodownloadCheckBox->isChecked())) { // the java will not be autodownloaded int button = QMessageBox::No; if (m_result.mojangPlatform == "32" && maxHeapSize() > 2048) { button = CustomMessageBox::selectable( @@ -488,7 +493,9 @@ void JavaSettingsWidget::retranslate() m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with.")); m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes.")); m_javaBrowseBtn->setText(tr("Browse")); - m_autodownloadCheckBox->setText(tr("Auto-download Mojang Java")); + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { + m_autodownloadCheckBox->setText(tr("Auto-download Mojang Java")); + } m_autodetectJavaCheckBox->setText(tr("Autodetect Java version")); m_autoJavaGroupBox->setTitle(tr("Autodetect Java")); } @@ -522,12 +529,12 @@ void JavaSettingsWidget::updateThresholds() } } -bool JavaSettingsWidget::autodownloadJava() const +bool JavaSettingsWidget::autoDownloadJava() const { - return m_autodetectJavaCheckBox->isChecked(); + return m_autodownloadCheckBox && m_autodownloadCheckBox->isChecked(); } -bool JavaSettingsWidget::autodetectJava() const +bool JavaSettingsWidget::autoDetectJava() const { - return m_autodownloadCheckBox->isChecked(); + return m_autodetectJavaCheckBox->isChecked(); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index c8b6953df6..877e60f466 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -42,8 +42,8 @@ class JavaSettingsWidget : public QWidget { int minHeapSize() const; int maxHeapSize() const; QString javaPath() const; - bool autodetectJava() const; - bool autodownloadJava() const; + bool autoDetectJava() const; + bool autoDownloadJava() const; void updateThresholds(); From 7a42fb284a28657106bf189a5ead0b1add38e9c8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 May 2024 18:33:40 +0300 Subject: [PATCH 72/83] reverse java version Signed-off-by: Trial97 --- launcher/ui/java/VersionList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/java/VersionList.cpp b/launcher/ui/java/VersionList.cpp index 5e385604d6..6f60a68673 100644 --- a/launcher/ui/java/VersionList.cpp +++ b/launcher/ui/java/VersionList.cpp @@ -103,7 +103,7 @@ bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) { auto rleft = std::dynamic_pointer_cast(right); auto rright = std::dynamic_pointer_cast(left); - return (*rleft) > (*rright); + return (*rleft) < (*rright); } void VersionList::sortVersions() From f6a7fc215aaacc235842a8f3fd31b81e3e9720c9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 21 May 2024 08:33:09 +0300 Subject: [PATCH 73/83] update java sorting by taking into consideration release time Signed-off-by: Trial97 --- launcher/java/JavaMetadata.cpp | 7 +++++++ launcher/java/JavaVersion.cpp | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/launcher/java/JavaMetadata.cpp b/launcher/java/JavaMetadata.cpp index e721947a75..2272470a8e 100644 --- a/launcher/java/JavaMetadata.cpp +++ b/launcher/java/JavaMetadata.cpp @@ -83,6 +83,13 @@ bool Metadata::operator<(const Metadata& rhs) if (id > rhs.version) { return false; } + auto date = releaseTime; + if (date < rhs.releaseTime) { + return true; + } + if (date > rhs.releaseTime) { + return false; + } return StringUtils::naturalCompare(m_name, rhs.m_name, Qt::CaseInsensitive) < 0; } diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index 2dc23472e2..5e97000121 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -59,12 +59,6 @@ bool JavaVersion::operator<(const JavaVersion& rhs) auto major = m_major; auto rmajor = rhs.m_major; - // HACK: discourage using java 9 - if (major > 8) - major = -major; - if (rmajor > 8) - rmajor = -rmajor; - if (major < rmajor) return true; if (major > rmajor) From bbf52e35497a596121befb4f7d9225ab99251732 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 01:59:50 +0300 Subject: [PATCH 74/83] renamed dialog and button action Signed-off-by: Trial97 --- launcher/ui/java/InstallJavaDialog.cpp | 12 ++++++++---- launcher/ui/pages/global/JavaPage.cpp | 7 +------ launcher/ui/pages/global/JavaPage.h | 1 - launcher/ui/widgets/JavaSettingsWidget.cpp | 4 ++-- launcher/ui/widgets/JavaSettingsWidget.h | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 78de3e20a0..60e3a770c6 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -184,18 +184,18 @@ InstallDialog::InstallDialog(const QString& uid, QWidget* parent) QList InstallDialog::getPages() { return { - // NeoForge + // Mojang new InstallJavaPage("net.minecraft.java", "", tr("Mojang")), - // Forge + // Adoptium new InstallJavaPage("net.adoptium.java", "", tr("Adoptium")), - // Fabric + // Azul new InstallJavaPage("com.azul.java", "", tr("Azul")), }; } QString InstallDialog::dialogTitle() { - return tr("Install Loader"); + return tr("Install Java"); } void InstallDialog::validate(BasePage* page) @@ -230,7 +230,11 @@ void InstallDialog::done(int result) ProgressDialog pg(this); pg.setSkipButton(true, tr("Abort")); pg.execWithTask(task.get()); + } else { + return; } + } else { + return; } } diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index fda4f87052..c8bbf6361b 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -199,7 +199,7 @@ void JavaPage::on_javaTestBtn_clicked() checker->run(); } -void JavaPage::on_javaDownloadBtn_clicked() +void JavaPage::on_downloadJavaButton_clicked() { auto jdialog = new Java::InstallDialog({}, this); jdialog->exec(); @@ -251,11 +251,6 @@ void JavaPage::updateThresholds() } } -void JavaPage::on_downloadJavaButton_clicked() -{ - on_javaDownloadBtn_clicked(); -} - void JavaPage::on_removeJavaButton_clicked() { auto version = ui->managedJavaList->selectedVersion(); diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 48e5577408..0a1c4a6bef 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -72,7 +72,6 @@ class JavaPage : public QWidget, public BasePage { void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); - void on_javaDownloadBtn_clicked(); void on_downloadJavaButton_clicked(); void on_removeJavaButton_clicked(); void on_refreshJavaButton_clicked(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 34cd70f353..e16f650fcb 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -44,7 +44,7 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { - connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaDownloadBtn_clicked); + connect(m_javaDownloadBtn, &QPushButton::clicked, this, &JavaSettingsWidget::javaDownloadBtn_clicked); } } @@ -354,7 +354,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() checkJavaPath(cooked_path); } -void JavaSettingsWidget::on_javaDownloadBtn_clicked() +void JavaSettingsWidget::javaDownloadBtn_clicked() { auto jdialog = new Java::InstallDialog({}, this); jdialog->exec(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 877e60f466..622c473fe5 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -53,7 +53,7 @@ class JavaSettingsWidget : public QWidget { void javaVersionSelected(BaseVersion::Ptr version); void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); - void on_javaDownloadBtn_clicked(); + void javaDownloadBtn_clicked(); void checkFinished(const JavaChecker::Result& result); protected: /* methods */ From 94fd02a34f1146fa84c6ea2516b694f6e3ce3d91 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 14:26:19 +0300 Subject: [PATCH 75/83] fix java download button Signed-off-by: Trial97 --- launcher/ui/java/InstallJavaDialog.cpp | 19 +++++++++---------- launcher/ui/java/InstallJavaDialog.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 60e3a770c6..d924022362 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -60,7 +60,8 @@ class InstallJavaPage : public QWidget, public BasePage { javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!")); horizontalLayout->addWidget(javaVersionSelect, 4); connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::setSelectedVersion); - connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::selectedVersionChanged); + connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::selectionChanged); + connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallJavaPage::selectionChanged); QMetaObject::connectSlotsByName(this); } @@ -119,7 +120,7 @@ class InstallJavaPage : public QWidget, public BasePage { javaVersionSelect->loadList(); } signals: - void selectedVersionChanged(BaseVersion::Ptr version); + void selectionChanged(); private: const QString uid; @@ -171,14 +172,11 @@ InstallDialog::InstallDialog(const QString& uid, QWidget* parent) if (page->id() == uid) container->selectPage(page->id()); - connect(pageCast(page), &InstallJavaPage::selectedVersionChanged, this, [this, page] { - if (page->id() == container->selectedPage()->id()) - validate(container->selectedPage()); - }); + connect(pageCast(page), &InstallJavaPage::selectionChanged, this, [this] { validate(); }); } - connect(container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* current) { validate(current); }); + connect(container, &PageContainer::selectedPageChanged, this, [this] { validate(); }); pageCast(container->selectedPage())->selectSearch(); - validate(container->selectedPage()); + validate(); } QList InstallDialog::getPages() @@ -198,9 +196,10 @@ QString InstallDialog::dialogTitle() return tr("Install Java"); } -void InstallDialog::validate(BasePage* page) +void InstallDialog::validate() { - buttons->button(QDialogButtonBox::Ok)->setEnabled(pageCast(page)->selectedVersion() != nullptr); + buttons->button(QDialogButtonBox::Ok) + ->setEnabled(!!std::dynamic_pointer_cast(pageCast(container->selectedPage())->selectedVersion())); } void InstallDialog::done(int result) diff --git a/launcher/ui/java/InstallJavaDialog.h b/launcher/ui/java/InstallJavaDialog.h index 525e750aa7..80d010c1a0 100644 --- a/launcher/ui/java/InstallJavaDialog.h +++ b/launcher/ui/java/InstallJavaDialog.h @@ -36,7 +36,7 @@ class InstallDialog final : public QDialog, private BasePageProvider { QList getPages() override; QString dialogTitle() override; - void validate(BasePage* page); + void validate(); void done(int result) override; private: From 8d3e6667cdb51c4018604313629bd57744bca8aa Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 15:09:49 +0300 Subject: [PATCH 76/83] fix java download tasks Signed-off-by: Trial97 --- .../java/download/ArchiveDownloadTask.cpp | 42 +++++++++--------- launcher/java/download/ArchiveDownloadTask.h | 2 + .../java/download/ManifestDownloadTask.cpp | 44 ++++++++++--------- launcher/java/download/ManifestDownloadTask.h | 2 + 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 3588606104..5aed70ede8 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -50,21 +50,17 @@ void ArchiveDownloadTask::executeTask() download->addNetAction(action); auto fullPath = entry->getFullPath(); - connect(download.get(), &NetJob::finished, [download, this] { - disconnect(this, &Task::aborted, download.get(), &NetJob::abort); - download->deleteLater(); - }); - connect(download.get(), &NetJob::failed, this, &ArchiveDownloadTask::emitFailed); - connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &Task::failed, this, &ArchiveDownloadTask::emitFailed); connect(download.get(), &Task::progress, this, &ArchiveDownloadTask::setProgress); connect(download.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); connect(download.get(), &Task::status, this, &ArchiveDownloadTask::setStatus); connect(download.get(), &Task::details, this, &ArchiveDownloadTask::setDetails); - connect(download.get(), &NetJob::succeeded, [this, fullPath] { + connect(download.get(), &Task::succeeded, [this, fullPath] { // This should do all of the extracting and creating folders extractJava(fullPath); }); - download->start(); + m_task = download; + m_task->start(); } void ArchiveDownloadTask::extractJava(QString input) @@ -102,34 +98,40 @@ void ArchiveDownloadTask::extractJava(QString input) emitFailed("Empty archive"); return; } - auto zipTask = makeShared(zip, m_final_path, files[0]); + m_task = makeShared(zip, m_final_path, files[0]); auto progressStep = std::make_shared(); - connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + connect(m_task.get(), &Task::finished, this, [this, progressStep] { progressStep->state = TaskStepState::Succeeded; stepProgress(*progressStep); }); - connect(this, &Task::aborted, zipTask.get(), &Task::abort); - connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); }); - - connect(zipTask.get(), &Task::succeeded, this, &ArchiveDownloadTask::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, &ArchiveDownloadTask::emitAborted); - connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + connect(m_task.get(), &Task::succeeded, this, &ArchiveDownloadTask::emitSucceeded); + connect(m_task.get(), &Task::aborted, this, &ArchiveDownloadTask::emitAborted); + connect(m_task.get(), &Task::failed, this, [this, progressStep](QString reason) { progressStep->state = TaskStepState::Failed; stepProgress(*progressStep); emitFailed(reason); }); - connect(zipTask.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); + connect(m_task.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); - connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + connect(m_task.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); stepProgress(*progressStep); }); - connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + connect(m_task.get(), &Task::status, this, [this, progressStep](QString status) { progressStep->status = status; stepProgress(*progressStep); }); - zipTask->start(); + m_task->start(); } + +bool ArchiveDownloadTask::abort() +{ + auto aborted = canAbort(); + if (m_task) + aborted = m_task->abort(); + emitAborted(); + return aborted; +}; } // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ArchiveDownloadTask.h b/launcher/java/download/ArchiveDownloadTask.h index c656567fe1..1db33763ac 100644 --- a/launcher/java/download/ArchiveDownloadTask.h +++ b/launcher/java/download/ArchiveDownloadTask.h @@ -30,6 +30,7 @@ class ArchiveDownloadTask : public Task { [[nodiscard]] bool canAbort() const override { return true; } void executeTask() override; + virtual bool abort() override; private slots: void extractJava(QString input); @@ -39,5 +40,6 @@ class ArchiveDownloadTask : public Task { QString m_final_path; QString m_checksum_type; QString m_checksum_hash; + Task::Ptr m_task; }; } // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ManifestDownloadTask.cpp b/launcher/java/download/ManifestDownloadTask.cpp index 5551c75d56..1fcc6f1722 100644 --- a/launcher/java/download/ManifestDownloadTask.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -51,18 +51,13 @@ void ManifestDownloadTask::executeTask() } download->addNetAction(action); - connect(download.get(), &NetJob::finished, [download, this] { - disconnect(this, &Task::aborted, download.get(), &NetJob::abort); - download->deleteLater(); - }); - connect(download.get(), &NetJob::failed, this, &ManifestDownloadTask::emitFailed); - connect(this, &Task::aborted, download.get(), &NetJob::abort); + connect(download.get(), &Task::failed, this, &ManifestDownloadTask::emitFailed); connect(download.get(), &Task::progress, this, &ManifestDownloadTask::setProgress); connect(download.get(), &Task::stepProgress, this, &ManifestDownloadTask::propagateStepProgress); connect(download.get(), &Task::status, this, &ManifestDownloadTask::setStatus); connect(download.get(), &Task::details, this, &ManifestDownloadTask::setDetails); - connect(download.get(), &NetJob::succeeded, [files, this] { + connect(download.get(), &Task::succeeded, [files, this] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -73,7 +68,8 @@ void ManifestDownloadTask::executeTask() } downloadJava(doc); }); - download->start(); + m_task = download; + m_task->start(); } void ManifestDownloadTask::downloadJava(const QJsonDocument& doc) @@ -107,7 +103,7 @@ void ManifestDownloadTask::downloadJava(const QJsonDocument& doc) } } } - auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network()); + auto elementDownload = makeShared("JRE::FileDownload", APPLICATION->network()); for (const auto& file : toDownload) { auto dl = Net::Download::makeFile(file.url, file.path); if (!file.hash.isEmpty()) { @@ -119,18 +115,24 @@ void ManifestDownloadTask::downloadJava(const QJsonDocument& doc) } elementDownload->addNetAction(dl); } - connect(elementDownload, &NetJob::finished, [elementDownload, this] { - disconnect(this, &Task::aborted, elementDownload, &NetJob::abort); - elementDownload->deleteLater(); - }); - connect(elementDownload, &NetJob::failed, this, &ManifestDownloadTask::emitFailed); - connect(elementDownload, &Task::progress, this, &ManifestDownloadTask::setProgress); - connect(elementDownload, &Task::stepProgress, this, &ManifestDownloadTask::propagateStepProgress); - connect(elementDownload, &Task::status, this, &ManifestDownloadTask::setStatus); - connect(elementDownload, &Task::details, this, &ManifestDownloadTask::setDetails); - connect(this, &Task::aborted, elementDownload, &NetJob::abort); - connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); }); - elementDownload->start(); + connect(elementDownload.get(), &Task::failed, this, &ManifestDownloadTask::emitFailed); + connect(elementDownload.get(), &Task::progress, this, &ManifestDownloadTask::setProgress); + connect(elementDownload.get(), &Task::stepProgress, this, &ManifestDownloadTask::propagateStepProgress); + connect(elementDownload.get(), &Task::status, this, &ManifestDownloadTask::setStatus); + connect(elementDownload.get(), &Task::details, this, &ManifestDownloadTask::setDetails); + + connect(elementDownload.get(), &Task::succeeded, this, &ManifestDownloadTask::emitSucceeded); + m_task = elementDownload; + m_task->start(); } + +bool ManifestDownloadTask::abort() +{ + auto aborted = canAbort(); + if (m_task) + aborted = m_task->abort(); + emitAborted(); + return aborted; +}; } // namespace Java \ No newline at end of file diff --git a/launcher/java/download/ManifestDownloadTask.h b/launcher/java/download/ManifestDownloadTask.h index f0eaf95a61..ae9e0d0edc 100644 --- a/launcher/java/download/ManifestDownloadTask.h +++ b/launcher/java/download/ManifestDownloadTask.h @@ -31,6 +31,7 @@ class ManifestDownloadTask : public Task { [[nodiscard]] bool canAbort() const override { return true; } void executeTask() override; + virtual bool abort() override; private slots: void downloadJava(const QJsonDocument& doc); @@ -40,5 +41,6 @@ class ManifestDownloadTask : public Task { QString m_final_path; QString m_checksum_type; QString m_checksum_hash; + Task::Ptr m_task; }; } // namespace Java \ No newline at end of file From 2fb3e12492f7fd70f15fdaa6f8066e7420fdc01f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 17:54:13 +0300 Subject: [PATCH 77/83] fix auto java install Signed-off-by: Trial97 --- launcher/minecraft/LaunchProfile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/LaunchProfile.cpp b/launcher/minecraft/LaunchProfile.cpp index 77072472c2..4687988506 100644 --- a/launcher/minecraft/LaunchProfile.cpp +++ b/launcher/minecraft/LaunchProfile.cpp @@ -166,7 +166,8 @@ void LaunchProfile::applyCompatibleJavaMajors(QList& javaMajor) } void LaunchProfile::applyCompatibleJavaName(QString javaName) { - m_compatibleJavaName = javaName; + if (!javaName.isEmpty()) + m_compatibleJavaName = javaName; } void LaunchProfile::applyLibrary(LibraryPtr library, const RuntimeContext& runtimeContext) From 1a66db78a989603a675e82d9cb30d91a319dff83 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Tue, 25 Jun 2024 15:17:51 +0300 Subject: [PATCH 78/83] Apply text change suggestions from code review Co-authored-by: seth Signed-off-by: Alexandru Ionut Tripon --- launcher/java/download/ArchiveDownloadTask.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 5aed70ede8..71e78629b2 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -67,7 +67,7 @@ void ArchiveDownloadTask::extractJava(QString input) { setStatus(tr("Extracting java")); if (input.endsWith("tar")) { - setStatus(tr("Extracting java(the progress will not be reported for tar)")); + setStatus(tr("Extracting Java (Progress is not reported for tar archives)")); QFile in(input); if (!in.open(QFile::ReadOnly)) { emitFailed(tr("Unable to open supplied tar file.")); @@ -80,7 +80,7 @@ void ArchiveDownloadTask::extractJava(QString input) emitSucceeded(); return; } else if (input.endsWith("tar.gz") || input.endsWith("taz") || input.endsWith("tgz")) { - setStatus(tr("Extracting java(the progress will not be reported for tar)")); + setStatus(tr("Extracting Java (Progress is not reported for tar archives)")); if (!GZTar::extract(input, QDir(m_final_path).absolutePath())) { emitFailed(tr("Unable to extract supplied tar file.")); return; @@ -95,7 +95,7 @@ void ArchiveDownloadTask::extractJava(QString input) } auto files = zip->getFileNameList(); if (files.isEmpty()) { - emitFailed("Empty archive"); + emitFailed(tr("Empty archive")); return; } m_task = makeShared(zip, m_final_path, files[0]); From 52839774e64e488139ff7d3c8d9cf41ada43f947 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Tue, 25 Jun 2024 15:19:23 +0300 Subject: [PATCH 79/83] Apply suggestions from code review Co-authored-by: seth Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/widgets/JavaSettingsWidget.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index e16f650fcb..dbd81cdd25 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -180,7 +180,7 @@ void JavaSettingsWidget::initialize() if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { auto button = - CustomMessageBox::selectable(this, tr("Auto Java Download"), + CustomMessageBox::selectable(this, tr("Automatic Java Download"), tr("%1 can automatically download the correct Java version for each version of Minecraft..\n" "Do you want to enable Java auto-download?\n") .arg(BuildConfig.LAUNCHER_DISPLAYNAME), @@ -220,8 +220,8 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() int button = QMessageBox::No; if (m_result.mojangPlatform == "32" && maxHeapSize() > 2048) { button = CustomMessageBox::selectable( - this, tr("Java x32 detected"), - tr("You selected an 32-bit java, but allocated more than 2048MiB as maximum memory.\n" + this, tr("32-bit Java detected"), + tr("You selected a 32-bit installation of Java, but allocated more than 2048MiB as maximum memory.\n" "%1 will not be able to start Minecraft.\n" "Do you wish to proceed?" "\n\n" @@ -232,9 +232,9 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() } else { button = CustomMessageBox::selectable(this, tr("No Java version selected"), - tr("You didn't select a Java version or selected something that doesn't work.\n" + tr("You either didn't select a Java version or selected one that does not work.\n" "%1 will not be able to start Minecraft.\n" - "Do you wish to proceed without any Java?" + "Do you wish to proceed without a functional version of Java?" "\n\n" "You can change the Java version in the settings later.\n") .arg(BuildConfig.LAUNCHER_DISPLAYNAME), @@ -246,7 +246,7 @@ JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() case QMessageBox::Yes: return ValidationStatus::JavaBad; case QMessageBox::Help: - DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("java-wizzard"))); + DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("java-wizard"))); /* fallthrough */ case QMessageBox::No: /* fallthrough */ @@ -515,7 +515,7 @@ void JavaSettingsWidget::updateThresholds() m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value")); } else if (observedMaxMemory > 2048 && m_result.is_64bit) { iconName = "status-bad"; - m_labelMaxMemIcon->setToolTip(tr("Because you're using 32 bit Java, you're exceeding the maximum possible allocation.")); + m_labelMaxMemIcon->setToolTip(tr("You are exceeding the maximum allocation supported by 32-bit installations of Java.")); } else { iconName = "status-good"; m_labelMaxMemIcon->setToolTip(""); From 4e9e7212a614fe2169ba0a760b765ab944382e53 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Tue, 25 Jun 2024 15:22:30 +0300 Subject: [PATCH 80/83] Apply suggestions from code review Co-authored-by: seth Signed-off-by: Alexandru Ionut Tripon --- launcher/minecraft/launch/AutoInstallJava.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 95bfa1dec7..98e381f3b8 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -74,13 +74,13 @@ void AutoInstallJava::executeTask() auto java = std::dynamic_pointer_cast(javas->at(i)); if (java && packProfile->getProfile()->getCompatibleJavaMajors().contains(java->id.major())) { if (!java->is_64bit) { - emit logLine(tr("The automatic Java mechanism detected an x32 java."), MessageLevel::Info); + emit logLine(tr("The automatic Java mechanism detected a 32-bit installation of Java."), MessageLevel::Info); } setJavaPath(java->path); return; } } - emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible Java version was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); }); connect(m_current_task.get(), &Task::progress, this, &AutoInstallJava::setProgress); @@ -91,7 +91,7 @@ void AutoInstallJava::executeTask() return; } if (m_supported_arch.isEmpty()) { - emit logLine(tr("Your system(%1 %2) is not compatible with auto java download. Using the default java path.") + emit logLine(tr("Your system(%1 %2) is not compatible with automatic Java installation. Using the default Java path.") .arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), MessageLevel::Warning); emitSucceeded(); @@ -99,8 +99,8 @@ void AutoInstallJava::executeTask() } auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); if (wantedJavaName.isEmpty()) { - emit logLine(tr("Your meta informtation is old or doesn't have the information necesary to determine what java should be used. " - "Using the default java path."), + emit logLine(tr("Your meta information is out of date or doesn't have the information necessary to determine what installation of Java should be used. " + "Using the default Java path."), MessageLevel::Warning); emitSucceeded(); return; @@ -127,7 +127,7 @@ void AutoInstallJava::setJavaPath(QString path) auto settings = m_instance->settings(); settings->set("OverrideJavaLocation", true); settings->set("JavaPath", path); - emit logLine(tr("Compatible java found at: %1.").arg(path), MessageLevel::Info); + emit logLine(tr("Compatible Java found at: %1.").arg(path), MessageLevel::Info); emitSucceeded(); } @@ -148,7 +148,7 @@ void AutoInstallJava::setJavaPathFromPartial() if (QFileInfo::exists(finalPath)) { setJavaPath(finalPath); } else { - emit logLine(tr("No compatible java version was found(the binary file doesn't exists). Using the default one."), + emit logLine(tr("No compatible Java version was found (the binary file does not exist). Using the default one."), MessageLevel::Warning); emitSucceeded(); } @@ -201,9 +201,9 @@ void AutoInstallJava::tryNextMajorJava() auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); auto majorJavaVersions = packProfile->getProfile()->getCompatibleJavaMajors(); if (m_majorJavaVersionIndex >= majorJavaVersions.length()) { - emit logLine(tr("No Java versions found for your operating system: %1 %2").arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), + emit logLine(tr("No versions of Java were found for your operating system: %1-%2").arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), MessageLevel::Warning); - emit logLine(tr("No compatible java version was found. Using the default one."), MessageLevel::Warning); + emit logLine(tr("No compatible version of Java was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); return; } From 555c4a7c59f4f09810615ecd5152b48a6fa73d51 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Tue, 25 Jun 2024 15:33:11 +0300 Subject: [PATCH 81/83] Apply suggestions from code review Co-authored-by: seth Signed-off-by: Alexandru Ionut Tripon --- launcher/java/download/ManifestDownloadTask.cpp | 2 +- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 +- launcher/ui/pages/global/JavaPage.cpp | 4 ++-- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/java/download/ManifestDownloadTask.cpp b/launcher/java/download/ManifestDownloadTask.cpp index 1fcc6f1722..836afeaac9 100644 --- a/launcher/java/download/ManifestDownloadTask.cpp +++ b/launcher/java/download/ManifestDownloadTask.cpp @@ -61,7 +61,7 @@ void ManifestDownloadTask::executeTask() QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << "Error while parsing JSON response at " << parse_error.offset << ". Reason: " << parse_error.errorString(); qWarning() << *files; emitFailed(parse_error.errorString()); return; diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 5f8b35b02c..1e74480897 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -56,7 +56,7 @@ void VerifyJavaInstall::executeTask() if (javaArchitecture == "32" && maxMemAlloc > 2048) { emit logLine(tr("Max memory allocation exceeds the supported value.\n" - "The selected java is 32-bit and doesn't support more than 2048MiB of RAM.\n" + "The selected installation of Java is 32-bit and doesn't support more than 2048MiB of RAM.\n" "The instance may not start due to this."), MessageLevel::Error); } diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index c8bbf6361b..ad37fa7408 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -161,8 +161,8 @@ void JavaPage::on_javaDetectBtn_clicked() ui->javaPathTextBox->setText(java->path); if (!java->is_64bit && APPLICATION->settings()->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), - tr("You selected a 32 bit java version.\n" - "This means that will not support more than 2048MiB of RAM.\n" + tr("You selected a 32-bit version of Java.\n" + "This installation does not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) ->exec(); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index fa52f2c51c..6e6b1db57b 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -418,8 +418,8 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() if (!java->is_64bit && m_settings->get("MaxMemAlloc").toInt() > 2048) { CustomMessageBox::selectable(this, tr("Confirm Selection"), - tr("You selected a 32 bit java version.\n" - "This means that will not support more than 2048MiB of RAM.\n" + tr("You selected a 32-bit version of Java.\n" + "This installation does not support more than 2048MiB of RAM.\n" "Please make sure that the maximum memory value is lower."), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) ->exec(); From 7c38edc93dda3fe4f177cb182314870e314367d8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 25 Jun 2024 16:10:05 +0300 Subject: [PATCH 82/83] Apply suggestion from code review Signed-off-by: Trial97 --- launcher/java/JavaMetadata.cpp | 10 ++- launcher/java/JavaMetadata.h | 2 +- launcher/java/JavaUtils.cpp | 21 +++--- launcher/java/JavaUtils.h | 1 + .../java/download/ArchiveDownloadTask.cpp | 71 ++++++++++--------- launcher/minecraft/launch/AutoInstallJava.cpp | 20 +++--- launcher/ui/java/InstallJavaDialog.cpp | 6 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 11 +-- 8 files changed, 75 insertions(+), 67 deletions(-) diff --git a/launcher/java/JavaMetadata.cpp b/launcher/java/JavaMetadata.cpp index 2272470a8e..2d68f55c8c 100644 --- a/launcher/java/JavaMetadata.cpp +++ b/launcher/java/JavaMetadata.cpp @@ -31,8 +31,10 @@ DownloadType parseDownloadType(QString javaDownload) { if (javaDownload == "manifest") return DownloadType::Manifest; - // if (javaDownload == "archive") - return DownloadType::Archive; + else if (javaDownload == "archive") + return DownloadType::Archive; + else + return DownloadType::Unknown; } QString downloadTypeToString(DownloadType javaDownload) { @@ -41,8 +43,10 @@ QString downloadTypeToString(DownloadType javaDownload) return "manifest"; case DownloadType::Archive: return "archive"; + case DownloadType::Unknown: + break; } - return ""; + return "unknown"; } MetadataPtr parseJavaMeta(const QJsonObject& in) { diff --git a/launcher/java/JavaMetadata.h b/launcher/java/JavaMetadata.h index 5281f2e27c..77a42fd78f 100644 --- a/launcher/java/JavaMetadata.h +++ b/launcher/java/JavaMetadata.h @@ -28,7 +28,7 @@ namespace Java { -enum class DownloadType { Manifest, Archive }; +enum class DownloadType { Manifest, Archive, Unknown }; class Metadata : public BaseVersion { public: diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 42d3ef6ab1..c0f64ad377 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -463,12 +463,10 @@ QString JavaUtils::getJavaCheckPath() QStringList getMinecraftJavaBundle() { - QString executable = "java"; QStringList processpaths; #if defined(Q_OS_OSX) processpaths << FS::PathCombine(QDir::homePath(), FS::PathCombine("Library", "Application Support", "minecraft", "runtime")); #elif defined(Q_OS_WIN32) - executable += "w.exe"; auto appDataPath = QProcessEnvironment::systemEnvironment().value("APPDATA", ""); processpaths << FS::PathCombine(QFileInfo(appDataPath).absoluteFilePath(), ".minecraft", "runtime"); @@ -493,7 +491,7 @@ QStringList getMinecraftJavaBundle() auto binFound = false; for (auto& entry : entries) { if (entry.baseName() == "bin") { - javas.append(FS::PathCombine(entry.canonicalFilePath(), executable)); + javas.append(FS::PathCombine(entry.canonicalFilePath(), JavaUtils::javaExecutable)); binFound = true; break; } @@ -507,19 +505,20 @@ QStringList getMinecraftJavaBundle() return javas; } +#if defined(Q_OS_WIN32) +const QString JavaUtils::javaExecutable = "javaw.exe"; +#else +const QString JavaUtils::javaExecutable = "java"; +#endif + QStringList getPrismJavaBundle() { QList javas; - QString executable = "java"; -#if defined(Q_OS_WIN32) - executable += "w.exe"; -#endif - auto scanDir = [&](QString prefix) { - javas.append(FS::PathCombine(prefix, "jre", "bin", executable)); - javas.append(FS::PathCombine(prefix, "bin", executable)); - javas.append(FS::PathCombine(prefix, executable)); + javas.append(FS::PathCombine(prefix, "jre", "bin", JavaUtils::javaExecutable)); + javas.append(FS::PathCombine(prefix, "bin", JavaUtils::javaExecutable)); + javas.append(FS::PathCombine(prefix, JavaUtils::javaExecutable)); }; auto scanJavaDir = [&](const QString& dirPath) { QDir dir(dirPath); diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index aa5315a194..eb3a17316b 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -42,4 +42,5 @@ class JavaUtils : public QObject { #endif static QString getJavaCheckPath(); + static const QString javaExecutable; }; diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index 71e78629b2..af5381dfc4 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -87,43 +87,46 @@ void ArchiveDownloadTask::extractJava(QString input) } emitSucceeded(); return; - } - auto zip = std::make_shared(input); - if (!zip->open(QuaZip::mdUnzip)) { - emitFailed(tr("Unable to open supplied zip file.")); - return; - } - auto files = zip->getFileNameList(); - if (files.isEmpty()) { - emitFailed(tr("Empty archive")); - return; - } - m_task = makeShared(zip, m_final_path, files[0]); + } else if (input.endsWith("zip")) { + auto zip = std::make_shared(input); + if (!zip->open(QuaZip::mdUnzip)) { + emitFailed(tr("Unable to open supplied zip file.")); + return; + } + auto files = zip->getFileNameList(); + if (files.isEmpty()) { + emitFailed(tr("No files were found in the supplied zip file,")); + return; + } + m_task = makeShared(zip, m_final_path, files[0]); - auto progressStep = std::make_shared(); - connect(m_task.get(), &Task::finished, this, [this, progressStep] { - progressStep->state = TaskStepState::Succeeded; - stepProgress(*progressStep); - }); + auto progressStep = std::make_shared(); + connect(m_task.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); + }); - connect(m_task.get(), &Task::succeeded, this, &ArchiveDownloadTask::emitSucceeded); - connect(m_task.get(), &Task::aborted, this, &ArchiveDownloadTask::emitAborted); - connect(m_task.get(), &Task::failed, this, [this, progressStep](QString reason) { - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - emitFailed(reason); - }); - connect(m_task.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); + connect(m_task.get(), &Task::succeeded, this, &ArchiveDownloadTask::emitSucceeded); + connect(m_task.get(), &Task::aborted, this, &ArchiveDownloadTask::emitAborted); + connect(m_task.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); + }); + connect(m_task.get(), &Task::stepProgress, this, &ArchiveDownloadTask::propagateStepProgress); - connect(m_task.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { - progressStep->update(current, total); - stepProgress(*progressStep); - }); - connect(m_task.get(), &Task::status, this, [this, progressStep](QString status) { - progressStep->status = status; - stepProgress(*progressStep); - }); - m_task->start(); + connect(m_task.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(m_task.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + m_task->start(); + } + + emitFailed(tr("Could not determine archive type!")); } bool ArchiveDownloadTask::abort() diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index 98e381f3b8..c77b9b1052 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -44,6 +44,7 @@ #include "SysInfo.h" #include "java/JavaInstall.h" #include "java/JavaInstallList.h" +#include "java/JavaUtils.h" #include "java/JavaVersion.h" #include "java/download/ArchiveDownloadTask.h" #include "java/download/ManifestDownloadTask.h" @@ -91,7 +92,7 @@ void AutoInstallJava::executeTask() return; } if (m_supported_arch.isEmpty()) { - emit logLine(tr("Your system(%1 %2) is not compatible with automatic Java installation. Using the default Java path.") + emit logLine(tr("Your system (%1-%2) is not compatible with automatic Java installation. Using the default Java path.") .arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), MessageLevel::Warning); emitSucceeded(); @@ -99,7 +100,8 @@ void AutoInstallJava::executeTask() } auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); if (wantedJavaName.isEmpty()) { - emit logLine(tr("Your meta information is out of date or doesn't have the information necessary to determine what installation of Java should be used. " + emit logLine(tr("Your meta information is out of date or doesn't have the information necessary to determine what installation of " + "Java should be used. " "Using the default Java path."), MessageLevel::Warning); emitSucceeded(); @@ -133,17 +135,13 @@ void AutoInstallJava::setJavaPath(QString path) void AutoInstallJava::setJavaPathFromPartial() { - QString executable = "java"; -#if defined(Q_OS_WIN32) - executable += "w.exe"; -#endif auto packProfile = m_instance->getPackProfile(); auto javaName = packProfile->getProfile()->getCompatibleJavaName(); QDir javaDir(APPLICATION->javaPath()); // just checking if the executable is there should suffice // but if needed this can be achieved through refreshing the javalist // and retrieving the path that contains the java name - auto relativeBinary = FS::PathCombine(javaName, "bin", executable); + auto relativeBinary = FS::PathCombine(javaName, "bin", JavaUtils::javaExecutable); auto finalPath = javaDir.absoluteFilePath(relativeBinary); if (QFileInfo::exists(finalPath)) { setJavaPath(finalPath); @@ -169,6 +167,9 @@ void AutoInstallJava::downloadJava(Meta::Version::Ptr version, QString javaName) case Java::DownloadType::Archive: m_current_task = makeShared(java->url, final_path, java->checksumType, java->checksumHash); break; + case Java::DownloadType::Unknown: + emitFailed(tr("Could not determine Java download type!")); + return; } auto deletePath = [final_path] { FS::deletePath(final_path); }; connect(m_current_task.get(), &Task::failed, this, [this, deletePath](QString reason) { @@ -201,8 +202,9 @@ void AutoInstallJava::tryNextMajorJava() auto wantedJavaName = packProfile->getProfile()->getCompatibleJavaName(); auto majorJavaVersions = packProfile->getProfile()->getCompatibleJavaMajors(); if (m_majorJavaVersionIndex >= majorJavaVersions.length()) { - emit logLine(tr("No versions of Java were found for your operating system: %1-%2").arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), - MessageLevel::Warning); + emit logLine( + tr("No versions of Java were found for your operating system: %1-%2").arg(SysInfo::currentSystem(), SysInfo::useQTForArch()), + MessageLevel::Warning); emit logLine(tr("No compatible version of Java was found. Using the default one."), MessageLevel::Warning); emitSucceeded(); return; diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index d924022362..1a4b4cc588 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -211,6 +211,7 @@ void InstallDialog::done(int result) if (meta) { Task::Ptr task; auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name); + auto deletePath = [final_path] { FS::deletePath(final_path); }; switch (meta->downloadType) { case Java::DownloadType::Manifest: task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); @@ -218,8 +219,11 @@ void InstallDialog::done(int result) case Java::DownloadType::Archive: task = makeShared(meta->url, final_path, meta->checksumType, meta->checksumHash); break; + case Java::DownloadType::Unknown: + QString error = QString(tr("Could not determine Java download type!")); + CustomMessageBox::selectable(this, tr("Error"), error, QMessageBox::Warning)->show(); + deletePath(); } - auto deletePath = [final_path] { FS::deletePath(final_path); }; connect(task.get(), &Task::failed, this, [this, &deletePath](QString reason) { QString error = QString("Java download failed: %1").arg(reason); CustomMessageBox::selectable(this, tr("Error"), error, QMessageBox::Warning)->show(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index dbd81cdd25..ec1ed0605c 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -339,17 +339,12 @@ void JavaSettingsWidget::javaVersionSelected(BaseVersion::Ptr version) void JavaSettingsWidget::on_javaBrowseBtn_clicked() { - QString filter; -#if defined Q_OS_WIN32 - filter = "Java (javaw.exe)"; -#else - filter = "Java (java)"; -#endif - QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter); + auto filter = QString("Java (%1)").arg(JavaUtils::javaExecutable); + auto raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter); if (raw_path.isEmpty()) { return; } - QString cooked_path = FS::NormalizePath(raw_path); + auto cooked_path = FS::NormalizePath(raw_path); m_javaPathTextBox->setText(cooked_path); checkJavaPath(cooked_path); } From 4ad19cded588dba201f3d1cdc2db248694a6101d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 28 Jun 2024 20:45:54 +0300 Subject: [PATCH 83/83] format Signed-off-by: Trial97 --- launcher/minecraft/launch/AutoInstallJava.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/launch/AutoInstallJava.cpp b/launcher/minecraft/launch/AutoInstallJava.cpp index c77b9b1052..eefed9cf55 100644 --- a/launcher/minecraft/launch/AutoInstallJava.cpp +++ b/launcher/minecraft/launch/AutoInstallJava.cpp @@ -56,7 +56,7 @@ AutoInstallJava::AutoInstallJava(LaunchTask* parent) : LaunchStep(parent) , m_instance(std::dynamic_pointer_cast(m_parent->instance())) - , m_supported_arch(SysInfo::getSupportedJavaArchitecture()){}; + , m_supported_arch(SysInfo::getSupportedJavaArchitecture()) {}; void AutoInstallJava::executeTask() {