Merge branch 'develop' into macos-drag-n-drop

This commit is contained in:
Sefa Eyeoglu 2022-11-04 18:30:42 +01:00
commit 21a7af535c
No known key found for this signature in database
GPG Key ID: C10411294912A422
158 changed files with 1328 additions and 394 deletions

9
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,9 @@
<!--
Hey there! Thanks for your contribution.
Please make sure that your commits are signed off first.
If you don't know how that works, check out our contribution guidelines: https://github.com/PrismLauncher/PrismLauncher/blob/develop/CONTRIBUTING.md#signing-your-work
If you already created your commits, you can run `git rebase --signoff develop` to retroactively sign-off all your commits and `git push --force` to override what you have pushed already.
Note that signing and signing-off are two different things!
-->

View File

@ -30,12 +30,12 @@ jobs:
- os: windows-2022 - os: windows-2022
name: "Windows-Legacy" name: "Windows-Legacy"
msystem: mingw32 msystem: clang32
qt_ver: 5 qt_ver: 5
- os: windows-2022 - os: windows-2022
name: "Windows" name: "Windows"
msystem: mingw32 msystem: clang64
qt_ver: 6 qt_ver: 6
- os: macos-12 - os: macos-12
@ -89,6 +89,7 @@ jobs:
update: true update: true
install: >- install: >-
git git
mingw-w64-x86_64-binutils
pacboy: >- pacboy: >-
toolchain:p toolchain:p
cmake:p cmake:p
@ -99,12 +100,11 @@ jobs:
qt${{ matrix.qt_ver }}-imageformats:p qt${{ matrix.qt_ver }}-imageformats:p
quazip-qt${{ matrix.qt_ver }}:p quazip-qt${{ matrix.qt_ver }}:p
ccache:p ccache:p
nsis:p
${{ matrix.qt_ver == 6 && 'qt6-5compat:p' || '' }} ${{ matrix.qt_ver == 6 && 'qt6-5compat:p' || '' }}
- name: Setup ccache - name: Setup ccache
if: runner.os != 'Windows' && inputs.build_type == 'Debug' if: runner.os != 'Windows' && inputs.build_type == 'Debug'
uses: hendrikmuhs/ccache-action@v1.2.3 uses: hendrikmuhs/ccache-action@v1.2.5
with: with:
key: ${{ matrix.os }}-qt${{ matrix.qt_ver }} key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}
@ -194,7 +194,7 @@ jobs:
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: msys2 {0} shell: msys2 {0}
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja
- name: Configure CMake (Linux) - name: Configure CMake (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
@ -251,6 +251,7 @@ jobs:
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
chmod +x "PrismLauncher.app/Contents/MacOS/prismlauncher" chmod +x "PrismLauncher.app/Contents/MacOS/prismlauncher"
sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PrismLauncher.app/Contents/MacOS/prismlauncher" sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PrismLauncher.app/Contents/MacOS/prismlauncher"
mv "PrismLauncher.app" "Prism Launcher.app"
tar -czf ../PrismLauncher.tar.gz * tar -czf ../PrismLauncher.tar.gz *
- name: Make Sparkle signature (macOS) - name: Make Sparkle signature (macOS)
@ -280,7 +281,7 @@ jobs:
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
if [ "${{ matrix.qt_ver }}" == "5" ]; then if [ "${{ matrix.qt_ver }}" == "5" ]; then
cp /mingw32/bin/libcrypto-1_1.dll /mingw32/bin/libssl-1_1.dll ./ cp /clang32/bin/libcrypto-1_1.dll /clang32/bin/libssl-1_1.dll ./
fi fi
- name: Package (Windows, portable) - name: Package (Windows, portable)
@ -292,7 +293,6 @@ jobs:
- name: Package (Windows, installer) - name: Package (Windows, installer)
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: msys2 {0}
run: | run: |
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi" makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi"

View File

@ -3,7 +3,7 @@ name: Build Application
on: on:
push: push:
branches-ignore: branches-ignore:
- 'stable' - 'renovate/**'
paths-ignore: paths-ignore:
- '**.md' - '**.md'
- '**/LICENSE' - '**/LICENSE'

View File

@ -34,6 +34,11 @@ set(CMAKE_C_STANDARD 11)
include(GenerateExportHeader) include(GenerateExportHeader)
set(CMAKE_CXX_FLAGS "-Wall -pedantic -fstack-protector-strong --param=ssp-buffer-size=4 ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-Wall -pedantic -fstack-protector-strong --param=ssp-buffer-size=4 ${CMAKE_CXX_FLAGS}")
# ATL's packlist needs more than the default 1 Mib stack on windows
if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,8388608 ${CMAKE_EXE_LINKER_FLAGS}")
endif()
# Fix build with Qt 5.13 # 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_NO_DEPRECATED_WARNINGS=Y")
@ -222,14 +227,14 @@ if(UNIX AND APPLE)
set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app")
# Mac bundle settings # Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_DisplayName}")
set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") set(MACOSX_BUNDLE_INFO_STRING "${Launcher_DisplayName}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.prismlauncher.${Launcher_Name}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.prismlauncher.${Launcher_Name}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_NAME}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}")
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}") set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}")
set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=")
set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml")
@ -251,7 +256,7 @@ elseif(UNIX)
set(BINARY_DEST_DIR "bin") set(BINARY_DEST_DIR "bin")
set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(JARS_DEST_DIR "share/jars") set(JARS_DEST_DIR "share/${Launcher_APP_BINARY_NAME}")
# install as bundle with no dependencies included # install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps") set(INSTALL_BUNDLE "nodeps")

View File

