fix silly mistakes and merge upstream

This commit is contained in:
flow 2022-03-18 07:54:47 -03:00
commit da43ed8ce1
31 changed files with 432 additions and 937 deletions

View File

@ -100,6 +100,7 @@ jobs:
- name: Install System Qt on Linux - name: Install System Qt on Linux
if: runner.os == 'Linux' && matrix.app_image != true if: runner.os == 'Linux' && matrix.app_image != true
run: | run: |
sudo apt-get -y update
sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5 sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
- name: Install Ninja - name: Install Ninja

340
BUILD.md
View File

@ -1,341 +1,5 @@
# Build Instructions # Build Instructions
# Contents Build instructions are available on [the website](https://polymc.org/wiki/development/build-instructions/).
- [Getting the source](#getting-the-source) 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).
- [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})
```

View File

@ -46,26 +46,24 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
##################################### Set Application options ##################################### ##################################### Set Application options #####################################
######## Set URLs ######## ######## 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_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.github.io/news/" CACHE STRING "URL that gets opened when the user clicks 'More News'") 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 version numbers ########
set(Launcher_VERSION_MAJOR 1) set(Launcher_VERSION_MAJOR 1)
set(Launcher_VERSION_MINOR 0) set(Launcher_VERSION_MINOR 1)
set(Launcher_VERSION_HOTFIX 6) set(Launcher_VERSION_HOTFIX 0)
# Build number # Build number
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
# Build platform. # 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 # Channel list URL
set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") 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 # The metadata server
set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") 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 # Translations Platform URL
set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/polymc/polymc/" CACHE STRING "URL for the translations platform.") 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 # Discord URL
set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.") set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.")
# Subreddit URL # Subreddit URL
set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.") set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.")
@ -164,13 +167,13 @@ if(UNIX AND APPLE)
# Mac bundle settings # Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") 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_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_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_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_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_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 # directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 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_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_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_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR})

View File

@ -5,8 +5,7 @@
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, either version 3 of the License, or the Free Software Foundation, version 3.
(at your option) any later version.
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

View File

@ -48,7 +48,7 @@ If you want to contribute to PolyMC you might find it useful to join our Discord
## Building ## 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 ## 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 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 ## Download information
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) 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 ## 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. 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.

View File

@ -25,12 +25,14 @@ Config::Config()
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@"; 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_COMMIT = "@Launcher_GIT_COMMIT@";
GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; 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 = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/"); VERSION_CHANNEL.remove("refs/heads/");
@ -50,12 +52,14 @@ Config::Config()
VERSION_STR = "@Launcher_VERSION_STRING@"; VERSION_STR = "@Launcher_VERSION_STRING@";
NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@"; NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@";
NEWS_OPEN_URL = "@Launcher_NEWS_OPEN_URL@"; NEWS_OPEN_URL = "@Launcher_NEWS_OPEN_URL@";
HELP_URL = "@Launcher_HELP_URL@";
IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@";
MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@"; MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@";
META_URL = "@Launcher_META_URL@"; META_URL = "@Launcher_META_URL@";
BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@";
TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@"; TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@";
MATRIX_URL = "@Launcher_MATRIX_URL@";
DISCORD_URL = "@Launcher_DISCORD_URL@"; DISCORD_URL = "@Launcher_DISCORD_URL@";
SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@"; SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@";
} }

View File

@ -46,13 +46,6 @@ public:
/// User-Agent to use for uncached requests. /// User-Agent to use for uncached requests.
QString USER_AGENT_UNCACHED; 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 /// The git commit hash of this build
QString GIT_COMMIT; QString GIT_COMMIT;
@ -73,6 +66,11 @@ public:
*/ */
QString NEWS_OPEN_URL; 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 * Client ID you can get from Imgur when you register an application
*/ */
@ -90,6 +88,7 @@ public:
QString BUG_TRACKER_URL; QString BUG_TRACKER_URL;
QString TRANSLATIONS_URL; QString TRANSLATIONS_URL;
QString MATRIX_URL;
QString DISCORD_URL; QString DISCORD_URL;
QString SUBREDDIT_URL; QString SUBREDDIT_URL;

View File

@ -515,8 +515,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
FS::updateTimestamp(m_rootPath); FS::updateTimestamp(m_rootPath);
#endif #endif
#ifdef MULTIMC_JARS_LOCATION #ifdef LAUNCHER_JARS_LOCATION
m_jarsPath = TOSTRING(MULTIMC_JARS_LOCATION); m_jarsPath = TOSTRING(LAUNCHER_JARS_LOCATION);
#endif #endif
qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; 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("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system")); m_settings->registerSetting("ApplicationTheme", QString("system"));
// Notifications
m_settings->registerSetting("ShownNotifications", QString());
// Remembered state // Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
@ -1494,7 +1491,7 @@ QString Application::getJarsPath()
{ {
return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars"); return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
} }
return m_jarsPath; return FS::PathCombine(m_rootPath, m_jarsPath);
} }
QString Application::getMSAClientID() QString Application::getMSAClientID()

View File

@ -174,13 +174,6 @@ add_unit_test(DownloadTask
DATA updater/testdata 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. # Backend for the news bar... there's usually no news.
set(NEWS_SOURCES set(NEWS_SOURCES
# News System # News System
@ -571,7 +564,6 @@ set(LOGIC_SOURCES
${NET_SOURCES} ${NET_SOURCES}
${LAUNCH_SOURCES} ${LAUNCH_SOURCES}
${UPDATE_SOURCES} ${UPDATE_SOURCES}
${NOTIFICATIONS_SOURCES}
${NEWS_SOURCES} ${NEWS_SOURCES}
${MINECRAFT_SOURCES} ${MINECRAFT_SOURCES}
${SCREENSHOTS_SOURCES} ${SCREENSHOTS_SOURCES}
@ -807,12 +799,12 @@ SET(LAUNCHER_SOURCES
ui/dialogs/NewComponentDialog.h ui/dialogs/NewComponentDialog.h
ui/dialogs/NewInstanceDialog.cpp ui/dialogs/NewInstanceDialog.cpp
ui/dialogs/NewInstanceDialog.h ui/dialogs/NewInstanceDialog.h
ui/dialogs/NotificationDialog.cpp
ui/dialogs/NotificationDialog.h
ui/pagedialog/PageDialog.cpp ui/pagedialog/PageDialog.cpp
ui/pagedialog/PageDialog.h ui/pagedialog/PageDialog.h
ui/dialogs/ProgressDialog.cpp ui/dialogs/ProgressDialog.cpp
ui/dialogs/ProgressDialog.h ui/dialogs/ProgressDialog.h
ui/dialogs/ReviewMessageBox.cpp
ui/dialogs/ReviewMessageBox.h
ui/dialogs/UpdateDialog.cpp ui/dialogs/UpdateDialog.cpp
ui/dialogs/UpdateDialog.h ui/dialogs/UpdateDialog.h
ui/dialogs/VersionSelectDialog.cpp ui/dialogs/VersionSelectDialog.cpp
@ -908,7 +900,6 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/ProfileSetupDialog.ui ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui ui/dialogs/ProgressDialog.ui
ui/dialogs/NewInstanceDialog.ui ui/dialogs/NewInstanceDialog.ui
ui/dialogs/NotificationDialog.ui
ui/dialogs/UpdateDialog.ui ui/dialogs/UpdateDialog.ui
ui/dialogs/NewComponentDialog.ui ui/dialogs/NewComponentDialog.ui
ui/dialogs/ProfileSelectDialog.ui ui/dialogs/ProfileSelectDialog.ui
@ -920,6 +911,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/AboutDialog.ui ui/dialogs/AboutDialog.ui
ui/dialogs/LoginDialog.ui ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui ui/dialogs/EditAccountDialog.ui
ui/dialogs/ReviewMessageBox.ui
) )
qt5_add_resources(LAUNCHER_RESOURCES qt5_add_resources(LAUNCHER_RESOURCES

View File

@ -56,7 +56,7 @@ void LaunchController::decideAccount()
m_parentWidget, m_parentWidget,
tr("No Accounts"), tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Mojang or Minecraft " 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?"), "Would you like to open the account manager to add an account now?"),
QMessageBox::Information, QMessageBox::Information,
QMessageBox::Yes | QMessageBox::No QMessageBox::Yes | QMessageBox::No

View File

@ -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;
}

View File

@ -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;
};

View File

@ -246,9 +246,13 @@
<!-- placeholder when loading screenshot images --> <!-- placeholder when loading screenshot images -->
<file>scalable/screenshot-placeholder.svg</file> <file>scalable/screenshot-placeholder.svg</file>
<!-- matrix logo -->
<file>scalable/matrix.svg</file>
<!-- discord logo icon thing. from discord. traced from bitmap --> <!-- discord logo icon thing. from discord. traced from bitmap -->
<file>scalable/discord.svg</file> <file>scalable/discord.svg</file>
<!-- instance icons --> <!-- instance icons -->
<file>32x32/instances/chicken.png</file> <file>32x32/instances/chicken.png</file>
<file>128x128/instances/chicken.png</file> <file>128x128/instances/chicken.png</file>

View File

@ -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>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -59,7 +59,6 @@
#include <net/NetJob.h> #include <net/NetJob.h>
#include <net/Download.h> #include <net/Download.h>
#include <news/NewsChecker.h> #include <news/NewsChecker.h>
#include <notifications/NotificationChecker.h>
#include <tools/BaseProfiler.h> #include <tools/BaseProfiler.h>
#include <updater/DownloadTask.h> #include <updater/DownloadTask.h>
#include <updater/UpdateChecker.h> #include <updater/UpdateChecker.h>
@ -82,7 +81,6 @@
#include "ui/dialogs/CopyInstanceDialog.h" #include "ui/dialogs/CopyInstanceDialog.h"
#include "ui/dialogs/UpdateDialog.h" #include "ui/dialogs/UpdateDialog.h"
#include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/EditAccountDialog.h"
#include "ui/dialogs/NotificationDialog.h"
#include "ui/dialogs/ExportInstanceDialog.h" #include "ui/dialogs/ExportInstanceDialog.h"
#include "UpdateController.h" #include "UpdateController.h"
@ -235,6 +233,7 @@ public:
TranslatedToolButton helpMenuButton; TranslatedToolButton helpMenuButton;
TranslatedAction actionReportBug; TranslatedAction actionReportBug;
TranslatedAction actionDISCORD; TranslatedAction actionDISCORD;
TranslatedAction actionMATRIX;
TranslatedAction actionREDDIT; TranslatedAction actionREDDIT;
TranslatedAction actionAbout; TranslatedAction actionAbout;
@ -344,12 +343,22 @@ public:
helpMenu->addAction(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()) { if (!BuildConfig.DISCORD_URL.isEmpty()) {
actionDISCORD = TranslatedAction(MainWindow); actionDISCORD = TranslatedAction(MainWindow);
actionDISCORD->setObjectName(QStringLiteral("actionDISCORD")); actionDISCORD->setObjectName(QStringLiteral("actionDISCORD"));
actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord")); actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord"));
actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "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); all_actions.append(&actionDISCORD);
helpMenu->addAction(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()); setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString());
// removing this looks stupid // removing this looks stupid
@ -1257,24 +1255,6 @@ QString intListToString(const QList<int> &list)
} }
return slist.join(','); 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) void MainWindow::downloadUpdates(GoUpdate::Status status)
{ {
@ -1500,6 +1480,11 @@ void MainWindow::on_actionDISCORD_triggered()
DesktopServices::openUrl(QUrl(BuildConfig.DISCORD_URL)); DesktopServices::openUrl(QUrl(BuildConfig.DISCORD_URL));
} }
void MainWindow::on_actionMATRIX_triggered()
{
DesktopServices::openUrl(QUrl(BuildConfig.MATRIX_URL));
}
void MainWindow::on_actionChangeInstIcon_triggered() void MainWindow::on_actionChangeInstIcon_triggered()
{ {
if (!m_selectedInstance) if (!m_selectedInstance)

View File

@ -28,7 +28,6 @@
class LaunchController; class LaunchController;
class NewsChecker; class NewsChecker;
class NotificationChecker;
class QToolButton; class QToolButton;
class InstanceProxyModel; class InstanceProxyModel;
class LabeledToolButton; class LabeledToolButton;
@ -73,6 +72,8 @@ private slots:
void on_actionREDDIT_triggered(); void on_actionREDDIT_triggered();
void on_actionMATRIX_triggered();
void on_actionDISCORD_triggered(); void on_actionDISCORD_triggered();
void on_actionCopyInstance_triggered(); void on_actionCopyInstance_triggered();
@ -166,8 +167,6 @@ private slots:
void updateNotAvailable(); void updateNotAvailable();
void notificationsChanged();
void defaultAccountChanged(); void defaultAccountChanged();
void changeActiveAccount(); void changeActiveAccount();
@ -213,7 +212,6 @@ private:
KonamiCode * secretEventFilter = nullptr; KonamiCode * secretEventFilter = nullptr;
unique_qobject_ptr<NewsChecker> m_newsChecker; unique_qobject_ptr<NewsChecker> m_newsChecker;
unique_qobject_ptr<NotificationChecker> m_notificationChecker;
InstancePtr m_selectedInstance; InstancePtr m_selectedInstance;
QString m_currentInstIcon; QString m_currentInstIcon;

View File

@ -5,7 +5,7 @@
#include <InstanceList.h> #include <InstanceList.h>
#include "ProgressDialog.h" #include "ProgressDialog.h"
#include "CustomMessageBox.h" #include "ReviewMessageBox.h"
#include <QLayout> #include <QLayout>
#include <QPushButton> #include <QPushButton>
@ -75,27 +75,16 @@ void ModDownloadDialog::confirm()
auto keys = modTask.keys(); auto keys = modTask.keys();
keys.sort(Qt::CaseInsensitive); keys.sort(Qt::CaseInsensitive);
auto info = QString(tr("You're about to download the following mods:")); auto confirm_dialog = ReviewMessageBox::create(
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(
this, this,
tr("Confirm mods to download"), tr("Confirm mods to download")
info,
QMessageBox::NoIcon,
QMessageBox::Cancel | QMessageBox::Ok,
QMessageBox::Ok
); );
auto AcceptButton = confirm_dialog->button(QMessageBox::Ok); for(auto task : keys){
connect(AcceptButton, &QPushButton::clicked, this, &ModDownloadDialog::accept); confirm_dialog->appendMod(task, modTask.find(task).value()->getFilename());
}
connect(confirm_dialog, &QDialog::accepted, this, &ModDownloadDialog::accept);
confirm_dialog->open(); confirm_dialog->open();
} }

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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>

View File

@ -234,11 +234,6 @@ void LauncherPage::applySettings()
{ {
auto s = APPLICATION->settings(); auto s = APPLICATION->settings();
if (ui->resetNotificationsBtn->isChecked())
{
s->set("ShownNotifications", QString());
}
// Updates // Updates
s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
s->set("UpdateChannel", m_currentUpdateChannel); s->set("UpdateChannel", m_currentUpdateChannel);
@ -247,16 +242,16 @@ void LauncherPage::applySettings()
switch (ui->themeComboBox->currentIndex()) switch (ui->themeComboBox->currentIndex())
{ {
case 0: case 0:
s->set("IconTheme", "pe_dark"); s->set("IconTheme", "pe_colored");
break; break;
case 1: case 1:
s->set("IconTheme", "pe_light"); s->set("IconTheme", "pe_light");
break; break;
case 2: case 2:
s->set("IconTheme", "pe_blue"); s->set("IconTheme", "pe_dark");
break; break;
case 3: case 3:
s->set("IconTheme", "pe_colored"); s->set("IconTheme", "pe_blue");
break; break;
case 4: case 4:
s->set("IconTheme", "OSX"); s->set("IconTheme", "OSX");
@ -268,10 +263,10 @@ void LauncherPage::applySettings()
s->set("IconTheme", "flat"); s->set("IconTheme", "flat");
break; break;
case 7: case 7:
s->set("IconTheme", "custom"); s->set("IconTheme", "multimc");
break; break;
case 8: case 8:
s->set("IconTheme", "multimc"); s->set("IconTheme", "custom");
break; break;
} }
@ -324,7 +319,7 @@ void LauncherPage::loadSettings()
m_currentUpdateChannel = s->get("UpdateChannel").toString(); m_currentUpdateChannel = s->get("UpdateChannel").toString();
//FIXME: make generic //FIXME: make generic
auto theme = s->get("IconTheme").toString(); auto theme = s->get("IconTheme").toString();
if (theme == "pe_dark") if (theme == "pe_colored")
{ {
ui->themeComboBox->setCurrentIndex(0); ui->themeComboBox->setCurrentIndex(0);
} }
@ -332,11 +327,11 @@ void LauncherPage::loadSettings()
{ {
ui->themeComboBox->setCurrentIndex(1); ui->themeComboBox->setCurrentIndex(1);
} }
else if (theme == "pe_blue") else if (theme == "pe_dark")
{ {
ui->themeComboBox->setCurrentIndex(2); ui->themeComboBox->setCurrentIndex(2);
} }
else if (theme == "pe_colored") else if (theme == "pe_blue")
{ {
ui->themeComboBox->setCurrentIndex(3); ui->themeComboBox->setCurrentIndex(3);
} }

View File

@ -184,25 +184,6 @@
<string>User Interface</string> <string>User Interface</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_6"> <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> <item>
<widget class="QGroupBox" name="sortingModeBox"> <widget class="QGroupBox" name="sortingModeBox">
<property name="enabled"> <property name="enabled">
@ -264,7 +245,7 @@
</property> </property>
<item> <item>
<property name="text"> <property name="text">
<string>Simple (Dark Icons)</string> <string>Simple (Colored Icons)</string>
</property> </property>
</item> </item>
<item> <item>
@ -274,12 +255,12 @@
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Simple (Blue Icons)</string> <string>Simple (Dark Icons)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Simple (Colored Icons)</string> <string>Simple (Blue Icons)</string>
</property> </property>
</item> </item>
<item> <item>
@ -294,7 +275,12 @@
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string notr="true">Flat</string> <string>Flat</string>
</property>
</item>
<item>
<property name="text">
<string>Legacy</string>
</property> </property>
</item> </item>
<item> <item>
@ -302,11 +288,6 @@
<string>Custom</string> <string>Custom</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>MultiMC</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -499,7 +480,6 @@
<tabstop>modsDirBrowseBtn</tabstop> <tabstop>modsDirBrowseBtn</tabstop>
<tabstop>iconsDirTextBox</tabstop> <tabstop>iconsDirTextBox</tabstop>
<tabstop>iconsDirBrowseBtn</tabstop> <tabstop>iconsDirBrowseBtn</tabstop>
<tabstop>resetNotificationsBtn</tabstop>
<tabstop>sortLastLaunchedBtn</tabstop> <tabstop>sortLastLaunchedBtn</tabstop>
<tabstop>sortByNameBtn</tabstop> <tabstop>sortByNameBtn</tabstop>
<tabstop>themeComboBox</tabstop> <tabstop>themeComboBox</tabstop>

View File

@ -152,8 +152,8 @@ ModFolderPage::ModFolderPage(
ui->actionsToolbar->insertActionBefore(ui->actionAdd, act); ui->actionsToolbar->insertActionBefore(ui->actionAdd, act);
connect(act, &QAction::triggered, this, &ModFolderPage::on_actionInstall_mods_triggered); connect(act, &QAction::triggered, this, &ModFolderPage::on_actionInstall_mods_triggered);
ui->actionAdd->setText("Add .jar"); ui->actionAdd->setText(tr("Add .jar"));
ui->actionAdd->setToolTip("Add mods via local file"); ui->actionAdd->setToolTip(tr("Add mods via local file"));
} }
ui->actionsToolbar->insertSpacer(ui->actionView_configs); ui->actionsToolbar->insertSpacer(ui->actionView_configs);

View File

@ -14,6 +14,7 @@
*/ */
#include "PageContainer.h" #include "PageContainer.h"
#include "BuildConfig.h"
#include "PageContainer_p.h" #include "PageContainer_p.h"
#include <QStackedLayout> #include <QStackedLayout>
@ -207,7 +208,7 @@ void PageContainer::help()
QString pageId = m_currentPage->helpPage(); QString pageId = m_currentPage->helpPage();
if (pageId.isEmpty()) if (pageId.isEmpty())
return; return;
DesktopServices::openUrl(QUrl("https://github.com/PolyMC/PolyMC/wiki/" + pageId)); DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg(pageId)));
} }
} }

View File

@ -9,9 +9,9 @@
<developer_name>PolyMC Team</developer_name> <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> <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> <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="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> <description>
<p>PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.</p> <p>PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.</p>
<p>Features:</p> <p>Features:</p>
@ -28,23 +28,23 @@
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<caption>The main PolyMC window</caption> <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>
<screenshot> <screenshot>
<caption>Modpack installation</caption> <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>
<screenshot> <screenshot>
<caption>Mod installation</caption> <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>
<screenshot> <screenshot>
<caption>Instance management</caption> <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>
<screenshot> <screenshot>
<caption>Cat :)</caption> <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> </screenshot>
</screenshots> </screenshots>
<releases> <releases>

View File

@ -1,31 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --> <svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home">
<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">
<defs> <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="#88b858" offset="0"/>
<stop stop-color="#72b147" offset=".5"/> <stop stop-color="#72b147" offset=".5"/>
<stop stop-color="#5a9a30" offset="1"/> <stop stop-color="#5a9a30" offset="1"/>
</linearGradient> </linearGradient>
</defs> </defs>
<g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)"> <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/>
<g> <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/>
<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="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/>
<path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/> <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="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/> <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="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="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="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="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="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="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/>
<path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/> <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> </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> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -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>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,31 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --> <svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home">
<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">
<defs> <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="#88b858" offset="0"/>
<stop stop-color="#72b147" offset=".5"/> <stop stop-color="#72b147" offset=".5"/>
<stop stop-color="#5a9a30" offset="1"/> <stop stop-color="#5a9a30" offset="1"/>
</linearGradient> </linearGradient>
</defs> </defs>
<g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)"> <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/>
<g> <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/>
<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="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/>
<path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/> <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="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/> <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="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="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="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="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="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="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/>
<path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/> <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> </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> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB