launcher/install-java.cpp

173 lines
5.5 KiB
C++

#include "install-java.h"
#include "network-downloader.h"
QString checkDirHash(QString path) {
QCryptographicHash hash(QCryptographicHash::Sha256);
QDir dir(path);
if (!dir.exists()) {
qDebug() << "Directory not exists:" << path;
return QString();
}
QFileInfoList fileList = dir.entryInfoList(
QDir::Files | QDir::NoSymLinks | QDir::AllDirs | QDir::NoDotAndDotDot,
QDir::Name | QDir::DirsFirst
);
for (const QFileInfo &info : fileList) {
if (info.isDir()) {
QString subHash = checkDirHash(info.absoluteFilePath());
hash.addData(subHash.toUtf8());
} else if (info.isFile()) {
QFile file(info.absoluteFilePath());
if (file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
QByteArray chunk = file.read(8192);
hash.addData(chunk);
}
file.close();
}
}
}
return QString(hash.result().toHex());
}
bool checkJava () {
QString JAVA_HASH = "null";
#if defined(Q_OS_WIN)
#if defined(Q_PROCESSOR_X86_64)
//JAVA_HASH = "null";
#elif defined(Q_PROCESSOR_ARM_64)
//JAVA_HASH = "null";
#endif
#elif defined(Q_OS_LINUX)
#if defined(Q_PROCESSOR_X86_64)
//JAVA_HASH = "6268e94a0d6f37390fd33325725eb2991f9b26eb739baf2506064bfe3ea33075";
#elif defined(Q_PROCESSOR_ARM_64)
#else
//JAVA_HASH = "null";
#endif
#endif
QString hash = checkDirHash("./java");
if (JAVA_HASH == "null" || hash != JAVA_HASH)
qDebug() << "Java hash:" << hash;
return hash == JAVA_HASH;
}
void installJava(std::function<void(QString)> logCallback = nullptr) {
// Detect OS and architecture
QString javaUrl;
QString archiveType = "zip";
#if defined(Q_OS_WIN)
#if defined(Q_PROCESSOR_X86_64)
javaUrl = "https://example.com/java-windows-x64.zip";
#elif defined(Q_PROCESSOR_X86)
javaUrl = "https://example.com/java-windows-x86.zip";
#else
if (logCallback) logCallback("Unsupported Windows architecture");
return;
#endif
#elif defined(Q_OS_LINUX)
#if defined(Q_PROCESSOR_X86_64)
javaUrl = "";
archiveType = "tar.gz";
#elif defined(Q_PROCESSOR_ARM_64)
javaUrl = "";
archiveType = "tar.gz";
#else
if (logCallback) logCallback("Unsupported Linux architecture");
return;
#endif
#elif defined(Q_OS_MACOS)
#if defined(Q_PROCESSOR_X86_64)
javaUrl = "https://example.com/java-macos-x64.tar.gz";
#elif defined(Q_PROCESSOR_ARM_64)
javaUrl = "https://example.com/java-macos-arm64.tar.gz";
#else
if (logCallback) logCallback("Unsupported macOS architecture");
return;
#endif
#else
if (logCallback) logCallback("Unsupported OS");
return;
#endif
if (logCallback) logCallback("Creating directories...");
QDir tempDir("./temp");
if (!tempDir.exists()) tempDir.mkpath(".");
QDir javaDir("./java");
if (!javaDir.exists()) javaDir.mkpath(".");
QString archivePath = tempDir.filePath(QFileInfo(QUrl(javaUrl).path()).fileName());
// Download archive
downloadFromUrl(javaUrl, archivePath, logCallback);
// Extract archive
if (logCallback) logCallback("Extracting Java archive...");
#if defined(Q_OS_WIN)
// Unzip and move contents up one level
QProcess proc;
QString tempExtractDir = "./temp/java_extract";
QDir().mkpath(tempExtractDir);
proc.start("powershell", {"-Command", QString("Expand-Archive -Force -Path '%1' -DestinationPath '%2'").arg(archivePath).arg(tempExtractDir)});
proc.waitForFinished(-1);
// Move contents from subfolder to ./java
QDir extracted(tempExtractDir);
QStringList entries = extracted.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
for (const QString &e : entries) {
QString srcPath = extracted.filePath(e);
QString dstPath = javaDir.filePath(e);
if (!QFile::rename(srcPath, dstPath)) {
QDir srcDir(srcPath);
srcDir.rename(srcPath, dstPath);
}
}
QDir(tempExtractDir).removeRecursively();
#elif defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
// Extract to temp folder first
QString tempExtractDir = "./temp/java_extract";
QDir().mkpath(tempExtractDir);
QProcess proc;
if (archiveType == "tar.gz") {
proc.start("tar", {"-xzf", archivePath, "-C", tempExtractDir});
} else if (archiveType == "zip") {
proc.start("unzip", {archivePath, "-d", tempExtractDir});
} else {
if (logCallback) logCallback("Unknown archive format");
return;
}
proc.waitForFinished(-1);
// Move contents of the inner folder to ./java
QDir extracted(tempExtractDir);
QStringList folders = extracted.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
QString rootFolder = folders.isEmpty() ? "" : folders.first();
QDir rootDir(tempExtractDir + "/" + rootFolder);
QStringList items = rootDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
for (const QString &item : items) {
QString src = rootDir.filePath(item);
QString dst = javaDir.filePath(item);
QFile::rename(src, dst);
}
QDir(tempExtractDir).removeRecursively();
#endif
if (logCallback) logCallback("Extraction complete.");
// Check hash
QString hash = checkDirHash("./java");
if (logCallback) logCallback("Java installation hash: " + hash);
}