Compare commits

...

40 Commits
1.0.0 ... 1.0.3

Author SHA1 Message Date
0e4ccaca02 fix icon and version
Closes: #16

Fixed the icon so Qt renders it properly, and actually renders it
properly in the About page. Also, scaled it up a bit

Changed launcher.svg icon to temporary Ouroboros logo

fixed genicons again

Fix version to 1.0.3 (making tag rn)

Install the PolyMC icon properly.
2022-01-03 17:46:05 -05:00
b3d8ecb467 fix genicons.sh to new rDNS stuff 2022-01-03 15:54:08 -05:00
97d4b947d0 update README
grammar/punctuation
2022-01-03 15:42:44 -05:00
3613ffa80e rDNS for icons and desktop file, and metainfo
Closes: #12, #13
2022-01-03 15:42:09 -05:00
38a1772f86 Merge pull request #14 from dada513/flathub
Change flatpak to flathub
2022-01-03 15:35:13 -05:00
4382344a7c Merge pull request #15 from dada513/debian_update 2022-01-03 07:55:17 -05:00
c7283adb9f change up deb packaging 2022-01-03 12:13:16 +01:00
672646384f remove icon 2022-01-03 12:08:54 +01:00
52e156908e Change flatpak to flathub 2022-01-03 11:59:23 +01:00
30f899f37d fix2 2021-12-31 17:04:58 -05:00
9dc3647f32 fix desktop file 2021-12-31 16:52:55 -05:00
3f3c5ea247 Rebranding logo
add temporary Ouroboros logo, thanks Lenny for vectorizing

change logo file names

Desktop file now includes proper exec using the app binary name