@ -1,14 +1,20 @@
<p align="center"> <p align="left">
<img src="./program_info/org.prismlauncher.PrismLauncher.logo.svg#gh-light-mode-only" alt="Prism Launcher logo" width="50%"/> <img src="./program_info/org.prismlauncher.PrismLauncher.logo.svg#gh-light-mode-only" alt="Prism Launcher logo" width="50%"/>
<img src="./program_info/org.prismlauncher.PrismLauncher.logo-darkmode.svg#gh-dark-mode-only" alt="Prism Launcher logo" width="50%"/> <img src="./program_info/org.prismlauncher.PrismLauncher.logo-darkmode.svg#gh-dark-mode-only" alt="Prism Launcher logo" width="50%"/>
</p> </p>
Prism Launcher is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once. Prism Launcher is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.
This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC.
## Installation ## Installation
<a href="https://repology.org/project/prismlauncher/versions">
<img src="https://repology.org/badge/vertical-allrepos/prismlauncher.svg" alt="Packaging status" align="right">
</a>
- All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/). - All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/).
- Last build status can be found [here](https://github.com/PrismLauncher/PrismLauncher/actions). - Last build status can be found [here](https://github.com/PrismLauncher/PrismLauncher/actions).
@ -16,25 +22,24 @@ This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC.
There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger.
Portable builds are provided for on Linux, Windows, and macOS. Portable builds are provided for Linux, Windows, and macOS.
For Arch, Debian and Gentoo, respectively, you can use these packages to get compiled development versions:
[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher)
For Debian and Arch, you can use these packages for the latest development versions:
[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue)](https://aur.archlinux.org/packages/prismlauncher-git/)
[![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange)](https://mpr.makedeb.org/packages/prismlauncher-git)
## Help & Support ## Help & Support
Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server. Feel free to create an issue if you need help.
#### Join our Discord server:
[![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher) [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher)
We will also soon be opening up our Matrix channels. #### Join our Matrix space:
You can already join our Matrix space: [![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge)](https://matrix.to/#/#prismlauncher:matrix.org)
[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?label=PrismLauncher%20space)](https://matrix.to/#/#prismlauncher:matrix.org) #### Join our SubReddit:
[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge)](https://www.reddit.com/r/PrismLauncher/)
We also have a subreddit you can post your issues and suggestions on:
[r/PrismLauncher](https://www.reddit.com/r/PrismLauncher/)
## Building ## Building
@ -60,13 +65,11 @@ Be aware that if you build this software without removing the provided API keys
If you do not agree with these terms and conditions, then remove the associated API keys from the [CMakeLists.txt](CMakeLists.txt) file by setting them to an empty string (`""`). If you do not agree with these terms and conditions, then remove the associated API keys from the [CMakeLists.txt](CMakeLists.txt) file by setting them to an empty string (`""`).
## License ## Sponsors & Partners
All launcher code is available under the GPL-3.0-only license. We thank all the wonderful backers over at Open Collective! Support Prism Launcher by [becoming a backer](https://opencollective.com/prismlauncher).
The logo and related assets are under the CC BY-SA 4.0 license. [![OpenCollective Backers](https://opencollective.com/prismlauncher/backers.svg?width=890&limit=1000)](https://opencollective.com/prismlauncher#backers)
## Sponsors
Thanks to JetBrains for providing us a few licenses for all their products, as part of their [Open Source program](https://www.jetbrains.com/opensource/). Thanks to JetBrains for providing us a few licenses for all their products, as part of their [Open Source program](https://www.jetbrains.com/opensource/).
@ -85,3 +88,12 @@ Thanks to Netlify for providing us their excellent web services, as part of thei
Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), for providing M1-Macs for development purposes! Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), for providing M1-Macs for development purposes!
<a href="https://www.macstadium.com"><img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" alt="Powered by MacStadium" width="300"></a> <a href="https://www.macstadium.com"><img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" alt="Powered by MacStadium" width="300"></a>
## License
All launcher code is available under the GPL-3.0-only license.
![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?style=for-the-badge)
The logo and related assets are under the CC BY-SA 4.0 license.

View File

@ -42,12 +42,14 @@ Config::Config()
{ {
// Name and copyright // Name and copyright
LAUNCHER_NAME = "@Launcher_Name@"; LAUNCHER_NAME = "@Launcher_Name@";
LAUNCHER_APP_BINARY_NAME = "@Launcher_APP_BINARY_NAME@";
LAUNCHER_DISPLAYNAME = "@Launcher_DisplayName@"; LAUNCHER_DISPLAYNAME = "@Launcher_DisplayName@";
LAUNCHER_COPYRIGHT = "@Launcher_Copyright@"; LAUNCHER_COPYRIGHT = "@Launcher_Copyright@";
LAUNCHER_DOMAIN = "@Launcher_Domain@"; LAUNCHER_DOMAIN = "@Launcher_Domain@";
LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@"; LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@";
LAUNCHER_GIT = "@Launcher_Git@"; LAUNCHER_GIT = "@Launcher_Git@";
LAUNCHER_DESKTOPFILENAME = "@Launcher_DesktopFileName@"; LAUNCHER_DESKTOPFILENAME = "@Launcher_DesktopFileName@";
LAUNCHER_SVGFILENAME = "@Launcher_SVGFileName@";
USER_AGENT = "@Launcher_UserAgent@"; USER_AGENT = "@Launcher_UserAgent@";
USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)"; USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)";

View File

@ -44,12 +44,14 @@ class Config {
public: public:
Config(); Config();
QString LAUNCHER_NAME; QString LAUNCHER_NAME;
QString LAUNCHER_APP_BINARY_NAME;
QString LAUNCHER_DISPLAYNAME; QString LAUNCHER_DISPLAYNAME;
QString LAUNCHER_COPYRIGHT; QString LAUNCHER_COPYRIGHT;
QString LAUNCHER_DOMAIN; QString LAUNCHER_DOMAIN;
QString LAUNCHER_CONFIGFILE; QString LAUNCHER_CONFIGFILE;
QString LAUNCHER_GIT; QString LAUNCHER_GIT;
QString LAUNCHER_DESKTOPFILENAME; QString LAUNCHER_DESKTOPFILENAME;
QString LAUNCHER_SVGFILENAME;
/// The major version number. /// The major version number.
int VERSION_MAJOR; int VERSION_MAJOR;

View File

@ -62,6 +62,7 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include "ui/WinDarkmode.h" #include "ui/WinDarkmode.h"
#include <versionhelpers.h>
#endif #endif
#include "ui/setupwizard/SetupWizard.h" #include "ui/setupwizard/SetupWizard.h"
@ -245,7 +246,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"}, {{"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"}, {{"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"}, {"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.addHelpOption();
parser.addVersionOption(); parser.addVersionOption();
@ -257,6 +259,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_profileToUse = parser.value("profile"); m_profileToUse = parser.value("profile");
m_liveCheck = parser.isSet("alive"); m_liveCheck = parser.isSet("alive");
m_zipToImport = parser.value("import"); m_zipToImport = parser.value("import");
m_instanceIdToShowWindowOf = parser.value("show");
// error if --launch is missing with --server or --profile // error if --launch is missing with --server or --profile
if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty())
@ -498,6 +501,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Theming // Theming
m_settings->registerSetting("IconTheme", QString("pe_colored")); m_settings->registerSetting("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system")); m_settings->registerSetting("ApplicationTheme", QString("system"));
m_settings->registerSetting("BackgroundCat", QString("kitteh"));
// Remembered state // Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
@ -992,6 +996,16 @@ void Application::performMainStartupAction()
return; 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) if(!m_mainWindow)
{ {
// normal main window // normal main window
@ -1130,15 +1144,6 @@ std::vector<ITheme *> Application::getValidApplicationThemes()
return ret; return ret;
} }
bool Application::isFlatpak()
{
#ifdef Q_OS_LINUX
return QFile::exists("/.flatpak-info");
#else
return false;
#endif
}
void Application::setApplicationTheme(const QString& name, bool initial) void Application::setApplicationTheme(const QString& name, bool initial)
{ {
auto systemPalette = qApp->palette(); auto systemPalette = qApp->palette();
@ -1148,7 +1153,7 @@ void Application::setApplicationTheme(const QString& name, bool initial)
auto & theme = (*themeIter).second; auto & theme = (*themeIter).second;
theme->apply(initial); theme->apply(initial);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (m_mainWindow) { if (m_mainWindow && IsWindows10OrGreater()) {
if (QString::compare(theme->id(), "dark") == 0) { if (QString::compare(theme->id(), "dark") == 0) {
WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
} else { } else {
@ -1171,7 +1176,7 @@ void Application::setIconTheme(const QString& name)
QIcon Application::getThemedIcon(const QString& name) QIcon Application::getThemedIcon(const QString& name)
{ {
if(name == "logo") { if(name == "logo") {
return QIcon(":/org.prismlauncher.PrismLauncher.svg"); // FIXME: Make this a BuildConfig variable return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME);
} }
return QIcon::fromTheme(name); return QIcon::fromTheme(name);
} }
@ -1389,10 +1394,13 @@ MainWindow* Application::showMainWindow(bool minimized)
m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray()));
m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray()));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { if (IsWindows10OrGreater())
WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); {
} else { if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) {
WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
} else {
WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false);
}
} }
#endif #endif
if(minimized) if(minimized)
@ -1577,7 +1585,7 @@ QString Application::getJarPath(QString jarFile)
{ {
QStringList potentialPaths = { QStringList potentialPaths = {
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
FS::PathCombine(m_rootPath, "share/jars"), FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME),
#endif #endif
FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(m_rootPath, "jars"),
FS::PathCombine(applicationDirPath(), "jars") FS::PathCombine(applicationDirPath(), "jars")

View File

@ -116,8 +116,6 @@ public:
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
bool isFlatpak();
void setIconTheme(const QString& name); void setIconTheme(const QString& name);
std::vector<ITheme *> getValidApplicationThemes(); std::vector<ITheme *> getValidApplicationThemes();
@ -301,6 +299,7 @@ public:
QString m_profileToUse; QString m_profileToUse;
bool m_liveCheck = false; bool m_liveCheck = false;
QUrl m_zipToImport; QUrl m_zipToImport;
QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile; std::unique_ptr<QFile> logFile;
}; };

View File

@ -17,13 +17,14 @@
#include <memory> #include <memory>
#include "BaseVersion.h"
class MinecraftInstance; class MinecraftInstance;
class QDir; class QDir;
class QString; class QString;
class QObject; class QObject;
class Task; class Task;
class BaseVersion; class BaseVersion;
typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
class BaseInstaller class BaseInstaller
{ {
@ -35,7 +36,7 @@ public:
virtual bool add(MinecraftInstance *to); virtual bool add(MinecraftInstance *to);
virtual bool remove(MinecraftInstance *from); virtual bool remove(MinecraftInstance *from);
virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersionPtr version, QObject *parent) = 0; virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersion::Ptr version, QObject *parent) = 0;
protected: protected:
virtual QString id() const = 0; virtual QString id() const = 0;

View File

@ -25,6 +25,7 @@
class BaseVersion class BaseVersion
{ {
public: public:
using Ptr = std::shared_ptr<BaseVersion>;
virtual ~BaseVersion() {} virtual ~BaseVersion() {}
/*! /*!
* A string used to identify this version in config files. * A string used to identify this version in config files.
@ -54,6 +55,4 @@ public:
}; };
}; };
typedef std::shared_ptr<BaseVersion> BaseVersionPtr; Q_DECLARE_METATYPE(BaseVersion::Ptr)
Q_DECLARE_METATYPE(BaseVersionPtr)

View File

@ -40,20 +40,20 @@ BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent)
{ {
} }
BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor) BaseVersion::Ptr BaseVersionList::findVersion(const QString &descriptor)
{ {
for (int i = 0; i < count(); i++) for (int i = 0; i < count(); i++)
{ {
if (at(i)->descriptor() == descriptor) if (at(i)->descriptor() == descriptor)
return at(i); return at(i);
} }
return BaseVersionPtr(); return nullptr;
} }
BaseVersionPtr BaseVersionList::getRecommended() const BaseVersion::Ptr BaseVersionList::getRecommended() const
{ {
if (count() <= 0) if (count() <= 0)
return BaseVersionPtr(); return nullptr;
else else
return at(0); return at(0);
} }
@ -66,7 +66,7 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const
if (index.row() > count()) if (index.row() > count())
return QVariant(); return QVariant();
BaseVersionPtr version = at(index.row()); BaseVersion::Ptr version = at(index.row());
switch (role) switch (role)
{ {

View File

@ -70,7 +70,7 @@ public:
virtual bool isLoaded() = 0; virtual bool isLoaded() = 0;
//! Gets the version at the given index. //! Gets the version at the given index.
virtual const BaseVersionPtr at(int i) const = 0; virtual const BaseVersion::Ptr at(int i) const = 0;
//! Returns the number of versions in the list. //! Returns the number of versions in the list.
virtual int count() const = 0; virtual int count() const = 0;
@ -90,13 +90,13 @@ public:
* \return A const pointer to the version with the given descriptor. NULL if * \return A const pointer to the version with the given descriptor. NULL if
* one doesn't exist. * one doesn't exist.
*/ */
virtual BaseVersionPtr findVersion(const QString &descriptor); virtual BaseVersion::Ptr findVersion(const QString &descriptor);
/*! /*!
* \brief Gets the recommended version from this list * \brief Gets the recommended version from this list
* If the list doesn't support recommended versions, this works exactly as getLatestStable * If the list doesn't support recommended versions, this works exactly as getLatestStable
*/ */
virtual BaseVersionPtr getRecommended() const; virtual BaseVersion::Ptr getRecommended() const;
/*! /*!
* Sorts the version list. * Sorts the version list.
@ -117,5 +117,5 @@ slots:
* then copies the versions and sets their parents correctly. * then copies the versions and sets their parents correctly.
* \param versions List of versions whose parents should be set. * \param versions List of versions whose parents should be set.
*/ */
virtual void updateListData(QList<BaseVersionPtr> versions) = 0; virtual void updateListData(QList<BaseVersion::Ptr> versions) = 0;
}; };

View File

@ -602,6 +602,7 @@ SET(LAUNCHER_SOURCES
resources/OSX/OSX.qrc resources/OSX/OSX.qrc
resources/iOS/iOS.qrc resources/iOS/iOS.qrc
resources/flat/flat.qrc resources/flat/flat.qrc
resources/flat_white/flat_white.qrc
resources/documents/documents.qrc resources/documents/documents.qrc
../${Launcher_Branding_LogoQRC} ../${Launcher_Branding_LogoQRC}

View File

@ -119,7 +119,7 @@ bool openDirectory(const QString &path, bool ensureExists)
return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak()) if(!isFlatpak())
{ {
return IndirectOpen(f); return IndirectOpen(f);
} }
@ -140,7 +140,7 @@ bool openFile(const QString &path)
return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak()) if(!isFlatpak())
{ {
return IndirectOpen(f); return IndirectOpen(f);
} }
@ -158,7 +158,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo
qDebug() << "Opening file" << path << "using" << application; qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
if(!APPLICATION->isFlatpak()) if(!isFlatpak())
{ {
return IndirectOpen([&]() return IndirectOpen([&]()
{ {
@ -178,7 +178,7 @@ bool run(const QString &application, const QStringList &args, const QString &wor
{ {
qDebug() << "Running" << application << "with args" << args.join(' '); qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak()) if(!isFlatpak())
{ {
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]() return IndirectOpen([&]()
@ -203,7 +203,7 @@ bool openUrl(const QUrl &url)
return QDesktopServices::openUrl(url); return QDesktopServices::openUrl(url);
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak()) if(!isFlatpak())
{ {
return IndirectOpen(f); return IndirectOpen(f);
} }
@ -216,4 +216,13 @@ bool openUrl(const QUrl &url)
#endif #endif
} }
bool isFlatpak()
{
#ifdef Q_OS_LINUX
return QFile::exists("/.flatpak-info");
#else
return false;
#endif
}
} }

View File

@ -33,4 +33,6 @@ namespace DesktopServices
* Open the URL, most likely in a browser. Maybe. * Open the URL, most likely in a browser. Maybe.
*/ */
bool openUrl(const QUrl &url); bool openUrl(const QUrl &url);
bool isFlatpak();
} }

View File

@ -44,6 +44,7 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QTextStream> #include <QTextStream>
#include <QUrl> #include <QUrl>
#include "DesktopServices.h"
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
#include <objbase.h> #include <objbase.h>
@ -182,6 +183,21 @@ bool copy::operator()(const QString& offset)
if (!m_followSymlinks) if (!m_followSymlinks)
opt |= copy_opts::copy_symlinks; opt |= copy_opts::copy_symlinks;
// Function that'll do the actual copying
auto copy_file = [&](QString src_path, QString relative_dst_path) {
if (m_blacklist && m_blacklist->matches(relative_dst_path))
return;
auto dst_path = PathCombine(dst, relative_dst_path);
ensureFilePathExists(dst_path);
fs::copy(toStdString(src_path), toStdString(dst_path), opt, err);
if (err) {
qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
}
};
// We can't use copy_opts::recursive because we need to take into account the // We can't use copy_opts::recursive because we need to take into account the
// blacklisted paths, so we iterate over the source directory, and if there's no blacklist // blacklisted paths, so we iterate over the source directory, and if there's no blacklist
@ -193,20 +209,13 @@ bool copy::operator()(const QString& offset)
auto src_path = source_it.next(); auto src_path = source_it.next();
auto relative_path = src_dir.relativeFilePath(src_path); auto relative_path = src_dir.relativeFilePath(src_path);
if (m_blacklist && m_blacklist->matches(relative_path)) copy_file(src_path, relative_path);
continue;
auto dst_path = PathCombine(dst, relative_path);
ensureFilePathExists(dst_path);
fs::copy(toStdString(src_path), toStdString(dst_path), opt, err);
if (err) {
qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
}
} }
// If the root src is not a directory, the previous iterator won't run.
if (!fs::is_directory(toStdString(src)))
copy_file(src, "");
return err.value() == 0; return err.value() == 0;
} }
@ -228,6 +237,9 @@ bool trash(QString path, QString *pathInTrash = nullptr)
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
return false; return false;
#else #else
// FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal
if (DesktopServices::isFlatpak())
return false;
return QFile::moveToTrash(path, pathInTrash); return QFile::moveToTrash(path, pathInTrash);
#endif #endif
} }
@ -401,6 +413,7 @@ bool overrideFolder(QString overwritten_path, QString override_path)
std::error_code err; std::error_code err;
fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing; 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); fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err);
if (err) { if (err) {

View File

@ -72,7 +72,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
uncompLength *= 2; 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; strm.avail_out = uncompLength - strm.total_out;
// Inflate another chunk. // Inflate another chunk.
@ -129,7 +129,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
{ {
compressedBytes.resize(compressedBytes.size() * 2); 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; temp = zs.avail_out = compressedBytes.size() - offset;
ret = deflate(&zs, Z_FINISH); ret = deflate(&zs, Z_FINISH);
offset += temp - zs.avail_out; offset += temp - zs.avail_out;

View File

@ -42,7 +42,7 @@ public:
} }
void put(QByteArray input) 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 const uint8_t * data() const
{ {

View File

@ -73,7 +73,7 @@ void JavaInstallList::load()
} }
} }
const BaseVersionPtr JavaInstallList::at(int i) const const BaseVersion::Ptr JavaInstallList::at(int i) const
{ {
return m_vlist.at(i); return m_vlist.at(i);
} }
@ -122,7 +122,7 @@ BaseVersionList::RoleList JavaInstallList::providesRoles() const
} }
void JavaInstallList::updateListData(QList<BaseVersionPtr> versions) void JavaInstallList::updateListData(QList<BaseVersion::Ptr> versions)
{ {
beginResetModel(); beginResetModel();
m_vlist = versions; m_vlist = versions;
@ -137,7 +137,7 @@ void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
m_loadTask.reset(); m_loadTask.reset();
} }
bool sortJavas(BaseVersionPtr left, BaseVersionPtr right) bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right)
{ {
auto rleft = std::dynamic_pointer_cast<JavaInstall>(right); auto rleft = std::dynamic_pointer_cast<JavaInstall>(right);
auto rright = std::dynamic_pointer_cast<JavaInstall>(left); auto rright = std::dynamic_pointer_cast<JavaInstall>(left);
@ -210,11 +210,11 @@ void JavaListLoadTask::javaCheckerFinished()
} }
} }
QList<BaseVersionPtr> javas_bvp; QList<BaseVersion::Ptr> javas_bvp;
for (auto java : candidates) for (auto java : candidates)
{ {
//qDebug() << java->id << java->arch << " at " << java->path; //qDebug() << java->id << java->arch << " at " << java->path;
BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java); BaseVersion::Ptr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
if (bp_java) if (bp_java)
{ {

View File

@ -42,7 +42,7 @@ public:
Task::Ptr getLoadTask() override; Task::Ptr getLoadTask() override;
bool isLoaded() override; bool isLoaded() override;
const BaseVersionPtr at(int i) const override; const BaseVersion::Ptr at(int i) const override;
int count() const override; int count() const override;
void sortVersions() override; void sortVersions() override;
@ -50,7 +50,7 @@ public:
RoleList providesRoles() const override; RoleList providesRoles() const override;
public slots: public slots:
void updateListData(QList<BaseVersionPtr> versions) override; void updateListData(QList<BaseVersion::Ptr> versions) override;
protected: protected:
void load(); void load();
@ -59,7 +59,7 @@ protected:
protected: protected:
Status m_status = Status::NotDone; Status m_status = Status::NotDone;
shared_qobject_ptr<JavaListLoadTask> m_loadTask; shared_qobject_ptr<JavaListLoadTask> m_loadTask;
QList<BaseVersionPtr> m_vlist; QList<BaseVersion::Ptr> m_vlist;
}; };
class JavaListLoadTask : public Task class JavaListLoadTask : public Task

View File

@ -379,7 +379,9 @@ QList<QString> JavaUtils::FindJavaPaths()
} }
} }
return addJavasFromEnv(candidates); candidates = addJavasFromEnv(candidates);
candidates.removeDuplicates();
return candidates;
} }
#elif defined(Q_OS_MAC) #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/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
} }
return addJavasFromEnv(javas); javas = addJavasFromEnv(javas);
javas.removeDuplicates();
return javas;
} }
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
@ -448,7 +452,9 @@ QList<QString> JavaUtils::FindJavaPaths()
scanJavaDir("/opt/jdks"); scanJavaDir("/opt/jdks");
// flatpak // flatpak
scanJavaDir("/app/jdk"); scanJavaDir("/app/jdk");
return addJavasFromEnv(javas); javas = addJavasFromEnv(javas);
javas.removeDuplicates();
return javas;
} }
#else #else
QList<QString> JavaUtils::FindJavaPaths() QList<QString> JavaUtils::FindJavaPaths()

