Compare commits

..

297 Commits
1.1.0 ... 1.2.0

Author SHA1 Message Date
56ce7f5dcd Merge pull request #437 from DioEgizio/bump-1.2.0 2022-04-17 23:51:25 +02:00
0ccbc801cf Merge pull request #411 from kthchew/feature/menubar 2022-04-17 23:19:51 +02:00
4c52cc414f Improve menu bar setting string 2022-04-17 16:39:08 -04:00
6b45386252 Disable instead of hide menu bar option on Linux
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
2022-04-17 20:32:51 +00:00
3acc761419 Fix bugs with instance menu bar options when opening without instances
- The launch option is no longer empty.
- The program now checks on startup whether an instance is selected to decide whether to disable instance options.

Also, get rid of a dynamic cast.
2022-04-17 12:44:24 -04:00
dd4c67b654 Merge pull request #439 from DioEgizio/CI/new-qt-macos
CHANGE: use Qt 5.15.3 (from brew) on macos
2022-04-17 16:59:05 +05:30
0c581cfb62 CHANGE: use Qt 5.15.3 (from brew) on macos
More updated Qt means less bugs and generally less issues.
The only drawback is losing MacOS Sierra support
2022-04-17 09:53:30 +02:00
703bf9bb7a Merge pull request #431 from Scrumplex/feat-quilt-modrinth
Query for Fabric mods if Quilt is in use
2022-04-17 13:46:22 +10:00
a40dee2230 Merge pull request #436 from flowln/bundled_libs
Don't force bundled libraries by default
2022-04-17 13:45:20 +10:00
cab9afa45f fix: query for Fabric mods if Quilt is in use
Right now we want to include Fabric mods in our searches where possible.
Modrinth allows definining multiple loaders, while Flame only allows a
single value.

As a compromise we ask for Fabric mods only on Flame and for both Fabric
and Quilt mods on Modrinth.
2022-04-16 23:40:10 +02:00
ba5946dc60 Merge pull request #336 from Scrumplex/refactor-portable 2022-04-16 21:25:05 +02:00
9bad83a551 Use TranslatedAction instead of QAction for menu bar actions 2022-04-16 13:35:13 -04:00
a549828655 Remove the Edit menu bar menu
It wouldn't bring much utility.

- The keyboard shortcuts for copy/paste/etc. already work and are well-known. The menu bar likely doesn't need to advertise them.
- There's not very many places you would be able to use these options in the main window (because there's not many places to type stuff in the main window). It would only be applicable on systems with a native menu bar that shows in all other windows as well (but again, the keyboard shortcuts still work).

Also, rename `actionWiki` -> `actionOpenWiki` to match the corresponding `on_actionOpenWiki_triggered`
2022-04-16 13:17:34 -04:00
c1398a6a1a bump to 1.2.0 2022-04-16 18:30:15 +02:00
e11d1b5202 Merge pull request #429 from Irgendwer01/develop
better FreeBSD support
2022-04-16 18:21:54 +02:00
abdb846c3f fix: set install prefix for Linux to /usr 2022-04-16 18:13:12 +02:00
b0b6dd8f87 fix(actions): remove macdeployqt 2022-04-16 18:13:12 +02:00
4a971226e4 refactor(actions): combine steps for unified builds 2022-04-16 18:13:12 +02:00
b10d4d3b8f fix: drop BUNDLE_DEST_DIR 2022-04-16 18:13:12 +02:00
6ed130fc16 fix: don't allow portable builds on macOS 2022-04-16 18:13:12 +02:00
90d4acd1a1 refactor: combine portable and system builds
Portable builds now have the same layout as system builds. If you want
to build a portable bundle, you now need to additionally install the
`portable` component.

For example:

    $ cmake -Bbuild -DCMAKE_INSTALL_PREFIX=install ...
    $ cmake --build build
    $ cmake --install build
    $ cmake --install build --component portable
2022-04-16 18:13:09 +02:00
a42d2afcee Merge pull request #392 from flowln/mod_filter 2022-04-16 18:03:03 +02:00
ba020fbd21 fix: Don't error when not finding valid system quazip 2022-04-16 11:27:00 -03:00
af167e8e67 libs: update bundled submodules 2022-04-16 10:23:15 -03:00
be82f4db9e libs: Don't force bundled libs
Now that QuaZip 1.3 is released, packages from package managers can
include the patch needed for PolyMC, so we can use the users system
libraries if available.
2022-04-16 10:10:13 -03:00
6a97ac603a Use preexisting actions in the menu bar
The code is now much cleaner.

Because the actions already present are enabled elsewhere even when the menu bar is hidden, keyboard shortcuts added to them automatically work regardless of whether the menu bar is visible. This means that the hacky workaround related to this can be removed.
2022-04-16 03:32:08 -04:00
e59d3a339f Close the current window instead of the main window from the menu bar
Systems with native menu bars show the same menu bar for all child windows. As a result, you cannot assume that the menu bar's parent (the `MainWindow`) will be the window in focus.
2022-04-16 02:07:29 -04:00
db7cb12551 Merge pull request #430 from DioEgizio/make-helppages-on-their-own-dir
CHANGE: switch the help pages to their own dir
2022-04-16 10:18:04 +10:00
1049507b3f Add logged in accounts to the profiles menu bar menu
Additionally, add keyboard shortcuts for switching between different accounts.
2022-04-15 19:55:49 -04:00
1303771b58 Add option to always show menu bar instead of toolbar
For those who like keyboard navigation at the expense of aesthetics.
2022-04-15 18:26:41 -04:00
f6605bc3f8 Implement help (open wiki) menu bar action 2022-04-15 16:44:27 -04:00
80ec178d5f Fix keyboard shortcut for delete instance on some devices
My laptop has a key labeled "delete," but for some reason it doesn't work with `QKeySequence::Delete`. Instead it's interpreted as a backspace.
2022-04-15 16:38:26 -04:00
ef76bd355a Merge pull request #398 from kthchew/feature/ml-instance-creation 2022-04-15 22:36:02 +02:00
b0a8bd7dfe Improve menu bar keyboard usability
More reasonable (unique) menu access keys were chosen.

In addition, move the settings action from the Help menu to the Edit menu.
2022-04-15 16:29:29 -04:00
5d8d7740ba Only enable instance options while an instance is selected 2022-04-15 15:55:03 -04:00
3e64935844 Add Quilt install option while creating an instance 2022-04-15 15:37:08 -04:00
7577115c3c Fix Fabric versions appearing for unsupported MC versions
Also remove an old TODO comment, mentioning an issue that was already fixed.
2022-04-15 15:37:08 -04:00
2cb242e9b3 Show no loader selected message when add instance window first opens
This resolves an issue where the message only shows when selecting a mod loader and then selecting "None" again.
2022-04-15 15:37:07 -04:00
7aeccbb6b0 Fix build on Qt 5.6 2022-04-15 15:37:07 -04:00
8406c7f431 Add option to install mod loader during instance creation 2022-04-15 15:37:07 -04:00
8c98cc9458 Merge pull request #333 from oynqr/build/lto 2022-04-15 16:02:06 +02:00
715d7d4424 Merge pull request #417 from Scrumplex/feat-install-manpage
Install manpage on Linux system builds
2022-04-15 21:53:50 +10:00
8e9eca6a97 ui: resize mod download dialog using its parents geometry 2022-04-15 08:49:43 -03:00
5f15f51610 ui: underline search button text when changing filters
This hopefully makes it easier to the user to know that their changes
will only apply after hitting the search button.

I tried setting the background color, but it seems more unreliable on
cross-platform than underlining. Also, it could be worse for daltonic people,
so I don't know what to do :(
2022-04-15 08:49:43 -03:00
277de41200 rework: make the filter as a tabbed widget in the dialog itself
Still needs a clear indication that the filter only applies after you
click the search button...
2022-04-15 08:49:43 -03:00
63bce04648 fix: Polish usage in some cases
Also fiz some typos
2022-04-15 08:49:43 -03:00
76dfb7825a fix: 'All' filter working and get around CF API capabilities 2022-04-15 08:49:43 -03:00
5cb0e75093 fix(ui): Refresh mod list when changing filtering options 2022-04-15 08:49:41 -03:00
c730fd6e5f feat: Use version filter when searching mods 2022-04-15 08:45:30 -03:00
c2b97c3e3f feat: Integrate newly created filter dialog in ModPage 2022-04-15 08:42:30 -03:00
e0ab8207ed feat: Add dialog to filter mod options in mod download 2022-04-15 08:41:12 -03:00
ecad388846 Merge branch 'PolyMC:develop' into develop 2022-04-15 13:04:25 +02:00
9a120f43c8 Update MinecraftInstance.cpp 2022-04-15 13:03:48 +02:00
4ff1306e0c Merge pull request #185 from Scrumplex/quilt
Quilt support
2022-04-15 11:38:50 +02:00
1dd663af6e CHANGE: switch the help pages to their own dir
also renames modrinth-platform/curseforge-platform to just Mod-platform since they have the pages are basically the same
2022-04-15 11:15:17 +02:00
06d9821b2c Update MinecraftInstance.cpp 2022-04-15 01:51:28 +02:00
abb20c65e3 better FreeBSD support 2022-04-15 01:40:25 +02:00
9fb5674233 refactor: cleanup ModLoaderType 2022-04-14 21:55:03 +02:00
18ac109e5a fix: support Quilt from Minecraft 1.14 onwards 2022-04-14 17:20:07 +02:00
14a0e85862 fix: remove unused code 2022-04-14 16:50:04 +02:00
fa2b3bcc63 feat: install manpage 2022-04-10 23:01:00 +02:00
620555d210 Merge pull request #413 from Regular-Baf/develop
Successfully switch to new discord logo. Hopefully.
2022-04-10 12:23:17 +10:00
ea3ceb382a Update launcher/resources/multimc/scalable/discord.svg
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
2022-04-09 23:42:08 +00:00
37a30fbc3f Update discord.svg 2022-04-09 13:22:39 +00:00
99193a2d7b Update discord.svg 2022-04-09 13:16:55 +00:00
abfb99ba3f Nevermind. It does. 2022-04-09 13:16:03 +00:00
fcb311eecd size doesnt matter? 2022-04-09 13:11:33 +00:00
54e4f88ada Attempt implementing the new discord logo 2022-04-09 13:00:27 +00:00
89125fde22 refactor: switch Quilt mappings to hashed MojMap 2022-04-09 14:56:07 +02:00
9f3eed6ca2 Fix typos causing build failures on non-macOS systems
It also did the exact opposite thing I was trying to do, so that's fixed too...
2022-04-08 17:00:42 -04:00
ab82358dcb Show and hide the menu bar with the 'alt' key
Only applicable for systems without a native menu bar (i.e. almost anything that is not macOS or Ubuntu Unity). On these systems, the menu bar appears on top of the window, which does not look good next to the tool bar already up there.

When the menu bar is hidden, the keyboard shortcuts set by the menu bar are disabled. They should always work, so this also adds a workaround for that.
2022-04-08 16:21:52 -04:00
75fddd0052 Create menubar prototype
Some stuff still needs to be fixed:

- The close window option always closes the main window, even if it is not the currently active window (only applicable on systems with native menu bar)
- None of the (text) editing actions are enabled
- Actions related to instances should only be active when an instance is selected
- The open wiki option ("PolyMC Help") needs to be implemented
- Delete instance keyboard shortcut does not seem to work on my system. Test further
- It would be nice if the profiles menu had all of the logged in accounts, and if they could be selected from that menu (preferably with keyboard shortcuts, probably Ctrl + 1, Ctrl + 2, ...)
2022-04-08 15:39:30 -04:00
8a2c5f5b0d Merge pull request #407 from DioEgizio/upstream-cherrypick 2022-04-08 16:18:28 +02:00
66caac0bbc Update launcher/JavaCommon.cpp
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
2022-04-08 11:16:00 +02:00
ab8d897bd7 Merge pull request #409 from flowln/tasks 2022-04-08 09:45:06 +02:00
3024dbcf2c Apply suggestion
Co-authored-by: Kenneth Chew <79120643+kthchew@users.noreply.github.com>
2022-04-08 08:50:32 +02:00
eeae3eca67 test: add new test to Task test
Also adds one more check to setStatus test
2022-04-07 19:42:26 -03:00
d0cda6d605 test: add basic Task unit test
Only only two tests for now. We can iterate on this later :^)

This is to try to avoid breaking things again!
2022-04-07 19:08:01 -03:00
167e32a69f fix: allow aborting CF modpack importing 2022-04-07 18:56:34 -03:00
be2512bb4b fix: issue with status of non-sequencial tasks 2022-04-07 18:41:32 -03:00
c3f1c13a31 Merge pull request #272 from Kranzes/develop 2022-04-07 20:30:26 +02:00
35cfb41a9c fix: check for Quilt as Fabric-compatible loader 2022-04-07 18:46:09 +02:00
74cdf5350d fix: restrict quilt-mappings versions to MC version 2022-04-07 18:46:00 +02:00
9349232bd4 refactor: dynamically get best version for intermediary mappings 2022-04-07 18:46:00 +02:00
1811302deb NOISSUE save custom offline player name 2022-04-07 18:29:15 +02:00
e6564aa69f NOISSUE fix error string for Xbox authorization failures 2022-04-07 18:29:10 +02:00
566a83b245 NOISSUE prevent -version being passed to the JRE
We want specific JREs, always, not something that is magically resolved.
This counteracts some really bad advice recently being spread on reddit.
2022-04-07 18:28:27 +02:00
9eb9ddc668 feat: initial Quilt support 2022-04-07 18:11:40 +02:00
cc5261051f Merge pull request #364 from Scrumplex/fix-i18n2
Fix translatable strings 2
2022-04-07 23:20:54 +10:00
fa870bc026 Merge pull request #380 from flowln/task-progress 2022-04-06 10:52:38 +02:00
99d569ed0e Merge pull request #384 from jamierocks/technic-improvements 2022-04-06 10:52:27 +02:00
a1a7b9c151 Merge pull request #397 from DioEgizio/manymc-detect-aarch64 2022-04-06 10:52:15 +02:00
Una
dc6340bf38 Allow components to specify Java agents and JVM arguments (#175) 2022-04-06 08:22:24 +02:00
8732bea99b Merge pull request #395 from HarryPeach/develop 2022-04-05 18:01:00 +02:00
bbc6b71138 Merge pull request #389 from DioEgizio/CI/remove-useless-deadcode 2022-04-04 21:03:34 +02:00
5fb096d7b9 Merge pull request #345 from Scrumplex/handle-incompatible-java 2022-04-04 21:01:49 +02:00
cf8680f1ab fix: properly detect arm64 2022-04-04 16:41:23 +02:00
115d8b5945 Merge pull request #390 from PolyMC/ZekeSmith-patch-matrix-reddit
Update matrix and add reddit links
2022-04-04 09:39:40 +02:00
bd8b61651a Check for empty slug before setting pack url 2022-04-03 23:12:46 +01:00
d2ffaee9f8 remove deadcode in CI 2022-04-03 14:43:02 +02:00
8f61633551 Merge pull request #381 from Scrumplex/merge-stable 2022-04-03 13:21:58 +02:00
d33d5b847d Merge pull request #387 from Scrumplex/fix-world-size
fix: calculate world sizes individually
2022-04-03 20:45:23 +10:00
c8879df621 Merge pull request #385 from PolyMC/ZekeSmith-patch-1
Update README.md
2022-04-03 20:42:34 +10:00
c367769781 Update CMakeLists.txt 2022-04-03 20:39:44 +10:00
02b44256b2 Fix matrix links and add reddit 2022-04-03 20:37:50 +10:00
b6e722a048 BuildConfig: Make Technic API base URL and build constants 2022-04-02 13:53:44 +01:00
7f2615b2a5 Technic: Verify checksums for pack build mods 2022-04-02 13:53:44 +01:00
a232c2d509 Technic: Display available versions for Solder packs 2022-04-02 13:53:44 +01:00
c8205fda9f Technic: Replace inline parsing code with API models 2022-04-02 13:53:44 +01:00
8df88e7fbb Technic: Add API models for Solder packs 2022-04-02 13:53:44 +01:00
c8092269ba Technic: Match CurseForge pack description format 2022-04-02 13:53:44 +01:00
9d88f07955 Technic: Include the modpack version in instance title 2022-04-02 13:53:43 +01:00
f267375ac2 Technic: Prevent potential HTML injection 2022-04-02 13:53:43 +01:00
d44fa416ca Technic: Allow pack API urls to be used in search
This mimics the behaviour that the Technic launcher has, and their
website displays API URLs for.

The big benefit of this, is to be able to install private packs now :)
2022-04-02 13:53:43 +01:00
41d7b27d43 fix: calculate world sizes individually 2022-04-02 13:29:37 +02:00
5f461374b8 Update README.md 2022-04-02 17:25:49 +10:00
d5576779b7 Merge pull request #383 from PolyMC/ZekeSmith-license
Update License
2022-04-02 06:11:48 +02:00
c098be40ab flake.lock: Update
Flake lock file updates:

• Updated input 'flake-compat':
    'github:edolstra/flake-compat/b7547d3eed6f32d06102ead8991ec52ab0a4f1a7' (2022-01-03)
  → 'github:edolstra/flake-compat/64a525ee38886ab9028e6f61790de0832aa3ef03' (2022-03-25)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e9545762b032559c27d8ec9141ed63ceca1aa1ac' (2022-03-10)
  → 'github:nixos/nixpkgs/30d3d79b7d3607d56546dd2a6b49e156ba0ec634' (2022-03-25)
2022-04-02 02:35:44 +03:00
333f7cc320 Merge pull request #373 from Scrumplex/feat-world-size 2022-04-02 00:59:15 +02:00
9180c751d8 fix(launch/VerifyJava): reword log output 2022-04-02 00:54:48 +02:00
131a04653f Update License 2022-04-02 07:52:07 +10:00
6e6d495bc7 nix: build with latest jdk version 2022-04-01 16:55:51 +03:00
2c07f758a0 nix: refactor flake (drop flake-utils) 2022-04-01 16:55:51 +03:00
251f0efec2 Merge remote-tracking branch 'upstream/stable' into develop 2022-04-01 15:33:33 +02:00
e8697068fb fix: codestyle 2022-04-01 15:00:05 +02:00
269c1bbf58 Merge pull request #370 from embeddedt/develop
Make launcher icon grayscale for pe_light theme
2022-04-01 22:58:54 +10:00
9b8493c304 feat: Use a single progress dialog when doing multiple tasks
This puts all mod downloading tasks inside a SequentialTask, which is,
for more than one task, a multi step task. This is handled by the
ProgressDialog by showing both the global progress of tasks executed,
and the individual progress of each of them.
2022-04-01 09:32:00 -03:00
c389a711ed fix: remove redundant include 2022-04-01 13:14:04 +02:00
382548e0a7 Merge pull request #355 from dada513/flatpak_properly
Fix flatpak properly
2022-04-01 21:03:14 +10:00
a90fc3d7fe Merge pull request #375 from dada513/fix_modrinth_url 2022-04-01 07:57:59 +02:00
48a6380e31 Fix modrinth usable URL in mod downloader 2022-03-31 20:39:10 +02:00
64ca96f470 feat: track and display world size 2022-03-31 18:45:17 +02:00
59b3e30821 Scrumplex moment 2022-03-31 16:11:04 +02:00
92e5e0e95b Make launcher icon grayscale for pe_light theme 2022-03-30 10:51:37 -04:00
9202996c62 fix(i18n): remove brand names from translations 2022-03-29 15:25:21 +02:00
e22d54abd3 Merge pull request #344 from oynqr/build/allow-disabling-tests 2022-03-29 14:42:49 +02:00
b53ba12fa2 Merge pull request #360 from FayneAldan/patch-2 2022-03-29 14:34:14 +02:00
335115041c Merge pull request #348 from txtsd/issues
Issue template changes
2022-03-29 11:26:22 +02:00
bac67800be Merge pull request #312 from Scrumplex/add-nightly.link
Add nightly.link comments
2022-03-29 11:25:43 +02:00
306df9e17f Merge pull request #352 from Scrumplex/fix-name
Update Credits and Branding
2022-03-29 11:24:48 +02:00
5f2e768376 Merge pull request #356 from flowln/version_optimize
Improve mod versions request to Modrinth
2022-03-29 11:24:12 +02:00
575c92ec47 Merge pull request #357 from FayneAldan/patch-1
Fix POLYMC_JAVA_PATHS env not working on Windows
2022-03-29 11:23:29 +02:00
4d8bf0b621 Convert \s in Windows POLYMC_JAVA_PATHS
Allows you to use either `\` or `/` on Windows
2022-03-28 15:55:54 -06:00
954074942e 😢 fix bully 2022-03-28 20:56:24 +02:00
341eb16a4c Merge branch 'develop' of https://github.com/PolyMC/PolyMC into flatpak_properly 2022-03-28 20:55:06 +02:00
3a7eeff135 Fix 2022-03-28 20:55:03 +02:00
659f93b1de Fix POLYMC_JAVA_PATHS env not working on Windows 2022-03-27 17:21:34 -06:00
ea60e48d9d chore: add license header
chore: add license header
2022-03-27 20:59:56 +02:00
6054abaffb fix(credits): wrap UTF-8 text with QString 2022-03-27 20:59:56 +02:00
3a1feed723 fix: update credits 2022-03-27 20:59:56 +02:00
85f3fc9944 fix: remove "PolyMC" from strings 2022-03-27 20:59:51 +02:00
87cf38a377 Merge pull request #341 from dada513/develop 2022-03-27 20:56:04 +02:00
5e77b548b1 Merge pull request #349 from txtsd/gha_ignore 2022-03-27 20:55:33 +02:00
104de9e795 Merge pull request #220 from flowln/mod_refactor 2022-03-27 20:55:16 +02:00
424f4a72ff Inform user about possible issues when using a Portal as instance folder 2022-03-27 16:08:11 +02:00
ec6409914d newline more like waste 2022-03-27 14:51:48 +02:00
6a25cacc3e Merge branch 'develop' of https://github.com/PolyMC/PolyMC into develop 2022-03-27 14:51:02 +02:00
b1af689546 Add quit launcher after game stops option (Steam Deck)
lecense
2022-03-27 14:50:47 +02:00
0a5dfeb3d7 fix newline (scrumplex nitpick not allowed) 2022-03-27 14:44:40 +02:00
6a180f495f more flatpak fixes 2022-03-27 14:42:02 +02:00
3672dbc5af Fix flatpak properly 2022-03-27 12:43:49 +02:00
81b50c0387 Merge pull request #351 from DioEgizio/lin-nodeps-again 2022-03-26 11:00:44 +01:00
bd60c54911 Merge pull request #314 from Scrumplex/chore-bump-1.1.1
Bump to 1.1.1
2022-03-26 10:55:33 +01:00
87acaa0926 Merge pull request #314 from Scrumplex/chore-bump-1.1.1
Bump to 1.1.1
2022-03-26 09:55:06 +00:00
54d2c91320 bring back portable linux builds 2022-03-26 07:06:37 +01:00
94e7961df0 chore: Don't build release type during development 2022-03-25 23:18:55 +05:30
0d46ea5c71 chore: Ignore more paths 2022-03-25 23:17:14 +05:30
6bd345b1ad fix(templates): Unsplit bulleted line 2022-03-25 22:43:26 +05:30
cb384261b8 fix(templates): Replace dead FAQ link with new wiki link 2022-03-25 22:42:41 +05:30
75301bec4b fix(templates): Use correct labels 2022-03-25 22:41:38 +05:30
d00c320c00 optimize: Improve mod versions request to Modrinth
This uses more arguments in the GET request for mod versions on the
Modrinth API, filtering what versions can be returned, decreasing load
on Modrinth servers and improving a little the time it takes for the versions to be
available to the user.

This also removes the now unneeded check on correct modloaders in
ModrinthPackIndex, since it is now filtered by the Modrinth server.

Lastly, this adds a couple of helper functions in ModModel.
2022-03-24 19:31:11 -03:00
e13ca94061 chore: resolve conflicts and merge upstream 2022-03-24 18:24:51 -03:00
e02369ba6b chore: add license header 2022-03-24 16:10:43 +01:00
82c35f2746 feat: block launch if Java is incompatible
Keep track of compatible Java versions from meta. Launch-step
VerifyJavaInstall will check if current instance's Java version is
compatible.
Also add override option both globally and per-instance in-case the user
doesn't care about the requirement.
2022-03-24 16:10:39 +01:00
a9d935f9ef Merge pull request #337 from oynqr/misc/create-vendored-tarball 2022-03-24 11:16:39 +01:00
92f3154e8f Merge pull request #337 from oynqr/misc/create-vendored-tarball 2022-03-24 11:15:39 +01:00
eb06d0116f Merge pull request #334 from flowln/right_file_2
Fix skipping file in mod version parsing
2022-03-24 11:10:11 +01:00
f66910d054 Merge pull request #334 from flowln/right_file_2
Fix skipping file in mod version parsing
2022-03-24 20:28:12 +11:00
1b47132ebb libnbtplusplus: fix compilation as shared library 2022-03-24 08:32:26 +01:00
a89cbf116d Allow disabling building of tests 2022-03-23 19:48:03 +01:00
471ea680a5 Update used actions and cleanup release flow 2022-03-23 16:18:25 +01:00
51de84407f Create vendored tarball on release 2022-03-23 12:37:44 +01:00
d252917792 Enable LTO for Actions 2022-03-23 11:40:19 +01:00
dfa5f614aa Put LTO behind an optional flag 2022-03-23 10:05:31 +01:00
f3a244e90a fix: fix skipping one on file counting in mod version parse 2022-03-22 19:45:31 -03:00
c7c83a35fa Enable LTO/IPO on release builds 2022-03-22 21:04:35 +01:00
6025cd0ca5 Merge pull request #330 from DioEgizio/notportable
bring back not portable windows builds
2022-03-22 20:11:15 +01:00
ce05ce92bb Merge pull request #322 from oynqr/build/static-rainbow
Build with static rainbow
2022-03-22 20:11:15 +01:00
a5fc640f2c Merge pull request #298 from Scrumplex/fix-i18n
Fix translatable strings
2022-03-22 20:11:15 +01:00
0a4a3fece5 Merge pull request #323 from Scrumplex/retranslate-pages
Retranslate all settings pages
2022-03-22 20:11:15 +01:00
fcf728f3b5 Merge pull request #315 from txtsd/display_scaling
Allow fractional DPI scaling
2022-03-22 20:11:15 +01:00
cd4851c98b Merge pull request #311 from DioEgizio/patch-2
fix webp
2022-03-22 20:11:15 +01:00
3db5f30403 Merge pull request #316 from Scrumplex/fix-disabled-controls 2022-03-22 20:11:15 +01:00
58957122b9 Merge pull request #306 from Scrumplex/limit-instance-lengths
Limit instance names to 128 chars
2022-03-22 20:11:15 +01:00
8b46658b05 Merge pull request #294 from oynqr/msys2
Switch to msys2 for Windows builds
2022-03-22 20:11:15 +01:00
571e322d66 Merge pull request #200 from Scrumplex/scrumplex-license-header 2022-03-22 20:11:15 +01:00
ddda02f092 Merge pull request #292 from lack/offline_username_limits
Limit offline username to 16 characters with override
2022-03-22 20:11:15 +01:00
bf6fa6bce4 Merge pull request #295 from Scrumplex/fix-portable
Make Launcher_PORTABLE work on all platforms
2022-03-22 20:11:15 +01:00
025a3cf730 Merge pull request #296 from flowln/right_file
Use primary file for mod downloading on Modrinth
2022-03-22 20:11:15 +01:00
6d9eaee7f9 Merge pull request #297 from DioEgizio/patch-1
bundle jre8u312 instead of latest on appimage
2022-03-22 20:11:15 +01:00
7471ce4530 Merge pull request #299 from flowln/paste_serv
Remove paste.polymc.org
2022-03-22 20:11:15 +01:00
149ffb844f Merge pull request #278 from Scrumplex/fix-copying
Clarify GPL-3.0-only
2022-03-22 20:11:15 +01:00
4cf3ac42c8 Merge pull request #280 from oynqr/gitdir-notfound-check
Add GITDIR-NOTFOUND check
2022-03-22 20:11:15 +01:00
d16c6b0e69 Merge pull request #265 from Scrumplex/fix-javacheck-appimage
Define JARs path relative to application root
2022-03-22 20:11:15 +01:00
76e1aba58b Merge pull request #273 from DioEgizio/extra-rebranding-macos
extra rebranding for macos
2022-03-22 20:11:15 +01:00
c560d06b8d Merge pull request #270 from flowln/dialog
Make a better "Mod download confirmation dialog"
2022-03-22 20:11:15 +01:00
0681568d3e Merge pull request #254 from Scrumplex/fix-update-metainfo
Update metainfo URLs
2022-03-22 20:11:15 +01:00
c7fdfb8116 Merge pull request #330 from DioEgizio/notportable
bring back not portable windows builds
2022-03-22 16:42:40 +01:00
c6b1a776dc fix some typos 2022-03-22 07:38:00 +01:00
8accb6f04e fix typos
opz :P
2022-03-21 19:29:33 +01:00
d1d055564c fix typo 2022-03-21 19:21:09 +01:00
2741c58a01 bring back notportable builds 2022-03-21 19:11:55 +01:00
64399dd8d6 Merge pull request #322 from oynqr/build/static-rainbow
Build with static rainbow
2022-03-21 16:58:37 +01:00
f2ca11688e Merge pull request #326 from Scrumplex/feat-backport-pr 2022-03-21 15:55:12 +01:00
3c0c57359b feat(actions): add backport bot 2022-03-21 14:46:01 +01:00
062fc79286 Merge pull request #298 from Scrumplex/fix-i18n
Fix translatable strings
2022-03-21 14:21:06 +01:00
2da565f5d4 Merge pull request #323 from Scrumplex/retranslate-pages
Retranslate all settings pages
2022-03-22 00:06:16 +11:00
e8373bbf65 Build with static rainbow 2022-03-21 12:47:42 +01:00
26acc836d9 Revert "fix: use our own prefix for rainbow lib"
This reverts commit 61db1c46beb465c33124ec4f34dfdcefd4d804d3.
2022-03-21 09:40:20 +01:00
9c22af9685 Merge pull request #315 from txtsd/display_scaling
Allow fractional DPI scaling
2022-03-21 11:21:21 +11:00
75d0078a38 fix: retranslate CustomCommands 2022-03-20 21:51:36 +01:00
536b1a23fc fix: retranslate mod download pages 2022-03-20 21:51:23 +01:00
cafff5e504 chore: add license header 2022-03-20 21:40:49 +01:00
dd5c4b6864 App: Retranslate all pages when the language is changed 2022-03-20 20:48:12 +01:00
a2c85a8531 App: Retranslate page header titles
This fixes a bug that is only practically effects the title of the
language page not updating the header when changing the language.
2022-03-20 20:02:21 +01:00
de4d757650 Merge pull request #311 from DioEgizio/patch-2
fix webp
2022-03-20 22:20:02 +05:30
f22cd0e8c7 Merge pull request #316 from Scrumplex/fix-disabled-controls 2022-03-20 17:46:09 +01:00
702a1da0ac fix: disable "Install Forge" button when needed 2022-03-20 15:35:35 +01:00
768007d980 fix: disable "Download mods" button when needed
Fixes #271
2022-03-20 15:34:13 +01:00
2e40ab6244 (fix): Allow fractional DPI scaling 2022-03-20 20:02:24 +05:30
95182ed74b chore: bump version 2022-03-20 15:11:43 +01:00
8bc6cdf55c Merge pull request #306 from Scrumplex/limit-instance-lengths
Limit instance names to 128 chars
2022-03-21 01:04:40 +11:00
6c0b101fed Merge branch 'PolyMC:develop' into patch-2 2022-03-20 15:02:04 +01:00
9841c0a63d Merge pull request #294 from oynqr/msys2
Switch to msys2 for Windows builds
2022-03-21 01:01:05 +11:00
17d200dc88 chore(actions): add nightly.link comments 2022-03-20 14:56:47 +01:00
c8fec556c0 Merge pull request #305 from flowln/gui_changes 2022-03-20 13:39:12 +01:00
b7f2959353 fix 2022-03-20 13:15:56 +01:00
4899d3c458 Merge pull request #200 from Scrumplex/scrumplex-license-header 2022-03-20 12:04:39 +01:00
c311dba465 fix: limit instance names to 128 chars 2022-03-19 23:23:08 +01:00
75ec4256e2 feat(ui): allow users to move toolbars to different places 2022-03-19 17:59:00 -03:00
bb5a91c179 Update CMakeLists.txt 2022-03-19 19:01:51 +01:00
8225f1ac92 Merge pull request #292 from lack/offline_username_limits
Limit offline username to 16 characters with override
2022-03-19 16:02:28 +01:00
06d16c6b13 Merge pull request #295 from Scrumplex/fix-portable
Make Launcher_PORTABLE work on all platforms
2022-03-19 15:59:38 +01:00
90780818ca Limit offline username to 16 characters with override
Offline usernames longer than 16 characters won't be able to connect to
LAN games or offline-mode servers, so just don't let it happen.

Add a checkbox to allow people to unrestrict usernames if they want.

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
2022-03-19 10:12:07 -04:00
a160bd0062 chore: add license header to files I modified 2022-03-19 12:46:56 +01:00
7e0312493b fix(i18n): improve social platform actions 2022-03-19 12:36:04 +01:00
ccfd06ad21 fix(i18n): remove brand names from translations 2022-03-19 12:35:15 +01:00
48c2146a42 fix(i18n): fix translatable strings 2022-03-19 12:29:46 +01:00
abb9fa8cbd Merge pull request #296 from flowln/right_file
Use primary file for mod downloading on Modrinth
2022-03-19 11:41:36 +11:00
f99245b917 Merge pull request #297 from DioEgizio/patch-1
bundle jre8u312 instead of latest on appimage
2022-03-19 11:40:17 +11:00
e35db82c27 Merge pull request #299 from flowln/paste_serv
Remove paste.polymc.org
2022-03-19 11:39:48 +11:00
6202525372 Readd short rev to artifact names 2022-03-18 22:28:52 +01:00
ec66c8fd3d fix(ui): remove paste.polymc.org 2022-03-18 14:21:42 -03:00
19804c5718 bundle jre8u312 instead of latest
8u320 or higher breaks old forge
2022-03-18 15:28:44 +01:00
fa5fa53592 fix: Use primary file for mod download on Modrinth 2022-03-18 10:52:47 -03:00
da43ed8ce1 fix silly mistakes and merge upstream 2022-03-18 07:54:47 -03:00
2d1f99b765 fix: make Launcher_PORTABLE work on all platforms
Fixes #261
2022-03-18 11:38:13 +01:00
f01b8f29c6 Use Temurin instead of AdoptOpenJDK 2022-03-17 23:32:44 +01:00
440e9731e2 Switch to msys2 for Windows builds 2022-03-17 22:06:06 +01:00
acdb54b88e Merge pull request #278 from Scrumplex/fix-copying
Clarify GPL-3.0-only
2022-03-16 12:37:05 +01:00
00c3336ec8 Merge pull request #280 from oynqr/gitdir-notfound-check
Add GITDIR-NOTFOUND check
2022-03-16 07:27:29 +01:00
a268ac7141 Add GITDIR-NOTFOUND check
This adds a check for a GIT_REFSPEC value of "GITDIR-NOTFOUND" and sets
the VERSION_CHANNEL to stable in that case. Without this change,
"GITDIR-N" is appended to the version string when building from a source
archive instead of a git checkout.
2022-03-15 09:04:43 +01:00
aedb513c9e Merge pull request #265 from Scrumplex/fix-javacheck-appimage
Define JARs path relative to application root
2022-03-14 23:31:38 +01:00
ac3a7acc45 Merge pull request #273 from DioEgizio/extra-rebranding-macos
extra rebranding for macos
2022-03-14 23:31:23 +01:00
8409aa2571 tidy: Fix clang-tidy issues on files changed in this PR
The checks used are roughly the same as the ones proposed in the
clang-tidy PR (except perhaps that I used modernize-* instead of listing
them individually,though I don't think this caused any readability
detriments).

In ModrinthModel.cpp and FlameModModel.cpp I ignored the
modernize-avoid-c-arrays one, mostly because making the sorts array an
std::array would most likely increase the code complexity because of the
virtual function. Aside from that, the static_cast warning from
Application.h was not dealt with, since it's not in this PR's scope.
2022-03-14 17:43:36 -03:00
199740cc61 fix(metainfo): clarify GPL-3.0-only 2022-03-14 18:44:02 +01:00
a0f76cba62 chore: clarify GPL-3.0-only 2022-03-14 18:42:41 +01:00
5b8003cbe5 Merge pull request #188 from PolyMC/removal/notifications
remove notifications
2022-03-15 00:51:28 +11:00
c0719102a0 Merge pull request #270 from flowln/dialog
Make a better "Mod download confirmation dialog"
2022-03-15 00:50:49 +11:00
9d8bbf34e6 Merge pull request #250 from Scrumplex/update-logo 2022-03-13 21:02:47 +01:00
ec9d0e70fb [macos] update copyright and info string 2022-03-13 17:57:25 +01:00
f1e44291cc add translation string 2022-03-13 13:11:35 -03:00
b3b613d8b4 feat(ui): make a better "Mod download confirmation dialog" 2022-03-13 11:50:18 -03:00
177b685557 Merge pull request #240 from PolyMC/ZekeSmith-move-to-wiki
Update Readme to link development building to the website wiki. also fix forking and licensing.
2022-03-14 00:26:09 +11:00
71a4333f55 Update README.md 2022-03-13 23:25:17 +10:00
f1c21a912a fix: simplify header SVG using SVGO 2022-03-13 14:22:31 +01:00
84a142096f chore: switch logo font to Josefin Sans 2022-03-13 14:22:18 +01:00
bb2b344d33 fix: define jars path relative to application root
Fixes #117
2022-03-13 12:48:24 +01:00
b96572774f Merge pull request #254 from Scrumplex/fix-update-metainfo
Update metainfo URLs
2022-03-13 13:22:42 +11:00
641a96e4a9 fix(metainfo): update URLs 2022-03-12 18:17:25 +01:00
4fe13c64a1 Update README.md 2022-03-08 19:07:21 +10:00
b3c2a56ece fix: delete semicolons at the end of .cpp file's functions
my lsp is weird sometimes
2022-03-07 19:55:20 -03:00
9c57b54a81 refactor: move things around so that related things are close together
This also adds some comments around ModModel.cpp and ModPage.cpp to add
some ease of reading the code.

Also move some things from headers to cpp files.
2022-03-07 19:32:28 -03:00
b131d3b2ec refactor: move more common code to base class
Also removes unused imports and organize the ModModel header
2022-03-07 18:28:24 -03:00
16bfafa29e refactor: de-duplicate common code in network mod APIs 2022-03-07 17:45:28 -03:00
f714adf6d2 refactor: move NetJob away from ModModel to ModAPI
This is done so that 1. ModAPI behaves more like an actual API instead
of just a helper, and 2. Allows for more easily creating other mod
providers that may or may not use network tasks (foreshadowing lol)
2022-03-07 16:22:57 -03:00
39bd04f06f refactor: use Enum instead of raw int for ModLoaderType 2022-03-06 16:45:39 -03:00
d755174bee clarify some method names and comments 2022-03-06 16:04:24 -03:00
1229e90817 merge upstream 2022-03-06 15:28:18 -03:00
5a638fa977 refactor: move "get versions" task from page to model
This seems more reasonable
2022-03-06 15:23:00 -03:00
5e9d49a910 refactor: use only a single unique_ptr for the api 2022-03-06 13:54:55 -03:00
9a8599e4ba fix windows compilation 2022-03-03 00:06:37 -03:00
2d68308d49 refactor: move url creation for mods to modplatform/
Moves all things related to creating the URLs of the mod platforms
that go to network tasks to a single place, so that:

1. Maintaining and fixing eventual issues is more straightforward.
2. Makes it possible to factor out more common code between the
   different modplatform pages
2022-03-02 23:13:04 -03:00
0dd1c26cf3 refactor: extract common code in mod pages and model
This creates a hierarchy in which ModPage and ModModel are the parents
of every mod provider, providing the basic functionality common to all
of them.

It also imposes a unique .ui file (they were already equal before, just
duplicated basically) on all mod providers.
2022-03-02 21:52:44 -03:00
881b2f2b38 refactor: Use a single indexed pack for mods
Since there's little difference between them, let's remove duplication
and merge them.
2022-03-02 18:49:19 -03:00
6d1f9d4d02 fix 2022-02-21 12:44:34 -05:00
da70122d9c remove notifications 2022-02-20 19:23:08 -05:00
239 changed files with 7893 additions and 3904 deletions

View File

@ -1,6 +1,6 @@
name: Bug Report
description: File a bug report
labels: [bug, needs-triage]
labels: [bug]
body:
- type: markdown
attributes:
@ -8,7 +8,7 @@ body:
If you need help with running Minecraft, please visit us on our Discord before making a bug report.
Before submitting a bug report, please make sure you have read this *entire* form, and that:
* You have read the [FAQ](https://github.com/PolyMC/PolyMC/wiki/FAQ) and it has not answered your question
* You have read the [PolyMC wiki](https://polymc.org/wiki/) and it has not answered your question.
* Your bug is not caused by Minecraft or any mods you have installed.
* Your issue has not been reported before, [make sure to use the search function!](https://github.com/PolyMC/PolyMC/issues)

View File

@ -1,7 +1,7 @@
# Template based on https://gitlab.archlinux.org/archlinux/rfcs/-/blob/0ba3b61e987e197f8d1901709409b8564958f78a/rfcs/0000-template.rst
name: Request for Comment (RFC)
description: Propose a larger change and start a discussion.
labels: [RFC]
labels: [rfc]
body:
- type: markdown
attributes:
@ -21,8 +21,7 @@ body:
Introduce the topic. If this is a not-well-known section of PolyMC, a detailed explanation of the background is recommended.
Some example points of discussion:
- What specific problems are you facing right now that you're trying to address?
- Are there any previous discussions? Link to them and summarize them (don't
- force your readers to read them though!).
- Are there any previous discussions? Link to them and summarize them (don't force your readers to read them though!).
- Is there any precedent set by other software? If so, link to resources.
placeholder: I don't like cats. I think many users also don't like cats.
validations:

View File

@ -1,6 +1,6 @@
name: Suggestion
description: Make a suggestion
labels: [idea, needs-triage]
labels: [enhancement]
body:
- type: markdown
attributes:

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
URL_JDK8="https://api.adoptium.net/v3/binary/latest/8/ga/linux/x64/jre/hotspot/normal/eclipse"
URL_JDK8="https://api.adoptium.net/v3/binary/version/jdk8u312-b07/linux/x64/jre/hotspot/normal/eclipse"
URL_JDK17="https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jre/hotspot/normal/eclipse"
mkdir -p JREs

19
.github/workflows/backport.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Backport PR to stable
on:
pull_request:
branches: [ develop ]
types: [ closed ]
jobs:
release_pull_request:
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'backport')
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Backport PR by cherry-pick-ing
uses: Nathanmalnoury/gh-backport-action@master
with:
pr_branch: 'stable'
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -16,58 +16,49 @@ jobs:
include:
- os: ubuntu-20.04
qt_version: 5.12.8
qt_host: linux
- os: ubuntu-20.04
qt_version: 5.15.2
qt_host: linux
app_image: true
- os: windows-2022
qt_version: 5.15.2
qt_host: windows
qt_arch: win32_mingw81
name: "Windows-i686"
msystem: mingw32
- os: windows-2022
name: "Windows-x86_64"
msystem: mingw64
- os: macos-11
qt_version: 5.12.12
qt_host: mac
macosx_deployment_target: 10.12
macosx_deployment_target: 10.13
runs-on: ${{ matrix.os }}
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
INSTALL_DIR: "install"
INSTALL_PORTABLE_DIR: "install-portable"
INSTALL_APPIMAGE_DIR: "install-appdir"
BUILD_DIR: "build"
steps:
- name: Install 32bit mingw on Windows
if: runner.os == 'Windows'
uses: egor-tensin/setup-mingw@v2
with:
platform: x86
- name: Install 32bit zlib via Strawberry on Windows
if: runner.os == 'Windows'
run: |
choco install strawberryperl -y --force --x86
##
# PREPARE
##
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: 'true'
# We need to do this here because it inexplicably fails if we split the step
- name: Download and install OpenSSL libs on Windows
- name: 'Setup MSYS2'
if: runner.os == 'Windows'
run: |
python -m pip install --upgrade pip
python -m pip install aqtinstall==2.0.5
python -m aqt install-tool -O "${{ github.workspace }}\Qt\" windows desktop tools_openssl_x86
mkdir ${{ env.INSTALL_DIR }}
copy "${{ github.workspace }}\Qt\Tools\OpenSSL\Win_x86\bin\libssl-1_1.dll" "${{ github.workspace }}\${{ env.INSTALL_DIR }}\"
copy "${{ github.workspace }}\Qt\Tools\OpenSSL\Win_x86\bin\libcrypto-1_1.dll" "${{ github.workspace }}\${{ env.INSTALL_DIR }}\"
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
update: true
install: >-
git
pacboy: >-
toolchain:p
cmake:p
ninja:p
qt5:p
- name: Set short version
shell: bash
@ -76,147 +67,190 @@ jobs:
echo "VERSION=$ver_short" >> $GITHUB_ENV
- name: Install OpenJDK
uses: AdoptOpenJDK/install-jdk@v1
uses: actions/setup-java@v3
with:
version: '17'
distribution: 'temurin'
java-version: '17'
- name: Cache Qt
id: cache-qt
uses: actions/cache@v2
with:
path: "${{ github.workspace }}/Qt/"
key: ${{ runner.os }}-${{ matrix.qt_version }}-${{ matrix.qt_arch }}-qt_cache
- name: Install Qt (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install qt@5
- name: Install Qt
if: runner.os != 'Linux' || matrix.app_image == true
uses: jurplel/install-qt-action@v2
with:
version: ${{ matrix.qt_version }}
host: ${{ matrix.qt_host }}
arch: ${{ matrix.qt_arch }}
cached: ${{ steps.cache-qt.outputs.cache-hit }}
dir: "${{ github.workspace }}/Qt/"
- name: Install System Qt on Linux
if: runner.os == 'Linux' && matrix.app_image != true
- name: Install Qt (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get -y update
sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
- name: Install Ninja
if: runner.os != 'Windows'
uses: urkle/action-get-ninja@v1
- name: Download linuxdeploy family for AppImage on Linux
if: matrix.app_image == true
- name: Prepare AppImage (Linux)
if: runner.os == 'Linux'
run: |
wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage"
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage"
- name: Download JREs for AppImage on Linux
if: matrix.app_image == true
shell: bash
run: |
${{ github.workspace }}/.github/scripts/prepare_JREs.sh
- name: Configure CMake
if: runner.os != 'Linux'
run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -G Ninja
##
# CONFIGURE
##
- name: Configure CMake on Linux
- name: Configure CMake (macOS)
if: runner.os == 'macOS'
run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DQt5_DIR=/usr/local/opt/qt@5 -DCMAKE_PREFIX_PATH=/usr/local/opt/qt@5 -G Ninja
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -G Ninja
- name: Configure CMake (Linux)
if: runner.os == 'Linux'
run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DLauncher_PORTABLE=OFF -G Ninja
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -G Ninja
##
# BUILD
##
- name: Build
if: runner.os != 'Windows'
run: |
cmake --build ${{ env.BUILD_DIR }}
- name: Install
if: runner.os != 'Linux'
- name: Build (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
cmake --build ${{ env.BUILD_DIR }}
##
# PACKAGE BUILDS
##
- name: Package (macOS)
if: runner.os == 'macOS'
run: |
cmake --install ${{ env.BUILD_DIR }}
- name: Install on Linux
cd ${{ env.INSTALL_DIR }}
chmod +x "PolyMC.app/Contents/MacOS/polymc"
tar -czf ../PolyMC.tar.gz *
- name: Package (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
cmake --install ${{ env.BUILD_DIR }}
cd ${{ env.INSTALL_DIR }}
if [ "${{ matrix.msystem }}" == "mingw32" ]; then
cp /mingw32/bin/libcrypto-1_1.dll /mingw32/bin/libssl-1_1.dll ./
elif [ "${{ matrix.msystem }}" == "mingw64" ]; then
cp /mingw64/bin/libcrypto-1_1-x64.dll /mingw64/bin/libssl-1_1-x64.dll ./
fi
- name: Package (Windows, portable)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
- name: Package (Linux)
if: runner.os == 'Linux'
run: |
DESTDIR=${{ env.INSTALL_DIR }} cmake --install ${{ env.BUILD_DIR }}
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }}
- name: Bundle AppImage
if: matrix.app_image == true
cd ${{ env.INSTALL_DIR }}
tar -czf ../PolyMC.tar.gz *
- name: Package (Linux, portable)
if: runner.os == 'Linux'
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
cd ${{ env.INSTALL_PORTABLE_DIR }}
tar -czf ../PolyMC-portable.tar.gz *
- name: Package AppImage (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr
export OUTPUT="PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
chmod +x linuxdeploy-*.AppImage
mkdir -p ${{ env.INSTALL_DIR }}/usr/lib/jvm/java-{8,17}-openjdk
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-{8,17}-openjdk
cp -r ${{ github.workspace }}/JREs/jre8/* ${{ env.INSTALL_DIR }}/usr/lib/jvm/java-8-openjdk
cp -r ${{ github.workspace }}/JREs/jre8/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk
cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_DIR }}/usr/lib/jvm/java-17-openjdk
cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_DIR }}/usr/lib"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64/server"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_DIR }}/usr/lib/jvm/java-17-openjdk/lib/server"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_DIR }}/usr/lib/jvm/java-17-openjdk/lib"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64/server"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib/server"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib"
export LD_LIBRARY_PATH
./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_DIR }}/usr/share/icons/hicolor/scalable/apps/org.polymc.PolyMC.svg
./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.polymc.PolyMC.svg
- name: Run windeployqt
if: runner.os == 'Windows'
run: |
windeployqt --no-translations --no-system-d3d-compiler --no-opengl-sw "${{ env.INSTALL_DIR }}/polymc.exe"
##
# UPLOAD BUILDS
##
- name: Run macdeployqt
- name: Upload binary tarball (macOS)
if: runner.os == 'macOS'
run: |
cd ${{ env.INSTALL_DIR }}
macdeployqt "PolyMC.app" -executable="PolyMC.app/Contents/MacOS/polymc" -always-overwrite
- name: chmod binary on macOS
if: runner.os == 'macOS'
run: |
chmod +x "${{ github.workspace }}/${{ env.INSTALL_DIR }}/PolyMC.app/Contents/MacOS/polymc"
- name: tar bundle on macOS
if: runner.os == 'macOS'
run: |
cd ${{ env.INSTALL_DIR }}
tar -czf ../PolyMC.tar.gz *
- name: tar on Linux
if: runner.os == 'Linux' && matrix.app_image != true
run: |
cd ${{ env.INSTALL_DIR }}
tar -czf ../PolyMC.tar.gz *
- name: Upload Linux tar.gz
if: runner.os == 'Linux' && matrix.app_image != true
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC.tar.gz
- name: Upload AppImage for Linux
if: matrix.app_image == true
uses: actions/upload-artifact@v2
- name: Upload binary zip (Windows)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: ${{ env.INSTALL_DIR }}/**
- name: Upload binary zip (Windows, portable)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ matrix.name }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: ${{ env.INSTALL_PORTABLE_DIR }}/**
- name: Upload binary tarball (Linux)
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC.tar.gz
- name: Upload binary tarball (Linux, portable)
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC-portable.tar.gz
- name: Upload AppImage (Linux)
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
path: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
- name: Upload package for Windows
if: runner.os == 'Windows'
uses: actions/upload-artifact@v2
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: ${{ env.INSTALL_DIR }}/**
- name: Upload package for macOS
if: runner.os == 'macOS'
uses: actions/upload-artifact@v2
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC.tar.gz

61
.github/workflows/pr-comment.yml vendored Normal file
View File

@ -0,0 +1,61 @@
name: Comment on pull request
on:
workflow_run:
workflows: ['Test workflow with upload']
types: [completed]
jobs:
pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v5
with:
# This snippet is public-domain, taken from
# https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
script: |
async function upsertComment(owner, repo, issue_number, purpose, body) {
const {data: comments} = await github.rest.issues.listComments(
{owner, repo, issue_number});
const marker = `<!-- bot: ${purpose} -->`;
body = marker + "\n" + body;
const existing = comments.filter((c) => c.body.includes(marker));
if (existing.length > 0) {
const last = existing[existing.length - 1];
core.info(`Updating comment ${last.id}`);
await github.rest.issues.updateComment({
owner, repo,
body,
comment_id: last.id,
});
} else {
core.info(`Creating a comment in issue / PR #${issue_number}`);
await github.rest.issues.createComment({issue_number, body, owner, repo});
}
}
const {owner, repo} = context.repo;
const run_id = ${{github.event.workflow_run.id}};
const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }};
if (!pull_requests.length) {
return core.error("This workflow doesn't match any pull requests!");
}
const artifacts = await github.paginate(
github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id});
if (!artifacts.length) {
return core.error(`No artifacts found`);
}
let body = `Download the artifacts for this pull request:\n`;
for (const art of artifacts) {
body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
}
core.info("Review thread message body:", body);
for (const pr of pull_requests) {
await upsertComment(owner, repo, pr.number,
"nightly-link", body);
}