fix genicons for use with libicns
2021-12-31 16:37:54 -05:00
541e2f0d8d Merge pull request #8 from dada513/upstream_update 2021-12-31 14:27:21 -05:00
fa98ed3ccd Merge remote-tracking branch 'upstream/develop' into upstream_update 2021-12-31 18:05:40 +01:00
9579231ccc NOISSUE fix build and change how NetJob is used
Feed it network upfront...
2021-12-31 05:27:59 +01:00
9cc168c526 NOISSUE fix some OS ifdefs 2021-12-31 00:36:25 +01:00
94fdf13f4a NOISSUE proper fix for missing profile + demo mode 2021-12-30 21:26:29 +01:00
3efcccf334 Merge pull request #4345 from graemeg/freebsd-support
Adds FreeBSD support to MultiMC
2021-12-30 20:00:45 +01:00
5e909a4e85 Merge pull request #4394 from Janrupf/develop
GH-4299 Fix Screenshot upload
2021-12-30 19:58:16 +01:00
e7b90a9a3c Merge pull request #4396 from Bildcraft1/develop
BUILD.MD: Changed from "Install Xcode" to install Xcode Command-Line tools
2021-12-30 19:25:31 +01:00
0c177b1086 added AppImage 2021-12-30 13:17:40 -05:00
ccbd223692 fix desktop icon 2021-12-30 13:03:13 -05:00
c613a1c958 add .desktop file 2021-12-30 11:53:17 -05:00
a6e59cb4f4 NOISSUE detect when user loses entitlements 2021-12-30 17:19:41 +01:00
a8b215b560 fix ebuild link 2021-12-30 09:35:52 -05:00
1f21d84fdc Update BUILD.md 2021-12-29 21:40:45 +01:00
a0f043d790 fix flatpak build link 2021-12-29 15:03:08 -05:00
113956ccc8 Enhance the dependencies list, and add information to build a .deb (#6) 2021-12-29 15:00:47 -05:00
be029ab360 GH-4299 Fix screenshot upload 2021-12-29 19:45:24 +01:00
6fe07561fe GH-4299 Don't hard crash on when missing network 2021-12-29 19:45:15 +01:00
f25a9bc103 Completely remove Google Analytics library 2021-12-29 10:37:09 -05:00
af76cf59b6 Move todo to wiki and update README
Moved "todo" section to wiki

Reqorded packages section.

Changed swirl overlay URL to my Gitea instance

Added Flatpak and Debian package info

Serve packages over packages.polymc.org, and added SHA256 sums
2021-12-29 10:12:17 -05:00
f42c3a953c Restore getNativePath() to its original form. 2021-12-28 21:59:24 +00:00
4063a496d7 Merge pull request #4392 from iGerman00/patch-1
BUILD.md - Clearer differences with binaries
2021-12-28 02:58:19 +01:00
01e4e62de3 BUILD.md - Clearer differences with binaries
Coming from personal inconvenience - I've tried to build this from source, and was faced with Microsoft accounts not working. Upon re-reading the READMEs, I didn't find a reason for it, so I resorted to messaging in the Discord, which, after some back and forth, allowed me to understand that additional private stuff is needed for it to work. The question could've been avoided entirely, in my opinion, if this was included in BUILD.md - the place where anyone intending to build from source will come for guidance.

(Not) Secrets should've been linked clearly because it's a crucial piece of info for someone building from source, since normally. I'd expect the source code to fully reflect the pre-built binaries.
2021-12-28 05:59:44 +05:00
b1b615e17f Merge pull request #4379 from CreeperzEdge/develop
Use correct title on Java check during setup
2021-12-27 17:44:26 +01:00
95c9a6d8f4 Use correct title on Java check during setup 2021-12-23 00:53:02 +11:00
3bc450a6d7 Restore the previously deleted line. 2021-12-12 16:45:18 +00:00
fce98f5e16 Fixes compilation error expanding from macro 'major'. 2021-12-12 11:45:58 +00:00
7179e75e70 Changes required to support FreeBSD 2021-12-12 11:39:36 +00:00
91 changed files with 445 additions and 1836 deletions

4
.gitignore vendored
View File

@ -45,8 +45,6 @@ run/
flatbuild
builddir
# Deb
packages/debian/polymc/usr/bin
packages/debian/polymc/usr/lib
packages/debian/polymc/usr/share/polymc/jars
packages/debian/polymc/usr/
packages/debian/polymc.deb
packages/debian/polymc/DEBIAN/control

View File

@ -26,11 +26,24 @@ Getting the project to build and run on Linux is easy if you use any modern and
## Build dependencies
* A C++ compiler capable of building C++11 code.
* Qt 5.6+ Development tools (http://qt-project.org/downloads) ("Qt Online Installer for Linux (64 bit)") or the equivalent from your package manager. It is always better to use the Qt from your distribution, as long as it has a new enough version.
* cmake 3.1 or newer
* zlib (for example, `zlib1g-dev`)
* Java JDK 8 (for example, `openjdk-8-jdk`)
* GL headers (for example, `libgl1-mesa-dev`)
* 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)
### Building a .deb
You need to install the build dependencies first
```
git clone https://github.com/PolyMC/PolyMC.git
git submodule init && git submodule update
cd packages/debian
./makedeb.sh
```
If everything works correctly, the .deb will be next to the build script, in `PolyMC/packages/debian`
### Building from command line
You need a source folder, a build folder and an install folder.
@ -180,11 +193,19 @@ zlib1.dll
# macOS
### Install prerequisites:
- Install XCode and set it up to the point where you can build things from a terminal
- Install XCode Command Line tools
- Install the official build of CMake (https://cmake.org/download/)
- Install JDK 8 (https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html)
- Get Qt 5.6 and install it (https://download.qt.io/new_archive/qt/5.6/5.6.3/)
### 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 `.app` will be constructed when you run `make install`. Supply it as the `CMAKE_INSTALL_PREFIX` argument during CMake configuration.

View File

@ -24,6 +24,7 @@ endif()
##################################### Set CMake options #####################################
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
@ -47,15 +48,18 @@ if(UNIX AND APPLE)
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type")
# Fix build with Qt 5.13
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
##################################### Set Application options #####################################
######## Set URLs ########
set(Launcher_NEWS_RSS_URL "https://multimc.org/rss.xml" CACHE STRING "URL to fetch Launcher's news RSS feed from.")
######## Set version numbers ########
set(Launcher_VERSION_MAJOR 0)
set(Launcher_VERSION_MINOR 6)
set(Launcher_VERSION_HOTFIX 14)
set(Launcher_VERSION_MAJOR 1)
set(Launcher_VERSION_MINOR 0)
set(Launcher_VERSION_HOTFIX 3)
# Build number
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
@ -78,9 +82,6 @@ set(Launcher_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE
# Imgur API Client ID
set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application")
# Google analytics ID
set(Launcher_ANALYTICS_ID "" CACHE STRING "ID you can get from Google analytics")
# MSA Client ID
set(Launcher_MSA_CLIENT_ID "17b47edd-c884-4997-926d-9e7f9a6b4647" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application")
@ -203,20 +204,27 @@ elseif(Launcher_LAYOUT_REAL STREQUAL "lin-nodeps")
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION ${BUNDLE_DEST_DIR} RENAME ${Launcher_Name})
elseif(Launcher_LAYOUT_REAL STREQUAL "lin-system")
set(Launcher_APP_BINARY_NAME "polymc" CACHE STRING "Name of the Launcher binary")
set(Launcher_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory")
set(Launcher_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory")
set(Launcher_SHARE_DEST_DIR "share/polymc" CACHE STRING "Path to the shard data directory")
set(JARS_DEST_DIR "${Launcher_SHARE_DEST_DIR}/jars")
set(Launcher_APP_BINARY_NAME "polymc" CACHE STRING "Name of the Launcher binary")
set(Launcher_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory")
set(Launcher_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory")
set(Launcher_SHARE_DEST_DIR "share/polymc" CACHE STRING "Path to the shared data directory")
set(JARS_DEST_DIR "${Launcher_SHARE_DEST_DIR}/jars")
set(Launcher_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file 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(BINARY_DEST_DIR ${Launcher_BINARY_DEST_DIR})
set(LIBRARY_DEST_DIR ${Launcher_LIBRARY_DEST_DIR})
set(BINARY_DEST_DIR ${Launcher_BINARY_DEST_DIR})
set(LIBRARY_DEST_DIR ${Launcher_LIBRARY_DEST_DIR})
MESSAGE(STATUS "Compiling for linux system with ${Launcher_SHARE_DEST_DIR} and LAUNCHER_LINUX_DATADIR")
SET(Launcher_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DLAUNCHER_LINUX_DATADIR")
MESSAGE(STATUS "Compiling for linux system with ${Launcher_SHARE_DEST_DIR} and LAUNCHER_LINUX_DATADIR")
SET(Launcher_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DLAUNCHER_LINUX_DATADIR")
# install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${Launcher_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_MetaInfo} DESTINATION ${Launcher_METAINFO_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${Launcher_ICON_DEST_DIR})
# install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps")
elseif(Launcher_LAYOUT_REAL STREQUAL "win-bundle")
set(BINARY_DEST_DIR ".")
@ -250,7 +258,6 @@ set(NBT_NAME Launcher_nbt++)
set(NBT_DEST_DIR ${LIBRARY_DEST_DIR})
add_subdirectory(libraries/libnbtplusplus)
add_subdirectory(libraries/ganalytics) # google analytics library
add_subdirectory(libraries/systeminfo) # system information library
add_subdirectory(libraries/hoedown) # markdown parser
add_subdirectory(libraries/launcher) # java based launcher part for Minecraft
@ -260,7 +267,7 @@ add_subdirectory(libraries/quazip) # zip manipulation library
add_subdirectory(libraries/rainbow) # Qt extension for colors
add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader
add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions
add_subdirectory(libraries/classparser) # google analytics library
add_subdirectory(libraries/classparser) # class parser library
add_subdirectory(libraries/optional-bare)
add_subdirectory(libraries/tomlc99) # toml parser
add_subdirectory(libraries/katabasis) # An OAuth2 library that tried to do too much

View File

@ -9,28 +9,18 @@ PolyMC is a custom launcher for Minecraft that focuses on predictability, long t
This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. The PolyMC community felt that the maintainer was not acting in the spirit of Free Software so this fork was made. Read "[Why was this fork made?](https://github.com/PolyMC/PolyMC/wiki/FAQ)" on the wiki for more details.
## todo
- [ ] Get a permanent name + icon.
- [ ] Style the logo for different icon styles.
- [ ] Packaging for Linux--Any help packaging for your favorite distro is appreciated!
- [ ] Packaging for MacOS/Windows
- [ ] Stop relying on MultiMC-Hosted metadata services
- [ ] Remove references to MultiMC
- [ ] Change up packaging, remove the install script junk
- [ ] AppImage, Flatpak, .deb, ebuild, and AUR packages
- [ ] Meson
- [x] Long-term solution for the MSA client ID issue
- [x] Figure out a way to switch to GPL.
## Packages
Experimental packages are available for Linux (non-portable) and Windows (portable). Both versions are confirmed to work but the Windows version needs more testing--please volunteer if you use Windows!
Several source build packages are available, along with experimental pre-built generic packages.
- An [AUR package](https://aur.archlinux.org/packages/polymc-git/) is also available.
- A Gentoo ebuild is available in the [swirl](https://github.com/binex-dsk/ebuilds) overlay, available as `games-action/polymc`. Check the README for instructions on how to add the overlay.
- A full list of generic, pre-built packages is available [here](https://jenkins.polymc.org/job/PolyMC/lastSuccessfulBuild/artifact/).
- An [AUR package](https://aur.archlinux.org/packages/polymc-git/) is available.
- A Gentoo ebuild is available in the [swirl](https://git.swurl.xyz/swirl/ebuilds) overlay, named `games-action/polymc`. Check the README for instructions on how to add the overlay.
- A Flatpak is available in [Flathub](https://flathub.org/apps/details/org.polymc.PolyMC). You can install it from there or build it yourself using [this source](https://github.com/flathub/org.polymc.PolyMC).
- Generic, prebuilt packages (archived by version) can be found [here](https://packages.polymc.org/) ([latest](https://packages.polymc.org/latest)).
- Last build status: https://jenkins.polymc.org/job/PolyMC/lastBuild/
- [Linux (AMD64) System](https://jenkins.polymc.org/job/PolyMC/lastSuccessfulBuild/artifact/lin64-system.tar.zst) - this is a generic system package intended to be used as a base for making distro-specific packages.
- [Windows (32-bit)](https://jenkins.polymc.org/job/PolyMC/lastSuccessfulBuild/artifact/win32.zip) - this is a portable package, you can extract it anywhere and run it. This package needs testing.
- [Linux (AMD64) System](https://packages.polymc.org/latest/lin64-system/lin64-system.tar.zst) ([SHA256](https://packages.polymc.org/latest/lin64-system/lin64-system.tar.zst.sha256)) - this is a generic system package intended to be used as a base for making distro-specific packages.
- [Windows (32-bit)](https://packages.polymc.org/latest/win32/win32.zip) ([SHA256](https://packages.polymc.org/latest/win32/win32.zip.sha256)) - this is a portable package, you can extract it anywhere and run it. This package needs testing.
- [Debian (AMD64)](https://packages.polymc.org/latest/deb/polymc-amd64.deb) ([SHA256](https://packages.polymc.org/latest/deb/polymc-amd64.deb.sha256)) - this is intended to be installed with `dpkg -i`. Alternatively, you may build the `.deb` yourself, by going to `packages/debian` and running `./makedeb.sh`.
- [AppImage (AMD64)](https://packages.polymc.org/latest/appimage/PolyMC-latest-x86_64.AppImage) ([SHA256](https://packages.polymc.org/latest/appimage/PolyMC-latest-x86_64.AppImage.sha256)) - `chmod +x` must be run on this file before usage. This should work on any distribution.
- MacOS currently does not have any packages. We are still working on setting up MacOS packaging.
## Development
@ -60,7 +50,7 @@ Feel free to create an issue if you need help. However, you might find it easier
[![PolyMC Discord](https://img.shields.io/discord/923671181020766230?label=PolyMC%20Discord)](https://discord.gg/xq7fxrgtMP)
For people who don't want to use Discord, we have a Matrix Space which is bridged to the discord server. Be sure to enable spaces first (Settings -> Labs -> Spaces), and then you may join the space:
For people who don't want to use Discord, we have a Matrix Space which is bridged to the Discord server. Be sure to enable spaces first (Settings -> Labs -> Spaces), and then you may join the space:
[![PolyMC Space](https://img.shields.io/matrix/polymc:polymc.org?label=PolyMC%20Space&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#polymc:polymc.org)

View File

@ -24,7 +24,6 @@ Config::Config()
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@";
ANALYTICS_ID = "@Launcher_ANALYTICS_ID@";
NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@";
FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@";

View File

@ -46,9 +46,6 @@ public:
QString USER_AGENT_UNCACHED;
/// Google analytics ID
QString ANALYTICS_ID;
/// URL for notifications
QString NOTIFICATION_URL;
@ -115,3 +112,4 @@ public:
};
extern const Config BuildConfig;

View File

@ -26,7 +26,6 @@
#include "ui/setupwizard/SetupWizard.h"
#include "ui/setupwizard/LanguageWizardPage.h"
#include "ui/setupwizard/JavaWizardPage.h"
#include "ui/setupwizard/AnalyticsWizardPage.h"
#include "ui/dialogs/CustomMessageBox.h"
@ -73,7 +72,6 @@
#include <DesktopServices.h>
#include <LocalPeer.h>
#include <ganalytics.h>
#include <sys.h>
@ -525,7 +523,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Set up paths
{
// Root path is used for updates.
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
QDir foo(FS::PathCombine(binPath, ".."));
m_rootPath = foo.absolutePath();
#elif defined(Q_OS_WIN32)
@ -719,14 +717,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// paste.ee API key
m_settings->registerSetting("PasteEEAPIKey", "multimc");
if(!BuildConfig.ANALYTICS_ID.isEmpty())
{
// Analytics
m_settings->registerSetting("Analytics", true);
m_settings->registerSetting("AnalyticsSeen", 0);
m_settings->registerSetting("AnalyticsClientID", QString());
}
// Init page provider
{
m_globalSettingsProvider = std::make_shared<GenericPageProvider>(tr("Settings"));
@ -908,46 +898,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
qDebug() << "<> Application theme set.";
}
// Initialize analytics
[this]()
{
const int analyticsVersion = 2;
if(BuildConfig.ANALYTICS_ID.isEmpty())
{
return;
}
auto analyticsSetting = m_settings->getSetting("Analytics");
connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Application::analyticsSettingChanged);
QString clientID = m_settings->get("AnalyticsClientID").toString();
if(clientID.isEmpty())
{
clientID = QUuid::createUuid().toString();
clientID.remove(QLatin1Char('{'));
clientID.remove(QLatin1Char('}'));
m_settings->set("AnalyticsClientID", clientID);
}
m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this);
m_analytics->setLogLevel(GAnalytics::Debug);
m_analytics->setAnonymizeIPs(true);
// FIXME: the ganalytics library has no idea about our fancy shared pointers...
m_analytics->setNetworkAccessManager(network().get());
if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version())
{
qDebug() << "Analytics info not seen by user yet (or old version).";
return;
}
if(!m_settings->get("Analytics").toBool())
{
qDebug() << "Analytics disabled by user.";
return;
}
m_analytics->enable();
qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID;
}();
if(createSetupWizard())
{
return;
@ -974,29 +924,13 @@ bool Application::createSetupWizard()
}
return false;
}();
bool analyticsRequired = [&]()
{
if(BuildConfig.ANALYTICS_ID.isEmpty())
{
return false;
}
if (!settings()->get("Analytics").toBool())
{
return false;
}
if (settings()->get("AnalyticsSeen").toInt() < analytics()->version())
{
return true;
}
return false;
}();
bool languageRequired = [&]()
{
if (settings()->get("Language").toString().isEmpty())
return true;
return false;
}();
bool wizardRequired = javaRequired || analyticsRequired || languageRequired;
bool wizardRequired = javaRequired || languageRequired;
if(wizardRequired)
{
@ -1009,10 +943,6 @@ bool Application::createSetupWizard()
{
m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
}
if(analyticsRequired)
{
m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard));
}
connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished);
m_setupWizard->show();
return true;
@ -1169,22 +1099,6 @@ void Application::messageReceived(const QByteArray& message)
}
}
void Application::analyticsSettingChanged(const Setting&, QVariant value)
{
if(!m_analytics)
return;
bool enabled = value.toBool();
if(enabled)
{
qDebug() << "Analytics enabled by user.";
}
else
{
qDebug() << "Analytics disabled by user.";
}
m_analytics->enable(enabled);
}
std::shared_ptr<TranslationsModel> Application::translations()
{
return m_translations;
@ -1234,7 +1148,7 @@ void Application::setIconTheme(const QString& name)
QIcon Application::getThemedIcon(const QString& name)
{
if(name == "logo") {
return QIcon(":/logo.svg");
return QIcon(":/org.polymc.PolyMC.svg");
}
return XdgIcon::fromTheme(name);
}
@ -1454,60 +1368,6 @@ MainWindow* Application::showMainWindow(bool minimized)
connect(m_mainWindow, &MainWindow::isClosing, this, &Application::on_windowClose);
m_openWindows++;
}
// FIXME: move this somewhere else...
if(m_analytics)
{
auto windowSize = m_mainWindow->size();
auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height());
qDebug() << "Viewport size" << sizeString;
m_analytics->setViewportSize(sizeString);
/*
* cm1 = java min heap [MB]
* cm2 = java max heap [MB]
* cm3 = system RAM [MB]
*
* cd1 = java version
* cd2 = java architecture
* cd3 = system architecture
* cd4 = CPU architecture
*/
QVariantMap customValues;
int min = m_settings->get("MinMemAlloc").toInt();
int max = m_settings->get("MaxMemAlloc").toInt();
if(min < max)
{
customValues["cm1"] = min;
customValues["cm2"] = max;
}
else
{
customValues["cm1"] = max;
customValues["cm2"] = min;
}
constexpr uint64_t Mega = 1024ull * 1024ull;
int ramSize = int(Sys::getSystemRam() / Mega);
qDebug() << "RAM size is" << ramSize << "MB";
customValues["cm3"] = ramSize;
customValues["cd1"] = m_settings->get("JavaVersion");
customValues["cd2"] = m_settings->get("JavaArchitecture");
customValues["cd3"] = Sys::isSystem64bit() ? "64":"32";
customValues["cd4"] = Sys::isCPU64bit() ? "64":"32";
auto kernelInfo = Sys::getKernelInfo();
customValues["cd5"] = kernelInfo.kernelName;
customValues["cd6"] = kernelInfo.kernelVersion;
auto distInfo = Sys::getDistributionInfo();
if(!distInfo.distributionName.isEmpty())
{
customValues["cd7"] = distInfo.distributionName;
}
if(!distInfo.distributionVersion.isEmpty())
{
customValues["cd8"] = distInfo.distributionVersion;
}
m_analytics->sendScreenView("Main Window", customValues);
}
return m_mainWindow;
}

View File

@ -33,7 +33,6 @@ class BaseDetachedToolFactory;
class TranslationsModel;
class ITheme;
class MCEditTool;
class GAnalytics;
namespace Meta {
class Index;
@ -60,10 +59,6 @@ public:
Application(int &argc, char **argv);
virtual ~Application();
GAnalytics *analytics() const {
return m_analytics;
}
std::shared_ptr<SettingsObject> settings() const {
return m_settings;
}
@ -161,7 +156,6 @@ private slots:
void messageReceived(const QByteArray & message);
void controllerSucceeded();
void controllerFailed(const QString & error);
void analyticsSettingChanged(const Setting &setting, QVariant value);
void setupWizardFinished(int status);
private:
@ -226,7 +220,6 @@ private:
// peer launcher instance connector - used to implement single instance launcher and signalling
LocalPeer * m_peerInstance = nullptr;
GAnalytics * m_analytics = nullptr;
SetupWizard * m_setupWizard = nullptr;
public:
QString m_instanceIdToLaunch;
@ -236,3 +229,4 @@ public:
QUrl m_zipToImport;
std::unique_ptr<QFile> logFile;
};

View File

@ -627,8 +627,6 @@ SET(LAUNCHER_SOURCES
# GUI - setup wizard
ui/setupwizard/SetupWizard.h
ui/setupwizard/SetupWizard.cpp
ui/setupwizard/AnalyticsWizardPage.cpp
ui/setupwizard/AnalyticsWizardPage.h
ui/setupwizard/BaseWizardPage.h
ui/setupwizard/JavaWizardPage.cpp
ui/setupwizard/JavaWizardPage.h
@ -932,7 +930,6 @@ target_link_libraries(Launcher_logic
hoedown
Launcher_rainbow
LocalPeer
ganalytics
)
target_link_libraries(Launcher_logic)

View File

@ -7,7 +7,7 @@
/**
* This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing.
*/
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
#include <unistd.h>
#include <errno.h>
@ -83,7 +83,7 @@ bool openDirectory(const QString &path, bool ensureExists)
{
return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
};
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
#else
return f();
@ -97,7 +97,7 @@ bool openFile(const QString &path)
{
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
};
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
#else
return f();
@ -107,7 +107,7 @@ bool openFile(const QString &path)
bool openFile(const QString &application, const QString &path, const QString &workingDirectory, qint64 *pid)
{
qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]()
{
@ -121,7 +121,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo
bool run(const QString &application, const QStringList &args, const QString &workingDirectory, qint64 *pid)
{
qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]()
{
@ -139,7 +139,7 @@ bool openUrl(const QUrl &url)
{
return QDesktopServices::openUrl(url);
};
#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
#else
return f();

View File

@ -403,7 +403,7 @@ QString getDesktopDir()
bool createShortCut(QString location, QString dest, QStringList args, QString name,
QString icon)
{
#if defined Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
location = PathCombine(location, name + ".desktop");
QFile f(location);

View File

@ -55,14 +55,14 @@ void InstanceImportTask::executeTask()
const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
auto entry = APPLICATION->metacache()->resolveEntry("general", path);
entry->setStale(true);
m_filesNetJob.reset(new NetJob(tr("Modpack download")));
m_filesNetJob = new NetJob(tr("Modpack download"), APPLICATION->network());
m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
m_archivePath = entry->getFullPath();
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded);
connect(job, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged);
connect(job, &NetJob::failed, this, &InstanceImportTask::downloadFailed);
m_filesNetJob->start(APPLICATION->network());
m_filesNetJob->start();
}
}
@ -337,7 +337,7 @@ void InstanceImportTask::processFlame()
connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, [&]()
{
auto results = m_modIdResolver->getResults();
m_filesNetJob.reset(new NetJob(tr("Mod download")));
m_filesNetJob = new NetJob(tr("Mod download"), APPLICATION->network());
for(auto result: results.files)
{
QString filename = result.fileName;
@ -391,7 +391,7 @@ void InstanceImportTask::processFlame()
setProgress(current, total);
});
setStatus(tr("Downloading mods..."));
m_filesNetJob->start(APPLICATION->network());
m_filesNetJob->start();
}
);
connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [&](QString reason)

View File

@ -16,6 +16,7 @@
#include <QHostInfo>
#include <QList>
#include <QHostAddress>
#include <QPushButton>
#include "BuildConfig.h"
#include "JavaCommon.h"
@ -145,36 +146,44 @@ void LaunchController::login() {
m_session->MakeOffline(usedname);
// offline flavored game from here :3
}
if(m_accountToUse->ownsMinecraft() && !m_accountToUse->hasProfile()) {
auto entitlement = m_accountToUse->accountData()->minecraftEntitlement;
QString errorString;
if(!entitlement.canPlayMinecraft) {
errorString = tr("The account does not own Minecraft. You need to purchase the game first to play it.");
QMessageBox::warning(
nullptr,
tr("Missing Minecraft profile"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString);
return;
}
// Now handle setting up a profile name here...
ProfileSetupDialog dialog(m_accountToUse, m_parentWidget);
if (dialog.exec() == QDialog::Accepted)
{
tryagain = true;
continue;
}
else
{
emitFailed(tr("Received undetermined session status during login."));
return;
if(m_accountToUse->ownsMinecraft()) {
if(!m_accountToUse->hasProfile()) {
// Now handle setting up a profile name here...
ProfileSetupDialog dialog(m_accountToUse, m_parentWidget);
if (dialog.exec() == QDialog::Accepted)
{
tryagain = true;
continue;
}
else
{
emitFailed(tr("Received undetermined session status during login."));
return;
}
}
// we own Minecraft, there is a profile, it's all ready to go!
launchInstance();
return;
}
else {
launchInstance();
// play demo ?
QMessageBox box(m_parentWidget);
box.setWindowTitle(tr("Play demo?"));
box.setText(tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play the demo?"));
box.setIcon(QMessageBox::Warning);
auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole);
auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole);
box.setDefaultButton(cancelButton);
box.exec();
if(box.clickedButton() == demoButton) {
// play demo here
m_session->MakeDemo();
launchInstance();
}
else {
emitFailed(tr("Launch cancelled - account does not own Minecraft."));
}
}
return;
}

View File

@ -93,7 +93,7 @@ void UpdateController::installUpdates()
qDebug() << "Installing updates.";
#ifdef Q_OS_WIN
QString finishCmd = QApplication::applicationFilePath();
#elif defined Q_OS_LINUX
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
QString finishCmd = FS::PathCombine(m_root, BuildConfig.LAUNCHER_NAME);
#elif defined Q_OS_MAC
QString finishCmd = QApplication::applicationFilePath();

View File

@ -78,7 +78,7 @@ void Version::parse()
// FIXME: this is bad. versions can contain a lot more separators...
QStringList parts = m_string.split('.');
for (const auto &part : parts)
for (const auto& part : parts)
{
m_sections.append(Section(part));
}

View File

@ -31,7 +31,7 @@ JavaUtils::JavaUtils()
{
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
static QString processLD_LIBRARY_PATH(const QString & LD_LIBRARY_PATH)
{
QDir mmcBin(QCoreApplication::applicationDirPath());
@ -83,7 +83,7 @@ QProcessEnvironment CleanEnviroment()
qDebug() << "Env: ignoring" << key << value;
continue;
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// Do not pass LD_* variables to java. They were intended for MultiMC
if(key.startsWith("LD_"))
{

View File

@ -40,7 +40,7 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(multimc);
Q_INIT_RESOURCE(backgrounds);
Q_INIT_RESOURCE(documents);
Q_INIT_RESOURCE(logo);
Q_INIT_RESOURCE(polymc);
Q_INIT_RESOURCE(pe_dark);
Q_INIT_RESOURCE(pe_light);

View File

@ -117,7 +117,7 @@ void Meta::BaseEntity::load(Net::Mode loadType)
{
return;
}
m_updateTask = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()));
m_updateTask = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()), APPLICATION->network());
auto url = this->url();
auto entry = APPLICATION->metacache()->resolveEntry("meta", localFilename());
entry->setStale(true);
@ -140,7 +140,7 @@ void Meta::BaseEntity::load(Net::Mode loadType)
m_updateStatus = UpdateStatus::Failed;
m_updateTask.reset();
});
m_updateTask->start(APPLICATION->network());
m_updateTask->start();
}
bool Meta::BaseEntity::isLoaded() const

View File

@ -29,6 +29,8 @@
#include "net/ChecksumValidator.h"
#include "BuildConfig.h"
#include "Application.h"
namespace {
QSet<QString> collectPathsFromDir(QString dirPath)
{
@ -318,7 +320,7 @@ QString AssetObject::getRelPath()
NetJob::Ptr AssetsIndex::getDownloadJob()
{
auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
auto job = new NetJob(QObject::tr("Assets for %1").arg(id), APPLICATION->network());
for (auto &object : objects.values())
{
auto dl = object.getDownloadAction();

View File

@ -431,8 +431,7 @@ QStringList MinecraftInstance::processMinecraftArgs(
QMap<QString, QString> token_mapping;
// yggdrasil!
if(session)
{
if(session) {
// token_mapping["auth_username"] = session->username;
token_mapping["auth_session"] = session->session;
token_mapping["auth_access_token"] = session->access_token;
@ -440,6 +439,9 @@ QStringList MinecraftInstance::processMinecraftArgs(
token_mapping["auth_uuid"] = session->uuid;
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
if(session->demo) {
args_pattern += " --demo";
}
}
// blatant self-promotion.
@ -872,7 +874,9 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
// if we aren't in offline mode,.
if(session->status != AuthSession::PlayableOffline)
{
process->appendStep(new ClaimAccount(pptr, session));
if(!session->demo) {
process->appendStep(new ClaimAccount(pptr, session));
}
process->appendStep(new Update(pptr, Net::Mode::Online));
}
else

View File

@ -17,6 +17,8 @@
OpSys OpSys_fromString(QString name)
{
if (name == "freebsd")
return Os_FreeBSD;
if (name == "linux")
return Os_Linux;
if (name == "windows")
@ -30,6 +32,8 @@ QString OpSys_toString(OpSys name)
{
switch (name)
{
case Os_FreeBSD:
return "freebsd";
case Os_Linux:
return "linux";
case Os_OSX:

View File

@ -18,6 +18,7 @@
enum OpSys
{
Os_Windows,
Os_FreeBSD,
Os_Linux,
Os_OSX,
Os_Other
@ -27,11 +28,11 @@ OpSys OpSys_fromString(QString);
QString OpSys_toString(OpSys);
#ifdef Q_OS_WIN32
#define currentSystem Os_Windows
#define currentSystem Os_Windows
#elif defined Q_OS_MAC
#define currentSystem Os_OSX
#elif defined Q_OS_FREEBSD
#define currentSystem Os_FreeBSD
#else
#ifdef Q_OS_MAC
#define currentSystem Os_OSX
#else
#define currentSystem Os_Linux
#endif
#define currentSystem Os_Linux
#endif

View File

@ -30,3 +30,8 @@ bool AuthSession::MakeOffline(QString offline_playername)
status = PlayableOffline;
return true;
}
void AuthSession::MakeDemo() {
player_name = "Player";
demo = true;
}

View File

@ -11,6 +11,7 @@ class QNetworkAccessManager;
struct AuthSession
{
bool MakeOffline(QString offline_playername);
void MakeDemo();
QString serializeUserProperties();
@ -43,6 +44,9 @@ struct AuthSession
bool auth_server_online = false;
// Did the user request online mode?
bool wants_online = true;
//Is this a demo session?
bool demo = false;
};
typedef std::shared_ptr<AuthSession> AuthSessionPtr;

View File

@ -226,6 +226,8 @@ bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output)
}
auto obj = doc.object();
output.canPlayMinecraft = false;
output.ownsMinecraft = false;
auto itemsArray = obj.value("items").toArray();
for(auto item: itemsArray) {

View File

@ -6,7 +6,7 @@
ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchStep(parent)
{
if(session->status == AuthSession::Status::PlayableOnline)
if(session->status == AuthSession::Status::PlayableOnline && !session->demo)
{
auto accounts = APPLICATION->accounts();
m_account = accounts->getAccountByProfileName(session->player_name);

View File

@ -23,6 +23,13 @@
#include "FileSystem.h"
#include <QDir>
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif
static QString replaceSuffix (QString target, const QString &suffix, const QString &replacement)
{
if (!target.endsWith(suffix))

View File

@ -19,8 +19,9 @@
#include "PrintInstanceInfo.h"
#include <launch/LaunchTask.h>
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
namespace {
#if defined(Q_OS_LINUX)
void probeProcCpuinfo(QStringList &log)
{
std::ifstream cpuin("/proc/cpuinfo");
@ -66,7 +67,43 @@ void runLspci(QStringList &log)
}
pclose(lspci);
}
#elif defined(Q_OS_FREEBSD)
void runSysctlHwModel(QStringList &log)
{
char buff[512];
FILE *hwmodel = popen("sysctl hw.model", "r");
while (fgets(buff, 512, hwmodel) != NULL)
{
log << QString::fromUtf8(buff);
break;
}
pclose(hwmodel);
}
void runPciconf(QStringList &log)
{
char buff[512];
std::string strcard;
FILE *pciconf = popen("pciconf -lv -a vgapci0", "r");
while (fgets(buff, 512, pciconf) != NULL)
{
if (strncmp(buff, " vendor", 10) == 0)
{
std::string str(buff);
strcard.append(str.substr(str.find_first_of("'") + 1, str.find_last_not_of("'") - (str.find_first_of("'") + 2)));
strcard.append(" ");
}
else if (strncmp(buff, " device", 10) == 0)
{
std::string str2(buff);
strcard.append(str2.substr(str2.find_first_of("'") + 1, str2.find_last_not_of("'") - (str2.find_first_of("'") + 2)));
}
log << QString::fromStdString(strcard);
break;
}
pclose(pciconf);
}
#endif
void runGlxinfo(QStringList & log)
{
// FIXME: fixed size buffers...
@ -94,10 +131,14 @@ void PrintInstanceInfo::executeTask()
auto instance = m_parent->instance();
QStringList log;
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX)
::probeProcCpuinfo(log);
::runLspci(log);
::runGlxinfo(log);
#elif defined(Q_OS_FREEBSD)
::runSysctlHwModel(log);
::runPciconf(log);
::runGlxinfo(log);
#endif
logLines(log, MessageLevel::Launcher);

View File

@ -5,6 +5,13 @@
#include <minecraft/PackProfile.h>
#include <minecraft/VersionFilterData.h>
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif
void VerifyJavaInstall::executeTask() {
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());

View File

@ -24,7 +24,10 @@ void AssetUpdateTask::executeTask()
auto assets = profile->getMinecraftAssets();
QUrl indexUrl = assets->url;
QString localPath = assets->id + ".json";
auto job = new NetJob(tr("Asset index for %1").arg(m_inst->name()));
auto job = new NetJob(
tr("Asset index for %1").arg(m_inst->name()),
APPLICATION->network()
);
auto metacache = APPLICATION->metacache();
auto entry = metacache->resolveEntry("asset_indexes", localPath);
@ -43,7 +46,7 @@ void AssetUpdateTask::executeTask()
connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
qDebug() << m_inst->name() << ": Starting asset index download";
downloadJob->start(APPLICATION->network());
downloadJob->start();
}
bool AssetUpdateTask::canAbort() const
@ -78,7 +81,7 @@ void AssetUpdateTask::assetIndexFinished()
connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded);
connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed);
connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
downloadJob->start(APPLICATION->network());
downloadJob->start();
return;
}
emitSucceeded();

View File

@ -61,7 +61,7 @@ void FMLLibrariesTask::executeTask()
// download missing libs to our place
setStatus(tr("Downloading FML libraries..."));
auto dljob = new NetJob("FML libraries");
auto dljob = new NetJob("FML libraries", APPLICATION->network());
auto metacache = APPLICATION->metacache();
for (auto &lib : fmlLibsToProcess)
{
@ -74,7 +74,7 @@ void FMLLibrariesTask::executeTask()
connect(dljob, &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed);
connect(dljob, &NetJob::progress, this, &FMLLibrariesTask::progress);
downloadJob.reset(dljob);
downloadJob->start(APPLICATION->network());
downloadJob->start();
}
bool FMLLibrariesTask::canAbort() const

View File

@ -20,7 +20,7 @@ void LibrariesTask::executeTask()
auto components = inst->getPackProfile();
auto profile = components->getProfile();
auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()), APPLICATION->network());
downloadJob.reset(job);
auto metacache = APPLICATION->metacache();
@ -65,7 +65,7 @@ void LibrariesTask::executeTask()
connect(downloadJob.get(), &NetJob::succeeded, this, &LibrariesTask::emitSucceeded);
connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed);
connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress);
downloadJob->start(APPLICATION->network());
downloadJob->start();
}
bool LibrariesTask::canAbort() const

View File

@ -58,12 +58,12 @@ bool PackInstallTask::abort()
void PackInstallTask::executeTask()
{
qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId();
auto *netJob = new NetJob("ATLauncher::VersionFetch");
auto *netJob = new NetJob("ATLauncher::VersionFetch", APPLICATION->network());
auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
.arg(m_pack).arg(m_version_name);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
@ -424,7 +424,7 @@ void PackInstallTask::installConfigs()
{
qDebug() << "PackInstallTask::installConfigs: " << QThread::currentThreadId();
setStatus(tr("Downloading configs..."));
jobPtr.reset(new NetJob(tr("Config download")));
jobPtr = new NetJob(tr("Config download"), APPLICATION->network());
auto path = QString("Configs/%1/%2.zip").arg(m_pack).arg(m_version_name);
auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip")
@ -458,7 +458,7 @@ void PackInstallTask::installConfigs()
setProgress(current, total);
});
jobPtr->start(APPLICATION->network());
jobPtr->start();
}
void PackInstallTask::extractConfigs()
@ -508,7 +508,7 @@ void PackInstallTask::downloadMods()
setStatus(tr("Downloading mods..."));
jarmods.clear();
jobPtr.reset(new NetJob(tr("Mod download")));
jobPtr = new NetJob(tr("Mod download"), APPLICATION->network());
for(const auto& mod : m_version.mods) {
// skip non-client mods
if(!mod.client) continue;
@ -613,7 +613,7 @@ void PackInstallTask::downloadMods()
setProgress(current, total);
});
jobPtr->start(APPLICATION->network());
jobPtr->start();
}
void PackInstallTask::onModsDownloaded() {

View File

@ -14,7 +14,7 @@ void Flame::FileResolvingTask::executeTask()
{
setStatus(tr("Resolving mod IDs..."));
setProgress(0, m_toProcess.files.size());
m_dljob = new NetJob("Mod id resolver");
m_dljob = new NetJob("Mod id resolver", m_network);
results.resize(m_toProcess.files.size());
int index = 0;
for(auto & file: m_toProcess.files)
@ -27,7 +27,7 @@ void Flame::FileResolvingTask::executeTask()
index ++;
}
connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
m_dljob->start(m_network);
m_dljob->start();
}
void Flame::FileResolvingTask::netJobFinished()

View File

@ -12,7 +12,7 @@ void PackFetchTask::fetch()
publicPacks.clear();
thirdPartyPacks.clear();
jobPtr = new NetJob("LegacyFTB::ModpackFetch");
jobPtr = new NetJob("LegacyFTB::ModpackFetch", m_network);
QUrl publicPacksUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml");
qDebug() << "Downloading public version info from" << publicPacksUrl.toString();
@ -25,7 +25,7 @@ void PackFetchTask::fetch()
QObject::connect(jobPtr.get(), &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished);
QObject::connect(jobPtr.get(), &NetJob::failed, this, &PackFetchTask::fileDownloadFailed);
jobPtr->start(m_network);
jobPtr->start();
}
void PackFetchTask::fetchPrivate(const QStringList & toFetch)
@ -35,7 +35,7 @@ void PackFetchTask::fetchPrivate(const QStringList & toFetch)
for (auto &packCode: toFetch)
{
QByteArray *data = new QByteArray();
NetJob *job = new NetJob("Fetching private pack");
NetJob *job = new NetJob("Fetching private pack", m_network);
job->addNetAction(Net::Download::makeByteArray(privatePackBaseUrl.arg(packCode), data));
QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode]
@ -63,7 +63,7 @@ void PackFetchTask::fetchPrivate(const QStringList & toFetch)
delete data;
});
job->start(m_network);
job->start();
}
}

View File

@ -33,7 +33,7 @@ void PackInstallTask::downloadPack()
auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
auto entry = APPLICATION->metacache()->resolveEntry("FTBPacks", packoffset);
netJobContainer = new NetJob("Download FTB Pack");
netJobContainer = new NetJob("Download FTB Pack", m_network);
entry->setStale(true);
QString url;
@ -51,7 +51,7 @@ void PackInstallTask::downloadPack()
connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
connect(netJobContainer.get(), &NetJob::progress, this, &PackInstallTask::onDownloadProgress);
netJobContainer->start(m_network);
netJobContainer->start();
progress(1, 4);
}

View File

@ -63,12 +63,11 @@ void PackInstallTask::executeTask()
return;
}
auto *netJob = new NetJob("ModpacksCH::VersionFetch");
auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1/%2")
.arg(m_pack.id).arg(version.id);
auto *netJob = new NetJob("ModpacksCH::VersionFetch", APPLICATION->network());
auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1/%2").arg(m_pack.id).arg(version.id);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
@ -113,7 +112,7 @@ void PackInstallTask::downloadPack()
{
setStatus(tr("Downloading mods..."));
jobPtr = new NetJob(tr("Mod download"));
jobPtr = new NetJob(tr("Mod download"), APPLICATION->network());
for(auto file : m_version.files) {
if(file.serverOnly) continue;
@ -159,7 +158,7 @@ void PackInstallTask::downloadPack()
setProgress(current, total);
});
jobPtr->start(APPLICATION->network());
jobPtr->start();
}
void PackInstallTask::install()

View File

@ -44,14 +44,14 @@ void Technic::SingleZipPackInstallTask::executeTask()
const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
auto entry = APPLICATION->metacache()->resolveEntry("general", path);
entry->setStale(true);
m_filesNetJob.reset(new NetJob(tr("Modpack download")));
m_filesNetJob = new NetJob(tr("Modpack download"), APPLICATION->network());
m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
m_archivePath = entry->getFullPath();
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded);
connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged);
connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed);
m_filesNetJob->start(APPLICATION->network());
m_filesNetJob->start();
}
void Technic::SingleZipPackInstallTask::downloadSucceeded()

View File

@ -42,12 +42,12 @@ bool Technic::SolderPackInstallTask::abort() {
void Technic::SolderPackInstallTask::executeTask()
{
setStatus(tr("Finding recommended version:\n%1").arg(m_sourceUrl.toString()));
m_filesNetJob.reset(new NetJob(tr("Finding recommended version")));
m_filesNetJob = new NetJob(tr("Finding recommended version"), m_network);
m_filesNetJob->addNetAction(Net::Download::makeByteArray(m_sourceUrl, &m_response));
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::versionSucceeded);
connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
m_filesNetJob->start(m_network);
m_filesNetJob->start();
}
void Technic::SolderPackInstallTask::versionSucceeded()
@ -67,12 +67,12 @@ void Technic::SolderPackInstallTask::versionSucceeded()
}
setStatus(tr("Resolving modpack files:\n%1").arg(m_sourceUrl.toString()));
m_filesNetJob.reset(new NetJob(tr("Resolving modpack files")));
m_filesNetJob = new NetJob(tr("Resolving modpack files"), m_network);
m_filesNetJob->addNetAction(Net::Download::makeByteArray(m_sourceUrl, &m_response));
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded);
connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
m_filesNetJob->start(m_network);
m_filesNetJob->start();
}
void Technic::SolderPackInstallTask::fileListSucceeded()
@ -99,7 +99,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded()
m_filesNetJob.reset();
return;
}
m_filesNetJob.reset(new NetJob(tr("Downloading modpack")));
m_filesNetJob = new NetJob(tr("Downloading modpack"), m_network);
int i = 0;
for (auto &modUrl: modUrls)
{
@ -113,7 +113,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded()
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged);
connect(m_filesNetJob.get(), &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
m_filesNetJob->start(m_network);
m_filesNetJob->start();
}
void Technic::SolderPackInstallTask::downloadSucceeded()