View File

@ -84,6 +84,7 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(OSX); Q_INIT_RESOURCE(OSX);
Q_INIT_RESOURCE(iOS); Q_INIT_RESOURCE(iOS);
Q_INIT_RESOURCE(flat); Q_INIT_RESOURCE(flat);
Q_INIT_RESOURCE(flat_white);
return app.exec(); return app.exec();
} }
case Application::Failed: case Application::Failed:

View File

@ -24,7 +24,7 @@ Index::Index(QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
{ {
} }
Index::Index(const QVector<VersionListPtr> &lists, QObject *parent) Index::Index(const QVector<VersionList::Ptr> &lists, QObject *parent)
: QAbstractListModel(parent), m_lists(lists) : QAbstractListModel(parent), m_lists(lists)
{ {
for (int i = 0; i < m_lists.size(); ++i) for (int i = 0; i < m_lists.size(); ++i)
@ -41,7 +41,7 @@ QVariant Index::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
VersionListPtr list = m_lists.at(index.row()); VersionList::Ptr list = m_lists.at(index.row());
switch (role) switch (role)
{ {
case Qt::DisplayRole: case Qt::DisplayRole:
@ -81,9 +81,9 @@ bool Index::hasUid(const QString &uid) const
return m_uids.contains(uid); return m_uids.contains(uid);
} }
VersionListPtr Index::get(const QString &uid) VersionList::Ptr Index::get(const QString &uid)
{ {
VersionListPtr out = m_uids.value(uid, nullptr); VersionList::Ptr out = m_uids.value(uid, nullptr);
if(!out) if(!out)
{ {
out = std::make_shared<VersionList>(uid); out = std::make_shared<VersionList>(uid);
@ -92,7 +92,7 @@ VersionListPtr Index::get(const QString &uid)
return out; return out;
} }
VersionPtr Index::get(const QString &uid, const QString &version) Version::Ptr Index::get(const QString &uid, const QString &version)
{ {
auto list = get(uid); auto list = get(uid);
return list->getVersion(version); return list->getVersion(version);
@ -105,7 +105,7 @@ void Index::parse(const QJsonObject& obj)
void Index::merge(const std::shared_ptr<Index> &other) void Index::merge(const std::shared_ptr<Index> &other)
{ {
const QVector<VersionListPtr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists; const QVector<VersionList::Ptr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
// initial load, no need to merge // initial load, no need to merge
if (m_lists.isEmpty()) if (m_lists.isEmpty())
{ {
@ -120,7 +120,7 @@ void Index::merge(const std::shared_ptr<Index> &other)
} }
else else
{ {
for (const VersionListPtr &list : lists) for (const VersionList::Ptr &list : lists)
{ {
if (m_uids.contains(list->uid())) if (m_uids.contains(list->uid()))
{ {
@ -138,7 +138,7 @@ void Index::merge(const std::shared_ptr<Index> &other)
} }
} }
void Index::connectVersionList(const int row, const VersionListPtr &list) void Index::connectVersionList(const int row, const VersionList::Ptr &list)
{ {
connect(list.get(), &VersionList::nameChanged, this, [this, row]() connect(list.get(), &VersionList::nameChanged, this, [this, row]()
{ {

View File

@ -19,20 +19,19 @@
#include <memory> #include <memory>
#include "BaseEntity.h" #include "BaseEntity.h"
#include "meta/VersionList.h"
class Task; class Task;
namespace Meta namespace Meta
{ {
using VersionListPtr = std::shared_ptr<class VersionList>;
using VersionPtr = std::shared_ptr<class Version>;
class Index : public QAbstractListModel, public BaseEntity class Index : public QAbstractListModel, public BaseEntity
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Index(QObject *parent = nullptr); explicit Index(QObject *parent = nullptr);
explicit Index(const QVector<VersionListPtr> &lists, QObject *parent = nullptr); explicit Index(const QVector<VersionList::Ptr> &lists, QObject *parent = nullptr);
enum enum
{ {
@ -49,21 +48,21 @@ public:
QString localFilename() const override { return "index.json"; } QString localFilename() const override { return "index.json"; }
// queries // queries
VersionListPtr get(const QString &uid); VersionList::Ptr get(const QString &uid);
VersionPtr get(const QString &uid, const QString &version); Version::Ptr get(const QString &uid, const QString &version);
bool hasUid(const QString &uid) const; bool hasUid(const QString &uid) const;
QVector<VersionListPtr> lists() const { return m_lists; } QVector<VersionList::Ptr> lists() const { return m_lists; }
public: // for usage by parsers only public: // for usage by parsers only
void merge(const std::shared_ptr<Index> &other); void merge(const std::shared_ptr<Index> &other);
void parse(const QJsonObject &obj) override; void parse(const QJsonObject &obj) override;
private: private:
QVector<VersionListPtr> m_lists; QVector<VersionList::Ptr> m_lists;
QHash<QString, VersionListPtr> m_uids; QHash<QString, VersionList::Ptr> m_uids;
void connectVersionList(const int row, const VersionListPtr &list); void connectVersionList(const int row, const VersionList::Ptr &list);
}; };
} }

View File

@ -37,11 +37,11 @@ MetadataVersion currentFormatVersion()
static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj) static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
{ {
const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages"); const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
QVector<VersionListPtr> lists; QVector<VersionList::Ptr> lists;
lists.reserve(objects.size()); lists.reserve(objects.size());
std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj) std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
{ {
VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid")); VersionList::Ptr list = std::make_shared<VersionList>(requireString(obj, "uid"));
list->setName(ensureString(obj, "name", QString())); list->setName(ensureString(obj, "name", QString()));
return list; return list;
}); });
@ -49,9 +49,9 @@ static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
} }
// Version // Version
static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj) static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &obj)
{ {
VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version")); Version::Ptr version = std::make_shared<Version>(uid, requireString(obj, "version"));
version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000); version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
version->setType(ensureString(obj, "type", QString())); version->setType(ensureString(obj, "type", QString()));
version->setRecommended(ensureBoolean(obj, QString("recommended"), false)); version->setRecommended(ensureBoolean(obj, QString("recommended"), false));
@ -63,9 +63,9 @@ static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
return version; return version;
} }
static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj) static Version::Ptr parseVersionInternal(const QJsonObject &obj)
{ {
VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj); Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj);
version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj), version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
QString("%1/%2.json").arg(version->uid(), version->version()), QString("%1/%2.json").arg(version->uid(), version->version()),
@ -74,12 +74,12 @@ static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj)
} }
// Version list / package // Version list / package
static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &obj) static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
{ {
const QString uid = requireString(obj, "uid"); const QString uid = requireString(obj, "uid");
const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions"); const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
QVector<VersionPtr> versions; QVector<Version::Ptr> versions;
versions.reserve(versionsRaw.size()); versions.reserve(versionsRaw.size());
std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj) std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
{ {
@ -88,7 +88,7 @@ static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &
return version; return version;
}); });
VersionListPtr list = std::make_shared<VersionList>(uid); VersionList::Ptr list = std::make_shared<VersionList>(uid);
list->setName(ensureString(obj, "name", QString())); list->setName(ensureString(obj, "name", QString()));
list->setVersions(versions); list->setVersions(versions);
return list; return list;

View File

@ -54,7 +54,7 @@ void Meta::Version::parse(const QJsonObject& obj)
parseVersion(obj, this); parseVersion(obj, this);
} }
void Meta::Version::mergeFromList(const Meta::VersionPtr& other) void Meta::Version::mergeFromList(const Meta::Version::Ptr& other)
{ {
if(other->m_providesRecommendations) if(other->m_providesRecommendations)
{ {
@ -85,7 +85,7 @@ void Meta::Version::mergeFromList(const Meta::VersionPtr& other)
} }
} }
void Meta::Version::merge(const VersionPtr &other) void Meta::Version::merge(const Version::Ptr &other)
{ {
mergeFromList(other); mergeFromList(other);
if(other->m_data) if(other->m_data)

View File

@ -30,13 +30,14 @@
namespace Meta namespace Meta
{ {
using VersionPtr = std::shared_ptr<class Version>;
class Version : public QObject, public BaseVersion, public BaseEntity class Version : public QObject, public BaseVersion, public BaseEntity
{ {
Q_OBJECT Q_OBJECT
public: /* con/des */ public:
using Ptr = std::shared_ptr<Version>;
explicit Version(const QString &uid, const QString &version); explicit Version(const QString &uid, const QString &version);
virtual ~Version(); virtual ~Version();
@ -78,8 +79,8 @@ public: /* con/des */
return m_data != nullptr; return m_data != nullptr;
} }
void merge(const VersionPtr &other); void merge(const Version::Ptr &other);
void mergeFromList(const VersionPtr &other); void mergeFromList(const Version::Ptr &other);
void parse(const QJsonObject &obj) override; void parse(const QJsonObject &obj) override;
QString localFilename() const override; QString localFilename() const override;
@ -113,4 +114,4 @@ private:
}; };
} }
Q_DECLARE_METATYPE(Meta::VersionPtr) Q_DECLARE_METATYPE(Meta::Version::Ptr)

View File

@ -40,7 +40,7 @@ bool VersionList::isLoaded()
return BaseEntity::isLoaded(); return BaseEntity::isLoaded();
} }
const BaseVersionPtr VersionList::at(int i) const const BaseVersion::Ptr VersionList::at(int i) const
{ {
return m_versions.at(i); return m_versions.at(i);
} }
@ -52,7 +52,7 @@ int VersionList::count() const
void VersionList::sortVersions() void VersionList::sortVersions()
{ {
beginResetModel(); beginResetModel();
std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b) std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
{ {
return *a.get() < *b.get(); return *a.get() < *b.get();
}); });
@ -66,7 +66,7 @@ QVariant VersionList::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
VersionPtr version = m_versions.at(index.row()); Version::Ptr version = m_versions.at(index.row());
switch (role) switch (role)
{ {
@ -129,9 +129,9 @@ QString VersionList::humanReadable() const
return m_name.isEmpty() ? m_uid : m_name; return m_name.isEmpty() ? m_uid : m_name;
} }
VersionPtr VersionList::getVersion(const QString &version) Version::Ptr VersionList::getVersion(const QString &version)
{ {
VersionPtr out = m_lookup.value(version, nullptr); Version::Ptr out = m_lookup.value(version, nullptr);
if(!out) if(!out)
{ {
out = std::make_shared<Version>(m_uid, version); out = std::make_shared<Version>(m_uid, version);
@ -143,7 +143,7 @@ VersionPtr VersionList::getVersion(const QString &version)
bool VersionList::hasVersion(QString version) const bool VersionList::hasVersion(QString version) const
{ {
auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(), auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(),
[&](Meta::VersionPtr const& a){ return a->version() == version; }); [&](Meta::Version::Ptr const& a){ return a->version() == version; });
return (ver != m_versions.constEnd()); return (ver != m_versions.constEnd());
} }
@ -153,11 +153,11 @@ void VersionList::setName(const QString &name)
emit nameChanged(name); emit nameChanged(name);
} }
void VersionList::setVersions(const QVector<VersionPtr> &versions) void VersionList::setVersions(const QVector<Version::Ptr> &versions)
{ {
beginResetModel(); beginResetModel();
m_versions = versions; m_versions = versions;
std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b) std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
{ {
return a->rawTime() > b->rawTime(); return a->rawTime() > b->rawTime();
}); });
@ -168,7 +168,7 @@ void VersionList::setVersions(const QVector<VersionPtr> &versions)
} }
// FIXME: this is dumb, we have 'recommended' as part of the metadata already... // FIXME: this is dumb, we have 'recommended' as part of the metadata already...
auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; }); auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr &ptr) { return ptr->type() == "release"; });
m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt; m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
endResetModel(); endResetModel();
} }
@ -179,7 +179,7 @@ void VersionList::parse(const QJsonObject& obj)
} }
// FIXME: this is dumb, we have 'recommended' as part of the metadata already... // FIXME: this is dumb, we have 'recommended' as part of the metadata already...
static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const Meta::VersionPtr &b) static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, const Meta::Version::Ptr &b)
{ {
if(!a) if(!a)
return b; return b;
@ -194,7 +194,7 @@ static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const
return (a->type() == "release" ? a : b); return (a->type() == "release" ? a : b);
} }
void VersionList::mergeFromIndex(const VersionListPtr &other) void VersionList::mergeFromIndex(const VersionList::Ptr &other)
{ {
if (m_name != other->m_name) if (m_name != other->m_name)
{ {
@ -202,7 +202,7 @@ void VersionList::mergeFromIndex(const VersionListPtr &other)
} }
} }
void VersionList::merge(const VersionListPtr &other) void VersionList::merge(const VersionList::Ptr &other)
{ {
if (m_name != other->m_name) if (m_name != other->m_name)
{ {
@ -216,7 +216,7 @@ void VersionList::merge(const VersionListPtr &other)
{ {
qWarning() << "Empty list loaded ..."; qWarning() << "Empty list loaded ...";
} }
for (const VersionPtr &version : other->m_versions) for (const Version::Ptr &version : other->m_versions)
{ {
// we already have the version. merge the contents // we already have the version. merge the contents
if (m_lookup.contains(version->version())) if (m_lookup.contains(version->version()))
@ -235,7 +235,7 @@ void VersionList::merge(const VersionListPtr &other)
endResetModel(); endResetModel();
} }
void VersionList::setupAddedVersion(const int row, const VersionPtr &version) void VersionList::setupAddedVersion(const int row, const Version::Ptr &version)
{ {
// FIXME: do not disconnect from everythin, disconnect only the lambdas here // FIXME: do not disconnect from everythin, disconnect only the lambdas here
version->disconnect(); version->disconnect();
@ -244,7 +244,7 @@ void VersionList::setupAddedVersion(const int row, const VersionPtr &version)
connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); }); connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
} }
BaseVersionPtr VersionList::getRecommended() const BaseVersion::Ptr VersionList::getRecommended() const
{ {
return m_recommended; return m_recommended;
} }

View File

@ -20,10 +20,10 @@
#include <QJsonObject> #include <QJsonObject>
#include <memory> #include <memory>
#include "meta/Version.h"
namespace Meta namespace Meta
{ {
using VersionPtr = std::shared_ptr<class Version>;
using VersionListPtr = std::shared_ptr<class VersionList>;
class VersionList : public BaseVersionList, public BaseEntity class VersionList : public BaseVersionList, public BaseEntity
{ {
@ -33,6 +33,8 @@ class VersionList : public BaseVersionList, public BaseEntity
public: public:
explicit VersionList(const QString &uid, QObject *parent = nullptr); explicit VersionList(const QString &uid, QObject *parent = nullptr);
using Ptr = std::shared_ptr<VersionList>;
enum Roles enum Roles
{ {
UidRole = Qt::UserRole + 100, UidRole = Qt::UserRole + 100,
@ -43,11 +45,11 @@ public:
Task::Ptr getLoadTask() override; Task::Ptr getLoadTask() override;
bool isLoaded() override; bool isLoaded() override;
const BaseVersionPtr at(int i) const override; const BaseVersion::Ptr at(int i) const override;
int count() const override; int count() const override;
void sortVersions() override; void sortVersions() override;
BaseVersionPtr getRecommended() const override; BaseVersion::Ptr getRecommended() const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
RoleList providesRoles() const override; RoleList providesRoles() const override;
@ -65,38 +67,38 @@ public:
} }
QString humanReadable() const; QString humanReadable() const;
VersionPtr getVersion(const QString &version); Version::Ptr getVersion(const QString &version);
bool hasVersion(QString version) const; bool hasVersion(QString version) const;
QVector<VersionPtr> versions() const QVector<Version::Ptr> versions() const
{ {
return m_versions; return m_versions;
} }
public: // for usage only by parsers public: // for usage only by parsers
void setName(const QString &name); void setName(const QString &name);
void setVersions(const QVector<VersionPtr> &versions); void setVersions(const QVector<Version::Ptr> &versions);
void merge(const VersionListPtr &other); void merge(const VersionList::Ptr &other);
void mergeFromIndex(const VersionListPtr &other); void mergeFromIndex(const VersionList::Ptr &other);
void parse(const QJsonObject &obj) override; void parse(const QJsonObject &obj) override;
signals: signals:
void nameChanged(const QString &name); void nameChanged(const QString &name);
protected slots: protected slots:
void updateListData(QList<BaseVersionPtr>) override void updateListData(QList<BaseVersion::Ptr>) override
{ {
} }
private: private:
QVector<VersionPtr> m_versions; QVector<Version::Ptr> m_versions;
QHash<QString, VersionPtr> m_lookup; QHash<QString, Version::Ptr> m_lookup;
QString m_uid; QString m_uid;
QString m_name; QString m_name;
VersionPtr m_recommended; Version::Ptr m_recommended;
void setupAddedVersion(const int row, const VersionPtr &version); void setupAddedVersion(const int row, const Version::Ptr &version);
}; };
} }
Q_DECLARE_METATYPE(Meta::VersionListPtr) Q_DECLARE_METATYPE(Meta::VersionList::Ptr)

View File

@ -7,7 +7,7 @@
#include "minecraft/PackProfile.h" #include "minecraft/PackProfile.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
VanillaCreationTask::VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version) VanillaCreationTask::VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version)
: InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version)) : InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version))
{} {}