View File

@ -9,12 +9,16 @@ on:
- '**/LICENSE'
- 'flake.lock'
- '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
paths-ignore:
- '**.md'
- '**/LICENSE'
- 'flake.lock'
- '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
workflow_dispatch:
jobs:
@ -24,9 +28,3 @@ jobs:
uses: ./.github/workflows/build.yml
with:
build_type: Debug
build_release:
name: Build Release
uses: ./.github/workflows/build.yml
with:
build_type: Release

View File

@ -19,10 +19,36 @@ jobs:
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: 'true'
path: 'PolyMC-source'
- name: Download artifacts
uses: actions/download-artifact@v3
- name: Grab and store version
run: |
tag_name=$(echo ${{ github.ref }} | grep -oE "[^/]+$")
echo "VERSION=$tag_name" >> $GITHUB_ENV
- name: Package artifacts properly
run: |
mv ${{ github.workspace }}/PolyMC-source PolyMC-${{ env.VERSION }}
mv PolyMC-Linux*/PolyMC.tar.gz PolyMC-Linux-${{ env.VERSION }}.tar.gz
mv PolyMC-*.AppImage/PolyMC-*.AppImage PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
mv PolyMC-macOS*/PolyMC.tar.gz PolyMC-macOS-${{ env.VERSION }}.tar.gz
tar -czf PolyMC-${{ env.VERSION }}.tar.gz PolyMC-${{ env.VERSION }}
for d in PolyMC-Windows-*; do
cd "${d}" || continue
ARCH="$(echo -n ${d} | cut -d '-' -f 3)"
PORT="$(echo -n ${d} | grep -o portable || true)"
NAME="PolyMC-Windows-${ARCH}"
test -z "${PORT}" || NAME="${NAME}-portable"
zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
cd ..
done
- name: Create release
id: create_release
uses: softprops/action-gh-release@v1
@ -33,67 +59,12 @@ jobs:
name: PolyMC ${{ env.VERSION }}
draft: true
prerelease: false
upload_release:
needs: create_release
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v2
- name: Grab and store version
run: |
tag_name=$(echo ${{ github.ref }} | grep -oE "[^/]+$")
echo "VERSION=$tag_name" >> $GITHUB_ENV
- name: Package artifacts properly
run: |
mv PolyMC-Linux*/PolyMC.tar.gz PolyMC-Linux-${{ env.VERSION }}.tar.gz
mv PolyMC-*.AppImage/PolyMC-*.AppImage PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
mv PolyMC-Windows* PolyMC-Windows-${{ env.VERSION }}
mv PolyMC-macOS*/PolyMC.tar.gz PolyMC-macOS-${{ env.VERSION }}.tar.gz
cd PolyMC-Windows-${{ env.VERSION }}
zip -r -9 ../PolyMC-Windows-${{ env.VERSION }}.zip *
cd ..
- name: Upload Linux asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_name: PolyMC-Linux-${{ env.VERSION }}.tar.gz
asset_path: PolyMC-Linux-${{ env.VERSION }}.tar.gz
asset_content_type: application/gzip
- name: Upload Linux AppImage asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_name: PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
asset_path: PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
asset_content_type: application/x-executable
- name: Upload Windows asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_name: PolyMC-Windows-${{ env.VERSION }}.zip
asset_path: PolyMC-Windows-${{ env.VERSION }}.zip
asset_content_type: application/zip
- name: Upload macOS asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_name: PolyMC-macOS-${{ env.VERSION }}.tar.gz
asset_path: PolyMC-macOS-${{ env.VERSION }}.tar.gz
asset_content_type: application/gzip
files: |
PolyMC-Linux-${{ env.VERSION }}.tar.gz
PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage
PolyMC-Windows-i686-${{ env.VERSION }}.zip
PolyMC-Windows-i686-portable-${{ env.VERSION }}.zip
PolyMC-Windows-x86_64-${{ env.VERSION }}.zip
PolyMC-Windows-x86_64-portable-${{ env.VERSION }}.zip
PolyMC-macOS-${{ env.VERSION }}.tar.gz
PolyMC-${{ env.VERSION }}.tar.gz

4
.gitignore vendored
View File

@ -42,3 +42,7 @@ run/
# Nix/NixOS
result/
# Flatpak
.flatpak-builder
flatbuild

4
.gitmodules vendored
View File

@ -1,7 +1,7 @@
[submodule "depends/libnbtplusplus"]
path = libraries/libnbtplusplus
url = https://github.com/MultiMC/libnbtplusplus.git
pushurl = git@github.com:MultiMC/libnbtplusplus.git
url = https://github.com/PolyMC/libnbtplusplus.git
pushurl = git@github.com:PolyMC/libnbtplusplus.git
[submodule "libraries/quazip"]
path = libraries/quazip

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.9.4)
if(WIN32)
# In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
@ -6,7 +6,7 @@ if(WIN32)
endif()
project(Launcher)
enable_testing()
include(CTest)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD)
if(IS_IN_SOURCE_BUILD)
@ -43,30 +43,43 @@ 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")
option(ENABLE_LTO "Enable Link Time Optimization" off)
if(ENABLE_LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error)
if(ipo_supported AND (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel"))
message(STATUS "IPO / LTO enabled")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
elseif(ipo_supported)
message(STATUS "Not enabling IPO / LTO on debug builds")
else()
message(STATUS "IPO / LTO not supported: <${ipo_error}>")
endif()
endif()
##################################### Set Application options #####################################
######## Set URLs ########
set(Launcher_NEWS_RSS_URL "https://polymc.org/feed/feed.xml" CACHE STRING "URL to fetch PolyMC's news RSS feed from.")
set(Launcher_NEWS_OPEN_URL "https://polymc.org/news" CACHE STRING "URL that gets opened when the user clicks 'More News'")
set(Launcher_HELP_URL "https://polymc.org/wiki/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
set(Launcher_HELP_URL "https://polymc.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
######## Set version numbers ########
set(Launcher_VERSION_MAJOR 1)
set(Launcher_VERSION_MINOR 1)
set(Launcher_VERSION_MINOR 2)
set(Launcher_VERSION_HOTFIX 0)
# Build number
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
# Build platform.
set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.")
set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.")
# Channel list URL
set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.")
# Notification URL
set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.")
# The metadata server
set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.")
@ -83,7 +96,7 @@ set(Launcher_BUG_TRACKER_URL "https://github.com/PolyMC/PolyMC/issues" CACHE STR
set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/polymc/polymc/" CACHE STRING "URL for the translations platform.")
# Matrix Space
set(Launcher_MATRIX_URL "https://matrix.to/#/#polymc:polymc.org" CACHE STRING "URL to the Matrix Space")
set(Launcher_MATRIX_URL "https://matrix.to/#/#polymc:matrix.org" CACHE STRING "URL to the Matrix Space")
# Discord URL
set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.")
@ -91,11 +104,10 @@ set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for t
# Subreddit URL
set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.")
set(Launcher_SUBREDDIT_URL "https://www.reddit.com/r/PolyMCLauncher/" CACHE STRING "URL for the subreddit.")
# Builds
# TODO: Launcher_FORCE_BUNDLED_LIBS should be off in the future, but as of QuaZip 1.2, we can't do that yet.
set(Launcher_FORCE_BUNDLED_LIBS ON CACHE BOOL "Prevent using system libraries, if they are available as submodules")
set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, if they are available as submodules")
set(Launcher_QT_VERSION_MAJOR "5" CACHE STRING "Major Qt version to build against")
@ -122,7 +134,7 @@ if(Launcher_QT_VERSION_MAJOR EQUAL 5)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml)
if(NOT Launcher_FORCE_BUNDLED_LIBS)
find_package(QuaZip-Qt5 REQUIRED)
find_package(QuaZip-Qt5 1.3)
endif()
if (NOT QuaZip-Qt5_FOUND)
set(QUAZIP_QT_MAJOR_VERSION ${QT_VERSION_MAJOR} CACHE STRING "Qt version to use (4, 5 or 6), defaults to ${QT_VERSION_MAJOR}" FORCE)
@ -152,9 +164,10 @@ add_subdirectory(program_info)
####################################### Install layout #######################################
# Install the build results according to platform
set(Launcher_PORTABLE 1 CACHE BOOL "The type of installation (Portable or System)")
if(NOT (UNIX AND APPLE))
# Install "portable.txt" if selected component is "portable"
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION "." COMPONENT portable EXCLUDE_FROM_ALL)
endif()
if(UNIX AND APPLE)
set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS")
@ -163,20 +176,18 @@ if(UNIX AND APPLE)
set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources")
set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars")
set(BUNDLE_DEST_DIR ".")
# Apps to bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app")
# Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}")
set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: Minecraft launcher and management utility.")
set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.polymc.${Launcher_Name}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 ${Launcher_Copyright}")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
@ -189,30 +200,12 @@ if(UNIX AND APPLE)
elseif(UNIX)
set(BINARY_DEST_DIR "bin")
if(Launcher_PORTABLE)
set(LIBRARY_DEST_DIR "bin")
set(BUNDLE_DEST_DIR ".")
set(JARS_DEST_DIR "bin/jars")
# launcher/Application.cpp will use this value
set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_PORTABLE")
# Install basic runner script
configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY)
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION ${BUNDLE_DEST_DIR} RENAME ${Launcher_Name})
else()
set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(JARS_DEST_DIR "share/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(Launcher_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR})
endif()
set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(JARS_DEST_DIR "share/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(LAUNCHER_MAN_DEST_DIR "share/man/man6" CACHE STRING "Path to the man page directory")
# install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps")
@ -220,11 +213,22 @@ elseif(UNIX)
# Set RPATH
SET(Launcher_BINARY_RPATH "$ORIGIN/")
# jars path is determined on runtime, relative to "Application root path", generally /usr or the root of the portable bundle
set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_JARS_LOCATION=${JARS_DEST_DIR}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR} RENAME "${Launcher_APP_BINARY_NAME}.6")
# Install basic runner script if component "portable" is selected
configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY)
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION "." RENAME ${Launcher_Name} COMPONENT portable EXCLUDE_FROM_ALL)
elseif(WIN32)
set(BINARY_DEST_DIR ".")
set(LIBRARY_DEST_DIR ".")
set(PLUGIN_DEST_DIR ".")
set(BUNDLE_DEST_DIR ".")
set(RESOURCES_DEST_DIR ".")
set(JARS_DEST_DIR "jars")
@ -260,6 +264,8 @@ if (FORCE_BUNDLED_QUAZIP)
set(BUILD_SHARED_LIBS 0) # link statically to avoid conflicts.
set(QUAZIP_INSTALL 0)
add_subdirectory(libraries/quazip) # zip manipulation library
else()
message(STATUS "Using system QuaZip")
endif()
add_subdirectory(libraries/rainbow) # Qt extension for colors
add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader

View File

@ -5,8 +5,7 @@
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -33,14 +33,22 @@ Feel free to create an issue if you need help. However, you might find it easier
For people who don't want to use Discord, we have a Matrix Space which is bridged to the Discord server:
[![PolyMC Space](https://img.shields.io/matrix/polymc:polymc.org?label=PolyMC%20Space&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#polymc:polymc.org)
[![PolyMC Space](https://img.shields.io/matrix/polymc:matrix.org?label=PolyMC%20space)](https://matrix.to/#/#polymc:matrix.org)
If there are any issues with the space or you are using a client that does not support the feature here are the individual rooms:
[![Support](https://img.shields.io/matrix/support:polymc.org?label=%23support&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#support:polymc.org)
[![Discussion](https://img.shields.io/matrix/discussion:polymc.org?label=%23discussion&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#discussion:polymc.org)
[![Development](https://img.shields.io/matrix/development:polymc.org?label=%23development&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#development:polymc.org)
[![News](https://img.shields.io/matrix/news:polymc.org?label=%23news&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#news:polymc.org)
[![Development](https://img.shields.io/matrix/polymc-development:matrix.org?label=PolyMC%20Development)](https://matrix.to/#/#polymc-development:matrix.org)
[![Discussion](https://img.shields.io/matrix/polymc-discussion:matrix.org?label=PolyMC%20Discussion)](https://matrix.to/#/#polymc-discussion:matrix.org)
[![Github](https://img.shields.io/matrix/polymc-github:matrix.org?label=PolyMC%20Github)](https://matrix.to/#/#polymc-github:matrix.org)
[![Maintainers](https://img.shields.io/matrix/polymc-maintainers:matrix.org?label=PolyMC%20Maintainers)](https://matrix.to/#/#polymc-maintainers:matrix.org)
[![News](https://img.shields.io/matrix/polymc-news:matrix.org?label=PolyMC%20News)](https://matrix.to/#/#polymc-news:matrix.org)
[![Offtopic](https://img.shields.io/matrix/polymc-offtopic:matrix.org?label=PolyMC%20Offtopic)](https://matrix.to/#/#polymc-offtopic:matrix.org)
[![Support](https://img.shields.io/matrix/polymc-support:matrix.org?label=PolyMC%20Support)](https://matrix.to/#/#polymc-support:matrix.org)
[![Voice](https://img.shields.io/matrix/polymc-voice:matrix.org?label=PolyMC%20Voice)](https://matrix.to/#/#polymc-voice:matrix.org)
we also have a subreddit you can post your issues and suggestions on:
[r/PolyMCLauncher](https://www.reddit.com/r/PolyMCLauncher/)
# Development
@ -48,7 +56,7 @@ If you want to contribute to PolyMC you might find it useful to join our Discord
## Building
If you want to build PolyMC yourself, check [BUILD.md](BUILD.md) for build instructions.
If you want to build PolyMC yourself, check [Build Instructions](https://polymc.org/wiki/development/build-instructions/) for build instructions.
## Code formatting
@ -66,9 +74,15 @@ In general, in order of importance:
The translation effort for PolyMC is hosted on [Weblate](https://hosted.weblate.org/projects/polymc/polymc/) and information about translating PolyMC is available at https://github.com/PolyMC/Translations
## Download infomation
To modify download infomation or change packaging infomation send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md)
## Download information
To modify download information or change packaging information send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md)
## Forking/Redistributing/Custom builds policy
Do whatever you want, we don't care. Just follow the license. If you have any questions about this feel free to ask in an issue.
All launcher code is available under the GPL-3 license.
[Source for the website](https://github.com/PolyMC/polymc.github.io) is hosted under the AGPL-3 License.
The logo and related assets are under the CC BY-SA 4.0 license.

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "BuildConfig.h"
#include <QObject>
@ -25,12 +60,14 @@ Config::Config()
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@";
NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@";
FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@";
GIT_COMMIT = "@Launcher_GIT_COMMIT@";
GIT_REFSPEC = "@Launcher_GIT_REFSPEC@";
if(GIT_REFSPEC.startsWith("refs/heads/"))
if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND"))
{
VERSION_CHANNEL = QStringLiteral("stable");
}
else if(GIT_REFSPEC.startsWith("refs/heads/"))
{
VERSION_CHANNEL = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/");

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QString>
@ -46,13 +81,6 @@ public:
/// User-Agent to use for uncached requests.
QString USER_AGENT_UNCACHED;
/// URL for notifications
QString NOTIFICATION_URL;
/// Used for matching notifications
QString FULL_VERSION_STR;
/// The git commit hash of this build
QString GIT_COMMIT;
@ -112,6 +140,12 @@ public:
QString ATL_DOWNLOAD_SERVER_URL = "https://download.nodecdn.net/containers/atl/";
QString TECHNIC_API_BASE_URL = "https://api.technicpack.net/";
/**
* The build that is reported to the Technic API.
*/
QString TECHNIC_API_BUILD = "multimc";
/**
* \brief Converts the Version to a string.
* \return The version number in string format (major.minor.revision.build).

View File

@ -5,44 +5,46 @@ set(TEST_RESOURCE_PATH ${CMAKE_CURRENT_LIST_DIR})
message(${TEST_RESOURCE_PATH})
function(add_unit_test name)
set(options "")
set(oneValueArgs DATA)
set(multiValueArgs SOURCES LIBS)
if(BUILD_TESTING)
set(options "")
set(oneValueArgs DATA)
set(multiValueArgs SOURCES LIBS)
cmake_parse_arguments(OPT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
cmake_parse_arguments(OPT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if(WIN32)
add_executable(${name}_test ${OPT_SOURCES} ${TEST_RESOURCE_PATH}/UnitTest/test.rc)
else()
add_executable(${name}_test ${OPT_SOURCES})
endif()
if(NOT "${OPT_DATA}" STREQUAL "")
set(TEST_DATA_PATH "${CMAKE_CURRENT_BINARY_DIR}/data")
set(TEST_DATA_PATH_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${OPT_DATA}")
message("From ${TEST_DATA_PATH_SRC} to ${TEST_DATA_PATH}")
string(REGEX REPLACE "[/\\:]" "_" DATA_TARGET_NAME "${TEST_DATA_PATH_SRC}")
if(UNIX)
# on unix we get the third / from the filename
set(TEST_DATA_URL "file://${TEST_DATA_PATH}")
if(WIN32)
add_executable(${name}_test ${OPT_SOURCES} ${TEST_RESOURCE_PATH}/UnitTest/test.rc)
else()
# we don't on windows, so we have to add it ourselves
set(TEST_DATA_URL "file:///${TEST_DATA_PATH}")
add_executable(${name}_test ${OPT_SOURCES})
endif()
if(NOT TARGET "${DATA_TARGET_NAME}")
add_custom_target(${DATA_TARGET_NAME})
add_dependencies(${name}_test ${DATA_TARGET_NAME})
add_custom_command(
TARGET ${DATA_TARGET_NAME}
COMMAND ${CMAKE_COMMAND} "-DTEST_DATA_URL=${TEST_DATA_URL}" -DSOURCE=${TEST_DATA_PATH_SRC} -DDESTINATION=${TEST_DATA_PATH} -P ${TEST_RESOURCE_PATH}/UnitTest/generate_test_data.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if(NOT "${OPT_DATA}" STREQUAL "")
set(TEST_DATA_PATH "${CMAKE_CURRENT_BINARY_DIR}/data")
set(TEST_DATA_PATH_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${OPT_DATA}")
message("From ${TEST_DATA_PATH_SRC} to ${TEST_DATA_PATH}")
string(REGEX REPLACE "[/\\:]" "_" DATA_TARGET_NAME "${TEST_DATA_PATH_SRC}")
if(UNIX)
# on unix we get the third / from the filename
set(TEST_DATA_URL "file://${TEST_DATA_PATH}")
else()
# we don't on windows, so we have to add it ourselves
set(TEST_DATA_URL "file:///${TEST_DATA_PATH}")
endif()
if(NOT TARGET "${DATA_TARGET_NAME}")
add_custom_target(${DATA_TARGET_NAME})
add_dependencies(${name}_test ${DATA_TARGET_NAME})
add_custom_command(
TARGET ${DATA_TARGET_NAME}
COMMAND ${CMAKE_COMMAND} "-DTEST_DATA_URL=${TEST_DATA_URL}" -DSOURCE=${TEST_DATA_PATH_SRC} -DDESTINATION=${TEST_DATA_PATH} -P ${TEST_RESOURCE_PATH}/UnitTest/generate_test_data.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
endif()
target_link_libraries(${name}_test Qt5::Test ${OPT_LIBS})
target_include_directories(${name}_test PRIVATE "${TEST_RESOURCE_PATH}/UnitTest/")
add_test(NAME ${name} COMMAND ${name}_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
target_link_libraries(${name}_test Qt5::Test ${OPT_LIBS})
target_include_directories(${name}_test PRIVATE "${TEST_RESOURCE_PATH}/UnitTest/")
add_test(NAME ${name} COMMAND ${name}_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endfunction()

30
flake.lock generated
View File

@ -3,11 +3,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1641205782,
"narHash": "sha256-4jY7RCWUoZ9cKD8co0/4tFARpWB+57+r1bLLvXNJliY=",
"lastModified": 1648199409,
"narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b7547d3eed6f32d06102ead8991ec52ab0a4f1a7",
"rev": "64a525ee38886ab9028e6f61790de0832aa3ef03",
"type": "github"
},
"original": {
@ -16,21 +16,6 @@
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"libnbtplusplus": {
"flake": false,
"locked": {
@ -49,16 +34,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1643169865,
"narHash": "sha256-+KIpNRazbc8Gac9jdWCKQkFv9bjceaLaLhlwqUEYu8c=",
"lastModified": 1648219316,
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "945ec499041db73043f745fad3b2a3a01e826081",
"rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
@ -82,7 +67,6 @@
"root": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"libnbtplusplus": "libnbtplusplus",
"nixpkgs": "nixpkgs",
"quazip": "quazip"

View File

@ -1,50 +1,34 @@
{
description = "PolyMC flake";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
inputs.libnbtplusplus = {
url = "github:multimc/libnbtplusplus";
flake = false;
};
inputs.quazip = {
url = "github:stachenov/quazip";
flake = false;
description = "A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once (Fork of MultiMC)";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
libnbtplusplus = { url = "github:multimc/libnbtplusplus"; flake = false; };
quazip = { url = "github:stachenov/quazip"; flake = false; };
};
outputs = args@{ self, nixpkgs, flake-utils, libnbtplusplus, quazip, ... }:
outputs = { self, nixpkgs, libnbtplusplus, quazip, ... }:
let
systems = [
"aarch64-linux"
# "aarch64-darwin" # qtbase is currently broken
"i686-linux"
"x86_64-darwin"
"x86_64-linux"
];
in {
overlay = final: prev: {
inherit (self.packages.${final.system}) polymc;
};
} // flake-utils.lib.eachSystem systems (system:
let pkgs = import nixpkgs { inherit system; };
in {
packages = {
polymc = pkgs.libsForQt5.callPackage ./packages/nix/polymc {
inherit self;
submoduleQuazip = quazip;
submoduleNbt = libnbtplusplus;
};
};
apps = {
polymc = flake-utils.lib.mkApp {
name = "polymc";
drv = self.packages.${system}.polymc;
};
};
defaultPackage = self.packages.${system}.polymc;
defaultApp = self.apps.${system}.polymc;
});
# Generate a user-friendly version number.
version = builtins.substring 0 8 self.lastModifiedDate;
# System types to support (qtbase is currently broken for "aarch64-darwin")
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" ];
# Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
# Nixpkgs instantiated for supported system types.
pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system});
in
{
packages = forAllSystems (system: { polymc = pkgs.${system}.libsForQt5.callPackage ./packages/nix/polymc { inherit version self quazip libnbtplusplus; }; });
defaultPackage = forAllSystems (system: self.packages.${system}.polymc);
apps = forAllSystems (system: { polymc = { type = "app"; program = "${self.defaultPackage.${system}}/bin/polymc"; }; });
defaultApp = forAllSystems (system: self.apps.${system}.polymc);
overlay = final: prev: { polymc = self.defaultPackage.${final.system}; };
};
}

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Application.h"
#include "BuildConfig.h"
@ -45,6 +80,7 @@
#include <QStringList>
#include <QDebug>
#include <QStyleFactory>
#include <QWindow>
#include "InstanceList.h"
@ -281,6 +317,26 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
QString origcwdPath = QDir::currentPath();
QString binPath = applicationDirPath();
{
// Root path is used for updates and portable data
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
QDir foo(FS::PathCombine(binPath, "..")); // typically portable-root or /usr
m_rootPath = foo.absolutePath();
#elif defined(Q_OS_WIN32)
m_rootPath = binPath;
#elif defined(Q_OS_MAC)
QDir foo(FS::PathCombine(binPath, "../.."));
m_rootPath = foo.absolutePath();
// on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues)
FS::updateTimestamp(m_rootPath);
#endif
#ifdef LAUNCHER_JARS_LOCATION
m_jarsPath = TOSTRING(LAUNCHER_JARS_LOCATION);
#endif
}
QString adjustedBy;
QString dataPath;
// change folder
@ -289,15 +345,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
{
// the dir param. it makes multimc data path point to whatever the user specified
// on command line
adjustedBy += "Command line " + dirParam;
adjustedBy = "Command line";
dataPath = dirParam;
}
else
{
#if !defined(LAUNCHER_PORTABLE) || defined(Q_OS_MAC)
QDir foo(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), ".."));
dataPath = foo.absolutePath();
adjustedBy += dataPath;
adjustedBy = "Persistent data path";
#ifdef Q_OS_LINUX
// TODO: this should be removed in a future version
@ -305,12 +360,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
QDir bar(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "polymc"));
if (bar.exists()) {
dataPath = bar.absolutePath();
adjustedBy += "Legacy data path " + dataPath;
adjustedBy = "Legacy data path";
}
#endif
#else
dataPath = applicationDirPath();
adjustedBy += "Fallback to binary path " + dataPath;
#ifndef Q_OS_MACOS
if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
dataPath = m_rootPath;
adjustedBy = "Portable data path";
}
#endif
}
@ -500,24 +558,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
qDebug() << "<> Log initialized.";
}
// Set up paths
{
// Root path is used for updates.
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
QDir foo(FS::PathCombine(binPath, ".."));
m_rootPath = foo.absolutePath();
#elif defined(Q_OS_WIN32)
m_rootPath = binPath;
#elif defined(Q_OS_MAC)
QDir foo(FS::PathCombine(binPath, "../.."));
m_rootPath = foo.absolutePath();
// on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues)
FS::updateTimestamp(m_rootPath);
#endif
#ifdef MULTIMC_JARS_LOCATION
m_jarsPath = TOSTRING(MULTIMC_JARS_LOCATION);
#endif
qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT;
qDebug() << "Version : " << BuildConfig.printableVersionString();
@ -575,12 +616,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system"));
// Notifications
m_settings->registerSetting("ShownNotifications", QString());
// Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
m_settings->registerSetting("MenuBarInsteadOfToolBar", false);
QString defaultMonospace;
int defaultSize = 11;
#ifdef Q_OS_WIN32
@ -650,6 +690,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("JavaVendor", "");
m_settings->registerSetting("LastHostname", "");
m_settings->registerSetting("JvmArgs", "");
m_settings->registerSetting("IgnoreJavaCompatibility", false);
// Native library workarounds
m_settings->registerSetting("UseNativeOpenAL", false);
@ -663,6 +704,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Minecraft launch method
m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
// Minecraft offline player name
m_settings->registerSetting("LastOfflinePlayerName", "");
// Wrapper command for launch
m_settings->registerSetting("WrapperCommand", "");
@ -695,6 +739,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("PastebinURL", "https://0x0.st");
m_settings->registerSetting("CloseAfterLaunch", false);
m_settings->registerSetting("QuitAfterGameStop", false);
// Custom MSA credentials
m_settings->registerSetting("MSAClientIDOverride", "");
@ -1107,6 +1152,15 @@ std::vector<ITheme *> Application::getValidApplicationThemes()
return ret;
}
bool Application::isFlatpak()
{
#ifdef Q_OS_LINUX
return QFile::exists("/.flatpak-info");
#else
return false;
#endif
}
void Application::setApplicationTheme(const QString& name, bool initial)
{
auto systemPalette = qApp->palette();
@ -1222,6 +1276,12 @@ bool Application::kill(InstancePtr instance)
return true;
}
void Application::closeCurrentWindow()
{
if (focusWindow())
focusWindow()->close();
}
void Application::addRunningInstance()
{
m_runningInstances ++;
@ -1494,10 +1554,10 @@ QString Application::getJarsPath()
{
return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
}
return m_jarsPath;
return FS::PathCombine(m_rootPath, m_jarsPath);
}
QString Application::getMSAClientID()
QString Application::getMSAClientID()
{
QString clientIDOverride = m_settings->get("MSAClientIDOverride").toString();
if (!clientIDOverride.isEmpty()) {

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QApplication>
@ -69,6 +104,8 @@ public:
QIcon getThemedIcon(const QString& name);
bool isFlatpak();
void setIconTheme(const QString& name);
std::vector<ITheme *> getValidApplicationThemes();
@ -152,6 +189,7 @@ public slots:
MinecraftAccountPtr accountToUse = nullptr
);
bool kill(InstancePtr instance);
void closeCurrentWindow();
private slots:
void on_windowClose();

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "BaseInstance.h"

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

View File

@ -144,6 +144,8 @@ set(LAUNCH_SOURCES
launch/steps/TextPrint.h
launch/steps/Update.cpp
launch/steps/Update.h
launch/steps/QuitAfterGameStop.cpp
launch/steps/QuitAfterGameStop.h
launch/LaunchStep.cpp
launch/LaunchStep.h
launch/LaunchTask.cpp
@ -174,13 +176,6 @@ add_unit_test(DownloadTask
DATA updater/testdata
)
# Rarely used notifications
set(NOTIFICATIONS_SOURCES
# Notifications - short warning messages
notifications/NotificationChecker.h
notifications/NotificationChecker.cpp
)
# Backend for the news bar... there's usually no news.
set(NEWS_SOURCES
# News System
@ -353,28 +348,30 @@ set(MINECRAFT_SOURCES
mojang/PackageManifest.h
mojang/PackageManifest.cpp
)
minecraft/Agent.h)
add_unit_test(GradleSpecifier
SOURCES minecraft/GradleSpecifier_test.cpp
LIBS Launcher_logic
)
add_executable(PackageManifest
mojang/PackageManifest_test.cpp
)
target_link_libraries(PackageManifest
Launcher_logic
Qt5::Test
)
target_include_directories(PackageManifest
PRIVATE ../cmake/UnitTest/
)
add_test(
NAME PackageManifest
COMMAND PackageManifest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if(BUILD_TESTING)
add_executable(PackageManifest
mojang/PackageManifest_test.cpp
)
target_link_libraries(PackageManifest
Launcher_logic
Qt5::Test
)
target_include_directories(PackageManifest
PRIVATE ../cmake/UnitTest/
)
add_test(
NAME PackageManifest
COMMAND PackageManifest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
add_unit_test(MojangVersionFormat
SOURCES minecraft/MojangVersionFormat_test.cpp
@ -416,6 +413,11 @@ set(TASKS_SOURCES
tasks/SequentialTask.cpp
)
add_unit_test(Task
SOURCES tasks/Task_test.cpp
LIBS Launcher_logic
)
set(SETTINGS_SOURCES
# Settings
settings/INIFile.cpp
@ -492,6 +494,16 @@ set(META_SOURCES
meta/Index.h
)
set(API_SOURCES
modplatform/ModAPI.h
modplatform/flame/FlameAPI.h
modplatform/modrinth/ModrinthAPI.h
modplatform/helpers/NetworkModAPI.h
modplatform/helpers/NetworkModAPI.cpp
)
set(FTB_SOURCES
modplatform/legacy_ftb/PackFetchTask.h
modplatform/legacy_ftb/PackFetchTask.cpp
@ -532,6 +544,8 @@ set(TECHNIC_SOURCES
modplatform/technic/SingleZipPackInstallTask.cpp
modplatform/technic/SolderPackInstallTask.h
modplatform/technic/SolderPackInstallTask.cpp
modplatform/technic/SolderPackManifest.h
modplatform/technic/SolderPackManifest.cpp
modplatform/technic/TechnicPackProcessor.h
modplatform/technic/TechnicPackProcessor.cpp
)
@ -561,7 +575,6 @@ set(LOGIC_SOURCES
${NET_SOURCES}
${LAUNCH_SOURCES}
${UPDATE_SOURCES}
${NOTIFICATIONS_SOURCES}
${NEWS_SOURCES}
${MINECRAFT_SOURCES}
${SCREENSHOTS_SOURCES}
@ -572,6 +585,7 @@ set(LOGIC_SOURCES
${TOOLS_SOURCES}
${META_SOURCES}
${ICONS_SOURCES}
${API_SOURCES}
${FTB_SOURCES}
${FLAME_SOURCES}
${MODRINTH_SOURCES}
@ -721,6 +735,11 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/VanillaPage.cpp
ui/pages/modplatform/VanillaPage.h
ui/pages/modplatform/ModPage.cpp
ui/pages/modplatform/ModPage.h
ui/pages/modplatform/ModModel.cpp
ui/pages/modplatform/ModModel.h
ui/pages/modplatform/atlauncher/AtlFilterModel.cpp
ui/pages/modplatform/atlauncher/AtlFilterModel.h
ui/pages/modplatform/atlauncher/AtlListModel.cpp
@ -791,12 +810,12 @@ SET(LAUNCHER_SOURCES
ui/dialogs/NewComponentDialog.h
ui/dialogs/NewInstanceDialog.cpp
ui/dialogs/NewInstanceDialog.h
ui/dialogs/NotificationDialog.cpp
ui/dialogs/NotificationDialog.h
ui/pagedialog/PageDialog.cpp
ui/pagedialog/PageDialog.h
ui/dialogs/ProgressDialog.cpp
ui/dialogs/ProgressDialog.h
ui/dialogs/ReviewMessageBox.cpp
ui/dialogs/ReviewMessageBox.h
ui/dialogs/UpdateDialog.cpp
ui/dialogs/UpdateDialog.h
ui/dialogs/VersionSelectDialog.cpp
@ -806,7 +825,6 @@ SET(LAUNCHER_SOURCES
ui/dialogs/ModDownloadDialog.cpp
ui/dialogs/ModDownloadDialog.h
# GUI - widgets
ui/widgets/Common.cpp
ui/widgets/Common.h
@ -830,6 +848,8 @@ SET(LAUNCHER_SOURCES
ui/widgets/LogView.h
ui/widgets/MCModInfoFrame.cpp
ui/widgets/MCModInfoFrame.h
ui/widgets/ModFilterWidget.cpp
ui/widgets/ModFilterWidget.h
ui/widgets/ModListView.cpp
ui/widgets/ModListView.h
ui/widgets/PageContainer.cpp
@ -879,21 +899,20 @@ qt5_wrap_ui(LAUNCHER_UI
ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
ui/pages/modplatform/atlauncher/AtlPage.ui
ui/pages/modplatform/VanillaPage.ui
ui/pages/modplatform/ModPage.ui
ui/pages/modplatform/flame/FlamePage.ui
ui/pages/modplatform/flame/FlameModPage.ui
ui/pages/modplatform/legacy_ftb/Page.ui
ui/pages/modplatform/ImportPage.ui
ui/pages/modplatform/ftb/FtbPage.ui
ui/pages/modplatform/technic/TechnicPage.ui
ui/pages/modplatform/modrinth/ModrinthPage.ui
ui/widgets/InstanceCardWidget.ui
ui/widgets/CustomCommands.ui
ui/widgets/MCModInfoFrame.ui
ui/widgets/ModFilterWidget.ui
ui/dialogs/CopyInstanceDialog.ui
ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui
ui/dialogs/NewInstanceDialog.ui
ui/dialogs/NotificationDialog.ui
ui/dialogs/UpdateDialog.ui
ui/dialogs/NewComponentDialog.ui
ui/dialogs/ProfileSelectDialog.ui
@ -905,6 +924,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/AboutDialog.ui
ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui
ui/dialogs/ReviewMessageBox.ui
)
qt5_add_resources(LAUNCHER_RESOURCES
@ -949,8 +969,8 @@ target_link_libraries(Launcher_logic
Launcher_iconfix
QuaZip::QuaZip
hoedown
PolyMC_rainbow
LocalPeer
Launcher_rainbow
)
target_link_libraries(Launcher_logic)
@ -971,7 +991,7 @@ if(DEFINED Launcher_APP_BINARY_DEFS)
endif()
install(TARGETS ${Launcher_Name}
BUNDLE DESTINATION ${BUNDLE_DEST_DIR} COMPONENT Runtime
BUNDLE DESTINATION "." COMPONENT Runtime
LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
)
@ -992,7 +1012,7 @@ if(INSTALL_BUNDLE STREQUAL "full")
DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "tga|tiff|mng|webp" EXCLUDE
REGEX "tga|tiff|mng" EXCLUDE
)
# Icon engines
install(
@ -1022,7 +1042,7 @@ if(INSTALL_BUNDLE STREQUAL "full")
DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "tga|tiff|mng|webp" EXCLUDE
REGEX "tga|tiff|mng" EXCLUDE
REGEX "d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE

View File

@ -1,8 +1,43 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 dada513 <dada513@protonmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2022 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "DesktopServices.h"
#include <QDir>
#include <QDesktopServices>
#include <QProcess>
#include <QDebug>
#include "Application.h"
/**
* This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing.
@ -84,7 +119,14 @@ bool openDirectory(const QString &path, bool ensureExists)
return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else
return f();
#endif
@ -98,7 +140,14 @@ bool openFile(const QString &path)
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else
return f();
#endif
@ -109,10 +158,17 @@ bool openFile(const QString &application, const QString &path, const QString &wo
qDebug() << "Opening file" << path << "using" << application;
#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([&]()
if(!APPLICATION->isFlatpak())
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory);
}, pid);
return IndirectOpen([&]()
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
}
#else
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
#endif
@ -122,11 +178,18 @@ bool run(const QString &application, const QStringList &args, const QString &wor
{
qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak())
{
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]()
{
return QProcess::startDetached(application, args, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, args, workingDirectory, pid);
}
#else
return QProcess::startDetached(application, args, workingDirectory, pid);
#endif
@ -140,7 +203,14 @@ bool openUrl(const QUrl &url)
return QDesktopServices::openUrl(url);
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f);
if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else
return f();
#endif

View File

@ -9,6 +9,15 @@
InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version)
{
m_version = version;
m_usingLoader = false;
}
InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loaderVersion)
{
m_version = version;
m_usingLoader = true;
m_loader = loader;
m_loaderVersion = loaderVersion;
}
void InstanceCreationTask::executeTask()
@ -21,6 +30,8 @@ void InstanceCreationTask::executeTask()
auto components = inst.getPackProfile();
components->buildingFromScratch();
components->setComponentVersion("net.minecraft", m_version->descriptor(), true);
if(m_usingLoader)
components->setComponentVersion(m_loader, m_loaderVersion->descriptor(), true);
inst.setName(m_instName);
inst.setIconKey(m_instIcon);
instanceSettings->resumeSave();

View File

@ -12,6 +12,7 @@ class InstanceCreationTask : public InstanceTask
Q_OBJECT
public:
explicit InstanceCreationTask(BaseVersionPtr version);
explicit InstanceCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loaderVersion);
protected:
//! Entry point for tasks.
@ -19,4 +20,7 @@ protected:
private: /* data */
BaseVersionPtr m_version;
bool m_usingLoader;
QString m_loader;
BaseVersionPtr m_loaderVersion;
};

View File

@ -40,6 +40,14 @@ InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)
m_sourceUrl = sourceUrl;
}
bool InstanceImportTask::abort()
{
m_filesNetJob->abort();
m_extractFuture.cancel();
return false;
}
void InstanceImportTask::executeTask()
{
if (m_sourceUrl.isLocalFile())
@ -241,6 +249,7 @@ void InstanceImportTask::processFlame()
QString forgeVersion;
QString fabricVersion;
// TODO: is Quilt relevant here?
for(auto &loader: pack.minecraft.modLoaders)
{
auto id = loader.id;
@ -283,7 +292,7 @@ void InstanceImportTask::processFlame()
}
else
{
logWarning(tr("Could not map recommended forge version for Minecraft %1").arg(mcVersion));
logWarning(tr("Could not map recommended Forge version for Minecraft %1").arg(mcVersion));
}
}
components->setComponentVersion("net.minecraftforge", forgeVersion);

View File

@ -37,6 +37,9 @@ class InstanceImportTask : public InstanceTask
public:
explicit InstanceImportTask(const QUrl sourceUrl);
bool canAbort() const override { return true; }
bool abort() override;
protected:
//! Entry point for tasks.
virtual void executeTask() override;

View File

@ -8,7 +8,7 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
|| jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize"))
{
auto warnStr = QObject::tr(
"You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n"
"You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n"
"There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n"
"This message will be displayed until you remove them from the JVM arguments.");
CustomMessageBox::selectable(
@ -17,6 +17,17 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
QMessageBox::Warning)->exec();
return false;
}
// block lunacy with passing required version to the JVM
if (jvmargs.contains(QRegExp("-version:.*"))) {
auto warnStr = QObject::tr(
"You tried to pass required Java version argument to the JVM (using \"-version:xxx\"). This is not safe and will not be allowed.\n"
"This message will be displayed until you remove this from the JVM arguments.");
CustomMessageBox::selectable(
parent, QObject::tr("JVM arguments warning"),
warnStr,
QMessageBox::Warning)->exec();
return false;
}
return true;
}
@ -40,7 +51,7 @@ void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result)
auto htmlError = result.errorLog;
QString text;
htmlError.replace('\n', "<br />");
text += QObject::tr("The specified java binary didn't work with the arguments you provided:<br />");
text += QObject::tr("The specified Java binary didn't work with the arguments you provided:<br />");
text += QString("<font color=\"red\">%1</font>").arg(htmlError);
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
}
@ -49,8 +60,8 @@ void JavaCommon::javaBinaryWasBad(QWidget *parent, JavaCheckResult result)
{
QString text;
text += QObject::tr(
"The specified java binary didn't work.<br />You should use the auto-detect feature, "
"or set the path to the java executable.<br />");
"The specified Java binary didn't work.<br />You should use the auto-detect feature, "
"or set the path to the Java executable.<br />");
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
}

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LaunchController.h"
#include "minecraft/auth/AccountList.h"
#include "Application.h"
@ -36,7 +71,10 @@ void LaunchController::executeTask()
return;
}
JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget);
if(!JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget)) {
emitFailed(tr("Invalid Java arguments specified. Please fix this first."));
return;
}
login();
}
@ -131,13 +169,14 @@ void LaunchController::login() {
if(!m_session->wants_online) {
// we ask the user for a player name
bool ok = false;
QString usedname = m_session->player_name;
QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString();
QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName;
QString name = QInputDialog::getText(
m_parentWidget,
tr("Player name"),
tr("Choose your offline mode player name."),
QLineEdit::Normal,
m_session->player_name,
usedname,
&ok
);
if (!ok)
@ -148,6 +187,7 @@ void LaunchController::login() {
if (name.length())
{
usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname);
}
m_session->MakeOffline(usedname);
// offline flavored game from here :3

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QObject>
#include <BaseInstance.h>

View File

@ -21,7 +21,7 @@ echo "Launcher Dir: ${LAUNCHER_DIR}"
# Set up env - filter out input LD_ variables but pass them in under different names
export GAME_LIBRARY_PATH=${GAME_LIBRARY_PATH-${LD_LIBRARY_PATH}}
export GAME_PRELOAD=${GAME_PRELOAD-${LD_PRELOAD}}
export LD_LIBRARY_PATH="${LAUNCHER_DIR}/bin":$LAUNCHER_LIBRARY_PATH
export LD_LIBRARY_PATH="${LAUNCHER_DIR}/lib@LIB_SUFFIX@":$LAUNCHER_LIBRARY_PATH
export LD_PRELOAD=$LAUNCHER_PRELOAD
export QT_PLUGIN_PATH="${LAUNCHER_DIR}/plugins"
export QT_FONTPATH="${LAUNCHER_DIR}/fonts"

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <quazip/quazip.h>

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

View File

@ -129,7 +129,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
auto os_arch = results["os.arch"];
auto java_version = results["java.version"];
auto java_vendor = results["java.vendor"];
bool is_64 = os_arch == "x86_64" || os_arch == "amd64";
bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64";
result.validity = JavaCheckResult::Validity::Valid;

View File

@ -183,7 +183,7 @@ void JavaListLoadTask::javaCheckerFinished()
JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = result.javaVersion;
javaVersion->arch = result.mojangPlatform;
javaVersion->arch = result.realPlatform;
javaVersion->path = result.path;
candidates.append(javaVersion);

View File

@ -153,7 +153,7 @@ QStringList addJavasFromEnv(QList<QString> javas)
{
QByteArray env = qgetenv("POLYMC_JAVA_PATHS");
#if defined(Q_OS_WIN32)
QList<QString> javaPaths = QString::fromLocal8Bit(env).split(QLatin1String(";"));
QList<QString> javaPaths = QString::fromLocal8Bit(env).replace("\\", "/").split(QLatin1String(";"));
#else
QList<QString> javaPaths = QString::fromLocal8Bit(env).split(QLatin1String(":"));
#endif
@ -355,7 +355,7 @@ QList<QString> JavaUtils::FindJavaPaths()
}
}
return candidates;
return addJavasFromEnv(candidates);
}
#elif defined(Q_OS_MAC)

View File

@ -1,18 +1,38 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* http://www.apache.org/licenses/LICENSE-2.0
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "launch/LaunchTask.h"
@ -212,7 +232,7 @@ shared_qobject_ptr<LogModel> LaunchTask::getLogModel()
m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
// FIXME: should this really be here?
m_logModel->setOverflowMessage(tr("PolyMC stopped watching the game log because the log length surpassed %1 lines.\n"
m_logModel->setOverflowMessage(tr("Stopped watching the game log because the log length surpassed %1 lines.\n"
"You may have to fix your mods because the game is still logging to files and"
" likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines()));
}

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "CheckJava.h"
@ -87,14 +107,14 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
// Error message displayed if java can't start
emit logLine(QString("Could not start java:"), MessageLevel::Error);
emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
emit logLine("\nCheck your PolyMC Java settings.", MessageLevel::Launcher);
emit logLine(QString("\nCheck your Java settings."), MessageLevel::Launcher);
printSystemInfo(false, false);
emitFailed(QString("Could not start java!"));
return;
}
case JavaCheckResult::Validity::ReturnedInvalidData:
{
emit logLine(QString("Java checker returned some invalid data PolyMC doesn't understand:"), MessageLevel::Error);
emit logLine(QString("Java checker returned some invalid data we don't understand:"), MessageLevel::Error);
emit logLines(result.outLog.split('\n'), MessageLevel::Warning);
emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher);
printSystemInfo(false, false);
@ -104,7 +124,8 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
case JavaCheckResult::Validity::Valid:
{
auto instance = m_parent->instance();
printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.javaVendor);
printJavaInfo(result.javaVersion.toString(), result.realPlatform, result.javaVendor);
printSystemInfo(true, result.is_64bit);
instance->settings()->set("JavaVersion", result.javaVersion.toString());
instance->settings()->set("JavaArchitecture", result.mojangPlatform);
instance->settings()->set("JavaVendor", result.javaVendor);
@ -117,8 +138,7 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString & vendor)
{
emit logLine(QString("Java is version %1, using %2-bit architecture, from %3.\n\n").arg(version, architecture, vendor), MessageLevel::Launcher);
printSystemInfo(true, architecture == "64");
emit logLine(QString("Java is version %1, using %2 architecture, from %3.\n\n").arg(version, architecture, vendor), MessageLevel::Launcher);
}
void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit)

View File

@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 dada513 <dada513@protonmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "QuitAfterGameStop.h"
#include <launch/LaunchTask.h>
#include "Application.h"
void QuitAfterGameStop::executeTask()
{
APPLICATION->quit();
}

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 dada513 <dada513@protonmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <launch/LaunchStep.h>
class QuitAfterGameStop: public LaunchStep
{
Q_OBJECT
public:
explicit QuitAfterGameStop(LaunchTask *parent) :LaunchStep(parent){};
virtual ~QuitAfterGameStop() {};
virtual void executeTask();
virtual bool canAbort() const
{
return false;
}
};

View File

@ -29,6 +29,10 @@ int main(int argc, char *argv[])
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
// initialize Qt
Application app(argc, argv);

View File

@ -0,0 +1,36 @@
#pragma once
#include <QString>
#include "Library.h"
class Agent;
typedef std::shared_ptr<Agent> AgentPtr;
class Agent {
public:
Agent(LibraryPtr library, QString &argument)
{
m_library = library;
m_argument = argument;
}
public: /* methods */
LibraryPtr library() {
return m_library;
}
QString argument() {
return m_argument;
}
protected: /* data */
/// The library pointing to the jar this Java agent is contained within
LibraryPtr m_library;
/// The argument to the Java agent, passed after an = if present
QString m_argument;
};

View File

@ -591,7 +591,7 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
{
component->m_version = "3.1.2";
}
else if (add.uid == "net.fabricmc.intermediary")
else if (add.uid == "net.fabricmc.intermediary" || add.uid == "org.quiltmc.hashed")
{
auto minecraft = std::find_if(components.begin(), components.end(), [](ComponentPtr & cmp){
return cmp->getID() == "net.minecraft";

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LaunchProfile.h"
#include <Version.h>
@ -7,11 +42,13 @@ void LaunchProfile::clear()
m_minecraftVersionType.clear();
m_minecraftAssets.reset();
m_minecraftArguments.clear();
m_addnJvmArguments.clear();
m_tweakers.clear();
m_mainClass.clear();
m_appletClass.clear();
m_libraries.clear();
m_mavenFiles.clear();
m_agents.clear();
m_traits.clear();
m_jarMods.clear();
m_mainJar.reset();
@ -45,6 +82,11 @@ void LaunchProfile::applyMinecraftArguments(const QString& minecraftArguments)
applyString(minecraftArguments, this->m_minecraftArguments);
}
void LaunchProfile::applyAddnJvmArguments(const QStringList& addnJvmArguments)
{
this->m_addnJvmArguments.append(addnJvmArguments);
}
void LaunchProfile::applyMinecraftVersionType(const QString& type)
{
applyString(type, this->m_minecraftVersionType);
@ -126,6 +168,11 @@ void LaunchProfile::applyMods(const QList<LibraryPtr>& mods)
}
}
void LaunchProfile::applyCompatibleJavaMajors(QList<int>& javaMajor)
{
m_compatibleJavaMajors.append(javaMajor);
}
void LaunchProfile::applyLibrary(LibraryPtr library)
{
if(!library->isActive())
@ -174,6 +221,22 @@ void LaunchProfile::applyMavenFile(LibraryPtr mavenFile)
m_mavenFiles.append(Library::limitedCopy(mavenFile));
}
void LaunchProfile::applyAgent(AgentPtr agent)
{
auto lib = agent->library();
if(!lib->isActive())
{
return;
}
if(lib->isNative())
{
return;
}
m_agents.append(agent);
}
const LibraryPtr LaunchProfile::getMainJar() const
{
return m_mainJar;
@ -255,6 +318,11 @@ QString LaunchProfile::getMinecraftArguments() const
return m_minecraftArguments;
}
const QStringList & LaunchProfile::getAddnJvmArguments() const
{
return m_addnJvmArguments;
}
const QList<LibraryPtr> & LaunchProfile::getJarMods() const
{
return m_jarMods;
@ -275,6 +343,16 @@ const QList<LibraryPtr> & LaunchProfile::getMavenFiles() const
return m_mavenFiles;
}
const QList<AgentPtr> & LaunchProfile::getAgents() const
{
return m_agents;
}
const QList<int> & LaunchProfile::getCompatibleJavaMajors() const
{
return m_compatibleJavaMajors;
}
void LaunchProfile::getLibraryFiles(
const QString& architecture,
QStringList& jars,

View File

@ -1,6 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QString>
#include "Library.h"
#include "Agent.h"
#include <ProblemProvider.h>
class LaunchProfile: public ProblemProvider
@ -13,6 +49,7 @@ public: /* application of profile variables from patches */
void applyMainClass(const QString& mainClass);
void applyAppletClass(const QString& appletClass);
void applyMinecraftArguments(const QString& minecraftArguments);
void applyAddnJvmArguments(const QStringList& minecraftArguments);
void applyMinecraftVersionType(const QString& type);
void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
void applyTraits(const QSet<QString> &traits);
@ -21,6 +58,8 @@ public: /* application of profile variables from patches */
void applyMods(const QList<LibraryPtr> &jarMods);
void applyLibrary(LibraryPtr library);
void applyMavenFile(LibraryPtr library);
void applyAgent(AgentPtr agent);
void applyCompatibleJavaMajors(QList<int>& javaMajor);
void applyMainJar(LibraryPtr jar);
void applyProblemSeverity(ProblemSeverity severity);
/// clear the profile
@ -33,12 +72,15 @@ public: /* getters for profile variables */
QString getMinecraftVersionType() const;
MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
QString getMinecraftArguments() const;
const QStringList & getAddnJvmArguments() const;
const QSet<QString> & getTraits() const;
const QStringList & getTweakers() const;
const QList<LibraryPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const;
const QList<LibraryPtr> & getNativeLibraries() const;
const QList<LibraryPtr> & getMavenFiles() const;
const QList<AgentPtr> & getAgents() const;
const QList<int> & getCompatibleJavaMajors() const;
const LibraryPtr getMainJar() const;
void getLibraryFiles(
const QString & architecture,
@ -69,6 +111,12 @@ private:
*/
QString m_minecraftArguments;
/**
* Additional arguments to pass to the JVM in addition to those the user has configured,
* memory settings, etc.
*/
QStringList m_addnJvmArguments;
/// A list of all tweaker classes
QStringList m_tweakers;
@ -84,6 +132,9 @@ private:
/// the list of maven files to be placed in the libraries folder, but not acted upon
QList<LibraryPtr> m_mavenFiles;
/// the list of java agents to add to JVM arguments
QList<AgentPtr> m_agents;
/// the main jar
LibraryPtr m_mainJar;
@ -99,6 +150,9 @@ private:
/// the list of mods
QList<LibraryPtr> m_mods;
/// compatible java major versions
QList<int> m_compatibleJavaMajors;
ProblemSeverity m_problemSeverity = ProblemSeverity::None;
};

View File

@ -1,4 +1,40 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MinecraftInstance.h"
#include "BuildConfig.h"
#include "minecraft/launch/CreateGameFolders.h"
#include "minecraft/launch/ExtractNatives.h"
#include "minecraft/launch/PrintInstanceInfo.h"
@ -20,6 +56,7 @@
#include "launch/steps/PreLaunchCommand.h"
#include "launch/steps/TextPrint.h"
#include "launch/steps/CheckJava.h"
#include "launch/steps/QuitAfterGameStop.h"
#include "minecraft/launch/LauncherPartLaunch.h"
#include "minecraft/launch/DirectJavaLaunch.h"
@ -88,6 +125,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
m_settings->registerOverride(globalSettings->getSetting("IgnoreJavaCompatibility"), javaOrLocation);
// special!
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
@ -175,8 +213,12 @@ QString MinecraftInstance::binRoot() const
QString MinecraftInstance::getNativePath() const
{
#ifdef Q_OS_FREEBSD
QDir natives_dir("/usr/local/lib/lwjgl/");
#else
QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
return natives_dir.absolutePath();
#endif
}
QString MinecraftInstance::getLocalLibraryPath() const
@ -292,6 +334,17 @@ QStringList MinecraftInstance::extraArguments() const
list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
"-Dfml.ignorePatchDiscrepancies=true"});
}
auto addn = m_components->getProfile()->getAddnJvmArguments();
if (!addn.isEmpty()) {
list.append(addn);
}
auto agents = m_components->getProfile()->getAgents();
for (auto agent : agents)
{
QStringList jar, temp1, temp2, temp3;
agent->library()->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, getLocalLibraryPath());
list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument()));
}
return list;
}
@ -434,7 +487,7 @@ QStringList MinecraftInstance::processMinecraftArgs(
}
// blatant self-promotion.
token_mapping["profile_name"] = token_mapping["version_name"] = "PolyMC";
token_mapping["profile_name"] = token_mapping["version_name"] = BuildConfig.LAUNCHER_NAME;
token_mapping["version_type"] = profile->getMinecraftVersionType();
@ -935,6 +988,11 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
{
process->setCensorFilter(createCensorFilterFromSession(session));
}
if(APPLICATION->settings()->get("QuitAfterGameStop").toBool())
{
auto step = new QuitAfterGameStop(pptr);
process->appendStep(step);
}
m_launchProcess = process;
emit launchTaskChanged(m_launchProcess);
return m_launchProcess;

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MojangVersionFormat.h"
#include "OneSixVersionFormat.h"
#include "MojangDownloadInfo.h"
@ -183,6 +218,15 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
);
}
}
if (in.contains("compatibleJavaMajors"))
{
for (auto compatible : requireArray(in.value("compatibleJavaMajors")))
{
out->compatibleJavaMajors.append(requireInteger(compatible));
}
}
if(in.contains("downloads"))
{
auto downloadsObj = requireObject(in, "downloads");

View File

@ -1,5 +1,6 @@
#include "OneSixVersionFormat.h"
#include <Json.h>
#include "minecraft/Agent.h"
#include "minecraft/ParseUtils.h"
#include <minecraft/MojangVersionFormat.h>
@ -108,6 +109,14 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
}
}
if (root.contains("+jvmArgs"))
{
for (auto arg : requireArray(root.value("+jvmArgs")))
{
out->addnJvmArguments.append(requireString(arg));
}
}
if (root.contains("jarMods"))
{
@ -176,6 +185,21 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
readLibs("mavenFiles", out->mavenFiles);
}
if(root.contains("+agents")) {
for (auto agentVal : requireArray(root.value("+agents")))
{
QJsonObject agentObj = requireObject(agentVal);
auto lib = libraryFromJson(*out, agentObj, filename);
QString arg = "";
if (agentObj.contains("argument"))
{
readString(agentObj, "argument", arg);
}
AgentPtr agent(new Agent(lib, arg));
out->agents.append(agent);
}
}
// if we have mainJar, just use it
if(root.contains("mainJar"))
{

View File

@ -970,3 +970,20 @@ void PackProfile::disableInteraction(bool disable)
}
}
}
ModAPI::ModLoaderType PackProfile::getModLoader()
{
if (!getComponentVersion("net.minecraftforge").isEmpty())
{
return ModAPI::Forge;
}
else if (!getComponentVersion("net.fabricmc.fabric-loader").isEmpty())
{
return ModAPI::Fabric;
}
else if (!getComponentVersion("org.quiltmc.quilt-loader").isEmpty())
{
return ModAPI::Quilt;
}
return ModAPI::Unspecified;
}

View File

@ -28,6 +28,7 @@
#include "BaseVersion.h"
#include "MojangDownloadInfo.h"
#include "net/Mode.h"
#include "modplatform/ModAPI.h"
class MinecraftInstance;
struct PackProfileData;
@ -117,6 +118,8 @@ public:
// todo(merged): is this the best approach
void appendComponent(ComponentPtr component);
ModAPI::ModLoaderType getModLoader();
private:
void scheduleSave();
bool saveIsScheduled() const;

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <QJsonArray>
#include <QJsonDocument>
@ -32,10 +67,12 @@ void VersionFile::applyTo(LaunchProfile *profile)
profile->applyMainClass(mainClass);
profile->applyAppletClass(appletClass);
profile->applyMinecraftArguments(minecraftArguments);
profile->applyAddnJvmArguments(addnJvmArguments);
profile->applyTweakers(addTweakers);
profile->applyJarMods(jarMods);
profile->applyMods(mods);
profile->applyTraits(traits);
profile->applyCompatibleJavaMajors(compatibleJavaMajors);
for (auto library : libraries)
{
@ -45,6 +82,10 @@ void VersionFile::applyTo(LaunchProfile *profile)
{
profile->applyMavenFile(mavenFile);
}
for (auto agent : agents)
{
profile->applyAgent(agent);
}
profile->applyProblemSeverity(getProblemSeverity());
}

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QString>
@ -10,6 +45,7 @@
#include "minecraft/Rule.h"
#include "ProblemProvider.h"
#include "Library.h"
#include "Agent.h"
#include <meta/JsonFormat.h>
class PackProfile;
@ -57,6 +93,12 @@ public: /* data */
/// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
QString minecraftArguments;
/// PolyMC: Additional JVM launch arguments
QStringList addnJvmArguments;
/// Mojang: list of compatible java majors
QList<int> compatibleJavaMajors;
/// Mojang: type of the Minecraft version
QString type;
@ -78,6 +120,9 @@ public: /* data */
/// PolyMC: list of maven files to put in the libraries folder, but not in classpath
QList<LibraryPtr> mavenFiles;
/// PolyMC: list of agents to add to JVM arguments
QList<AgentPtr> agents;
/// The main jar (Minecraft version library, normally)
LibraryPtr mainJar;

View File

@ -17,6 +17,7 @@
#include <QString>
#include <QDebug>
#include <QSaveFile>
#include <QDirIterator>
#include "World.h"
#include "GZip.h"
@ -187,6 +188,26 @@ bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data)
return f.commit();
}
int64_t calculateWorldSize(const QFileInfo &file)
{
if (file.isFile() && file.suffix() == "zip")
{
return file.size();
}
else if(file.isDir())
{
QDirIterator it(file.absoluteFilePath(), QDir::Files, QDirIterator::Subdirectories);
int64_t total = 0;
while (it.hasNext())
{
total += it.fileInfo().size();
it.next();
}
return total;
}
return -1;
}
World::World(const QFileInfo &file)
{
repath(file);
@ -196,6 +217,7 @@ void World::repath(const QFileInfo &file)
{
m_containerFile = file;
m_folderName = file.fileName();
m_size = calculateWorldSize(file);
if(file.isFile() && file.suffix() == "zip")
{
m_iconFile = QString();
@ -482,6 +504,7 @@ void World::loadFromLevelDat(QByteArray data)
if(randomSeed) {
qDebug() << "Seed:" << *randomSeed;
}
qDebug() << "Size:" << m_size;
qDebug() << "GameType:" << m_gameType.toLogString();
}

View File

@ -52,6 +52,10 @@ public:
{
return m_iconFile;
}
int64_t bytes() const
{
return m_size;
}
QDateTime lastPlayed() const
{
return m_lastPlayed;
@ -105,6 +109,7 @@ protected:
QString m_iconFile;
QDateTime levelDatTime;
QDateTime m_lastPlayed;
int64_t m_size;
int64_t m_randomSeed = 0;
GameType m_gameType;
bool is_valid = false;

View File

@ -14,6 +14,8 @@
*/
#include "WorldList.h"
#include "Application.h"
#include <FileSystem.h>
#include <QMimeData>
#include <QUrl>
@ -150,7 +152,7 @@ bool WorldList::resetIcon(int row)
int WorldList::columnCount(const QModelIndex &parent) const
{
return 3;
return 4;
}
QVariant WorldList::data(const QModelIndex &index, int role) const
@ -164,6 +166,8 @@ QVariant WorldList::data(const QModelIndex &index, int role) const
if (row < 0 || row >= worlds.size())
return QVariant();
QLocale locale;
auto & world = worlds[row];
switch (role)
{
@ -179,6 +183,9 @@ QVariant WorldList::data(const QModelIndex &index, int role) const
case LastPlayedColumn:
return world.lastPlayed();
case SizeColumn:
return locale.formattedDataSize(world.bytes());
default:
return QVariant();
}
@ -207,6 +214,10 @@ QVariant WorldList::data(const QModelIndex &index, int role) const
{
return world.lastPlayed();
}
case SizeRole:
{
return locale.formattedDataSize(world.bytes());
}
case IconFileRole:
{
return world.iconFile();
@ -229,6 +240,9 @@ QVariant WorldList::headerData(int section, Qt::Orientation orientation, int rol
return tr("Game Mode");
case LastPlayedColumn:
return tr("Last Played");
case SizeColumn:
//: World size on disk
return tr("Size");
default:
return QVariant();
}
@ -242,6 +256,8 @@ QVariant WorldList::headerData(int section, Qt::Orientation orientation, int rol
return tr("Game mode of the world.");
case LastPlayedColumn:
return tr("Date and time the world was last played.");
case SizeColumn:
return tr("Size of the world on disk.");
default:
return QVariant();
}

View File

@ -32,7 +32,8 @@ public:
{
NameColumn,
GameModeColumn,
LastPlayedColumn
LastPlayedColumn,
SizeColumn
};
enum Roles
@ -43,6 +44,7 @@ public:
NameRole,
GameModeRole,
LastPlayedRole,
SizeRole,
IconFileRole
};

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AccountData.h"
#include <QJsonDocument>
#include <QJsonObject>

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QString>
#include <QByteArray>

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AccountList.h"

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AccountTask.h"

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

View File

@ -1,18 +1,38 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* http://www.apache.org/licenses/LICENSE-2.0
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MinecraftAccount.h"

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MSAStep.h"
#include <QNetworkRequest>

View File

@ -1,3 +1,37 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QObject>

View File

@ -65,7 +65,7 @@ void XboxAuthorizationStep::onRequestDone(
if(!processSTSError(error, data, headers)) {
emit finished(
AccountTaskState::STATE_FAILED_SOFT,
tr("Failed to get authorization for %1 services. Error %1.").arg(m_authorizationKind, error)
tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, error)
);
}
return;

View File

@ -88,7 +88,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state)
case LoggedProcess::FailedToStart:
{
//: Error message displayed if instance can't start
const char *reason = QT_TR_NOOP("Could not launch minecraft!");
const char *reason = QT_TR_NOOP("Could not launch Minecraft!");
emit logLine(reason, MessageLevel::Fatal);
emitFailed(tr(reason));
return;

View File

@ -154,7 +154,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
case LoggedProcess::FailedToStart:
{
//: Error message displayed if instace can't start
const char *reason = QT_TR_NOOP("Could not launch minecraft!");
const char *reason = QT_TR_NOOP("Could not launch Minecraft!");
emit logLine(reason, MessageLevel::Fatal);
emitFailed(tr(reason));
return;
@ -170,6 +170,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
{
if (APPLICATION->settings()->get("CloseAfterLaunch").toBool())
APPLICATION->showMainWindow();
m_parent->setPid(-1);
// if the exit code wasn't 0, report this as a crash
auto exitCode = m_process.exitCode();

View File

@ -1,50 +1,75 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "VerifyJavaInstall.h"
#include <launch/LaunchTask.h>
#include <minecraft/MinecraftInstance.h>
#include <minecraft/PackProfile.h>
#include <minecraft/VersionFilterData.h>
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif
#include "java/JavaVersion.h"
#include "minecraft/PackProfile.h"
#include "minecraft/MinecraftInstance.h"
void VerifyJavaInstall::executeTask() {
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto instance = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto packProfile = instance->getPackProfile();
auto settings = instance->settings();
auto storedVersion = settings->get("JavaVersion").toString();
auto ignoreCompatibility = settings->get("IgnoreJavaCompatibility").toBool();
auto javaVersion = m_inst->getJavaVersion();
auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft");
auto compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors();
// Java 17 requirement
if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java17BeginsDate) {
if (javaVersion.major() < 17) {
emit logLine("Minecraft 1.18 Pre Release 2 and above require the use of Java 17",
MessageLevel::Fatal);
emitFailed(tr("Minecraft 1.18 Pre Release 2 and above require the use of Java 17"));
return;
}
}
// Java 16 requirement
else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) {
if (javaVersion.major() < 16) {
emit logLine("Minecraft 21w19a and above require the use of Java 16",
MessageLevel::Fatal);
emitFailed(tr("Minecraft 21w19a and above require the use of Java 16"));
return;
}
}
// Java 8 requirement
else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java8BeginsDate) {
if (javaVersion.major() < 8) {
emit logLine("Minecraft 17w13a and above require the use of Java 8",
MessageLevel::Fatal);
emitFailed(tr("Minecraft 17w13a and above require the use of Java 8"));
return;
}
JavaVersion javaVersion(storedVersion);
if (compatibleMajors.isEmpty() || compatibleMajors.contains(javaVersion.major()))
{
emitSucceeded();
return;
}
emitSucceeded();
if (ignoreCompatibility)
{
emit logLine(tr("Java major version is incompatible. Things might break."), MessageLevel::Warning);
emitSucceeded();
return;
}
emit logLine(tr("This instance is not compatible with Java version %1.\n"
"Please switch to one of the following Java versions for this instance:").arg(javaVersion.major()),
MessageLevel::Error);
for (auto major : compatibleMajors)
{
emit logLine(tr("Java version %1").arg(major), MessageLevel::Error);
}
emitFailed(QString("Incompatible Java major version"));
}

View File

@ -1,6 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <launch/LaunchStep.h>
#include <launch/LaunchTask.h>
class VerifyJavaInstall : public LaunchStep {
Q_OBJECT

View File

@ -391,7 +391,7 @@ void LocalModParseTask::processAsZip()
zip.close();
return;
}
else if (zip.setCurrentFile("fabric.mod.json"))
else if (zip.setCurrentFile("fabric.mod.json")) // TODO: Support quilt.mod.json
{
if (!file.open(QIODevice::ReadOnly))
{

View File

@ -14,7 +14,7 @@ void FoldersTask::executeTask()
QDir mcDir(m_inst->gameRoot());
if (!mcDir.exists() && !mcDir.mkpath("."))
{
emitFailed(tr("Failed to create folder for minecraft binaries."));
emitFailed(tr("Failed to create folder for Minecraft binaries."));
return;
}
emitSucceeded();

View File

@ -48,6 +48,10 @@ void LibrariesTask::executeTask()
libArtifactPool.append(profile->getLibraries());
libArtifactPool.append(profile->getNativeLibraries());
libArtifactPool.append(profile->getMavenFiles());
for (auto agent : profile->getAgents())
{
libArtifactPool.append(agent->library());
}
libArtifactPool.append(profile->getMainJar());
processArtifactPool(libArtifactPool, failedLocalLibraries, inst->getLocalLibraryPath());

View File

@ -0,0 +1,69 @@
#pragma once
#include <QString>
#include <QList>
#include "Version.h"
namespace ModPlatform {
class ListModel;
}
class ModAPI {
protected:
using CallerType = ModPlatform::ListModel;
public:
virtual ~ModAPI() = default;
// https://docs.curseforge.com/?http#tocS_ModLoaderType
enum ModLoaderType { Unspecified = 0, Forge = 1, Cauldron = 2, LiteLoader = 3, Fabric = 4, Quilt = 5 };
struct SearchArgs {
int offset;
QString search;
QString sorting;
ModLoaderType mod_loader;
std::list<Version> versions;
};
virtual void searchMods(CallerType* caller, SearchArgs&& args) const = 0;
struct VersionSearchArgs {
QString addonId;
std::list<Version> mcVersions;
ModLoaderType loader;
};
virtual void getVersions(CallerType* caller, VersionSearchArgs&& args) const = 0;
static auto getModLoaderString(ModLoaderType type) -> const QString {
switch (type) {
case Unspecified:
break;
case Forge:
return "forge";
case Cauldron:
return "cauldron";
case LiteLoader:
return "liteloader";
case Fabric:
return "fabric";
case Quilt:
return "quilt";
}
return "";
}
protected:
inline auto getGameVersionsString(std::list<Version> mcVersions) const -> QString
{
QString s;
for(auto& ver : mcVersions){
s += QString("%1,").arg(ver.toString());
}
s.remove(s.length() - 1, 1); //remove last comma
return s;
}
};

View File

@ -0,0 +1,42 @@
#pragma once
#include <QList>
#include <QMetaType>
#include <QString>
#include <QVariant>
#include <QVector>
namespace ModPlatform {
struct ModpackAuthor {
QString name;
QString url;
};
struct IndexedVersion {
QVariant addonId;
QVariant fileId;
QString version;
QVector<QString> mcVersion;
QString downloadUrl;
QString date;
QString fileName;
QVector<QString> loaders = {};
};
struct IndexedPack {
QVariant addonId;
QString name;
QString description;
QList<ModpackAuthor> authors;
QString logoName;
QString logoUrl;
QString websiteUrl;
bool versionsLoaded = false;
QVector<IndexedVersion> versions;
};
} // namespace ModPlatform
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)

View File

@ -0,0 +1,43 @@
#pragma once
#include "modplatform/helpers/NetworkModAPI.h"
class FlameAPI : public NetworkModAPI {
private:
inline auto getModSearchURL(SearchArgs& args) const -> QString override
{
auto gameVersionStr = args.versions.size() != 0 ? QString("gameVersion=%1").arg(args.versions.front().toString()) : QString();
return QString(
"https://addons-ecs.forgesvc.net/api/v2/addon/search?"
"gameId=432&"
"categoryId=0&"
"sectionId=6&"
"index=%1&"
"pageSize=25&"
"searchFilter=%2&"
"sort=%3&"
"modLoaderType=%4&"
"%5")
.arg(args.offset)
.arg(args.search)
.arg(args.sorting)
.arg(getMappedModLoader(args.mod_loader))
.arg(gameVersionStr);
};
inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override
{
return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(args.addonId);
};
public:
static auto getMappedModLoader(const ModLoaderType type) -> const ModLoaderType
{
// TODO: remove this once Quilt drops official Fabric support
if (type == Quilt) // NOTE: Most if not all Fabric mods should work *currently*
return Fabric;
return type;
}
};

View File

@ -1,13 +1,12 @@
#include <QObject>
#include "FlameModIndex.h"
#include "Json.h"
#include "net/NetJob.h"
#include "BaseInstance.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "modplatform/flame/FlameAPI.h"
#include "net/NetJob.h"
void FlameMod::loadIndexedPack(FlameMod::IndexedPack & pack, QJsonObject & obj)
void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{
pack.addonId = Json::requireInteger(obj, "id");
pack.name = Json::requireString(obj, "name");
@ -16,10 +15,10 @@ void FlameMod::loadIndexedPack(FlameMod::IndexedPack & pack, QJsonObject & obj)
bool thumbnailFound = false;
auto attachments = Json::requireArray(obj, "attachments");
for(auto attachmentRaw: attachments) {
for (auto attachmentRaw : attachments) {
auto attachmentObj = Json::requireObject(attachmentRaw);
bool isDefault = attachmentObj.value("isDefault").toBool(false);
if(isDefault) {
if (isDefault) {
thumbnailFound = true;
pack.logoName = Json::requireString(attachmentObj, "title");
pack.logoUrl = Json::requireString(attachmentObj, "thumbnailUrl");
@ -27,37 +26,36 @@ void FlameMod::loadIndexedPack(FlameMod::IndexedPack & pack, QJsonObject & obj)
}
}
if(!thumbnailFound) {
throw JSONValidationError(QString("Pack without an icon, skipping: %1").arg(pack.name));
}
if (!thumbnailFound) { throw JSONValidationError(QString("Pack without an icon, skipping: %1").arg(pack.name)); }
auto authors = Json::requireArray(obj, "authors");
for(auto authorIter: authors) {
for (auto authorIter : authors) {
auto author = Json::requireObject(authorIter);
FlameMod::ModpackAuthor packAuthor;
ModPlatform::ModpackAuthor packAuthor;
packAuthor.name = Json::requireString(author, "name");
packAuthor.url = Json::requireString(author, "url");
pack.authors.append(packAuthor);
}
}
void FlameMod::loadIndexedPackVersions(FlameMod::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr<QNetworkAccessManager>& network, BaseInstance * inst)
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
const shared_qobject_ptr<QNetworkAccessManager>& network,
BaseInstance* inst)
{
QVector<FlameMod::IndexedVersion> unsortedVersions;
bool hasFabric = !((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty();
QString mcVersion = ((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.minecraft");
QVector<ModPlatform::IndexedVersion> unsortedVersions;
auto profile = (dynamic_cast<MinecraftInstance*>(inst))->getPackProfile();
bool hasFabric = FlameAPI::getMappedModLoader(profile->getModLoader()) == ModAPI::Fabric;
QString mcVersion = profile->getComponentVersion("net.minecraft");
for(auto versionIter: arr) {
for (auto versionIter : arr) {
auto obj = versionIter.toObject();
auto versionArray = Json::requireArray(obj, "gameVersion");
if (versionArray.isEmpty()) {
continue;
}
if (versionArray.isEmpty()) { continue; }
FlameMod::IndexedVersion file;
for(auto mcVer : versionArray){
ModPlatform::IndexedVersion file;
for (auto mcVer : versionArray) {
file.mcVersion.append(mcVer.toString());
}
@ -70,29 +68,28 @@ void FlameMod::loadIndexedPackVersions(FlameMod::IndexedPack & pack, QJsonArray
auto modules = Json::requireArray(obj, "modules");
bool is_valid_fabric_version = false;
for(auto m : modules){
auto fname = Json::requireString(m.toObject(),"foldername");
for (auto m : modules) {
auto fname = Json::requireString(m.toObject(), "foldername");
// FIXME: This does not work properly when a mod supports more than one mod loader, since
// FIXME: This also doesn't deal with Quilt mods at the moment
// they bundle the meta files for all of them in the same arquive, even when that version
// doesn't support the given mod loader.
if(hasFabric){
if(fname == "fabric.mod.json"){
if (hasFabric) {
if (fname == "fabric.mod.json") {
is_valid_fabric_version = true;
break;
}
}
else break;
} else
break;
// NOTE: Since we're not validating forge versions, we can just skip this loop.
}
if(hasFabric && !is_valid_fabric_version)
continue;
if (hasFabric && !is_valid_fabric_version) continue;
unsortedVersions.append(file);
}
auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool
{
//dates are in RFC 3339 format
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
// dates are in RFC 3339 format
return a.date > b.date;
};
std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate);

View File

@ -3,48 +3,18 @@
//
#pragma once
#include <QList>
#include <QMetaType>
#include <QString>
#include <QVector>
#include <QNetworkAccessManager>
#include <QObjectPtr.h>
#include "net/NetJob.h"
#include "modplatform/ModIndex.h"
#include "BaseInstance.h"
#include <QNetworkAccessManager>
namespace FlameMod {
struct ModpackAuthor {
QString name;
QString url;
};
struct IndexedVersion {
int addonId;
int fileId;
QString version;
QVector<QString> mcVersion;
QString downloadUrl;
QString date;
QString fileName;
};
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
const shared_qobject_ptr<QNetworkAccessManager>& network,
BaseInstance* inst);
struct IndexedPack
{
int addonId;
QString name;
QString description;
QList<ModpackAuthor> authors;
QString logoName;
QString logoUrl;
QString websiteUrl;
bool versionsLoaded = false;
QVector<IndexedVersion> versions;
};
void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
void loadIndexedPackVersions(IndexedPack &pack, QJsonArray &arr, const shared_qobject_ptr<QNetworkAccessManager> &network, BaseInstance *inst);
}
Q_DECLARE_METATYPE(FlameMod::IndexedPack)
} // namespace FlameMod

View File

@ -0,0 +1,60 @@
#include "NetworkModAPI.h"
#include "ui/pages/modplatform/ModModel.h"
#include "Application.h"
#include "net/NetJob.h"
void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const
{
auto netJob = new NetJob(QString("%1::Search").arg(caller->debugName()), APPLICATION->network());
auto searchUrl = getModSearchURL(args);
auto response = new QByteArray();
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response));
QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); });
QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed);
QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from " << caller->debugName() << " at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
caller->searchRequestFinished(doc);
});
netJob->start();
}
void NetworkModAPI::getVersions(CallerType* caller, VersionSearchArgs&& args) const
{
auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(caller->debugName()).arg(args.addonId), APPLICATION->network());
auto response = new QByteArray();
netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(args), response));
QObject::connect(netJob, &NetJob::succeeded, caller, [response, caller, args] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from " << caller->debugName() << " at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
caller->versionRequestSucceeded(doc, args.addonId);
});
QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] {
netJob->deleteLater();
delete response;
});
netJob->start();
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "modplatform/ModAPI.h"
class NetworkModAPI : public ModAPI {
public:
void searchMods(CallerType* caller, SearchArgs&& args) const override;
void getVersions(CallerType* caller, VersionSearchArgs&& args) const override;
protected:
virtual auto getModSearchURL(SearchArgs& args) const -> QString = 0;
virtual auto getVersionsURL(VersionSearchArgs& args) const -> QString = 0;
};

View File

@ -114,7 +114,7 @@ void PackInstallTask::install()
//ok, found minecraft dir, move contents to instance dir
if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"))
{
emitFailed(tr("Failed to move unzipped minecraft!"));
emitFailed(tr("Failed to move unzipped Minecraft!"));
return;
}
}

View File

@ -0,0 +1,68 @@
#pragma once
#include "modplatform/helpers/NetworkModAPI.h"
#include <QDebug>
class ModrinthAPI : public NetworkModAPI {
public:
inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; };
private:
inline auto getModSearchURL(SearchArgs& args) const -> QString override
{
if (!validateModLoader(args.mod_loader)) {
qWarning() << "Modrinth only have Forge and Fabric-compatible mods!";
return "";
}
return QString(
"https://api.modrinth.com/v2/search?"
"offset=%1&"
"limit=25&"
"query=%2&"
"index=%3&"
"facets=[[\"categories:%4\"],%5[\"project_type:mod\"]]")
.arg(args.offset)
.arg(args.search)
.arg(args.sorting)
.arg(getModLoaderString(args.mod_loader))
.arg(getGameVersionsArray(args.versions));
};
inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override
{
return QString("https://api.modrinth.com/v2/project/%1/version?"
"game_versions=[%2]"
"loaders=[%3]")
.arg(args.addonId)
.arg(getGameVersionsString(args.mcVersions))
.arg(getModLoaderString(args.loader));
};
auto getGameVersionsArray(std::list<Version> mcVersions) const -> QString
{
QString s;
for(auto& ver : mcVersions){
s += QString("\"versions:%1\",").arg(ver.toString());
}
s.remove(s.length() - 1, 1); //remove last comma
return s.isEmpty() ? QString() : QString("[%1],").arg(s);
}
static auto getModLoaderString(ModLoaderType type) -> const QString
{
if (type == Unspecified)
return "fabric, forge, quilt";
// TODO: remove this once Quilt drops official Fabric support
if (type == Quilt) // NOTE: Most if not all Fabric mods should work *currently*
return "fabric, quilt";
return ModAPI::getModLoaderString(type);
}
inline auto validateModLoader(ModLoaderType modLoader) const -> bool
{
return modLoader == Unspecified || modLoader == Forge || modLoader == Fabric || modLoader == Quilt;
}
};

View File

@ -1,92 +1,88 @@
#include <QObject>
#include "ModrinthPackIndex.h"
#include "ModrinthAPI.h"
#include "Json.h"
#include "net/NetJob.h"
#include "BaseInstance.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "net/NetJob.h"
static ModrinthAPI api;
void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj)
void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{
pack.addonId = Json::requireString(obj, "project_id");
pack.name = Json::requireString(obj, "title");
pack.websiteUrl = Json::ensureString(obj, "page_url", "");
QString slug = Json::ensureString(obj, "slug", "");
if (!slug.isEmpty())
pack.websiteUrl = "https://modrinth.com/mod/" + Json::ensureString(obj, "slug", "");
else
pack.websiteUrl = "";
pack.description = Json::ensureString(obj, "description", "");
pack.logoUrl = Json::requireString(obj, "icon_url");
pack.logoName = pack.addonId;
pack.logoName = pack.addonId.toString();
Modrinth::ModpackAuthor modAuthor;
ModPlatform::ModpackAuthor modAuthor;
modAuthor.name = Json::requireString(obj, "author");
modAuthor.url = "https://modrinth.com/user/"+modAuthor.name;
pack.author = modAuthor;
modAuthor.url = api.getAuthorURL(modAuthor.name);
pack.authors.append(modAuthor);
}
void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr<QNetworkAccessManager>& network, BaseInstance * inst)
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
const shared_qobject_ptr<QNetworkAccessManager>& network,
BaseInstance* inst)
{
QVector<Modrinth::IndexedVersion> unsortedVersions;
bool hasFabric = !((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty();
QString mcVersion = ((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.minecraft");
QVector<ModPlatform::IndexedVersion> unsortedVersions;
QString mcVersion = (static_cast<MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
for(auto versionIter: arr) {
for (auto versionIter : arr) {
auto obj = versionIter.toObject();
Modrinth::IndexedVersion file;
file.addonId = Json::requireString(obj,"project_id") ;
ModPlatform::IndexedVersion file;
file.addonId = Json::requireString(obj, "project_id");
file.fileId = Json::requireString(obj, "id");
file.date = Json::requireString(obj, "date_published");
auto versionArray = Json::requireArray(obj, "game_versions");
if (versionArray.empty()) {
continue;
}
for(auto mcVer : versionArray){
if (versionArray.empty()) { continue; }
for (auto mcVer : versionArray) {
file.mcVersion.append(mcVer.toString());
}
auto loaders = Json::requireArray(obj,"loaders");
for(auto loader : loaders){
auto loaders = Json::requireArray(obj, "loaders");
for (auto loader : loaders) {
file.loaders.append(loader.toString());
}
file.version = Json::requireString(obj, "name");
auto files = Json::requireArray(obj, "files");
int i = 0;
while (files.count() > 1 && i < files.count()){
//try to resolve the correct file
// Find correct file (needed in cases where one version may have multiple files)
// Will default to the last one if there's no primary (though I think Modrinth requires that
// at least one file is primary, idk)
// NOTE: files.count() is 1-indexed, so we need to subtract 1 to become 0-indexed
while (i < files.count() - 1){
auto parent = files[i].toObject();
auto fileName = Json::requireString(parent, "filename");
//avoid grabbing "dev" files
if(fileName.contains("javadocs",Qt::CaseInsensitive) || fileName.contains("sources",Qt::CaseInsensitive)){
i++;
continue;
}
//grab the correct mod loader
if(fileName.contains("forge",Qt::CaseInsensitive) || fileName.contains("fabric",Qt::CaseInsensitive) ){
if(hasFabric){
if(fileName.contains("forge",Qt::CaseInsensitive)){
i++;
continue;
}
}else{
if(fileName.contains("fabric",Qt::CaseInsensitive)){
i++;
continue;
}
}
}
break;
// Grab the primary file, if available
if(Json::requireBoolean(parent, "primary"))
break;
i++;
}
auto parent = files[i].toObject();
if(parent.contains("url")) {
if (parent.contains("url")) {
file.downloadUrl = Json::requireString(parent, "url");
file.fileName = Json::requireString(parent, "filename");
unsortedVersions.append(file);
}
}
auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool
{
//dates are in RFC 3339 format
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
// dates are in RFC 3339 format
return a.date > b.date;
};
std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate);

View File

@ -1,48 +1,16 @@
#pragma once
#include <QList>
#include <QMetaType>
#include <QString>
#include <QVector>
#include <QNetworkAccessManager>
#include <QObjectPtr.h>
#include "net/NetJob.h"
#include "modplatform/ModIndex.h"
#include "BaseInstance.h"
#include <QNetworkAccessManager>
namespace Modrinth {
struct ModpackAuthor {
QString name;
QString url;
};
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
const shared_qobject_ptr<QNetworkAccessManager>& network,
BaseInstance* inst);
struct IndexedVersion {
QString addonId;
QString fileId;
QString version;
QVector<QString> mcVersion;
QString downloadUrl;
QString date;
QString fileName;
QVector<QString> loaders;
};
struct IndexedPack
{
QString addonId;
QString name;
QString description;
ModpackAuthor author;
QString logoName;
QString logoUrl;
QString websiteUrl;
bool versionsLoaded = false;
QVector<IndexedVersion> versions;
};
void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
void loadIndexedPackVersions(IndexedPack &pack, QJsonArray &arr, const shared_qobject_ptr<QNetworkAccessManager> &network, BaseInstance *inst);
}
Q_DECLARE_METATYPE(Modrinth::IndexedPack)
} // namespace Modrinth

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2021-2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SolderPackInstallTask.h"
@ -19,16 +39,23 @@
#include <Json.h>
#include <QtConcurrentRun>
#include <MMCZip.h>
#include "TechnicPackProcessor.h"
#include "SolderPackManifest.h"
#include "net/ChecksumValidator.h"
Technic::SolderPackInstallTask::SolderPackInstallTask(
shared_qobject_ptr<QNetworkAccessManager> network,
const QUrl &sourceUrl,
const QUrl &solderUrl,
const QString &pack,
const QString &version,
const QString &minecraftVersion
) {
m_sourceUrl = sourceUrl;
m_minecraftVersion = minecraftVersion;
m_solderUrl = solderUrl;
m_pack = pack;
m_version = version;
m_network = network;
m_minecraftVersion = minecraftVersion;
}
bool Technic::SolderPackInstallTask::abort() {
@ -41,34 +68,12 @@ bool Technic::SolderPackInstallTask::abort() {
void Technic::SolderPackInstallTask::executeTask()
{
setStatus(tr("Finding recommended version:\n%1").arg(m_sourceUrl.toString()));
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();
}
setStatus(tr("Resolving modpack files"));
void Technic::SolderPackInstallTask::versionSucceeded()
{
try
{
QJsonDocument doc = Json::requireDocument(m_response);
QJsonObject obj = Json::requireObject(doc);
QString version = Json::requireString(obj, "recommended", "__placeholder__");
m_sourceUrl = m_sourceUrl.toString() + '/' + version;
}
catch (const JSONValidationError &e)
{
emitFailed(e.cause());
m_filesNetJob.reset();
return;
}
setStatus(tr("Resolving modpack files:\n%1").arg(m_sourceUrl.toString()));
m_filesNetJob = new NetJob(tr("Resolving modpack files"), m_network);
m_filesNetJob->addNetAction(Net::Download::makeByteArray(m_sourceUrl, &m_response));
auto sourceUrl = QString("%1/modpack/%2/%3").arg(m_solderUrl.toString(), m_pack, m_version);
m_filesNetJob->addNetAction(Net::Download::makeByteArray(sourceUrl, &m_response));
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded);
connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
@ -77,38 +82,47 @@ void Technic::SolderPackInstallTask::versionSucceeded()
void Technic::SolderPackInstallTask::fileListSucceeded()
{
setStatus(tr("Downloading modpack:"));
QStringList modUrls;
try
{
QJsonDocument doc = Json::requireDocument(m_response);
QJsonObject obj = Json::requireObject(doc);
QString minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
if (!minecraftVersion.isEmpty())
m_minecraftVersion = minecraftVersion;
QJsonArray mods = Json::requireArray(obj, "mods", "'mods'");
for (auto mod: mods)
{
QJsonObject modObject = Json::requireObject(mod);
modUrls.append(Json::requireString(modObject, "url", "'url'"));
}
setStatus(tr("Downloading modpack"));
QJsonParseError parse_error {};
QJsonDocument doc = QJsonDocument::fromJson(m_response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from Solder at " << parse_error.offset << " reason: " << parse_error.errorString();
qWarning() << m_response;
return;
}
catch (const JSONValidationError &e)
{
emitFailed(e.cause());
auto obj = doc.object();
TechnicSolder::PackBuild build;
try {
TechnicSolder::loadPackBuild(build, obj);
}
catch (const JSONValidationError& e) {
emitFailed(tr("Could not understand pack manifest:\n") + e.cause());
m_filesNetJob.reset();
return;
}
if (!build.minecraft.isEmpty())
m_minecraftVersion = build.minecraft;
m_filesNetJob = new NetJob(tr("Downloading modpack"), m_network);
int i = 0;
for (auto &modUrl: modUrls)
{
for (const auto &mod : build.mods) {
auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i));
m_filesNetJob->addNetAction(Net::Download::makeFile(modUrl, path));
auto dl = Net::Download::makeFile(mod.url, path);
if (!mod.md5.isEmpty()) {
auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
}
m_filesNetJob->addNetAction(dl);
i++;
}
m_modCount = modUrls.size();
m_modCount = build.mods.size();
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged);
@ -206,6 +220,5 @@ void Technic::SolderPackInstallTask::extractFinished()
void Technic::SolderPackInstallTask::extractAborted()
{
emitFailed(tr("Instance import has been aborted."));
return;
}

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2021-2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
@ -27,7 +47,7 @@ namespace Technic
{
Q_OBJECT
public:
explicit SolderPackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, const QUrl &sourceUrl, const QString &minecraftVersion);
explicit SolderPackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, const QUrl &solderUrl, const QString& pack, const QString& version, const QString &minecraftVersion);
bool canAbort() const override { return true; }
bool abort() override;
@ -37,7 +57,6 @@ namespace Technic
virtual void executeTask() override;
private slots:
void versionSucceeded();
void fileListSucceeded();
void downloadSucceeded();
void downloadFailed(QString reason);
@ -51,7 +70,9 @@ namespace Technic
shared_qobject_ptr<QNetworkAccessManager> m_network;
NetJob::Ptr m_filesNetJob;
QUrl m_sourceUrl;
QUrl m_solderUrl;
QString m_pack;
QString m_version;
QString m_minecraftVersion;
QByteArray m_response;
QTemporaryDir m_outputDir;

View File

@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "SolderPackManifest.h"
#include "Json.h"
namespace TechnicSolder {
void loadPack(Pack& v, QJsonObject& obj)
{
v.recommended = Json::requireString(obj, "recommended");
v.latest = Json::requireString(obj, "latest");
auto builds = Json::requireArray(obj, "builds");
for (const auto buildRaw : builds) {
auto build = Json::requireString(buildRaw);
v.builds.append(build);
}
}
static void loadPackBuildMod(PackBuildMod& b, QJsonObject& obj)
{
b.name = Json::requireString(obj, "name");
b.version = Json::requireString(obj, "version");
b.md5 = Json::requireString(obj, "md5");
b.url = Json::requireString(obj, "url");
}
void loadPackBuild(PackBuild& v, QJsonObject& obj)
{
v.minecraft = Json::requireString(obj, "minecraft");
auto mods = Json::requireArray(obj, "mods");
for (const auto modRaw : mods) {
auto modObj = Json::requireObject(modRaw);
PackBuildMod mod;
loadPackBuildMod(mod, modObj);
v.mods.append(mod);
}
}
}

View File

@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QString>
#include <QVector>
#include <QJsonObject>
namespace TechnicSolder {
struct Pack {
QString recommended;
QString latest;
QVector<QString> builds;
};
void loadPack(Pack& v, QJsonObject& obj);
struct PackBuildMod {
QString name;
QString version;
QString md5;
QString url;
};
struct PackBuild {
QString minecraft;
QVector<PackBuildMod> mods;
};
void loadPackBuild(PackBuild& v, QJsonObject& obj);
}

View File

@ -88,7 +88,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const
else
{
if (minecraftVersion.isEmpty())
emit failed(tr("Could not find \"version.json\" inside \"bin/modpack.jar\", but minecraft version is unknown"));
emit failed(tr("Could not find \"version.json\" inside \"bin/modpack.jar\", but Minecraft version is unknown"));
components->setComponentVersion("net.minecraft", minecraftVersion, true);
components->installJarMods({modpackJar});

View File

@ -1,129 +0,0 @@
#include "NotificationChecker.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include "net/Download.h"
#include "Application.h"
NotificationChecker::NotificationChecker(QObject *parent)
: QObject(parent)
{
}
void NotificationChecker::setNotificationsUrl(const QUrl &notificationsUrl)
{
m_notificationsUrl = notificationsUrl;
}
void NotificationChecker::setApplicationChannel(QString channel)
{
m_appVersionChannel = channel;
}
void NotificationChecker::setApplicationFullVersion(QString version)
{
m_appFullVersion = version;
}
void NotificationChecker::setApplicationPlatform(QString platform)
{
m_appPlatform = platform;
}
QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const
{
return m_entries;
}
void NotificationChecker::checkForNotifications()
{
if (!m_notificationsUrl.isValid())
{
qCritical() << "Failed to check for notifications. No notifications URL set."
<< "If you'd like to use PolyMC's notification system, please pass the "
"URL to CMake at compile time.";
return;
}
if (m_checkJob)
{
return;
}
m_checkJob = new NetJob("Checking for notifications", APPLICATION->network());
auto entry = APPLICATION->metacache()->resolveEntry("root", "notifications.json");
entry->setStale(true);
m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry));
connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded);
m_checkJob->start();
}
void NotificationChecker::downloadSucceeded(int)
{
m_entries.clear();
QFile file(m_download->getTargetFilepath());
if (file.open(QFile::ReadOnly))
{
QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
for (auto it = root.begin(); it != root.end(); ++it)
{
QJsonObject obj = (*it).toObject();
NotificationEntry entry;
entry.id = obj.value("id").toDouble();
entry.message = obj.value("message").toString();
entry.channel = obj.value("channel").toString();
entry.platform = obj.value("platform").toString();
entry.from = obj.value("from").toString();
entry.to = obj.value("to").toString();
const QString type = obj.value("type").toString("critical");
if (type == "critical")
{
entry.type = NotificationEntry::Critical;
}
else if (type == "warning")
{
entry.type = NotificationEntry::Warning;
}
else if (type == "information")
{
entry.type = NotificationEntry::Information;
}
if(entryApplies(entry))
m_entries.append(entry);
}
}
m_checkJob.reset();
emit notificationCheckFinished();
}
bool versionLessThan(const QString &v1, const QString &v2)
{
QStringList l1 = v1.split('.');
QStringList l2 = v2.split('.');
while (!l1.isEmpty() && !l2.isEmpty())
{
int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
if (one != two)
{
return one < two;
}
}
return false;
}
bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const
{
bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
bool fromApplies =
entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
bool toApplies =
entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
return channelApplies && platformApplies && fromApplies && toApplies;
}

View File

@ -1,61 +0,0 @@
#pragma once
#include <QObject>
#include "net/NetJob.h"
#include "net/Download.h"
class NotificationChecker : public QObject
{
Q_OBJECT
public:
explicit NotificationChecker(QObject *parent = 0);
void setNotificationsUrl(const QUrl &notificationsUrl);
void setApplicationPlatform(QString platform);
void setApplicationChannel(QString channel);
void setApplicationFullVersion(QString version);
struct NotificationEntry
{
int id;
QString message;
enum
{
Critical,
Warning,
Information
} type;
QString channel;
QString platform;
QString from;
QString to;
};
QList<NotificationEntry> notificationEntries() const;
public
slots:
void checkForNotifications();
private
slots:
void downloadSucceeded(int);
signals:
void notificationCheckFinished();
private:
bool entryApplies(const NotificationEntry &entry) const;
private:
QList<NotificationEntry> m_entries;
QUrl m_notificationsUrl;
NetJob::Ptr m_checkJob;
Net::Download::Ptr m_download;
QString m_appVersionChannel;
QString m_appPlatform;
QString m_appFullVersion;
};

View File

@ -1,108 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128mm"
height="128mm"
viewBox="0 0 453.54331 453.54331"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="discord.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4166">
<stop
style="stop-color:#7593d7;stop-opacity:1"
offset="0"
id="stop4168" />
<stop
style="stop-color:#4f6aa3;stop-opacity:1"
offset="1"
id="stop4170" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4166"
id="linearGradient4174"
x1="351.42856"
y1="513.79077"
x2="351.42856"
y2="943.79077"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(24.999996,-5.8267714e-6)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="249.4082"
inkscape:cy="153.28604"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-nodes="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-midpoints="false"
inkscape:snap-page="true"
inkscape:window-width="1911"
inkscape:window-height="2120"
inkscape:window-x="2970"
inkscape:window-y="0"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid4155" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-1.4285583,-500.24745)">
<path
style="fill:url(#linearGradient4174);fill-opacity:1;fill-rule:evenodd"
d="m 73.928594,513.79076 a 37.5,37.5 0 0 0 -37.36914,34.88476 l -0.13086,0.11524 0,2.5 0,302.5 0.11914,0.11914 a 37.5,37.5 0 0 0 -0.11914,2.38086 37.5,37.5 0 0 0 37.5,37.5 37.5,37.5 0 0 0 2.41406,-0.0859 l 0.0859,0.0859 250.000006,0 -10,-40 100,90 0,-392.5 0,-2.5 -0.0918,-0.0918 a 37.5,37.5 0 0 0 -34.77734,-34.77734 l -0.13086,-0.13086 -2.5,0 -302.500006,0 -0.13477,0.11914 a 37.5,37.5 0 0 0 -2.36523,-0.11914 z"
id="path4157"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#ffffff;fill-rule:evenodd"
d="m 262.51367,111.60742 -3.53515,4.79688 c 20.92905,7.8755 41.53825,15.82838 52.90625,26.01172 -54.51023,-27.29925 -111.94069,-29.57156 -173.11524,0.25195 13.83558,-12.04023 34.12183,-19.9521 56.31641,-26.64258 l -2.39844,-3.78711 c -19.87573,2.47189 -39.74673,4.97961 -57.48273,19.75608 -1.26426,1.0533 -2.43875,1.7112 -3.75946,3.35134 -1.04157,1.68882 -1.47654,2.94289 -2.20384,4.4259 -16.51968,33.6846 -29.13904,71.47893 -29.23561,122.47449 13.7929,19.97074 35.85963,31.20604 66.79492,33.08203 l 14.01563,-19.0664 c -16.32939,-4.839 -28.63498,-12.99042 -36.86914,-24.4961 68.24127,41.30702 122.04171,25.27927 169.32617,-0.50585 -10.12692,12.60017 -23.08016,21.50538 -39.39649,26.01171 l 14.52149,17.80469 c 31.64413,-2.6726 53.44205,-13.71547 66.03906,-32.57812 -1.25854,-42.6757 -9.40904,-79.47015 -23.71494,-111.01207 -2.51316,-5.54105 -4.27674,-11.49413 -8.10537,-16.14028 -3.45571,-4.1936 -7.96544,-7.13252 -12.90109,-9.9657 -12.42806,-7.13399 -28.6789,-11.32721 -47.20243,-13.77258 z m -76.00195,82.42383 c 12.33462,8e-5 22.33381,10.55717 22.33398,23.58008 -1.7e-4,13.02291 -9.99936,23.58 -22.33398,23.58008 -12.33462,-7e-5 -22.33382,-10.55716 -22.33399,-23.58008 1.7e-4,-13.02292 9.99937,-23.58001 22.33399,-23.58008 z m 79.54883,0 c 12.33462,8e-5 22.33381,10.55717 22.33398,23.58008 -1.7e-4,13.02291 -9.99936,23.58 -22.33398,23.58008 -12.33462,-7e-5 -22.33382,-10.55716 -22.33399,-23.58008 1.7e-4,-13.02292 9.99937,-23.58001 22.33399,-23.58008 z"
transform="translate(1.4285583,500.24745)"
id="path4176"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccscsccccccccsasccccccccccc" />
</g>
<?xml version="1.0" encoding="UTF-8"?>
<svg fill="none" version="1.1" viewBox="0 0 71 71" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 8.0294)" clip-path="url(#clip0)">
<path d="m60.104 4.8978c-4.5253-2.0764-9.378-3.6062-14.452-4.4824-0.0924-0.01691-0.1847 0.025349-0.2323 0.10987-0.6241 1.11-1.3154 2.5581-1.7995 3.6963-5.4572-0.817-10.886-0.817-16.232 0-0.4842-1.1635-1.2006-2.5863-1.8275-3.6963-0.0476-0.0817-0.1399-0.12396-0.2323-0.10987-5.071 0.87338-9.9237 2.4032-14.452 4.4824-0.0392 0.0169-0.0728 0.0451-0.0951 0.0817-9.2046 13.751-11.726 27.165-10.489 40.412 0.005597 0.0648 0.041978 0.1268 0.092353 0.1662 6.0729 4.4598 11.956 7.1673 17.729 8.9619 0.0924 0.0282 0.1903-0.0056 0.2491-0.0817 1.3657-1.865 2.5831-3.8315 3.6269-5.8995 0.0616-0.1211 0.0028-0.2648-0.1231-0.3127-1.931-0.7325-3.7697-1.6256-5.5384-2.6398-0.1399-0.0817-0.1511-0.2818-0.0224-0.3776 0.3722-0.2789 0.7445-0.5691 1.0999-0.8621 0.0643-0.0535 0.1539-0.0648 0.2295-0.031 11.62 5.3051 24.199 5.3051 35.682 0 0.0756-0.0366 0.1652-0.0253 0.2323 0.0282 0.3555 0.293 0.7277 0.586 1.1027 0.8649 0.1287 0.0958 0.1203 0.2959-0.0196 0.3776-1.7687 1.0339-3.6074 1.9073-5.5412 2.637-0.1259 0.0479-0.1819 0.1944-0.1203 0.3155 1.0662 2.0651 2.2836 4.0316 3.6241 5.8967 0.056 0.0789 0.1567 0.1127 0.2491 0.0845 5.8014-1.7946 11.684-4.5021 17.757-8.9619 0.0532-0.0394 0.0868-0.0986 0.0924-0.1634 1.4804-15.315-2.4796-28.618-10.498-40.412-0.0196-0.0394-0.0531-0.0676-0.0923-0.0845zm-36.379 32.428c-3.4983 0-6.3808-3.2117-6.3808-7.156s2.8266-7.156 6.3808-7.156c3.5821 0 6.4367 3.2399 6.3807 7.156 0 3.9443-2.8266 7.156-6.3807 7.156zm23.592 0c-3.4982 0-6.3807-3.2117-6.3807-7.156s2.8265-7.156 6.3807-7.156c3.5822 0 6.4367 3.2399 6.3808 7.156 0 3.9443-2.7986 7.156-6.3808 7.156z" fill="#5865f2"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="71" height="55" fill="#fff"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -3,18 +3,18 @@
<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linearGradient84726" x1="4.4979" x2="12.435" y1="3.8011" y2="9.5681" gradientUnits="userSpaceOnUse">
<stop stop-color="#88b858" offset="0"/>
<stop stop-color="#72b147" offset=".5"/>
<stop stop-color="#5a9a30" offset="1"/>
<stop stop-color="#dedede" offset="0"/>
<stop stop-color="#d2d2d2" offset=".5"/>
<stop stop-color="#c0c0c0" offset="1"/>
</linearGradient>
</defs>
<g>
<path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#765338"/>
<path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/>
<path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/>
<path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#72b147"/>
<path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#5a9a30"/>
<path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#88b858"/>
<path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#8f8f8f"/>
<path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#c2c2c2"/>
<path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#7c7c7c"/>
<path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#d3d3d3"/>
<path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#bcbcbc"/>
<path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#dedede"/>
<path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/>
</g>
<path d="m0.75424 7.3773-0.22507-0.69269 7.9375 5.7669 7.9375-5.7669-0.22507 0.69269-7.7124 5.6034z" fill-opacity="0"/>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,7 +1,23 @@
#include "SequentialTask.h"
SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-1)
SequentialTask::SequentialTask(QObject* parent, const QString& task_name) : Task(parent), m_name(task_name), m_currentIndex(-1) {}
SequentialTask::~SequentialTask()
{
for(auto task : m_queue){
if(task)
task->deleteLater();
}
}
auto SequentialTask::getStepProgress() const -> qint64
{
return m_stepProgress;
}
auto SequentialTask::getStepTotalProgress() const -> qint64
{
return m_stepTotalProgress;
}
void SequentialTask::addTask(Task::Ptr task)
@ -15,16 +31,24 @@ void SequentialTask::executeTask()
startNext();
}
bool SequentialTask::abort()
{
bool succeeded = true;
for (auto& task : m_queue) {
if (!task->abort()) succeeded = false;
}
return succeeded;
}
void SequentialTask::startNext()
{
if (m_currentIndex != -1)
{
if (m_currentIndex != -1) {
Task::Ptr previous = m_queue[m_currentIndex];
disconnect(previous.get(), 0, this, 0);
}
m_currentIndex++;
if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
{
if (m_queue.isEmpty() || m_currentIndex >= m_queue.size()) {
emitSucceeded();
return;
}
@ -33,23 +57,27 @@ void SequentialTask::startNext()
connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
setStatus(tr("Executing task %1 out of %2").arg(m_currentIndex + 1).arg(m_queue.size()));
next->start();
}
void SequentialTask::subTaskFailed(const QString &msg)
void SequentialTask::subTaskFailed(const QString& msg)
{
emitFailed(msg);
}
void SequentialTask::subTaskStatus(const QString &msg)
void SequentialTask::subTaskStatus(const QString& msg)
{
setStatus(msg);
setStepStatus(m_queue[m_currentIndex]->getStatus());
}
void SequentialTask::subTaskProgress(qint64 current, qint64 total)
{
if(total == 0)
{
if (total == 0) {
setProgress(0, 100);
return;
}
setProgress(current, total);
setProgress(m_currentIndex, m_queue.count());
m_stepProgress = current;
m_stepTotalProgress = total;
}

View File

@ -9,13 +9,21 @@ class SequentialTask : public Task
{
Q_OBJECT
public:
explicit SequentialTask(QObject *parent = 0);
virtual ~SequentialTask() {};
explicit SequentialTask(QObject *parent = nullptr, const QString& task_name = "");
virtual ~SequentialTask();
inline auto isMultiStep() const -> bool override { return m_queue.size() > 1; };
auto getStepProgress() const -> qint64 override;
auto getStepTotalProgress() const -> qint64 override;
inline auto getStepStatus() const -> QString override { return m_step_status; }
void addTask(Task::Ptr task);
protected:
void executeTask();
protected slots:
void executeTask() override;
public slots:
bool abort() override;
private
slots:
@ -24,7 +32,19 @@ slots:
void subTaskStatus(const QString &msg);
void subTaskProgress(qint64 current, qint64 total);
signals:
void stepStatus(QString status);
private:
void setStepStatus(QString status) { m_step_status = status; };
private:
QString m_name;
QString m_step_status;
QQueue<Task::Ptr > m_queue;
int m_currentIndex;
qint64 m_stepProgress = 0;
qint64 m_stepTotalProgress = 100;
};

View File

@ -21,29 +21,27 @@
#include "QObjectPtr.h"
class Task : public QObject
{
class Task : public QObject {
Q_OBJECT
public:
public:
using Ptr = shared_qobject_ptr<Task>;
enum class State
{
Inactive,
Running,
Succeeded,
Failed,
AbortedByUser
};
enum class State { Inactive, Running, Succeeded, Failed, AbortedByUser };
public:
explicit Task(QObject *parent = 0);
virtual ~Task() {};
public:
explicit Task(QObject* parent = 0);
virtual ~Task() = default;
bool isRunning() const;
bool isFinished() const;
bool wasSuccessful() const;
/*!
* MultiStep tasks are combinations of multiple tasks into a single logical task.
* The main usage of this is in SequencialTask.
*/
virtual auto isMultiStep() const -> bool { return false; }
/*!
* Returns the string that was passed to emitFailed as the error message when the task failed.
* If the task hasn't failed, returns an empty string.
@ -54,52 +52,45 @@ public:
virtual bool canAbort() const { return false; }
QString getStatus()
{
return m_status;
}
QString getStatus() { return m_status; }
virtual auto getStepStatus() const -> QString { return m_status; }
qint64 getProgress()
{
return m_progress;
}
qint64 getProgress() { return m_progress; }
qint64 getTotalProgress() { return m_progressTotal; }
virtual auto getStepProgress() const -> qint64 { return 0; }
virtual auto getStepTotalProgress() const -> qint64 { return 100; }
qint64 getTotalProgress()
{
return m_progressTotal;
}
protected:
void logWarning(const QString& line);
protected:
void logWarning(const QString & line);
private:
private:
QString describe();
signals:
signals:
void started();
void progress(qint64 current, qint64 total);
virtual void progress(qint64 current, qint64 total);
void finished();
void succeeded();
void failed(QString reason);
void status(QString status);
public slots:
public slots:
virtual void start();
virtual bool abort() { return false; };
protected:
protected:
virtual void executeTask() = 0;
protected slots:
protected slots:
virtual void emitSucceeded();
virtual void emitAborted();
virtual void emitFailed(QString reason);
public slots:
void setStatus(const QString &status);
public slots:
void setStatus(const QString& status);
void setProgress(qint64 current, qint64 total);
private:
private:
State m_state = State::Inactive;
QStringList m_Warnings;
QString m_failReason = "";
@ -107,4 +98,3 @@ private:
int m_progress = 0;
int m_progressTotal = 100;
};

View File

@ -0,0 +1,68 @@
#include <QTest>
#include "TestUtil.h"
#include "Task.h"
/* Does nothing. Only used for testing. */
class BasicTask : public Task {
Q_OBJECT
friend class TaskTest;
private:
void executeTask() override {};
};
/* Does nothing. Only used for testing. */
class BasicTask_MultiStep : public Task {
Q_OBJECT
friend class TaskTest;
private:
auto isMultiStep() const -> bool override { return true; }
void executeTask() override {};
};
class TaskTest : public QObject {
Q_OBJECT
private slots:
void test_SetStatus_NoMultiStep(){
BasicTask t;
QString status {"test status"};
t.setStatus(status);
QCOMPARE(t.getStatus(), status);
QCOMPARE(t.getStepStatus(), status);
}
void test_SetStatus_MultiStep(){
BasicTask_MultiStep t;
QString status {"test status"};
t.setStatus(status);
QCOMPARE(t.getStatus(), status);
// Even though it is multi step, it does not override the getStepStatus method,
// so it should remain the same.
QCOMPARE(t.getStepStatus(), status);
}
void test_SetProgress(){
BasicTask t;
int current = 42;
int total = 207;
t.setProgress(current, total);
QCOMPARE(t.getProgress(), current);
QCOMPARE(t.getTotalProgress(), total);
}
};
QTEST_GUILESS_MAIN(TaskTest)
#include "Task_test.moc"

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