View File

@ -29,7 +29,7 @@ class NetJob : public Task
public:
using Ptr = shared_qobject_ptr<NetJob>;
explicit NetJob(QString job_name) : Task()
explicit NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network) : Task(), m_network(network)
{
setObjectName(job_name);
}
@ -65,19 +65,6 @@ private slots:
public slots:
virtual void executeTask() override;
virtual bool abort() override;
virtual void start(shared_qobject_ptr<QNetworkAccessManager> network) {
m_network = network;
start();
}
protected slots:
void start() override {
if(!m_network) {
throw "Missing network while trying to start " + objectName();
return;
}
Task::start();
}
private slots:
void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal);

View File

@ -37,12 +37,12 @@ void NewsChecker::reloadNews()
qDebug() << "Reloading news.";
NetJob* job = new NetJob("News RSS Feed");
NetJob* job = new NetJob("News RSS Feed", m_network);
job->addNetAction(Net::Download::makeByteArray(m_feedUrl, &newsData));
QObject::connect(job, &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished);
QObject::connect(job, &NetJob::failed, this, &NewsChecker::rssDownloadFailed);
m_newsNetJob.reset(job);
job->start(m_network);
job->start();
}
void NewsChecker::rssDownloadFinished()

View File

@ -52,12 +52,12 @@ void NotificationChecker::checkForNotifications()
{
return;
}
m_checkJob.reset(new NetJob("Checking for notifications"));
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(APPLICATION->network());
m_checkJob->start();
}
void NotificationChecker::downloadSucceeded(int)

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -52,7 +52,7 @@ QString MCEditTool::getProgramPath()
#else
const QString mceditPath = path();
QDir mceditDir(mceditPath);
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if (mceditDir.exists("mcedit.sh"))
{
return mceditDir.absoluteFilePath("mcedit.sh");

View File

@ -573,14 +573,14 @@ void TranslationsModel::downloadIndex()
return;
}
qDebug() << "Downloading Translations Index...";
d->m_index_job.reset(new NetJob("Translations Index"));
d->m_index_job = new NetJob("Translations Index", APPLICATION->network());
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("translations", "index_v2.json");
entry->setStale(true);
d->m_index_task = Net::Download::makeCached(QUrl("https://files.multimc.org/translations/index_v2.json"), entry);
d->m_index_job->addNetAction(d->m_index_task);
connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed);
connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexReceived);
d->m_index_job->start(APPLICATION->network());
d->m_index_job->start();
}
void TranslationsModel::updateLanguage(QString key)
@ -625,13 +625,13 @@ void TranslationsModel::downloadTranslation(QString key)
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash));
dl->m_total_progress = lang->file_size;
d->m_dl_job.reset(new NetJob("Translation for " + key));
d->m_dl_job = new NetJob("Translation for " + key, APPLICATION->network());
d->m_dl_job->addNetAction(dl);
connect(d->m_dl_job.get(), &NetJob::succeeded, this, &TranslationsModel::dlGood);
connect(d->m_dl_job.get(), &NetJob::failed, this, &TranslationsModel::dlFailed);
d->m_dl_job->start(APPLICATION->network());
d->m_dl_job->start();
}
void TranslationsModel::downloadNext()