View File

@ -7,16 +7,16 @@
class VanillaCreationTask final : public InstanceCreationTask { class VanillaCreationTask final : public InstanceCreationTask {
Q_OBJECT Q_OBJECT
public: public:
VanillaCreationTask(BaseVersionPtr version) : InstanceCreationTask(), m_version(std::move(version)) {} VanillaCreationTask(BaseVersion::Ptr version) : InstanceCreationTask(), m_version(std::move(version)) {}
VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version); VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version);
bool createInstance() override; bool createInstance() override;
private: private:
// Version to update to / create of the instance. // Version to update to / create of the instance.
BaseVersionPtr m_version; BaseVersion::Ptr m_version;
bool m_using_loader = false; bool m_using_loader = false;
QString m_loader; QString m_loader;
BaseVersionPtr m_loader_version; BaseVersion::Ptr m_loader_version;
}; };

View File

@ -71,5 +71,7 @@ void VerifyJavaInstall::executeTask() {
{ {
emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); emit logLine(tr("Java version %1").arg(major), MessageLevel::Error);
} }
emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error);
emitFailed(QString("Incompatible Java major version")); emitFailed(QString("Incompatible Java major version"));
} }

View File

@ -58,7 +58,7 @@
namespace ATLauncher { namespace ATLauncher {
static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version); static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version);
PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode) PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode)
{ {
@ -736,7 +736,12 @@ void PackInstallTask::downloadMods()
QVector<QString> selectedMods; QVector<QString> selectedMods;
if (!optionalMods.isEmpty()) { if (!optionalMods.isEmpty()) {
setStatus(tr("Selecting optional mods...")); setStatus(tr("Selecting optional mods..."));
selectedMods = m_support->chooseOptionalMods(m_version, optionalMods); auto mods = m_support->chooseOptionalMods(m_version, optionalMods);
if (!mods.has_value()) {
emitAborted();
return;
}
selectedMods = mods.value();
} }
setStatus(tr("Downloading mods...")); setStatus(tr("Downloading mods..."));
@ -1032,7 +1037,7 @@ void PackInstallTask::install()
emitSucceeded(); emitSucceeded();
} }
static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version) static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version)
{ {
auto vlist = APPLICATION->metadataIndex()->get(uid); auto vlist = APPLICATION->metadataIndex()->get(uid);
if (!vlist) if (!vlist)

View File

@ -62,13 +62,13 @@ public:
/** /**
* Requests a user interaction to select which optional mods should be installed. * Requests a user interaction to select which optional mods should be installed.
*/ */
virtual QVector<QString> chooseOptionalMods(PackVersion version, QVector<ATLauncher::VersionMod> mods) = 0; virtual std::optional<QVector<QString>> chooseOptionalMods(PackVersion version, QVector<ATLauncher::VersionMod> mods) = 0;
/** /**
* Requests a user interaction to select a component version from a given version list * Requests a user interaction to select a component version from a given version list
* and constrained to a given Minecraft version. * and constrained to a given Minecraft version.
*/ */
virtual QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) = 0; virtual QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) = 0;
/** /**
* Requests a user interaction to display a message. * Requests a user interaction to display a message.
@ -137,8 +137,8 @@ private:
QString archivePath; QString archivePath;
QStringList jarmods; QStringList jarmods;
Meta::VersionPtr minecraftVersion; Meta::Version::Ptr minecraftVersion;
QMap<QString, Meta::VersionPtr> componentsToInstall; QMap<QString, Meta::Version::Ptr> componentsToInstall;
QFuture<std::optional<QStringList>> m_extractFuture; QFuture<std::optional<QStringList>> m_extractFuture;
QFutureWatcher<std::optional<QStringList>> m_extractFutureWatcher; QFutureWatcher<std::optional<QStringList>> m_extractFutureWatcher;

View File

@ -3,6 +3,8 @@
#include "Json.h" #include "Json.h"
#include "net/Upload.h" #include "net/Upload.h"
#include "modplatform/modrinth/ModrinthPackIndex.h"
Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess) Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess)
: m_network(network), m_toProcess(toProcess) : m_network(network), m_toProcess(toProcess)
{} {}
@ -12,6 +14,8 @@ bool Flame::FileResolvingTask::abort()
bool aborted = true; bool aborted = true;
if (m_dljob) if (m_dljob)
aborted &= m_dljob->abort(); aborted &= m_dljob->abort();
if (m_checkJob)
aborted &= m_checkJob->abort();
return aborted ? Task::abort() : false; return aborted ? Task::abort() : false;
} }
@ -40,7 +44,7 @@ void Flame::FileResolvingTask::netJobFinished()
setProgress(1, 3); setProgress(1, 3);
int index = 0; int index = 0;
// job to check modrinth for blocked projects // job to check modrinth for blocked projects
auto job = new NetJob("Modrinth check", m_network); m_checkJob = new NetJob("Modrinth check", m_network);
blockedProjects = QMap<File *,QByteArray *>(); blockedProjects = QMap<File *,QByteArray *>();
auto doc = Json::requireDocument(*result); auto doc = Json::requireDocument(*result);
auto array = Json::requireArray(doc.object()["data"]); auto array = Json::requireArray(doc.object()["data"]);
@ -60,15 +64,15 @@ void Flame::FileResolvingTask::netJobFinished()
out.resolved = true; out.resolved = true;
}); });
job->addNetAction(dl); m_checkJob->addNetAction(dl);
blockedProjects.insert(&out, output); blockedProjects.insert(&out, output);
} }
} }
index++; index++;
} }
connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
job->start(); m_checkJob->start();
} }
void Flame::FileResolvingTask::modrinthCheckFinished() { void Flame::FileResolvingTask::modrinthCheckFinished() {
@ -82,18 +86,21 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
delete bytes; delete bytes;
continue; continue;
} }
QJsonDocument doc = QJsonDocument::fromJson(*bytes); QJsonDocument doc = QJsonDocument::fromJson(*bytes);
auto obj = doc.object(); auto obj = doc.object();
auto array = Json::requireArray(obj,"files"); auto file = Modrinth::loadIndexedPackVersion(obj);
for (auto file: array) {
auto fileObj = Json::requireObject(file); // If there's more than one mod loader for this version, we can't know for sure
auto primary = Json::requireBoolean(fileObj,"primary"); // which file is relative to each loader, so it's best to not use any one and
if (primary) { // let the user download it manually.
out->url = Json::requireUrl(fileObj,"url"); if (file.loaders.size() <= 1) {
qDebug() << "Found alternative on modrinth " << out->fileName; out->url = file.downloadUrl;
break; qDebug() << "Found alternative on modrinth " << out->fileName;
} } else {
out->resolved = false;
} }
delete bytes; delete bytes;
} }
//copy to an output list and filter out projects found on modrinth //copy to an output list and filter out projects found on modrinth

View File

@ -30,8 +30,9 @@ protected slots:
private: /* data */ private: /* data */
shared_qobject_ptr<QNetworkAccessManager> m_network; shared_qobject_ptr<QNetworkAccessManager> m_network;
Flame::Manifest m_toProcess; Flame::Manifest m_toProcess;
std::shared_ptr<QByteArray> result; std::shared_ptr<QByteArray> result;
NetJob::Ptr m_dljob; NetJob::Ptr m_dljob;
NetJob::Ptr m_checkJob;
void modrinthCheckFinished(); void modrinthCheckFinished();

