aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp14
-rw-r--r--launcher/Application.h1
-rw-r--r--launcher/FileSystem.cpp1
-rw-r--r--launcher/GZip.cpp4
-rw-r--r--launcher/HoeDown.h2
-rw-r--r--launcher/java/JavaUtils.cpp12
-rw-r--r--launcher/modplatform/helpers/NetworkModAPI.cpp1
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.cpp55
-rw-r--r--launcher/tasks/Task.cpp2
-rw-r--r--launcher/ui/dialogs/AboutDialog.ui13
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.cpp15
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp25
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h1
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp2
-rw-r--r--launcher/ui/themes/DarkTheme.cpp2
15 files changed, 89 insertions, 61 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 97f757f7..f6b41850 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -245,7 +245,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
{{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"},
{{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"},
{"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"},
- {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}
+ {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"},
+ {"show", "Opens the window for the specified instance (by instance ID)", "show"}
});
parser.addHelpOption();
parser.addVersionOption();
@@ -257,6 +258,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_profileToUse = parser.value("profile");
m_liveCheck = parser.isSet("alive");
m_zipToImport = parser.value("import");
+ m_instanceIdToShowWindowOf = parser.value("show");
// error if --launch is missing with --server or --profile
if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty())
@@ -986,6 +988,16 @@ void Application::performMainStartupAction()
return;
}
}
+ if(!m_instanceIdToShowWindowOf.isEmpty())
+ {
+ auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf);
+ if(inst)
+ {
+ qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf;
+ showInstanceWindow(inst);
+ return;
+ }
+ }
if(!m_mainWindow)
{
// normal main window
diff --git a/launcher/Application.h b/launcher/Application.h
index 34ad8c15..c453cc28 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -301,6 +301,7 @@ public:
QString m_profileToUse;
bool m_liveCheck = false;
QUrl m_zipToImport;
+ QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile;
};
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 39e68c20..76cfccb0 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -401,6 +401,7 @@ bool overrideFolder(QString overwritten_path, QString override_path)
std::error_code err;
fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing;
+ // FIXME: hello traveller! Apparently std::copy does NOT overwrite existing files on GNU libstdc++ on Windows?
fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err);
if (err) {
diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp
index 067104cf..e36dc8a4 100644
--- a/launcher/GZip.cpp
+++ b/launcher/GZip.cpp
@@ -72,7 +72,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
uncompLength *= 2;
}
- strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out);
+ strm.next_out = reinterpret_cast<Bytef *>((uncompressedBytes.data() + strm.total_out));
strm.avail_out = uncompLength - strm.total_out;
// Inflate another chunk.
@@ -129,7 +129,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
{
compressedBytes.resize(compressedBytes.size() * 2);
}
- zs.next_out = (Bytef *) (compressedBytes.data() + offset);
+ zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset));
temp = zs.avail_out = compressedBytes.size() - offset;
ret = deflate(&zs, Z_FINISH);
offset += temp - zs.avail_out;
diff --git a/launcher/HoeDown.h b/launcher/HoeDown.h
index b9e06ffb..cb62de6c 100644
--- a/launcher/HoeDown.h
+++ b/launcher/HoeDown.h
@@ -42,7 +42,7 @@ public:
}
void put(QByteArray input)
{
- hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size());
+ hoedown_buffer_put(buf, reinterpret_cast<uint8_t *>(input.data()), input.size());
}
const uint8_t * data() const
{
diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp
index 040fe821..6c0c60cd 100644
--- a/launcher/java/JavaUtils.cpp
+++ b/launcher/java/JavaUtils.cpp
@@ -379,7 +379,9 @@ QList<QString> JavaUtils::FindJavaPaths()
}
}
- return addJavasFromEnv(candidates);
+ candidates = addJavasFromEnv(candidates);
+ candidates.removeDuplicates();
+ return candidates;
}
#elif defined(Q_OS_MAC)
@@ -402,7 +404,9 @@ QList<QString> JavaUtils::FindJavaPaths()
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
}
- return addJavasFromEnv(javas);
+ javas = addJavasFromEnv(javas);
+ javas.removeDuplicates();
+ return javas;
}
#elif defined(Q_OS_LINUX)
@@ -448,7 +452,9 @@ QList<QString> JavaUtils::FindJavaPaths()
scanJavaDir("/opt/jdks");
// flatpak
scanJavaDir("/app/jdk");
- return addJavasFromEnv(javas);
+ javas = addJavasFromEnv(javas);
+ javas.removeDuplicates();
+ return javas;
}
#else
QList<QString> JavaUtils::FindJavaPaths()
diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp
index 866e7540..7633030e 100644
--- a/launcher/modplatform/helpers/NetworkModAPI.cpp
+++ b/launcher/modplatform/helpers/NetworkModAPI.cpp
@@ -15,6 +15,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const
QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); });
QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed);
+ QObject::connect(netJob, &NetJob::aborted, caller, &CallerType::searchRequestAborted);
QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
index 3e53becb..ae45e096 100644
--- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
+++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
@@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
-* PolyMC - Minecraft Launcher
-* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
-*
-* 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 <https://www.gnu.org/licenses/>.
-*/
+ * PolyMC - Minecraft Launcher
+ * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
#include "ModrinthPackIndex.h"
#include "ModrinthAPI.h"
@@ -35,7 +35,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
pack.provider = ModPlatform::Provider::MODRINTH;
pack.name = Json::requireString(obj, "title");
-
+
pack.slug = Json::ensureString(obj, "slug", "");
if (!pack.slug.isEmpty())
pack.websiteUrl = "https://modrinth.com/mod/" + pack.slug;
@@ -59,23 +59,23 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{
pack.extraData.issuesUrl = Json::ensureString(obj, "issues_url");
- if(pack.extraData.issuesUrl.endsWith('/'))
+ if (pack.extraData.issuesUrl.endsWith('/'))
pack.extraData.issuesUrl.chop(1);
pack.extraData.sourceUrl = Json::ensureString(obj, "source_url");
- if(pack.extraData.sourceUrl.endsWith('/'))
+ if (pack.extraData.sourceUrl.endsWith('/'))
pack.extraData.sourceUrl.chop(1);
pack.extraData.wikiUrl = Json::ensureString(obj, "wiki_url");
- if(pack.extraData.wikiUrl.endsWith('/'))
+ if (pack.extraData.wikiUrl.endsWith('/'))
pack.extraData.wikiUrl.chop(1);
pack.extraData.discordUrl = Json::ensureString(obj, "discord_url");
- if(pack.extraData.discordUrl.endsWith('/'))
+ if (pack.extraData.discordUrl.endsWith('/'))
pack.extraData.discordUrl.chop(1);
auto donate_arr = Json::ensureArray(obj, "donation_urls");
- for(auto d : donate_arr){
+ for (auto d : donate_arr) {
auto d_obj = Json::requireObject(d);
ModPlatform::DonationData donate;
@@ -104,7 +104,7 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
auto obj = versionIter.toObject();
auto file = loadIndexedPackVersion(obj);
- if(file.fileId.isValid()) // Heuristic to check if the returned value is valid
+ if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
unsortedVersions.append(file);
}
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
@@ -116,7 +116,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
pack.versionsLoaded = true;
}
-auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_type, QString preferred_file_name) -> ModPlatform::IndexedVersion
+auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name)
+ -> ModPlatform::IndexedVersion
{
ModPlatform::IndexedVersion file;
@@ -141,6 +142,12 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t
auto files = Json::requireArray(obj, "files");
int i = 0;
+ if (files.empty()) {
+ // This should not happen normally, but check just in case
+ qWarning() << "Modrinth returned an unexpected empty list of files:" << obj;
+ return {};
+ }
+
// Find correct file (needed in cases where one version may have multiple files)
// Will default to the last one if there's no primary (though I think Modrinth requires that
// at least one file is primary, idk)
@@ -167,7 +174,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t
file.fileName = Json::requireString(parent, "filename");
file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1);
auto hash_list = Json::requireObject(parent, "hashes");
-
+
if (hash_list.contains(preferred_hash_type)) {
file.hash = Json::requireString(hash_list, preferred_hash_type);
file.hash_type = preferred_hash_type;
diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp
index b4babdd4..9ea1bb26 100644
--- a/launcher/tasks/Task.cpp
+++ b/launcher/tasks/Task.cpp
@@ -153,7 +153,7 @@ QString Task::describe()
auto name = objectName();
if(name.isEmpty())
{
- out << QString("0x%1").arg((quintptr)this, 0, 16);
+ out << QString("0x%1").arg(reinterpret_cast<quintptr>(this), 0, 16);
}
else
{
diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui
index e0429321..4a9eef08 100644
--- a/launcher/ui/dialogs/AboutDialog.ui
+++ b/launcher/ui/dialogs/AboutDialog.ui
@@ -87,14 +87,11 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="versionLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByMouse</set>
</property>
@@ -167,7 +164,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="platformLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -183,7 +180,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="buildDateLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -199,7 +196,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="commitLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -215,7 +212,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="channelLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index 4171586e..cedd4a96 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -366,33 +366,28 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
auto changelog = new QTreeWidgetItem(changelog_item);
auto changelog_area = new QTextBrowser();
+ QString text = info.changelog;
switch (info.provider) {
case ModPlatform::Provider::MODRINTH: {
HoeDown h;
// HoeDown bug?: \n aren't converted to <br>
- auto text = h.process(info.changelog.toUtf8());
+ text = h.process(info.changelog.toUtf8());
// Don't convert if there's an HTML tag right after (Qt rendering weirdness)
text.remove(QRegularExpression("(\n+)(?=<)"));
text.replace('\n', "<br>");
- changelog_area->setHtml(text);
break;
}
- case ModPlatform::Provider::FLAME: {
- changelog_area->setHtml(info.changelog);
+ default:
break;
- }
}
+ changelog_area->setHtml(text);
changelog_area->setOpenExternalLinks(true);
- changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
+ changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::WidgetWidth);
changelog_area->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
- // HACK: Is there a better way of achieving this?
- auto font_height = QFontMetrics(changelog_area->font()).height();
- changelog_area->setMaximumHeight((changelog_area->toPlainText().count(QRegularExpression("\n|<br>")) + 2) * font_height);
-
ui->modTreeWidget->setItemWidget(changelog, 0, changelog_area);
ui->modTreeWidget->addTopLevelItem(item_top);
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index 49766fa6..ed58eb32 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -267,18 +267,25 @@ void ListModel::searchRequestFailed(QString reason)
.arg(m_parent->displayName())
.arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
}
+
jobPtr.reset();
+ searchState = Finished;
+}
- if (searchState == ResetRequested) {
- beginResetModel();
- modpacks.clear();
- endResetModel();
+void ListModel::searchRequestAborted()
+{
+ if (searchState != ResetRequested)
+ qCritical() << "Search task in ModModel aborted by an unknown reason!";
- nextSearchOffset = 0;
- performPaginatedSearch();
- } else {
- searchState = Finished;
- }
+ // Retry fetching
+ jobPtr.reset();
+
+ beginResetModel();
+ modpacks.clear();
+ endResetModel();
+
+ nextSearchOffset = 0;
+ performPaginatedSearch();
}
void ListModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index a58c7c55..d2636d87 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -51,6 +51,7 @@ class ListModel : public QAbstractListModel {
public slots:
void searchRequestFinished(QJsonDocument& doc);
void searchRequestFailed(QString reason);
+ void searchRequestAborted();
void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
index 004fdc57..9138dcbb 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -331,7 +331,7 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVers
connect(ui->clearAllButton, &QPushButton::clicked,
listModel, &AtlOptionalModListModel::clearAll);
connect(ui->installButton, &QPushButton::clicked,
- this, &QDialog::close);
+ this, &QDialog::accept);
}
AtlOptionalModDialog::~AtlOptionalModDialog() {
diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp
index 07a2efd2..48231b53 100644
--- a/launcher/ui/themes/DarkTheme.cpp
+++ b/launcher/ui/themes/DarkTheme.cpp
@@ -31,7 +31,7 @@ QPalette DarkTheme::colorScheme()
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::BrightText, Qt::red);
darkPalette.setColor(QPalette::Link, QColor(47,163,198));
- darkPalette.setColor(QPalette::Highlight, QColor(145,205,92));
+ darkPalette.setColor(QPalette::Highlight, QColor(150,219,89));
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray);
return fadeInactive(darkPalette, fadeAmount(), fadeColor());