View File

@ -133,10 +133,10 @@ AboutDialog::~AboutDialog()
void AboutDialog::loadPatronList()
{
netJob = new NetJob("Patreon Patron List");
netJob = new NetJob("Patreon Patron List", APPLICATION->network());
netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://files.multimc.org/patrons.txt"), &dataSink));
connect(netJob.get(), &NetJob::succeeded, this, &AboutDialog::patronListLoaded);
netJob->start(APPLICATION->network());
netJob->start();
}
void AboutDialog::patronListLoaded()

View File

@ -34,7 +34,7 @@ UpdateDialog::~UpdateDialog()
void UpdateDialog::loadChangelog()
{
auto channel = APPLICATION->settings()->get("UpdateChannel").toString();
dljob.reset(new NetJob("Changelog"));
dljob = new NetJob("Changelog", APPLICATION->network());
QString url;
if(channel == "stable")
{
@ -49,7 +49,7 @@ void UpdateDialog::loadChangelog()
dljob->addNetAction(Net::Download::makeByteArray(QUrl(url), &changelogData));
connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded);
connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed);
dljob->start(APPLICATION->network());
dljob->start();
}
QString reprocessMarkdown(QByteArray markdown)

View File

@ -73,11 +73,6 @@ LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::Launch
{
ui->updateSettingsBox->setHidden(true);
}
// Analytics
if(BuildConfig.ANALYTICS_ID.isEmpty())
{
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab));
}
connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview()));
connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview()));
@ -321,12 +316,6 @@ void LauncherPage::applySettings()
s->set("InstSortMode", "Name");
break;
}
// Analytics
if(!BuildConfig.ANALYTICS_ID.isEmpty())
{
s->set("Analytics", ui->analyticsCheck->isChecked());
}
}
void LauncherPage::loadSettings()
{
@ -422,12 +411,6 @@ void LauncherPage::loadSettings()
{
ui->sortByNameBtn->setChecked(true);
}
// Analytics
if(!BuildConfig.ANALYTICS_ID.isEmpty())
{
ui->analyticsCheck->setChecked(s->get("Analytics").toBool());
}
}
void LauncherPage::refreshFontPreview()

