aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--launcher/Application.cpp15
-rw-r--r--launcher/Application.h1
-rw-r--r--launcher/UpdateController.cpp14
-rw-r--r--launcher/main.cpp2
-rw-r--r--launcher/minecraft/GradleSpecifier.h2
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp6
-rw-r--r--launcher/minecraft/VersionFile.cpp3
-rw-r--r--launcher/minecraft/mod/LocalModParseTask.cpp8
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.cpp16
-rw-r--r--launcher/modplatform/flame/FlameModIndex.cpp9
-rw-r--r--launcher/modplatform/flame/PackManifest.cpp15
-rw-r--r--launcher/modplatform/technic/SolderPackManifest.cpp2
-rw-r--r--launcher/net/Download.cpp3
-rw-r--r--launcher/ui/dialogs/ExportInstanceDialog.cpp8
-rw-r--r--launcher/ui/pages/global/APIPage.cpp4
-rw-r--r--launcher/ui/pages/global/APIPage.ui64
-rw-r--r--launcher/ui/pages/global/ExternalToolsPage.cpp2
-rw-r--r--launcher/ui/pages/modplatform/flame/FlamePage.ui192
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui7
20 files changed, 231 insertions, 146 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d3683d7..e07d2aa6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9.4)
+cmake_minimum_required(VERSION 3.15) # minimum version required by QuaZip
if(WIN32)
# In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
@@ -43,6 +43,8 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type")
# Fix build with Qt 5.13
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_DISABLE_DEPRECATED_BEFORE=0x050C00")
+
option(ENABLE_LTO "Enable Link Time Optimization" off)
if(ENABLE_LTO)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index afb33a50..ce62c41a 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -223,9 +223,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
setApplicationName(BuildConfig.LAUNCHER_NAME);
setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME);
setApplicationVersion(BuildConfig.printableVersionString());
- #if (QT_VERSION >= QT_VERSION_CHECK(5,7,0))
- setDesktopFileName(BuildConfig.LAUNCHER_DESKTOPFILENAME);
- #endif
+ setDesktopFileName(BuildConfig.LAUNCHER_DESKTOPFILENAME);
startTime = QDateTime::currentDateTime();
// Don't quit on hiding the last window
@@ -681,6 +679,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Custom MSA credentials
m_settings->registerSetting("MSAClientIDOverride", "");
+ m_settings->registerSetting("CFKeyOverride", "");
// Init page provider
{
@@ -1510,3 +1509,13 @@ QString Application::getMSAClientID()
return BuildConfig.MSA_CLIENT_ID;
}
+
+QString Application::getCurseKey()
+{
+ QString keyOverride = m_settings->get("CFKeyOverride").toString();
+ if (!keyOverride.isEmpty()) {
+ return keyOverride;
+ }
+
+ return BuildConfig.CURSEFORGE_API_KEY;
+}
diff --git a/launcher/Application.h b/launcher/Application.h
index 172321c0..3129b4fb 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -155,6 +155,7 @@ public:
QString getJarsPath();
QString getMSAClientID();
+ QString getCurseKey();
/// this is the root of the 'installation'. Used for automatic updates
const QString &root() {
diff --git a/launcher/UpdateController.cpp b/launcher/UpdateController.cpp
index c02cd1e7..646f8e57 100644
--- a/launcher/UpdateController.cpp
+++ b/launcher/UpdateController.cpp
@@ -138,20 +138,6 @@ void UpdateController::installUpdates()
}
#endif
QFileInfo destination (FS::PathCombine(m_root, op.destination));
-#ifdef Q_OS_WIN32
- if(QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
- {
- if(destination.fileName() == windowsExeName)
- {
- QDir rootDir(m_root);
- exeOrigin = rootDir.relativeFilePath(op.source);
- exePath = rootDir.relativeFilePath(op.destination);
- exeBackup = rootDir.relativeFilePath(FS::PathCombine(backupPath, destination.fileName()));
- useXPHack = true;
- continue;
- }
- }
-#endif
if(destination.exists())
{
QString backupName = op.destination;
diff --git a/launcher/main.cpp b/launcher/main.cpp
index 275fff32..85c5fdee 100644
--- a/launcher/main.cpp
+++ b/launcher/main.cpp
@@ -24,10 +24,8 @@ int main(int argc, char *argv[])
return 42;
#endif
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
diff --git a/launcher/minecraft/GradleSpecifier.h b/launcher/minecraft/GradleSpecifier.h
index 60e0a726..d9bb0207 100644
--- a/launcher/minecraft/GradleSpecifier.h
+++ b/launcher/minecraft/GradleSpecifier.h
@@ -124,7 +124,7 @@ struct GradleSpecifier
}
bool matchName(const GradleSpecifier & other) const
{
- return other.artifactId() == artifactId() && other.groupId() == groupId();
+ return other.artifactId() == artifactId() && other.groupId() == groupId() && other.classifier() == classifier();
}
bool operator==(const GradleSpecifier & other) const
{
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index e20dc24c..61326fac 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -2,6 +2,7 @@
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ * Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* 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
@@ -487,9 +488,8 @@ QStringList MinecraftInstance::processMinecraftArgs(
}
}
- // blatant self-promotion.
- token_mapping["profile_name"] = token_mapping["version_name"] = BuildConfig.LAUNCHER_NAME;
-
+ token_mapping["profile_name"] = name();
+ token_mapping["version_name"] = profile->getMinecraftVersion();
token_mapping["version_type"] = profile->getMinecraftVersionType();
QString absRootDir = QDir(gameRoot()).absolutePath();
diff --git a/launcher/minecraft/VersionFile.cpp b/launcher/minecraft/VersionFile.cpp
index 9db30ba2..f242fbe7 100644
--- a/launcher/minecraft/VersionFile.cpp
+++ b/launcher/minecraft/VersionFile.cpp
@@ -2,6 +2,7 @@
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ * Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* 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
@@ -55,7 +56,7 @@ void VersionFile::applyTo(LaunchProfile *profile)
// Only real Minecraft can set those. Don't let anything override them.
if (isMinecraftVersion(uid))
{
- profile->applyMinecraftVersion(minecraftVersion);
+ profile->applyMinecraftVersion(version);
profile->applyMinecraftVersionType(type);
// HACK: ignore assets from other version files than Minecraft
// workaround for stupid assets issue caused by amazon:
diff --git a/launcher/minecraft/mod/LocalModParseTask.cpp b/launcher/minecraft/mod/LocalModParseTask.cpp
index 631c3abb..a7bec5ae 100644
--- a/launcher/minecraft/mod/LocalModParseTask.cpp
+++ b/launcher/minecraft/mod/LocalModParseTask.cpp
@@ -430,7 +430,7 @@ void LocalModParseTask::processAsZip()
zip.close();
return;
}
- else if (zip.setCurrentFile("fabric.mod.json"))
+ else if (zip.setCurrentFile("quilt.mod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
@@ -438,12 +438,12 @@ void LocalModParseTask::processAsZip()
return;
}
- m_result->details = ReadFabricModInfo(file.readAll());
+ m_result->details = ReadQuiltModInfo(file.readAll());
file.close();
zip.close();
return;
}
- else if (zip.setCurrentFile("quilt.mod.json"))
+ else if (zip.setCurrentFile("fabric.mod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
@@ -451,7 +451,7 @@ void LocalModParseTask::processAsZip()
return;
}
- m_result->details = ReadQuiltModInfo(file.readAll());
+ m_result->details = ReadFabricModInfo(file.readAll());
file.close();
zip.close();
return;
diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp
index 95924a68..0deb99c4 100644
--- a/launcher/modplatform/flame/FileResolvingTask.cpp
+++ b/launcher/modplatform/flame/FileResolvingTask.cpp
@@ -31,7 +31,21 @@ void Flame::FileResolvingTask::netJobFinished()
for (auto& bytes : results) {
auto& out = m_toProcess.files[index];
try {
- failed &= (!out.parseFromBytes(bytes));
+ bool fail = (!out.parseFromBytes(bytes));
+ if(fail){
+ //failed :( probably disabled mod, try to add to the list
+ auto doc = Json::requireDocument(bytes);
+ if (!doc.isObject()) {
+ throw JSONValidationError(QString("data is not an object? that's not supposed to happen"));
+ }
+ auto obj = Json::ensureObject(doc.object(), "data");
+ //FIXME : HACK, MAY NOT WORK FOR LONG
+ out.url = QUrl(QString("https://media.forgecdn.net/files/%1/%2/%3")
+ .arg(QString::number(QString::number(out.fileId).leftRef(4).toInt())
+ ,QString::number(QString::number(out.fileId).rightRef(3).toInt())
+ ,QUrl::toPercentEncoding(out.fileName)), QUrl::TolerantMode);
+ }
+ failed &= fail;
} catch (const JSONValidationError& e) {
qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a parsing error:";
qCritical() << e.cause();
diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp
index ba0824cf..9846b156 100644
--- a/launcher/modplatform/flame/FlameModIndex.cpp
+++ b/launcher/modplatform/flame/FlameModIndex.cpp
@@ -56,8 +56,15 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
file.fileId = Json::requireInteger(obj, "id");
file.date = Json::requireString(obj, "fileDate");
file.version = Json::requireString(obj, "displayName");
- file.downloadUrl = Json::requireString(obj, "downloadUrl");
file.fileName = Json::requireString(obj, "fileName");
+ file.downloadUrl = Json::ensureString(obj, "downloadUrl", "");
+ if(file.downloadUrl.isEmpty()){
+ //FIXME : HACK, MAY NOT WORK FOR LONG
+ file.downloadUrl = QString("https://media.forgecdn.net/files/%1/%2/%3")
+ .arg(QString::number(QString::number(file.fileId.toInt()).leftRef(4).toInt())
+ ,QString::number(QString::number(file.fileId.toInt()).rightRef(3).toInt())
+ ,QUrl::toPercentEncoding(file.fileName));
+ }
unsortedVersions.append(file);
}
diff --git a/launcher/modplatform/flame/PackManifest.cpp b/launcher/modplatform/flame/PackManifest.cpp
index e4f90c1a..3217a756 100644
--- a/launcher/modplatform/flame/PackManifest.cpp
+++ b/launcher/modplatform/flame/PackManifest.cpp
@@ -71,11 +71,6 @@ bool Flame::File::parseFromBytes(const QByteArray& bytes)
fileName = Json::requireString(obj, "fileName");
- QString rawUrl = Json::requireString(obj, "downloadUrl");
- url = QUrl(rawUrl, QUrl::TolerantMode);
- if (!url.isValid()) {
- throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
- }
// This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience
// It is also optional
type = File::Type::SingleFile;
@@ -87,7 +82,17 @@ bool Flame::File::parseFromBytes(const QByteArray& bytes)
// this is probably a mod, dunno what else could modpacks download
targetFolder = "mods";
}
+ QString rawUrl = Json::ensureString(obj, "downloadUrl");
+ if(rawUrl.isEmpty()){
+ //either there somehow is an emtpy string as a link, or it's null either way it's invalid
+ //soft failing
+ return false;
+ }
+ url = QUrl(rawUrl, QUrl::TolerantMode);
+ if (!url.isValid()) {
+ throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
+ }
resolved = true;
return true;
}
diff --git a/launcher/modplatform/technic/SolderPackManifest.cpp b/launcher/modplatform/technic/SolderPackManifest.cpp
index 16fe0b0e..e52a7ec0 100644
--- a/launcher/modplatform/technic/SolderPackManifest.cpp
+++ b/launcher/modplatform/technic/SolderPackManifest.cpp
@@ -37,7 +37,7 @@ void loadPack(Pack& v, QJsonObject& obj)
static void loadPackBuildMod(PackBuildMod& b, QJsonObject& obj)
{
b.name = Json::requireString(obj, "name");
- b.version = Json::requireString(obj, "version");
+ b.version = Json::ensureString(obj, "version", "");
b.md5 = Json::requireString(obj, "md5");
b.url = Json::requireString(obj, "url");
}
diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp
index 97033de1..966d4126 100644
--- a/launcher/net/Download.cpp
+++ b/launcher/net/Download.cpp
@@ -44,6 +44,7 @@
#include "MetaCacheSink.h"
#include "BuildConfig.h"
+#include "Application.h"
namespace Net {
@@ -117,7 +118,7 @@ void Download::executeTask()
request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT);
if (request.url().host().contains("api.curseforge.com")) {
- request.setRawHeader("x-api-key", BuildConfig.CURSEFORGE_API_KEY.toUtf8());
+ request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8());
};
QNetworkReply* rep = m_network->get(request);
diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp
index 5fac1015..8631edf6 100644
--- a/launcher/ui/dialogs/ExportInstanceDialog.cpp
+++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp
@@ -117,7 +117,7 @@ public:
flags |= Qt::ItemIsUserCheckable;
if (sourceIndex.model()->hasChildren(sourceIndex))
{
- flags |= Qt::ItemIsTristate;
+ flags |= Qt::ItemIsAutoTristate;
}
}
@@ -210,7 +210,7 @@ public:
QStack<QModelIndex> todo;
while (1)
{
- auto node = doing.child(row, 0);
+ auto node = fsm->index(row, 0, doing);
if (!node.isValid())
{
if (!todo.size())
@@ -259,7 +259,7 @@ public:
QStack<QModelIndex> todo;
while (1)
{
- auto node = doing.child(row, 0);
+ auto node = this->index(row, 0, doing);
if (!node.isValid())
{
if (!todo.size())
@@ -460,7 +460,7 @@ void ExportInstanceDialog::rowsInserted(QModelIndex parent, int top, int bottom)
//WARNING: possible off-by-one?
for(int i = top; i < bottom; i++)
{
- auto node = parent.child(i, 0);
+ auto node = proxyModel->index(i, 0, parent);
if(proxyModel->shouldExpand(node))
{
auto expNode = node.parent();
diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp
index 287eb74f..8b806bcf 100644
--- a/launcher/ui/pages/global/APIPage.cpp
+++ b/launcher/ui/pages/global/APIPage.cpp
@@ -70,6 +70,8 @@ void APIPage::loadSettings()
ui->urlChoices->setCurrentText(pastebinURL);
QString msaClientID = s->get("MSAClientIDOverride").toString();
ui->msaClientID->setText(msaClientID);
+ QString curseKey = s->get("CFKeyOverride").toString();
+ ui->curseKey->setText(curseKey);
}
void APIPage::applySettings()
@@ -79,6 +81,8 @@ void APIPage::applySettings()
s->set("PastebinURL", pastebinURL);
QString msaClientID = ui->msaClientID->text();
s->set("MSAClientIDOverride", msaClientID);
+ QString curseKey = ui->curseKey->text();
+ s->set("CFKeyOverride", curseKey);
}
bool APIPage::apply()
diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui
index acde9aef..eaa44c88 100644
--- a/launcher/ui/pages/global/APIPage.ui
+++ b/launcher/ui/pages/global/APIPage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>491</width>
- <height>474</height>
+ <width>603</width>
+ <height>530</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -148,17 +148,56 @@
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <widget class="QGroupBox" name="groupBox_curse">
+ <property name="enabled">
+ <bool>true</bool>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
+ <property name="title">
+ <string>&amp;CurseForge Core API</string>
</property>
- </spacer>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Note: you probably don't need to set this if CurseForge already works.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="curseKey">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="placeholderText">
+ <string>(Default)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Enter a custom API Key for CurseForge here. </string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</item>
</layout>
</widget>
@@ -166,9 +205,6 @@
</item>
</layout>
</widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- </tabstops>
<resources/>
<connections/>
</ui>
diff --git a/launcher/ui/pages/global/ExternalToolsPage.cpp b/launcher/ui/pages/global/ExternalToolsPage.cpp
index 693ca5c1..5ba0ebc2 100644
--- a/launcher/ui/pages/global/ExternalToolsPage.cpp
+++ b/launcher/ui/pages/global/ExternalToolsPage.cpp
@@ -54,9 +54,7 @@ ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
- #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
ui->jsonEditorTextBox->setClearButtonEnabled(true);
- #endif
ui->mceditLink->setOpenExternalLinks(true);
ui->jvisualvmLink->setOpenExternalLinks(true);
diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui
index 6d8d8e10..9fab9773 100644
--- a/launcher/ui/pages/modplatform/flame/FlamePage.ui
+++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui
@@ -1,90 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>FlamePage</class>
- <widget class="QWidget" name="FlamePage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>837</width>
- <height>685</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QListView" name="packView">
- <property name="iconSize">
- <size>
- <width>48</width>
- <height>48</height>
- </size>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QTextBrowser" name="packDescription">
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="openLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
- <item row="0" column="2">
- <widget class="QComboBox" name="versionSelectionBox"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Version selected:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QComboBox" name="sortByBox"/>
- </item>
- </layout>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="searchButton">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter...</string>
- </property>
- </widget>
- </item>
+ <class>FlamePage</class>
+ <widget class="QWidget" name="FlamePage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="font">
+ <font>
+ <italic>true</italic>
+ </font>
+ </property>
+ <property name="text">
+ <string>Note: CurseForge's API is very unreliable. CurseForge and some mod authors have disallowed downloading mods in third-party applications like PolyMC. As such, you may need to manually download some mods to be able to install a modpack.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLineEdit" name="searchEdit">
+ <property name="placeholderText">
+ <string>Search and filter...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="searchButton">
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </widget>
+ </item>
</layout>
- </widget>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>searchButton</tabstop>
- <tabstop>packView</tabstop>
- <tabstop>packDescription</tabstop>
- <tabstop>sortByBox</tabstop>
- <tabstop>versionSelectionBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
+ </item>
+ <item row="2" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QListView" name="packView">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="packDescription">
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="openLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QComboBox" name="sortByBox"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Version selected:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="versionSelectionBox"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>packView</tabstop>
+ <tabstop>packDescription</tabstop>
+ <tabstop>sortByBox</tabstop>
+ <tabstop>versionSelectionBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
</ui>
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
index 4fb59cdf..ae9556ed 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>837</width>
- <height>685</height>
+ <width>800</width>
+ <height>600</height>
</rect>
</property>
<layout class="QVBoxLayout">
@@ -24,6 +24,9 @@
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>