aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml43
-rw-r--r--.github/workflows/trigger_release.yml4
-rw-r--r--flake.lock16
-rw-r--r--flake.nix2
-rw-r--r--launcher/CMakeLists.txt1
-rw-r--r--launcher/java/JavaUtils.cpp9
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp6
-rw-r--r--launcher/minecraft/auth/steps/LauncherLoginStep.cpp17
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStep.cpp17
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp17
-rw-r--r--launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp21
-rw-r--r--launcher/minecraft/auth/steps/XboxProfileStep.cpp17
-rw-r--r--launcher/minecraft/auth/steps/XboxUserStep.cpp13
-rw-r--r--launcher/modplatform/flame/FlameCheckUpdate.cpp4
-rw-r--r--launcher/net/NetUtils.h44
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.cpp13
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.ui2
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp15
-rw-r--r--nix/default.nix2
19 files changed, 197 insertions, 66 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1108fed6..0599c1d9 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -23,10 +23,9 @@ jobs:
qt_ver: 5
- os: ubuntu-20.04
- appimage: true
qt_ver: 6
qt_host: linux
- qt_version: '6.3.1'
+ qt_version: '6.2.4'
qt_modules: 'qt5compat qtimageformats'
qt_path: /home/runner/work/PolyMC/Qt
@@ -92,7 +91,7 @@ jobs:
if: runner.os != 'Windows' && inputs.build_type == 'Debug'
uses: hendrikmuhs/ccache-action@v1.2.1
with:
- key: ${{ matrix.os }}-${{ matrix.appimage }}
+ key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}
- name: Setup ccache (Windows)
if: runner.os == 'Windows' && inputs.build_type == 'Debug'
@@ -115,9 +114,9 @@ jobs:
uses: actions/cache@v3.0.2
with:
path: '${{ github.workspace }}\.ccache'
- key: ${{ matrix.os }}--qt${{ matrix.qt_ver }}
+ key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}
restore-keys: |
- ${{ matrix.os }}--qt${{ matrix.qt_ver }}
+ ${{ matrix.os }}-qt${{ matrix.qt_ver }}
- name: Set short version
shell: bash
@@ -138,7 +137,7 @@ jobs:
brew install ninja extra-cmake-modules
- name: Install Qt (Linux)
- if: runner.os == 'Linux' && matrix.appimage != true
+ if: runner.os == 'Linux' && matrix.qt_ver != 6
run: |
sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
@@ -162,7 +161,7 @@ jobs:
aqtversion: ==2.1.*
- name: Prepare AppImage (Linux)
- if: runner.os == 'Linux' && matrix.appimage == true
+ if: runner.os == 'Linux' && matrix.qt_ver != 5
run: |
wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage"
@@ -281,7 +280,7 @@ jobs:
makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi"
- name: Package (Linux)
- if: runner.os == 'Linux' && matrix.appimage != true
+ if: runner.os == 'Linux'
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }}
@@ -289,7 +288,7 @@ jobs:
tar --owner root --group root -czf ../PolyMC.tar.gz *
- name: Package (Linux, portable)
- if: runner.os == 'Linux' && matrix.appimage != true
+ if: runner.os == 'Linux'
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
@@ -298,7 +297,7 @@ jobs:
tar -czf ../PolyMC-portable.tar.gz *
- name: Package AppImage (Linux)
- if: runner.os == 'Linux' && matrix.appimage == true
+ if: runner.os == 'Linux' && matrix.qt_ver != 5
shell: bash
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr
@@ -357,22 +356,36 @@ jobs:
name: PolyMC-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC-Setup.exe
- - name: Upload binary tarball (Linux)
- if: runner.os == 'Linux' && matrix.appimage != true
+ - name: Upload binary tarball (Linux, Qt 5)
+ if: runner.os == 'Linux' && matrix.qt_ver != 6
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC.tar.gz
- - name: Upload binary tarball (Linux, portable)
- if: runner.os == 'Linux' && matrix.appimage != true
+ - name: Upload binary tarball (Linux, portable, Qt 5)
+ if: runner.os == 'Linux' && matrix.qt_ver != 6
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC-portable.tar.gz
+ - name: Upload binary tarball (Linux, Qt 6)
+ if: runner.os == 'Linux' && matrix.qt_ver !=5
+ uses: actions/upload-artifact@v3
+ with:
+ name: PolyMC-${{ runner.os }}-Qt6-${{ env.VERSION }}-${{ inputs.build_type }}
+ path: PolyMC.tar.gz
+
+ - name: Upload binary tarball (Linux, portable, Qt 6)
+ if: runner.os == 'Linux' && matrix.qt_ver != 5
+ uses: actions/upload-artifact@v3
+ with:
+ name: PolyMC-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
+ path: PolyMC-portable.tar.gz
+
- name: Upload AppImage (Linux)
- if: runner.os == 'Linux' && matrix.appimage == true
+ if: runner.os == 'Linux' && matrix.qt_ver != 5
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml
index af4a5f03..45ef7281 100644
--- a/.github/workflows/trigger_release.yml
+++ b/.github/workflows/trigger_release.yml
@@ -35,6 +35,8 @@ jobs:
- name: Package artifacts properly
run: |
mv ${{ github.workspace }}/PolyMC-source PolyMC-${{ env.VERSION }}
+ mv PolyMC-Linux-Qt6-Portable*/PolyMC-portable.tar.gz PolyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
+ mv PolyMC-Linux-Qt6*/PolyMC.tar.gz PolyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz
mv PolyMC-Linux-Portable*/PolyMC-portable.tar.gz PolyMC-Linux-Portable-${{ env.VERSION }}.tar.gz
mv PolyMC-Linux*/PolyMC.tar.gz PolyMC-Linux-${{ env.VERSION }}.tar.gz
mv PolyMC-*.AppImage/PolyMC-*.AppImage PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
@@ -70,6 +72,8 @@ jobs:
PolyMC-Linux-Portable-${{ env.VERSION }}.tar.gz
PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
PolyMC-Windows-Legacy-${{ env.VERSION }}.zip
+ PolyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz
+ PolyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
PolyMC-Windows-Legacy-Portable-${{ env.VERSION }}.zip
PolyMC-Windows-Legacy-Setup-${{ env.VERSION }}.exe
PolyMC-Windows-${{ env.VERSION }}.zip
diff --git a/flake.lock b/flake.lock
index 120b11c5..bfc9ac6d 100644
--- a/flake.lock
+++ b/flake.lock
@@ -19,26 +19,26 @@
"libnbtplusplus": {
"flake": false,
"locked": {
- "lastModified": 1591558203,
- "narHash": "sha256-QgvNvaoFflCXEPCCFBCeZvYTpuiwScBG7EosUgFwFNQ=",
- "owner": "multimc",
+ "lastModified": 1650031308,
+ "narHash": "sha256-TvVOjkUobYJD9itQYueELJX3wmecvEdCbJ0FinW2mL4=",
+ "owner": "PolyMC",
"repo": "libnbtplusplus",
- "rev": "dc72a20b7efd304d12af2025223fad07b4b78464",
+ "rev": "2203af7eeb48c45398139b583615134efd8d407f",
"type": "github"
},
"original": {
- "owner": "multimc",
+ "owner": "PolyMC",
"repo": "libnbtplusplus",
"type": "github"
}
},
"nixpkgs": {
"locked": {
- "lastModified": 1654665288,
- "narHash": "sha256-7blJpfoZEu7GKb84uh3io/5eSJNdaagXD9d15P9iQMs=",
+ "lastModified": 1658119717,
+ "narHash": "sha256-4upOZIQQ7Bc4CprqnHsKnqYfw+arJeAuU+QcpjYBXW0=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "43ecbe7840d155fa933ee8a500fb00dbbc651fc8",
+ "rev": "9eb60f25aff0d2218c848dd4574a0ab5e296cabe",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index c2fdffda..51bc1fda 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,7 +4,7 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
- libnbtplusplus = { url = "github:multimc/libnbtplusplus"; flake = false; };
+ libnbtplusplus = { url = "github:PolyMC/libnbtplusplus"; flake = false; };
};
outputs = { self, nixpkgs, libnbtplusplus, ... }:
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 3c9aee6a..a4a1315d 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -117,6 +117,7 @@ set(NET_SOURCES
net/NetAction.h
net/NetJob.cpp
net/NetJob.h
+ net/NetUtils.h
net/PasteUpload.cpp
net/PasteUpload.h
net/Sink.h
diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp
index 51d5b89d..2b19fca0 100644
--- a/launcher/java/JavaUtils.cpp
+++ b/launcher/java/JavaUtils.cpp
@@ -205,7 +205,7 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
// Read the current type version from the registry.
// This will be used to find any key that contains the JavaHome value.
- TCHAR subKeyName[255];
+ WCHAR subKeyName[255];
DWORD subKeyNameSize, numSubKeys, retCode;
// Get the number of subkeys
@@ -231,12 +231,11 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)
{
// Read the JavaHome value to find where Java is installed.
- TCHAR *value = NULL;
DWORD valueSz = 0;
- if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE *)value,
- &valueSz) == ERROR_MORE_DATA)
+ if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL,
+ &valueSz) == ERROR_SUCCESS)
{
- value = new TCHAR[valueSz];
+ WCHAR *value = new WCHAR[valueSz];
RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE *)value,
&valueSz);
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index 360e754d..5a6f8de0 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -709,15 +709,15 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
{
if(mod->type() == Mod::MOD_FOLDER)
{
- out << u8" [📁] " + mod->fileinfo().completeBaseName() + " (folder)";
+ out << u8" [🖿] " + mod->fileinfo().completeBaseName() + " (folder)";
continue;
}
if(mod->enabled()) {
- out << u8" [✔️]" + mod->fileinfo().completeBaseName();
+ out << u8" [✔] " + mod->fileinfo().completeBaseName();
}
else {
- out << u8" [❌] " + mod->fileinfo().completeBaseName() + " (disabled)";
+ out << u8" [✘] " + mod->fileinfo().completeBaseName() + " (disabled)";
}
}
diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp
index f5697223..8c53f037 100644
--- a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp
+++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp
@@ -5,6 +5,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "minecraft/auth/AccountTask.h"
+#include "net/NetUtils.h"
LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) {
@@ -58,10 +59,18 @@ void LauncherLoginStep::onRequestDone(
#ifndef NDEBUG
qDebug() << data;
#endif
- emit finished(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)
- );
+ if (Net::isApplicationError(error)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_OFFLINE,
+ tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)
+ );
+ }
return;
}
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
index add91659..b39b9326 100644
--- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
@@ -4,6 +4,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
+#include "net/NetUtils.h"
MinecraftProfileStep::MinecraftProfileStep(AccountData* data) : AuthStep(data) {
@@ -64,10 +65,18 @@ void MinecraftProfileStep::onRequestDone(
qWarning() << " Response:";
qWarning() << QString::fromUtf8(data);
- emit finished(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("Minecraft Java profile acquisition failed.")
- );
+ if (Net::isApplicationError(error)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_OFFLINE,
+ tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)
+ );
+ }
return;
}
if(!Parsers::parseMinecraftProfile(data, m_data->minecraftProfile)) {
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp
index d3035272..6a1eb7a0 100644
--- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp
@@ -4,6 +4,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
+#include "net/NetUtils.h"
MinecraftProfileStepMojang::MinecraftProfileStepMojang(AccountData* data) : AuthStep(data) {
@@ -67,10 +68,18 @@ void MinecraftProfileStepMojang::onRequestDone(
qWarning() << " Response:";
qWarning() << QString::fromUtf8(data);
- emit finished(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("Minecraft Java profile acquisition failed.")
- );
+ if (Net::isApplicationError(error)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_OFFLINE,
+ tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)
+ );
+ }
return;
}
if(!Parsers::parseMinecraftProfileMojang(data, m_data->minecraftProfile)) {
diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp
index 589768e3..14bde47e 100644
--- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp
+++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp
@@ -6,6 +6,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
+#include "net/NetUtils.h"
XboxAuthorizationStep::XboxAuthorizationStep(AccountData* data, Katabasis::Token *token, QString relyingParty, QString authorizationKind):
AuthStep(data),
@@ -62,10 +63,24 @@ void XboxAuthorizationStep::onRequestDone(
#endif
if (error != QNetworkReply::NoError) {
qWarning() << "Reply error:" << error;
- if(!processSTSError(error, data, headers)) {
+ if (Net::isApplicationError(error)) {
+ if(!processSTSError(error, data, headers)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, error)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, requestor->errorString_)
+ );
+ }
+ }
+ else {
emit finished(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, error)
+ AccountTaskState::STATE_OFFLINE,
+ tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, requestor->errorString_)
);
}
return;
diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.cpp b/launcher/minecraft/auth/steps/XboxProfileStep.cpp
index 9f50138e..738fe1db 100644
--- a/launcher/minecraft/auth/steps/XboxProfileStep.cpp
+++ b/launcher/minecraft/auth/steps/XboxProfileStep.cpp
@@ -6,6 +6,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
+#include "net/NetUtils.h"
XboxProfileStep::XboxProfileStep(AccountData* data) : AuthStep(data) {
@@ -58,10 +59,18 @@ void XboxProfileStep::onRequestDone(
#ifndef NDEBUG
qDebug() << data;
#endif
- finished(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("Failed to retrieve the Xbox profile.")
- );
+ if (Net::isApplicationError(error)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_OFFLINE,
+ tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_)
+ );
+ }
return;
}
diff --git a/launcher/minecraft/auth/steps/XboxUserStep.cpp b/launcher/minecraft/auth/steps/XboxUserStep.cpp
index a38a28e4..53069597 100644
--- a/launcher/minecraft/auth/steps/XboxUserStep.cpp
+++ b/launcher/minecraft/auth/steps/XboxUserStep.cpp
@@ -4,6 +4,7 @@
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
+#include "net/NetUtils.h"
XboxUserStep::XboxUserStep(AccountData* data) : AuthStep(data) {
@@ -53,7 +54,17 @@ void XboxUserStep::onRequestDone(
if (error != QNetworkReply::NoError) {
qWarning() << "Reply error:" << error;
- emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed."));
+ if (Net::isApplicationError(error)) {
+ emit finished(AccountTaskState::STATE_FAILED_SOFT,
+ tr("XBox user authentication failed: %1").arg(requestor->errorString_)
+ );
+ }
+ else {
+ emit finished(
+ AccountTaskState::STATE_OFFLINE,
+ tr("XBox user authentication failed: %1").arg(requestor->errorString_)
+ );
+ }
return;
}
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp
index 68a4589b..8dd3a846 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.cpp
+++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp
@@ -123,7 +123,7 @@ void FlameCheckUpdate::executeTask()
continue;
}
- setStatus(tr("Getting API response from CurseForge for '%1'").arg(mod->name()));
+ setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
setProgress(i++, m_mods.size());
auto latest_ver = api.getLatestVersion({ mod->metadata()->project_id.toString(), m_game_versions, m_loaders });
@@ -145,7 +145,7 @@ void FlameCheckUpdate::executeTask()
if (latest_ver.downloadUrl.isEmpty() && latest_ver.fileId != mod->metadata()->file_id) {
auto pack = getProjectInfo(latest_ver);
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver.fileId.toString());
- emit checkFailed(mod, tr("Mod has a new update available, but is opted-out on CurseForge"), recover_url);
+ emit checkFailed(mod, tr("Mod has a new update available, but is not downloadable using CurseForge."), recover_url);
continue;
}
diff --git a/launcher/net/NetUtils.h b/launcher/net/NetUtils.h
new file mode 100644
index 00000000..fa3bd8c0
--- /dev/null
+++ b/launcher/net/NetUtils.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * PolyMC - Minecraft Launcher
+ * Copyright (c) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include <QNetworkReply>
+#include <QSet>
+
+namespace Net {
+ inline bool isApplicationError(QNetworkReply::NetworkError x) {
+ // Mainly taken from https://github.com/qt/qtbase/blob/dev/src/network/access/qhttpthreaddelegate.cpp
+ static QSet<QNetworkReply::NetworkError> errors = {
+ QNetworkReply::ProtocolInvalidOperationError,
+ QNetworkReply::AuthenticationRequiredError,
+ QNetworkReply::ContentAccessDenied,
+ QNetworkReply::ContentNotFoundError,
+ QNetworkReply::ContentOperationNotPermittedError,
+ QNetworkReply::ProxyAuthenticationRequiredError,
+ QNetworkReply::ContentConflictError,
+ QNetworkReply::ContentGoneError,
+ QNetworkReply::InternalServerError,
+ QNetworkReply::OperationNotImplementedError,
+ QNetworkReply::ServiceUnavailableError,
+ QNetworkReply::UnknownServerError,
+ QNetworkReply::UnknownContentError
+ };
+ return errors.contains(x);
+ }
+} // namespace Net
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index b6e76ff1..d73c8ebb 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -158,8 +158,9 @@ void ModUpdateDialog::checkCandidates()
if (!reason.isEmpty())
text += tr("Reason: %1").arg(reason) + "<br>";
if (!recover_url.isEmpty())
- text += tr("Possible solution: ") + tr("Getting the latest version manually:") + "<br>" +
- QString("<a href='%1'>").arg(recover_url.toString()) + recover_url.toString() + "</a><br>";
+ //: %1 is the link to download it manually
+ text += tr("Possible solution: Getting the latest version manually:<br>%1<br>")
+ .arg(QString("<a href='%1'>%1</a>").arg(recover_url.toString()));
text += "<br>";
}
@@ -241,9 +242,9 @@ auto ModUpdateDialog::ensureMetadata() -> bool
}
ChooseProviderDialog chooser(this);
- chooser.setDescription(tr("This mod (%1) does not have a metadata yet. We need to create one in order to keep relevant "
- "information on how to update this "
- "mod. To do this, please select a mod provider from which we can search for updates for %1.")
+ chooser.setDescription(tr("The mod '%1' does not have a metadata yet. We need to generate it in order to track relevant "
+ "information on how to update this mod. "
+ "To do this, please select a mod provider which we can use to check for updates for this mod.")
.arg(candidate->name()));
auto confirmed = chooser.exec() == QDialog::DialogCode::Accepted;
@@ -330,7 +331,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::P
m_second_try_metadata->addTask(task);
} else {
- QString reason{ tr("Didn't find a valid version on the selected mod provider(s)") };
+ QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") };
m_failed_metadata.append({mod, reason});
}
diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui
index 8edcfd64..a13666b2 100644
--- a/launcher/ui/pages/instance/ExternalResourcesPage.ui
+++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui
@@ -155,7 +155,7 @@
<string>Check for &amp;Updates</string>
</property>
<property name="toolTip">
- <string>"Tries to find / update all selected resources (all resources if none is selected)"</string>
+ <string>Try to check or update all selected resources (all resources if none are selected)</string>
</property>
</action>
</widget>
diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp
index b190e51a..14e1f1e5 100644
--- a/launcher/ui/pages/instance/ModFolderPage.cpp
+++ b/launcher/ui/pages/instance/ModFolderPage.cpp
@@ -80,7 +80,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
connect(ui->actionDownloadItem, &QAction::triggered, this, &ModFolderPage::installMods);
- ui->actionUpdateItem->setToolTip(tr("Tries to find / update all selected mods (all mods if none is selected)"));
+ ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem);
connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods);
@@ -190,10 +190,15 @@ void ModFolderPage::updateMods()
return;
}
if (update_dialog.noUpdates()) {
- CustomMessageBox::selectable(this, tr("Update checker"),
- (mods_list.size() == 1)
- ? tr("'%1' is up-to-date! :)").arg(mods_list.front()->name())
- : tr("All %1mods are up-to-date! :)").arg(use_all ? "" : (tr("selected") + " ")))
+ QString message{ tr("'%1' is up-to-date! :)").arg(mods_list.front()->name()) };
+ if (mods_list.size() > 1) {
+ if (use_all) {
+ message = tr("All mods are up-to-date! :)");
+ } else {
+ message = tr("All selected mods are up-to-date! :)");
+ }
+ }
+ CustomMessageBox::selectable(this, tr("Update checker"), message)
->exec();
return;
}
diff --git a/nix/default.nix b/nix/default.nix
index 40a9a587..42ddda18 100644
--- a/nix/default.nix
+++ b/nix/default.nix
@@ -79,6 +79,8 @@ stdenv.mkDerivation rec {
meta = with lib; {
homepage = "https://polymc.org/";
+ downloadPage = "https://polymc.org/download/";
+ changelog = "https://github.com/PolyMC/PolyMC/releases";
description = "A free, open source launcher for Minecraft";
longDescription = ''
Allows you to have multiple, separate instances of Minecraft (each with