View File

@ -485,69 +485,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="analyticsTab">
<attribute name="title">
<string>Analytics</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QGroupBox" name="consoleSettingsBox_2">
<property name="title">
<string>Analytics Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="analyticsCheck">
<property name="text">
<string>Send anonymous usage statistics?</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;
&lt;body&gt;
&lt;p&gt;The launcher sends anonymous usage statistics on every start of the application.&lt;/p&gt;&lt;p&gt;The following data is collected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launcher version.&lt;/li&gt;
&lt;li&gt;Operating system name, version and architecture.&lt;/li&gt;
&lt;li&gt;CPU architecture (kernel architecture on linux).&lt;/li&gt;
&lt;li&gt;Size of system memory.&lt;/li&gt;
&lt;li&gt;Java version, architecture and memory settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -304,7 +304,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
return;
QList<ScreenShot::Ptr> uploaded;
auto job = NetJob::Ptr(new NetJob("Screenshot Upload"));
auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network()));
if(selection.size() < 2)
{
auto item = selection.at(0);
@ -314,6 +314,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
m_uploadActive = true;
ProgressDialog dialog(this);
if(dialog.execWithTask(job.get()) != QDialog::Accepted)
{
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
@ -345,7 +346,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
job->addNetAction(ImgurUpload::make(screenshot));
}
SequentialTask task;
auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation"));
auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation", APPLICATION->network()));
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
albumTask->addNetAction(imgurAlbum);
task.addTask(job);
@ -354,8 +355,12 @@ void ScreenshotsPage::on_actionUpload_triggered()
ProgressDialog prog(this);
if (prog.execWithTask(&task) != QDialog::Accepted)
{
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
tr("Unknown error"), QMessageBox::Warning)->exec();
CustomMessageBox::selectable(
this,
tr("Failed to upload screenshots!"),
tr("Unknown error"),
QMessageBox::Warning
)->exec();
}
else
{

View File

@ -86,11 +86,11 @@ void ListModel::request()
modpacks.clear();
endResetModel();
auto *netJob = new NetJob("Atl::Request");
auto *netJob = new NetJob("Atl::Request", APPLICATION->network());
auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/json/packsnew.json");
netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
@ -183,7 +183,7 @@ void ListModel::requestLogo(QString file, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file));
NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@ -201,7 +201,7 @@ void ListModel::requestLogo(QString file, QString url)
emit logoFailed(file);
});
job->start(APPLICATION->network());
job->start();
m_loadingLogos.append(file);
}

View File

@ -100,7 +100,7 @@ void ListModel::requestLogo(QString logo, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)));
NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo));
NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@ -118,7 +118,7 @@ void ListModel::requestLogo(QString logo, QString url)
emit logoFailed(logo);
});
job->start(APPLICATION->network());
job->start();
m_loadingLogos.append(logo);
}
@ -158,7 +158,7 @@ void ListModel::fetchMore(const QModelIndex& parent)
void ListModel::performPaginatedSearch()
{
NetJob *netJob = new NetJob("Flame::Search");
NetJob *netJob = new NetJob("Flame::Search", APPLICATION->network());
auto searchUrl = QString(
"https://addons-ecs.forgesvc.net/api/v2/addon/search?"
"categoryId=0&"
@ -171,7 +171,7 @@ void ListModel::performPaginatedSearch()
).arg(nextSearchOffset).arg(currentSearchTerm).arg(currentSort);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
}

View File

@ -109,7 +109,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second)
if (current.versionsLoaded == false)
{
qDebug() << "Loading flame modpack versions";
NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name));
NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name), APPLICATION->network());
std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
int addonId = current.addonId;
netJob->addNetAction(Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response.get()));
@ -140,7 +140,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second)
suggestCurrent();
});
netJob->start(APPLICATION->network());
netJob->start();
}
else
{

View File

@ -107,11 +107,11 @@ void ListModel::request()
modpacks.clear();
endResetModel();
auto *netJob = new NetJob("Ftb::Request");
auto *netJob = new NetJob("Ftb::Request", APPLICATION->network());
auto url = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all");
netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
@ -150,12 +150,11 @@ void ListModel::requestFailed(QString reason)
void ListModel::requestPack()
{
auto *netJob = new NetJob("Ftb::Search");
auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1")
.arg(currentPack);
auto *netJob = new NetJob("Ftb::Search", APPLICATION->network());
auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1").arg(currentPack);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed);
@ -271,7 +270,7 @@ void ListModel::requestLogo(QString logo, QString url)
bool stale = entry->isStale();
NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo));
NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@ -288,7 +287,7 @@ void ListModel::requestLogo(QString logo, QString url)
auto &newLogoEntry = m_logoMap[logo];
newLogoEntry.downloadJob = job;
newLogoEntry.fullpath = fullPath;
job->start(APPLICATION->network());
job->start();
}
}

View File

@ -216,7 +216,7 @@ void ListModel::requestLogo(QString file)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file));
NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry));
auto fullPath = entry->getFullPath();
@ -234,7 +234,7 @@ void ListModel::requestLogo(QString file)
emit logoFailed(file);
});
job->start(APPLICATION->network());
job->start();
m_loadingLogos.append(file);
}

View File

@ -91,7 +91,7 @@ void Technic::ListModel::searchWithTerm(const QString& term)
void Technic::ListModel::performSearch()
{
NetJob *netJob = new NetJob("Technic::Search");
NetJob *netJob = new NetJob("Technic::Search", APPLICATION->network());
QString searchUrl = "";
if (currentSearchTerm.isEmpty()) {
searchUrl = "https://api.technicpack.net/trending?build=multimc";
@ -104,7 +104,7 @@ void Technic::ListModel::performSearch()
}
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start(APPLICATION->network());
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
}
@ -216,7 +216,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo));
NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo));
NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@ -231,7 +231,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url)
logoFailed(logo);
});
job->start(APPLICATION->network());
job->start();
m_loadingLogos.append(logo);
}

View File

@ -111,7 +111,7 @@ void TechnicPage::suggestCurrent()
return;
}
NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name), APPLICATION->network());
std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
QString slug = current.slug;
netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.technicpack.net/modpack/%1?build=multimc").arg(slug), response.get()));
@ -167,7 +167,7 @@ void TechnicPage::suggestCurrent()
current.metadataLoaded = true;
metadataLoaded();
});
netJob->start(APPLICATION->network());
netJob->start();
}
// expects current.metadataLoaded to be true

View File

@ -1,63 +0,0 @@
#include "AnalyticsWizardPage.h"
#include <Application.h>
#include <QVBoxLayout>
#include <QTextBrowser>
#include <QCheckBox>
#include <ganalytics.h>
#include <BuildConfig.h>
AnalyticsWizardPage::AnalyticsWizardPage(QWidget *parent)
: BaseWizardPage(parent)
{
setObjectName(QStringLiteral("analyticsPage"));
verticalLayout_3 = new QVBoxLayout(this);
verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
textBrowser = new QTextBrowser(this);
textBrowser->setObjectName(QStringLiteral("textBrowser"));
textBrowser->setAcceptRichText(false);
textBrowser->setOpenExternalLinks(true);
verticalLayout_3->addWidget(textBrowser);
checkBox = new QCheckBox(this);
checkBox->setObjectName(QStringLiteral("checkBox"));
checkBox->setChecked(true);
verticalLayout_3->addWidget(checkBox);
retranslate();
}
AnalyticsWizardPage::~AnalyticsWizardPage()
{
}
bool AnalyticsWizardPage::validatePage()
{
auto settings = APPLICATION->settings();
auto analytics = APPLICATION->analytics();
auto status = checkBox->isChecked();
settings->set("AnalyticsSeen", analytics->version());
settings->set("Analytics", status);
return true;
}
void AnalyticsWizardPage::retranslate()
{
setTitle(tr("Analytics"));
setSubTitle(tr("We track some anonymous statistics about users."));
textBrowser->setHtml(tr(
"<html><body>"
"<p>The launcher sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
"<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the "
"matter</a>.</p>"
"<p>The following data is collected:</p>"
"<ul><li>A random unique ID of the installation.<br />It is stored in the application settings file.</li>"
"<li>Anonymized (partial) IP address.</li>"
"<li>Launcher version.</li>"
"<li>Operating system name, version and architecture.</li>"
"<li>CPU architecture (kernel architecture on linux).</li>"
"<li>Size of system memory.</li>"
"<li>Java version, architecture and memory settings.</li></ul>"
"<p>If we change the tracked information, you will see this page again.</p></body></html>"));
checkBox->setText(tr("Enable Analytics"));
}

View File

@ -1,25 +0,0 @@
#pragma once
#include "BaseWizardPage.h"
class QVBoxLayout;
class QTextBrowser;
class QCheckBox;
class AnalyticsWizardPage : public BaseWizardPage
{
Q_OBJECT
public:
explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR);
virtual ~AnalyticsWizardPage();
bool validatePage() override;
protected:
void retranslate() override;
private:
QVBoxLayout *verticalLayout_3 = nullptr;
QTextBrowser *textBrowser = nullptr;
QCheckBox *checkBox = nullptr;
};

View File

@ -2,12 +2,10 @@
#include "LanguageWizardPage.h"
#include "JavaWizardPage.h"
#include "AnalyticsWizardPage.h"
#include "translations/TranslationsModel.h"
#include <Application.h>
#include <FileSystem.h>
#include <ganalytics.h>
#include <QAbstractButton>
#include <BuildConfig.h>

View File

@ -319,7 +319,7 @@ void JavaSettingsWidget::on_javaStatusBtn_clicked()
}
CustomMessageBox::selectable(
this,
failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"),
failed ? QObject::tr("Java test failure") : QObject::tr("Java test success"),
text,
failed ? QMessageBox::Critical : QMessageBox::Information
)->show();

View File