View File

@ -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::started, caller, [caller, netJob] { caller->setActiveJob(netJob); });
QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed);
QObject::connect(netJob, &NetJob::aborted, caller, &CallerType::searchRequestAborted);
QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] {
QJsonParseError parse_error{}; QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);

View File

@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3. * the Free Software Foundation, version 3.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "ModrinthPackIndex.h" #include "ModrinthPackIndex.h"
#include "ModrinthAPI.h" #include "ModrinthAPI.h"
@ -59,23 +59,23 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj) void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{ {
pack.extraData.issuesUrl = Json::ensureString(obj, "issues_url"); 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.issuesUrl.chop(1);
pack.extraData.sourceUrl = Json::ensureString(obj, "source_url"); 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.sourceUrl.chop(1);
pack.extraData.wikiUrl = Json::ensureString(obj, "wiki_url"); 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.wikiUrl.chop(1);
pack.extraData.discordUrl = Json::ensureString(obj, "discord_url"); pack.extraData.discordUrl = Json::ensureString(obj, "discord_url");
if(pack.extraData.discordUrl.endsWith('/')) if (pack.extraData.discordUrl.endsWith('/'))
pack.extraData.discordUrl.chop(1); pack.extraData.discordUrl.chop(1);
auto donate_arr = Json::ensureArray(obj, "donation_urls"); auto donate_arr = Json::ensureArray(obj, "donation_urls");
for(auto d : donate_arr){ for (auto d : donate_arr) {
auto d_obj = Json::requireObject(d); auto d_obj = Json::requireObject(d);
ModPlatform::DonationData donate; ModPlatform::DonationData donate;
@ -104,7 +104,7 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
auto obj = versionIter.toObject(); auto obj = versionIter.toObject();
auto file = loadIndexedPackVersion(obj); 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); unsortedVersions.append(file);
} }
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
@ -116,7 +116,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
pack.versionsLoaded = true; 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; ModPlatform::IndexedVersion file;
@ -141,6 +142,12 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t
auto files = Json::requireArray(obj, "files"); auto files = Json::requireArray(obj, "files");
int i = 0; 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) // 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 // Will default to the last one if there's no primary (though I think Modrinth requires that
// at least one file is primary, idk) // at least one file is primary, idk)

