aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml1
-rw-r--r--BUILD.md340
-rw-r--r--CMakeLists.txt26
-rw-r--r--COPYING.md3
-rw-r--r--README.md12
-rw-r--r--buildconfig/BuildConfig.cpp.in10
-rw-r--r--buildconfig/BuildConfig.h13
-rw-r--r--launcher/Application.cpp11
-rw-r--r--launcher/CMakeLists.txt14
-rw-r--r--launcher/LaunchController.cpp2
-rw-r--r--launcher/notifications/NotificationChecker.cpp129
-rw-r--r--launcher/notifications/NotificationChecker.h61
-rw-r--r--launcher/resources/multimc/multimc.qrc4
-rw-r--r--launcher/resources/multimc/scalable/matrix.svg7
-rw-r--r--launcher/ui/MainWindow.cpp49
-rw-r--r--launcher/ui/MainWindow.h6
-rw-r--r--launcher/ui/dialogs/ModDownloadDialog.cpp27
-rw-r--r--launcher/ui/dialogs/NotificationDialog.cpp86
-rw-r--r--launcher/ui/dialogs/NotificationDialog.h44
-rw-r--r--launcher/ui/dialogs/NotificationDialog.ui85
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.cpp31
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.h23
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.ui98
-rw-r--r--launcher/ui/pages/global/LauncherPage.cpp21
-rw-r--r--launcher/ui/pages/global/LauncherPage.ui32
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp4
-rw-r--r--launcher/ui/widgets/PageContainer.cpp3
-rw-r--r--program_info/org.polymc.PolyMC.metainfo.xml.in14
-rw-r--r--program_info/polymc-header-black.svg34
-rw-r--r--program_info/polymc-header.Source.svg139
-rw-r--r--program_info/polymc-header.svg34
31 files changed, 429 insertions, 934 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index af5a1074..b5797e95 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -100,6 +100,7 @@ jobs:
- name: Install System Qt on Linux
if: runner.os == 'Linux' && matrix.app_image != true
run: |
+ sudo apt-get -y update
sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
- name: Install Ninja
diff --git a/BUILD.md b/BUILD.md
index fa6a8d04..8a76b68b 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -1,341 +1,5 @@
# Build Instructions
-# Contents
+Build instructions are available on [the website](https://polymc.org/wiki/development/build-instructions/).
-- [Getting the source](#getting-the-source)
-- [Linux](#linux)
-- [Windows](#windows)
-- [macOS](#macos)
-
-# Getting the source
-
-Clone the source code using git and grab all the submodules:
-
-```
-git clone https://github.com/PolyMC/PolyMC.git
-cd PolyMC
-git submodule init
-git submodule update
-```
-
-The rest of the documentation assumes you have already cloned the repository.
-
-# Linux and FreeBSD
-
-Getting the project to build and run on Linux is easy if you use any modern and up-to-date linux distribution. If you're using FreeBSD you should use 13.0-RELEASE or newer.
-
-## Build dependencies
-- A C++ compiler capable of building C++11 code.
-- Qt Development tools 5.6 or newer (`qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5` on Debian-based system)
-- cmake 3.1 or newer (`cmake` on Debian-based system)
-- zlib (`zlib1g-dev` on Debian-based system)
-- Java JDK (`openjdk-17-jdk`on Debian-based system)
-- GL headers (`libgl1-mesa-dev` on Debian-based system)
-- games/lwjgl port if using FreeBSD
-
-You can use IDEs like KDevelop or QtCreator to open the CMake project if you want to work on the code.
-
-### Building a portable binary
-
-```sh
-mkdir install
-# configure the project
-cmake -S . -B build \
- -DCMAKE_INSTALL_PREFIX=./install
-# build
-cd build
-make -j$(nproc) install
-```
-
-### Building & Installing to the System
-
-This is the preferred method for installation, and is suitable for packages.
-
-```sh
-# configure everything
-cmake -S . -B build \
-  -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX="/usr" \ # Use "/usr" when building Linux packages. If building on FreeBSD or not for package, use "/usr/local"
- -DLauncher_PORTABLE=OFF
-cd build
-make -j$(nproc) install # Optionally specify DESTDIR for packages (i.e. DESTDIR=${pkgdir})
-```
-
-### Building a .deb
-
-Requirements: [makedeb](https://docs.makedeb.org/) installed on your system.
-
-```
-git clone https://mpr.makedeb.org/polymc.git
-cd polymc
-makedeb -s
-```
-
-The deb will be located in the directory the repo was cloned in.
-
-### Building an .rpm
-
-Build dependencies are automatically installed using `dnf`, but you do need the `rpmdevtools` package (on Fedora)
-in order to fetch sources and setup your tree.
-You don't need to clone the repo for this; the spec file handles that
-
-```
-cd ~
-# setup your ~/rpmbuild directory, required for rpmbuild to work.
-rpmdev-setuptree
-# get the rpm spec file from the polymc-misc repo
-wget https://raw.githubusercontent.com/PolyMC/polymc-misc/master/rpm/polymc.spec
-# install build dependencies
-sudo dnf builddep polymc.spec
-# download build sources
-spectool -g -R polymc.spec
-# now build!
-rpmbuild -bb polymc.spec
-```
-
-The path to the rpm packages will be printed when the build is complete.
-
-### Building a Slackware package
-
-To build a Slackware package, first install [qt5 SlackBuild](http://slackbuilds.org/repository/14.2/libraries/qt5/) (on 15.0 and newer installed by defualt), then set up a [JDK](https://codeberg.org/glowiak/SlackBuilds/raw/branch/master/tgz/adoptium-jdk8.tar.gz).
-
-If you're using Slackware 14.2, update cmake with these commands:
-
-```
-mkdir -p /tmp/SBo
-cd /tmp/SBo
-wget -c https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2.tar.gz
-tar xzvf cmake-3.22.2.tar.gz
-cd cmake-3.22.2
-./configure --prefix=/usr
-make
-sudo make install
-```
-
-Next, download the [SlackBuild](https://codeberg.org/glowiak/SlackBuilds/raw/branch/master/tgz/polymc.tar.gz), unpack it and type in extracted directory:
-
-```
-sudo ./polymc.SlackBuild # script will do everything, just sit up and wait
-sudo /sbin/installpkg /tmp/polymc-version-arch-1_SBo.tgz # install the created package
-```
-
-### Building a flatpak
-
-You don't need to clone the entire PolyMC repo for this; the flatpak file handles that.
-`flatpak` and `flatpak-builder` need to be installed on your system
-
-```sh
-git clone https://github.com/flathub/org.polymc.PolyMC
-cd org.polymc.PolyMC
-# remove --user --install if you want to build without installing
-flatpak-builder --user --install flatbuild org.polymc.PolyMC.yml
-```
-
-### Installing Qt using the installer (optional)
-
-1. Run the Qt installer.
-2. Choose a place to install Qt.
-3. Choose the components you want to install.
- - You need Qt 5.6.x 64-bit ticked.
- - You need Tools/Qt Creator ticked.
- - Other components are selected by default, you can untick them if you don't need them.
-4. Accept the license agreements.
-5. Double check the install details and then click "Install".
- - Installation can take a very long time, go grab a cup of tea or something and let it work.
-
-### Loading the project in Qt Creator (optional)
-
-1. Open Qt Creator.
-2. Choose `File->Open File or Project`.
-3. Navigate to the Launcher source folder you cloned and choose CMakeLists.txt.
-4. Read the instructions that just popped up about a build location and choose one.
-5. You should see "Run CMake" in the window.
- - Make sure that Generator is set to "Unix Generator (Desktop Qt 5.6.x GCC 64bit)".
- - Hit the "Run CMake" button.
- - You'll see warnings and it might not be clear that it succeeded until you scroll to the bottom of the window.
- - Hit "Finish" if CMake ran successfully.
-6. Cross your fingers and press the Run button (bottom left of Qt Creator).
- - If the project builds successfully it will run and the Launcher window will pop up.
-
-**If this doesn't work for you, let us know on our Discord.**
-
-# Windows
-
-Getting the project to build and run on Windows is easy if you use Qt's IDE, Qt Creator. The project will simply not compile using Microsoft build tools, because that's not something we do. If it does compile, it is by chance only.
-
-## Dependencies
-
-- [Qt 5.6+ Development tools](http://qt-project.org/downloads) -- Qt Online Installer for Windows
- - http://download.qt.io/new_archive/qt/5.6/5.6.0/qt-opensource-windows-x86-mingw492-5.6.0.exe
- - Download the MinGW version (MSVC version does not work).
-- [OpenSSL](https://github.com/IndySockets/OpenSSL-Binaries/tree/master/Archive/) -- Win32 OpenSSL, version 1.0.2g (from 2016)
- - https://github.com/IndySockets/OpenSSL-Binaries/raw/master/Archive/openssl-1.0.2g-i386-win32.zip
- - the usual OpenSSL for Windows (http://slproweb.com/products/Win32OpenSSL.html) only provides the newest version of OpenSSL, and we need the 1.0.2g version
- - **Download the 32-bit version, not 64-bit.**
- - Microsoft Visual C++ 2008 Redist is required for this, there's a link on the OpenSSL download page above next to the main download.
- - We use a custom build of OpenSSL that doesn't have this dependency. For normal development, the custom build is not necessary though.
-- [zlib 1.2+](http://gnuwin32.sourceforge.net/packages/zlib.htm) - the Setup is fine
-- [Java JDK 8](https://adoptium.net/releases.html?variant=openjdk8) - Use the MSI installer.
-- [CMake](http://www.cmake.org/cmake/resources/software.html) -- Windows (Win32 Installer)
-
-Ensure that OpenSSL, zlib, Java and CMake are on `PATH`.
-
-## Getting set up
-
-### Installing Qt
-
-1. Run the Qt installer
-2. Choose a place to install Qt (C:\Qt is the default),
-3. Choose the components you want to install
- - You need Qt 5.6 (32 bit) ticked,
- - You need Tools/Qt Creator ticked,
- - Other components are selected by default, you can untick them if you don't need them.
-4. Accept the license agreements,
-5. Double check the install details and then click "Install"
- - Installation can take a very long time, go grab a cup of tea or something and let it work.
-
-### Installing OpenSSL
-
-1. Download .zip file from the link above.
-2. Unzip and add the directory to PATH, so CMake can find it.
-
-### Installing CMake
-
-1. Run the CMake installer,
-2. It's easiest if you choose to add CMake to the PATH for all users,
- - If you don't choose to do this, remember where you installed CMake.
-
-### Loading the project
-
-1. Open Qt Creator,
-2. Choose File->Open File or Project,
-3. Navigate to the Launcher source folder you cloned and choose CMakeLists.txt,
-4. Read the instructions that just popped up about a build location and choose one,
-5. If you chose not to add CMake to the system PATH, tell Qt Creator where you installed it,
- - Otherwise you can skip this step.
-6. You should see "Run CMake" in the window,
- - Make sure that Generator is set to "MinGW Generator (Desktop Qt 5.6.x MinGW 32bit)",
- - Hit the "Run CMake" button,
- - You'll see warnings and it might not be clear that it succeeded until you scroll to the bottom of the window.
- - Hit "Finish" if CMake ran successfully.
-7. Cross your fingers and press the Run button (bottom left of Qt Creator)!
- - If the project builds successfully it will run and the Launcher window will pop up,
- - Test OpenSSL by making an instance and trying to log in. If Qt Creator couldn't find OpenSSL during the CMake stage, login will fail and you'll get an error.
-
-The following .dlls are needed for the app to run (copy them to build directory if you want to be able to move the build to another pc):
-
-```
-
-platforms/qwindows.dll
-libeay32.dll
-libgcc_s_dw2-1.dll
-libssp-0.dll
-libstdc++-6.dll
-libwinpthread-1.dll
-Qt5Core.dll
-Qt5Gui.dll
-Qt5Network.dll
-Qt5Svg.dll
-Qt5Widgets.dll
-Qt5Xml.dll
-ssleay32.dll
-zlib1.dll
-
-```
-
-**These build instructions worked for me (Drayshak) on a fresh Windows 8 x64 Professional install. If they don't work for you, let us know on our Discord.**
-
-### Compile from command line on Windows
-
-1. If you installed Qt with the web installer, there should be a shortcut called `Qt 5.4 for Desktop (MinGW 4.9 32-bit)` in the Start menu on Windows 7 and 10. Best way to find it is to search for it. Do note you cannot just use cmd.exe, you have to use the shortcut, otherwise the proper MinGW software will not be on the PATH.
-2. Once that is open, change into your user directory, and clone PolyMC by doing `git clone --recursive https://github.com/PolyMC/PolyMC.git`, and change directory to the folder you cloned to.
-3. Make a build directory, and change directory to the directory and do `cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:\Path\that\makes\sense\for\you`. By default, it will install to C:\Program Files (x86), which you might not want, if you want a local installation. If you want to install it to that directory, make sure to run the command window as administrator.
-4. If you want PolyMC to store its data in `%APPDATA%`, append `-DLauncher_PORTABLE=OFF` to the previous command.
-5. Do `mingw32-make -j$(nproc)`, where X is the number of cores your CPU has plus one.
-6. Now to wait for it to compile. This could take some time. Hopefully it compiles properly.
-7. Run the command `mingw32-make install`, and it should install PolyMC, to whatever the `-DCMAKE_INSTALL_PREFIX` was.
-8. In most cases, whenever compiling, the OpenSSL dll's aren't put into the directory to where PolyMC installs, meaning you cannot log in. The best way to fix this is just to do `copy C:\OpenSSL-Win32\*.dll C:\Where\you\installed\PolyMC\to`. This should copy the required OpenSSL dll's to log in.
-
-# macOS
-
-### Install prerequisites:
-
-- Install XCode Command Line tools
-- Install the official build of CMake (https://cmake.org/download/)
-- Install JDK 8 (https://adoptium.net/releases.html?variant=openjdk8&jvmVariant=hotspot)
-- Get Qt 5.6 and install it (https://download.qt.io/new_archive/qt/5.6/5.6.3/) or higher (tested) (https://www.qt.io/download-qt-installer?utm_referrer=https%3A%2F%2Fwww.qt.io%2Fdownload-open-source)
-
-You can use `homebrew` to simplify the installation of build dependencies
-
-### XCode Command Line tools
-
-If you don't have XCode CommandLine tools installed, you can install them by using this command in the Terminal App
-
-```bash
-xcode-select --install
-```
-
-### Build
-
-Pick an installation path - this is where the final `PolyMC.app` will be constructed when you run `make install`. Supply it as the `CMAKE_INSTALL_PREFIX` argument during CMake configuration. By default, it's in the dist folder under PolyMC
-
-```
-mkdir build
-cd build
-cmake \
- -DCMAKE_C_COMPILER=/usr/bin/clang \
- -DCMAKE_CXX_COMPILER=/usr/bin/clang++ \
- -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX:PATH="$(dirname $PWD)/dist/" \
- -DCMAKE_PREFIX_PATH="/path/to/Qt/" \
- -DQt5_DIR="/path/to/Qt/" \
- -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \
- ..
-make install
-```
-
-Remember to replace `/path/to/Qt/` with the actual path. For newer Qt installations, it is often in your home directory.
-
-**Note:** The final app bundle may not run due to code signing issues, which
-need to be fixed with `codesign -fs -`.
-
-# OpenBSD
-
-Tested on OpenBSD 7.0-alpha i386, on older should work too
-
-## Build dependencies
-- A C++ compiler capable of building C++11 code (included in base system)
-- Qt Development tools 5.6 or newer ([meta/qt5](https://openports.se/meta/qt5))
-- cmake 3.1 or newer ([devel/cmake](https://openports.se/devel/cmake))
-- zlib (included in base system)
-- Java JDK ([devel/jdk-1.8](https://openports.se/devel/jdk/1.8))
-- GL headers (included in base system)
-- lwjgl ([games/lwjgl](https://openports.se/games/lwjgl) and [games/lwjgl3](https://openports.se/games/lwjgl3))
-
-You can use IDEs like KDevelop or QtCreator to open the CMake project if you want to work on the code.
-
-### Building a portable binary
-
-```sh
-mkdir install
-# configure the project
-cmake -S . -B build \
- -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_PREFIX_PATH=/usr/local/lib/qt5/cmake
-# build
-cd build
-make -j$(nproc) install
-```
-
-### Building & Installing to the System
-
-This is the preferred method for installation, and is suitable for packages.
-
-```sh
-# configure everything
-cmake -S . -B build \
-  -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX="/usr/local" \ # /usr/local is default in OpenBSD and FreeBSD
- -DLauncher_PORTABLE=OFF -DCMAKE_PREFIX_PATH=/usr/local/lib/qt5/cmake # use linux layout and point to qt5 libs
-cd build
-make -j$(nproc) install # Optionally specify DESTDIR for packages (i.e. DESTDIR=${pkgdir})
-```
+If you would like to contribute or fix an issue with the Build instructions you can do so [here](https://github.com/PolyMC/polymc.github.io/blob/master/src/wiki/development/build-instructions.md).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c370b6ea..7cd0cf86 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,26 +46,24 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
##################################### Set Application options #####################################
######## Set URLs ########
-set(Launcher_NEWS_RSS_URL "https://polymc.github.io/feed/feed.xml" CACHE STRING "URL to fetch PolyMC's news RSS feed from.")
-set(Launcher_NEWS_OPEN_URL "https://polymc.github.io/news/" CACHE STRING "URL that gets opened when the user clicks 'More News'")
+set(Launcher_NEWS_RSS_URL "https://polymc.org/feed/feed.xml" CACHE STRING "URL to fetch PolyMC's news RSS feed from.")
+set(Launcher_NEWS_OPEN_URL "https://polymc.org/news" CACHE STRING "URL that gets opened when the user clicks 'More News'")
+set(Launcher_HELP_URL "https://polymc.org/wiki/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
######## Set version numbers ########
set(Launcher_VERSION_MAJOR 1)
-set(Launcher_VERSION_MINOR 0)
-set(Launcher_VERSION_HOTFIX 6)
+set(Launcher_VERSION_MINOR 1)
+set(Launcher_VERSION_HOTFIX 0)
# Build number
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
# Build platform.
-set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.")
+set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.")
# Channel list URL
set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.")
-# Notification URL
-set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.")
-
# The metadata server
set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.")
@@ -81,9 +79,14 @@ set(Launcher_BUG_TRACKER_URL "https://github.com/PolyMC/PolyMC/issues" CACHE STR
# Translations Platform URL
set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/polymc/polymc/" CACHE STRING "URL for the translations platform.")
+# Matrix Space
+set(Launcher_MATRIX_URL "https://matrix.to/#/#polymc:polymc.org" CACHE STRING "URL to the Matrix Space")
+
# Discord URL
set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.")
+
+
# Subreddit URL
set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.")
@@ -164,13 +167,13 @@ if(UNIX AND APPLE)
# Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}")
- set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: Minecraft launcher and management utility.")
+ 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_GUI_IDENTIFIER "org.polymc.${Launcher_Name}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
- set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 ${Launcher_Copyright}")
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
@@ -201,7 +204,8 @@ elseif(UNIX)
set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory")
set(LAUNCHER_ICON_DEST_DIR "share/icons/hicolor/scalable/apps" CACHE STRING "Path to the scalable icon directory")
- set(Launcher_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}")
+ # jars path is determined on runtime, relative to "Application root path", generally /usr for Launcher_PORTABLE=0
+ set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_JARS_LOCATION=${JARS_DEST_DIR}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR})
diff --git a/COPYING.md b/COPYING.md
index 1ac6d5cb..273a5b3a 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -5,8 +5,7 @@
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/README.md b/README.md
index 5d83a8f9..a114869c 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ If you want to contribute to PolyMC you might find it useful to join our Discord
## Building
-If you want to build PolyMC yourself, check [BUILD.md](BUILD.md) for build instructions.
+If you want to build PolyMC yourself, check [Build Instructions](https://polymc.org/wiki/development/build-instructions/) for build instructions.
## Code formatting
@@ -66,9 +66,15 @@ In general, in order of importance:
The translation effort for PolyMC is hosted on [Weblate](https://hosted.weblate.org/projects/polymc/polymc/) and information about translating PolyMC is available at https://github.com/PolyMC/Translations
-## Download infomation
-To modify download infomation or change packaging infomation send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md)
+## Download information
+To modify download information or change packaging information send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md)
## Forking/Redistributing/Custom builds policy
Do whatever you want, we don't care. Just follow the license. If you have any questions about this feel free to ask in an issue.
+
+All launcher code is available under the GPL-3 license.
+
+[Source for the website](https://github.com/PolyMC/polymc.github.io) is hosted under the AGPL-3 License.
+
+The logo and related assets are under the CC BY-NC-SA 4.0 license.
diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in
index 0ffc9326..4625b1bf 100644
--- a/buildconfig/BuildConfig.cpp.in
+++ b/buildconfig/BuildConfig.cpp.in
@@ -25,12 +25,14 @@ Config::Config()
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@";
- NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@";
- FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@";
GIT_COMMIT = "@Launcher_GIT_COMMIT@";
GIT_REFSPEC = "@Launcher_GIT_REFSPEC@";
- if(GIT_REFSPEC.startsWith("refs/heads/"))
+ if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND"))
+ {
+ VERSION_CHANNEL = QStringLiteral("stable");
+ }
+ else if(GIT_REFSPEC.startsWith("refs/heads/"))
{
VERSION_CHANNEL = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/");
@@ -50,12 +52,14 @@ Config::Config()
VERSION_STR = "@Launcher_VERSION_STRING@";
NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@";
NEWS_OPEN_URL = "@Launcher_NEWS_OPEN_URL@";
+ HELP_URL = "@Launcher_HELP_URL@";
IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@";
MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@";
META_URL = "@Launcher_META_URL@";
BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@";
TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@";
+ MATRIX_URL = "@Launcher_MATRIX_URL@";
DISCORD_URL = "@Launcher_DISCORD_URL@";
SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@";
}
diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h
index 863f88df..79210505 100644
--- a/buildconfig/BuildConfig.h
+++ b/buildconfig/BuildConfig.h
@@ -46,13 +46,6 @@ public:
/// User-Agent to use for uncached requests.
QString USER_AGENT_UNCACHED;
-
- /// URL for notifications
- QString NOTIFICATION_URL;
-
- /// Used for matching notifications
- QString FULL_VERSION_STR;
-
/// The git commit hash of this build
QString GIT_COMMIT;
@@ -74,6 +67,11 @@ public:
QString NEWS_OPEN_URL;
/**
+ * URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help
+ */
+ QString HELP_URL;
+
+ /**
* Client ID you can get from Imgur when you register an application
*/
QString IMGUR_CLIENT_ID;
@@ -90,6 +88,7 @@ public:
QString BUG_TRACKER_URL;
QString TRANSLATIONS_URL;
+ QString MATRIX_URL;
QString DISCORD_URL;
QString SUBREDDIT_URL;
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 0ce80d4b..e0d7ba0a 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -515,8 +515,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
FS::updateTimestamp(m_rootPath);
#endif
-#ifdef MULTIMC_JARS_LOCATION
- m_jarsPath = TOSTRING(MULTIMC_JARS_LOCATION);
+#ifdef LAUNCHER_JARS_LOCATION
+ m_jarsPath = TOSTRING(LAUNCHER_JARS_LOCATION);
#endif
qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT;
@@ -575,9 +575,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system"));
- // Notifications
- m_settings->registerSetting("ShownNotifications", QString());
-
// Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
@@ -1494,10 +1491,10 @@ QString Application::getJarsPath()
{
return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
}
- return m_jarsPath;
+ return FS::PathCombine(m_rootPath, m_jarsPath);
}
-QString Application::getMSAClientID()
+QString Application::getMSAClientID()
{
QString clientIDOverride = m_settings->get("MSAClientIDOverride").toString();
if (!clientIDOverride.isEmpty()) {
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 48370c96..38ff0f65 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -174,13 +174,6 @@ add_unit_test(DownloadTask
DATA updater/testdata
)
-# Rarely used notifications
-set(NOTIFICATIONS_SOURCES
- # Notifications - short warning messages
- notifications/NotificationChecker.h
- notifications/NotificationChecker.cpp
-)
-
# Backend for the news bar... there's usually no news.
set(NEWS_SOURCES
# News System
@@ -571,7 +564,6 @@ set(LOGIC_SOURCES
${NET_SOURCES}
${LAUNCH_SOURCES}
${UPDATE_SOURCES}
- ${NOTIFICATIONS_SOURCES}
${NEWS_SOURCES}
${MINECRAFT_SOURCES}
${SCREENSHOTS_SOURCES}
@@ -807,12 +799,12 @@ SET(LAUNCHER_SOURCES
ui/dialogs/NewComponentDialog.h
ui/dialogs/NewInstanceDialog.cpp
ui/dialogs/NewInstanceDialog.h
- ui/dialogs/NotificationDialog.cpp
- ui/dialogs/NotificationDialog.h
ui/pagedialog/PageDialog.cpp
ui/pagedialog/PageDialog.h
ui/dialogs/ProgressDialog.cpp
ui/dialogs/ProgressDialog.h
+ ui/dialogs/ReviewMessageBox.cpp
+ ui/dialogs/ReviewMessageBox.h
ui/dialogs/UpdateDialog.cpp
ui/dialogs/UpdateDialog.h
ui/dialogs/VersionSelectDialog.cpp
@@ -908,7 +900,6 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui
ui/dialogs/NewInstanceDialog.ui
- ui/dialogs/NotificationDialog.ui
ui/dialogs/UpdateDialog.ui
ui/dialogs/NewComponentDialog.ui
ui/dialogs/ProfileSelectDialog.ui
@@ -920,6 +911,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/AboutDialog.ui
ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui
+ ui/dialogs/ReviewMessageBox.ui
)
qt5_add_resources(LAUNCHER_RESOURCES
diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp
index 40178b70..4fd2eade 100644
--- a/launcher/LaunchController.cpp
+++ b/launcher/LaunchController.cpp
@@ -56,7 +56,7 @@ void LaunchController::decideAccount()
m_parentWidget,
tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Mojang or Minecraft "
- "account logged in."
+ "account logged in. "
"Would you like to open the account manager to add an account now?"),
QMessageBox::Information,
QMessageBox::Yes | QMessageBox::No
diff --git a/launcher/notifications/NotificationChecker.cpp b/launcher/notifications/NotificationChecker.cpp
deleted file mode 100644
index 10b91691..00000000
--- a/launcher/notifications/NotificationChecker.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "NotificationChecker.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QDebug>
-
-#include "net/Download.h"
-
-#include "Application.h"
-
-NotificationChecker::NotificationChecker(QObject *parent)
- : QObject(parent)
-{
-}
-
-void NotificationChecker::setNotificationsUrl(const QUrl &notificationsUrl)
-{
- m_notificationsUrl = notificationsUrl;
-}
-
-void NotificationChecker::setApplicationChannel(QString channel)
-{
- m_appVersionChannel = channel;
-}
-
-void NotificationChecker::setApplicationFullVersion(QString version)
-{
- m_appFullVersion = version;
-}
-
-void NotificationChecker::setApplicationPlatform(QString platform)
-{
- m_appPlatform = platform;
-}
-
-QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const
-{
- return m_entries;
-}
-
-void NotificationChecker::checkForNotifications()
-{
- if (!m_notificationsUrl.isValid())
- {
- qCritical() << "Failed to check for notifications. No notifications URL set."
- << "If you'd like to use PolyMC's notification system, please pass the "
- "URL to CMake at compile time.";
- return;
- }
- if (m_checkJob)
- {
- return;
- }
- m_checkJob = new NetJob("Checking for notifications", APPLICATION->network());
- auto entry = APPLICATION->metacache()->resolveEntry("root", "notifications.json");
- entry->setStale(true);
- m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry));
- connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded);
- m_checkJob->start();
-}
-
-void NotificationChecker::downloadSucceeded(int)
-{
- m_entries.clear();
-
- QFile file(m_download->getTargetFilepath());
- if (file.open(QFile::ReadOnly))
- {
- QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
- for (auto it = root.begin(); it != root.end(); ++it)
- {
- QJsonObject obj = (*it).toObject();
- NotificationEntry entry;
- entry.id = obj.value("id").toDouble();
- entry.message = obj.value("message").toString();
- entry.channel = obj.value("channel").toString();
- entry.platform = obj.value("platform").toString();
- entry.from = obj.value("from").toString();
- entry.to = obj.value("to").toString();
- const QString type = obj.value("type").toString("critical");
- if (type == "critical")
- {
- entry.type = NotificationEntry::Critical;
- }
- else if (type == "warning")
- {
- entry.type = NotificationEntry::Warning;
- }
- else if (type == "information")
- {
- entry.type = NotificationEntry::Information;
- }
- if(entryApplies(entry))
- m_entries.append(entry);
- }
- }
-
- m_checkJob.reset();
-
- emit notificationCheckFinished();
-}
-
-bool versionLessThan(const QString &v1, const QString &v2)
-{
- QStringList l1 = v1.split('.');
- QStringList l2 = v2.split('.');
- while (!l1.isEmpty() && !l2.isEmpty())
- {
- int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
- int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
- if (one != two)
- {
- return one < two;
- }
- }
- return false;
-}
-
-bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const
-{
- bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
- bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
- bool fromApplies =
- entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
- bool toApplies =
- entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
- return channelApplies && platformApplies && fromApplies && toApplies;
-}
diff --git a/launcher/notifications/NotificationChecker.h b/launcher/notifications/NotificationChecker.h
deleted file mode 100644
index 0f305f33..00000000
--- a/launcher/notifications/NotificationChecker.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#pragma once
-
-#include <QObject>
-
-#include "net/NetJob.h"
-#include "net/Download.h"
-
-class NotificationChecker : public QObject
-{
- Q_OBJECT
-
-public:
- explicit NotificationChecker(QObject *parent = 0);
-
- void setNotificationsUrl(const QUrl &notificationsUrl);
- void setApplicationPlatform(QString platform);
- void setApplicationChannel(QString channel);
- void setApplicationFullVersion(QString version);
-
- struct NotificationEntry
- {
- int id;
- QString message;
- enum
- {
- Critical,
- Warning,
- Information
- } type;
- QString channel;
- QString platform;
- QString from;
- QString to;
- };
-
- QList<NotificationEntry> notificationEntries() const;
-
-public
-slots:
- void checkForNotifications();
-
-private
-slots:
- void downloadSucceeded(int);
-
-signals:
- void notificationCheckFinished();
-
-private:
- bool entryApplies(const NotificationEntry &entry) const;
-
-private:
- QList<NotificationEntry> m_entries;
- QUrl m_notificationsUrl;
- NetJob::Ptr m_checkJob;
- Net::Download::Ptr m_download;
-
- QString m_appVersionChannel;
- QString m_appPlatform;
- QString m_appFullVersion;
-};
diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc
index ef29cf9b..d31885b9 100644
--- a/launcher/resources/multimc/multimc.qrc
+++ b/launcher/resources/multimc/multimc.qrc
@@ -246,9 +246,13 @@
<!-- placeholder when loading screenshot images -->
<file>scalable/screenshot-placeholder.svg</file>
+ <!-- matrix logo -->
+ <file>scalable/matrix.svg</file>
+
<!-- discord logo icon thing. from discord. traced from bitmap -->
<file>scalable/discord.svg</file>
+
<!-- instance icons -->
<file>32x32/instances/chicken.png</file>
<file>128x128/instances/chicken.png</file>
diff --git a/launcher/resources/multimc/scalable/matrix.svg b/launcher/resources/multimc/scalable/matrix.svg
new file mode 100644
index 00000000..237c55a2
--- /dev/null
+++ b/launcher/resources/multimc/scalable/matrix.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64">
+ <g fill="#fff">
+ <path d="M49.46 42.2h-5.32c-.178 0-.323-.145-.323-.323V30.91l-.074-1.808c-.047-.53-.173-.992-.376-1.376-.194-.367-.487-.664-.868-.883s-.93-.332-1.62-.332-1.238.13-1.647.382-.743.597-.976 1.01a4.21 4.21 0 0 0-.486 1.462c-.085.567-.128 1.15-.128 1.732v10.79c0 .178-.145.323-.323.323H32c-.178 0-.323-.145-.323-.323V31.02l-.037-1.69c-.024-.524-.124-1.013-.297-1.45-.164-.415-.43-.74-.814-.992s-.972-.378-1.752-.378c-.22 0-.527.053-.908.157-.368.1-.732.294-1.08.577s-.65.694-.904 1.235-.382 1.27-.382 2.167v11.24c0 .178-.144.323-.323.323h-5.32c-.178 0-.323-.145-.323-.323V22.515c0-.178.145-.322.323-.322h5.02c.178 0 .323.145.323.322V24.3c.618-.726 1.33-1.315 2.125-1.757 1.032-.574 2.225-.865 3.548-.865 1.265 0 2.44.25 3.5.743.934.44 1.68 1.17 2.224 2.18.556-.703 1.263-1.34 2.108-1.895 1.036-.682 2.274-1.028 3.68-1.028 1.048 0 2.036.13 2.937.387.917.263 1.715.69 2.373 1.267s1.18 1.348 1.548 2.278c.363.922.547 2.04.547 3.323v12.964c0 .178-.145.323-.323.323z" opacity=".5" />
+ <path d="M24.88 22.515v2.623h.075c.7-.998 1.542-1.774 2.53-2.323s2.117-.824 3.39-.824c1.224 0 2.342.238 3.353.712s1.78 1.31 2.305 2.51c.574-.85 1.355-1.6 2.342-2.248s2.154-.974 3.504-.974c1.024 0 1.973.125 2.848.375s1.623.65 2.248 1.2 1.11 1.268 1.462 2.154.525 1.955.525 3.204v12.964h-5.32V30.91l-.075-1.836c-.05-.574-.187-1.073-.412-1.5s-.556-.762-.993-1.012-1.03-.374-1.78-.374-1.355.145-1.817.43-.824.663-1.087 1.124-.437.987-.524 1.574a12 12 0 0 0-.131 1.78v10.79H32V31.022l-.037-1.705c-.025-.562-.13-1.08-.32-1.556s-.5-.855-.937-1.143-1.08-.43-1.93-.43c-.25 0-.58.056-.993.17a3.3 3.3 0 0 0-1.199.637c-.388.313-.718.762-.993 1.35s-.412 1.355-.412 2.304v11.24h-5.32V22.515z" opacity=".5" />
+ </g>
+ <path d="M1.432 6.084v51.833h3.73v1.244H0V4.84h5.162v1.243zm20.788 16.43v2.623h.075c.7-.998 1.542-1.774 2.53-2.323s2.117-.824 3.4-.824c1.224 0 2.342.238 3.353.712s1.78 1.3 2.305 2.5c.574-.85 1.355-1.6 2.342-2.248s2.154-.974 3.504-.974c1.024 0 1.973.125 2.848.375s1.623.65 2.248 1.2 1.1 1.268 1.462 2.154.525 1.955.525 3.204v12.964h-5.32V30.9l-.075-1.836c-.05-.574-.187-1.073-.412-1.5s-.556-.762-.993-1.012-1.03-.374-1.78-.374-1.355.145-1.817.43a3.12 3.12 0 0 0-1.087 1.124c-.263.46-.437.987-.524 1.574a12 12 0 0 0-.131 1.78v10.8h-5.32V31.022l-.037-1.705c-.025-.562-.13-1.08-.32-1.556s-.5-.855-.937-1.143-1.08-.43-1.93-.43c-.25 0-.58.056-.993.17a3.3 3.3 0 0 0-1.199.637c-.388.313-.718.762-.993 1.35s-.412 1.355-.412 2.304v11.24H17.2V22.515zm40.348 35.402V6.084h-3.73V4.84H64v54.32h-5.162v-1.244z" />
+</svg> \ No newline at end of file
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index ad7227cc..7b758e05 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -59,7 +59,6 @@
#include <net/NetJob.h>
#include <net/Download.h>
#include <news/NewsChecker.h>
-#include <notifications/NotificationChecker.h>
#include <tools/BaseProfiler.h>
#include <updater/DownloadTask.h>
#include <updater/UpdateChecker.h>
@@ -82,7 +81,6 @@
#include "ui/dialogs/CopyInstanceDialog.h"
#include "ui/dialogs/UpdateDialog.h"
#include "ui/dialogs/EditAccountDialog.h"
-#include "ui/dialogs/NotificationDialog.h"
#include "ui/dialogs/ExportInstanceDialog.h"
#include "UpdateController.h"
@@ -235,6 +233,7 @@ public:
TranslatedToolButton helpMenuButton;
TranslatedAction actionReportBug;
TranslatedAction actionDISCORD;
+ TranslatedAction actionMATRIX;
TranslatedAction actionREDDIT;
TranslatedAction actionAbout;
@@ -343,13 +342,23 @@ public:
all_actions.append(&actionReportBug);
helpMenu->addAction(actionReportBug);
}
+
+ if(!BuildConfig.MATRIX_URL.isEmpty()) {
+ actionMATRIX = TranslatedAction(MainWindow);
+ actionMATRIX->setObjectName(QStringLiteral("actionMATRIX"));
+ actionMATRIX->setIcon(APPLICATION->getThemedIcon("matrix"));
+ actionMATRIX.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Matrix"));
+ actionMATRIX.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 Matrix space"));
+ all_actions.append(&actionMATRIX);
+ helpMenu->addAction(actionMATRIX);
+ }
if (!BuildConfig.DISCORD_URL.isEmpty()) {
actionDISCORD = TranslatedAction(MainWindow);
actionDISCORD->setObjectName(QStringLiteral("actionDISCORD"));
actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord"));
actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord"));
- actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 discord voice chat."));
+ actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 Discord guild."));
all_actions.append(&actionDISCORD);
helpMenu->addAction(actionDISCORD);
}
@@ -835,17 +844,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow
}
}
- {
- auto checker = new NotificationChecker();
- checker->setNotificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL));
- checker->setApplicationChannel(BuildConfig.VERSION_CHANNEL);
- checker->setApplicationPlatform(BuildConfig.BUILD_PLATFORM);
- checker->setApplicationFullVersion(BuildConfig.FULL_VERSION_STR);
- m_notificationChecker.reset(checker);
- connect(m_notificationChecker.get(), &NotificationChecker::notificationCheckFinished, this, &MainWindow::notificationsChanged);
- checker->checkForNotifications();
- }
-
setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString());
// removing this looks stupid
@@ -1257,24 +1255,6 @@ QString intListToString(const QList<int> &list)
}
return slist.join(',');
}
-void MainWindow::notificationsChanged()
-{
- QList<NotificationChecker::NotificationEntry> entries = m_notificationChecker->notificationEntries();
- QList<int> shownNotifications = stringToIntList(APPLICATION->settings()->get("ShownNotifications").toString());
- for (auto it = entries.begin(); it != entries.end(); ++it)
- {
- NotificationChecker::NotificationEntry entry = *it;
- if (!shownNotifications.contains(entry.id))
- {
- NotificationDialog dialog(entry, this);
- if (dialog.exec() == NotificationDialog::DontShowAgain)
- {
- shownNotifications.append(entry.id);
- }
- }
- }
- APPLICATION->settings()->set("ShownNotifications", intListToString(shownNotifications));
-}
void MainWindow::downloadUpdates(GoUpdate::Status status)
{
@@ -1500,6 +1480,11 @@ void MainWindow::on_actionDISCORD_triggered()
DesktopServices::openUrl(QUrl(BuildConfig.DISCORD_URL));
}
+void MainWindow::on_actionMATRIX_triggered()
+{
+ DesktopServices::openUrl(QUrl(BuildConfig.MATRIX_URL));
+}
+
void MainWindow::on_actionChangeInstIcon_triggered()
{
if (!m_selectedInstance)
diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h
index f6940ab0..f2852d78 100644
--- a/launcher/ui/MainWindow.h
+++ b/launcher/ui/MainWindow.h
@@ -28,7 +28,6 @@
class LaunchController;
class NewsChecker;
-class NotificationChecker;
class QToolButton;
class InstanceProxyModel;
class LabeledToolButton;
@@ -73,6 +72,8 @@ private slots:
void on_actionREDDIT_triggered();
+ void on_actionMATRIX_triggered();
+
void on_actionDISCORD_triggered();
void on_actionCopyInstance_triggered();
@@ -166,8 +167,6 @@ private slots:
void updateNotAvailable();
- void notificationsChanged();
-
void defaultAccountChanged();
void changeActiveAccount();
@@ -213,7 +212,6 @@ private:
KonamiCode * secretEventFilter = nullptr;
unique_qobject_ptr<NewsChecker> m_newsChecker;
- unique_qobject_ptr<NotificationChecker> m_notificationChecker;
InstancePtr m_selectedInstance;
QString m_currentInstIcon;
diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp
index 23ca8731..a53f93e8 100644
--- a/launcher/ui/dialogs/ModDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ModDownloadDialog.cpp
@@ -5,7 +5,7 @@
#include <InstanceList.h>
#include "ProgressDialog.h"
-#include "CustomMessageBox.h"
+#include "ReviewMessageBox.h"
#include <QLayout>
#include <QPushButton>
@@ -75,27 +75,16 @@ void ModDownloadDialog::confirm()
auto keys = modTask.keys();
keys.sort(Qt::CaseInsensitive);
- auto info = QString(tr("You're about to download the following mods:"));
- info.append("\n\n");
- for(auto task : keys){
- info.append(task);
- info.append("\n --> ");
- info.append(tr("File name: "));
- info.append(modTask.find(task).value()->getFilename());
- info.append('\n');
- }
-
- auto confirm_dialog = CustomMessageBox::selectable(
+ auto confirm_dialog = ReviewMessageBox::create(
this,
- tr("Confirm mods to download"),
- info,
- QMessageBox::NoIcon,
- QMessageBox::Cancel | QMessageBox::Ok,
- QMessageBox::Ok
+ tr("Confirm mods to download")
);
- auto AcceptButton = confirm_dialog->button(QMessageBox::Ok);
- connect(AcceptButton, &QPushButton::clicked, this, &ModDownloadDialog::accept);
+ for(auto task : keys){
+ confirm_dialog->appendMod(task, modTask.find(task).value()->getFilename());
+ }
+
+ connect(confirm_dialog, &QDialog::accepted, this, &ModDownloadDialog::accept);
confirm_dialog->open();
}
diff --git a/launcher/ui/dialogs/NotificationDialog.cpp b/launcher/ui/dialogs/NotificationDialog.cpp
deleted file mode 100644
index f2a35ae2..00000000
--- a/launcher/ui/dialogs/NotificationDialog.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "NotificationDialog.h"
-#include "ui_NotificationDialog.h"
-
-#include <QTimerEvent>
-#include <QStyle>
-
-NotificationDialog::NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent) :
- QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint),
- ui(new Ui::NotificationDialog)
-{
- ui->setupUi(this);
-
- QStyle::StandardPixmap icon;
- switch (entry.type)
- {
- case NotificationChecker::NotificationEntry::Critical:
- icon = QStyle::SP_MessageBoxCritical;
- break;
- case NotificationChecker::NotificationEntry::Warning:
- icon = QStyle::SP_MessageBoxWarning;
- break;
- default:
- case NotificationChecker::NotificationEntry::Information:
- icon = QStyle::SP_MessageBoxInformation;
- break;
- }
- ui->iconLabel->setPixmap(style()->standardPixmap(icon, 0, this));
- ui->messageLabel->setText(entry.message);
-
- m_dontShowAgainText = tr("Don't show again");
- m_closeText = tr("Close");
-
- ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
- ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
-
- startTimer(1000);
-}
-
-NotificationDialog::~NotificationDialog()
-{
- delete ui;
-}
-
-void NotificationDialog::timerEvent(QTimerEvent *event)
-{
- if (m_dontShowAgainTime > 0)
- {
- m_dontShowAgainTime--;
- if (m_dontShowAgainTime == 0)
- {
- ui->dontShowAgainBtn->setText(m_dontShowAgainText);
- ui->dontShowAgainBtn->setEnabled(true);
- }
- else
- {
- ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
- }
- }
- if (m_closeTime > 0)
- {
- m_closeTime--;
- if (m_closeTime == 0)
- {
- ui->closeBtn->setText(m_closeText);
- ui->closeBtn->setEnabled(true);
- }
- else
- {
- ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
- }
- }
-
- if (m_closeTime == 0 && m_dontShowAgainTime == 0)
- {
- killTimer(event->timerId());
- }
-}
-
-void NotificationDialog::on_dontShowAgainBtn_clicked()
-{
- done(DontShowAgain);
-}
-void NotificationDialog::on_closeBtn_clicked()
-{
- done(Normal);
-}
diff --git a/launcher/ui/dialogs/NotificationDialog.h b/launcher/ui/dialogs/NotificationDialog.h
deleted file mode 100644
index e1cbb9fa..00000000
--- a/launcher/ui/dialogs/NotificationDialog.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef NOTIFICATIONDIALOG_H
-#define NOTIFICATIONDIALOG_H
-
-#include <QDialog>
-
-#include "notifications/NotificationChecker.h"
-
-namespace Ui {
-class NotificationDialog;
-}
-
-class NotificationDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- explicit NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent = 0);
- ~NotificationDialog();
-
- enum ExitCode
- {
- Normal,
- DontShowAgain
- };
-
-protected:
- void timerEvent(QTimerEvent *event);
-
-private:
- Ui::NotificationDialog *ui;
-
- int m_dontShowAgainTime = 10;
- int m_closeTime = 5;
-
- QString m_dontShowAgainText;
- QString m_closeText;
-
-private
-slots:
- void on_dontShowAgainBtn_clicked();
- void on_closeBtn_clicked();
-};
-
-#endif // NOTIFICATIONDIALOG_H
diff --git a/launcher/ui/dialogs/NotificationDialog.ui b/launcher/ui/dialogs/NotificationDialog.ui
deleted file mode 100644
index 3e6c22bc..00000000
--- a/launcher/ui/dialogs/NotificationDialog.ui
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>NotificationDialog</class>
- <widget class="QDialog" name="NotificationDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>320</width>
- <height>240</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Notification</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
- <item>
- <widget class="QLabel" name="iconLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="messageLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::TextBrowserInteraction</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="dontShowAgainBtn">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Don't show again</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="closeBtn">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Close</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp
new file mode 100644
index 00000000..2bfd02e0
--- /dev/null
+++ b/launcher/ui/dialogs/ReviewMessageBox.cpp
@@ -0,0 +1,31 @@
+#include "ReviewMessageBox.h"
+#include "ui_ReviewMessageBox.h"
+
+ReviewMessageBox::ReviewMessageBox(QWidget* parent, QString const& title, QString const& icon)
+ : QDialog(parent), ui(new Ui::ReviewMessageBox)
+{
+ ui->setupUi(this);
+}
+
+ReviewMessageBox::~ReviewMessageBox()
+{
+ delete ui;
+}
+
+auto ReviewMessageBox::create(QWidget* parent, QString&& title, QString&& icon) -> ReviewMessageBox*
+{
+ return new ReviewMessageBox(parent, title, icon);
+}
+
+void ReviewMessageBox::appendMod(const QString& name, const QString& filename)
+{
+ auto itemTop = new QTreeWidgetItem(ui->modTreeWidget);
+ itemTop->setText(0, name);
+
+ auto filenameItem = new QTreeWidgetItem(itemTop);
+ filenameItem->setText(0, tr("Filename: %1").arg(filename));
+
+ itemTop->insertChildren(0, { filenameItem });
+
+ ui->modTreeWidget->addTopLevelItem(itemTop);
+}
diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h
new file mode 100644
index 00000000..48742cd9
--- /dev/null
+++ b/launcher/ui/dialogs/ReviewMessageBox.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <QDialog>
+
+namespace Ui {
+class ReviewMessageBox;
+}
+
+class ReviewMessageBox final : public QDialog {
+ Q_OBJECT
+
+ public:
+ static auto create(QWidget* parent, QString&& title, QString&& icon = "") -> ReviewMessageBox*;
+
+ void appendMod(const QString& name, const QString& filename);
+
+ ~ReviewMessageBox();
+
+ private:
+ ReviewMessageBox(QWidget* parent, const QString& title, const QString& icon);
+
+ Ui::ReviewMessageBox* ui;
+};
diff --git a/launcher/ui/dialogs/ReviewMessageBox.ui b/launcher/ui/dialogs/ReviewMessageBox.ui
new file mode 100644
index 00000000..d04f3b3f
--- /dev/null
+++ b/launcher/ui/dialogs/ReviewMessageBox.ui
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ReviewMessageBox</class>
+ <widget class="QDialog" name="ReviewMessageBox">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Confirm mod selection</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>You're about to download the following mods:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QTreeWidget" name="modTreeWidget">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectItems</enum>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ReviewMessageBox</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>200</x>
+ <y>265</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>149</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ReviewMessageBox</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>200</x>
+ <y>265</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>149</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index 0ffe8050..ee68cd08 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -234,11 +234,6 @@ void LauncherPage::applySettings()
{
auto s = APPLICATION->settings();
- if (ui->resetNotificationsBtn->isChecked())
- {
- s->set("ShownNotifications", QString());
- }
-
// Updates
s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
s->set("UpdateChannel", m_currentUpdateChannel);
@@ -247,16 +242,16 @@ void LauncherPage::applySettings()
switch (ui->themeComboBox->currentIndex())
{
case 0:
- s->set("IconTheme", "pe_dark");
+ s->set("IconTheme", "pe_colored");
break;
case 1:
s->set("IconTheme", "pe_light");
break;
case 2:
- s->set("IconTheme", "pe_blue");
+ s->set("IconTheme", "pe_dark");
break;
case 3:
- s->set("IconTheme", "pe_colored");
+ s->set("IconTheme", "pe_blue");
break;
case 4:
s->set("IconTheme", "OSX");
@@ -268,10 +263,10 @@ void LauncherPage::applySettings()
s->set("IconTheme", "flat");
break;
case 7:
- s->set("IconTheme", "custom");
+ s->set("IconTheme", "multimc");
break;
case 8:
- s->set("IconTheme", "multimc");
+ s->set("IconTheme", "custom");
break;
}
@@ -324,7 +319,7 @@ void LauncherPage::loadSettings()
m_currentUpdateChannel = s->get("UpdateChannel").toString();
//FIXME: make generic
auto theme = s->get("IconTheme").toString();
- if (theme == "pe_dark")
+ if (theme == "pe_colored")
{
ui->themeComboBox->setCurrentIndex(0);
}
@@ -332,11 +327,11 @@ void LauncherPage::loadSettings()
{
ui->themeComboBox->setCurrentIndex(1);
}
- else if (theme == "pe_blue")
+ else if (theme == "pe_dark")
{
ui->themeComboBox->setCurrentIndex(2);
}
- else if (theme == "pe_colored")
+ else if (theme == "pe_blue")
{
ui->themeComboBox->setCurrentIndex(3);
}
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 47fed873..c110dd09 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -185,25 +185,6 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>Launcher notifications</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QPushButton" name="resetNotificationsBtn">
- <property name="text">
- <string>Reset hidden notifications</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
<widget class="QGroupBox" name="sortingModeBox">
<property name="enabled">
<bool>true</bool>
@@ -264,7 +245,7 @@
</property>
<item>
<property name="text">
- <string>Simple (Dark Icons)</string>
+ <string>Simple (Colored Icons)</string>
</property>
</item>
<item>
@@ -274,12 +255,12 @@
</item>
<item>
<property name="text">
- <string>Simple (Blue Icons)</string>
+ <string>Simple (Dark Icons)</string>
</property>
</item>
<item>
<property name="text">
- <string>Simple (Colored Icons)</string>
+ <string>Simple (Blue Icons)</string>
</property>
</item>
<item>
@@ -294,17 +275,17 @@
</item>
<item>
<property name="text">
- <string notr="true">Flat</string>
+ <string>Flat</string>
</property>
</item>
<item>
<property name="text">
- <string>Custom</string>
+ <string>Legacy</string>
</property>
</item>
<item>
<property name="text">
- <string>MultiMC</string>
+ <string>Custom</string>
</property>
</item>
</widget>
@@ -499,7 +480,6 @@
<tabstop>modsDirBrowseBtn</tabstop>
<tabstop>iconsDirTextBox</tabstop>
<tabstop>iconsDirBrowseBtn</tabstop>
- <tabstop>resetNotificationsBtn</tabstop>
<tabstop>sortLastLaunchedBtn</tabstop>
<tabstop>sortByNameBtn</tabstop>
<tabstop>themeComboBox</tabstop>
diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp
index e4ad9012..ffb87bbe 100644
--- a/launcher/ui/pages/instance/ModFolderPage.cpp
+++ b/launcher/ui/pages/instance/ModFolderPage.cpp
@@ -152,8 +152,8 @@ ModFolderPage::ModFolderPage(
ui->actionsToolbar->insertActionBefore(ui->actionAdd, act);
connect(act, &QAction::triggered, this, &ModFolderPage::on_actionInstall_mods_triggered);
- ui->actionAdd->setText("Add .jar");
- ui->actionAdd->setToolTip("Add mods via local file");
+ ui->actionAdd->setText(tr("Add .jar"));
+ ui->actionAdd->setToolTip(tr("Add mods via local file"));
}
ui->actionsToolbar->insertSpacer(ui->actionView_configs);
diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp
index 6de49467..558a98fb 100644
--- a/launcher/ui/widgets/PageContainer.cpp
+++ b/launcher/ui/widgets/PageContainer.cpp
@@ -14,6 +14,7 @@
*/
#include "PageContainer.h"
+#include "BuildConfig.h"
#include "PageContainer_p.h"
#include <QStackedLayout>
@@ -207,7 +208,7 @@ void PageContainer::help()
QString pageId = m_currentPage->helpPage();
if (pageId.isEmpty())
return;
- DesktopServices::openUrl(QUrl("https://github.com/PolyMC/PolyMC/wiki/" + pageId));
+ DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg(pageId)));
}
}
diff --git a/program_info/org.polymc.PolyMC.metainfo.xml.in b/program_info/org.polymc.PolyMC.metainfo.xml.in
index 03401f3d..ff4af1c3 100644
--- a/program_info/org.polymc.PolyMC.metainfo.xml.in
+++ b/program_info/org.polymc.PolyMC.metainfo.xml.in
@@ -9,9 +9,9 @@
<developer_name>PolyMC Team</developer_name>
<summary>A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once</summary>
<metadata_license>CC0-1.0</metadata_license>
- <project_license>GPL-3.0-or-later</project_license>
+ <project_license>GPL-3.0-only</project_license>
<url type="homepage">https://polymc.org/</url>
- <url type="help">https://github.com/PolyMC/PolyMC#help--support</url>
+ <url type="help">https://polymc.org/wiki/</url>
<description>
<p>PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.</p>
<p>Features:</p>
@@ -28,23 +28,23 @@
<screenshots>
<screenshot type="default">
<caption>The main PolyMC window</caption>
- <image type="source" width="1011" height="994">https://polymc.github.io/assets/img/screenshots/LauncherDark.png</image>
+ <image type="source" width="1011" height="994">https://polymc.org/img/screenshots/LauncherDark.png</image>
</screenshot>
<screenshot>
<caption>Modpack installation</caption>
- <image type="source" width="911" height="682">https://polymc.github.io/assets/img/screenshots/ModpackInstallDark.png</image>
+ <image type="source" width="911" height="682">https://polymc.org/img/screenshots/ModpackInstallDark.png</image>
</screenshot>
<screenshot>
<caption>Mod installation</caption>
- <image type="source" width="987" height="723">https://polymc.github.io/assets/img/screenshots/ModInstallDark.png</image>
+ <image type="source" width="987" height="723">https://polymc.org/img/screenshots/ModInstallDark.png</image>
</screenshot>
<screenshot>
<caption>Instance management</caption>
- <image type="source" width="902" height="920">https://polymc.github.io/assets/img/screenshots/PropertiesDark.png</image>
+ <image type="source" width="902" height="920">https://polymc.org/img/screenshots/PropertiesDark.png</image>
</screenshot>
<screenshot>
<caption>Cat :)</caption>
- <image type="source" width="1011" height="994">https://polymc.github.io/assets/img/screenshots/LauncherCatDark.png</image>
+ <image type="source" width="1011" height="994">https://polymc.org/img/screenshots/LauncherCatDark.png</image>
</screenshot>
</screenshots>
<releases>
diff --git a/program_info/polymc-header-black.svg b/program_info/polymc-header-black.svg
index 34cda4ab..e9e7c3e2 100644
--- a/program_info/polymc-header-black.svg
+++ b/program_info/polymc-header-black.svg
@@ -1,31 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg width="1424" height="512" version="1.1" viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home">
<defs>
- <linearGradient id="linearGradient84726" x1="4.4979" x2="12.435" y1="3.8011" y2="9.5681" gradientUnits="userSpaceOnUse">
+ <linearGradient id="a" x1="4.498" x2="12.435" y1="3.801" y2="9.568" gradientUnits="userSpaceOnUse">
<stop stop-color="#88b858" offset="0"/>
<stop stop-color="#72b147" offset=".5"/>
<stop stop-color="#5a9a30" offset="1"/>
</linearGradient>
</defs>
- <g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)">
- <g>
- <path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#765338"/>
- <path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/>
- <path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/>
- <path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#72b147"/>
- <path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#5a9a30"/>
- <path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#88b858"/>
- <path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/>
+ <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/>
+ <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/>
+ <path d="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/>
+ <path d="m79 95.709-2.53 1.84-2.532-1.84c0-1.84 2.531-1.84 2.531-1.84s2.531 0 2.531 1.84z" fill="#72b147"/>
+ <path d="M76.47 93.872s0-40.121 55.165-40.121l-1.564 4.819-6.384 8.324-6.384.962-6.383 8.324-6.384.961-6.384 8.325-6.384.961-6.384 8.324-6.383.962z" fill="#5a9a30"/>
+ <path d="m73.938 95.709-6.383-.961-6.384-8.325-6.384-.961-6.384-8.324-6.384-.962-6.383-8.324-6.384-.962-6.384-8.324-1.564-4.819c55.165 0 55.165 40.121 55.165 40.121z" fill="#88b858"/>
+ <path d="m.53 6.685 7.937 5.766 7.937-5.766L8.467.918z" fill="url(#a)" transform="matrix(6.95 0 0 6.9572 17.626 7.241)"/>
+ <path d="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/>
+ <g fill="#000" stroke-width=".265" aria-label="PolyMC">
+ <g stroke-width=".01" aria-label="PolyMC">
+ <path d="M168.153 47.323q5.434 0 9.287 1.858 3.852 1.788 5.916 5.228 2.133 3.44 2.133 8.324 0 2.958-.895 5.847-.894 2.82-2.889 5.16-1.926 2.27-5.09 3.646t-7.705 1.375h-7.361v18.3h-6.673V47.322zm.688 25.041q2.958 0 4.884-.963 1.927-.963 3.027-2.408 1.1-1.513 1.582-3.164.482-1.651.482-2.958 0-1.514-.482-3.096-.481-1.651-1.65-2.958-1.101-1.376-2.959-2.202-1.788-.894-4.471-.894h-7.705v18.643zM187.49 82.6q0-4.265 1.994-7.705 2.064-3.44 5.641-5.434 3.577-1.995 8.118-1.995 4.678 0 8.186 1.995 3.509 1.995 5.435 5.434 1.926 3.44 1.926 7.705t-1.926 7.773q-1.926 3.44-5.503 5.435-3.509 1.995-8.187 1.995-4.54 0-8.118-1.857-3.508-1.927-5.572-5.298-1.995-3.44-1.995-8.048zm6.397.07q0 2.751 1.238 5.021 1.238 2.202 3.302 3.509 2.133 1.307 4.678 1.307 2.683 0 4.747-1.307 2.133-1.307 3.302-3.509 1.17-2.27 1.17-5.022 0-2.752-1.17-4.953-1.17-2.27-3.302-3.577-2.064-1.376-4.747-1.376-2.614 0-4.747 1.376-2.063 1.376-3.302 3.646-1.17 2.201-1.17 4.884zM223.251 43.858h6.398v53.246h-6.398zM238.914 110.808l18.78-42.17h5.917l-18.368 42.17zm7.017-13.484-13.69-28.687h7.223l11.489 25.453zM266.775 97.085V51.2h.063l23.855 33.774-3.043-.67L311.384 51.2h.122v45.885h-7.06v-29.88l.487 3.59-16.065 22.7h-.122l-16.31-22.7 1.218-3.286v29.576zM352.299 93.62q-.974.67-2.921 1.643-1.887.973-4.564 1.704-2.617.67-5.843.608-5.172-.062-9.31-1.825-4.138-1.826-6.999-4.869-2.86-3.104-4.442-7.06-1.522-4.016-1.522-8.52 0-5.05 1.583-9.25t4.503-7.241q2.921-3.104 6.938-4.808 4.016-1.704 8.763-1.704 4.199 0 7.485 1.156 3.347 1.096 5.598 2.496l-2.799 6.633q-1.704-1.156-4.26-2.313-2.556-1.156-5.781-1.156-2.921 0-5.599 1.217-2.678 1.156-4.686 3.347-2.008 2.13-3.225 4.99-1.156 2.86-1.156 6.208 0 3.468 1.034 6.39 1.096 2.92 3.043 5.05 2.008 2.07 4.747 3.287 2.799 1.156 6.268 1.156 3.408 0 5.964-1.035 2.616-1.095 4.199-2.434z"/>
</g>
- <path d="m0.75424 7.3773-0.22507-0.69269 7.9375 5.7669 7.9375-5.7669-0.22507 0.69269-7.7124 5.6034z" fill-opacity="0"/>
- </g>
- <g id="polymc-header-text" fill="black" transform="matrix(6.9306 0 0 6.9306 -702.9 -659.02)" stroke-width=".26458" aria-label="PolyMC">
- <path d="m120.51 108.48v2.7957h-1.3074v-7.5241h2.8784q1.2609 0 1.9999 0.65629 0.74414 0.65629 0.74414 1.7363 0 1.1059-0.72864 1.7208-0.72346 0.61495-2.0309 0.61495zm0-1.049h1.571q0.69763 0 1.0645-0.32556 0.3669-0.33073 0.3669-0.95084 0-0.60978-0.37207-0.97152-0.37207-0.3669-1.0232-0.37723h-1.6071z"/>
- <path d="m125.55 108.43q0-0.82165 0.32556-1.4779 0.32556-0.66145 0.91467-1.0128 0.58911-0.35657 1.3539-0.35657 1.1317 0 1.8345 0.72864 0.70797 0.72863 0.76481 1.9327l5e-3 0.29455q0 0.82682-0.32039 1.478-0.31523 0.65112-0.9095 1.0077-0.58911 0.35657-1.3643 0.35657-1.1834 0-1.8965-0.78548-0.70796-0.79065-0.70796-2.1032zm1.2557 0.10852q0 0.863 0.35657 1.3539 0.35656 0.48576 0.99218 0.48576t0.98702-0.49609q0.35657-0.49609 0.35657-1.4521 0-0.84749-0.36691-1.3436-0.36173-0.49609-0.98701-0.49609-0.61495 0-0.97668 0.49092-0.36174 0.48576-0.36174 1.4573z"/>
- <path d="m133.14 111.27h-1.2557v-7.9375h1.2557z"/>
- <path d="m136.46 109.47 1.1369-3.793h1.3384l-2.2221 6.4389q-0.5116 1.4108-1.7363 1.4108-0.27388 0-0.60461-0.093v-0.97151l0.23771 0.0155q0.47542 0 0.71314-0.1757 0.24287-0.17053 0.3824-0.57877l0.18087-0.48059-1.9637-5.5655h1.3539z"/>
- <path d="m141.48 103.75 2.1704 5.7671 2.1652-5.7671h1.6898v7.5241h-1.3022v-2.4805l0.12919-3.3176-2.2221 5.7981h-0.93534l-2.2169-5.7929 0.12919 3.3124v2.4805h-1.3022v-7.5241z"/>
- <path d="m154.79 108.82q-0.11369 1.2041-0.88883 1.881-0.77515 0.67179-2.0619 0.67179-0.89916 0-1.5865-0.42375-0.68212-0.42891-1.0542-1.2144t-0.38758-1.8242v-0.7028q0-1.0645 0.37724-1.8758 0.37724-0.81131 1.08-1.2506 0.70797-0.43925 1.633-0.43925 1.2454 0 2.005 0.67696 0.75965 0.67696 0.88367 1.912h-1.3022q-0.093-0.81132-0.47543-1.1679-0.37723-0.36174-1.111-0.36174-0.85265 0-1.3126 0.62529-0.45475 0.62011-0.46509 1.8242v0.66662q0 1.2196 0.43408 1.8604 0.43925 0.64078 1.2816 0.64078 0.76998 0 1.1576-0.34623t0.49093-1.1524z"/>
</g>
</svg>
diff --git a/program_info/polymc-header.Source.svg b/program_info/polymc-header.Source.svg
new file mode 100644
index 00000000..c960f33b
--- /dev/null
+++ b/program_info/polymc-header.Source.svg
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="1424"
+ height="512"
+ version="1.1"
+ viewBox="0 0 376.77 135.47"
+ id="svg866"
+ sodipodi:docname="PolyMC-Header.Source.svg"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview868"
+ pagecolor="#343434"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.61938202"
+ inkscape:cx="534.40363"
+ inkscape:cy="299.49206"
+ inkscape:window-width="2560"
+ inkscape:window-height="1382"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg866" />
+ <defs
+ id="defs831">
+ <linearGradient
+ id="linearGradient84726"
+ x1="4.4979"
+ x2="12.435"
+ y1="3.8011"
+ y2="9.5681"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="#88b858"
+ offset="0"
+ id="stop824" />
+ <stop
+ stop-color="#72b147"
+ offset=".5"
+ id="stop826" />
+ <stop
+ stop-color="#5a9a30"
+ offset="1"
+ id="stop828" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient84726"
+ id="linearGradient1147"
+ gradientUnits="userSpaceOnUse"
+ x1="4.4979"
+ y1="3.8011"
+ x2="12.435"
+ y2="9.5681" />
+ </defs>
+ <g
+ id="g1157">
+ <g
+ transform="matrix(6.95,0,0,6.9572,17.626477,7.241195)"
+ id="g1322">
+ <g
+ id="g1318">
+ <path
+ d="m 3.561,16.016 c 0,0 0,-3.5642 4.9056,-3.5642 4.9069,0 4.9056,3.5642 4.9056,3.5642 z"
+ fill="#765338"
+ id="path1304" />
+ <path
+ d="M 8.4667,12.452 3.5611,16.0162 0.5292,6.6851 Z"
+ fill="#b7835a"
+ id="path1306" />
+ <path
+ d="m 8.4667,12.452 7.9375,-5.7669 -3.0319,9.3311 z"
+ fill="#5b422d"
+ id="path1308" />
+ <path
+ d="M 8.8308,12.716 8.46663,12.98058 8.10246,12.716 c 0,-0.26458 0.36417,-0.26458 0.36417,-0.26458 0,0 0.36417,0 0.36417,0.26458 z"
+ fill="#72b147"
+ id="path1310" />
+ <path
+ d="m 8.4667,12.452 c 0,0 -2e-7,-5.7669 7.9375,-5.7669 l -0.22507,0.69269 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 z"
+ fill="#5a9a30"
+ id="path1312" />
+ <path
+ d="M 8.1025,12.716 7.18397,12.57781 6.26544,11.38131 5.34691,11.24312 4.42838,10.04662 3.50985,9.90843 2.59132,8.71193 1.67279,8.57374 0.75426,7.37724 0.52919,6.68455 c 7.9375,1e-7 7.9375,5.7669 7.9375,5.7669 z"
+ fill="#88b858"
+ id="path1314" />
+ <path
+ d="m 0.52917,6.6846 7.9375,5.7669 7.9375,-5.7669 -7.9375,-5.7669 z"
+ fill="url(#linearGradient84726)"
+ id="path1316"
+ style="fill:url(#linearGradient1147)" />
+ </g>
+ <path
+ d="m 0.75424,7.3773 -0.22507,-0.69269 7.9375,5.7669 7.9375,-5.7669 -0.22507,0.69269 -7.7124,5.6034 z"
+ fill-opacity="0"
+ id="path1320" />
+ </g>
+ <g
+ id="polymc-header-text-3"
+ fill="white"
+ transform="matrix(6.9306,0,0,6.9306,-695.39957,-649.40511)"
+ stroke-width="0.26458"
+ aria-label="PolyMC"
+ style="fill:#ffffff;fill-opacity:1">
+ <text
+ xml:space="preserve"
+ style="font-size:9.92603px;line-height:1.25;font-family:sans-serif;letter-spacing:-0.610833px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke-width:0.0101009"
+ x="121.65298"
+ y="107.71044"
+ id="text4534"><tspan
+ sodipodi:role="line"
+ id="tspan4532"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.92603px;font-family:'Josefin Sans';-inkscape-font-specification:'Josefin Sans';fill:#ffffff;fill-opacity:1;stroke-width:0.0101009"
+ x="121.65298"
+ y="107.71044">Poly<tspan
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:8.78072px;font-family:'Josefin Sans';-inkscape-font-specification:'Josefin Sans Semi-Bold'"
+ id="tspan137828"
+ rotate="0 0">MC</tspan></tspan></text>
+ </g>
+ </g>
+ <g
+ id="polymc-header-text-4"
+ fill="white"
+ transform="matrix(6.9306,0,0,6.9306,-697.30938,-585.54339)"
+ stroke-width="0.26458"
+ aria-label="PolyMC"
+ style="fill:#ffffff;fill-opacity:1" />
+</svg>
diff --git a/program_info/polymc-header.svg b/program_info/polymc-header.svg
index a896787f..837004e1 100644
--- a/program_info/polymc-header.svg
+++ b/program_info/polymc-header.svg
@@ -1,31 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg width="1424" height="512" version="1.1" viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home">
<defs>
- <linearGradient id="linearGradient84726" x1="4.4979" x2="12.435" y1="3.8011" y2="9.5681" gradientUnits="userSpaceOnUse">
+ <linearGradient id="a" x1="4.498" x2="12.435" y1="3.801" y2="9.568" gradientUnits="userSpaceOnUse">
<stop stop-color="#88b858" offset="0"/>
<stop stop-color="#72b147" offset=".5"/>
<stop stop-color="#5a9a30" offset="1"/>
</linearGradient>
</defs>
- <g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)">
- <g>
- <path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#765338"/>
- <path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/>
- <path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/>
- <path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#72b147"/>
- <path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#5a9a30"/>
- <path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#88b858"/>
- <path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/>
+ <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/>
+ <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/>
+ <path d="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/>
+ <path d="m79 95.709-2.53 1.84-2.532-1.84c0-1.84 2.531-1.84 2.531-1.84s2.531 0 2.531 1.84z" fill="#72b147"/>
+ <path d="M76.47 93.872s0-40.121 55.165-40.121l-1.564 4.819-6.384 8.324-6.384.962-6.383 8.324-6.384.961-6.384 8.325-6.384.961-6.384 8.324-6.383.962z" fill="#5a9a30"/>
+ <path d="m73.938 95.709-6.383-.961-6.384-8.325-6.384-.961-6.384-8.324-6.384-.962-6.383-8.324-6.384-.962-6.384-8.324-1.564-4.819c55.165 0 55.165 40.121 55.165 40.121z" fill="#88b858"/>
+ <path d="m.53 6.685 7.937 5.766 7.937-5.766L8.467.918z" fill="url(#a)" transform="matrix(6.95 0 0 6.9572 17.626 7.241)"/>
+ <path d="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/>
+ <g fill="#fff" stroke-width=".265" aria-label="PolyMC">
+ <g stroke-width=".01" aria-label="PolyMC">
+ <path d="M168.153 47.323q5.434 0 9.287 1.858 3.852 1.788 5.916 5.228 2.133 3.44 2.133 8.324 0 2.958-.895 5.847-.894 2.82-2.889 5.16-1.926 2.27-5.09 3.646t-7.705 1.375h-7.361v18.3h-6.673V47.322zm.688 25.041q2.958 0 4.884-.963 1.927-.963 3.027-2.408 1.1-1.513 1.582-3.164.482-1.651.482-2.958 0-1.514-.482-3.096-.481-1.651-1.65-2.958-1.101-1.376-2.959-2.202-1.788-.894-4.471-.894h-7.705v18.643zM187.49 82.6q0-4.265 1.994-7.705 2.064-3.44 5.641-5.434 3.577-1.995 8.118-1.995 4.678 0 8.186 1.995 3.509 1.995 5.435 5.434 1.926 3.44 1.926 7.705t-1.926 7.773q-1.926 3.44-5.503 5.435-3.509 1.995-8.187 1.995-4.54 0-8.118-1.857-3.508-1.927-5.572-5.298-1.995-3.44-1.995-8.048zm6.397.07q0 2.751 1.238 5.021 1.238 2.202 3.302 3.509 2.133 1.307 4.678 1.307 2.683 0 4.747-1.307 2.133-1.307 3.302-3.509 1.17-2.27 1.17-5.022 0-2.752-1.17-4.953-1.17-2.27-3.302-3.577-2.064-1.376-4.747-1.376-2.614 0-4.747 1.376-2.063 1.376-3.302 3.646-1.17 2.201-1.17 4.884zM223.251 43.858h6.398v53.246h-6.398zM238.914 110.808l18.78-42.17h5.917l-18.368 42.17zm7.017-13.484-13.69-28.687h7.223l11.489 25.453zM266.775 97.085V51.2h.063l23.855 33.774-3.043-.67L311.384 51.2h.122v45.885h-7.06v-29.88l.487 3.59-16.065 22.7h-.122l-16.31-22.7 1.218-3.286v29.576zM352.299 93.62q-.974.67-2.921 1.643-1.887.973-4.564 1.704-2.617.67-5.843.608-5.172-.062-9.31-1.825-4.138-1.826-6.999-4.869-2.86-3.104-4.442-7.06-1.522-4.016-1.522-8.52 0-5.05 1.583-9.25t4.503-7.241q2.921-3.104 6.938-4.808 4.016-1.704 8.763-1.704 4.199 0 7.485 1.156 3.347 1.096 5.598 2.496l-2.799 6.633q-1.704-1.156-4.26-2.313-2.556-1.156-5.781-1.156-2.921 0-5.599 1.217-2.678 1.156-4.686 3.347-2.008 2.13-3.225 4.99-1.156 2.86-1.156 6.208 0 3.468 1.034 6.39 1.096 2.92 3.043 5.05 2.008 2.07 4.747 3.287 2.799 1.156 6.268 1.156 3.408 0 5.964-1.035 2.616-1.095 4.199-2.434z"/>
</g>
- <path d="m0.75424 7.3773-0.22507-0.69269 7.9375 5.7669 7.9375-5.7669-0.22507 0.69269-7.7124 5.6034z" fill-opacity="0"/>
- </g>
- <g id="polymc-header-text" fill="white" transform="matrix(6.9306 0 0 6.9306 -702.9 -659.02)" stroke-width=".26458" aria-label="PolyMC">
- <path d="m120.51 108.48v2.7957h-1.3074v-7.5241h2.8784q1.2609 0 1.9999 0.65629 0.74414 0.65629 0.74414 1.7363 0 1.1059-0.72864 1.7208-0.72346 0.61495-2.0309 0.61495zm0-1.049h1.571q0.69763 0 1.0645-0.32556 0.3669-0.33073 0.3669-0.95084 0-0.60978-0.37207-0.97152-0.37207-0.3669-1.0232-0.37723h-1.6071z"/>
- <path d="m125.55 108.43q0-0.82165 0.32556-1.4779 0.32556-0.66145 0.91467-1.0128 0.58911-0.35657 1.3539-0.35657 1.1317 0 1.8345 0.72864 0.70797 0.72863 0.76481 1.9327l5e-3 0.29455q0 0.82682-0.32039 1.478-0.31523 0.65112-0.9095 1.0077-0.58911 0.35657-1.3643 0.35657-1.1834 0-1.8965-0.78548-0.70796-0.79065-0.70796-2.1032zm1.2557 0.10852q0 0.863 0.35657 1.3539 0.35656 0.48576 0.99218 0.48576t0.98702-0.49609q0.35657-0.49609 0.35657-1.4521 0-0.84749-0.36691-1.3436-0.36173-0.49609-0.98701-0.49609-0.61495 0-0.97668 0.49092-0.36174 0.48576-0.36174 1.4573z"/>
- <path d="m133.14 111.27h-1.2557v-7.9375h1.2557z"/>
- <path d="m136.46 109.47 1.1369-3.793h1.3384l-2.2221 6.4389q-0.5116 1.4108-1.7363 1.4108-0.27388 0-0.60461-0.093v-0.97151l0.23771 0.0155q0.47542 0 0.71314-0.1757 0.24287-0.17053 0.3824-0.57877l0.18087-0.48059-1.9637-5.5655h1.3539z"/>
- <path d="m141.48 103.75 2.1704 5.7671 2.1652-5.7671h1.6898v7.5241h-1.3022v-2.4805l0.12919-3.3176-2.2221 5.7981h-0.93534l-2.2169-5.7929 0.12919 3.3124v2.4805h-1.3022v-7.5241z"/>
- <path d="m154.79 108.82q-0.11369 1.2041-0.88883 1.881-0.77515 0.67179-2.0619 0.67179-0.89916 0-1.5865-0.42375-0.68212-0.42891-1.0542-1.2144t-0.38758-1.8242v-0.7028q0-1.0645 0.37724-1.8758 0.37724-0.81131 1.08-1.2506 0.70797-0.43925 1.633-0.43925 1.2454 0 2.005 0.67696 0.75965 0.67696 0.88367 1.912h-1.3022q-0.093-0.81132-0.47543-1.1679-0.37723-0.36174-1.111-0.36174-0.85265 0-1.3126 0.62529-0.45475 0.62011-0.46509 1.8242v0.66662q0 1.2196 0.43408 1.8604 0.43925 0.64078 1.2816 0.64078 0.76998 0 1.1576-0.34623t0.49093-1.1524z"/>
</g>
</svg>