@ -47,7 +47,7 @@ void DownloadTask::loadVersionInfo()
{
setStatus(tr("Loading version information..."));
NetJob *netJob = new NetJob("Version Info");
NetJob *netJob = new NetJob("Version Info", m_network);
// Find the index URL.
QUrl newIndexUrl = QUrl(m_status.newRepoUrl).resolved(QString::number(m_status.newVersionId) + ".json");
@ -67,7 +67,7 @@ void DownloadTask::loadVersionInfo()
connect(netJob, &NetJob::succeeded, this, &DownloadTask::processDownloadedVersionInfo);
connect(netJob, &NetJob::failed, this, &DownloadTask::vinfoDownloadFailed);
m_vinfoNetJob.reset(netJob);
netJob->start(m_network);
netJob->start();
}
void DownloadTask::vinfoDownloadFailed()
@ -121,7 +121,7 @@ void DownloadTask::processDownloadedVersionInfo()
setStatus(tr("Processing file lists - figuring out how to install the update..."));
// make a new netjob for the actual update files
NetJob::Ptr netJob (new NetJob("Update Files"));
NetJob::Ptr netJob = new NetJob("Update Files", m_network);
// fill netJob and operationList
if (!processFileLists(m_currentVersionFileList, m_newVersionFileList, m_status.rootPath, m_updateFilesDir.path(), netJob, m_operations))
@ -145,7 +145,7 @@ void DownloadTask::processDownloadedVersionInfo()
}
qDebug() << "Begin downloading update files to" << m_updateFilesDir.path();
m_filesNetJob = netJob;
m_filesNetJob->start(m_network);
m_filesNetJob->start();
}
void DownloadTask::fileDownloadFinished()

View File

@ -179,7 +179,8 @@ slots:
OperationList operations;
processFileLists(currentVersion, newVersion, QDir::currentPath(), tempFolder, new NetJob("Dummy"), operations);
shared_qobject_ptr<QNetworkAccessManager> network = new QNetworkAccessManager();
processFileLists(currentVersion, newVersion, QDir::currentPath(), tempFolder, new NetJob("Dummy", network), operations);
qDebug() << (operations == expectedOperations);
qDebug() << operations;
qDebug() << expectedOperations;

View File

@ -104,11 +104,11 @@ void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
indexJob = new NetJob("GoUpdate Repository Index");
indexJob = new NetJob("GoUpdate Repository Index", m_network);
indexJob->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData));
connect(indexJob.get(), &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); });
connect(indexJob.get(), &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
indexJob->start(m_network);
indexJob->start();
}
void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
@ -191,11 +191,11 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
}
m_chanListLoading = true;
chanListJob = new NetJob("Update System Channel List");
chanListJob = new NetJob("Update System Channel List", m_network);
chanListJob->addNetAction(Net::Download::makeByteArray(QUrl(m_channelUrl), &chanlistData));
connect(chanListJob.get(), &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
connect(chanListJob.get(), &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
chanListJob->start(m_network);
chanListJob->start();
}
void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)

View File

@ -9,13 +9,6 @@ This library has served as a base for some (much more full-featured and advanced
Copyright belongs to Petr Mrázek, unless explicitly stated otherwise in the source files. Available under the Apache 2.0 license.
## ganalytics
A Google Analytics library for Qt.
BSD licensed, derived from [qt-google-analytics](https://github.com/HSAnet/qt-google-analytics).
Modifications include better handling of IP anonymization (can be enabled) and general improvements of the API (application handles persistence and ID generation instead of the library).
## hoedown
Hoedown is a revived fork of Sundown, the Markdown parser based on the original code of the Upskirt library by Natacha Porté.

View File

@ -1,17 +0,0 @@
project(ganalytics)
find_package(Qt5Core)
find_package(Qt5Gui)
find_package(Qt5Network)
set(ganalytics_SOURCES
src/ganalytics.cpp
src/ganalytics_worker.cpp
src/ganalytics_worker.h
include/ganalytics.h
)
add_library(ganalytics STATIC ${ganalytics_SOURCES})
target_link_libraries(ganalytics Qt5::Core Qt5::Gui Qt5::Network)
target_include_directories(ganalytics PUBLIC include)
target_link_libraries(ganalytics systeminfo)

View File

@ -1,24 +0,0 @@
Copyright (c) 2014-2015, University of Applied Sciences Augsburg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Applied Sciences Augsburg nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
OODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
UT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,34 +0,0 @@
qt-google-analytics
================
Qt5 classes for providing google analytics usage in a Qt/QML application.
## Building
Include ```qt-google-analytics.pri``` in your .pro file.
## Using
Please make sure you have set your application information using ```QApplication::setApplicationName``` and ```QApplication::setApplicationVersion```.
### In C++:
```
GAnalytics tracker("UA-my-id");
tracker.sendScreenView("Main Screen");
```
### In QtQuick:
Register the class on the C++ side using ```qmlRegisterType<GAnalytics>("analytics", 0, 1, "Tracker");```
```
Tracker {
id: tracker
trackingID: "UA-my-id"
}
[...]
tracker.sendScreenView("Main Screen")
```
There is also an example application in the examples folder.
## License
Copyright (c) 2014-2016, University of Applied Sciences Augsburg.
All rights reserved. Distributed under the terms and conditions of the BSD License. See separate LICENSE.txt.

View File

@ -1,67 +0,0 @@
#pragma once
#include <QObject>
#include <QVariantMap>
class QNetworkAccessManager;
class GAnalyticsWorker;
class GAnalytics : public QObject
{
Q_OBJECT
Q_ENUMS(LogLevel)
public:
explicit GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent = 0);
~GAnalytics();
public:
enum LogLevel
{
Debug,
Info,
Error
};
int version();
void setLogLevel(LogLevel logLevel);
LogLevel logLevel() const;
// Getter and Setters
void setViewportSize(const QString &viewportSize);
QString viewportSize() const;
void setLanguage(const QString &language);
QString language() const;
void setAnonymizeIPs(bool anonymize);
bool anonymizeIPs();
void setSendInterval(int milliseconds);
int sendInterval() const;
void enable(bool state = true);
bool isEnabled();
/// Get or set the network access manager. If none is set, the class creates its own on the first request
void setNetworkAccessManager(QNetworkAccessManager *networkAccessManager);
QNetworkAccessManager *networkAccessManager() const;
public slots:
void sendScreenView(const QString &screenName, const QVariantMap &customValues = QVariantMap());
void sendEvent(const QString &category, const QString &action, const QString &label = QString(), const QVariant &value = QVariant(),
const QVariantMap &customValues = QVariantMap());
void sendException(const QString &exceptionDescription, bool exceptionFatal = true, const QVariantMap &customValues = QVariantMap());
void startSession();
void endSession();
private:
GAnalyticsWorker *d;
friend QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics);
friend QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics);
};
QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics);
QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics);

View File

@ -1,237 +0,0 @@
#include "ganalytics.h"
#include "ganalytics_worker.h"
#include "sys.h"
#include <QDataStream>
#include <QDebug>
#include <QLocale>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QQueue>
#include <QSettings>
#include <QTimer>
#include <QUrlQuery>
#include <QUuid>
GAnalytics::GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent) : QObject(parent)
{
d = new GAnalyticsWorker(this);
d->m_trackingID = trackingID;
d->m_clientID = clientID;
d->m_version = version;
}
/**
* Destructor of class GAnalytics.
*/
GAnalytics::~GAnalytics()
{
delete d;
}
void GAnalytics::setLogLevel(GAnalytics::LogLevel logLevel)
{
d->m_logLevel = logLevel;
}
GAnalytics::LogLevel GAnalytics::logLevel() const
{
return d->m_logLevel;
}
// SETTER and GETTER
void GAnalytics::setViewportSize(const QString &viewportSize)
{
d->m_viewportSize = viewportSize;
}
QString GAnalytics::viewportSize() const
{
return d->m_viewportSize;
}
void GAnalytics::setLanguage(const QString &language)
{
d->m_language = language;
}
QString GAnalytics::language() const
{
return d->m_language;
}
void GAnalytics::setAnonymizeIPs(bool anonymize)
{
d->m_anonymizeIPs = anonymize;
}
bool GAnalytics::anonymizeIPs()
{
return d->m_anonymizeIPs;
}
void GAnalytics::setSendInterval(int milliseconds)
{
d->m_timer.setInterval(milliseconds);
}
int GAnalytics::sendInterval() const
{
return (d->m_timer.interval());
}
bool GAnalytics::isEnabled()
{
return d->m_isEnabled;
}
void GAnalytics::enable(bool state)
{
d->enable(state);
}
int GAnalytics::version()
{
return d->m_version;
}
void GAnalytics::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager)
{
if (d->networkManager != networkAccessManager)
{
// Delete the old network manager if it was our child
if (d->networkManager && d->networkManager->parent() == this)
{
d->networkManager->deleteLater();
}
d->networkManager = networkAccessManager;
}
}
QNetworkAccessManager *GAnalytics::networkAccessManager() const
{
return d->networkManager;
}
static void appendCustomValues(QUrlQuery &query, const QVariantMap &customValues)
{
for (QVariantMap::const_iterator iter = customValues.begin(); iter != customValues.end(); ++iter)
{
query.addQueryItem(iter.key(), iter.value().toString());
}
}
/**
* Sent screen view is called when the user changed the applications view.
* These action of the user should be noticed and reported. Therefore
* a QUrlQuery is build in this method. It holts all the parameter for
* a http POST. The UrlQuery will be stored in a message Queue.
*/
void GAnalytics::sendScreenView(const QString &screenName, const QVariantMap &customValues)
{
d->logMessage(Info, QString("ScreenView: %1").arg(screenName));
QUrlQuery query = d->buildStandardPostQuery("screenview");
query.addQueryItem("cd", screenName);
query.addQueryItem("an", d->m_appName);
query.addQueryItem("av", d->m_appVersion);
appendCustomValues(query, customValues);
d->enqueQueryWithCurrentTime(query);
}
/**
* This method is called whenever a button was pressed in the application.
* A query for a POST message will be created to report this event. The
* created query will be stored in a message queue.
*/
void GAnalytics::sendEvent(const QString &category, const QString &action, const QString &label, const QVariant &value, const QVariantMap &customValues)
{
QUrlQuery query = d->buildStandardPostQuery("event");
query.addQueryItem("an", d->m_appName);
query.addQueryItem("av", d->m_appVersion);
query.addQueryItem("ec", category);
query.addQueryItem("ea", action);
if (!label.isEmpty())
query.addQueryItem("el", label);
if (value.isValid())
query.addQueryItem("ev", value.toString());
appendCustomValues(query, customValues);
d->enqueQueryWithCurrentTime(query);
}
/**
* Method is called after an exception was raised. It builds a
* query for a POST message. These query will be stored in a
* message queue.
*/
void GAnalytics::sendException(const QString &exceptionDescription, bool exceptionFatal, const QVariantMap &customValues)
{
QUrlQuery query = d->buildStandardPostQuery("exception");
query.addQueryItem("an", d->m_appName);
query.addQueryItem("av", d->m_appVersion);
query.addQueryItem("exd", exceptionDescription);
if (exceptionFatal)
{
query.addQueryItem("exf", "1");
}
else
{
query.addQueryItem("exf", "0");
}
appendCustomValues(query, customValues);
d->enqueQueryWithCurrentTime(query);
}
/**
* Session starts. This event will be sent by a POST message.
* Query is setup in this method and stored in the message
* queue.
*/
void GAnalytics::startSession()
{
QVariantMap customValues;
customValues.insert("sc", "start");
sendEvent("Session", "Start", QString(), QVariant(), customValues);
}
/**
* Session ends. This event will be sent by a POST message.
* Query is setup in this method and stored in the message
* queue.
*/
void GAnalytics::endSession()
{
QVariantMap customValues;
customValues.insert("sc", "end");
sendEvent("Session", "End", QString(), QVariant(), customValues);
}
/**
* Qut stream to persist class GAnalytics.
*/
QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics)
{
outStream << analytics.d->persistMessageQueue();
return outStream;
}
/**
* In stream to read GAnalytics from file.
*/
QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics)
{
QList<QString> dataList;
inStream >> dataList;
analytics.d->readMessagesFromFile(dataList);
return inStream;
}

View File