View File

@ -38,5 +38,6 @@
<file>scalable/tag.svg</file> <file>scalable/tag.svg</file>
<file>scalable/export.svg</file> <file>scalable/export.svg</file>
<file>scalable/rename.svg</file> <file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="Calque_1"
x="0px"
y="0px"
viewBox="0 0 32.099998 32"
enable-background="new 0 0 32 32"
xml:space="preserve"
width="32.099998"
height="32"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs45" />
<rect
fill-rule="evenodd"
clip-rule="evenodd"
fill="none"
width="32"
height="32"
id="rect1776"
x="0.1"
y="0" /><path
fill="#b6b5b6"
d="M 30,28.4 H 2 c -1.1,0 -2,-0.9 -2,-2 v -18 c 0,-1.1 0.9,-2 2,-2 h 28 c 1.1,0 2,0.9 2,2 v 18 c 0,1.1 -0.9,2 -2,2 z"
id="path1778" /><path
fill="#fbfbfb"
d="M 30,27.4 H 2 c -1.1,0 -2,-0.9 -2,-2 v -17 c 0,-1.1 0.9,-2 2,-2 h 28 c 1.1,0 2,0.9 2,2 v 17 c 0,1.1 -0.9,2 -2,2 z"
id="path1780" /><path
id="path11889"
style="color:#000000;fill:#585858;fill-opacity:1;stroke-width:0.999994;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
d="m 11.520289,8.4637512 c -0.06474,-0.00183 -0.129661,-0.00125 -0.194234,0.00117 C 9.7763279,8.5230552 8.3049,9.7900155 8.3049,11.461507 v 10.877094 c -6e-7,2.228655 2.616628,3.738089 4.545774,2.622156 l 9.398109,-5.436205 c 1.928423,-1.115516 1.928423,-4.133479 0,-5.248993 L 12.850674,8.839348 C 12.428673,8.595238 11.973493,8.4765655 11.520289,8.4637512 Z m -0.184873,1.2309276 c 0.307885,1.456e-4 0.612521,0.080796 0.882242,0.2363567 a 0.89871379,0.89871379 0 0 0 0.0012,0 l 9.398109,5.4362075 c 1.143234,0.659415 1.143234,2.406201 0,3.065618 l -9.398109,5.436206 a 0.89871379,0.89871379 0 0 0 -0.0012,0 C 11.076744,24.528497 9.5659235,23.656375 9.56625,22.338599 V 11.461504 c 3.043e-4,-0.851902 0.622381,-1.5925143 1.461434,-1.7399133 0.102209,-0.018038 0.205103,-0.026958 0.307732,-0.026912 z" /></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -37,17 +37,21 @@
</cc:Agent> </cc:Agent>
</dc:contributor> </dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source> <dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
<dc:rights>
<cc:Agent>
<dc:title>CC BY-SA 4.0</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher> <dc:publisher>
<cc:Agent> <cc:Agent>
<dc:title>Prism Launcher</dc:title> <dc:title>Prism Launcher</dc:title>
</cc:Agent> </cc:Agent>
</dc:publisher> </dc:publisher>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work> </cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
</cc:License>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,8 +1,14 @@
<!DOCTYPE RCC> <!DOCTYPE RCC>
<RCC version="1.0"> <RCC version="1.0">
<qresource prefix="/backgrounds"> <qresource prefix="/backgrounds">
<file alias="kitteh">catbgrnd2.png</file> <file alias="kitteh">kitteh.png</file>
<file alias="catmas">catmas.png</file> <file alias="kitteh-xmas">kitteh-xmas.png</file>
<file alias="cattiversary">cattiversary.png</file> <file alias="kitteh-bday">kitteh-bday.png</file>
<file alias="rory">rory.png</file>
<file alias="rory-xmas">rory-xmas.png</file>
<file alias="rory-bday">rory-bday.png</file>
<file alias="rory-flat">rory-flat.png</file>
<file alias="rory-flat-xmas">rory-flat-xmas.png</file>
<file alias="rory-flat-bday">rory-flat-bday.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -46,5 +46,6 @@
<file>scalable/tag.svg</file> <file>scalable/tag.svg</file>
<file>scalable/export.svg</file> <file>scalable/export.svg</file>
<file>scalable/rename.svg</file> <file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#757575"
height="48"
width="48"
version="1.1"
id="svg24108"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs24112" />
<path
d="M 11.674384,43.35533 V 4.3446706 L 42.325617,23.850001 Z"
id="path24106"
style="stroke-width:1" />
</svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@ -37,17 +37,21 @@
</cc:Agent> </cc:Agent>
</dc:contributor> </dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source> <dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
<dc:rights>
<cc:Agent>
<dc:title>CC BY-SA 4.0</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher> <dc:publisher>
<cc:Agent> <cc:Agent>
<dc:title>Prism Launcher</dc:title> <dc:title>Prism Launcher</dc:title>
</cc:Agent> </cc:Agent>
</dc:publisher> </dc:publisher>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work> </cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
</cc:License>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,51 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/icons/flat_white">
<file>index.theme</file>
<file>scalable/about.svg</file>
<file>scalable/accounts.svg</file>
<file>scalable/bug.svg</file>
<file>scalable/cat.svg</file>
<file>scalable/centralmods.svg</file>
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/discord.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
<file>scalable/jarmods.svg</file>
<file>scalable/java.svg</file>
<file>scalable/language.svg</file>
<file>scalable/launcher.svg</file>
<file>scalable/loadermods.svg</file>
<file>scalable/log.svg</file>
<file>scalable/minecraft.svg</file>
<file>scalable/new.svg</file>
<file>scalable/news.svg</file>
<file>scalable/notes.svg</file>
<file>scalable/packages.svg</file>
<file>scalable/proxy.svg</file>
<file>scalable/quickmods.svg</file>
<file>scalable/reddit-alien.svg</file>
<file>scalable/refresh.svg</file>
<file>scalable/resourcepacks.svg</file>
<file>scalable/shaderpacks.svg</file>
<file>scalable/screenshot-placeholder.svg</file>
<file>scalable/screenshots.svg</file>
<file>scalable/settings.svg</file>
<file>scalable/star.svg</file>
<file>scalable/status-bad.svg</file>
<file>scalable/status-good.svg</file>
<file>scalable/status-running.svg</file>
<file>scalable/status-yellow.svg</file>
<file>scalable/viewfolder.svg</file>
<file>scalable/worlds.svg</file>
<file>scalable/delete.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/tag.svg</file>
<file>scalable/launch.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,11 @@
[Icon Theme]
Name=Flat (White)
Comment=White version of the flat icons (dark mode)
Inherits=multimc
Directories=scalable
[scalable]
Size=48
Type=Scalable
MinSize=16
MaxSize=256

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"/>
</svg>

After

Width:  |  Height:  |  Size: 321 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M16,13C15.71,13 15.38,13 15.03,13.05C16.19,13.89 17,15 17,16.5V19H23V16.5C23,14.17 18.33,13 16,13M8,13C5.67,13 1,14.17 1,16.5V19H15V16.5C15,14.17 10.33,13 8,13M8,11A3,3 0 0,0 11,8A3,3 0 0,0 8,5A3,3 0 0,0 5,8A3,3 0 0,0 8,11M16,11A3,3 0 0,0 19,8A3,3 0 0,0 16,5A3,3 0 0,0 13,8A3,3 0 0,0 16,11Z"/>
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/>
</svg>

After

