diff options
Diffstat (limited to 'api/logic')
33 files changed, 437 insertions, 60 deletions
diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp index cff16631..46b45827 100644 --- a/api/logic/BaseInstance.cpp +++ b/api/logic/BaseInstance.cpp @@ -37,6 +37,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("notes", ""); m_settings->registerSetting("lastLaunchTime", 0); m_settings->registerSetting("totalTimePlayed", 0); + m_settings->registerSetting("lastTimePlayed", 0); // Custom Commands auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); @@ -146,9 +147,12 @@ void BaseInstance::setRunning(bool running) } else { - qint64 current = settings()->get("totalTimePlayed").toLongLong(); QDateTime timeEnded = QDateTime::currentDateTime(); + + qint64 current = settings()->get("totalTimePlayed").toLongLong(); settings()->set("totalTimePlayed", current + m_timeStarted.secsTo(timeEnded)); + settings()->set("lastTimePlayed", m_timeStarted.secsTo(timeEnded)); + emit propertiesChanged(this); } @@ -166,9 +170,20 @@ int64_t BaseInstance::totalTimePlayed() const return current; } +int64_t BaseInstance::lastTimePlayed() const +{ + if(m_isRunning) + { + QDateTime timeNow = QDateTime::currentDateTime(); + return m_timeStarted.secsTo(timeNow); + } + return settings()->get("lastTimePlayed").toLongLong(); +} + void BaseInstance::resetTimePlayed() { settings()->reset("totalTimePlayed"); + settings()->reset("lastTimePlayed"); } QString BaseInstance::instanceType() const diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h index 64de4bb3..d250e03e 100644 --- a/api/logic/BaseInstance.h +++ b/api/logic/BaseInstance.h @@ -87,6 +87,7 @@ public: void setRunning(bool running); bool isRunning() const; int64_t totalTimePlayed() const; + int64_t lastTimePlayed() const; void resetTimePlayed(); /// get the type of this instance diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index c3322955..6d269714 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -246,6 +246,8 @@ set(MINECRAFT_SOURCES minecraft/launch/ReconstructAssets.h minecraft/launch/ScanModFolders.cpp minecraft/launch/ScanModFolders.h + minecraft/launch/VerifyJavaInstall.cpp + minecraft/launch/VerifyJavaInstall.h minecraft/legacy/LegacyModList.h minecraft/legacy/LegacyModList.cpp @@ -302,6 +304,10 @@ set(MINECRAFT_SOURCES minecraft/mod/ModFolderLoadTask.cpp minecraft/mod/LocalModParseTask.h minecraft/mod/LocalModParseTask.cpp + minecraft/mod/ResourcePackFolderModel.h + minecraft/mod/ResourcePackFolderModel.cpp + minecraft/mod/TexturePackFolderModel.h + minecraft/mod/TexturePackFolderModel.cpp # Assets minecraft/AssetsUtils.h diff --git a/api/logic/java/JavaUtils.cpp b/api/logic/java/JavaUtils.cpp index 18a731ca..4b231e6a 100644 --- a/api/logic/java/JavaUtils.cpp +++ b/api/logic/java/JavaUtils.cpp @@ -150,7 +150,7 @@ JavaInstallPtr JavaUtils::GetDefaultJava() } #if defined(Q_OS_WIN32) -QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName) +QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName, QString keyJavaDir, QString subkeySuffix) { QList<JavaInstallPtr> javas; @@ -175,8 +175,6 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz); } - QString recommended = value; - TCHAR subKeyName[255]; DWORD subKeyNameSize, numSubKeys, retCode; @@ -195,7 +193,7 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString if (retCode == ERROR_SUCCESS) { // Now open the registry key for the version that we just got. - QString newKeyName = keyName + "\\" + subKeyName; + QString newKeyName = keyName + "\\" + subKeyName + subkeySuffix; HKEY newKey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0, @@ -204,11 +202,11 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString // Read the JavaHome value to find where Java is installed. value = new char[0]; valueSz = 0; - if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value, + if (RegQueryValueEx(newKey, keyJavaDir.toStdString().c_str(), NULL, NULL, (BYTE *)value, &valueSz) == ERROR_MORE_DATA) { value = new char[valueSz]; - RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value, + RegQueryValueEx(newKey, keyJavaDir.toStdString().c_str(), NULL, NULL, (BYTE *)value, &valueSz); // Now, we construct the version object and add it to the list. @@ -237,37 +235,78 @@ QList<QString> JavaUtils::FindJavaPaths() { QList<JavaInstallPtr> java_candidates; + // Oracle QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); - QList<JavaInstallPtr> NEWJRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE"); - QList<JavaInstallPtr> NEWJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK"); + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); + + // Oracle for Java 9 and newer + QList<JavaInstallPtr> NEWJRE64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); + QList<JavaInstallPtr> NEWJDK64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); QList<JavaInstallPtr> NEWJRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE"); + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); QList<JavaInstallPtr> NEWJDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK"); - + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); + + // AdoptOpenJDK + QList<JavaInstallPtr> ADOPTOPENJRE32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); + QList<JavaInstallPtr> ADOPTOPENJRE64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); + QList<JavaInstallPtr> ADOPTOPENJDK32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); + QList<JavaInstallPtr> ADOPTOPENJDK64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); + + // Microsoft + QList<JavaInstallPtr> MICROSOFTJDK64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI"); + + // Azul Zulu + QList<JavaInstallPtr> ZULU64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); + QList<JavaInstallPtr> ZULU32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); + + // BellSoft Liberica + QList<JavaInstallPtr> LIBERICA64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); + QList<JavaInstallPtr> LIBERICA32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); + + // List x64 before x86 java_candidates.append(JRE64s); java_candidates.append(NEWJRE64s); + java_candidates.append(ADOPTOPENJRE64s); java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre8/bin/javaw.exe")); java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/javaw.exe")); java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/javaw.exe")); java_candidates.append(JDK64s); java_candidates.append(NEWJDK64s); + java_candidates.append(ADOPTOPENJDK64s); + java_candidates.append(MICROSOFTJDK64s); + java_candidates.append(ZULU64s); + java_candidates.append(LIBERICA64s); + java_candidates.append(JRE32s); java_candidates.append(NEWJRE32s); + java_candidates.append(ADOPTOPENJRE32s); java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre8/bin/javaw.exe")); java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/javaw.exe")); java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/javaw.exe")); java_candidates.append(JDK32s); java_candidates.append(NEWJDK32s); + java_candidates.append(ADOPTOPENJDK32s); + java_candidates.append(ZULU32s); + java_candidates.append(LIBERICA32s); + java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path)); QList<QString> candidates; @@ -342,6 +381,9 @@ QList<QString> JavaUtils::FindJavaPaths() scanJavaDir("/usr/lib32/jvm"); // javas stored in MultiMC's folder scanJavaDir("java"); + // manually installed JDKs in /opt + scanJavaDir("/opt/jdk"); + scanJavaDir("/opt/jdks"); return javas; } #else diff --git a/api/logic/java/JavaUtils.h b/api/logic/java/JavaUtils.h index 7474c494..206acf89 100644 --- a/api/logic/java/JavaUtils.h +++ b/api/logic/java/JavaUtils.h @@ -39,6 +39,6 @@ public: JavaInstallPtr GetDefaultJava(); #ifdef Q_OS_WIN - QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName); + QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName, QString keyJavaDir, QString subkeySuffix = ""); #endif }; diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index a1341e69..dbf9f816 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -23,12 +23,15 @@ #include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/ReconstructAssets.h" #include "minecraft/launch/ScanModFolders.h" +#include "minecraft/launch/VerifyJavaInstall.h" #include "java/launch/CheckJava.h" #include "java/JavaUtils.h" #include "meta/Index.h" #include "meta/VersionList.h" #include "mod/ModFolderModel.h" +#include "mod/ResourcePackFolderModel.h" +#include "mod/TexturePackFolderModel.h" #include "WorldList.h" #include "icons/IIconList.h" @@ -795,9 +798,15 @@ QString MinecraftInstance::getStatusbarDescription() QString description; description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName())); - if(m_settings->get("ShowGameTime").toBool() && totalTimePlayed() > 0) + if(m_settings->get("ShowGameTime").toBool()) { - description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed()))); + if (lastTimePlayed() > 0) { + description.append(tr(", last played for %1").arg(prettifyTimeDuration(lastTimePlayed()))); + } + + if (totalTimePlayed() > 0) { + description.append(tr(", total played for %1").arg(prettifyTimeDuration(totalTimePlayed()))); + } } if(hasCrashed()) { @@ -913,6 +922,11 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(new ReconstructAssets(pptr)); } + // verify that minimum Java requirements are met + { + process->appendStep(new VerifyJavaInstall(pptr)); + } + { // actually launch the game auto method = launchMethod(); @@ -986,7 +1000,7 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::resourcePackList() const { if (!m_resource_pack_list) { - m_resource_pack_list.reset(new ModFolderModel(resourcePacksDir())); + m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir())); m_resource_pack_list->disableInteraction(isRunning()); connect(this, &BaseInstance::runningStatusChanged, m_resource_pack_list.get(), &ModFolderModel::disableInteraction); } @@ -997,7 +1011,7 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::texturePackList() const { if (!m_texture_pack_list) { - m_texture_pack_list.reset(new ModFolderModel(texturePacksDir())); + m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir())); m_texture_pack_list->disableInteraction(isRunning()); connect(this, &BaseInstance::runningStatusChanged, m_texture_pack_list.get(), &ModFolderModel::disableInteraction); } diff --git a/api/logic/minecraft/VersionFilterData.cpp b/api/logic/minecraft/VersionFilterData.cpp index a47fc0a0..38e7b60c 100644 --- a/api/logic/minecraft/VersionFilterData.cpp +++ b/api/logic/minecraft/VersionFilterData.cpp @@ -65,4 +65,7 @@ VersionFilterData::VersionFilterData() QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform", "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl", "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"}; + + java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00"); + java16BeginsDate = timeFromS3Time("2021-05-12T11:19:15+00:00"); } diff --git a/api/logic/minecraft/VersionFilterData.h b/api/logic/minecraft/VersionFilterData.h index afd4502b..d100acc3 100644 --- a/api/logic/minecraft/VersionFilterData.h +++ b/api/logic/minecraft/VersionFilterData.h @@ -23,5 +23,9 @@ struct VersionFilterData QDateTime legacyCutoffDate; // Libraries that belong to LWJGL QSet<QString> lwjglWhitelist; + // release date of first version to require Java 8 (17w13a) + QDateTime java8BeginsDate; + // release data of first version to require Java 16 (21w19a) + QDateTime java16BeginsDate; }; extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData; diff --git a/api/logic/minecraft/launch/CreateGameFolders.cpp b/api/logic/minecraft/launch/CreateGameFolders.cpp index 415b7e23..4081e72e 100644 --- a/api/logic/minecraft/launch/CreateGameFolders.cpp +++ b/api/logic/minecraft/launch/CreateGameFolders.cpp @@ -15,7 +15,7 @@ void CreateGameFolders::executeTask() if(!FS::ensureFolderPathExists(minecraftInstance->gameRoot())) { emit logLine("Couldn't create the main game folder", MessageLevel::Error); - emitFailed("Couldn't create the main game folder"); + emitFailed(tr("Couldn't create the main game folder")); return; } diff --git a/api/logic/minecraft/launch/DirectJavaLaunch.cpp b/api/logic/minecraft/launch/DirectJavaLaunch.cpp index cf4564b6..2110384f 100644 --- a/api/logic/minecraft/launch/DirectJavaLaunch.cpp +++ b/api/logic/minecraft/launch/DirectJavaLaunch.cpp @@ -66,9 +66,9 @@ void DirectJavaLaunch::executeTask() auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); if (realWrapperCommand.isEmpty()) { - QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); + emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); + emitFailed(tr(reason).arg(wrapperCommand)); return; } emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC); @@ -87,18 +87,17 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) { case LoggedProcess::FailedToStart: { - //: Error message displayed if instace can't start - QString reason = tr("Could not launch minecraft!"); + //: Error message displayed if instance can't start + const char *reason = QT_TR_NOOP("Could not launch minecraft!"); emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + emitFailed(tr(reason)); return; } case LoggedProcess::Aborted: case LoggedProcess::Crashed: - { m_parent->setPid(-1); - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } case LoggedProcess::Finished: @@ -108,7 +107,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) auto exitCode = m_process.exitCode(); if(exitCode != 0) { - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } //FIXME: make this work again @@ -118,7 +117,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state) break; } case LoggedProcess::Running: - emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); + emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); m_parent->setPid(m_process.processId()); m_parent->instance()->setLastLaunch(); break; diff --git a/api/logic/minecraft/launch/ExtractNatives.cpp b/api/logic/minecraft/launch/ExtractNatives.cpp index d41cb8fd..d57499aa 100644 --- a/api/logic/minecraft/launch/ExtractNatives.cpp +++ b/api/logic/minecraft/launch/ExtractNatives.cpp @@ -94,9 +94,9 @@ void ExtractNatives::executeTask() { if(!unzipNatives(source, outputPath, jniHackEnabled, nativeOpenAL, nativeGLFW)) { - auto reason = tr("Couldn't extract native jar '%1' to destination '%2'").arg(source, outputPath); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("Couldn't extract native jar '%1' to destination '%2'"); + emit logLine(QString(reason).arg(source, outputPath), MessageLevel::Fatal); + emitFailed(tr(reason).arg(source, outputPath)); } } emitSucceeded(); diff --git a/api/logic/minecraft/launch/LauncherPartLaunch.cpp b/api/logic/minecraft/launch/LauncherPartLaunch.cpp index ab3b6d10..ee469770 100644 --- a/api/logic/minecraft/launch/LauncherPartLaunch.cpp +++ b/api/logic/minecraft/launch/LauncherPartLaunch.cpp @@ -118,9 +118,9 @@ void LauncherPartLaunch::executeTask() auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); if (realWrapperCommand.isEmpty()) { - QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); + emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); + emitFailed(tr(reason).arg(wrapperCommand)); return; } emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC); @@ -140,17 +140,16 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) case LoggedProcess::FailedToStart: { //: Error message displayed if instace can't start - QString reason = tr("Could not launch minecraft!"); + const char *reason = QT_TR_NOOP("Could not launch minecraft!"); emit logLine(reason, MessageLevel::Fatal); - emitFailed(reason); + emitFailed(tr(reason)); return; } case LoggedProcess::Aborted: case LoggedProcess::Crashed: - { m_parent->setPid(-1); - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } case LoggedProcess::Finished: @@ -160,7 +159,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) auto exitCode = m_process.exitCode(); if(exitCode != 0) { - emitFailed("Game crashed."); + emitFailed(tr("Game crashed.")); return; } //FIXME: make this work again @@ -170,7 +169,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) break; } case LoggedProcess::Running: - emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); + emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC); m_parent->setPid(m_process.processId()); m_parent->instance()->setLastLaunch(); // send the launch script to the launcher part diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.cpp b/api/logic/minecraft/launch/VerifyJavaInstall.cpp new file mode 100644 index 00000000..657669af --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.cpp @@ -0,0 +1,34 @@ +#include "VerifyJavaInstall.h" + +#include <launch/LaunchTask.h> +#include <minecraft/MinecraftInstance.h> +#include <minecraft/PackProfile.h> +#include <minecraft/VersionFilterData.h> + +void VerifyJavaInstall::executeTask() { + auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance()); + + auto javaVersion = m_inst->getJavaVersion(); + auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft"); + + // Java 16 requirement + if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) { + if (javaVersion.major() < 16) { + emit logLine("Minecraft 21w19a and above require the use of Java 16", + MessageLevel::Fatal); + emitFailed(tr("Minecraft 21w19a and above require the use of Java 16")); + return; + } + } + // Java 8 requirement + else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java8BeginsDate) { + if (javaVersion.major() < 8) { + emit logLine("Minecraft 17w13a and above require the use of Java 8", + MessageLevel::Fatal); + emitFailed(tr("Minecraft 17w13a and above require the use of Java 8")); + return; + } + } + + emitSucceeded(); +} diff --git a/api/logic/minecraft/launch/VerifyJavaInstall.h b/api/logic/minecraft/launch/VerifyJavaInstall.h new file mode 100644 index 00000000..a553106d --- /dev/null +++ b/api/logic/minecraft/launch/VerifyJavaInstall.h @@ -0,0 +1,17 @@ +#pragma once + +#include <launch/LaunchStep.h> + +class VerifyJavaInstall : public LaunchStep { + Q_OBJECT + +public: + explicit VerifyJavaInstall(LaunchTask *parent) : LaunchStep(parent) { + }; + ~VerifyJavaInstall() override = default; + + void executeTask() override; + bool canAbort() const override { + return false; + } +}; diff --git a/api/logic/minecraft/mod/ResourcePackFolderModel.cpp b/api/logic/minecraft/mod/ResourcePackFolderModel.cpp new file mode 100644 index 00000000..f3d7f566 --- /dev/null +++ b/api/logic/minecraft/mod/ResourcePackFolderModel.cpp @@ -0,0 +1,23 @@ +#include "ResourcePackFolderModel.h" + +ResourcePackFolderModel::ResourcePackFolderModel(const QString &dir) : ModFolderModel(dir) { +} + +QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role == Qt::ToolTipRole) { + switch (section) { + case ActiveColumn: + return tr("Is the resource pack enabled?"); + case NameColumn: + return tr("The name of the resource pack."); + case VersionColumn: + return tr("The version of the resource pack."); + case DateColumn: + return tr("The date and time this resource pack was last changed (or added)."); + default: + return QVariant(); + } + } + + return ModFolderModel::headerData(section, orientation, role); +} diff --git a/api/logic/minecraft/mod/ResourcePackFolderModel.h b/api/logic/minecraft/mod/ResourcePackFolderModel.h new file mode 100644 index 00000000..47eb4bb2 --- /dev/null +++ b/api/logic/minecraft/mod/ResourcePackFolderModel.h @@ -0,0 +1,13 @@ +#pragma once + +#include "ModFolderModel.h" + +class MULTIMC_LOGIC_EXPORT ResourcePackFolderModel : public ModFolderModel +{ + Q_OBJECT + +public: + explicit ResourcePackFolderModel(const QString &dir); + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; +}; diff --git a/api/logic/minecraft/mod/TexturePackFolderModel.cpp b/api/logic/minecraft/mod/TexturePackFolderModel.cpp new file mode 100644 index 00000000..d5956da1 --- /dev/null +++ b/api/logic/minecraft/mod/TexturePackFolderModel.cpp @@ -0,0 +1,23 @@ +#include "TexturePackFolderModel.h" + +TexturePackFolderModel::TexturePackFolderModel(const QString &dir) : ModFolderModel(dir) { +} + +QVariant TexturePackFolderModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role == Qt::ToolTipRole) { + switch (section) { + case ActiveColumn: + return tr("Is the texture pack enabled?"); + case NameColumn: + return tr("The name of the texture pack."); + case VersionColumn: + return tr("The version of the texture pack."); + case DateColumn: + return tr("The date and time this texture pack was last changed (or added)."); + default: + return QVariant(); + } + } + + return ModFolderModel::headerData(section, orientation, role); +} diff --git a/api/logic/minecraft/mod/TexturePackFolderModel.h b/api/logic/minecraft/mod/TexturePackFolderModel.h new file mode 100644 index 00000000..d773b17b --- /dev/null +++ b/api/logic/minecraft/mod/TexturePackFolderModel.h @@ -0,0 +1,13 @@ +#pragma once + +#include "ModFolderModel.h" + +class MULTIMC_LOGIC_EXPORT TexturePackFolderModel : public ModFolderModel +{ + Q_OBJECT + +public: + explicit TexturePackFolderModel(const QString &dir); + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; +}; diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp index 89c4dfd3..55087a27 100644 --- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -4,6 +4,7 @@ #include <MMCZip.h> #include <minecraft/OneSixVersionFormat.h> #include <Version.h> +#include <net/ChecksumValidator.h> #include "ATLPackInstallTask.h" #include "BuildConfig.h" @@ -27,7 +28,11 @@ PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString pack, bool PackInstallTask::abort() { - return true; + if(abortable) + { + return jobPtr->abort(); + } + return false; } void PackInstallTask::executeTask() @@ -407,21 +412,29 @@ void PackInstallTask::installConfigs() auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", path); entry->setStale(true); - jobPtr->addNetAction(Net::Download::makeCached(url, entry)); + auto dl = Net::Download::makeCached(url, entry); + if (!m_version.configs.sha1.isEmpty()) { + auto rawSha1 = QByteArray::fromHex(m_version.configs.sha1.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + } + jobPtr->addNetAction(dl); archivePath = entry->getFullPath(); connect(jobPtr.get(), &NetJob::succeeded, this, [&]() { + abortable = false; jobPtr.reset(); extractConfigs(); }); connect(jobPtr.get(), &NetJob::failed, [&](QString reason) { + abortable = false; jobPtr.reset(); emitFailed(reason); }); connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + abortable = true; setProgress(current, total); }); @@ -457,16 +470,31 @@ void PackInstallTask::extractConfigs() void PackInstallTask::downloadMods() { qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId(); + + QVector<ATLauncher::VersionMod> optionalMods; + for (const auto& mod : m_version.mods) { + if (mod.optional) { + optionalMods.push_back(mod); + } + } + + // Select optional mods, if pack contains any + QVector<QString> selectedMods; + if (!optionalMods.isEmpty()) { + setStatus(tr("Selecting optional mods...")); + selectedMods = m_support->chooseOptionalMods(optionalMods); + } + setStatus(tr("Downloading mods...")); jarmods.clear(); jobPtr.reset(new NetJob(tr("Mod download"))); for(const auto& mod : m_version.mods) { // skip non-client mods - if (!mod.client) continue; + if(!mod.client) continue; - // skip optional mods for now - if(mod.optional) continue; + // skip optional mods that were not selected + if(mod.optional && !selectedMods.contains(mod.name)) continue; QString url; switch(mod.download) { @@ -493,6 +521,10 @@ void PackInstallTask::downloadMods() modsToExtract.insert(entry->getFullPath(), mod); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); } else if(mod.type == ModType::Decomp) { @@ -501,6 +533,10 @@ void PackInstallTask::downloadMods() modsToDecomp.insert(entry->getFullPath(), mod); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); } else { @@ -511,6 +547,10 @@ void PackInstallTask::downloadMods() entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); + if (!mod.md5.isEmpty()) { + auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); + } jobPtr->addNetAction(dl); auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file); @@ -543,11 +583,13 @@ void PackInstallTask::downloadMods() connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded); connect(jobPtr.get(), &NetJob::failed, [&](QString reason) { + abortable = false; jobPtr.reset(); emitFailed(reason); }); connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + abortable = true; setProgress(current, total); }); @@ -555,6 +597,8 @@ void PackInstallTask::downloadMods() } void PackInstallTask::onModsDownloaded() { + abortable = false; + qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId(); jobPtr.reset(); diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h index 3647e471..15fd9b32 100644 --- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h +++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h @@ -19,6 +19,11 @@ class MULTIMC_LOGIC_EXPORT UserInteractionSupport { public: /** + * Requests a user interaction to select which optional mods should be installed. + */ + virtual QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) = 0; + + /** * Requests a user interaction to select a component version from a given version list * and constrained to a given Minecraft version. */ @@ -34,6 +39,7 @@ public: explicit PackInstallTask(UserInteractionSupport *support, QString pack, QString version); virtual ~PackInstallTask(){} + bool canAbort() const override { return true; } bool abort() override; protected: @@ -67,6 +73,8 @@ private: private: UserInteractionSupport *m_support; + bool abortable = false; + NetJobPtr jobPtr; QByteArray response; diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp index 57cc52b6..e25d8346 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp @@ -109,6 +109,11 @@ static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj p.server = Json::ensureString(obj, "server", ""); } +static void loadVersionConfigs(ATLauncher::VersionConfigs & p, QJsonObject & obj) { + p.filesize = Json::requireInteger(obj, "filesize"); + p.sha1 = Json::requireString(obj, "sha1"); +} + static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { p.name = Json::requireString(obj, "name"); p.version = Json::requireString(obj, "version"); @@ -143,8 +148,24 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { p.decompFile = Json::requireString(obj, "decompFile"); } + p.description = Json::ensureString(obj, QString("description"), ""); p.optional = Json::ensureBoolean(obj, QString("optional"), false); + p.recommended = Json::ensureBoolean(obj, QString("recommended"), false); + p.selected = Json::ensureBoolean(obj, QString("selected"), false); + p.hidden = Json::ensureBoolean(obj, QString("hidden"), false); + p.library = Json::ensureBoolean(obj, QString("library"), false); + p.group = Json::ensureString(obj, QString("group"), ""); + if(obj.contains("depends")) { + auto dependsArr = Json::requireArray(obj, "depends"); + for (const auto depends : dependsArr) { + p.depends.append(Json::requireString(depends)); + } + } + p.client = Json::ensureBoolean(obj, QString("client"), false); + + // computed + p.effectively_hidden = p.hidden || p.library; } void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) @@ -179,7 +200,6 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) } } - if(obj.contains("mods")) { auto mods = Json::requireArray(obj, "mods"); for (const auto modRaw : mods) @@ -190,4 +210,9 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) v.mods.append(mod); } } + + if(obj.contains("configs")) { + auto configsObj = Json::requireObject(obj, "configs"); + loadVersionConfigs(v.configs, configsObj); + } } diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h index 937106a5..17821e4c 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.h +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.h @@ -86,8 +86,25 @@ struct VersionMod QString decompType_raw; QString decompFile; + QString description; bool optional; + bool recommended; + bool selected; + bool hidden; + bool library; + QString group; + QVector<QString> depends; + bool client; + + // computed + bool effectively_hidden; +}; + +struct VersionConfigs +{ + int filesize; + QString sha1; }; struct PackVersion @@ -101,6 +118,7 @@ struct PackVersion VersionLoader loader; QVector<VersionLibrary> libraries; QVector<VersionMod> mods; + VersionConfigs configs; }; MULTIMC_LOGIC_EXPORT void loadVersion(PackVersion & v, QJsonObject & obj); diff --git a/api/logic/modplatform/legacy_ftb/PackInstallTask.h b/api/logic/modplatform/legacy_ftb/PackInstallTask.h index 7868d1c4..f3515781 100644 --- a/api/logic/modplatform/legacy_ftb/PackInstallTask.h +++ b/api/logic/modplatform/legacy_ftb/PackInstallTask.h @@ -20,6 +20,7 @@ public: explicit PackInstallTask(Modpack pack, QString version); virtual ~PackInstallTask(){} + bool canAbort() const override { return true; } bool abort() override; protected: diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp b/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp index ddc7fe35..f22373bc 100644 --- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -1,10 +1,12 @@ #include "FTBPackInstallTask.h" #include "BuildConfig.h" +#include "Env.h" #include "FileSystem.h" #include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "net/ChecksumValidator.h" #include "settings/INISettingsObject.h" namespace ModpacksCH { @@ -17,7 +19,11 @@ PackInstallTask::PackInstallTask(Modpack pack, QString version) bool PackInstallTask::abort() { - return true; + if(abortable) + { + return jobPtr->abort(); + } + return false; } void PackInstallTask::executeTask() @@ -93,26 +99,41 @@ void PackInstallTask::downloadPack() for(auto file : m_version.files) { if(file.serverOnly) continue; + QFileInfo fileName(file.name); + auto cacheName = fileName.completeBaseName() + "-" + file.sha1 + "." + fileName.suffix(); + + auto entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", cacheName); + entry->setStale(true); + auto relpath = FS::PathCombine("minecraft", file.path, file.name); auto path = FS::PathCombine(m_stagingPath, relpath); qDebug() << "Will download" << file.url << "to" << path; - auto dl = Net::Download::makeFile(file.url, path); + filesToCopy[entry->getFullPath()] = path; + + auto dl = Net::Download::makeCached(file.url, entry); + if (!file.sha1.isEmpty()) { + auto rawSha1 = QByteArray::fromHex(file.sha1.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + } jobPtr->addNetAction(dl); } connect(jobPtr.get(), &NetJob::succeeded, this, [&]() { + abortable = false; jobPtr.reset(); install(); }); connect(jobPtr.get(), &NetJob::failed, [&](QString reason) { + abortable = false; jobPtr.reset(); emitFailed(reason); }); connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + abortable = true; setProgress(current, total); }); @@ -121,6 +142,19 @@ void PackInstallTask::downloadPack() void PackInstallTask::install() { + setStatus(tr("Copying modpack files")); + + for (auto iter = filesToCopy.begin(); iter != filesToCopy.end(); iter++) { + auto &from = iter.key(); + auto &to = iter.value(); + FS::copy fileCopyOperation(from, to); + if(!fileCopyOperation()) { + qWarning() << "Failed to copy" << from << "to" << to; + emitFailed(tr("Failed to copy files")); + return; + } + } + setStatus(tr("Installing modpack")); auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h b/api/logic/modplatform/modpacksch/FTBPackInstallTask.h index 4f7786fd..55db3d3c 100644 --- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h +++ b/api/logic/modplatform/modpacksch/FTBPackInstallTask.h @@ -16,6 +16,7 @@ public: explicit PackInstallTask(Modpack pack, QString version); virtual ~PackInstallTask(){} + bool canAbort() const override { return true; } bool abort() override; protected: @@ -30,6 +31,8 @@ private: void install(); private: + bool abortable = false; + NetJobPtr jobPtr; QByteArray response; @@ -37,6 +40,8 @@ private: QString m_version_name; Version m_version; + QMap<QString, QString> filesToCopy; + }; } diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp index 96e1804d..dbce8e53 100644 --- a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp @@ -28,6 +28,14 @@ Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUr m_minecraftVersion = minecraftVersion; } +bool Technic::SingleZipPackInstallTask::abort() { + if(m_abortable) + { + return m_filesNetJob->abort(); + } + return false; +} + void Technic::SingleZipPackInstallTask::executeTask() { setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); @@ -47,6 +55,8 @@ void Technic::SingleZipPackInstallTask::executeTask() void Technic::SingleZipPackInstallTask::downloadSucceeded() { + m_abortable = false; + setStatus(tr("Extracting modpack")); QDir extractDir(FS::PathCombine(m_stagingPath, ".minecraft")); qDebug() << "Attempting to create instance from" << m_archivePath; @@ -67,12 +77,14 @@ void Technic::SingleZipPackInstallTask::downloadSucceeded() void Technic::SingleZipPackInstallTask::downloadFailed(QString reason) { + m_abortable = false; emitFailed(reason); m_filesNetJob.reset(); } void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current, qint64 total) { + m_abortable = true; setProgress(current / 2, total); } diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.h b/api/logic/modplatform/technic/SingleZipPackInstallTask.h index c56b9e46..ec2ff605 100644 --- a/api/logic/modplatform/technic/SingleZipPackInstallTask.h +++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.h @@ -36,6 +36,9 @@ class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask public: SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion); + bool canAbort() const override { return true; } + bool abort() override; + protected: void executeTask() override; @@ -48,6 +51,8 @@ private slots: void extractAborted(); private: + bool m_abortable = false; + QUrl m_sourceUrl; QString m_minecraftVersion; QString m_archivePath; diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.cpp b/api/logic/modplatform/technic/SolderPackInstallTask.cpp index 1d17073c..1b4186d4 100644 --- a/api/logic/modplatform/technic/SolderPackInstallTask.cpp +++ b/api/logic/modplatform/technic/SolderPackInstallTask.cpp @@ -27,6 +27,14 @@ Technic::SolderPackInstallTask::SolderPackInstallTask(const QUrl &sourceUrl, con m_minecraftVersion = minecraftVersion; } +bool Technic::SolderPackInstallTask::abort() { + if(m_abortable) + { + return m_filesNetJob->abort(); + } + return false; +} + void Technic::SolderPackInstallTask::executeTask() { setStatus(tr("Finding recommended version:\n%1").arg(m_sourceUrl.toString())); @@ -106,6 +114,8 @@ void Technic::SolderPackInstallTask::fileListSucceeded() void Technic::SolderPackInstallTask::downloadSucceeded() { + m_abortable = false; + setStatus(tr("Extracting modpack")); m_filesNetJob.reset(); m_extractFuture = QtConcurrent::run([this]() @@ -132,12 +142,14 @@ void Technic::SolderPackInstallTask::downloadSucceeded() void Technic::SolderPackInstallTask::downloadFailed(QString reason) { + m_abortable = false; emitFailed(reason); m_filesNetJob.reset(); } void Technic::SolderPackInstallTask::downloadProgressChanged(qint64 current, qint64 total) { + m_abortable = true; setProgress(current / 2, total); } diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.h b/api/logic/modplatform/technic/SolderPackInstallTask.h index 0fe6cb83..9f0f20a9 100644 --- a/api/logic/modplatform/technic/SolderPackInstallTask.h +++ b/api/logic/modplatform/technic/SolderPackInstallTask.h @@ -29,6 +29,9 @@ namespace Technic public: explicit SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion); + bool canAbort() const override { return true; } + bool abort() override; + protected: //! Entry point for tasks. virtual void executeTask() override; @@ -43,6 +46,8 @@ namespace Technic void extractAborted(); private: + bool m_abortable = false; + NetJobPtr m_filesNetJob; QUrl m_sourceUrl; QString m_minecraftVersion; diff --git a/api/logic/net/Download.cpp b/api/logic/net/Download.cpp index 340f8657..3f183b7d 100644 --- a/api/logic/net/Download.cpp +++ b/api/logic/net/Download.cpp @@ -15,6 +15,7 @@ #include "Download.h" +#include "BuildConfig.h" #include <QFileInfo> #include <QDateTime> #include <QDebug> @@ -94,7 +95,7 @@ void Download::start() return; } - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0"); + request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT); QNetworkReply *rep = ENV.qnam().get(request); diff --git a/api/logic/net/PasteUpload.cpp b/api/logic/net/PasteUpload.cpp index 3526e207..cb470c49 100644 --- a/api/logic/net/PasteUpload.cpp +++ b/api/logic/net/PasteUpload.cpp @@ -5,6 +5,7 @@ #include <QJsonArray> #include <QJsonDocument> #include <QFile> +#include <BuildConfig.h> PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window) { @@ -34,7 +35,7 @@ bool PasteUpload::validateText() void PasteUpload::executeTask() { QNetworkRequest request(QUrl("https://api.paste.ee/v1/pastes")); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); + request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); request.setRawHeader("Content-Type", "application/json"); request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size())); diff --git a/api/logic/screenshots/ImgurAlbumCreation.cpp b/api/logic/screenshots/ImgurAlbumCreation.cpp index ff9ec6fd..1f195f00 100644 --- a/api/logic/screenshots/ImgurAlbumCreation.cpp +++ b/api/logic/screenshots/ImgurAlbumCreation.cpp @@ -20,9 +20,9 @@ void ImgurAlbumCreation::start() { m_status = Job_InProgress; QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); + request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); + request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); request.setRawHeader("Accept", "application/json"); QStringList hashes; diff --git a/api/logic/screenshots/ImgurUpload.cpp b/api/logic/screenshots/ImgurUpload.cpp index 1585b061..7e95d5ca 100644 --- a/api/logic/screenshots/ImgurUpload.cpp +++ b/api/logic/screenshots/ImgurUpload.cpp @@ -23,8 +23,8 @@ void ImgurUpload::start() finished = false; m_status = Job_InProgress; QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); + request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); + request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); request.setRawHeader("Accept", "application/json"); QFile f(m_shot->m_file.absoluteFilePath()); |