@ -1,254 +0,0 @@
#include "ganalytics.h"
#include "ganalytics_worker.h"
#include "sys.h"
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QGuiApplication>
#include <QScreen>
const QLatin1String GAnalyticsWorker::dateTimeFormat("yyyy,MM,dd-hh:mm::ss:zzz");
GAnalyticsWorker::GAnalyticsWorker(GAnalytics *parent)
: QObject(parent), q(parent), m_logLevel(GAnalytics::Error)
{
m_appName = QCoreApplication::instance()->applicationName();
m_appVersion = QCoreApplication::instance()->applicationVersion();
m_request.setUrl(QUrl("https://www.google-analytics.com/collect"));
m_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
m_request.setHeader(QNetworkRequest::UserAgentHeader, getUserAgent());
m_language = QLocale::system().name().toLower().replace("_", "-");
m_screenResolution = getScreenResolution();
m_timer.setInterval(m_timerInterval);
connect(&m_timer, &QTimer::timeout, this, &GAnalyticsWorker::postMessage);
}
void GAnalyticsWorker::enable(bool state)
{
// state change to the same is not valid.
if(m_isEnabled == state)
{
return;
}
m_isEnabled = state;
if(m_isEnabled)
{
// enable -> start doing things :)
m_timer.start();
}
else
{
// disable -> stop the timer
m_timer.stop();
}
}
void GAnalyticsWorker::logMessage(GAnalytics::LogLevel level, const QString &message)
{
if (m_logLevel > level)
{
return;
}
qDebug() << "[Analytics]" << message;
}
/**
* Build the POST query. Adds all parameter to the query
* which are used in every POST.
* @param type Type of POST message. The event which is to post.
* @return query Most used parameter in a query for a POST.
*/
QUrlQuery GAnalyticsWorker::buildStandardPostQuery(const QString &type)
{
QUrlQuery query;
query.addQueryItem("v", "1");
query.addQueryItem("tid", m_trackingID);
query.addQueryItem("cid", m_clientID);
if (!m_userID.isEmpty())
{
query.addQueryItem("uid", m_userID);
}
query.addQueryItem("t", type);
query.addQueryItem("ul", m_language);
query.addQueryItem("vp", m_viewportSize);
query.addQueryItem("sr", m_screenResolution);
if(m_anonymizeIPs)
{
query.addQueryItem("aip", "1");
}
return query;
}
/**
* Get primary screen resolution.
* @return A QString like "800x600".
*/
QString GAnalyticsWorker::getScreenResolution()
{
QScreen *screen = QGuiApplication::primaryScreen();
QSize size = screen->size();
return QString("%1x%2").arg(size.width()).arg(size.height());
}
/**
* Try to gain information about the system where this application
* is running. It needs to get the name and version of the operating
* system, the language and screen resolution.
* All this information will be send in POST messages.
* @return agent A QString with all the information formatted for a POST message.
*/
QString GAnalyticsWorker::getUserAgent()
{
return QString("%1/%2").arg(m_appName).arg(m_appVersion);
}
/**
* The message queue contains a list of QueryBuffer object.
* QueryBuffer holds a QUrlQuery object and a QDateTime object.
* These both object are freed from the buffer object and
* inserted as QString objects in a QList.
* @return dataList The list with concartinated queue data.
*/
QList<QString> GAnalyticsWorker::persistMessageQueue()
{
QList<QString> dataList;
foreach (QueryBuffer buffer, m_messageQueue)
{
dataList << buffer.postQuery.toString();
dataList << buffer.time.toString(dateTimeFormat);
}
return dataList;
}
/**
* Reads persistent messages from a file.
* Gets all message data as a QList<QString>.
* Two lines in the list build a QueryBuffer object.
*/
void GAnalyticsWorker::readMessagesFromFile(const QList<QString> &dataList)
{
QListIterator<QString> iter(dataList);
while (iter.hasNext())
{
QString queryString = iter.next();
QString dateString = iter.next();
QUrlQuery query;
query.setQuery(queryString);
QDateTime dateTime = QDateTime::fromString(dateString, dateTimeFormat);
QueryBuffer buffer;
buffer.postQuery = query;
buffer.time = dateTime;
m_messageQueue.enqueue(buffer);
}
}
/**
* Takes a QUrlQuery object and wrapp it together with
* a QTime object into a QueryBuffer struct. These struct
* will be stored in the message queue.
*/
void GAnalyticsWorker::enqueQueryWithCurrentTime(const QUrlQuery &query)
{
QueryBuffer buffer;
buffer.postQuery = query;
buffer.time = QDateTime::currentDateTime();
m_messageQueue.enqueue(buffer);
}
/**
* This function is called by a timer interval.
* The function tries to send a messages from the queue.
* If message was successfully send then this function
* will be called back to send next message.
* If message queue contains more than one message then
* the connection will kept open.
* The message POST is asyncroniously when the server
* answered a signal will be emitted.
*/
void GAnalyticsWorker::postMessage()
{
if (m_messageQueue.isEmpty())
{
// queue empty -> try sending later
m_timer.start();
return;
}
else
{
// queue has messages -> stop timer and start sending
m_timer.stop();
}
QString connection = "close";
if (m_messageQueue.count() > 1)
{
connection = "keep-alive";
}
QueryBuffer buffer = m_messageQueue.head();
QDateTime sendTime = QDateTime::currentDateTime();
qint64 timeDiff = buffer.time.msecsTo(sendTime);
if (timeDiff > fourHours)
{
// too old.
m_messageQueue.dequeue();
emit postMessage();
return;
}
buffer.postQuery.addQueryItem("qt", QString::number(timeDiff));
m_request.setRawHeader("Connection", connection.toUtf8());
m_request.setHeader(QNetworkRequest::ContentLengthHeader, buffer.postQuery.toString().length());
logMessage(GAnalytics::Debug, "Query string = " + buffer.postQuery.toString());
// Create a new network access manager if we don't have one yet
if (networkManager == NULL)
{
networkManager = new QNetworkAccessManager(this);
}
QNetworkReply *reply = networkManager->post(m_request, buffer.postQuery.query(QUrl::EncodeUnicode).toUtf8());
connect(reply, SIGNAL(finished()), this, SLOT(postMessageFinished()));
}
/**
* NetworkAccsessManager has finished to POST a message.
* If POST message was successfully send then the message
* query should be removed from queue.
* SIGNAL "postMessage" will be emitted to send next message
* if there is any.
* If message couldn't be send then next try is when the
* timer emits its signal.
*/
void GAnalyticsWorker::postMessageFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
int httpStausCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpStausCode < 200 || httpStausCode > 299)
{
logMessage(GAnalytics::Error, QString("Error posting message: %1").arg(reply->errorString()));
// An error ocurred. Try sending later.
m_timer.start();
return;
}
else
{
logMessage(GAnalytics::Debug, "Message sent");
}
m_messageQueue.dequeue();
postMessage();
reply->deleteLater();
}

View File

@ -1,65 +0,0 @@
#pragma once
#include <QUrlQuery>
#include <QDateTime>
#include <QTimer>
#include <QNetworkRequest>
#include <QQueue>
struct QueryBuffer
{
QUrlQuery postQuery;
QDateTime time;
};
class GAnalyticsWorker : public QObject
{
Q_OBJECT
public:
explicit GAnalyticsWorker(GAnalytics *parent = 0);
GAnalytics *q;
QNetworkAccessManager *networkManager = nullptr;
QQueue<QueryBuffer> m_messageQueue;
QTimer m_timer;
QNetworkRequest m_request;
GAnalytics::LogLevel m_logLevel;
QString m_trackingID;
QString m_clientID;
QString m_userID;
QString m_appName;
QString m_appVersion;
QString m_language;
QString m_screenResolution;
QString m_viewportSize;
bool m_anonymizeIPs = false;
bool m_isEnabled = false;
int m_timerInterval = 30000;
int m_version = 0;
const static int fourHours = 4 * 60 * 60 * 1000;
const static QLatin1String dateTimeFormat;
public:
void logMessage(GAnalytics::LogLevel level, const QString &message);
QUrlQuery buildStandardPostQuery(const QString &type);
QString getScreenResolution();
QString getUserAgent();
QList<QString> persistMessageQueue();
void readMessagesFromFile(const QList<QString> &dataList);
void enqueQueryWithCurrentTime(const QUrlQuery &query);
void setIsSending(bool doSend);
void enable(bool state);
public slots:
void postMessage();
void postMessageFinished();
};

View File