Width:  |  Height:  |  Size: 496 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,8L10.67,8.09C9.81,7.07 7.4,4.5 5,4.5C5,4.5 3.03,7.46 4.96,11.41C4.41,12.24 4.07,12.67 4,13.66L2.07,13.95L2.28,14.93L4.04,14.67L4.18,15.38L2.61,16.32L3.08,17.21L4.53,16.32C5.68,18.76 8.59,20 12,20C15.41,20 18.32,18.76 19.47,16.32L20.92,17.21L21.39,16.32L19.82,15.38L19.96,14.67L21.72,14.93L21.93,13.95L20,13.66C19.93,12.67 19.59,12.24 19.04,11.41C20.97,7.46 19,4.5 19,4.5C16.6,4.5 14.19,7.07 13.33,8.09L12,8M9,11A1,1 0 0,1 10,12A1,1 0 0,1 9,13A1,1 0 0,1 8,12A1,1 0 0,1 9,11M15,11A1,1 0 0,1 16,12A1,1 0 0,1 15,13A1,1 0 0,1 14,12A1,1 0 0,1 15,11M11,14H13L12.3,15.39C12.5,16.03 13.06,16.5 13.75,16.5A1.5,1.5 0 0,0 15.25,15H15.75A2,2 0 0,1 13.75,17C13,17 12.35,16.59 12,16V16H12C11.65,16.59 11,17 10.25,17A2,2 0 0,1 8.25,15H8.75A1.5,1.5 0 0,0 10.25,16.5C10.94,16.5 11.5,16.03 11.7,15.39L11,14Z"/>
</svg>

After

Width:  |  Height:  |  Size: 914 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-2.06 11L15 15.28 12.06 17l.78-3.33-2.59-2.24 3.41-.29L15 8l1.34 3.14 3.41.29-2.59 2.24.78 3.33z"/>
</svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1-2.73 2.71-2.73 7.08 0 9.79 2.73 2.71 7.15 2.71 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58 3.51-3.47 9.14-3.47 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/>
</svg>

After

Width:  |  Height:  |  Size: 265 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M22,12A10,10,0,1,1,12,2,10,10,0,0,1,22,12ZM12,4a8,8,0,1,0,8,8A8,8,0,0,0,12,4Zm4.23,14-1.12-4.82,3.73-3.23-4.92-.42L12,5,10.08,9.54,5.16,10l3.73,3.23L7.77,18,12,15.45,16.23,18"/>
</svg>

After

Width:  |  Height:  |  Size: 296 B

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#D8DEE9"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="custom-commands.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1382"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="39.333333"
inkscape:cx="11.38983"
inkscape:cy="13.283898"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
<g
id="g503">
<path
d="M 0,0 H 24 V 24 H 0 Z"
fill="none"
id="path491" />
<path
d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
id="path493" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs8"/>
<path id="path5145" style="fill:#D8DEE9;fill-opacity:1;stroke:none;stroke-width:1.4;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none" d="M 7.1074219 0.96484375 L 7.1074219 2.7304688 L 2.6132812 2.7304688 L 2.6132812 4.4960938 L 21.386719 4.4960938 L 21.386719 2.7304688 L 16.892578 2.7304688 L 16.892578 0.96484375 L 7.1074219 0.96484375 z M 5.0058594 6.0839844 L 5.0058594 22.859375 L 18.994141 22.859375 L 18.994141 6.0839844 L 5.0058594 6.0839844 z M 7.9160156 9.0605469 L 10.193359 9.0605469 L 10.193359 19.882812 L 7.9160156 19.882812 L 7.9160156 9.0605469 z M 13.804688 9.0605469 L 16.085938 9.0605469 L 16.085938 19.882812 L 13.804688 19.882812 L 13.804688 9.0605469 z "/>
</svg>

After

Width:  |  Height:  |  Size: 943 B

View File

@ -0,0 +1,4 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M10.14,11.63a1.15,1.15,0,1,0,1,1.14A1.1,1.1,0,0,0,10.14,11.63Zm3.75,0a1.15,1.15,0,1,0,1,1.14A1.1,1.1,0,0,0,13.89,11.63Z"/>
<path d="M18.89,3H5.11A2.11,2.11,0,0,0,3,5.12V19a2.11,2.11,0,0,0,2.11,2.12H16.77l-.55-1.9,1.32,1.22,1.24,1.15,2.21,2V5.12A2.11,2.11,0,0,0,18.89,3Zm-4,13.43s-.37-.44-.68-.83a3.25,3.25,0,0,0,1.86-1.22,5.89,5.89,0,0,1-1.18.61,6.77,6.77,0,0,1-1.49.44,7.21,7.21,0,0,1-2.66,0A8.63,8.63,0,0,1,9.25,15a6,6,0,0,1-.75-.35l-.09-.05,0,0-.29-.17a3.2,3.2,0,0,0,1.8,1.21l-.69.85a3.73,3.73,0,0,1-3.14-1.56,13.77,13.77,0,0,1,1.48-6,5.09,5.09,0,0,1,2.89-1.08l.1.12A6.94,6.94,0,0,0,7.82,9.26s.23-.12.61-.3a7.72,7.72,0,0,1,2.33-.65l.17,0a8.7,8.7,0,0,1,2.08,0,8.38,8.38,0,0,1,3.1,1A6.85,6.85,0,0,0,13.55,8l.14-.16a5.09,5.09,0,0,1,2.89,1.08,13.77,13.77,0,0,1,1.48,6A3.76,3.76,0,0,1,14.92,16.43Z"/>
</svg>

After

Width:  |  Height:  |  Size: 921 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs8"/>
<path id="path2" d="M 4 4 C 2.9000011 4 2.0097656 4.9000011 2.0097656 6 L 2 18 C 2 19.099999 2.9000011 20 4 20 L 20 20 C 21.099999 20 22 19.099999 22 18 L 22 8 C 22 6.9000011 21.099999 6 20 6 L 12 6 L 10 4 L 4 4 z M 12.537109 9.9082031 L 13.185547 10.298828 L 17.554688 12.929688 L 13.185547 15.5625 L 12.537109 15.953125 L 11.755859 14.65625 L 12.404297 14.265625 L 13.349609 13.695312 L 6.4453125 13.695312 L 6.4453125 12.166016 L 13.351562 12.166016 L 12.404297 11.595703 L 11.755859 11.205078 L 12.537109 9.9082031 z "/>
</svg>

After

Width:  |  Height:  |  Size: 771 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M22.7,19L13.6,9.9C14.5,7.6 14,4.9 12.1,3C10.1,1 7.1,0.6 4.7,1.7L9,6L6,9L1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1C4.8,14 7.5,14.5 9.8,13.6L18.9,22.7C19.3,23.1 19.9,23.1 20.3,22.7L22.6,20.4C23.1,20 23.1,19.3 22.7,19Z"/>
</svg>

After

Width:  |  Height:  |  Size: 329 B

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg4"
version="1.1"
width="24"
viewBox="0 0 24 24"
height="24"
fill="#D8DEE9">
<path
d="m 15.07,11.25 -0.9,0.92 C 13.45,12.89 13,13.5 13,15 h -2 v -0.5 c 0,-1.11 0.45,-2.11 1.17,-2.83 l 1.24,-1.26 C 13.78,10.049999 14,9.549999 14,9 14,7.89 13.100001,7 12,7 A 2,2 0 0 0 10,9 H 7.9999995 A 4,4 0 0 1 12,5 4,4 0 0 1 16,9 c 0,0.879999 -0.36,1.67 -0.93,2.25 M 13,19 h -2 v -2 h 2 M 12,2 A 10,10 0 0 0 1.9999995,12 10,10 0 0 0 12,22 10,10 0 0 0 22,12 C 22,6.47 17.5,2 12,2 Z"
id="path817" />
</svg>

After

Width:  |  Height:  |  Size: 818 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M2,21H20V19H2M20,8H18V5h2m0-2H4V13a4,4,0,0,0,4,4h6a4,4,0,0,0,4-4V10h2a2,2,0,0,0,2-2V5A2,2,0,0,0,20,3ZM11,4.43l1.62,3.29,3.63.53-2.63,2.56.62,3.62L11,12.72,7.75,14.43l.62-3.62L5.74,8.25l3.63-.53Z"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M2,21H20V19H2M20,8H18V5H20M20,3H4V13A4,4 0 0,0 8,17H14A4,4 0 0,0 18,13V10H20A2,2 0 0,0 22,8V5C22,3.89 21.1,3 20,3Z"/>
</svg>

After

Width:  |  Height:  |  Size: 236 B

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
fill="#D8DEE9"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="language.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8">
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2123"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="6.9532167"
inkscape:cx="-18.49351"
inkscape:cy="-12.477971"
inkscape:window-x="1200"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<path
d="M 5,3 C 3.89,3 3,3.89 3,5 v 14 c 0,1.104569 0.895431,2 2,2 h 14 c 1.104569,0 2,-0.895431 2,-2 V 5 C 21,3.89 20.1,3 19,3 Z m 10.359375,4.505859 c 0.400344,0 0.726563,0.326845 0.726563,0.728516 v 0.724609 h 2.21875 c 0.400344,0 0.726562,0.326845 0.726562,0.728516 0,0.401669 -0.326217,0.726562 -0.726562,0.726562 h -0.191407 c -0.412128,1.326612 -1.066893,2.363281 -1.746093,3.181641 0.53207,0.488052 1.100334,0.887517 1.666015,1.335938 0.311924,0.250518 0.365651,0.709744 0.115235,1.023437 -0.249259,0.313205 -0.708226,0.362473 -1.019532,0.111328 -0.614642,-0.486742 -1.192601,-0.892661 -1.769531,-1.423828 -0.576929,0.531167 -1.104107,0.937086 -1.71875,1.423828 -0.311303,0.251148 -0.768322,0.201879 -1.017578,-0.111328 -0.250416,-0.313693 -0.200604,-0.772919 0.111328,-1.023437 0.565677,-0.448421 1.087072,-0.847886 1.619141,-1.335938 -0.679199,-0.818312 -1.283234,-1.854981 -1.695313,-3.181641 h -0.197265 c -0.400344,0 -0.720704,-0.324893 -0.720704,-0.726562 0,-0.401671 0.320361,-0.728516 0.720704,-0.728516 h 2.173828 V 8.234375 c 0,-0.401671 0.324264,-0.728516 0.724609,-0.728516 z M 7.142578,7.800781 h 1.496094 c 0.345155,0 0.643047,0.243927 0.710937,0.582031 l 1.447266,7.244141 c 0.07851,0.39257 -0.174512,0.773053 -0.566406,0.851563 -0.384074,0.07905 -0.774336,-0.168718 -0.853516,-0.566407 L 8.914062,13.595703 H 6.867188 L 6.402344,15.912109 C 6.324551,16.303955 5.947553,16.559826 5.550781,16.478516 5.158934,16.400005 4.905865,16.019523 4.984375,15.626953 L 6.431641,8.382812 C 6.499536,8.044708 6.797425,7.800781 7.142578,7.800781 Z m 0.4375,1.632813 -0.578125,2.898437 H 8.46875 L 7.890625,9.433594 Z m 6.589844,0.980468 c 0.312752,0.842923 0.729088,1.524886 1.189453,2.105469 0.460366,-0.580583 0.925527,-1.262594 1.238281,-2.105469 z"
id="path1072"
inkscape:connector-curvature="0" />
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#D8DEE9"
height="48"
width="48"
version="1.1"
id="svg24108"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs24112" />
<path
d="M 11.674384,43.35533 V 4.3446706 L 42.325617,23.850001 Z"
id="path24106"
style="stroke-width:1" />
</svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" fill="#D8DEE9" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m20 4h-16v16h16zm0 18h-16c-1.1046 0-2-0.89543-2-2v-16c0-1.1046 0.89543-2 2-2h16c1.1046 0 2 0.89543 2 2v16c0 1.1046-0.89543 2-2 2z"/><path d="m7.2 18c-0.225 0-0.45-0.075-0.6-0.15-0.375-0.225-0.6-0.6-0.6-1.05v-9.6c0-0.45 0.225-0.825 0.6-1.05 0.225-0.15 0.375-0.15 0.6-0.15 0.15 0 0.375 0.075 0.525 0.15l9.6 4.8c0.375 0.225 0.675 0.6 0.675 1.05 0 0.45-0.225 0.9-0.675 1.05l-9.6 4.8c-0.15 0.075-0.375 0.15-0.525 0.15z" clip-rule="evenodd" fill="#D8DEE9" fill-rule="evenodd" stroke-width=".99999"/></svg>