@ -320,7 +320,7 @@ Description: Make it so that the QIcon loader honors /usr/share/pixmaps
icon theme specification.
Bug: https://bugreports.qt.nokia.com/browse/QTBUG-12874
*********************************************************************/
#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
/* Freedesktop standard says to look in /usr/share/pixmaps last */
if (entries.isEmpty())
{

View File

@ -47,6 +47,7 @@ Sys::KernelInfo Sys::getKernelInfo()
uint64_t Sys::getSystemRam()
{
std::string token;
#ifdef Q_OS_LINUX
std::ifstream file("/proc/meminfo");
while(file >> token)
{
@ -65,6 +66,19 @@ uint64_t Sys::getSystemRam()
// ignore rest of the line
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
#elif defined(Q_OS_FREEBSD)
char buff[512];
FILE *fp = popen("sysctl hw.physmem", "r");
if (fp != NULL)
{
while(fgets(buff, 512, fp) != NULL)
{
std::string str(buff);
uint64_t mem = std::stoull(str.substr(12, std::string::npos));
return mem * 1024ull;
}
}
#endif
return 0; // nothing found
}

View File

@ -1,28 +0,0 @@
# Building the flatpak
### 1. Install tools
Install `flatpak` and `flatpak-builder` from your distribution repositories.
### 2. Install SDK
`flatpak install org.kde.Sdk org.kde.Platform`
Pick version `5.15`
### 3. Get the yml flatpak file
You can download it directly from github, or clone the repo.
### 4. Build it
```
flatpak-builder --ccache --force-clean flatbuild packages/flatpak/org.polymc.PolyMC.yml
```
If you didn't clone the repo, the path might be different.
### 5. Install the custom build
```
flatpak-builder --user --install --ccache --force-clean flatbuild packages/org.polymc.PolyMC.yml
```

View File

@ -1,11 +0,0 @@
[Desktop Entry]
Version=1.0
Name=PolyMC
Comment=A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.
Type=Application
Terminal=false
Exec=polymc
StartupNotify=true
Icon=null
Categories=Game;
Keywords=game;minecraft;launcher;

View File

@ -1,74 +0,0 @@
app-id: org.polymc.PolyMC
runtime: org.kde.Platform
runtime-version: "5.15"
sdk: org.kde.Sdk
command: polymc
finish-args:
- --share=ipc
- --socket=x11
- --socket=wayland
- --device=dri
- --share=network
# for Discord RPC mods
- --filesystem=xdg-run/app/com.discordapp.Discord:create
modules:
- name: compile
buildsystem: simple
build-commands:
- mkdir build
- mkdir -p /app/bin
- cd build && JAVA_HOME=/run/build/compile/jdk PATH=$JAVA_HOME:$PATH JAVA_COMPILER=../jdk/bin/javac cmake -DLauncher_LAYOUT=lin-system -DCMAKE_INSTALL_PREFIX=/app/ .. && make -j$(nproc) install
sources:
- type: git
url: https://github.com/PolyMC/PolyMC.git
tag: 1.0.0
- type: archive
url: https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17%2B35/OpenJDK17-jdk_x64_linux_hotspot_17_35.tar.gz
sha256: 6f1335d9a7855159f982dac557420397be9aa85f3f7bc84e111d25871c02c0c7
archive-type: tar-gzip
dest: jdk
# old MC versions depend on Xrandr
- name: xrandr
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make
- make install
sources:
- type: archive
url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.1.tar.xz
sha256: 7bc76daf9d72f8aff885efad04ce06b90488a1a169d118dea8a2b661832e8762
- name: java
buildsystem: simple
build-commands:
- mkdir -p /app/jdk
- mv ./* /app/jdk
sources:
# JDK 17 for MC 1.18
- type: archive
url: https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.1%2B12/OpenJDK17U-jre_x64_linux_hotspot_17.0.1_12.tar.gz
sha256: 9d58cb741509a88e0ae33eb022334fb900b409b198eca6fe76246f0677b392ad
strip-components: 0
# JDK for Minecraft 1.17 - 1.18
- type: archive
url: https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz
sha256: 323d6d7474a359a28eff7ddd0df8e65bd61554a8ed12ef42fd9365349e573c2c
strip-components: 0
# JDK 11 for 1.9 - 1.15.2
- type: archive
url: https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-jre_x64_linux_hotspot_11.0.13_8.tar.gz
sha256: fb0a27e6e1f26a1ee79daa92e4cfe3ec0d676acfe114d99dd84b3414f056e8a0
strip-components: 0
# JDK 8 for pre1.9
- type: archive
url: https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u312-b07/OpenJDK8U-jre_x64_linux_hotspot_8u312b07.tar.gz
sha256: 18fd13e77621f712326bfcf79c3e3cc08c880e3e4b8f63a1e5da619f3054b063
strip-components: 0
- name: desktopfiles
buildsystem: simple
build-commands:
- install -Dm644 org.polymc.PolyMC.desktop /app/share/applications/org.polymc.PolyMC.desktop
sources:
- type: file
path: org.polymc.PolyMC.desktop

View File

@ -8,6 +8,11 @@ set(Launcher_UserAgent "${Launcher_CommonName}/5.0" PARENT_SCOPE)
set(Launcher_ConfigFile "polymc.cfg" PARENT_SCOPE)
set(Launcher_Git "https://github.com/PolyMC/PolyMC" PARENT_SCOPE)
set(Launcher_Branding_ICNS "program_info/Launcher.icns" PARENT_SCOPE)
set(Launcher_Branding_WindowsRC "program_info/launcher.rc" PARENT_SCOPE)
set(Launcher_Branding_LogoQRC "program_info/logo.qrc" PARENT_SCOPE)
set(Launcher_Desktop "program_info/org.polymc.PolyMC.desktop" PARENT_SCOPE)
set(Launcher_MetaInfo "program_info/org.polymc.PolyMC.metainfo.xml" PARENT_SCOPE)
set(Launcher_SVG "program_info/org.polymc.PolyMC.svg" PARENT_SCOPE)
set(Launcher_Branding_ICNS "program_info/polymc.icns" PARENT_SCOPE)
set(Launcher_Branding_WindowsRC "program_info/polymc.rc" PARENT_SCOPE)
set(Launcher_Branding_LogoQRC "program_info/polymc.qrc" PARENT_SCOPE)
configure_file(org.polymc.PolyMC.desktop.in org.polymc.PolyMC.desktop)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@ -3,3 +3,4 @@
This is PolyMC's program info which contains information about:
- Application name and logo (and branding in general)
- Various URLs and API endpoints
- Desktop file

View File

@ -1,18 +1,19 @@
#/bin/bash
inkscape -w 16 -h 16 -o logo_16.png logo.svg
inkscape -w 24 -h 24 -o logo_24.png logo.svg
inkscape -w 32 -h 32 -o logo_32.png logo.svg
inkscape -w 48 -h 48 -o logo_48.png logo.svg
inkscape -w 64 -h 64 -o logo_64.png logo.svg
inkscape -w 128 -h 128 -o logo_128.png logo.svg
inkscape -w 16 -h 16 -o polymc_16.png org.polymc.PolyMC.svg
inkscape -w 24 -h 24 -o polymc_24.png org.polymc.PolyMC.svg
inkscape -w 32 -h 32 -o polymc_32.png org.polymc.PolyMC.svg
inkscape -w 48 -h 48 -o polymc_48.png org.polymc.PolyMC.svg
inkscape -w 64 -h 64 -o polymc_64.png org.polymc.PolyMC.svg
inkscape -w 128 -h 128 -o polymc_128.png org.polymc.PolyMC.svg
convert logo_128.png logo_64.png logo_48.png logo_32.png logo_24.png logo_16.png Launcher.ico
convert polymc_128.png polymc_64.png polymc_48.png polymc_32.png polymc_24.png polymc_16.png polymc.ico
inkscape -w 256 -h 256 -o logo_256.png logo.svg
inkscape -w 512 -h 512 -o logo_512.png logo.svg
inkscape -w 1024 -h 1024 -o logo_1024.png logo.svg
inkscape -w 256 -h 256 -o polymc_256.png org.polymc.PolyMC.svg
inkscape -w 512 -h 512 -o polymc_512.png org.polymc.PolyMC.svg
inkscape -w 1024 -h 1024 -o polymc_1024.png org.polymc.PolyMC.svg
png2icns Launcher.icns logo_1024.png logo_512.png logo_256.png logo_128.png logo_32.png logo_16.png
png2icns polymc.icns polymc_1024.png polymc_512.png polymc_256.png polymc_128.png polymc_32.png polymc_16.png
rm -f logo_*.png
rm -f polymc_*.png
rm -rf polymc.iconset

View File

@ -1,271 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="68.26667"
height="68.26667"
id="svg4427"
version="1.1"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
sodipodi:docname="logo.svg"
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"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4429">
<linearGradient
id="linearGradient5668"
inkscape:collect="always">
<stop
id="stop5670"
offset="0"
style="stop-color:#75b54b;stop-opacity:1;" />
<stop
id="stop5672"
offset="1"
style="stop-color:#75b54b;stop-opacity:0.6" />
</linearGradient>
<linearGradient
id="linearGradient5084"
inkscape:collect="always">
<stop
id="stop5086"
offset="0"
style="stop-color:#000000;stop-opacity:0.8" />
<stop
id="stop5088"
offset="1"
style="stop-color:#000000;stop-opacity:0.35" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5668"
id="linearGradient5072"
x1="6.7342591"
y1="28.510933"
x2="50.506943"
y2="61.773685"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.01532073,-0.00938002)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5084"
id="linearGradient5082"
x1="14.312115"
y1="9.7948904"
x2="44.097023"
y2="82.973114"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5668"
id="linearGradient3281"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.01532073,-0.00938002)"
x1="6.7342591"
y1="28.510933"
x2="50.506943"
y2="61.773685" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5668"
id="linearGradient3283"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.01532073,-0.00938002)"
x1="6.7342591"
y1="28.510933"
x2="50.506943"
y2="61.773685" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5084"
id="linearGradient3288"
gradientUnits="userSpaceOnUse"
x1="14.312115"
y1="9.7948904"
x2="44.097023"
y2="82.973114" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5084"
id="linearGradient3290"
gradientUnits="userSpaceOnUse"
x1="14.312115"
y1="9.7948904"
x2="44.097023"
y2="82.973114" />
<linearGradient
inkscape:collect="always"
id="linearGradient5580">
<stop
style="stop-color:#000000;stop-opacity:0.0627451"
offset="0"
id="stop5576" />
<stop
style="stop-color:#252424;stop-opacity:0.58823532"
offset="1"
id="stop5578" />
</linearGradient>
<linearGradient
id="linearGradient3999"
inkscape:collect="always">
<stop
id="stop3995"
offset="0"
style="stop-color:#777777;stop-opacity:1" />
<stop
id="stop3997"
offset="1"
style="stop-color:#4f4e4e;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient2727"
inkscape:collect="always">
<stop
id="stop2723"
offset="0"
style="stop-color:#7f8080;stop-opacity:1" />
<stop
id="stop2725"
offset="1"
style="stop-color:#404040;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2727"
id="linearGradient2050"
gradientUnits="userSpaceOnUse"
x1="36.546478"
y1="33.80484"
x2="86.415741"
y2="97.065842"
gradientTransform="translate(-0.0016031,-4.5764148e-4)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3999"
id="radialGradient2052"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.00142193,-4.5702768e-4)"
cx="34.133331"
cy="34.133335"
fx="34.133331"
fy="34.133335"
r="29.866665" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient2140"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.0010513,-9.083059e-4)"
x1="29.866674"
y1="29.867579"
x2="38.400005"
y2="38.400913" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.0000001"
inkscape:cx="-15.9375"
inkscape:cy="15.75"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="3840"
inkscape:window-height="2129"
inkscape:window-x="1200"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-midpoints="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="false"
inkscape:snap-intersection-paths="true"
inkscape:object-paths="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-text-baseline="true"
inkscape:snap-center="true"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid4446"
empspacing="16"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="4.2666667"
spacingy="4.2666667"
originx="0"
originy="0" />
</sodipodi:namedview>
<metadata
id="metadata4432">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g2048"
transform="translate(9.113e-4,0.00104183)">
<rect
rx="8.5333338"
ry="8.5333338"
style="fill:url(#linearGradient2050);fill-opacity:1;stroke:none;stroke-width:17.0667"
id="rect2026"
width="68.266998"
height="68.26667"
x="-0.0016037956"
y="-0.00045376646" />
<rect
rx="4.2666626"
y="4.2662144"
x="4.2652307"
height="59.733334"
width="59.73333"
id="rect2028"
style="opacity:0.5;fill:url(#radialGradient2052);fill-opacity:1;stroke:none;stroke-width:14.9333"
ry="4.2666669" />
<path
style="opacity:1;fill:url(#linearGradient2140);fill-opacity:1;stroke:none;stroke-width:17.06666756"
d="m 8.5322887,-9.083059e-4 c -4.72747,0 -8.5332,3.8057359059 -8.5332,8.5332029059 V 59.731515 c 0,4.727467 3.80573,8.535156 8.5332,8.535156 H 59.731502 c 4.72747,0 8.5332,-3.807689 8.5332,-8.535156 V 8.5322946 c 0,-4.727467 -3.80573,-8.5332029059 -8.5332,-8.5332029059 z m 0,4.2675779059 H 59.731502 c 2.36373,0 4.26758,1.901892 4.26758,4.265625 V 59.731515 c 0,2.363733 -1.90385,4.267578 -4.26758,4.267578 H 8.5322887 c -2.36373,0 -4.26758,-1.903845 -4.26758,-4.267578 V 8.5322946 c 0,-2.363733 1.90385,-4.265625 4.26758,-4.265625 z"
id="path2046"
inkscape:connector-curvature="0" />
</g>
<path
style="fill:#000000;fill-opacity:0.494118;fill-rule:evenodd;stroke:none;stroke-width:0.999996px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 17.343575,15.030602 -1e-6,43.517002 38.229105,-21.758501 z"
id="path1382"
sodipodi:nodetypes="cccc" />
<path
style="fill:#00ff66;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.999996px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.888808,11.986385 -1e-6,43.517003 38.229104,-21.758501 z"
id="path1059"
sodipodi:nodetypes="cccc" />
<path
id="path13539"
style="fill:#ff00ff;fill-opacity:0.992157;fill-rule:evenodd;stroke:none;stroke-width:0.999996px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 19.576616,50.882478 C 29.612077,45.170295 39.647539,39.458112 49.682999,33.745928 39.647539,28.032869 29.612077,22.319811 19.576616,16.606753 c 0,11.425241 0,22.850484 0,34.275725 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -4,8 +4,8 @@ Name=PolyMC
Comment=A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.
Type=Application
Terminal=false
Exec=polymc
Exec=@Launcher_APP_BINARY_NAME@
StartupNotify=true
Icon=null
Icon=org.polymc.PolyMC
Categories=Game;
Keywords=game;minecraft;launcher;

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.polymc.PolyMC</id>
<provides><id>org.polymc.PolyMC</id></provides>
<launchable type="desktop-id">org.polymc.PolyMC.desktop</launchable>
<name>PolyMC</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>
<metadata_license>CC0-1.0</metadata_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>
<description>
<p>
PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.
Features:
- Easily install game modifications, such as Fabric or Forge
- Control your java settings
- Manage worlds and resource packs from the launcher
- See logs and other details easily
- Kill Minecraft in case of a crash/freeze
- Isolate minecraft instances to keep everything clean
This flatpak includes Wayland support without XWayland: to enable, tick Use system installation of GLFW... in the settings of a Minecraft instance.
All java versions that are required by Minecraft are included.
If using a Hybrid-Graphics device, you can use the prime-run script as a wrapper command to run Minecraft using the dedicated graphics card.
</p>
</description>
<screenshots>
<screenshot type="default">
<caption>The main PolyMC window</caption>
<image type="source" width="802" height="639">https://i.imgur.com/q2GcDo4.png</image>
</screenshot>
</screenshots>
<releases>
<release version="1.0.2" date="2022-01-01"/>
</releases>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">moderate</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">none</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
</content_rating>
</component>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 47 KiB

BIN
program_info/polymc.icns Normal file

Binary file not shown.

BIN
program_info/polymc.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity name="MultiMC.Application.5" type="win32" version="5.0.0.0" />
<assemblyIdentity name="PolyMC.Application.5" type="win32" version="5.0.0.0" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>

View File

@ -1,8 +1,6 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<file>logo.svg</file>
<file>org.polymc.PolyMC.svg</file>
</qresource>
</RCC>

View File

@ -3,8 +3,8 @@
#endif
#include <windows.h>
IDI_ICON1 ICON DISCARDABLE "Launcher.ico"
1 RT_MANIFEST "Launcher.manifest"
IDI_ICON1 ICON DISCARDABLE "polymc.ico"
1 RT_MANIFEST "polymc.manifest"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
@ -15,10 +15,10 @@ BEGIN
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "MultiMC Contributors"
VALUE "CompanyName", "MultiMC & PolyMC Contributors"
VALUE "FileDescription", "A Minecraft Launcher"
VALUE "FileVersion", "1.0.0.0"
VALUE "ProductName", "Launcher"
VALUE "ProductName", "PolyMC"
VALUE "ProductVersion", "5"
END
END