After

Width:  |  Height:  |  Size: 660 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M16.23,18l-1.12-4.82,3.73-3.23-4.92-.42L12,5,10.08,9.54,5.16,10l3.73,3.23L7.77,18,12,15.45,16.23,18M20,4H4V20H20Zm0,18H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2H20a2,2,0,0,1,2,2V20A2,2,0,0,1,20,22Z"/>
</svg>

After

Width:  |  Height:  |  Size: 309 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>
</svg>

After

Width:  |  Height:  |  Size: 248 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V9.21L13,12.58V19.29L19,15.91Z"/>
</svg>

After

Width:  |  Height:  |  Size: 529 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0,2A2,2,0,0,1,2,0H22a2,2,0,0,1,2,2V8L22,8V6H20V8H18v2H16V8H14V6H12V8H10V6H8v4H6V8H4V6H2V8H0ZM0,22a2,2,0,0,0,2,2H22a2,2,0,0,0,2-2V10H22V22H2V10H0Zm18.71-3.29a3.83,3.83,0,0,0-5.41-5.41L12,14.59l-1.29-1.29a3.83,3.83,0,1,0,0,5.41L12,17.41l1.29,1.29a3.83,3.83,0,0,0,5.41,0Zm-4-4a1.83,1.83,0,1,1,0,2.59L13.41,16Zm-5.41,0L10.59,16,9.29,17.29a1.83,1.83,0,1,1,0-2.59Z"/>
</svg>

After

Width:  |  Height:  |  Size: 481 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/>
</svg>

After

Width:  |  Height:  |  Size: 235 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M20,11H4V8H20M20,15H13V13H20M20,19H13V17H20M11,19H4V13H11M20.33,4.67L18.67,3L17,4.67L15.33,3L13.67,4.67L12,3L10.33,4.67L8.67,3L7,4.67L5.33,3L3.67,4.67L2,3V19A2,2 0 0,0 4,21H20A2,2 0 0,0 22,19V3L20.33,4.67Z"/>
</svg>

After

Width:  |  Height:  |  Size: 327 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M14,17H7V15H14M17,13H7V11H17M17,9H7V7H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"/>
</svg>

After

Width:  |  Height:  |  Size: 247 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M5.12,5l.81-1h12l.94,1m1.67.23L19.15,3.55A1.45,1.45,0,0,0,18,3H6a1.49,1.49,0,0,0-1.16.55L3.46,5.23A1.92,1.92,0,0,0,3,6.5V19a2,2,0,0,0,2,2H19a2,2,0,0,0,2-2V6.5A1.92,1.92,0,0,0,20.54,5.23Z"/>
</svg>

After

Width:  |  Height:  |  Size: 308 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,3h0a9,9,0,0,0-9,9v9H5.09V12a6.91,6.91,0,1,1,7.23,6.9,5.9,5.9,0,0,1-2.59-.47v-3A4.13,4.13,0,1,0,7.85,12v9H12A9,9,0,1,0,12,3Zm0,15.91h0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 260 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M22 4v-.5C22 2.12 20.88 1 19.5 1S17 2.12 17 3.5V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4zm-2.28 8c.04.33.08.66.08 1 0 2.08-.8 3.97-2.1 5.39-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H7v-2h2c.55 0 1-.45 1-1V8h2c1.1 0 2-.9 2-2V3.46c-.95-.3-1.95-.46-3-.46C5.48 3 1 7.48 1 13s4.48 10 10 10 10-4.48 10-10c0-.34-.02-.67-.05-1h-2.03zM10 20.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L8 16v1c0 1.1.9 2 2 2v1.93z"/>
</svg>

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M8.75,5.5v7.15H10.7V18.5l4.55-7.8h-2.6l2.6-5.2ZM20,4H4V20H20Zm0,18H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2H20a2,2,0,0,1,2,2V20A2,2,0,0,1,20,22Z"/>
</svg>

After

Width:  |  Height:  |  Size: 257 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M20,11.86a1.76,1.76,0,0,0-1.75-1.75,1.73,1.73,0,0,0-1.22.51,9,9,0,0,0-4.67-1.38l1-3.16L16,6.71s0,0,0,0a1.46,1.46,0,1,0,.1-.53l-2.89-.68a.25.25,0,0,0-.29.17L11.83,9.23a9.16,9.16,0,0,0-4.88,1.36,1.75,1.75,0,1,0-2.07,2.79,3,3,0,0,0-.06.58C4.82,16.58,8,18.7,12,18.7s7.14-2.13,7.14-4.74a2.94,2.94,0,0,0-.05-.55A1.74,1.74,0,0,0,20,11.86ZM8.51,13.08a1.06,1.06,0,1,1,1.06,1.06A1.06,1.06,0,0,1,8.51,13.08Zm6.06,3.14A3.48,3.48,0,0,1,12,17h0a3.48,3.48,0,0,1-2.56-.79.25.25,0,0,1,.35-.35,3,3,0,0,0,2.2.65h0a3,3,0,0,0,2.2-.65.25.25,0,1,1,.35.35Zm-.13-2.08a1.06,1.06,0,1,1,1.06-1.06A1.06,1.06,0,0,1,14.44,14.14Z"/>
</svg>

After

Width:  |  Height:  |  Size: 719 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><defs id="defs6"/>
<path id="rect345" style="stroke-width:1.40001;stroke-linecap:square" d="m 16.944458,1.2305698 -2.249239,2.2492384 5.824973,5.8249729 2.249239,-2.2492385 a 0.74206194,0.74206194 90.000002 0 0 0,-1.0494341 L 17.993892,1.2305699 a 0.74206211,0.74206211 2.5523302e-6 0 0 -1.049434,-1e-7 z M 13.645389,4.5296385 3.5726925,14.602335 9.3976653,20.427306 19.470362,10.35461 Z M 2.5228612,15.652165 1.0244287,22.411695 a 0.47276304,0.47276304 44.999993 0 0 0.5638754,0.563875 l 6.75953,-1.498434 z"/></svg>

After

Width:  |  Height:  |  Size: 757 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19.51 3.08L3.08 19.51c.09.34.27.65.51.9.25.24.56.42.9.51L20.93 4.49c-.19-.69-.73-1.23-1.42-1.41zM11.88 3L3 11.88v2.83L14.71 3h-2.83zM5 3c-1.1 0-2 .9-2 2v2l4-4H5zm14 18c.55 0 1.05-.22 1.41-.59.37-.36.59-.86.59-1.41v-2l-4 4h2zm-9.71 0h2.83L21 12.12V9.29L9.29 21z"/>
</svg>

After

Width:  |  Height:  |  Size: 383 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"/>
</svg>

After

Width:  |  Height:  |  Size: 388 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M21 3H3C2 3 1 4 1 5v14c0 1.1.9 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zM5 17l3.5-4.5 2.5 3.01L14.5 11l4.5 6H5z"/>
</svg>

After

Width:  |  Height:  |  Size: 227 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#D8DEE9"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="shaderpacks.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="9.7227182"
inkscape:cx="16.302025"
inkscape:cy="3.1884088"
inkscape:window-width="3840"
inkscape:window-height="2129"
inkscape:window-x="1200"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4">
<inkscape:grid
type="xygrid"
id="grid974" />
</sodipodi:namedview>
<path
id="path2"
d="M 5 3 C 3.9 3 3 3.9 3 5 L 3 7 L 5 5 L 7 3 L 5 3 z M 11.880859 3 L 9.8808594 5 L 12.710938 5 L 14.710938 3 L 11.880859 3 z M 19.509766 3.0800781 L 17.589844 5 L 19 5 L 19 6.4179688 L 20.929688 4.4902344 C 20.739687 3.8002344 20.199766 3.2600781 19.509766 3.0800781 z M 21 9.2890625 L 19 11.289062 L 19 14.119141 L 21 12.119141 L 21 9.2890625 z M 5 9.8808594 L 3 11.880859 L 3 14.710938 L 5 12.710938 L 5 9.8808594 z M 21 17 L 19 19 L 17 21 L 19 21 C 19.55 21 20.050156 20.780156 20.410156 20.410156 C 20.780156 20.050156 21 19.55 21 19 L 21 17 z M 5 17.589844 L 3.0800781 19.509766 C 3.1700781 19.849766 3.3498438 20.160156 3.5898438 20.410156 C 3.8398438 20.650156 4.1502344 20.829922 4.4902344 20.919922 L 6.4121094 19 L 5 19 L 5 17.589844 z M 11.289062 19 L 9.2890625 21 L 12.119141 21 L 14.119141 19 L 11.289062 19 z " />
<path
style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 7,9 v 8 h 8 V 9 Z"
id="path6727"
sodipodi:nodetypes="ccccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 7,9 9,7 h 8 l -2,2 z"
id="path7008" />
<path
style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 17,7 v 8 l -2,2 V 9 Z"
id="path7010"
sodipodi:nodetypes="ccccc" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"/>
</svg>

After

Width:  |  Height:  |  Size: 222 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm4.24,7.17L13.41,12l2.83,2.83-1.41,1.41L12,13.41,9.17,16.24,7.76,14.83,10.59,12,7.76,9.17,9.17,7.76,12,10.59l2.83-2.83Z"/>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
</svg>

After

Width:  |  Height:  |  Size: 239 B

View File

@ -0,0 +1,3 @@
<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

Some files were not shown because too many files have changed in this diff Show More