Compare commits

...

737 Commits
1.0.2 ... 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
9f8983b570 Merge pull request #235 from Scrumplex/chore-bump-1.1.0
Bump to 1.1.0
2022-03-12 13:34:36 +00:00
e42c5b00a4 Merge pull request #251 from flowln/fix_tr 2022-03-12 10:58:36 +01:00
a3d7ad731d fix missing translation strings
my mistake, sorry! ToT
2022-03-11 18:43:17 -03:00
dc98609ef8 Merge pull request #241 from PolyMC/ZekeSmith-move-to-wiki-1 2022-03-11 10:42:13 +01:00
c799faaca6 fix: typos 2022-03-11 09:21:59 +01:00
07e4c4d189 Merge pull request #242 from deadmeu/develop
Fix missing space in "No Accounts" message
2022-03-11 14:53:05 +11:00
c4a8fd353c Merge pull request #243 from dada513/mx_button 2022-03-10 18:52:57 +01:00
91524d6d6e Merge pull request #247 from txtsd/actions_fix
Fix Ubuntu system Qt failure
2022-03-10 23:45:32 +11:00
c1201997a3 Fix Ubuntu system Qt failure 2022-03-10 13:38:16 +05:30
d814e21f0d add matrix button 2022-03-08 18:41:23 +01:00
49d122a2c4 Fix missing space in "No Accounts" message 2022-03-08 23:24:11 +10:00
0813eba367 Update BUILD.md 2022-03-08 19:09:54 +10: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
dc9e250868 Merge pull request #232 from Scrumplex/fix-help-links
Switch to polymc.org wiki
2022-03-08 01:22:34 +11:00
b6cf0359fa Merge pull request #230 from Scrumplex/fix-iconthemes
Reorganize icon themes
2022-03-08 01:20:35 +11: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
ae39d16c11 chore: bump to 1.1.0 2022-03-06 11:40:11 +01:00
b93daf1fb7 fix: update news links to point to polymc.org 2022-03-06 11:32:06 +01:00
6545d250e8 refactor: move help URL into buildconfig 2022-03-06 11:31:50 +01:00
b162351ff4 fix: switch to polymc.org wiki 2022-03-05 21:49:13 +01:00
53468ea474 Merge pull request #221 from flowln/install_button 2022-03-05 20:43:44 +01:00
3697d70b48 fix: reorganize icon themes
Rename MultiMC to Legacy
Simple (Colored) is now the first icon theme
Custom is now the last icon theme, which also fixes a loading issue when
Legacy was selected
Fix loading of Legacy theme
2022-03-05 20:29:54 +01:00
e0c025b162 fix extra spacing in resource packs and shader packs, and move button up
hopefully now its finally ok
2022-03-03 09:51:46 -03:00
9e443faba3 hack: hide 'Download Mods' button when not in the mods tab 2022-03-03 04:02:22 -03:00
f95cebaf06 change 'Install Mods' -> 'Download Mods' and change position 2022-03-03 01:10:10 -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
ca211558b5 Merge pull request #216 from txtsd/ignore_paths
Don't build when updating non-code
2022-03-02 11:48:45 +11:00
3a03f90831 Ignore certain paths for CI 2022-03-02 01:17:08 +05:30
9020f632b2 Merge pull request #214 from PolyMC/ZekeSmith-newReadme
Modify readme to use website
2022-03-01 16:56:41 +01:00
8bdd2befe9 Merge pull request #205 from timoreo22/fix-version-select
Fixed wrong version info
2022-03-01 16:56:10 +01:00
ebececf8c6 Update and link latest build to actions 2022-03-01 23:19:30 +10:00
e1f28be151 Merge pull request #163 from txtsd/windows_data_dir
Replace build layouts with Launcher_PORTABLE cmake flag
2022-03-02 00:03:31 +11:00
10231aa404 Modify readme to use website 2022-03-01 10:33:59 +10:00
139ff82432 Merge pull request #207 from flowln/curseforge_api 2022-02-28 13:35:58 +01:00
4e8f075ff3 fix: Do not loop when its not a fabric mod on Flame version validation
Since there's no validation for forge mods since the start, we were just
looping with no porpuse in this situation.
2022-02-27 22:02:43 -03:00
148775b3e9 Update FMLLIBS_BASE_URL
Updated FMLLIBS_BASE_URL to https://files.polymc.org/fmllibs/

Fixes #208
2022-02-27 19:40:52 +00:00
075d900d45 fix: Always tell Flame API which modloader we are using
Fixes #206 partially. Although we don't list mods that have no
compatibility with the mod loader we are using, mods that have support
for both loaders still show up, and the versions for both the loaders
are still shown.

Also simplifies a little the logic in
FlameModIndex::loadIndexedPackVersions
2022-02-27 16:07:45 -03:00
5d1ca33b84 Apply suggestions from code review
Co-authored-by: LennyMcLennington <lenny@sneed.church>
2022-02-27 08:35:47 -08:00
ccc493cb2b Cleanly free NetJob in flame modpack 2022-02-27 13:14:12 +01:00
2745325ae0 Fixed wrong version info 2022-02-27 11:55:24 +01:00
84e9ce71b0 Merge pull request #203 from glowiak/patch-4 2022-02-27 09:53:56 +01:00
88fc1e32ee Merge pull request #201 from Scrumplex/fix-instancetype-reregistration 2022-02-26 14:37:27 +01:00
4f975bfb04 Notify about needed AppBSD version 2022-02-26 13:04:35 +01:00
692b9cf0e0 Merge pull request #195 from babbaj/nix-refactor
nix: Use POLYMC_JAVA_PATHS
2022-02-26 07:34:19 +01:00
ae354688c9 Merge pull request #193 from flowln/develop
Allow for downloading multiple mods at once
2022-02-26 07:33:11 +01:00
c9bf7f9896 fix: load instances no matter their instance type 2022-02-26 00:31:37 +01:00
e8929599a5 nix: Use POLYMC_JAVA_PATHS 2022-02-25 16:47:47 -05:00
27f37315f8 Merge pull request #199 from Scrumplex/fix-translations 2022-02-25 17:47:08 +01:00
c4f4e9e620 merge upstream and resolve conflicts 2022-02-25 13:43:27 -03:00
f2b850ad20 Merge pull request #183 from timoreo22/fix-versions-segfault
Fixed segfault in mod download
2022-02-26 01:55:11 +11:00
ccc27d1b7c Merge pull request #192 from Scrumplex/refactor-remove-legacy-instances
Drop legacy instances
2022-02-26 01:54:15 +11:00
4835ec3f6d fix(i18n): update translations URL 2022-02-25 15:19:15 +01:00
40a9828fba fix: improve readability and set ok button as disabled by default 2022-02-23 19:17:33 -03:00
04840d0638 fix(ui): add translation func to text in the confirm dialog 2022-02-23 14:44:55 -03:00
38f12c50f7 Merge branch 'PolyMC:develop' into develop 2022-02-23 14:34:51 -03:00
ca8b62291f fix: use legacy data path if it exists 2022-02-23 16:22:53 +05:30
69d01204e0 Implement PR suggestions 2022-02-23 16:22:53 +05:30
1e3b896fda Replace layouts with LAUNCH_PORTABLE 2022-02-23 16:22:23 +05:30
9e35560554 Merge pull request #158 from txtsd/actions
CI: Release builds and workflow
2022-02-23 10:36:47 +01:00
f9d4751ec0 Use System Qt for generic Linux build 2022-02-22 20:40:16 +05:30
a66e6a413f Merge pull request #169 from Scrumplex/rfc-template
Add issue template for RFCs
2022-02-23 00:10:09 +10:00
2c911a5475 Merge pull request #174 from dada513/readme_better
Prepare readme for 1.1.0, mark unofficial packages as unofficial
2022-02-23 00:09:56 +10:00
e2c2a38005 Merge pull request #186 from theglitch76-forks/develop
Enable WSL support
2022-02-22 08:23:57 +01:00
aa4a6bb3be Merge pull request #172 from Scrumplex/fix-update-client-id
Switch to new MSA Client ID
2022-02-22 08:23:42 +01:00
4af020161d Merge pull request #180 from Scrumplex/feat-msa-clientid-detection
Detect MSA Client ID change
2022-02-22 08:23:28 +01:00
f8b0d6453a fix: sort mod list in confirmation dialog 2022-02-21 23:25:33 -03:00
0102e91940 feat: add confirm dialog for installing mods
When selecting multiple mods at once, it can become hard to keep track
of which ones you selected.

To address this, a dialog is now displayed
when you finish selecting the mods to download, showing you which ones
you selected and their filenames. From there, you can either accept it
and download the mods, or you can cancel it and go back to the mod
selection dialog.
2022-02-21 23:09:14 -03:00
1004211a66 fix(ui): change text in selection button when there's no valid version 2022-02-21 22:52:50 -03:00
f5cf4eb45f feat(ui): allow downloading multiple mods from CurseForge at once 2022-02-21 21:53:21 -03:00
512395e3f1 feat(ui): allow downloading multiple mods in Modrinth at once 2022-02-21 21:34:53 -03:00
9c6727e27f feat: change task container in ModDownloadDialog to a QHash
Previously, we used a unique_ptr to a ModDownloadTask to keep track of
the selected mod to download when we accepted the dialog.

In order to allow multiple mods to be selected at once for download,
this has been changed to a QHash where the key is the mods name (since
it doesn't seem right to allow for multiple versions of the same mod to
be downloaded at once), and the value is a pointer to the corresponding
ModDownloadTask.
2022-02-21 21:34:06 -03:00
624ab25cd4 refactor: set default InstanceType to OneSix 2022-02-21 22:59:07 +01:00
a70d1f1a91 refactor: drop LegacyInstance 2022-02-21 22:30:44 +01:00
3059f13011 refactor: drop migration for pre-component instances 2022-02-21 22:11:10 +01:00
6d1f9d4d02 fix 2022-02-21 12:44:34 -05:00
d3e7d30ee0 Create releases in a separate workflow 2022-02-21 21:48:31 +05:30
5bbb4f31dc Add generic Linux system builds 2022-02-21 21:48:31 +05:30
da70122d9c remove notifications 2022-02-20 19:23:08 -05:00
8556ff5eac Revert ba6a97557a0d90d77e9eba560931414e39042447
Let evil win.
2022-02-20 15:00:23 -06:00
adacab3349 Fixed segfault when closing window while version info download is still going 2022-02-19 15:17:45 +01:00
613b351f13 Merge pull request #168 from Kloenk/nix_flake_meta
Nix flake meta
2022-02-19 08:25:30 +01:00
80a29af497 fix: typo for account disabled error messages 2022-02-18 19:18:29 +01:00
7e1fad55d9 Merge pull request #178 from Scrumplex/add-contributor-covenant
Add Contributor Covenant 2.1
2022-02-19 00:09:59 +10:00
9b7cd029a7 Grab short version 2022-02-18 19:27:15 +05:30
c5d9944993 feat(accounts): interrupt MSAStep when client ID doesn't match 2022-02-18 12:32:24 +01:00
14717396eb feat(accounts): save client id in MSAStep 2022-02-18 12:32:24 +01:00
9c71f364d2 feat(accounts): add disabled account state 2022-02-18 12:32:24 +01:00
be910374dc feat(accounts): support msa-client-id value 2022-02-18 12:32:24 +01:00
10de75623e readd all packages 2022-02-18 10:28:17 +01:00
7fc55b58fe chore: clarify trolling in code of conduct 2022-02-18 09:44:27 +01:00
12c8a04458 Merge pull request #173 from Scrumplex/fix-application-cpp
fix: improve code readability in Application.cpp
2022-02-17 23:43:59 +00:00
796e58b6f2 Merge pull request #176 from PolyMC/upstream-merge
upstream merge
2022-02-17 23:34:50 +00:00
a7d37fa69a chore: add Contributor Covenant 2022-02-17 23:55:34 +01:00
7b4b997a34 Merge remote-tracking branch 'upstream/develop' into develop 2022-02-17 15:47:43 -05:00
6b4469c6cc fix: combine errors if --launch is missing 2022-02-17 15:29:09 +01:00
107a0ea852 fix2 2022-02-17 13:19:35 +01:00
6d7676202f unofficial => community maintained 2022-02-17 12:53:44 +01:00
0305b7a1fd Prepare readme for 1.1.0, mark unofficial packages as unofficial 2022-02-17 11:55:09 +01:00
02384f81c7 Merge pull request #131 from glowiak/patch-1
Add Slackware package
2022-02-17 11:32:17 +01:00
4536b19512 Merge pull request #171 from DioEgizio/fix-org.polymc-macos
Change: set MACOSX_BUNDLE_GUI_IDENTIFIER to org.polymc (fixes org.multimc.PolyMC)
2022-02-16 21:07:50 +01:00
45f89c6255 Merge branch 'develop' into patch-1 2022-02-16 18:36:28 +01:00
b1cf77e847 update 2022-02-16 18:31:34 +01:00
037b0d7190 fix: improve code readability in Application.cpp 2022-02-16 17:33:28 +01:00
ff17202b43 refactor: switch to new MSA Client ID 2022-02-16 17:03:13 +01:00
a3d8313dcb Change: set MACOSX_BUNDLE_GUI_IDENTIFIER to org.polymc instead of org.multimc 2022-02-16 15:45:16 +01:00
36841eaf63 chore(github): add issue template for RFCs 2022-02-16 12:38:28 +01:00
e24a183dad Only trigger GH Release on stable branch 2022-02-15 14:38:26 +05:30
8596753a63 Allow building release builds and…
…trigger GH release using tags
2022-02-15 14:24:52 +05:30
51183bef33 nix: add meta attribute 2022-02-14 21:08:10 +01:00
2cd837896d Merge pull request #160 from Scrumplex/custom-be-gone 2022-02-14 16:56:53 +01:00
c75ae71190 flake.nix: drop aarch64-darwin
Currently qtbase is broken on aarch64-darwin, therefor dropping support, so the check can succeed
2022-02-14 15:45:51 +01:00
48c20f5aaa Merge pull request #164 from Scrumplex/rebase-stable
Merge stable into develop
2022-02-14 10:10:35 +01:00
929a035f96 Revert "make wsl work"
This reverts commit 5779f20fa1633577889b7bda839c5486eb2ba922.
2022-02-13 18:47:54 +00:00
5779f20fa1 make wsl work 2022-02-13 13:35:15 -05:00
384e0df9e1 Merge remote-tracking branch 'upstream/stable' into rebase-stable 2022-02-13 18:08:41 +01:00
a5b06514c6 Merge pull request #161 from Scrumplex/custom-clientid
Add MSA-Client-ID override in UI
2022-02-13 14:06:27 +00:00
a309f4e721 fix: MSA = Microsoft Authentication 2022-02-12 21:27:35 +01:00
159d868b77 fix(ui): explain why 'Add Microsoft' might be disabled 2022-02-12 21:27:35 +01:00
0854e83ce4 feat: implement MSA client id override
Closes #11
2022-02-12 21:27:32 +01:00
bb02226870 feat(ui): add custom MSA client id setting 2022-02-12 21:05:42 +01:00
9ddbaaf7e8 feat: use commit hash for channel if ref not available 2022-02-12 19:04:45 +01:00
3b7cc4391a fix: don't use custom for version channel
Closes #159
2022-02-12 18:17:56 +01:00
70a055bc27 Merge pull request #143 from Scrumplex/refactor-link-nbtpp-static 2022-02-12 17:47:38 +01:00
61db1c46be fix: use our own prefix for rainbow lib 2022-02-12 17:02:54 +01:00
a60b2feb5f Revert "refactor(build): link rainbow statically"
Windows build fails for some reason. Needs to be investigated later

This reverts commit 812f00eb81158bfb4c2d61b228c0c1c796641ac1.
2022-02-12 16:56:35 +01:00
6ba031f048 refactor(build): link iconfix statically 2022-02-12 16:10:53 +01:00
812f00eb81 refactor(build): link rainbow statically 2022-02-12 16:10:46 +01:00
2f6973e08b Merge pull request #157 from txtsd/actions_fix
Adjust OpenSSL step
2022-02-12 03:15:11 -08:00
fb14796ed7 Adjust OpenSSL step 2022-02-12 14:56:15 +05:30
7d912726d0 Merge pull request #134 from glowiak/patch-2
OpenBSD support and slackware build instructions
2022-02-12 03:30:24 +00:00
e3c8eb062c Merge pull request #149 from ZekeSmith/patch-1
License for assets
2022-02-12 03:29:59 +00:00
3cf81faabc change "loader mods" to "mods"
Closes: #128
2022-02-11 22:09:47 -05:00
0df605e559 Merge pull request #155 from txtsd/actions
fix(ci): Unsplit OpenSSL step
2022-02-12 02:22:23 +00:00
e97a6ef957 Unsplit OpenSSL step 2022-02-12 00:19:11 +05:30
c4dd8d9c72 Update LICENSE 2022-02-12 01:03:33 +10:00
bcfa3246cb Merge pull request #146 from dada513/macos_application_support
[MACOS] Move app data to Application Support
2022-02-11 13:52:56 +00:00
f67871e79e refactor(build): link nbt++ statically 2022-02-11 14:24:01 +01:00
11f892380e Merge pull request #145 from dada513/metainfix
Update metadata
2022-02-11 13:54:14 +01:00
fd72cb034c Merge pull request #140 from txtsd/actions
CI: Build AppImages
2022-02-11 12:38:03 +00:00
b9be8d08d2 Remove superfluous variable 2022-02-11 18:05:26 +05:30
33d369d78c Add missing deploy flags 2022-02-11 18:05:26 +05:30
0e6e6a7521 Remove generic Linux builds
They don't necessarily run on all distros
2022-02-11 18:05:26 +05:30
eb692c2ee9 Split OpenSSL step 2022-02-11 18:05:26 +05:30
3eee38fedd Make 32bit Windows build instead 2022-02-11 18:05:26 +05:30
0ba61bb590 Implement even more PR suggestions 2022-02-11 18:05:26 +05:30
9497485103 Implement more PR suggestions 2022-02-11 18:05:26 +05:30
551d9c86ba Implement PR suggestions 2022-02-11 18:05:26 +05:30
e61e827eb9 Use Adoptium JREs 2022-02-11 18:05:26 +05:30
92a5b12bd9 Remove PrefersNonDefaultGPU 2022-02-11 18:05:26 +05:30
35d1330fe2 Build AppImages for Linux
Now builds windows and macOS builds,
with windeployqt and macdeploqt.
Also adds SHA to the build filenames.
2022-02-11 18:05:26 +05:30
b4e0b7584a newlines 2022-02-11 13:17:11 +01:00
2341212337 Merge pull request #150 from dada513/fix_kwin_icon
Fix freedesktop icons. Again
2022-02-11 12:05:01 +00:00
53ea261350 Merge pull request #151 from dada513/rss_not_begone
Re-add RSS feed with the new PolyMC website
2022-02-11 12:03:29 +00:00
a17e5d0a4d Merge pull request #129 from timoreo22/fix-mod-name
Fixed the download menu putting the wrong name
2022-02-10 23:41:27 +00:00
5d4a66ed8a Merge pull request #152 from Scrumplex/update-translations-url
Update link to translations platform (Weblate)
2022-02-10 23:38:47 +00:00
8d2e7db178 fix: update link to translations platform 2022-02-10 14:55:52 +01:00
383c93ff01 Merge pull request #148 from helpimnotdrowning/develop
Fix Weblate link in README
2022-02-10 13:40:12 +00:00
13d41bde7f remove unused parsing of dates (bloat) 2022-02-10 13:57:18 +01:00
d42d6fe25a fix rss format 2022-02-10 13:57:06 +01:00
beaac54dc9 Merge remote-tracking branch 'polymc/develop' into rss_not_begone 2022-02-10 13:14:30 +01:00
70f8cb81b8 Initial RSS re-add and removed hardcoded strings 2022-02-10 13:14:25 +01:00
f8ca6b4867 Revert "refactor: remove news feed"
This reverts commit 361ce7818ec8891e9a35bdfac4cdea77a0b6a949.
2022-02-10 12:55:07 +01:00
49f5f67467 Update screenshots to use new site 2022-02-10 12:26:33 +01:00
35d2ae3ef7 Remove drama from readme and remove mmc discord link 2022-02-10 11:21:25 +00:00
22ca572ae0 ci: rebuild 2022-02-10 09:32:12 +01:00
619fcbfabf rename LAUNCHER_DESKTOPNAME to LAUNCHER_DESKTOPFILENAME 2022-02-10 08:56:34 +01:00
292869141f Merge remote-tracking branch 'polymc/develop' into fix_kwin_icon 2022-02-10 08:05:17 +01:00
ca9929214d Merge remote-tracking branch 'polymc/develop' into macos_application_support 2022-02-10 08:04:59 +01:00
121ad4e4bf Merge remote-tracking branch 'polymc/develop' into metainfix 2022-02-10 08:04:38 +01:00
2f87a4477e Fix desktop id for GH-150 2022-02-10 07:53:04 +01:00
d72c511131 Revert "Fix freedesktop icons" and fix icon on kwin 2022-02-10 07:46:41 +01:00
8b68c06547 License for assets
The PolyMC logo and assets are licensed under the CC BY-NC-SA 4.0 having it in this folder should help to clear this up.
2022-02-10 13:58:19 +10:00
b911151786 Fix Weblate link in README
original link was missing /projects/ dir and leading to a nonexistant page
2022-02-09 21:40:57 -06:00
7531a2894b Missed a closing parenthesis in README.md, oops. 2022-02-09 23:13:33 +00:00
5b507a8944 Add info about translating PolyMC to the README 2022-02-09 23:00:03 +00:00
d2f86cbf32 Move app data to Application Support 2022-02-09 12:23:18 +01:00
08dff6613b remove redundant data 2022-02-09 08:21:51 +01:00
901ec15dc8 Update metadata 2022-02-09 08:19:34 +01:00
5284d604ef translations 2022-02-09 00:02:51 +00:00
b2b4ab3f0c Update BUILD.md 2022-02-07 10:11:36 +01:00
b646fc5a13 Update build instructions for Slackware 14.2 2022-02-06 12:18:39 +01:00
d35cbfd9c4 Add Slackware instructions 2022-02-06 12:11:20 +01:00
f25152e068 Update BUILD.md 2022-02-06 12:06:08 +01:00
dd8946b15a Update BUILD.md 2022-02-06 12:03:17 +01:00
305350fdc8 Update BUILD.md 2022-02-06 09:41:13 +01:00
f31d5372e7 Update BUILD.md 2022-02-06 09:39:14 +01:00
ca1a2bbe2c Add OpenBSD instructions 2022-02-06 09:38:26 +01:00
dba9199e58 Support OpenBSD in UpdateController.cpp 2022-02-06 09:35:48 +01:00
e806903d7e Support OpenBSD without patches 2022-02-06 09:32:55 +01:00
41d8e3cbd7 add arches 2022-02-05 16:07:31 +01:00
5e32783c4e Update README.md 2022-02-05 16:05:34 +01:00
fdc3a4104b Add OpenBSD 2022-02-05 16:03:16 +01:00
8199941a81 Fix typo 2022-02-05 14:04:34 +01:00
651d237200 Update README.md 2022-02-04 21:07:34 +01:00
6f5b380199 Update README.md 2022-02-04 20:58:12 +01:00
c746d77a06 Update README.md
Co-authored-by: dada513 <dada513@protonmail.com>
2022-02-04 20:42:30 +01:00
9ab3841570 change fbsd icon
Co-authored-by: dada513 <dada513@protonmail.com>
2022-02-04 20:40:47 +01:00
3a28741cc3 Add FreeBSD 2022-02-04 18:12:32 +01:00
22f7a85cf2 Add Slackware package 2022-02-04 17:59:37 +01:00
86935068f5 Fix wrong mod file name 2022-02-04 16:24:19 +01:00
00e12b776b Merge pull request #126 from Scrumplex/fix-quazip-build
fix: link QuaZip statically
2022-02-04 07:40:09 -05:00
3b96a9a8fa Merge pull request #124 from babbaj/develop
nix: fix quazip input
2022-02-04 07:34:13 -05:00
5ac5c767e0 Merge pull request #125 from dada513/based_build_md
fix build.md
2022-02-04 07:33:22 -05:00
f1d3d4a366 fix: link QuaZip statically 2022-02-04 13:24:13 +01:00
1160066f0d fix build.md 2022-02-04 11:06:04 +00:00
8d603d6162 nix: fix quazip input 2022-02-04 02:13:48 -05:00
076efc4cb2 Merge branch 'update-quazip' of git://github.com/Scrumplex/PolyMC into develop 2022-02-03 14:14:12 -05:00
2c62a34c2f Merge branch 'feature/offline_mode' into develop 2022-02-03 13:59:25 -05:00
2177aa2a6b Merge branch 'offline-mode-accounts' of git://github.com/NyaomiDEV/PolyMC into feature/offline_mode 2022-02-03 13:54:27 -05:00
e8a4902a3d Merge branch 'feature/download_mods' into develop 2022-02-03 13:53:30 -05:00
e2952061af Merge branch 'feature/download_mods' of git://github.com/timoreo22/PolyMC into feature/download_mods 2022-02-03 13:45:20 -05:00
fcc4420cfe Merge branch 'feature/close_after_launch' into develop 2022-02-03 13:44:09 -05:00
f5358aa1ca Merge branch 'develop' into feature/close_after_launch 2022-02-03 13:43:44 -05:00
3d3f9a8609 make closeAfterLaunch good 2022-02-03 12:50:24 -05:00
1f176fcb7b fix aur formatting in README 2022-02-03 12:47:16 -05:00
3ca661127f NOISSUE Add missing tooltip for Export Instance action 2022-02-03 18:09:51 +01:00
407f9d9ef0 Merge remote-tracking branch 'upstream/develop' into develop 2022-02-02 11:17:04 -05:00
bff683e6d4 Merge pull request #108 from redstrate/improve_about_page
Improve the About page
2022-02-02 09:17:30 -05:00
770da6317e Merge pull request #122 from txtsd/actions
GitHub Actions for crossplatform builds
2022-02-02 09:14:12 -05:00
cf3c2482c9 fix some windows branding
Closes: #121
2022-02-02 08:46:26 -05:00
2001c5dec7 Merge pull request #123 from Skyblueborb/patch-1
Fix Gentoo Command Syntax
2022-02-02 08:41:31 -05:00
80cf716c98 Fix Gentoo Command Syntax
The proper syntax for adding repos is `eselect repository enable <repo>`
2022-02-02 10:34:26 +01:00
37e1962845 Add build.yml 2022-02-02 06:28:00 +00:00
f8c5d80c66 Merge pull request #4480 from Oreoezi/develop
Update BUILD.md
2022-02-01 22:33:45 +01:00
11841c47e6 Double braindead combo 2022-02-01 22:23:34 +01:00
71b1ac9f34 Fix braindead moments 2022-02-01 21:56:52 +01:00
eda06df878 Update BUILD.md 2022-02-01 20:33:38 +00:00
c4cb7ddc4f fix: bring back JAR Folder mods
what is this?
2022-01-31 21:40:59 +01:00
a8089b76c0 fix: bring back instance exports 2022-01-31 21:40:59 +01:00
71516e6c72 fix: set Launcher_FORCE_BUNDLED_LIBS=on by default
We need to wait for a new QuaZip release to become widely available, until we can turn this off again
2022-01-31 21:40:59 +01:00
88686ef065 refactor: restructure CMake to support future Qt versions 2022-01-31 21:40:59 +01:00
0442b80a2c refactor: simpler includes for quazip 2022-01-31 21:40:59 +01:00
81c72c2038 refactor: bring back methods that need to be reimplemented 2022-01-31 21:40:59 +01:00
3aa809b8c0 refactor: add in-tree QuaZip 2022-01-31 21:40:59 +01:00
efa414c442 refactor: initial migration to QuaZip 1.2
Let's move off our custom QuaZip. In the olden times we needed the
custom version of QuaZip, as it was basically unmaintained and on
SourceForge (eww). But nowadays it's maintained and on GitHub. See
new GitHub page: https://github.com/stachenov/quazip
2022-01-31 21:40:59 +01:00
c39da093bf change COPR to polymc/polymc 2022-01-31 12:35:30 -05:00
aa2c27bf69 Update to Modrinth API V2 2022-01-31 17:18:11 +01:00
1f92125a7f Move RPM package to a separate repo. 2022-01-31 10:41:05 -05:00
5c48b7dfab Merge pull request #104 from dada513/makedeb
Remove debian packages from repo
2022-01-31 10:40:12 -05:00
d664361b15 remove deb packaging 2022-01-31 10:36:57 -05:00
813de1c703 pkgs: remove debian packaging from repo 2022-01-31 16:03:50 +01:00
02f24117f0 better package list 2022-01-31 10:00:25 -05:00
7a7a937f1e remove changelog because it's annoying 2022-01-31 09:54:16 -05:00
0211ee3ef1 Add "PolyMC Contributors" to Credits section
This also adds a link to the PolyMC Contributors page on Github.
2022-01-31 09:09:58 -05:00
c569bfbe6d Merge pull request #111 from DioEgizio/patch-1
improve a bit MacOS build instructions
2022-01-30 11:33:42 -05:00
b925338688 Merge pull request #112 from muscaln/flake
Nix updates
2022-01-30 11:32:49 -05:00
2cf04d034a Merge pull request #4300 from Ghosty141/feature/screenshot_copy
GH-4044 Implemented copy screenshots to the clipboard
2022-01-30 16:11:47 +01:00
049aafd0a1 Merge pull request #4461 from Jan200101/rpm
Update rpm spec to support OpenSuse and conform to Fedora guidelines
2022-01-30 16:07:51 +01:00
e0a04c5031 Lock offline mode support behind insertion of at least one Minecraft account
Co-Authored-By: Naomi Calabretta <tony0000.ac@gmail.com>
2022-01-30 02:42:29 +01:00
9d23ac562f Add offline mode support 2022-01-30 02:35:56 +01:00
0065a29901 Close after Launch setting 2022-01-29 19:04:44 -05:00
8ea1ebaf1b I haven't tested qt 5.6, i use 5.12 2022-01-29 18:14:56 +01:00
5c2d3e430d Merge branch 'develop' into patch-1 2022-01-29 18:10:46 +01:00
b710b719a8 nix: use .desktop file provided by cmake 2022-01-29 17:38:12 +03:00
7df5091fdc flake.lock: Update
Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/74f7e4319258e287b0f9cb95426c9853b282730b' (2021-11-28)
  → 'github:numtide/flake-utils/846b2ae0fc4cc943637d3d1def4454213e203cba' (2022-01-20)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/b2737d4980a17cc2b7d600d7d0b32fd7333aca88' (2022-01-11)
  → 'github:nixos/nixpkgs/945ec499041db73043f745fad3b2a3a01e826081' (2022-01-26)
2022-01-29 17:35:50 +03:00
5abb97362f Merge pull request #102 from dada513/rework_docs
docs: rework README and BUILD
2022-01-29 09:24:08 -05:00
b34239ebc6 adoptium 2022-01-29 11:00:13 +01:00
7ef6c586c5 update readme 2022-01-29 10:59:04 +01:00
9d36cf4b5a fix another typo (omg I'm doing too commits) 2022-01-29 10:26:13 +01:00
04be2404ce fix typo 2022-01-29 10:24:49 +01:00
7f4fd04cfe not needed actually 2022-01-29 10:24:06 +01:00
b2bcdb9d9b fix a typo+explain better 2022-01-29 10:18:12 +01:00
d81e2bb0b0 extra refinements 2022-01-29 10:14:00 +01:00
177c10bb0f fix MacOS build instructions 2022-01-29 10:12:04 +01:00
304775952f EVEN MORE BASED 2022-01-29 09:40:27 +01:00
ca00103ee2 make packaging based 2022-01-29 08:56:04 +01:00
3aa9f5c376 Update rpm spec to support OpenSuse and conform to Fedora guidelines 2022-01-28 19:42:30 +01:00
efc44c56a6 Fix button being present in other pages 2022-01-28 19:32:42 +01:00
8b790a6dd9 Merge branch 'PolyMC:develop' into feature/download_mods 2022-01-28 18:12:35 +01:00
f36930d812 Merge pull request #107 from redstrate/fix_icon_bug
Fix icons changing when exiting the settings window
2022-01-28 09:31:41 -05:00
232295bda7 add gentoo instructions 2022-01-28 09:12:55 +01:00
451768ccf9 Merge remote-tracking branch 'upstream/develop' into rework_docs 2022-01-28 09:10:47 +01:00
c1aaf89baa Improve the About page
Improves #106. This more clearly marks the original MultiMC contributors,
and now correctly hides the "Build Platform" if this is set as empty. The
version label is now moved under the "PolyMC" title so it looks just a
little bit better (and matches other applications). The copyright on the
"About" page now correctly attributes the MultiMC contributors just like on
the "License" page.
2022-01-27 19:06:07 -05:00
5ac528f141 Fix icons changing when exiting the settings window 2022-01-27 18:37:57 -05:00
204e3dca22 fix version 2022-01-27 17:23:50 -05:00
33aac2985a Merge pull request #105 from Scrumplex/rss-begone
Remove news
2022-01-27 17:00:15 -05:00
361ce7818e refactor: remove news feed
Closes #63
2022-01-27 22:59:20 +01:00
ad6e3a0868 Fix meta 2022-01-27 16:58:28 -05:00
fd2269ac15 Fix meta 2022-01-27 16:54:05 -05:00
14a8ead6b4 fix conflict 2022-01-27 19:01:20 +01:00
bbf0508846 docs: rework README and BUILD 2022-01-27 18:59:44 +01:00
79314ee67b Merge pull request #103 from redstrate/fix_rpm_build
Fix RPM build instructions
2022-01-27 12:43:54 -05:00
86b0637ef7 Merge pull request #101 from redstrate/fix_freedesktop_icon
Fix Freedesktop icons
2022-01-27 09:56:39 -05:00
1c982b0182 Fix RPM build instructions 2022-01-27 13:17:26 +00:00
cd5faee7d7 Fix RPM spec referencing old desktop file 2022-01-27 08:06:35 -05:00
ec1e27031a Fix Freedesktop icons
This fixes #51. The desktop file is now exactly the same as the window class,
which is also now corrected to org.polymc.polymc. The file capitalization
is also consistent with other Freedesktop files as well.
2022-01-27 00:08:53 -05:00
02889b7a11 Merge pull request #67 from PolyMC/feature/no_paste_ee
Full replacement of paste.ee
2022-01-26 17:40:49 -05:00
0eff21a4f1 Validate Pastebin URL with regex 2022-01-26 00:34:02 +00:00
0680945839 Merge pull request #96 from dada513/develop
rebase with upstream
2022-01-24 19:36:31 -05:00
631e670775 Merge pull request #99 from Jan200101/PR/rpm-opensuse
remove explicit dependencies, correct dependencies to work on OpenSuse
2022-01-24 18:40:44 -05:00
4edd2cff9f remove explicit dependencies, correct dependencies to work on OpenSuse 2022-01-24 23:15:54 +01:00
0235eb5c28 Fix error message
The code is trying to get a string from a json object, and if that fails it should log "is not a string", not "is not a timestamp".
2022-01-24 11:44:47 +01:00
8804b035b2 NOISSUE log server response when failing to fetch profile 2022-01-24 11:44:47 +01:00
54e3438e37 NOISSUE correctly set http status code in auth reply 2022-01-24 11:44:47 +01:00
ddfed7bb87 NOISSUE in java checker, ignore invalid lines altogether
Declaring them as errors is just causing problems because Java
randomly prints garbage to STDOUT now.
2022-01-24 11:44:47 +01:00
70c04745ee NOISSUE add some logging to profile fetching failures 2022-01-24 11:44:47 +01:00
63d4486855 Merge pull request #4447 from Stypox/patch-1
Fix error message
2022-01-24 10:32:14 +01:00
1d0e6bf453 Changed modrinth author data to not be a list 2022-01-24 07:23:01 +01:00
a2d88f6df4 Fixed spacing 2022-01-24 07:12:19 +01:00
019c77f9f7 Merge pull request #52 from oynqr/develop
Default to system locale language
2022-01-23 15:00:26 -05:00
5b5c5afc3a Merge pull request #88 from Scrumplex/launch-msa-login
Add open page & copy code button to MSA login dialog
2022-01-23 14:55:05 -05:00
af20b5ee0e support paste.polymc.org 2022-01-23 12:54:58 -05:00
a1b779da15 Merge pull request #95 from danielhuang/patch-1
Add StartupWMClass to desktop file
2022-01-23 12:05:39 -05:00
8b31c638f3 Fix error message
The code is trying to get a string from a json object, and if that fails it should log "is not a string", not "is not a timestamp".
2022-01-22 21:58:32 +01:00
3da69d8e53 Update org.polymc.PolyMC.desktop.in 2022-01-22 14:13:21 -05:00
dd76fb0ec7 feat(MSALogin): add open page & copy code button
Closes #55
2022-01-20 21:04:48 +01:00
caeab926bc PasteUpload: Trim whitespace from response body 2022-01-19 19:05:52 +00:00
35caa3c21a Merge pull request #87 from Scrumplex/themed-header-image
Header image's text color should follow GitHub theme
2022-01-19 13:06:45 -05:00
7022d3d401 fix(readme): header color should follow GH theme
As browser color scheme preference and GitHub theme can be different
from each other, let's follow GitHub theme instead of browser
preference.
2022-01-19 18:59:24 +01:00
6d22794cf9 Reduce spaghettiness 2022-01-19 09:47:09 +01:00
b50e584369 PasteUpload task changed to use 0x0.st's protocol
- Modified PasteUpload task to upload the log file to 0x0.st and other
  services with the same protocol.

- Modified Paste settings UI to allow the user to select a custom paste
  URL, simplified the settings page code.
2022-01-19 08:27:26 +00:00
affc2521aa Various fixes 2022-01-18 12:28:55 +01:00
63098b6f19 Merge pull request #4428 from MandipJoshi/patch-1
Update README.md copyright date changed
2022-01-17 10:00:40 +01:00
83e1dd285a Set default lang only if index received 2022-01-17 09:52:04 +01:00
b9beb3c7d2 Sort system locale to front of list 2022-01-17 09:52:04 +01:00
2dd2555a63 Update selected language automatically 2022-01-17 09:52:04 +01:00
126e6d13aa Use isEmpty instead of 0 length check 2022-01-17 09:52:04 +01:00
236c0166f6 Default to system locale language 2022-01-17 09:52:04 +01:00
9a33fb1f49 Update README.md 2022-01-17 12:09:36 +05:45
2c2c22ccf8 Merge pull request #82 from PolyMC/revert-offline-mode
Revert offline mode support (#81 and #50)
2022-01-17 03:56:27 +00:00
55597b458c Revert "Merge pull request #50 from bexnoss/offline-mode"
This reverts commit b4f750e7db40352111417ea89a9f375ae8c746ab, reversing
changes made to b19e3156154ba0dd232a3d165b1759c57e2858f2.
2022-01-17 03:45:47 +00:00
f55297eca9 Revert "Merge pull request #81 from bexnoss/fix-msa-account-refresh"
This reverts commit 0bc8baf1172d6967cdb2993826e3469ecd9aab66, reversing
changes made to 81fe41a038ee12ff2ee0200525b39e4ad650bec2.
2022-01-17 03:45:33 +00:00
0bc8baf117 Merge pull request #81 from bexnoss/fix-msa-account-refresh 2022-01-16 17:32:13 -05:00
5f9270ed4b Fix MSA account refresh 2022-01-16 23:30:17 +01:00
81fe41a038 Default to colored icons, update copyright
Closes: #74
2022-01-16 12:03:30 -05:00
0316cf88aa Merge pull request #78 from bexnoss/readme-svg-header 2022-01-16 10:33:35 -05:00
917f8a31e3 NOISSUE log server response when failing to fetch profile 2022-01-16 12:51:42 +01:00
aa770b63fb NOISSUE correctly set http status code in auth reply 2022-01-16 12:46:20 +01:00
c1bf31cb27 NOISSUE in java checker, ignore invalid lines altogether
Declaring them as errors is just causing problems because Java
randomly prints garbage to STDOUT now.
2022-01-16 12:05:40 +01:00
86d99f80c3 NOISSUE add some logging to profile fetching failures 2022-01-16 11:43:19 +01:00
975f77756d Added curseforge selection 2022-01-16 11:20:21 +01:00
8172dcd2d5 Replace PNG README header with SVG
Instead of GitHub specific MarkDown based theming this uses CSS in SVG.
2022-01-16 07:55:10 +01:00
b95c27ceef fix readme formatting 2022-01-15 21:26:00 -05:00
f78bb90ed9 GH-4125 fix it better 2022-01-15 16:25:52 -05:00
dc129fd886 GH-4125 workaround for java printing garbage to stdout on bedrock linux 2022-01-15 16:25:52 -05:00
621e0ba4a8 Added smart file selection
This might fail in a few special cases
2022-01-15 10:25:24 +01:00
f6de472da2 Added a no version message 2022-01-15 09:06:48 +01:00
4b37c46889 Filtering per mod loader & mc version 2022-01-15 08:51:47 +01:00
c371558883 Merge pull request #68 from GriffintheFolf/execname
Fix program executable name for shell script
2022-01-14 21:46:46 -05:00
0bbd0ac0b9 Change method of shell script fix per suggestion
The Launcher.in file is now modified rather than CMakeLists.txt
2022-01-14 19:28:10 -07:00
ac93c64cd4 Fix program executable name for shell script 2022-01-14 16:59:16 -07:00
6cd4375aff add arch linux package to readme
closes: #53
2022-01-14 18:39:25 -05:00
a606b47a22 pastebin URL app setting 2022-01-14 18:30:02 -05:00
a62155c1c9 preliminary stuff for paste.ee removal 2022-01-14 18:20:06 -05:00
b4f750e7db Merge pull request #50 from bexnoss/offline-mode
Offline Mode Support
2022-01-14 18:03:35 -05:00
b19e315615 Set maximum memory allocated to 4GB by default 2022-01-14 17:34:50 -05:00
41dba376a8 remove 5 from display name
Closes: #58
2022-01-14 17:33:34 -05:00
2896f70cd8 Removing copyrights 2022-01-14 22:07:54 +01:00
1a8c972aef Fixed icons
Also having a mod loader is now enforced
2022-01-14 20:22:15 +01:00
cdaa397dcf Reword offline mode disclaimer 2022-01-14 14:19:31 +01:00
9e6fa8f29a Added the downloading of the mods 2022-01-14 12:47:18 +01:00
4d599eb118 Added modrinth icon 2022-01-14 10:51:44 +01:00
4e9039be2d Start of mod downloading 2022-01-14 09:56:27 +01:00
395e265564 Add offline mode disclaimer 2022-01-14 00:01:05 +01:00
b07853c9ef Merge pull request #61 from meguminloli/develop 2022-01-13 13:55:29 -05:00
b635a7e693 update NIX.md 2022-01-13 15:43:29 +02:00
f84fc783b6 removed redundant recs
removed file
2022-01-13 15:29:10 +02:00
2301a934b0 Merge pull request #59 from A-UNDERSCORE-D/patch-1 2022-01-13 08:19:08 -05:00
60e9d2754a changed flake.nix
removed result
2022-01-13 13:14:50 +02:00
A_D
d06c2cacb1 Readd original MultiMC/Launcher copyright
The original MMC code remains Apache.
2022-01-13 09:59:16 +02:00
49c2bd477c Merge pull request #45 from cidkidnix/develop 2022-01-12 21:11:09 -05:00
46a3b4de6e Remove unnecessary semicolon 2022-01-12 18:41:33 +01:00
6ecc8c5496 Remove unnecessary license header 2022-01-12 14:57:32 +01:00
a1ff3b1ee3 Add offline mode support 2022-01-12 14:26:02 +01:00
d4b522b6cb Add offline mode UI 2022-01-12 10:36:26 +01:00
3b524e99cc Merge pull request #46 from muscaln/java 2022-01-11 14:44:21 -05:00
3329d94c9b Introduce POLYMC_JAVA_PATHS env 2022-01-11 18:24:37 +03:00
a12118f1a0 Sort java versions from current to oldest 2022-01-11 17:40:58 +03:00
5fe33a98a2 nix: remove patch due to breakage 2022-01-10 18:24:49 -06:00
1d8196e11a More rebranding
Closes: #39

Mostly done with rebranding now. We just need to translate some services
to PolyMC.
2022-01-10 12:47:35 -05:00
c7f6f94930 Merge pull request #42 from Eonfge/patch-1 2022-01-10 12:02:12 -05:00
131615811b Set PrefersNonDefaultGPU for hybrid devices
With the Property 'PrefersNonDefaultGPU', you can signal to dekstop environments like GNOME that you want to run the application using the more powerful secondary graphics card, if such a card is available. Specification: https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s06.html

With this change, you won't have to include a special prime-run script.
2022-01-10 14:55:18 +01:00
3fa6e22430 Merge pull request #40 from Jan200101/PR/rpm-1.0.5 2022-01-09 17:57:18 -05:00
c86ac772c8 Update RPM and build instruction 2022-01-09 21:51:56 +01:00
1cc7a193c2 add logo to different styles
Also fixed genicons to automate this.
2022-01-09 14:18:51 -05:00
e50d07f791 remove patreon stuff
Closes: #22

Update to 1.0.5

Remove "Forking/Redistribution" tab in About (why is it even there?)

Metainfo now corresponds to version

add discord

Completely removed Patreon.
2022-01-09 13:51:46 -05:00
b515cb478e fix empty exec line when binary_name is unset 2022-01-09 13:34:01 -05:00
29e9d65cb2 rpm readme update 2022-01-09 13:32:12 -05:00
42574f185e Merge pull request #38 from cidkidnix/develop
Nix: Package fixup
2022-01-09 13:28:32 -05:00
92872e957b nix: package fixup 2022-01-09 12:00:37 -06:00
20747dd50a Merge pull request #37 from Jan200101/PR/rpm
rework rpm spec
2022-01-09 13:00:14 -05:00
a83cb2f2b8 rework rpm spec 2022-01-09 18:50:00 +01:00
541f26b33a Merge pull request #29 from cidkidnix/develop 2022-01-09 10:58:51 -05:00
459aafbca4 Merge pull request #34 from muscaln/develop 2022-01-09 10:56:47 -05:00
9bd86f84de nix: make sure tarball is pointed to proper repo
Co-authored-by: Louis Bettens <lourkeur@users.noreply.github.com>
2022-01-09 08:37:47 -06:00
0ce1b68261 Don't import channel as root, import channel as user
Co-authored-by: Louis Bettens <lourkeur@users.noreply.github.com>
2022-01-09 08:35:52 -06:00
fe9ce7a329 Make instuctions more clear 2022-01-09 08:17:52 -06:00
8ccef671d5 Update instructions 2022-01-09 08:16:15 -06:00
957cd29dbf nix: add support for non-flake builds 2022-01-09 17:08:19 +03:00
72656d41df Merge branch 'develop' into develop 2022-01-09 04:16:15 -06:00
15f62e54ab Make readme reflect new flake changes 2022-01-09 04:12:55 -06:00
5a09dcae68 forgot linebreak 2022-01-09 00:19:21 -05:00
87af5f631d Update branding: New Logo (#30)
New logo
Co-authored-by: swirl <swurl@swurl.xyz>
2022-01-09 00:13:15 -05:00
27eca06947 rpm in readme 2022-01-08 23:55:59 -05:00
c63b5bb132 Merge pull request #32 from getchoo/add-rpm-packaging
add rpm build script and spec file
2022-01-08 23:52:05 -05:00
3b09ee97be Merge pull request #33 from getchoo/remove-wsl-detection
stop cmake from blocking builds on wsl
2022-01-08 23:51:10 -05:00
59ef13f032 add documentation for building a .rpm 2022-01-08 23:13:10 -05:00
390a90b361 stop cmake from blocking builds on wsl 2022-01-08 22:49:30 -05:00
2ca094bd57 add rpm build script and spec file 2022-01-08 22:44:18 -05:00
42eb011e3f Merge pull request #31 from muscaln/flake 2022-01-08 19:59:10 -05:00
4a9d9b268a nix: fix 'nix run' 2022-01-09 02:40:13 +03:00
ae3c613f6c nix: use user package set on overlay and switch to ninja 2022-01-09 01:36:28 +03:00
ccde63bbab add nix result path to .gitignore 2022-01-09 01:36:28 +03:00
9499acedab nix: fix overlay 2022-01-09 00:40:55 +03:00
2a760a8e32 Revert "nix: revert overlay changes and add conditionals to derivation for flake build" 2022-01-08 23:09:53 +03:00
6065b4dcf9 nix: revert overlay changes and add conditionals to derivation for flake build 2022-01-08 23:06:56 +03:00
9611b92b07 nix: fix build 2022-01-08 22:33:06 +03:00
d29d020d6f {nix,flake}: add submodules 2022-01-08 22:33:06 +03:00
8d4f8795de nix: update package and remove meta section since we are not on nixpkgs 2022-01-08 22:33:06 +03:00
b1fa551fd2 flake: updates 2022-01-08 22:33:06 +03:00
8d184958d8 nix: init flake 2022-01-08 22:32:49 +03:00
1e51827ba3 add LICENSE file explicitly
Closes: #24
2022-01-08 10:32:30 -05:00
2776453dfe Make README.md look better for nix 2022-01-08 09:31:50 -06:00
e544637333 Add to README.md 2022-01-08 09:30:51 -06:00
e665d52044 add missing char 2022-01-08 09:28:37 -06:00
0ec2170b5e Add documentation for nix package 2022-01-08 09:27:47 -06:00
83fcebe2a9 Merge pull request #25 from cidkidnix/develop 2022-01-08 10:17:39 -05:00
0399fa7d2a Fix wrong path in overlay 2022-01-08 09:15:24 -06:00
8d000d29fa Fix desktop file and move directories around 2022-01-08 09:12:44 -06:00
52420963cf GH-4125 fix it better 2022-01-08 12:26:16 +01:00
addf5f4e52 NOISSUE update README for clarity 2022-01-08 11:45:10 +01:00
03d7300732 GH-4125 workaround for java printing garbage to stdout on bedrock linux 2022-01-08 11:14:07 +01:00
d68980810a make sure we use our desktop file 2022-01-08 01:50:23 -06:00
2a88099094 fix build 2022-01-08 01:45:52 -06:00
069d4dd2d1 Opps forgot something 2022-01-08 01:42:24 -06:00
e8f56d399b Fix desktop file 2022-01-08 01:41:31 -06:00
73c0a0d43b Make nix support not rely on flakes 2022-01-08 01:34:32 -06:00
fc81b81c26 Add nixos support 2022-01-08 01:33:26 -06:00
2c7d248703 New pixel Ouroboros logo by @karolinaabb 2022-01-06 22:42:33 -05:00
2e43d6cffa match license in metainfo
Closes: #18
2022-01-06 22:37:37 -05:00
915c658a52 Merge pull request #17 from dada513/develop
Fix metainfo parsing
2022-01-04 16:44:23 -05:00
3dcc7dee6c cleaner difference between flatpak and normal manifest 2022-01-04 15:43:41 +01:00
07649b6388 Fix metainfo parsing 2022-01-04 07:31:10 +01:00
0e4ccaca02 fix icon and version
Closes: #16

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

Changed launcher.svg icon to temporary Ouroboros logo

fixed genicons again

Fix version to 1.0.3 (making tag rn)

Install the PolyMC icon properly.
2022-01-03 17:46:05 -05:00
b3d8ecb467 fix genicons.sh to new rDNS stuff 2022-01-03 15:54:08 -05:00
97d4b947d0 update README
grammar/punctuation
2022-01-03 15:42:44 -05:00
3613ffa80e rDNS for icons and desktop file, and metainfo
Closes: #12, #13
2022-01-03 15:42:09 -05:00
38a1772f86 Merge pull request #14 from dada513/flathub
Change flatpak to flathub
2022-01-03 15:35:13 -05:00
4382344a7c Merge pull request #15 from dada513/debian_update 2022-01-03 07:55:17 -05:00
c7283adb9f change up deb packaging 2022-01-03 12:13:16 +01:00
672646384f remove icon 2022-01-03 12:08:54 +01:00
52e156908e Change flatpak to flathub 2022-01-03 11:59:23 +01:00
a97d0a36f4 NOISSUE Copy Image is not shown if the selection is > 1 2021-12-03 16:29:28 +01:00
e9c52ec696 NOISSUE Added Copy File(s) feature for the screenshot page
- Ctrl+C now copies the file instead of the image data
- Renamed Copy to Copy Image
2021-12-03 16:08:11 +01:00
75f2dab3c8 NOISSUE Implemented copy screenshots to the clipboard
- Added context-menu entry
- Ctrl+C keybind works as well
- If multiple screenshots are selected, only the first one gets copied
2021-12-03 03:11:53 +01:00
344 changed files with 12242 additions and 6400 deletions

View File

@ -1,6 +1,6 @@
name: Bug Report name: Bug Report
description: File a bug report description: File a bug report
labels: [bug, needs-triage] labels: [bug]
body: body:
- type: markdown - type: markdown
attributes: attributes:
@ -8,7 +8,7 @@ body:
If you need help with running Minecraft, please visit us on our Discord before making a bug report. 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: 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 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) * Your issue has not been reported before, [make sure to use the search function!](https://github.com/PolyMC/PolyMC/issues)

68
.github/ISSUE_TEMPLATE/rfc.yml vendored Normal file
View File

@ -0,0 +1,68 @@
# 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]
body:
- type: markdown
attributes:
value: |
### Use this form to suggest a larger change for PolyMC.
- type: textarea
attributes:
label: Goal
description: Short description, 1-2 sentences.
placeholder: Remove the cat from the launcher.
validations:
required: true
- type: textarea
attributes:
label: Motivation
description: |
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!).
- 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:
required: true
- type: textarea
attributes:
label: Specification
description: A concrete, thorough explanation of what is being planned.
placeholder: Remove the cat button and all references to the cat from the codebase. Including resource files.
validations:
required: true
- type: textarea
attributes:
label: Drawbacks
description: Carefully consider every possible objection and issue with your proposal. This section should be updated as feedback comes in from discussion.
placeholder: Some users might like cats.
validations:
required: true
- type: textarea
attributes:
label: Unresolved Questions
description: |
Are there any portions of your proposal which need to be discussed with the community before the RFC can proceed?
Be careful here -- an RFC with a lot of remaining questions is likely to be stalled.
If your RFC is mostly unresolved questions and not too much substance, it may not be ready.
placeholder: Do a lot of users care about the cat?
validations:
required: true
- type: textarea
attributes:
label: Alternatives Considered
description: A list of alternatives, that have been considered and offer equal or similar features to the proposed change.
placeholder: Maybe the cat could be replaced with an axolotl?
validations:
required: true
- type: checkboxes
attributes:
label: This suggestion is unique
options:
- label: I have searched the issue tracker and did not find an issue describing my suggestion, especially not one that has been rejected.
required: true
- type: textarea
attributes:
label: You may use the editor below to elaborate further.

View File

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

41
.github/scripts/prepare_JREs.sh vendored Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env bash
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
pushd JREs
wget --content-disposition "$URL_JDK8"
wget --content-disposition "$URL_JDK17"
for file in *;
do
mkdir temp
re='(OpenJDK([[:digit:]]+)U-jre_x64_linux_hotspot_([[:digit:]]+)(.*).tar.gz)'
if [[ $file =~ $re ]];
then
version_major=${BASH_REMATCH[2]}
version_trailing=${BASH_REMATCH[4]}
if [ $version_major = 17 ];
then
hyphen='-'
else
hyphen=''
fi
version_edit=$(echo $version_trailing | sed -e 's/_/+/g' | sed -e 's/b/-b/g')
dir_name=jdk$hyphen$version_major$version_edit-jre
mkdir jre$version_major
tar -xzf $file -C temp
pushd temp/$dir_name
cp -r . ../../jre$version_major
popd
fi
rm -rf temp
done
popd

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

256
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,256 @@
name: Build
on:
workflow_call:
inputs:
build_type:
description: Type of build (Debug, Release, RelWithDebInfo, MinSizeRel)
type: string
default: Debug
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: windows-2022
name: "Windows-i686"
msystem: mingw32
- os: windows-2022
name: "Windows-x86_64"
msystem: mingw64
- os: macos-11
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:
##
# PREPARE
##
- name: Checkout
uses: actions/checkout@v3
with:
submodules: 'true'
- name: 'Setup MSYS2'
if: runner.os == 'Windows'
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
run: |
ver_short=`git rev-parse --short HEAD`
echo "VERSION=$ver_short" >> $GITHUB_ENV
- name: Install OpenJDK
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Install Qt (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install qt@5
- 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: 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"
${{ github.workspace }}/.github/scripts/prepare_JREs.sh
##
# CONFIGURE
##
- 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 }} -DENABLE_LTO=ON -G Ninja
##
# BUILD
##
- name: Build
if: runner.os != 'Windows'
run: |
cmake --build ${{ env.BUILD_DIR }}
- 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 }}
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: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }}
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_APPIMAGE_DIR }}/usr/lib/jvm/java-{8,17}-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_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk
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_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.polymc.PolyMC.svg
##
# UPLOAD BUILDS
##
- name: Upload binary tarball (macOS)
if: runner.os == 'macOS'
uses: actions/upload-artifact@v3
with:
name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: PolyMC.tar.gz
- 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

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

30
.github/workflows/trigger_builds.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: Build Application
on:
push:
branches-ignore:
- 'stable'
paths-ignore:
- '**.md'
- '**/LICENSE'
- 'flake.lock'
- '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
paths-ignore:
- '**.md'
- '**/LICENSE'
- 'flake.lock'
- '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
workflow_dispatch:
jobs:
build_debug:
name: Build Debug
uses: ./.github/workflows/build.yml
with:
build_type: Debug

70
.github/workflows/trigger_release.yml vendored Normal file
View File

@ -0,0 +1,70 @@
name: Build Application and Make Release
on:
push:
tags:
- '*'
jobs:
build_release:
name: Build Release
uses: ./.github/workflows/build.yml
with:
build_type: Release
create_release:
needs: build_release
runs-on: ubuntu-latest
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
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
name: PolyMC ${{ env.VERSION }}
draft: true
prerelease: false
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

12
.gitignore vendored
View File

@ -40,13 +40,9 @@ run/
.cache/ .cache/
# Flatpak builds # Nix/NixOS
result/
# Flatpak
.flatpak-builder .flatpak-builder
flatbuild flatbuild
builddir
# Deb
packages/debian/polymc/usr/bin
packages/debian/polymc/usr/lib
packages/debian/polymc/usr/share/polymc/jars
packages/debian/polymc.deb
packages/debian/polymc/DEBIAN/control

10
.gitmodules vendored
View File

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

233
BUILD.md
View File

@ -1,232 +1,5 @@
Build Instructions # Build Instructions
==================
# Contents Build instructions are available on [the website](https://polymc.org/wiki/development/build-instructions/).
* [Note](#note) If you would like to contribute or fix an issue with the Build instructions you can do so [here](https://github.com/PolyMC/polymc.github.io/blob/master/src/wiki/development/build-instructions.md).
* [Getting the source](#source)
* [Linux](#linux)
* [Windows](#windows)
* [macOS](#macos)
# Getting the source
Clone the source code using git and grab all the submodules:
```
git clone https://github.com/PolyMC/PolyMC.git
git submodule init
git submodule update
```
# Linux
Getting the project to build and run on Linux is easy if you use any modern and up-to-date linux distribution.
## Build dependencies
* A C++ compiler capable of building C++11 code.
* Qt Development tools 5.6 or newer (`qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5` on Debian-based system)
* cmake 3.1 or newer (`cmake` on Debian-based system)
* zlib (`zlib1g-dev` on Debian-based system)
* Java JDK (`openjdk-17-jdk`on Debian-based system)
* GL headers (`libgl1-mesa-dev` on Debian-based system)
### Building a .deb
You need to install the build dependencies first
```
git clone https://github.com/PolyMC/PolyMC.git
git submodule init && git submodule update
cd packages/debian
./makedeb.sh
```
If everything works correctly, the .deb will be next to the build script, in `PolyMC/packages/debian`
### Building from command line
You need a source folder, a build folder and an install folder.
```
# make all the folders
mkdir ~/PolyMC && cd ~/PolyMC
mkdir build
mkdir install
# clone the complete source
git clone --recursive https://github.com/PolyMC/PolyMC.git src
# configure the project
cd build
cmake -DCMAKE_INSTALL_PREFIX=../install ../src
make -j$(nproc) install
```
You can use IDEs like KDevelop or QtCreator to open the CMake project if you want to work on the code.
### Building & Installing to the System
This is the preferred method for installation, and is suitable for packages.
```
git clone --recursive https://github.com/PolyMC/PolyMC.git && cd PolyMC
# configure everything
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="/usr" \ # Use "/usr" for packages, otherwise, leave it at the default "/usr/local".
-DLauncher_LAYOUT=lin-system
make -j$(nproc) install # Optionally specify DESTDIR for packages (i.e. DESTDIR=${pkgdir})
```
### Installing Qt using the installer (optional)
1. Run the Qt installer.
2. Choose a place to install Qt.
3. Choose the components you want to install.
- You need Qt 5.6.x 64-bit ticked.
- You need Tools/Qt Creator ticked.
- Other components are selected by default, you can untick them if you don't need them.
4. Accept the license agreements.
5. Double check the install details and then click "Install".
- Installation can take a very long time, go grab a cup of tea or something and let it work.
### Loading the project in Qt Creator (optional)
1. Open Qt Creator.
2. Choose `File->Open File or Project`.
3. Navigate to the Launcher source folder you cloned and choose CMakeLists.txt.
4. Read the instructions that just popped up about a build location and choose one.
5. You should see "Run CMake" in the window.
- Make sure that Generator is set to "Unix Generator (Desktop Qt 5.6.x GCC 64bit)".
- Hit the "Run CMake" button.
- You'll see warnings and it might not be clear that it succeeded until you scroll to the bottom of the window.
- Hit "Finish" if CMake ran successfully.
6. Cross your fingers and press the Run button (bottom left of Qt Creator).
- If the project builds successfully it will run and the Launcher window will pop up.
**If this doesn't work for you, let us know on our Discord.**
# Windows
Getting the project to build and run on Windows is easy if you use Qt's IDE, Qt Creator. The project will simply not compile using Microsoft build tools, because that's not something we do. If it does compile, it is by chance only.
## Dependencies
* [Qt 5.6+ Development tools](http://qt-project.org/downloads) -- Qt Online Installer for Windows
- http://download.qt.io/new_archive/qt/5.6/5.6.0/qt-opensource-windows-x86-mingw492-5.6.0.exe
- Download the MinGW version (MSVC version does not work).
* [OpenSSL](https://github.com/IndySockets/OpenSSL-Binaries/tree/master/Archive/) -- Win32 OpenSSL, version 1.0.2g (from 2016)
- https://github.com/IndySockets/OpenSSL-Binaries/raw/master/Archive/openssl-1.0.2g-i386-win32.zip
- the usual OpenSSL for Windows (http://slproweb.com/products/Win32OpenSSL.html) only provides the newest version of OpenSSL, and we need the 1.0.2g version
- **Download the 32-bit version, not 64-bit.**
- Microsoft Visual C++ 2008 Redist is required for this, there's a link on the OpenSSL download page above next to the main download.
- We use a custom build of OpenSSL that doesn't have this dependency. For normal development, the custom build is not necessary though.
* [zlib 1.2+](http://gnuwin32.sourceforge.net/packages/zlib.htm) - the Setup is fine
* [Java JDK 8](https://adoptium.net/releases.html?variant=openjdk8) - Use the MSI installer.
* [CMake](http://www.cmake.org/cmake/resources/software.html) -- Windows (Win32 Installer)
Ensure that OpenSSL, zlib, Java and CMake are on `PATH`.
## Getting set up
### Installing Qt
1. Run the Qt installer
2. Choose a place to install Qt (C:\Qt is the default),
3. Choose the components you want to install
- You need Qt 5.6 (32 bit) ticked,
- You need Tools/Qt Creator ticked,
- Other components are selected by default, you can untick them if you don't need them.
4. Accept the license agreements,
5. Double check the install details and then click "Install"
- Installation can take a very long time, go grab a cup of tea or something and let it work.
### Installing OpenSSL
1. Download .zip file from the link above.
2. Unzip and add the directory to PATH, so CMake can find it.
### Installing CMake
1. Run the CMake installer,
2. It's easiest if you choose to add CMake to the PATH for all users,
- If you don't choose to do this, remember where you installed CMake.
### Loading the project
1. Open Qt Creator,
2. Choose File->Open File or Project,
3. Navigate to the Launcher source folder you cloned and choose CMakeLists.txt,
4. Read the instructions that just popped up about a build location and choose one,
5. If you chose not to add CMake to the system PATH, tell Qt Creator where you installed it,
- Otherwise you can skip this step.
6. You should see "Run CMake" in the window,
- Make sure that Generator is set to "MinGW Generator (Desktop Qt 5.6.x MinGW 32bit)",
- Hit the "Run CMake" button,
- You'll see warnings and it might not be clear that it succeeded until you scroll to the bottom of the window.
- Hit "Finish" if CMake ran successfully.
7. Cross your fingers and press the Run button (bottom left of Qt Creator)!
- If the project builds successfully it will run and the Launcher window will pop up,
- Test OpenSSL by making an instance and trying to log in. If Qt Creator couldn't find OpenSSL during the CMake stage, login will fail and you'll get an error.
The following .dlls are needed for the app to run (copy them to build directory if you want to be able to move the build to another pc):
```
platforms/qwindows.dll
libeay32.dll
libgcc_s_dw2-1.dll
libssp-0.dll
libstdc++-6.dll
libwinpthread-1.dll
Qt5Core.dll
Qt5Gui.dll
Qt5Network.dll
Qt5Svg.dll
Qt5Widgets.dll
Qt5Xml.dll
ssleay32.dll
zlib1.dll
```
**These build instructions worked for me (Drayshak) on a fresh Windows 8 x64 Professional install. If they don't work for you, let us know on our Discord.**
### Compile from command line on Windows
1. If you installed Qt with the web installer, there should be a shortcut called `Qt 5.4 for Desktop (MinGW 4.9 32-bit)` in the Start menu on Windows 7 and 10. Best way to find it is to search for it. Do note you cannot just use cmd.exe, you have to use the shortcut, otherwise the proper MinGW software will not be on the PATH.
2. Once that is open, change into your user directory, and clone PolyMC by doing `git clone --recursive https://github.com/PolyMC/PolyMC.git`, and change directory to the folder you cloned to.
3. Make a build directory, and change directory to the directory and do `cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:\Path\that\makes\sense\for\you`. By default, it will install to C:\Program Files (x86), which you might not want, if you want a local installation. If you want to install it to that directory, make sure to run the command window as administrator.
3. Do `mingw32-make -jX`, where X is the number of cores your CPU has plus one.
4. Now to wait for it to compile. This could take some time. Hopefully it compiles properly.
5. Run the command `mingw32-make install`, and it should install PolyMC, to whatever the `-DCMAKE_INSTALL_PREFIX` was.
6. In most cases, whenever compiling, the OpenSSL dll's aren't put into the directory to where PolyMC installs, meaning you cannot log in. The best way to fix this is just to do `copy C:\OpenSSL-Win32\*.dll C:\Where\you\installed\PolyMC\to`. This should copy the required OpenSSL dll's to log in.
# macOS
### Install prerequisites:
- Install XCode Command Line tools
- Install the official build of CMake (https://cmake.org/download/)
- Install JDK 8 (https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html)
- Get Qt 5.6 and install it (https://download.qt.io/new_archive/qt/5.6/5.6.3/)
### XCode Command Line tools
If you don't have XCode CommandLine tools installed, you can install them by using this command in the Terminal App
```bash
xcode-select --install
```
### Build
Pick an installation path - this is where the final `.app` will be constructed when you run `make install`. Supply it as the `CMAKE_INSTALL_PREFIX` argument during CMake configuration.
```
git clone --recursive https://github.com/PolyMC/PolyMC.git
cd Launcher
mkdir build
cd build
cmake \
-DCMAKE_C_COMPILER=/usr/bin/clang \
-DCMAKE_CXX_COMPILER=/usr/bin/clang++ \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX:PATH="$(dirname $PWD)/dist/" \
-DCMAKE_PREFIX_PATH="/path/to/Qt5.6/" \
-DQt5_DIR="/path/to/Qt5.6/" \
-DLauncher_LAYOUT=mac-bundle \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \
..
make install
```
**Note:** The final app bundle may not run due to code signing issues, which
need to be fixed with `codesign -fs -`.

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1) cmake_minimum_required(VERSION 3.9.4)
if(WIN32) if(WIN32)
# In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows # In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
@ -6,21 +6,13 @@ if(WIN32)
endif() endif()
project(Launcher) project(Launcher)
enable_testing() include(CTest)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD) string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD)
if(IS_IN_SOURCE_BUILD) if(IS_IN_SOURCE_BUILD)
message(FATAL_ERROR "You are building the Launcher in-source. Please separate the build tree from the source tree.") message(FATAL_ERROR "You are building the Launcher in-source. Please separate the build tree from the source tree.")
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
if(CMAKE_HOST_SYSTEM_VERSION MATCHES ".*[Mm]icrosoft.*" OR
CMAKE_HOST_SYSTEM_VERSION MATCHES ".*WSL.*"
)
message(FATAL_ERROR "Building the Launcher is not supported in Linux-on-Windows distributions.")
endif()
endif()
##################################### Set CMake options ##################################### ##################################### Set CMake options #####################################
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -51,48 +43,73 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type")
# Fix build with Qt 5.13 # Fix build with Qt 5.13
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
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 Application options #####################################
######## Set URLs ######## ######## Set URLs ########
set(Launcher_NEWS_RSS_URL "https://multimc.org/rss.xml" CACHE STRING "URL to fetch Launcher's news RSS feed from.") set(Launcher_NEWS_RSS_URL "https://polymc.org/feed/feed.xml" CACHE STRING "URL to fetch PolyMC's news RSS feed from.")
set(Launcher_NEWS_OPEN_URL "https://polymc.org/news" CACHE STRING "URL that gets opened when the user clicks 'More News'")
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 version numbers ########
set(Launcher_VERSION_MAJOR 0) set(Launcher_VERSION_MAJOR 1)
set(Launcher_VERSION_MINOR 6) set(Launcher_VERSION_MINOR 2)
set(Launcher_VERSION_HOTFIX 14) set(Launcher_VERSION_HOTFIX 0)
# Build number # Build number
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
# Build platform. # Build platform.
set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.")
# Channel list URL # Channel list URL
set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.")
# Notification URL
set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.")
# The metadata server # The metadata server
set(Launcher_META_URL "https://meta.multimc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.")
# paste.ee API key
set(Launcher_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE STRING "API key you can get from paste.ee when you register an account")
# Imgur API Client ID # Imgur API Client ID
set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application")
# MSA Client ID # MSA Client ID
set(Launcher_MSA_CLIENT_ID "17b47edd-c884-4997-926d-9e7f9a6b4647" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application") set(Launcher_MSA_CLIENT_ID "549033b2-1532-4d4e-ae77-1bbaa46f9d74" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application")
# Bug tracker URL # Bug tracker URL
set(Launcher_BUG_TRACKER_URL "https://github.com/PolyMC/PolyMC/issues" CACHE STRING "URL for the bug tracker.") set(Launcher_BUG_TRACKER_URL "https://github.com/PolyMC/PolyMC/issues" CACHE STRING "URL for the bug tracker.")
# Translations Platform URL
set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/polymc/polymc/" CACHE STRING "URL for the translations platform.")
# Matrix Space
set(Launcher_MATRIX_URL "https://matrix.to/#/#polymc:matrix.org" CACHE STRING "URL to the Matrix Space")
# Discord URL # Discord URL
set(Launcher_DISCORD_URL "" CACHE STRING "URL for the Discord guild.") set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.")
# Subreddit URL # Subreddit URL
set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.") set(Launcher_SUBREDDIT_URL "https://www.reddit.com/r/PolyMCLauncher/" CACHE STRING "URL for the subreddit.")
# Builds
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")
#### Check the current Git commit and branch #### Check the current Git commit and branch
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
@ -102,6 +119,8 @@ message(STATUS "Git commit: ${Launcher_GIT_COMMIT}")
message(STATUS "Git refspec: ${Launcher_GIT_REFSPEC}") message(STATUS "Git refspec: ${Launcher_GIT_REFSPEC}")
set(Launcher_RELEASE_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}") set(Launcher_RELEASE_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}")
string(TIMESTAMP TODAY "%Y-%m-%d")
set(Launcher_RELEASE_TIMESTAMP "${TODAY}")
#### Custom target to just print the version. #### Custom target to just print the version.
add_custom_target(version echo "Version: ${Launcher_RELEASE_VERSION_NAME}") add_custom_target(version echo "Version: ${Launcher_RELEASE_VERSION_NAME}")
@ -110,12 +129,20 @@ add_custom_target(tcversion echo "\\#\\#teamcity[setParameter name=\\'env.LAUNCH
################################ 3rd Party Libs ################################ ################################ 3rd Party Libs ################################
# Find the required Qt parts # Find the required Qt parts
find_package(Qt5Core REQUIRED) if(Launcher_QT_VERSION_MAJOR EQUAL 5)
find_package(Qt5Widgets REQUIRED) set(QT_VERSION_MAJOR 5)
find_package(Qt5Concurrent REQUIRED) find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml)
find_package(Qt5Network REQUIRED)
find_package(Qt5Test REQUIRED) if(NOT Launcher_FORCE_BUNDLED_LIBS)
find_package(Qt5Xml 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)
set(FORCE_BUNDLED_QUAZIP 1)
endif()
else()
message(FATAL_ERROR "Qt version ${Launcher_QT_VERSION_MAJOR} is not supported")
endif()
# The Qt5 cmake files don't provide its install paths, so ask qmake. # The Qt5 cmake files don't provide its install paths, so ask qmake.
include(QMakeQuery) include(QMakeQuery)
@ -130,51 +157,37 @@ if (Qt5_POSITION_INDEPENDENT_CODE)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif() endif()
####################################### Secrets ####################################### ####################################### Program Info #######################################
set(Launcher_APP_BINARY_NAME "polymc" CACHE STRING "Name of the Launcher binary")
add_subdirectory(program_info) add_subdirectory(program_info)
####################################### Install layout ####################################### ####################################### Install layout #######################################
# How to install the build results if(NOT (UNIX AND APPLE))
set(Launcher_LAYOUT "auto" CACHE STRING "The layout for the launcher installation (auto, win-bundle, lin-nodeps, lin-system, mac-bundle)") # Install "portable.txt" if selected component is "portable"
set_property(CACHE Launcher_LAYOUT PROPERTY STRINGS auto win-bundle lin-nodeps lin-system mac-bundle) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION "." COMPONENT portable EXCLUDE_FROM_ALL)
if(Launcher_LAYOUT STREQUAL "auto")
if(UNIX AND APPLE)
set(Launcher_LAYOUT_REAL "mac-bundle")
elseif(UNIX)
set(Launcher_LAYOUT_REAL "lin-nodeps")
elseif(WIN32)
set(Launcher_LAYOUT_REAL "win-bundle")
else()
message(FATAL_ERROR "Cannot choose a sensible install layout for your platform.")
endif()
else()
set(Launcher_LAYOUT_REAL ${Launcher_LAYOUT})
endif() endif()
if(Launcher_LAYOUT_REAL STREQUAL "mac-bundle") if(UNIX AND APPLE)
set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS")
set(LIBRARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") set(LIBRARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS")
set(PLUGIN_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") set(PLUGIN_DEST_DIR "${Launcher_Name}.app/Contents/MacOS")
set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources") set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources")
set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars") set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars")
set(BUNDLE_DEST_DIR ".")
# Apps to bundle # Apps to bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app")
# Mac bundle settings # Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_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.multimc.${Launcher_Name}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.polymc.${Launcher_Name}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}")
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 ${Launcher_Copyright}") set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}")
# directories to look for dependencies # directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
@ -185,13 +198,14 @@ if(Launcher_LAYOUT_REAL STREQUAL "mac-bundle")
# Add the icon # Add the icon
install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR} RENAME ${Launcher_Name}.icns) install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR} RENAME ${Launcher_Name}.icns)
elseif(Launcher_LAYOUT_REAL STREQUAL "lin-nodeps") elseif(UNIX)
set(BINARY_DEST_DIR "bin") set(BINARY_DEST_DIR "bin")
set(LIBRARY_DEST_DIR "bin") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(PLUGIN_DEST_DIR "plugins") set(JARS_DEST_DIR "share/jars")
set(BUNDLE_DEST_DIR ".") set(LAUNCHER_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory")
set(RESOURCES_DEST_DIR ".") set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory")
set(JARS_DEST_DIR "bin/jars") 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 # install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps") set(INSTALL_BUNDLE "nodeps")
@ -199,34 +213,22 @@ elseif(Launcher_LAYOUT_REAL STREQUAL "lin-nodeps")
# Set RPATH # Set RPATH
SET(Launcher_BINARY_RPATH "$ORIGIN/") SET(Launcher_BINARY_RPATH "$ORIGIN/")
# Install basic runner script # 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) 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}) install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION "." RENAME ${Launcher_Name} COMPONENT portable EXCLUDE_FROM_ALL)
elseif(Launcher_LAYOUT_REAL STREQUAL "lin-system") elseif(WIN32)
set(Launcher_APP_BINARY_NAME "polymc" CACHE STRING "Name of the Launcher binary")
set(Launcher_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory")
set(Launcher_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory")
set(Launcher_SHARE_DEST_DIR "share/polymc" CACHE STRING "Path to the shared data directory")
set(JARS_DEST_DIR "${Launcher_SHARE_DEST_DIR}/jars")
set(Launcher_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory")
set(BINARY_DEST_DIR ${Launcher_BINARY_DEST_DIR})
set(LIBRARY_DEST_DIR ${Launcher_LIBRARY_DEST_DIR})
MESSAGE(STATUS "Compiling for linux system with ${Launcher_SHARE_DEST_DIR} and LAUNCHER_LINUX_DATADIR")
SET(Launcher_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DLAUNCHER_LINUX_DATADIR")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${Launcher_DESKTOP_DEST_DIR})
# install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps")
elseif(Launcher_LAYOUT_REAL STREQUAL "win-bundle")
set(BINARY_DEST_DIR ".") set(BINARY_DEST_DIR ".")
set(LIBRARY_DEST_DIR ".") set(LIBRARY_DEST_DIR ".")
set(PLUGIN_DEST_DIR ".") set(PLUGIN_DEST_DIR ".")
set(BUNDLE_DEST_DIR ".")
set(RESOURCES_DEST_DIR ".") set(RESOURCES_DEST_DIR ".")
set(JARS_DEST_DIR "jars") set(JARS_DEST_DIR "jars")
@ -239,7 +241,7 @@ elseif(Launcher_LAYOUT_REAL STREQUAL "win-bundle")
# install as bundle # install as bundle
set(INSTALL_BUNDLE "full") set(INSTALL_BUNDLE "full")
else() else()
message(FATAL_ERROR "No sensible install layout set.") message(FATAL_ERROR "Platform not supported")
endif() endif()
################################ Included Libs ################################ ################################ Included Libs ################################
@ -247,11 +249,9 @@ endif()
include(ExternalProject) include(ExternalProject)
set_directory_properties(PROPERTIES EP_BASE External) set_directory_properties(PROPERTIES EP_BASE External)
option(NBT_BUILD_SHARED "Build NBT shared library" ON) option(NBT_BUILD_SHARED "Build NBT shared library" OFF)
option(NBT_USE_ZLIB "Build NBT library with zlib support" OFF) option(NBT_USE_ZLIB "Build NBT library with zlib support" OFF)
option(NBT_BUILD_TESTS "Build NBT library tests" OFF) #FIXME: fix unit tests. option(NBT_BUILD_TESTS "Build NBT library tests" OFF) #FIXME: fix unit tests.
set(NBT_NAME Launcher_nbt++)
set(NBT_DEST_DIR ${LIBRARY_DEST_DIR})
add_subdirectory(libraries/libnbtplusplus) add_subdirectory(libraries/libnbtplusplus)
add_subdirectory(libraries/systeminfo) # system information library add_subdirectory(libraries/systeminfo) # system information library
@ -259,7 +259,14 @@ add_subdirectory(libraries/hoedown) # markdown parser
add_subdirectory(libraries/launcher) # java based launcher part for Minecraft add_subdirectory(libraries/launcher) # java based launcher part for Minecraft
add_subdirectory(libraries/javacheck) # java compatibility checker add_subdirectory(libraries/javacheck) # java compatibility checker
add_subdirectory(libraries/xz-embedded) # xz compression add_subdirectory(libraries/xz-embedded) # xz compression
add_subdirectory(libraries/quazip) # zip manipulation library if (FORCE_BUNDLED_QUAZIP)
message(STATUS "Using 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/rainbow) # Qt extension for colors
add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader
add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions

136
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,136 @@
# Contributor Covenant Code of Conduct
This is a modified version of the Contributor Covenant.
See commit history to see our changes.
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling (antagonistic, inflammatory, insincere behaviour), insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement via email at
[polymc-enforcement@scrumplex.net](mailto:polymc-enforcement@scrumplex.net) (Email
address subject to change).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@ -1,12 +1,11 @@
# PolyMC # PolyMC
Copyright (C) 2012-2021 MultiMC Contributors Copyright (C) 2012-2021 MultiMC Contributors
Copyright (C) 2021 PolyMC Contributors Copyright (C) 2021-2022 PolyMC Contributors
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, version 3.
(at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -16,6 +15,20 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
# Launcher (https://github.com/MultiMC/Launcher)
Copyright 2012-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.
# MinGW runtime (Windows) # MinGW runtime (Windows)
Copyright (c) 2012 MinGW.org project Copyright (c) 2012 MinGW.org project

674
LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
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/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

110
README.md
View File

@ -1,62 +1,88 @@
<p align="center"> <p align="center">
<img src="https://avatars.githubusercontent.com/u/96310119" alt="PolyMC logo"/> <img src="./program_info/polymc-header-black.svg#gh-light-mode-only" alt="PolyMC logo"/>
<img src="./program_info/polymc-header.svg#gh-dark-mode-only" alt="PolyMC logo"/>
</p> </p>
<br>
PolyMC 5
=========
PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity. PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.
This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. The PolyMC community felt that the maintainer was not acting in the spirit of Free Software so this fork was made. Read "[Why was this fork made?](https://github.com/PolyMC/PolyMC/wiki/FAQ)" on the wiki for more details. This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. The PolyMC community felt that the maintainer was not acting in the spirit of Free Software so this fork was made.
<br>
## Packages # Installation
Several source build packages are available, along with experimental pre-built generic packages.
- An [AUR package](https://aur.archlinux.org/packages/polymc-git/) is available. - All downloads and instructions for PolyMC can be found [here](https://polymc.org/download/)
- A Gentoo ebuild is available in the [swirl](https://git.swurl.xyz/swirl/ebuilds) overlay, named `games-action/polymc`. Check the README for instructions on how to add the overlay. - Last build status: https://github.com/PolyMC/PolyMC/actions
- A Flatpak is available. Instructions on building it can be found in [packages/flatpak/BUILDING.md](packages/flatpak/BUILDING.md).
- Generic, prebuilt packages (archived by version) can be found [here](https://packages.polymc.org/) ([latest](https://packages.polymc.org/latest))
- Last build status: https://jenkins.polymc.org/job/PolyMC/lastBuild/
- [Linux (AMD64) System](https://packages.polymc.org/latest/lin64-system/lin64-system.tar.zst) ([SHA256](https://packages.polymc.org/latest/lin64-system/lin64-system.tar.zst.sha256)) - this is a generic system package intended to be used as a base for making distro-specific packages.
- [Windows (32-bit)](https://packages.polymc.org/latest/win32/win32.zip) ([SHA256](https://packages.polymc.org/latest/win32/win32.zip.sha256)) - this is a portable package, you can extract it anywhere and run it. This package needs testing.
- [Debian (AMD64)](https://packages.polymc.org/latest/deb/polymc-amd64.deb) ([SHA256](https://packages.polymc.org/latest/deb/polymc-amd64.deb.sha256)) - this is intended to be installed with `dpkg -i`. Alternatively, you may build the `.deb` yourself, by going to `packages/debian` and running `./makedeb.sh`.
- [AppImage (AMD64)](https://packages.polymc.org/latest/appimage/PolyMC-latest-x86_64.AppImage) ([SHA256](https://packages.polymc.org/latest/appimage/PolyMC-latest-x86_64.AppImage.sha256)) - `chmod +x` must be run on this file before usage. This should work on any distribution
- MacOS currently does not have any packages. We are still working on setting up MacOS packaging.
## Development
If you want to contribute to PolyMC you might find it useful to join [#development:polymc.org on Matrix](https://matrix.to/#/#development:polymc.org) or join [our Discord server](https://discord.gg/xq7fxrgtMP), which is bridged with the PolyMC Matrix rooms. Thank you!
### Building ## Development Builds
If you want to build PolyMC yourself, check [BUILD.md](BUILD.md) for build instructions.
### Code formatting There are per-commit development builds available [here](https://github.com/PolyMC/PolyMC/actions). These have debug information in the binaries, so their file sizes are relatively larger.
Just follow the existing formatting. Portable builds are provided for AppImage on Linux, Windows, and macOS.
In general, in order of importance: For Debian and Arch, you can use these packages for the latest development versions:
* Make sure your IDE is not messing up line endings or whitespace and avoid using linters. [![polymc-git](https://img.shields.io/badge/aur-polymc--git-blue)](https://aur.archlinux.org/packages/polymc-git/)
* Prefer readability over dogma. [![polymc-git](https://img.shields.io/badge/mpr-polymc--git-orange)](https://mpr.makedeb.org/packages/polymc-git)
* Keep to the existing formatting. For flatpak, you can use [flathub-beta](https://discourse.flathub.org/t/how-to-use-flathub-beta/2111)
* Indent with 4 space unless it's in a submodule.
* Keep lists (of arguments, parameters, initializers...) as lists, not paragraphs. It should either read from top to bottom, or left to right. Not both.
## Translations # Help & Support
TODO
## 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.
## Help & Support
Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server. Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server.
[![PolyMC Discord](https://img.shields.io/discord/923671181020766230?label=PolyMC%20Discord)](https://discord.gg/xq7fxrgtMP) [![PolyMC Discord](https://img.shields.io/discord/923671181020766230?label=PolyMC%20Discord)](https://discord.gg/xq7fxrgtMP)
For people who don't want to use Discord, we have a Matrix Space which is bridged to the discord server. Be sure to enable spaces first (Settings -> Labs -> Spaces), and then you may join the space: For people who don't want to use Discord, we have a Matrix Space which is bridged to the Discord server:
[![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)
Matrix's support for spaces is still in development, so if you have issues accessing rooms via the space, then you can join the rooms directly: 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) [![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/discussion:polymc.org?label=%23discussion&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#discussion:polymc.org) [![Discussion](https://img.shields.io/matrix/polymc-discussion:matrix.org?label=PolyMC%20Discussion)](https://matrix.to/#/#polymc-discussion:matrix.org)
[![Development](https://img.shields.io/matrix/development:polymc.org?label=%23development&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#development:polymc.org) [![Github](https://img.shields.io/matrix/polymc-github:matrix.org?label=PolyMC%20Github)](https://matrix.to/#/#polymc-github:matrix.org)
[![News](https://img.shields.io/matrix/news:polymc.org?label=%23news&server_fqdn=matrix.polymc.org)](https://matrix.to/#/#news:polymc.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
If you want to contribute to PolyMC you might find it useful to join our Discord Server or Matrix Space.
## Building
If you want to build PolyMC yourself, check [Build Instructions](https://polymc.org/wiki/development/build-instructions/) for build instructions.
## Code formatting
Just follow the existing formatting.
In general, in order of importance:
- Make sure your IDE is not messing up line endings or whitespace and avoid using linters.
- Prefer readability over dogma.
- Keep to the existing formatting.
- Indent with 4 space unless it's in a submodule.
- Keep lists (of arguments, parameters, initializers...) as lists, not paragraphs. It should either read from top to bottom, or left to right. Not both.
## Translations
The translation effort for PolyMC is hosted on [Weblate](https://hosted.weblate.org/projects/polymc/polymc/) and information about translating PolyMC is available at https://github.com/PolyMC/Translations
## Download 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 "BuildConfig.h"
#include <QObject> #include <QObject>
@ -12,6 +47,7 @@ Config::Config()
LAUNCHER_DOMAIN = "@Launcher_Domain@"; LAUNCHER_DOMAIN = "@Launcher_Domain@";
LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@"; LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@";
LAUNCHER_GIT = "@Launcher_Git@"; LAUNCHER_GIT = "@Launcher_Git@";
LAUNCHER_DESKTOPFILENAME = "@Launcher_DesktopFileName@";
USER_AGENT = "@Launcher_UserAgent@"; USER_AGENT = "@Launcher_UserAgent@";
USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)"; USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)";
@ -24,30 +60,41 @@ Config::Config()
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@"; UPDATER_BASE = "@Launcher_UPDATER_BASE@";
NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@";
FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@";
GIT_COMMIT = "@Launcher_GIT_COMMIT@"; GIT_COMMIT = "@Launcher_GIT_COMMIT@";
GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; GIT_REFSPEC = "@Launcher_GIT_REFSPEC@";
if(GIT_REFSPEC.startsWith("refs/heads/") && !UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty() && VERSION_BUILD >= 0) if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND"))
{
VERSION_CHANNEL = QStringLiteral("stable");
}
else if(GIT_REFSPEC.startsWith("refs/heads/"))
{ {
VERSION_CHANNEL = GIT_REFSPEC; VERSION_CHANNEL = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/"); VERSION_CHANNEL.remove("refs/heads/");
UPDATER_ENABLED = true; if(!UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty() && VERSION_BUILD >= 0) {
UPDATER_ENABLED = true;
}
}
else if (!GIT_COMMIT.isEmpty())
{
VERSION_CHANNEL = GIT_COMMIT.mid(0, 8);
} }
else else
{ {
VERSION_CHANNEL = QObject::tr("custom"); VERSION_CHANNEL = QObject::tr("unknown");
} }
VERSION_STR = "@Launcher_VERSION_STRING@"; VERSION_STR = "@Launcher_VERSION_STRING@";
NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@"; NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@";
PASTE_EE_KEY = "@Launcher_PASTE_EE_API_KEY@"; NEWS_OPEN_URL = "@Launcher_NEWS_OPEN_URL@";
HELP_URL = "@Launcher_HELP_URL@";
IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@";
MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@"; MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@";
META_URL = "@Launcher_META_URL@"; META_URL = "@Launcher_META_URL@";
BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@";
TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@";
MATRIX_URL = "@Launcher_MATRIX_URL@";
DISCORD_URL = "@Launcher_DISCORD_URL@"; DISCORD_URL = "@Launcher_DISCORD_URL@";
SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@"; SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@";
} }

View File

@ -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 #pragma once
#include <QString> #include <QString>
@ -14,6 +49,7 @@ public:
QString LAUNCHER_DOMAIN; QString LAUNCHER_DOMAIN;
QString LAUNCHER_CONFIGFILE; QString LAUNCHER_CONFIGFILE;
QString LAUNCHER_GIT; QString LAUNCHER_GIT;
QString LAUNCHER_DESKTOPFILENAME;
/// The major version number. /// The major version number.
int VERSION_MAJOR; int VERSION_MAJOR;
@ -45,13 +81,6 @@ public:
/// User-Agent to use for uncached requests. /// User-Agent to use for uncached requests.
QString USER_AGENT_UNCACHED; QString USER_AGENT_UNCACHED;
/// URL for notifications
QString NOTIFICATION_URL;
/// Used for matching notifications
QString FULL_VERSION_STR;
/// The git commit hash of this build /// The git commit hash of this build
QString GIT_COMMIT; QString GIT_COMMIT;
@ -68,9 +97,14 @@ public:
QString NEWS_RSS_URL; QString NEWS_RSS_URL;
/** /**
* API key you can get from paste.ee when you register an account * URL that gets opened when the user clicks "More News"
*/ */
QString PASTE_EE_KEY; QString NEWS_OPEN_URL;
/**
* URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help
*/
QString HELP_URL;
/** /**
* Client ID you can get from Imgur when you register an application * Client ID you can get from Imgur when you register an application
@ -88,6 +122,8 @@ public:
QString META_URL; QString META_URL;
QString BUG_TRACKER_URL; QString BUG_TRACKER_URL;
QString TRANSLATIONS_URL;
QString MATRIX_URL;
QString DISCORD_URL; QString DISCORD_URL;
QString SUBREDDIT_URL; QString SUBREDDIT_URL;
@ -95,8 +131,8 @@ public:
QString LIBRARY_BASE = "https://libraries.minecraft.net/"; QString LIBRARY_BASE = "https://libraries.minecraft.net/";
QString AUTH_BASE = "https://authserver.mojang.com/"; QString AUTH_BASE = "https://authserver.mojang.com/";
QString IMGUR_BASE_URL = "https://api.imgur.com/3/"; QString IMGUR_BASE_URL = "https://api.imgur.com/3/";
QString FMLLIBS_BASE_URL = "https://files.multimc.org/fmllibs/"; QString FMLLIBS_BASE_URL = "https://files.polymc.org/fmllibs/";
QString TRANSLATIONS_BASE_URL = "https://files.multimc.org/translations/"; QString TRANSLATIONS_BASE_URL = "https://i18n.polymc.org/";
QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/"; QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/";
@ -104,6 +140,12 @@ public:
QString ATL_DOWNLOAD_SERVER_URL = "https://download.nodecdn.net/containers/atl/"; 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. * \brief Converts the Version to a string.
* \return The version number in string format (major.minor.revision.build). * \return The version number in string format (major.minor.revision.build).

File diff suppressed because it is too large Load Diff

View File

@ -5,44 +5,46 @@ set(TEST_RESOURCE_PATH ${CMAKE_CURRENT_LIST_DIR})
message(${TEST_RESOURCE_PATH}) message(${TEST_RESOURCE_PATH})
function(add_unit_test name) function(add_unit_test name)
set(options "") if(BUILD_TESTING)
set(oneValueArgs DATA) set(options "")
set(multiValueArgs SOURCES LIBS) 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) if(WIN32)
add_executable(${name}_test ${OPT_SOURCES} ${TEST_RESOURCE_PATH}/UnitTest/test.rc) 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}")
else() else()
# we don't on windows, so we have to add it ourselves add_executable(${name}_test ${OPT_SOURCES})
set(TEST_DATA_URL "file:///${TEST_DATA_PATH}")
endif() endif()
if(NOT TARGET "${DATA_TARGET_NAME}")
add_custom_target(${DATA_TARGET_NAME}) if(NOT "${OPT_DATA}" STREQUAL "")
add_dependencies(${name}_test ${DATA_TARGET_NAME}) set(TEST_DATA_PATH "${CMAKE_CURRENT_BINARY_DIR}/data")
add_custom_command( set(TEST_DATA_PATH_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${OPT_DATA}")
TARGET ${DATA_TARGET_NAME} message("From ${TEST_DATA_PATH_SRC} to ${TEST_DATA_PATH}")
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 string(REGEX REPLACE "[/\\:]" "_" DATA_TARGET_NAME "${TEST_DATA_PATH_SRC}")
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 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() 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() 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() endfunction()

View File

@ -14,7 +14,7 @@ BEGIN
BEGIN BEGIN
BLOCK "000004b0" BLOCK "000004b0"
BEGIN BEGIN
VALUE "CompanyName", "MultiMC Contributors" VALUE "CompanyName", "MultiMC & PolyMC Contributors"
VALUE "FileDescription", "Testcase" VALUE "FileDescription", "Testcase"
VALUE "FileVersion", "1.0.0.0" VALUE "FileVersion", "1.0.0.0"
VALUE "ProductName", "Launcher Testcase" VALUE "ProductName", "Launcher Testcase"

1
default.nix Normal file
View File

@ -0,0 +1 @@
(import packages/nix/flake-compat.nix).defaultNix

78
flake.lock generated Normal file
View File

@ -0,0 +1,78 @@
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1648199409,
"narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "64a525ee38886ab9028e6f61790de0832aa3ef03",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"libnbtplusplus": {
"flake": false,
"locked": {
"lastModified": 1591558203,
"narHash": "sha256-QgvNvaoFflCXEPCCFBCeZvYTpuiwScBG7EosUgFwFNQ=",
"owner": "multimc",
"repo": "libnbtplusplus",
"rev": "dc72a20b7efd304d12af2025223fad07b4b78464",
"type": "github"
},
"original": {
"owner": "multimc",
"repo": "libnbtplusplus",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1648219316,
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"quazip": {
"flake": false,
"locked": {
"lastModified": 1643049383,
"narHash": "sha256-LcJY6yd6GyeL7X5MP4L94diceM1TYespWByliBsjK98=",
"owner": "stachenov",
"repo": "quazip",
"rev": "09ec1d10c6d627f895109b21728dda000cbfa7d1",
"type": "github"
},
"original": {
"owner": "stachenov",
"repo": "quazip",
"type": "github"
}
},
"root": {
"inputs": {
"flake-compat": "flake-compat",
"libnbtplusplus": "libnbtplusplus",
"nixpkgs": "nixpkgs",
"quazip": "quazip"
}
}
},
"root": "root",
"version": 7
}

34
flake.nix Normal file
View File

@ -0,0 +1,34 @@
{
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 = { self, nixpkgs, libnbtplusplus, quazip, ... }:
let
# 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 "Application.h"
#include "BuildConfig.h" #include "BuildConfig.h"
@ -14,7 +49,7 @@
#include "ui/pages/global/ProxyPage.h" #include "ui/pages/global/ProxyPage.h"
#include "ui/pages/global/ExternalToolsPage.h" #include "ui/pages/global/ExternalToolsPage.h"
#include "ui/pages/global/AccountListPage.h" #include "ui/pages/global/AccountListPage.h"
#include "ui/pages/global/PasteEEPage.h" #include "ui/pages/global/APIPage.h"
#include "ui/pages/global/CustomCommandsPage.h" #include "ui/pages/global/CustomCommandsPage.h"
#include "ui/themes/ITheme.h" #include "ui/themes/ITheme.h"
@ -45,6 +80,7 @@
#include <QStringList> #include <QStringList>
#include <QDebug> #include <QDebug>
#include <QStyleFactory> #include <QStyleFactory>
#include <QWindow>
#include "InstanceList.h" #include "InstanceList.h"
@ -187,30 +223,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
setApplicationName(BuildConfig.LAUNCHER_NAME); setApplicationName(BuildConfig.LAUNCHER_NAME);
setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME); setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME);
setApplicationVersion(BuildConfig.printableVersionString()); setApplicationVersion(BuildConfig.printableVersionString());
#if (QT_VERSION >= QT_VERSION_CHECK(5,7,0))
setDesktopFileName(BuildConfig.LAUNCHER_DESKTOPFILENAME);
#endif
startTime = QDateTime::currentDateTime(); startTime = QDateTime::currentDateTime();
#ifdef Q_OS_LINUX
{
QFile osrelease("/proc/sys/kernel/osrelease");
if (osrelease.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&osrelease);
auto contents = in.readAll();
if(
contents.contains("WSL", Qt::CaseInsensitive) ||
contents.contains("Microsoft", Qt::CaseInsensitive)
) {
showFatalErrorMessage(
"Unsupported system detected!",
"Linux-on-Windows distributions are not supported.\n\n"
"Please use the Windows binary when playing on Windows."
);
return;
}
}
}
#endif
// Don't quit on hiding the last window // Don't quit on hiding the last window
this->setQuitOnLastWindowClosed(false); this->setQuitOnLastWindowClosed(false);
@ -283,14 +300,43 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
return; return;
} }
} }
m_instanceIdToLaunch = args["launch"].toString(); m_instanceIdToLaunch = args["launch"].toString();
m_serverToJoin = args["server"].toString(); m_serverToJoin = args["server"].toString();
m_profileToUse = args["profile"].toString(); m_profileToUse = args["profile"].toString();
m_liveCheck = args["alive"].toBool(); m_liveCheck = args["alive"].toBool();
m_zipToImport = args["import"].toUrl(); m_zipToImport = args["import"].toUrl();
// error if --launch is missing with --server or --profile
if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty())
{
std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl;
m_status = Application::Failed;
return;
}
QString origcwdPath = QDir::currentPath(); QString origcwdPath = QDir::currentPath();
QString binPath = applicationDirPath(); 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 adjustedBy;
QString dataPath; QString dataPath;
// change folder // change folder
@ -299,24 +345,30 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
{ {
// the dir param. it makes multimc data path point to whatever the user specified // the dir param. it makes multimc data path point to whatever the user specified
// on command line // on command line
adjustedBy += "Command line " + dirParam; adjustedBy = "Command line";
dataPath = dirParam; dataPath = dirParam;
} }
else else
{ {
#ifdef LAUNCHER_LINUX_DATADIR QDir foo(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), ".."));
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
dataPath = xdgDataHome + "/polymc";
adjustedBy += "XDG standard " + dataPath;
#elif defined(Q_OS_MAC)
QDir foo(FS::PathCombine(applicationDirPath(), "../../Data"));
dataPath = foo.absolutePath(); dataPath = foo.absolutePath();
adjustedBy += "Fallback to special Mac location " + dataPath; adjustedBy = "Persistent data path";
#else
dataPath = applicationDirPath(); #ifdef Q_OS_LINUX
adjustedBy += "Fallback to binary path " + dataPath; // TODO: this should be removed in a future version
// TODO: provide a migration path similar to macOS migration
QDir bar(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "polymc"));
if (bar.exists()) {
dataPath = bar.absolutePath();
adjustedBy = "Legacy data path";
}
#endif
#ifndef Q_OS_MACOS
if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
dataPath = m_rootPath;
adjustedBy = "Portable data path";
}
#endif #endif
} }
@ -357,20 +409,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
return; return;
} }
if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty())
{
std::cerr << "--server can only be used in combination with --launch!" << std::endl;
m_status = Application::Failed;
return;
}
if(m_instanceIdToLaunch.isEmpty() && !m_profileToUse.isEmpty())
{
std::cerr << "--account can only be used in combination with --launch!" << std::endl;
m_status = Application::Failed;
return;
}
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
// move user data to new location if on macOS and it still exists in Contents/MacOS // move user data to new location if on macOS and it still exists in Contents/MacOS
QDir fi(applicationDirPath()); QDir fi(applicationDirPath());
@ -435,7 +473,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
#endif #endif
/* /*
* Establish the mechanism for communication with an already running MultiMC that uses the same data path. * Establish the mechanism for communication with an already running PolyMC that uses the same data path.
* If there is one, tell it what the user actually wanted to do and exit. * If there is one, tell it what the user actually wanted to do and exit.
* We want to initialize this before logging to avoid messing with the log of a potential already running copy. * We want to initialize this before logging to avoid messing with the log of a potential already running copy.
*/ */
@ -520,24 +558,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
qDebug() << "<> Log initialized."; 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() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT;
qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Version : " << BuildConfig.printableVersionString();
@ -566,26 +587,23 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
qDebug() << "<> Paths set."; qDebug() << "<> Paths set.";
} }
do // once if(m_liveCheck)
{ {
if(m_liveCheck) QFile check(liveCheckFile);
if(check.open(QIODevice::WriteOnly | QIODevice::Truncate))
{ {
QFile check(liveCheckFile);
if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qWarning() << "Could not open" << liveCheckFile << "for writing!";
break;
}
auto payload = appID.toString().toUtf8(); auto payload = appID.toString().toUtf8();
if(check.write(payload) != payload.size()) if(check.write(payload) == payload.size())
{ {
check.close();
} else {
qWarning() << "Could not write into" << liveCheckFile << "!"; qWarning() << "Could not write into" << liveCheckFile << "!";
check.remove(); check.remove(); // also closes file!
break;
} }
check.close(); } else {
qWarning() << "Could not open" << liveCheckFile << "for writing!";
} }
} while(false); }
// Initialize application settings // Initialize application settings
{ {
@ -595,15 +613,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("AutoUpdate", true); m_settings->registerSetting("AutoUpdate", true);
// Theming // Theming
m_settings->registerSetting("IconTheme", QString("multimc")); m_settings->registerSetting("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system")); m_settings->registerSetting("ApplicationTheme", QString("system"));
// Notifications
m_settings->registerSetting("ShownNotifications", QString());
// Remembered state // Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
m_settings->registerSetting("MenuBarInsteadOfToolBar", false);
QString defaultMonospace; QString defaultMonospace;
int defaultSize = 11; int defaultSize = 11;
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
@ -662,7 +679,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Memory // Memory
m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512);
m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024); m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 4096);
m_settings->registerSetting("PermGen", 128); m_settings->registerSetting("PermGen", 128);
// Java Settings // Java Settings
@ -673,6 +690,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("JavaVendor", ""); m_settings->registerSetting("JavaVendor", "");
m_settings->registerSetting("LastHostname", ""); m_settings->registerSetting("LastHostname", "");
m_settings->registerSetting("JvmArgs", ""); m_settings->registerSetting("JvmArgs", "");
m_settings->registerSetting("IgnoreJavaCompatibility", false);
// Native library workarounds // Native library workarounds
m_settings->registerSetting("UseNativeOpenAL", false); m_settings->registerSetting("UseNativeOpenAL", false);
@ -686,6 +704,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Minecraft launch method // Minecraft launch method
m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
// Minecraft offline player name
m_settings->registerSetting("LastOfflinePlayerName", "");
// Wrapper command for launch // Wrapper command for launch
m_settings->registerSetting("WrapperCommand", ""); m_settings->registerSetting("WrapperCommand", "");
@ -714,8 +735,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("UpdateDialogGeometry", ""); m_settings->registerSetting("UpdateDialogGeometry", "");
// paste.ee API key // pastebin URL
m_settings->registerSetting("PasteEEAPIKey", "multimc"); m_settings->registerSetting("PastebinURL", "https://0x0.st");
m_settings->registerSetting("CloseAfterLaunch", false);
m_settings->registerSetting("QuitAfterGameStop", false);
// Custom MSA credentials
m_settings->registerSetting("MSAClientIDOverride", "");
// Init page provider // Init page provider
{ {
@ -728,7 +755,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_globalSettingsProvider->addPage<ProxyPage>(); m_globalSettingsProvider->addPage<ProxyPage>();
m_globalSettingsProvider->addPage<ExternalToolsPage>(); m_globalSettingsProvider->addPage<ExternalToolsPage>();
m_globalSettingsProvider->addPage<AccountListPage>(); m_globalSettingsProvider->addPage<AccountListPage>();
m_globalSettingsProvider->addPage<PasteEEPage>(); m_globalSettingsProvider->addPage<APIPage>();
} }
qDebug() << "<> Settings loaded."; qDebug() << "<> Settings loaded.";
} }
@ -1125,6 +1152,15 @@ std::vector<ITheme *> Application::getValidApplicationThemes()
return ret; return ret;
} }
bool Application::isFlatpak()
{
#ifdef Q_OS_LINUX
return QFile::exists("/.flatpak-info");
#else
return false;
#endif
}
void Application::setApplicationTheme(const QString& name, bool initial) void Application::setApplicationTheme(const QString& name, bool initial)
{ {
auto systemPalette = qApp->palette(); auto systemPalette = qApp->palette();
@ -1148,7 +1184,7 @@ void Application::setIconTheme(const QString& name)
QIcon Application::getThemedIcon(const QString& name) QIcon Application::getThemedIcon(const QString& name)
{ {
if(name == "logo") { if(name == "logo") {
return QIcon(":/polymc.svg"); return QIcon(":/org.polymc.PolyMC.svg");
} }
return XdgIcon::fromTheme(name); return XdgIcon::fromTheme(name);
} }
@ -1240,6 +1276,12 @@ bool Application::kill(InstancePtr instance)
return true; return true;
} }
void Application::closeCurrentWindow()
{
if (focusWindow())
focusWindow()->close();
}
void Application::addRunningInstance() void Application::addRunningInstance()
{ {
m_runningInstances ++; m_runningInstances ++;
@ -1512,5 +1554,15 @@ QString Application::getJarsPath()
{ {
return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars"); return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
} }
return m_jarsPath; return FS::PathCombine(m_rootPath, m_jarsPath);
}
QString Application::getMSAClientID()
{
QString clientIDOverride = m_settings->get("MSAClientIDOverride").toString();
if (!clientIDOverride.isEmpty()) {
return clientIDOverride;
}
return BuildConfig.MSA_CLIENT_ID;
} }

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 #pragma once
#include <QApplication> #include <QApplication>
@ -69,6 +104,8 @@ public:
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
bool isFlatpak();
void setIconTheme(const QString& name); void setIconTheme(const QString& name);
std::vector<ITheme *> getValidApplicationThemes(); std::vector<ITheme *> getValidApplicationThemes();
@ -117,6 +154,8 @@ public:
QString getJarsPath(); QString getJarsPath();
QString getMSAClientID();
/// this is the root of the 'installation'. Used for automatic updates /// this is the root of the 'installation'. Used for automatic updates
const QString &root() { const QString &root() {
return m_rootPath; return m_rootPath;
@ -150,6 +189,7 @@ public slots:
MinecraftAccountPtr accountToUse = nullptr MinecraftAccountPtr accountToUse = nullptr
); );
bool kill(InstancePtr instance); bool kill(InstancePtr instance);
void closeCurrentWindow();
private slots: private slots:
void on_windowClose(); 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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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" #include "BaseInstance.h"
@ -39,6 +59,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("lastLaunchTime", 0); m_settings->registerSetting("lastLaunchTime", 0);
m_settings->registerSetting("totalTimePlayed", 0); m_settings->registerSetting("totalTimePlayed", 0);
m_settings->registerSetting("lastTimePlayed", 0); m_settings->registerSetting("lastTimePlayed", 0);
m_settings->registerSetting("InstanceType", "OneSix");
// Custom Commands // Custom Commands
auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false);

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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 #pragma once

View File

@ -37,6 +37,10 @@ set(CORE_SOURCES
InstanceImportTask.h InstanceImportTask.h
InstanceImportTask.cpp InstanceImportTask.cpp
# Mod downloading task
ModDownloadTask.h
ModDownloadTask.cpp
# Use tracking separate from memory management # Use tracking separate from memory management
Usable.h Usable.h
@ -140,6 +144,8 @@ set(LAUNCH_SOURCES
launch/steps/TextPrint.h launch/steps/TextPrint.h
launch/steps/Update.cpp launch/steps/Update.cpp
launch/steps/Update.h launch/steps/Update.h
launch/steps/QuitAfterGameStop.cpp
launch/steps/QuitAfterGameStop.h
launch/LaunchStep.cpp launch/LaunchStep.cpp
launch/LaunchStep.h launch/LaunchStep.h
launch/LaunchTask.cpp launch/LaunchTask.cpp
@ -170,13 +176,6 @@ add_unit_test(DownloadTask
DATA updater/testdata DATA updater/testdata
) )
# Rarely used notifications
set(NOTIFICATIONS_SOURCES
# Notifications - short warning messages
notifications/NotificationChecker.h
notifications/NotificationChecker.cpp
)
# Backend for the news bar... there's usually no news. # Backend for the news bar... there's usually no news.
set(NEWS_SOURCES set(NEWS_SOURCES
# News System # News System
@ -221,7 +220,11 @@ set(MINECRAFT_SOURCES
minecraft/auth/flows/Mojang.h minecraft/auth/flows/Mojang.h
minecraft/auth/flows/MSA.cpp minecraft/auth/flows/MSA.cpp
minecraft/auth/flows/MSA.h minecraft/auth/flows/MSA.h
minecraft/auth/flows/Offline.cpp
minecraft/auth/flows/Offline.h
minecraft/auth/steps/OfflineStep.cpp
minecraft/auth/steps/OfflineStep.h
minecraft/auth/steps/EntitlementsStep.cpp minecraft/auth/steps/EntitlementsStep.cpp
minecraft/auth/steps/EntitlementsStep.h minecraft/auth/steps/EntitlementsStep.h
minecraft/auth/steps/GetSkinStep.cpp minecraft/auth/steps/GetSkinStep.cpp
@ -278,13 +281,6 @@ set(MINECRAFT_SOURCES
minecraft/launch/VerifyJavaInstall.cpp minecraft/launch/VerifyJavaInstall.cpp
minecraft/launch/VerifyJavaInstall.h minecraft/launch/VerifyJavaInstall.h
minecraft/legacy/LegacyModList.h
minecraft/legacy/LegacyModList.cpp
minecraft/legacy/LegacyInstance.h
minecraft/legacy/LegacyInstance.cpp
minecraft/legacy/LegacyUpgradeTask.h
minecraft/legacy/LegacyUpgradeTask.cpp
minecraft/GradleSpecifier.h minecraft/GradleSpecifier.h
minecraft/MinecraftInstance.cpp minecraft/MinecraftInstance.cpp
minecraft/MinecraftInstance.h minecraft/MinecraftInstance.h
@ -352,28 +348,30 @@ set(MINECRAFT_SOURCES
mojang/PackageManifest.h mojang/PackageManifest.h
mojang/PackageManifest.cpp mojang/PackageManifest.cpp
) minecraft/Agent.h)
add_unit_test(GradleSpecifier add_unit_test(GradleSpecifier
SOURCES minecraft/GradleSpecifier_test.cpp SOURCES minecraft/GradleSpecifier_test.cpp
LIBS Launcher_logic LIBS Launcher_logic
) )
add_executable(PackageManifest if(BUILD_TESTING)
mojang/PackageManifest_test.cpp add_executable(PackageManifest
) mojang/PackageManifest_test.cpp
target_link_libraries(PackageManifest )
Launcher_logic target_link_libraries(PackageManifest
Qt5::Test Launcher_logic
) Qt5::Test
target_include_directories(PackageManifest )
PRIVATE ../cmake/UnitTest/ target_include_directories(PackageManifest
) PRIVATE ../cmake/UnitTest/
add_test( )
NAME PackageManifest add_test(
COMMAND PackageManifest NAME PackageManifest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND PackageManifest
) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
add_unit_test(MojangVersionFormat add_unit_test(MojangVersionFormat
SOURCES minecraft/MojangVersionFormat_test.cpp SOURCES minecraft/MojangVersionFormat_test.cpp
@ -415,6 +413,11 @@ set(TASKS_SOURCES
tasks/SequentialTask.cpp tasks/SequentialTask.cpp
) )
add_unit_test(Task
SOURCES tasks/Task_test.cpp
LIBS Launcher_logic
)
set(SETTINGS_SOURCES set(SETTINGS_SOURCES
# Settings # Settings
settings/INIFile.cpp settings/INIFile.cpp
@ -491,6 +494,16 @@ set(META_SOURCES
meta/Index.h 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 set(FTB_SOURCES
modplatform/legacy_ftb/PackFetchTask.h modplatform/legacy_ftb/PackFetchTask.h
modplatform/legacy_ftb/PackFetchTask.cpp modplatform/legacy_ftb/PackFetchTask.cpp
@ -506,12 +519,19 @@ set(FLAME_SOURCES
# Flame # Flame
modplatform/flame/FlamePackIndex.cpp modplatform/flame/FlamePackIndex.cpp
modplatform/flame/FlamePackIndex.h modplatform/flame/FlamePackIndex.h
modplatform/flame/FlameModIndex.cpp
modplatform/flame/FlameModIndex.h
modplatform/flame/PackManifest.h modplatform/flame/PackManifest.h
modplatform/flame/PackManifest.cpp modplatform/flame/PackManifest.cpp
modplatform/flame/FileResolvingTask.h modplatform/flame/FileResolvingTask.h
modplatform/flame/FileResolvingTask.cpp modplatform/flame/FileResolvingTask.cpp
) )
set(MODRINTH_SOURCES
modplatform/modrinth/ModrinthPackIndex.cpp
modplatform/modrinth/ModrinthPackIndex.h
)
set(MODPACKSCH_SOURCES set(MODPACKSCH_SOURCES
modplatform/modpacksch/FTBPackInstallTask.h modplatform/modpacksch/FTBPackInstallTask.h
modplatform/modpacksch/FTBPackInstallTask.cpp modplatform/modpacksch/FTBPackInstallTask.cpp
@ -524,6 +544,8 @@ set(TECHNIC_SOURCES
modplatform/technic/SingleZipPackInstallTask.cpp modplatform/technic/SingleZipPackInstallTask.cpp
modplatform/technic/SolderPackInstallTask.h modplatform/technic/SolderPackInstallTask.h
modplatform/technic/SolderPackInstallTask.cpp modplatform/technic/SolderPackInstallTask.cpp
modplatform/technic/SolderPackManifest.h
modplatform/technic/SolderPackManifest.cpp
modplatform/technic/TechnicPackProcessor.h modplatform/technic/TechnicPackProcessor.h
modplatform/technic/TechnicPackProcessor.cpp modplatform/technic/TechnicPackProcessor.cpp
) )
@ -553,7 +575,6 @@ set(LOGIC_SOURCES
${NET_SOURCES} ${NET_SOURCES}
${LAUNCH_SOURCES} ${LAUNCH_SOURCES}
${UPDATE_SOURCES} ${UPDATE_SOURCES}
${NOTIFICATIONS_SOURCES}
${NEWS_SOURCES} ${NEWS_SOURCES}
${MINECRAFT_SOURCES} ${MINECRAFT_SOURCES}
${SCREENSHOTS_SOURCES} ${SCREENSHOTS_SOURCES}
@ -564,8 +585,10 @@ set(LOGIC_SOURCES
${TOOLS_SOURCES} ${TOOLS_SOURCES}
${META_SOURCES} ${META_SOURCES}
${ICONS_SOURCES} ${ICONS_SOURCES}
${API_SOURCES}
${FTB_SOURCES} ${FTB_SOURCES}
${FLAME_SOURCES} ${FLAME_SOURCES}
${MODRINTH_SOURCES}
${MODPACKSCH_SOURCES} ${MODPACKSCH_SOURCES}
${TECHNIC_SOURCES} ${TECHNIC_SOURCES}
${ATLAUNCHER_SOURCES} ${ATLAUNCHER_SOURCES}
@ -685,8 +708,6 @@ SET(LAUNCHER_SOURCES
ui/pages/instance/OtherLogsPage.h ui/pages/instance/OtherLogsPage.h
ui/pages/instance/ServersPage.cpp ui/pages/instance/ServersPage.cpp
ui/pages/instance/ServersPage.h ui/pages/instance/ServersPage.h
ui/pages/instance/LegacyUpgradePage.cpp
ui/pages/instance/LegacyUpgradePage.h
ui/pages/instance/WorldListPage.cpp ui/pages/instance/WorldListPage.cpp
ui/pages/instance/WorldListPage.h ui/pages/instance/WorldListPage.h
@ -707,13 +728,18 @@ SET(LAUNCHER_SOURCES
ui/pages/global/LauncherPage.h ui/pages/global/LauncherPage.h
ui/pages/global/ProxyPage.cpp ui/pages/global/ProxyPage.cpp
ui/pages/global/ProxyPage.h ui/pages/global/ProxyPage.h
ui/pages/global/PasteEEPage.cpp ui/pages/global/APIPage.cpp
ui/pages/global/PasteEEPage.h ui/pages/global/APIPage.h
# GUI - platform pages # GUI - platform pages
ui/pages/modplatform/VanillaPage.cpp ui/pages/modplatform/VanillaPage.cpp
ui/pages/modplatform/VanillaPage.h 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.cpp
ui/pages/modplatform/atlauncher/AtlFilterModel.h ui/pages/modplatform/atlauncher/AtlFilterModel.h
ui/pages/modplatform/atlauncher/AtlListModel.cpp ui/pages/modplatform/atlauncher/AtlListModel.cpp
@ -739,6 +765,10 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/flame/FlameModel.h ui/pages/modplatform/flame/FlameModel.h
ui/pages/modplatform/flame/FlamePage.cpp ui/pages/modplatform/flame/FlamePage.cpp
ui/pages/modplatform/flame/FlamePage.h ui/pages/modplatform/flame/FlamePage.h
ui/pages/modplatform/flame/FlameModModel.cpp
ui/pages/modplatform/flame/FlameModModel.h
ui/pages/modplatform/flame/FlameModPage.cpp
ui/pages/modplatform/flame/FlameModPage.h
ui/pages/modplatform/technic/TechnicModel.cpp ui/pages/modplatform/technic/TechnicModel.cpp
ui/pages/modplatform/technic/TechnicModel.h ui/pages/modplatform/technic/TechnicModel.h
@ -748,6 +778,11 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/ImportPage.cpp ui/pages/modplatform/ImportPage.cpp
ui/pages/modplatform/ImportPage.h ui/pages/modplatform/ImportPage.h
ui/pages/modplatform/modrinth/ModrinthModel.cpp
ui/pages/modplatform/modrinth/ModrinthModel.h
ui/pages/modplatform/modrinth/ModrinthPage.cpp
ui/pages/modplatform/modrinth/ModrinthPage.h
# GUI - dialogs # GUI - dialogs
ui/dialogs/AboutDialog.cpp ui/dialogs/AboutDialog.cpp
ui/dialogs/AboutDialog.h ui/dialogs/AboutDialog.h
@ -769,23 +804,26 @@ SET(LAUNCHER_SOURCES
ui/dialogs/LoginDialog.h ui/dialogs/LoginDialog.h
ui/dialogs/MSALoginDialog.cpp ui/dialogs/MSALoginDialog.cpp
ui/dialogs/MSALoginDialog.h ui/dialogs/MSALoginDialog.h
ui/dialogs/OfflineLoginDialog.cpp
ui/dialogs/OfflineLoginDialog.h
ui/dialogs/NewComponentDialog.cpp ui/dialogs/NewComponentDialog.cpp
ui/dialogs/NewComponentDialog.h ui/dialogs/NewComponentDialog.h
ui/dialogs/NewInstanceDialog.cpp ui/dialogs/NewInstanceDialog.cpp
ui/dialogs/NewInstanceDialog.h ui/dialogs/NewInstanceDialog.h
ui/dialogs/NotificationDialog.cpp
ui/dialogs/NotificationDialog.h
ui/pagedialog/PageDialog.cpp ui/pagedialog/PageDialog.cpp
ui/pagedialog/PageDialog.h ui/pagedialog/PageDialog.h
ui/dialogs/ProgressDialog.cpp ui/dialogs/ProgressDialog.cpp
ui/dialogs/ProgressDialog.h ui/dialogs/ProgressDialog.h
ui/dialogs/ReviewMessageBox.cpp
ui/dialogs/ReviewMessageBox.h
ui/dialogs/UpdateDialog.cpp ui/dialogs/UpdateDialog.cpp
ui/dialogs/UpdateDialog.h ui/dialogs/UpdateDialog.h
ui/dialogs/VersionSelectDialog.cpp ui/dialogs/VersionSelectDialog.cpp
ui/dialogs/VersionSelectDialog.h ui/dialogs/VersionSelectDialog.h
ui/dialogs/SkinUploadDialog.cpp ui/dialogs/SkinUploadDialog.cpp
ui/dialogs/SkinUploadDialog.h ui/dialogs/SkinUploadDialog.h
ui/dialogs/ModDownloadDialog.cpp
ui/dialogs/ModDownloadDialog.h
# GUI - widgets # GUI - widgets
ui/widgets/Common.cpp ui/widgets/Common.cpp
@ -810,6 +848,8 @@ SET(LAUNCHER_SOURCES
ui/widgets/LogView.h ui/widgets/LogView.h
ui/widgets/MCModInfoFrame.cpp ui/widgets/MCModInfoFrame.cpp
ui/widgets/MCModInfoFrame.h ui/widgets/MCModInfoFrame.h
ui/widgets/ModFilterWidget.cpp
ui/widgets/ModFilterWidget.h
ui/widgets/ModListView.cpp ui/widgets/ModListView.cpp
ui/widgets/ModListView.h ui/widgets/ModListView.h
ui/widgets/PageContainer.cpp ui/widgets/PageContainer.cpp
@ -842,7 +882,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/pages/global/AccountListPage.ui ui/pages/global/AccountListPage.ui
ui/pages/global/JavaPage.ui ui/pages/global/JavaPage.ui
ui/pages/global/LauncherPage.ui ui/pages/global/LauncherPage.ui
ui/pages/global/PasteEEPage.ui ui/pages/global/APIPage.ui
ui/pages/global/ProxyPage.ui ui/pages/global/ProxyPage.ui
ui/pages/global/MinecraftPage.ui ui/pages/global/MinecraftPage.ui
ui/pages/global/ExternalToolsPage.ui ui/pages/global/ExternalToolsPage.ui
@ -855,11 +895,11 @@ qt5_wrap_ui(LAUNCHER_UI
ui/pages/instance/InstanceSettingsPage.ui ui/pages/instance/InstanceSettingsPage.ui
ui/pages/instance/VersionPage.ui ui/pages/instance/VersionPage.ui
ui/pages/instance/WorldListPage.ui ui/pages/instance/WorldListPage.ui
ui/pages/instance/LegacyUpgradePage.ui
ui/pages/instance/ScreenshotsPage.ui ui/pages/instance/ScreenshotsPage.ui
ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
ui/pages/modplatform/atlauncher/AtlPage.ui ui/pages/modplatform/atlauncher/AtlPage.ui
ui/pages/modplatform/VanillaPage.ui ui/pages/modplatform/VanillaPage.ui
ui/pages/modplatform/ModPage.ui
ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/flame/FlamePage.ui
ui/pages/modplatform/legacy_ftb/Page.ui ui/pages/modplatform/legacy_ftb/Page.ui
ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/ImportPage.ui
@ -868,11 +908,11 @@ qt5_wrap_ui(LAUNCHER_UI
ui/widgets/InstanceCardWidget.ui ui/widgets/InstanceCardWidget.ui
ui/widgets/CustomCommands.ui ui/widgets/CustomCommands.ui
ui/widgets/MCModInfoFrame.ui ui/widgets/MCModInfoFrame.ui
ui/widgets/ModFilterWidget.ui
ui/dialogs/CopyInstanceDialog.ui ui/dialogs/CopyInstanceDialog.ui
ui/dialogs/ProfileSetupDialog.ui ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui ui/dialogs/ProgressDialog.ui
ui/dialogs/NewInstanceDialog.ui ui/dialogs/NewInstanceDialog.ui
ui/dialogs/NotificationDialog.ui
ui/dialogs/UpdateDialog.ui ui/dialogs/UpdateDialog.ui
ui/dialogs/NewComponentDialog.ui ui/dialogs/NewComponentDialog.ui
ui/dialogs/ProfileSelectDialog.ui ui/dialogs/ProfileSelectDialog.ui
@ -880,9 +920,11 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportInstanceDialog.ui
ui/dialogs/IconPickerDialog.ui ui/dialogs/IconPickerDialog.ui
ui/dialogs/MSALoginDialog.ui ui/dialogs/MSALoginDialog.ui
ui/dialogs/OfflineLoginDialog.ui
ui/dialogs/AboutDialog.ui ui/dialogs/AboutDialog.ui
ui/dialogs/LoginDialog.ui ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui ui/dialogs/EditAccountDialog.ui
ui/dialogs/ReviewMessageBox.ui
) )
qt5_add_resources(LAUNCHER_RESOURCES qt5_add_resources(LAUNCHER_RESOURCES
@ -908,9 +950,8 @@ endif()
add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES}) add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES})
target_link_libraries(Launcher_logic target_link_libraries(Launcher_logic
systeminfo systeminfo
Launcher_quazip
Launcher_classparser Launcher_classparser
${NBT_NAME} nbt++
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
optional-bare optional-bare
tomlc99 tomlc99
@ -926,10 +967,10 @@ target_link_libraries(Launcher_logic
) )
target_link_libraries(Launcher_logic target_link_libraries(Launcher_logic
Launcher_iconfix Launcher_iconfix
${QUAZIP_LIBRARIES} QuaZip::QuaZip
hoedown hoedown
Launcher_rainbow
LocalPeer LocalPeer
Launcher_rainbow
) )
target_link_libraries(Launcher_logic) target_link_libraries(Launcher_logic)
@ -950,7 +991,7 @@ if(DEFINED Launcher_APP_BINARY_DEFS)
endif() endif()
install(TARGETS ${Launcher_Name} install(TARGETS ${Launcher_Name}
BUNDLE DESTINATION ${BUNDLE_DEST_DIR} COMPONENT Runtime BUNDLE DESTINATION "." COMPONENT Runtime
LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
) )
@ -971,7 +1012,7 @@ if(INSTALL_BUNDLE STREQUAL "full")
DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
DESTINATION ${PLUGIN_DEST_DIR} DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime COMPONENT Runtime
REGEX "tga|tiff|mng|webp" EXCLUDE REGEX "tga|tiff|mng" EXCLUDE
) )
# Icon engines # Icon engines
install( install(
@ -1001,7 +1042,7 @@ if(INSTALL_BUNDLE STREQUAL "full")
DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
DESTINATION ${PLUGIN_DEST_DIR} DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime COMPONENT Runtime
REGEX "tga|tiff|mng|webp" EXCLUDE REGEX "tga|tiff|mng" EXCLUDE
REGEX "d\\." EXCLUDE REGEX "d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" 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 "DesktopServices.h"
#include <QDir> #include <QDir>
#include <QDesktopServices> #include <QDesktopServices>
#include <QProcess> #include <QProcess>
#include <QDebug> #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. * 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())); return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f); if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else #else
return f(); return f();
#endif #endif
@ -98,7 +140,14 @@ bool openFile(const QString &path)
return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f); if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else #else
return f(); return f();
#endif #endif
@ -109,10 +158,17 @@ bool openFile(const QString &application, const QString &path, const QString &wo
qDebug() << "Opening file" << path << "using" << application; qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]() if(!APPLICATION->isFlatpak())
{ {
return QProcess::startDetached(application, QStringList() << path, workingDirectory); return IndirectOpen([&]()
}, pid); {
return QProcess::startDetached(application, QStringList() << path, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
}
#else #else
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid); return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
#endif #endif
@ -122,11 +178,18 @@ bool run(const QString &application, const QStringList &args, const QString &wor
{ {
qDebug() << "Running" << application << "with args" << args.join(' '); qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!APPLICATION->isFlatpak())
{
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]() return IndirectOpen([&]()
{ {
return QProcess::startDetached(application, args, workingDirectory); return QProcess::startDetached(application, args, workingDirectory);
}, pid); }, pid);
}
else
{
return QProcess::startDetached(application, args, workingDirectory, pid);
}
#else #else
return QProcess::startDetached(application, args, workingDirectory, pid); return QProcess::startDetached(application, args, workingDirectory, pid);
#endif #endif
@ -140,7 +203,14 @@ bool openUrl(const QUrl &url)
return QDesktopServices::openUrl(url); return QDesktopServices::openUrl(url);
}; };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
return IndirectOpen(f); if(!APPLICATION->isFlatpak())
{
return IndirectOpen(f);
}
else
{
return f();
}
#else #else
return f(); return f();
#endif #endif

View File

@ -42,7 +42,6 @@ void InstanceCopyTask::copyFinished()
} }
// FIXME: shouldn't this be able to report errors? // FIXME: shouldn't this be able to report errors?
auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg")); auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
instanceSettings->registerSetting("InstanceType", "Legacy");
InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath)); InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
inst->setName(m_instName); inst->setName(m_instName);

View File

@ -9,6 +9,15 @@
InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version) InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version)
{ {
m_version = 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() void InstanceCreationTask::executeTask()
@ -17,12 +26,12 @@ void InstanceCreationTask::executeTask()
{ {
auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg")); auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
instanceSettings->suspendSave(); instanceSettings->suspendSave();
instanceSettings->registerSetting("InstanceType", "Legacy");
instanceSettings->set("InstanceType", "OneSix");
MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath); MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
auto components = inst.getPackProfile(); auto components = inst.getPackProfile();
components->buildingFromScratch(); components->buildingFromScratch();
components->setComponentVersion("net.minecraft", m_version->descriptor(), true); components->setComponentVersion("net.minecraft", m_version->descriptor(), true);
if(m_usingLoader)
components->setComponentVersion(m_loader, m_loaderVersion->descriptor(), true);
inst.setName(m_instName); inst.setName(m_instName);
inst.setIconKey(m_instIcon); inst.setIconKey(m_instIcon);
instanceSettings->resumeSave(); instanceSettings->resumeSave();

View File

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

View File

@ -29,7 +29,7 @@
#include "modplatform/flame/FileResolvingTask.h" #include "modplatform/flame/FileResolvingTask.h"
#include "modplatform/flame/PackManifest.h" #include "modplatform/flame/PackManifest.h"
#include "Json.h" #include "Json.h"
#include <quazipdir.h> #include <quazip/quazipdir.h>
#include "modplatform/technic/TechnicPackProcessor.h" #include "modplatform/technic/TechnicPackProcessor.h"
#include "icons/IconList.h" #include "icons/IconList.h"
@ -40,6 +40,14 @@ InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)
m_sourceUrl = sourceUrl; m_sourceUrl = sourceUrl;
} }
bool InstanceImportTask::abort()
{
m_filesNetJob->abort();
m_extractFuture.cancel();
return false;
}
void InstanceImportTask::executeTask() void InstanceImportTask::executeTask()
{ {
if (m_sourceUrl.isLocalFile()) if (m_sourceUrl.isLocalFile())
@ -241,6 +249,7 @@ void InstanceImportTask::processFlame()
QString forgeVersion; QString forgeVersion;
QString fabricVersion; QString fabricVersion;
// TODO: is Quilt relevant here?
for(auto &loader: pack.minecraft.modLoaders) for(auto &loader: pack.minecraft.modLoaders)
{ {
auto id = loader.id; auto id = loader.id;
@ -261,8 +270,6 @@ void InstanceImportTask::processFlame()
QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg"); QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
auto instanceSettings = std::make_shared<INISettingsObject>(configPath); auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
instanceSettings->registerSetting("InstanceType", "Legacy");
instanceSettings->set("InstanceType", "OneSix");
MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
auto mcVersion = pack.minecraft.version; auto mcVersion = pack.minecraft.version;
// Hack to correct some 'special sauce'... // Hack to correct some 'special sauce'...
@ -285,7 +292,7 @@ void InstanceImportTask::processFlame()
} }
else 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); components->setComponentVersion("net.minecraftforge", forgeVersion);
@ -422,7 +429,6 @@ void InstanceImportTask::processMultiMC()
{ {
QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg"); QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
auto instanceSettings = std::make_shared<INISettingsObject>(configPath); auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
instanceSettings->registerSetting("InstanceType", "Legacy");
NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath); NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath);

View File

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

View File

@ -32,7 +32,6 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include "InstanceTask.h" #include "InstanceTask.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "minecraft/legacy/LegacyInstance.h"
#include "NullInstance.h" #include "NullInstance.h"
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "FileSystem.h" #include "FileSystem.h"
@ -544,23 +543,8 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
auto instanceRoot = FS::PathCombine(m_instDir, id); auto instanceRoot = FS::PathCombine(m_instDir, id);
auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg")); auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg"));
InstancePtr inst; InstancePtr inst;
// TODO: Handle incompatible instances
instanceSettings->registerSetting("InstanceType", "Legacy"); inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
QString inst_type = instanceSettings->get("InstanceType").toString();
if (inst_type == "OneSix" || inst_type == "Nostalgia")
{
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
}
else if (inst_type == "Legacy")
{
inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
}
else
{
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
}
qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot(); qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot();
return inst; return inst;
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "minecraft/legacy/LegacyInstance.h"
#include <FileSystem.h> #include <FileSystem.h>
#include "ui/pages/BasePage.h" #include "ui/pages/BasePage.h"
#include "ui/pages/BasePageProvider.h" #include "ui/pages/BasePageProvider.h"
@ -14,7 +13,6 @@
#include "ui/pages/instance/ScreenshotsPage.h" #include "ui/pages/instance/ScreenshotsPage.h"
#include "ui/pages/instance/InstanceSettingsPage.h" #include "ui/pages/instance/InstanceSettingsPage.h"
#include "ui/pages/instance/OtherLogsPage.h" #include "ui/pages/instance/OtherLogsPage.h"
#include "ui/pages/instance/LegacyUpgradePage.h"
#include "ui/pages/instance/WorldListPage.h" #include "ui/pages/instance/WorldListPage.h"
#include "ui/pages/instance/ServersPage.h" #include "ui/pages/instance/ServersPage.h"
#include "ui/pages/instance/GameOptionsPage.h" #include "ui/pages/instance/GameOptionsPage.h"
@ -34,31 +32,20 @@ public:
QList<BasePage *> values; QList<BasePage *> values;
values.append(new LogPage(inst)); values.append(new LogPage(inst));
std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst); std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst);
if(onesix) values.append(new VersionPage(onesix.get()));
{ auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Mods"), "Loader-mods");
values.append(new VersionPage(onesix.get())); modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Loader mods"), "Loader-mods"); values.append(modsPage);
modsPage->setFilter("%1 (*.zip *.jar *.litemod)"); values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods"));
values.append(modsPage); values.append(new ResourcePackPage(onesix.get()));
values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods")); values.append(new TexturePackPage(onesix.get()));
values.append(new ResourcePackPage(onesix.get())); values.append(new ShaderPackPage(onesix.get()));
values.append(new TexturePackPage(onesix.get())); values.append(new NotesPage(onesix.get()));
values.append(new ShaderPackPage(onesix.get())); values.append(new WorldListPage(onesix.get(), onesix->worldList()));
values.append(new NotesPage(onesix.get())); values.append(new ServersPage(onesix));
values.append(new WorldListPage(onesix.get(), onesix->worldList())); // values.append(new GameOptionsPage(onesix.get()));
values.append(new ServersPage(onesix)); values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
// values.append(new GameOptionsPage(onesix.get())); values.append(new InstanceSettingsPage(onesix.get()));
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get()));
}
std::shared_ptr<LegacyInstance> legacy = std::dynamic_pointer_cast<LegacyInstance>(inst);
if(legacy)
{
values.append(new LegacyUpgradePage(legacy));
values.append(new NotesPage(legacy.get()));
values.append(new WorldListPage(legacy.get(), legacy->worldList()));
values.append(new ScreenshotsPage(FS::PathCombine(legacy->gameRoot(), "screenshots")));
}
auto logMatcher = inst->getLogFileMatcher(); auto logMatcher = inst->getLogFileMatcher();
if(logMatcher) if(logMatcher)
{ {
@ -74,3 +61,4 @@ public:
protected: protected:
InstancePtr inst; InstancePtr inst;
}; };

View File

@ -8,7 +8,7 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
|| jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize")) || jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize"))
{ {
auto warnStr = QObject::tr( 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" "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."); "This message will be displayed until you remove them from the JVM arguments.");
CustomMessageBox::selectable( CustomMessageBox::selectable(
@ -17,6 +17,17 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
QMessageBox::Warning)->exec(); QMessageBox::Warning)->exec();
return false; 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; return true;
} }
@ -40,7 +51,7 @@ void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result)
auto htmlError = result.errorLog; auto htmlError = result.errorLog;
QString text; QString text;
htmlError.replace('\n', "<br />"); 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); text += QString("<font color=\"red\">%1</font>").arg(htmlError);
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); 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; QString text;
text += QObject::tr( text += QObject::tr(
"The specified java binary didn't work.<br />You should use the auto-detect feature, " "The specified Java binary didn't work.<br />You should use the auto-detect feature, "
"or set the path to the java executable.<br />"); "or set the path to the Java executable.<br />");
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); 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 "LaunchController.h"
#include "minecraft/auth/AccountList.h" #include "minecraft/auth/AccountList.h"
#include "Application.h" #include "Application.h"
@ -36,7 +71,10 @@ void LaunchController::executeTask()
return; 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(); login();
} }
@ -56,7 +94,7 @@ void LaunchController::decideAccount()
m_parentWidget, m_parentWidget,
tr("No Accounts"), tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Mojang or Minecraft " tr("In order to play Minecraft, you must have at least one Mojang or Minecraft "
"account logged in." "account logged in. "
"Would you like to open the account manager to add an account now?"), "Would you like to open the account manager to add an account now?"),
QMessageBox::Information, QMessageBox::Information,
QMessageBox::Yes | QMessageBox::No QMessageBox::Yes | QMessageBox::No
@ -116,6 +154,12 @@ void LaunchController::login() {
m_session->wants_online = m_online; m_session->wants_online = m_online;
m_accountToUse->fillSession(m_session); m_accountToUse->fillSession(m_session);
// Launch immediately in true offline mode
if(m_accountToUse->isOffline()) {
launchInstance();
return;
}
switch(m_accountToUse->accountState()) { switch(m_accountToUse->accountState()) {
case AccountState::Offline: { case AccountState::Offline: {
m_session->wants_online = false; m_session->wants_online = false;
@ -125,13 +169,14 @@ void LaunchController::login() {
if(!m_session->wants_online) { if(!m_session->wants_online) {
// we ask the user for a player name // we ask the user for a player name
bool ok = false; 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( QString name = QInputDialog::getText(
m_parentWidget, m_parentWidget,
tr("Player name"), tr("Player name"),
tr("Choose your offline mode player name."), tr("Choose your offline mode player name."),
QLineEdit::Normal, QLineEdit::Normal,
m_session->player_name, usedname,
&ok &ok
); );
if (!ok) if (!ok)
@ -142,6 +187,7 @@ void LaunchController::login() {
if (name.length()) if (name.length())
{ {
usedname = name; usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname);
} }
m_session->MakeOffline(usedname); m_session->MakeOffline(usedname);
// offline flavored game from here :3 // offline flavored game from here :3
@ -222,6 +268,18 @@ void LaunchController::login() {
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
case AccountState::Disabled: {
auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again.");
QMessageBox::warning(
m_parentWidget,
tr("Client identification changed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString);
return;
}
case AccountState::Gone: { case AccountState::Gone: {
auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to."); auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to.");
QMessageBox::warning( QMessageBox::warning(

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 #pragma once
#include <QObject> #include <QObject>
#include <BaseInstance.h> #include <BaseInstance.h>

View File

@ -14,14 +14,14 @@ if [[ $EUID -eq 0 ]]; then
fi fi
LAUNCHER_NAME=@Launcher_Name@ LAUNCHER_NAME=@Launcher_APP_BINARY_NAME@
LAUNCHER_DIR="$(dirname "$(readlink -f "$0")")" LAUNCHER_DIR="$(dirname "$(readlink -f "$0")")"
echo "Launcher Dir: ${LAUNCHER_DIR}" echo "Launcher Dir: ${LAUNCHER_DIR}"
# Set up env - filter out input LD_ variables but pass them in under different names # 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_LIBRARY_PATH=${GAME_LIBRARY_PATH-${LD_LIBRARY_PATH}}
export GAME_PRELOAD=${GAME_PRELOAD-${LD_PRELOAD}} 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 LD_PRELOAD=$LAUNCHER_PRELOAD
export QT_PLUGIN_PATH="${LAUNCHER_DIR}/plugins" export QT_PLUGIN_PATH="${LAUNCHER_DIR}/plugins"
export QT_FONTPATH="${LAUNCHER_DIR}/fonts" export QT_FONTPATH="${LAUNCHER_DIR}/fonts"

View File

@ -1,29 +1,48 @@
/* 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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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.h> #include <quazip/quazip.h>
#include <quazipdir.h> #include <quazip/quazipdir.h>
#include <quazipfile.h> #include <quazip/quazipfile.h>
#include <JlCompress.h>
#include "MMCZip.h" #include "MMCZip.h"
#include "FileSystem.h" #include "FileSystem.h"
#include <QDebug> #include <QDebug>
// ours // ours
bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, const JlCompress::FilterFunction filter) bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, const FilterFunction filter)
{ {
QuaZip modZip(from.filePath()); QuaZip modZip(from.filePath());
modZip.open(QuaZip::mdUnzip); modZip.open(QuaZip::mdUnzip);
@ -74,6 +93,39 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &containe
return true; return true;
} }
bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files)
{
QDir directory(dir);
if (!directory.exists()) return false;
for (auto e : files) {
auto filePath = directory.relativeFilePath(e.absoluteFilePath());
if( !JlCompress::compressFile(zip, e.absoluteFilePath(), filePath)) return false;
}
return true;
}
bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files)
{
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed);
return false;
}
auto result = compressDirFiles(&zip, dir, files);
zip.close();
if(zip.getZipError()!=0) {
QFile::remove(fileCompressed);
return false;
}
return result;
}
// ours // ours
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods) bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
{ {
@ -122,13 +174,22 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
} }
else if (mod.type() == Mod::MOD_FOLDER) else if (mod.type() == Mod::MOD_FOLDER)
{ {
// untested, but seems to be unused / not possible to reach
// FIXME: buggy - does not work with addedFiles // FIXME: buggy - does not work with addedFiles
auto filename = mod.filename(); auto filename = mod.filename();
QString what_to_zip = filename.absoluteFilePath(); QString what_to_zip = filename.absoluteFilePath();
QDir dir(what_to_zip); QDir dir(what_to_zip);
dir.cdUp(); dir.cdUp();
QString parent_dir = dir.absolutePath(); QString parent_dir = dir.absolutePath();
if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, addedFiles)) auto files = QFileInfoList();
MMCZip::collectFileListRecursively(what_to_zip, nullptr, &files, nullptr);
for (auto e : files) {
if (addedFiles.contains(e.filePath()))
files.removeAll(e);
}
if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files))
{ {
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
@ -136,7 +197,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
return false; return false;
} }
qDebug() << "Adding folder " << filename.fileName() << " from " qDebug() << "Adding folder " << filename.fileName() << " from "
<< filename.absoluteFilePath(); << filename.absoluteFilePath();
} }
else else
{ {
@ -310,3 +371,37 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target)
} }
return MMCZip::extractRelFile(&zip, file, target); return MMCZip::extractRelFile(&zip, file, target);
} }
bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList *files,
MMCZip::FilterFunction excludeFilter) {
QDir rootDirectory(rootDir);
if (!rootDirectory.exists()) return false;
QDir directory;
if (subDir == nullptr)
directory = rootDirectory;
else
directory = QDir(subDir);
if (!directory.exists()) return false; // shouldn't ever happen
// recurse directories
QFileInfoList entries = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
for (const auto& e: entries) {
if (!collectFileListRecursively(rootDir, e.filePath(), files, excludeFilter))
return false;
}
// collect files
entries = directory.entryInfoList(QDir::Files);
for (const auto& e: entries) {
QString relativeFilePath = rootDirectory.relativeFilePath(e.absoluteFilePath());
if (excludeFilter && excludeFilter(relativeFilePath)) {
qDebug() << "Skipping file " << relativeFilePath;
continue;
}
files->append(e.filePath()); // we want the original paths for MMCZip::compressDirFiles
}
return true;
}

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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 #pragma once
@ -21,17 +41,36 @@
#include "minecraft/mod/Mod.h" #include "minecraft/mod/Mod.h"
#include <functional> #include <functional>
#include <JlCompress.h> #include <quazip/JlCompress.h>
#include <nonstd/optional> #include <nonstd/optional>
namespace MMCZip namespace MMCZip
{ {
using FilterFunction = std::function<bool(const QString &)>;
/** /**
* Merge two zip files, using a filter function * Merge two zip files, using a filter function
*/ */
bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
const JlCompress::FilterFunction filter = nullptr); const FilterFunction filter = nullptr);
/**
* Compress directory, by providing a list of files to compress
* \param zip target archive
* \param dir directory that will be compressed (to compress with relative paths)
* \param files list of files to compress
* \return true for success or false for failure
*/
bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files);
/**
* Compress directory, by providing a list of files to compress
* \param fileCompressed target archive file
* \param dir directory that will be compressed (to compress with relative paths)
* \param files list of files to compress
* \return true for success or false for failure
*/
bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files);
/** /**
* take a source jar, add mods to it, resulting in target jar * take a source jar, add mods to it, resulting in target jar
@ -89,4 +128,13 @@ namespace MMCZip
*/ */
bool extractFile(QString fileCompressed, QString file, QString dir); bool extractFile(QString fileCompressed, QString file, QString dir);
/**
* Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included.
* \param rootDir directory to start off
* \param subDir subdirectory, should be nullptr for first invocation
* \param files resulting list of QFileInfo
* \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude)
* \return true for success or false for failure
*/
bool collectFileListRecursively(const QString &rootDir, const QString &subDir, QFileInfoList *files, FilterFunction excludeFilter);
} }

View File

@ -0,0 +1,39 @@
#include "ModDownloadTask.h"
#include "Application.h"
ModDownloadTask::ModDownloadTask(const QUrl sourceUrl,const QString filename, const std::shared_ptr<ModFolderModel> mods)
: m_sourceUrl(sourceUrl), mods(mods), filename(filename) {
}
void ModDownloadTask::executeTask() {
setStatus(tr("Downloading mod:\n%1").arg(m_sourceUrl.toString()));
m_filesNetJob.reset(new NetJob(tr("Mod download"), APPLICATION->network()));
m_filesNetJob->addNetAction(Net::Download::makeFile(m_sourceUrl, mods->dir().absoluteFilePath(filename)));
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ModDownloadTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &ModDownloadTask::downloadProgressChanged);
connect(m_filesNetJob.get(), &NetJob::failed, this, &ModDownloadTask::downloadFailed);
m_filesNetJob->start();
}
void ModDownloadTask::downloadSucceeded()
{
emitSucceeded();
m_filesNetJob.reset();
}
void ModDownloadTask::downloadFailed(QString reason)
{
emitFailed(reason);
m_filesNetJob.reset();
}
void ModDownloadTask::downloadProgressChanged(qint64 current, qint64 total)
{
emit progress(current, total);
}
bool ModDownloadTask::abort() {
return m_filesNetJob->abort();
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "QObjectPtr.h"
#include "tasks/Task.h"
#include "minecraft/mod/ModFolderModel.h"
#include "net/NetJob.h"
#include <QUrl>
class ModDownloadTask : public Task {
Q_OBJECT
public:
explicit ModDownloadTask(const QUrl sourceUrl, const QString filename, const std::shared_ptr<ModFolderModel> mods);
const QString& getFilename() const { return filename; }
public slots:
bool abort() override;
protected:
//! Entry point for tasks.
void executeTask() override;
private:
QUrl m_sourceUrl;
NetJob::Ptr m_filesNetJob;
const std::shared_ptr<ModFolderModel> mods;
const QString filename;
void downloadProgressChanged(qint64 current, qint64 total);
void downloadFailed(QString reason);
void downloadSucceeded();
};

View File

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

View File

@ -103,11 +103,15 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
for(QString line : lines) for(QString line : lines)
{ {
line = line.trimmed(); line = line.trimmed();
// NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux
if (line.contains("/bedrock/strata")) {
continue;
}
auto parts = line.split('=', QString::SkipEmptyParts); auto parts = line.split('=', QString::SkipEmptyParts);
if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
{ {
success = false; continue;
} }
else else
{ {
@ -125,7 +129,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
auto os_arch = results["os.arch"]; auto os_arch = results["os.arch"];
auto java_version = results["java.version"]; auto java_version = results["java.version"];
auto java_vendor = results["java.vendor"]; 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; result.validity = JavaCheckResult::Validity::Valid;

View File

@ -120,8 +120,8 @@ void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
bool sortJavas(BaseVersionPtr left, BaseVersionPtr right) bool sortJavas(BaseVersionPtr left, BaseVersionPtr right)
{ {
auto rleft = std::dynamic_pointer_cast<JavaInstall>(left); auto rleft = std::dynamic_pointer_cast<JavaInstall>(right);
auto rright = std::dynamic_pointer_cast<JavaInstall>(right); auto rright = std::dynamic_pointer_cast<JavaInstall>(left);
return (*rleft) > (*rright); return (*rleft) > (*rright);
} }
@ -183,7 +183,7 @@ void JavaListLoadTask::javaCheckerFinished()
JavaInstallPtr javaVersion(new JavaInstall()); JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = result.javaVersion; javaVersion->id = result.javaVersion;
javaVersion->arch = result.mojangPlatform; javaVersion->arch = result.realPlatform;
javaVersion->path = result.path; javaVersion->path = result.path;
candidates.append(javaVersion); candidates.append(javaVersion);

View File

@ -77,14 +77,14 @@ QProcessEnvironment CleanEnviroment()
qDebug() << "Env: ignoring" << key << value; qDebug() << "Env: ignoring" << key << value;
continue; continue;
} }
// filter MultiMC-related things // filter PolyMC-related things
if(key.startsWith("QT_")) if(key.startsWith("QT_"))
{ {
qDebug() << "Env: ignoring" << key << value; qDebug() << "Env: ignoring" << key << value;
continue; continue;
} }
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// Do not pass LD_* variables to java. They were intended for MultiMC // Do not pass LD_* variables to java. They were intended for PolyMC
if(key.startsWith("LD_")) if(key.startsWith("LD_"))
{ {
qDebug() << "Env: ignoring" << key << value; qDebug() << "Env: ignoring" << key << value;
@ -149,6 +149,21 @@ JavaInstallPtr JavaUtils::GetDefaultJava()
return javaVersion; return javaVersion;
} }
QStringList addJavasFromEnv(QList<QString> javas)
{
QByteArray env = qgetenv("POLYMC_JAVA_PATHS");
#if defined(Q_OS_WIN32)
QList<QString> javaPaths = QString::fromLocal8Bit(env).replace("\\", "/").split(QLatin1String(";"));
#else
QList<QString> javaPaths = QString::fromLocal8Bit(env).split(QLatin1String(":"));
#endif
for(QString i : javaPaths)
{
javas.append(i);
};
return javas;
}
#if defined(Q_OS_WIN32) #if defined(Q_OS_WIN32)
QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName, QString keyJavaDir, QString subkeySuffix) QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName, QString keyJavaDir, QString subkeySuffix)
{ {
@ -290,7 +305,7 @@ QList<QString> JavaUtils::FindJavaPaths()
KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath");
QList<JavaInstallPtr> ZULU32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ZULU32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath");
// BellSoft Liberica // BellSoft Liberica
QList<JavaInstallPtr> LIBERICA64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> LIBERICA64s = this->FindJavaFromRegistryKey(
KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath");
@ -328,7 +343,7 @@ QList<QString> JavaUtils::FindJavaPaths()
java_candidates.append(ADOPTIUMJDK32s); java_candidates.append(ADOPTIUMJDK32s);
java_candidates.append(ZULU32s); java_candidates.append(ZULU32s);
java_candidates.append(LIBERICA32s); java_candidates.append(LIBERICA32s);
java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path)); java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
QList<QString> candidates; QList<QString> candidates;
@ -340,7 +355,7 @@ QList<QString> JavaUtils::FindJavaPaths()
} }
} }
return candidates; return addJavasFromEnv(candidates);
} }
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
@ -363,7 +378,7 @@ QList<QString> JavaUtils::FindJavaPaths()
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
} }
return javas; return addJavasFromEnv(javas);
} }
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
@ -402,14 +417,14 @@ QList<QString> JavaUtils::FindJavaPaths()
scanJavaDir("/usr/lib/jvm"); scanJavaDir("/usr/lib/jvm");
scanJavaDir("/usr/lib64/jvm"); scanJavaDir("/usr/lib64/jvm");
scanJavaDir("/usr/lib32/jvm"); scanJavaDir("/usr/lib32/jvm");
// javas stored in MultiMC's folder // javas stored in PolyMC's folder
scanJavaDir("java"); scanJavaDir("java");
// manually installed JDKs in /opt // manually installed JDKs in /opt
scanJavaDir("/opt/jdk"); scanJavaDir("/opt/jdk");
scanJavaDir("/opt/jdks"); scanJavaDir("/opt/jdks");
// flatpak // flatpak
scanJavaDir("/app/jdk"); scanJavaDir("/app/jdk");
return javas; return addJavasFromEnv(javas);
} }
#else #else
QList<QString> JavaUtils::FindJavaPaths() QList<QString> JavaUtils::FindJavaPaths()
@ -419,6 +434,6 @@ QList<QString> JavaUtils::FindJavaPaths()
QList<QString> javas; QList<QString> javas;
javas.append(this->GetDefaultJava()->path); javas.append(this->GetDefaultJava()->path);
return javas; return addJavasFromEnv(javas);
} }
#endif #endif

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"); * This program is distributed in the hope that it will be useful,
* you may not use this file except in compliance with the License. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* You may obtain a copy of the License at * 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 * This file incorporates work covered by the following copyright and
* distributed under the License is distributed on an "AS IS" BASIS, * permission notice:
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * Copyright 2013-2021 MultiMC Contributors
* limitations under the License. *
* 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" #include "launch/LaunchTask.h"
@ -212,7 +232,7 @@ shared_qobject_ptr<LogModel> LaunchTask::getLogModel()
m_logModel->setMaxLines(m_instance->getConsoleMaxLines()); m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow()); m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
// FIXME: should this really be here? // FIXME: should this really be here?
m_logModel->setOverflowMessage(tr("MultiMC 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" "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())); " likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines()));
} }
@ -277,4 +297,3 @@ QString LaunchTask::substituteVariables(const QString &cmd) const
} }
return out; return out;
} }

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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" #include "CheckJava.h"
@ -87,14 +107,14 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
// Error message displayed if java can't start // Error message displayed if java can't start
emit logLine(QString("Could not start java:"), MessageLevel::Error); emit logLine(QString("Could not start java:"), MessageLevel::Error);
emit logLines(result.errorLog.split('\n'), MessageLevel::Error); emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
emit logLine("\nCheck your MultiMC Java settings.", MessageLevel::Launcher); emit logLine(QString("\nCheck your Java settings."), MessageLevel::Launcher);
printSystemInfo(false, false); printSystemInfo(false, false);
emitFailed(QString("Could not start java!")); emitFailed(QString("Could not start java!"));
return; return;
} }
case JavaCheckResult::Validity::ReturnedInvalidData: case JavaCheckResult::Validity::ReturnedInvalidData:
{ {
emit logLine(QString("Java checker returned some invalid data MultiMC 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 logLines(result.outLog.split('\n'), MessageLevel::Warning);
emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher); emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher);
printSystemInfo(false, false); printSystemInfo(false, false);
@ -104,7 +124,8 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
case JavaCheckResult::Validity::Valid: case JavaCheckResult::Validity::Valid:
{ {
auto instance = m_parent->instance(); 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("JavaVersion", result.javaVersion.toString());
instance->settings()->set("JavaArchitecture", result.mojangPlatform); instance->settings()->set("JavaArchitecture", result.mojangPlatform);
instance->settings()->set("JavaVendor", result.javaVendor); 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) 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); emit logLine(QString("Java is version %1, using %2 architecture, from %3.\n\n").arg(version, architecture, vendor), MessageLevel::Launcher);
printSystemInfo(true, architecture == "64");
} }
void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit) 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); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif #endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
// initialize Qt // initialize Qt
Application app(argc, argv); 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"; 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){ auto minecraft = std::find_if(components.begin(), components.end(), [](ComponentPtr & cmp){
return cmp->getID() == "net.minecraft"; 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 "LaunchProfile.h"
#include <Version.h> #include <Version.h>
@ -7,11 +42,13 @@ void LaunchProfile::clear()
m_minecraftVersionType.clear(); m_minecraftVersionType.clear();
m_minecraftAssets.reset(); m_minecraftAssets.reset();
m_minecraftArguments.clear(); m_minecraftArguments.clear();
m_addnJvmArguments.clear();
m_tweakers.clear(); m_tweakers.clear();
m_mainClass.clear(); m_mainClass.clear();
m_appletClass.clear(); m_appletClass.clear();
m_libraries.clear(); m_libraries.clear();
m_mavenFiles.clear(); m_mavenFiles.clear();
m_agents.clear();
m_traits.clear(); m_traits.clear();
m_jarMods.clear(); m_jarMods.clear();
m_mainJar.reset(); m_mainJar.reset();
@ -45,6 +82,11 @@ void LaunchProfile::applyMinecraftArguments(const QString& minecraftArguments)
applyString(minecraftArguments, this->m_minecraftArguments); applyString(minecraftArguments, this->m_minecraftArguments);
} }
void LaunchProfile::applyAddnJvmArguments(const QStringList& addnJvmArguments)
{
this->m_addnJvmArguments.append(addnJvmArguments);
}
void LaunchProfile::applyMinecraftVersionType(const QString& type) void LaunchProfile::applyMinecraftVersionType(const QString& type)
{ {
applyString(type, this->m_minecraftVersionType); 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) void LaunchProfile::applyLibrary(LibraryPtr library)
{ {
if(!library->isActive()) if(!library->isActive())
@ -174,6 +221,22 @@ void LaunchProfile::applyMavenFile(LibraryPtr mavenFile)
m_mavenFiles.append(Library::limitedCopy(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 const LibraryPtr LaunchProfile::getMainJar() const
{ {
return m_mainJar; return m_mainJar;
@ -255,6 +318,11 @@ QString LaunchProfile::getMinecraftArguments() const
return m_minecraftArguments; return m_minecraftArguments;
} }
const QStringList & LaunchProfile::getAddnJvmArguments() const
{
return m_addnJvmArguments;
}
const QList<LibraryPtr> & LaunchProfile::getJarMods() const const QList<LibraryPtr> & LaunchProfile::getJarMods() const
{ {
return m_jarMods; return m_jarMods;
@ -275,6 +343,16 @@ const QList<LibraryPtr> & LaunchProfile::getMavenFiles() const
return m_mavenFiles; return m_mavenFiles;
} }
const QList<AgentPtr> & LaunchProfile::getAgents() const
{
return m_agents;
}
const QList<int> & LaunchProfile::getCompatibleJavaMajors() const
{
return m_compatibleJavaMajors;
}
void LaunchProfile::getLibraryFiles( void LaunchProfile::getLibraryFiles(
const QString& architecture, const QString& architecture,
QStringList& jars, 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 #pragma once
#include <QString> #include <QString>
#include "Library.h" #include "Library.h"
#include "Agent.h"
#include <ProblemProvider.h> #include <ProblemProvider.h>
class LaunchProfile: public ProblemProvider class LaunchProfile: public ProblemProvider
@ -13,6 +49,7 @@ public: /* application of profile variables from patches */
void applyMainClass(const QString& mainClass); void applyMainClass(const QString& mainClass);
void applyAppletClass(const QString& appletClass); void applyAppletClass(const QString& appletClass);
void applyMinecraftArguments(const QString& minecraftArguments); void applyMinecraftArguments(const QString& minecraftArguments);
void applyAddnJvmArguments(const QStringList& minecraftArguments);
void applyMinecraftVersionType(const QString& type); void applyMinecraftVersionType(const QString& type);
void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets); void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
void applyTraits(const QSet<QString> &traits); void applyTraits(const QSet<QString> &traits);
@ -21,6 +58,8 @@ public: /* application of profile variables from patches */
void applyMods(const QList<LibraryPtr> &jarMods); void applyMods(const QList<LibraryPtr> &jarMods);
void applyLibrary(LibraryPtr library); void applyLibrary(LibraryPtr library);
void applyMavenFile(LibraryPtr library); void applyMavenFile(LibraryPtr library);
void applyAgent(AgentPtr agent);
void applyCompatibleJavaMajors(QList<int>& javaMajor);
void applyMainJar(LibraryPtr jar); void applyMainJar(LibraryPtr jar);
void applyProblemSeverity(ProblemSeverity severity); void applyProblemSeverity(ProblemSeverity severity);
/// clear the profile /// clear the profile
@ -33,12 +72,15 @@ public: /* getters for profile variables */
QString getMinecraftVersionType() const; QString getMinecraftVersionType() const;
MojangAssetIndexInfo::Ptr getMinecraftAssets() const; MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
QString getMinecraftArguments() const; QString getMinecraftArguments() const;
const QStringList & getAddnJvmArguments() const;
const QSet<QString> & getTraits() const; const QSet<QString> & getTraits() const;
const QStringList & getTweakers() const; const QStringList & getTweakers() const;
const QList<LibraryPtr> & getJarMods() const; const QList<LibraryPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const; const QList<LibraryPtr> & getLibraries() const;
const QList<LibraryPtr> & getNativeLibraries() const; const QList<LibraryPtr> & getNativeLibraries() const;
const QList<LibraryPtr> & getMavenFiles() const; const QList<LibraryPtr> & getMavenFiles() const;
const QList<AgentPtr> & getAgents() const;
const QList<int> & getCompatibleJavaMajors() const;
const LibraryPtr getMainJar() const; const LibraryPtr getMainJar() const;
void getLibraryFiles( void getLibraryFiles(
const QString & architecture, const QString & architecture,
@ -69,6 +111,12 @@ private:
*/ */
QString m_minecraftArguments; 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 /// A list of all tweaker classes
QStringList m_tweakers; QStringList m_tweakers;
@ -84,6 +132,9 @@ private:
/// the list of maven files to be placed in the libraries folder, but not acted upon /// the list of maven files to be placed in the libraries folder, but not acted upon
QList<LibraryPtr> m_mavenFiles; QList<LibraryPtr> m_mavenFiles;
/// the list of java agents to add to JVM arguments
QList<AgentPtr> m_agents;
/// the main jar /// the main jar
LibraryPtr m_mainJar; LibraryPtr m_mainJar;
@ -99,6 +150,9 @@ private:
/// the list of mods /// the list of mods
QList<LibraryPtr> m_mods; QList<LibraryPtr> m_mods;
/// compatible java major versions
QList<int> m_compatibleJavaMajors;
ProblemSeverity m_problemSeverity = ProblemSeverity::None; ProblemSeverity m_problemSeverity = ProblemSeverity::None;
}; };

View File

@ -156,7 +156,7 @@ public: /* methods */
QStringList & failedLocalFiles, const QString & overridePath) const; QStringList & failedLocalFiles, const QString & overridePath) const;
private: /* methods */ private: /* methods */
/// the default storage prefix used by MultiMC /// the default storage prefix used by PolyMC
static QString defaultStoragePrefix(); static QString defaultStoragePrefix();
/// Get the prefix - root of the storage to be used /// Get the prefix - root of the storage to be used
@ -177,23 +177,23 @@ protected: /* data */
/// DEPRECATED URL prefix of the maven repo where the file can be downloaded /// DEPRECATED URL prefix of the maven repo where the file can be downloaded
QString m_repositoryURL; QString m_repositoryURL;
/// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined /// DEPRECATED: PolyMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined
QString m_absoluteURL; QString m_absoluteURL;
/// MultiMC extension - filename override /// PolyMC extension - filename override
QString m_filename; QString m_filename;
/// DEPRECATED MultiMC extension - display name /// DEPRECATED PolyMC extension - display name
QString m_displayname; QString m_displayname;
/** /**
* MultiMC-specific type hint - modifies how the library is treated * PolyMC-specific type hint - modifies how the library is treated
*/ */
QString m_hint; QString m_hint;
/** /**
* storage - by default the local libraries folder in multimc, but could be elsewhere * storage - by default the local libraries folder in polymc, but could be elsewhere
* MultiMC specific, because of FTB. * PolyMC specific, because of FTB.
*/ */
QString m_storagePrefix; QString m_storagePrefix;
@ -215,3 +215,4 @@ protected: /* data */
/// MOJANG: container with Mojang style download info /// MOJANG: container with Mojang style download info
MojangLibraryDownloadInfo::Ptr m_mojangDownloads; MojangLibraryDownloadInfo::Ptr m_mojangDownloads;
}; };

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 "MinecraftInstance.h"
#include "BuildConfig.h"
#include "minecraft/launch/CreateGameFolders.h" #include "minecraft/launch/CreateGameFolders.h"
#include "minecraft/launch/ExtractNatives.h" #include "minecraft/launch/ExtractNatives.h"
#include "minecraft/launch/PrintInstanceInfo.h" #include "minecraft/launch/PrintInstanceInfo.h"
@ -20,6 +56,7 @@
#include "launch/steps/PreLaunchCommand.h" #include "launch/steps/PreLaunchCommand.h"
#include "launch/steps/TextPrint.h" #include "launch/steps/TextPrint.h"
#include "launch/steps/CheckJava.h" #include "launch/steps/CheckJava.h"
#include "launch/steps/QuitAfterGameStop.h"
#include "minecraft/launch/LauncherPartLaunch.h" #include "minecraft/launch/LauncherPartLaunch.h"
#include "minecraft/launch/DirectJavaLaunch.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("JavaPath"), javaOrLocation);
m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs); m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
m_settings->registerOverride(globalSettings->getSetting("IgnoreJavaCompatibility"), javaOrLocation);
// special! // special!
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation); m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
@ -124,18 +162,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
m_settings->registerSetting("JoinServerOnLaunch", false); m_settings->registerSetting("JoinServerOnLaunch", false);
m_settings->registerSetting("JoinServerOnLaunchAddress", ""); m_settings->registerSetting("JoinServerOnLaunchAddress", "");
// DEPRECATED: Read what versions the user configuration thinks should be used
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
m_settings->registerSetting("LWJGLVersion", "");
m_settings->registerSetting("ForgeVersion", "");
m_settings->registerSetting("LiteloaderVersion", "");
m_components.reset(new PackProfile(this)); m_components.reset(new PackProfile(this));
m_components->setOldConfigVersion("net.minecraft", m_settings->get("IntendedVersion").toString());
auto setting = m_settings->getSetting("LWJGLVersion");
m_components->setOldConfigVersion("org.lwjgl", m_settings->get("LWJGLVersion").toString());
m_components->setOldConfigVersion("net.minecraftforge", m_settings->get("ForgeVersion").toString());
m_components->setOldConfigVersion("com.mumfrey.liteloader", m_settings->get("LiteloaderVersion").toString());
} }
void MinecraftInstance::saveNow() void MinecraftInstance::saveNow()
@ -186,8 +213,12 @@ QString MinecraftInstance::binRoot() const
QString MinecraftInstance::getNativePath() const QString MinecraftInstance::getNativePath() const
{ {
#ifdef Q_OS_FREEBSD
QDir natives_dir("/usr/local/lib/lwjgl/");
#else
QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/")); QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
return natives_dir.absolutePath(); return natives_dir.absolutePath();
#endif
} }
QString MinecraftInstance::getLocalLibraryPath() const QString MinecraftInstance::getLocalLibraryPath() const
@ -303,6 +334,17 @@ QStringList MinecraftInstance::extraArguments() const
list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true", list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
"-Dfml.ignorePatchDiscrepancies=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; return list;
} }
@ -445,7 +487,7 @@ QStringList MinecraftInstance::processMinecraftArgs(
} }
// blatant self-promotion. // blatant self-promotion.
token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5"; token_mapping["profile_name"] = token_mapping["version_name"] = BuildConfig.LAUNCHER_NAME;
token_mapping["version_type"] = profile->getMinecraftVersionType(); token_mapping["version_type"] = profile->getMinecraftVersionType();
@ -946,6 +988,11 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
{ {
process->setCensorFilter(createCensorFilterFromSession(session)); process->setCensorFilter(createCensorFilterFromSession(session));
} }
if(APPLICATION->settings()->get("QuitAfterGameStop").toBool())
{
auto step = new QuitAfterGameStop(pptr);
process->appendStep(step);
}
m_launchProcess = process; m_launchProcess = process;
emit launchTaskChanged(m_launchProcess); emit launchTaskChanged(m_launchProcess);
return m_launchProcess; return m_launchProcess;

View File

@ -20,7 +20,7 @@
#include <QUrl> #include <QUrl>
#include "tasks/Task.h" #include "tasks/Task.h"
#include <quazip.h> #include <quazip/quazip.h>
#include "QObjectPtr.h" #include "QObjectPtr.h"

View File

@ -22,7 +22,7 @@
#include "net/NetJob.h" #include "net/NetJob.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include "minecraft/VersionFilterData.h" #include "minecraft/VersionFilterData.h"
#include <quazip.h> #include <quazip/quazip.h>
class MinecraftVersion; class MinecraftVersion;
class MinecraftInstance; class MinecraftInstance;

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 "MojangVersionFormat.h"
#include "OneSixVersionFormat.h" #include "OneSixVersionFormat.h"
#include "MojangDownloadInfo.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")) if(in.contains("downloads"))
{ {
auto downloadsObj = requireObject(in, "downloads"); auto downloadsObj = requireObject(in, "downloads");

View File

@ -1,5 +1,6 @@
#include "OneSixVersionFormat.h" #include "OneSixVersionFormat.h"
#include <Json.h> #include <Json.h>
#include "minecraft/Agent.h"
#include "minecraft/ParseUtils.h" #include "minecraft/ParseUtils.h"
#include <minecraft/MojangVersionFormat.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")) if (root.contains("jarMods"))
{ {
@ -176,6 +185,21 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
readLibs("mavenFiles", out->mavenFiles); 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 we have mainJar, just use it
if(root.contains("mainJar")) if(root.contains("mainJar"))
{ {

View File

@ -272,18 +272,6 @@ void PackProfile::save_internal()
bool PackProfile::load() bool PackProfile::load()
{ {
auto filename = componentsFilePath(); auto filename = componentsFilePath();
QFile componentsFile(filename);
// migrate old config to new one, if needed
if(!componentsFile.exists())
{
if(!migratePreComponentConfig())
{
// FIXME: the user should be notified...
qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name();
return false;
}
}
// load the new component list and swap it with the current one... // load the new component list and swap it with the current one...
ComponentContainer newComponents; ComponentContainer newComponents;
@ -369,239 +357,6 @@ void PackProfile::updateFailed(const QString& error)
invalidateLaunchProfile(); invalidateLaunchProfile();
} }
// NOTE this is really old stuff, and only needs to be used when loading the old hardcoded component-unaware format (loadPreComponentConfig).
static void upgradeDeprecatedFiles(QString root, QString instanceName)
{
auto versionJsonPath = FS::PathCombine(root, "version.json");
auto customJsonPath = FS::PathCombine(root, "custom.json");
auto mcJson = FS::PathCombine(root, "patches" , "net.minecraft.json");
QString sourceFile;
QString renameFile;
// convert old crap.
if(QFile::exists(customJsonPath))
{
sourceFile = customJsonPath;
renameFile = versionJsonPath;
}
else if(QFile::exists(versionJsonPath))
{
sourceFile = versionJsonPath;
}
if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
{
if(!FS::ensureFilePathExists(mcJson))
{
qWarning() << "Couldn't create patches folder for" << instanceName;
return;
}
if(!renameFile.isEmpty() && QFile::exists(renameFile))
{
if(!QFile::rename(renameFile, renameFile + ".old"))
{
qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName;
return;
}
}
auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
ProfileUtils::removeLwjglFromPatch(file);
file->uid = "net.minecraft";
file->version = file->minecraftVersion;
file->name = "Minecraft";
Meta::Require needsLwjgl;
needsLwjgl.uid = "org.lwjgl";
file->requires.insert(needsLwjgl);
if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson))
{
return;
}
if(!QFile::rename(sourceFile, sourceFile + ".old"))
{
qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName;
return;
}
}
}
/*
* Migrate old layout to the component based one...
* - Part of the version information is taken from `instance.cfg` (fed to this class from outside).
* - Part is taken from the old order.json file.
* - Part is loaded from loose json files in the instance's `patches` directory.
*/
bool PackProfile::migratePreComponentConfig()
{
// upgrade the very old files from the beginnings of MultiMC 5
upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
QList<ComponentPtr> components;
QSet<QString> loaded;
auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
{
auto jsonFilePath = FS::PathCombine(d->m_instance->instanceRoot(), "patches" , uid + ".json");
auto intendedVersion = d->getOldConfigVersion(uid);
// load up the base minecraft patch
ComponentPtr component;
if(QFile::exists(jsonFilePath))
{
if(intendedVersion.isEmpty())
{
intendedVersion = emptyVersion;
}
auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
// fix uid
file->uid = uid;
// if version is missing, add it from the outside.
if(file->version.isEmpty())
{
file->version = intendedVersion;
}
// if this is a dependency (LWJGL), mark it also as volatile
if(asDependency)
{
file->m_volatile = true;
}
// insert requirements if needed
if(!req.uid.isEmpty())
{
file->requires.insert(req);
}
// insert conflicts if needed
if(!conflict.uid.isEmpty())
{
file->conflicts.insert(conflict);
}
// FIXME: @QUALITY do not ignore return value
ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), jsonFilePath);
component = new Component(this, uid, file);
component->m_version = intendedVersion;
}
else if(!intendedVersion.isEmpty())
{
auto metaVersion = APPLICATION->metadataIndex()->get(uid, intendedVersion);
component = new Component(this, metaVersion);
}
else
{
return;
}
component->m_dependencyOnly = asDependency;
component->m_important = !asDependency;
components.append(component);
};
// TODO: insert depends and conflicts here if these are customized files...
Meta::Require reqLwjgl;
reqLwjgl.uid = "org.lwjgl";
reqLwjgl.suggests = "2.9.1";
Meta::Require conflictLwjgl3;
conflictLwjgl3.uid = "org.lwjgl3";
Meta::Require nullReq;
addBuiltinPatch("org.lwjgl", true, "2.9.1", nullReq, conflictLwjgl3);
addBuiltinPatch("net.minecraft", false, QString(), reqLwjgl, nullReq);
// first, collect all other file-based patches and load them
QMap<QString, ComponentPtr> loadedComponents;
QDir patchesDir(FS::PathCombine(d->m_instance->instanceRoot(),"patches"));
for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
{
// parse the file
qDebug() << "Reading" << info.fileName();
auto file = ProfileUtils::parseJsonFile(info, true);
// correct missing or wrong uid based on the file name
QString uid = info.completeBaseName();
// ignore builtins, they've been handled already
if (uid == "net.minecraft")
continue;
if (uid == "org.lwjgl")
continue;
// handle horrible corner cases
if(uid.isEmpty())
{
// if you have a file named '.json', make it just go away.
// FIXME: @QUALITY do not ignore return value
QFile::remove(info.absoluteFilePath());
continue;
}
file->uid = uid;
// FIXME: @QUALITY do not ignore return value
ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), info.absoluteFilePath());
auto component = new Component(this, file->uid, file);
auto version = d->getOldConfigVersion(file->uid);
if(!version.isEmpty())
{
component->m_version = version;
}
loadedComponents[file->uid] = component;
}
// try to load the other 'hardcoded' patches (forge, liteloader), if they weren't loaded from files
auto loadSpecial = [&](const QString & uid, int order)
{
auto patchVersion = d->getOldConfigVersion(uid);
if(!patchVersion.isEmpty() && !loadedComponents.contains(uid))
{
auto patch = new Component(this, APPLICATION->metadataIndex()->get(uid, patchVersion));
patch->setOrder(order);
loadedComponents[uid] = patch;
}
};
loadSpecial("net.minecraftforge", 5);
loadSpecial("com.mumfrey.liteloader", 10);
// load the old order.json file, if present
ProfileUtils::PatchOrder userOrder;
ProfileUtils::readOverrideOrders(FS::PathCombine(d->m_instance->instanceRoot(), "order.json"), userOrder);
// now add all the patches by user sort order
for (auto uid : userOrder)
{
// ignore builtins
if (uid == "net.minecraft")
continue;
if (uid == "org.lwjgl")
continue;
// ordering has a patch that is gone?
if(!loadedComponents.contains(uid))
{
continue;
}
components.append(loadedComponents.take(uid));
}
// is there anything left to sort? - this is used when there are leftover components that aren't part of the order.json
if(!loadedComponents.isEmpty())
{
// inserting into multimap by order number as key sorts the patches and detects duplicates
QMultiMap<int, ComponentPtr> files;
auto iter = loadedComponents.begin();
while(iter != loadedComponents.end())
{
files.insert((*iter)->getOrder(), *iter);
iter++;
}
// then just extract the patches and put them in the list
for (auto order : files.keys())
{
const auto &values = files.values(order);
for(auto &value: values)
{
// TODO: put back the insertion of problem messages here, so the user knows about the id duplication
components.append(value);
}
}
}
// new we have a complete list of components...
return savePackProfile(componentsFilePath(), components);
}
// END: save/load // END: save/load
void PackProfile::appendComponent(ComponentPtr component) void PackProfile::appendComponent(ComponentPtr component)
@ -1169,15 +924,6 @@ std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
return d->m_profile; return d->m_profile;
} }
void PackProfile::setOldConfigVersion(const QString& uid, const QString& version)
{
if(version.isEmpty())
{
return;
}
d->m_oldConfigVersions[uid] = version;
}
bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important) bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important)
{ {
auto iter = d->componentIndex.find(uid); auto iter = d->componentIndex.find(uid);
@ -1224,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 "BaseVersion.h"
#include "MojangDownloadInfo.h" #include "MojangDownloadInfo.h"
#include "net/Mode.h" #include "net/Mode.h"
#include "modplatform/ModAPI.h"
class MinecraftInstance; class MinecraftInstance;
struct PackProfileData; struct PackProfileData;
@ -117,6 +118,8 @@ public:
// todo(merged): is this the best approach // todo(merged): is this the best approach
void appendComponent(ComponentPtr component); void appendComponent(ComponentPtr component);
ModAPI::ModLoaderType getModLoader();
private: private:
void scheduleSave(); void scheduleSave();
bool saveIsScheduled() const; bool saveIsScheduled() const;
@ -143,8 +146,6 @@ private:
bool installCustomJar_internal(QString filepath); bool installCustomJar_internal(QString filepath);
bool removeComponent_internal(ComponentPtr patch); bool removeComponent_internal(ComponentPtr patch);
bool migratePreComponentConfig();
private: /* data */ private: /* data */
std::unique_ptr<PackProfileData> d; std::unique_ptr<PackProfileData> d;

View File

@ -18,18 +18,6 @@ struct PackProfileData
// the launch profile (volatile, temporary thing created on demand) // the launch profile (volatile, temporary thing created on demand)
std::shared_ptr<LaunchProfile> m_profile; std::shared_ptr<LaunchProfile> m_profile;
// version information migrated from instance.cfg file. Single use on migration!
std::map<QString, QString> m_oldConfigVersions;
QString getOldConfigVersion(const QString& uid) const
{
const auto iter = m_oldConfigVersions.find(uid);
if(iter != m_oldConfigVersions.cend())
{
return (*iter).second;
}
return QString();
}
// persistent list of components and related machinery // persistent list of components and related machinery
ComponentContainer components; ComponentContainer components;
ComponentIndex componentIndex; ComponentIndex componentIndex;

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 <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
@ -32,10 +67,12 @@ void VersionFile::applyTo(LaunchProfile *profile)
profile->applyMainClass(mainClass); profile->applyMainClass(mainClass);
profile->applyAppletClass(appletClass); profile->applyAppletClass(appletClass);
profile->applyMinecraftArguments(minecraftArguments); profile->applyMinecraftArguments(minecraftArguments);
profile->applyAddnJvmArguments(addnJvmArguments);
profile->applyTweakers(addTweakers); profile->applyTweakers(addTweakers);
profile->applyJarMods(jarMods); profile->applyJarMods(jarMods);
profile->applyMods(mods); profile->applyMods(mods);
profile->applyTraits(traits); profile->applyTraits(traits);
profile->applyCompatibleJavaMajors(compatibleJavaMajors);
for (auto library : libraries) for (auto library : libraries)
{ {
@ -45,6 +82,10 @@ void VersionFile::applyTo(LaunchProfile *profile)
{ {
profile->applyMavenFile(mavenFile); profile->applyMavenFile(mavenFile);
} }
for (auto agent : agents)
{
profile->applyAgent(agent);
}
profile->applyProblemSeverity(getProblemSeverity()); 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 #pragma once
#include <QString> #include <QString>
@ -10,6 +45,7 @@
#include "minecraft/Rule.h" #include "minecraft/Rule.h"
#include "ProblemProvider.h" #include "ProblemProvider.h"
#include "Library.h" #include "Library.h"
#include "Agent.h"
#include <meta/JsonFormat.h> #include <meta/JsonFormat.h>
class PackProfile; class PackProfile;
@ -27,19 +63,19 @@ public: /* methods */
void applyTo(LaunchProfile* profile); void applyTo(LaunchProfile* profile);
public: /* data */ public: /* data */
/// MultiMC: order hint for this version file if no explicit order is set /// PolyMC: order hint for this version file if no explicit order is set
int order = 0; int order = 0;
/// MultiMC: human readable name of this package /// PolyMC: human readable name of this package
QString name; QString name;
/// MultiMC: package ID of this package /// PolyMC: package ID of this package
QString uid; QString uid;
/// MultiMC: version of this package /// PolyMC: version of this package
QString version; QString version;
/// MultiMC: DEPRECATED dependency on a Minecraft version /// PolyMC: DEPRECATED dependency on a Minecraft version
QString dependsOnMinecraftVersion; QString dependsOnMinecraftVersion;
/// Mojang: DEPRECATED used to version the Mojang version format /// Mojang: DEPRECATED used to version the Mojang version format
@ -51,12 +87,18 @@ public: /* data */
/// Mojang: class to launch Minecraft with /// Mojang: class to launch Minecraft with
QString mainClass; QString mainClass;
/// MultiMC: class to launch legacy Minecraft with (embed in a custom window) /// PolyMC: class to launch legacy Minecraft with (embed in a custom window)
QString appletClass; QString appletClass;
/// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution) /// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
QString minecraftArguments; QString minecraftArguments;
/// PolyMC: Additional JVM launch arguments
QStringList addnJvmArguments;
/// Mojang: list of compatible java majors
QList<int> compatibleJavaMajors;
/// Mojang: type of the Minecraft version /// Mojang: type of the Minecraft version
QString type; QString type;
@ -69,35 +111,38 @@ public: /* data */
/// Mojang: DEPRECATED asset group to be used with Minecraft /// Mojang: DEPRECATED asset group to be used with Minecraft
QString assets; QString assets;
/// MultiMC: list of tweaker mod arguments for launchwrapper /// PolyMC: list of tweaker mod arguments for launchwrapper
QStringList addTweakers; QStringList addTweakers;
/// Mojang: list of libraries to add to the version /// Mojang: list of libraries to add to the version
QList<LibraryPtr> libraries; QList<LibraryPtr> libraries;
/// MultiMC: list of maven files to put in the libraries folder, but not in classpath /// PolyMC: list of maven files to put in the libraries folder, but not in classpath
QList<LibraryPtr> mavenFiles; QList<LibraryPtr> mavenFiles;
/// PolyMC: list of agents to add to JVM arguments
QList<AgentPtr> agents;
/// The main jar (Minecraft version library, normally) /// The main jar (Minecraft version library, normally)
LibraryPtr mainJar; LibraryPtr mainJar;
/// MultiMC: list of attached traits of this version file - used to enable features /// PolyMC: list of attached traits of this version file - used to enable features
QSet<QString> traits; QSet<QString> traits;
/// MultiMC: list of jar mods added to this version /// PolyMC: list of jar mods added to this version
QList<LibraryPtr> jarMods; QList<LibraryPtr> jarMods;
/// MultiMC: list of mods added to this version /// PolyMC: list of mods added to this version
QList<LibraryPtr> mods; QList<LibraryPtr> mods;
/** /**
* MultiMC: set of packages this depends on * PolyMC: set of packages this depends on
* NOTE: this is shared with the meta format!!! * NOTE: this is shared with the meta format!!!
*/ */
Meta::RequireSet requires; Meta::RequireSet requires;
/** /**
* MultiMC: set of packages this conflicts with * PolyMC: set of packages this conflicts with
* NOTE: this is shared with the meta format!!! * NOTE: this is shared with the meta format!!!
*/ */
Meta::RequireSet conflicts; Meta::RequireSet conflicts;
@ -112,3 +157,4 @@ public:
// Mojang: extended asset index download information // Mojang: extended asset index download information
std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex; std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
}; };

View File

@ -17,6 +17,7 @@
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <QSaveFile> #include <QSaveFile>
#include <QDirIterator>
#include "World.h" #include "World.h"
#include "GZip.h" #include "GZip.h"
@ -26,9 +27,9 @@
#include <io/stream_reader.h> #include <io/stream_reader.h>
#include <tag_string.h> #include <tag_string.h>
#include <tag_primitive.h> #include <tag_primitive.h>
#include <quazip.h> #include <quazip/quazip.h>
#include <quazipfile.h> #include <quazip/quazipfile.h>
#include <quazipdir.h> #include <quazip/quazipdir.h>
#include <QCoreApplication> #include <QCoreApplication>
@ -187,6 +188,26 @@ bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data)
return f.commit(); 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) World::World(const QFileInfo &file)
{ {
repath(file); repath(file);
@ -196,6 +217,7 @@ void World::repath(const QFileInfo &file)
{ {
m_containerFile = file; m_containerFile = file;
m_folderName = file.fileName(); m_folderName = file.fileName();
m_size = calculateWorldSize(file);
if(file.isFile() && file.suffix() == "zip") if(file.isFile() && file.suffix() == "zip")
{ {
m_iconFile = QString(); m_iconFile = QString();
@ -482,6 +504,7 @@ void World::loadFromLevelDat(QByteArray data)
if(randomSeed) { if(randomSeed) {
qDebug() << "Seed:" << *randomSeed; qDebug() << "Seed:" << *randomSeed;
} }
qDebug() << "Size:" << m_size;
qDebug() << "GameType:" << m_gameType.toLogString(); qDebug() << "GameType:" << m_gameType.toLogString();
} }

View File

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

View File

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

View File

@ -32,7 +32,8 @@ public:
{ {
NameColumn, NameColumn,
GameModeColumn, GameModeColumn,
LastPlayedColumn LastPlayedColumn,
SizeColumn
}; };
enum Roles enum Roles
@ -43,6 +44,7 @@ public:
NameRole, NameRole,
GameModeRole, GameModeRole,
LastPlayedRole, LastPlayedRole,
SizeRole,
IconFileRole 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 "AccountData.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -314,6 +349,8 @@ bool AccountData::resumeStateFromV3(QJsonObject data) {
type = AccountType::MSA; type = AccountType::MSA;
} else if (typeS == "Mojang") { } else if (typeS == "Mojang") {
type = AccountType::Mojang; type = AccountType::Mojang;
} else if (typeS == "Offline") {
type = AccountType::Offline;
} else { } else {
qWarning() << "Failed to parse account data: type is not recognized."; qWarning() << "Failed to parse account data: type is not recognized.";
return false; return false;
@ -325,6 +362,10 @@ bool AccountData::resumeStateFromV3(QJsonObject data) {
} }
if(type == AccountType::MSA) { if(type == AccountType::MSA) {
auto clientIDV = data.value("msa-client-id");
if (clientIDV.isString()) {
msaClientID = clientIDV.toString();
} // leave msaClientID empty if it doesn't exist or isn't a string
msaToken = tokenFromJSONV3(data, "msa"); msaToken = tokenFromJSONV3(data, "msa");
userToken = tokenFromJSONV3(data, "utoken"); userToken = tokenFromJSONV3(data, "utoken");
xboxApiToken = tokenFromJSONV3(data, "xrp-main"); xboxApiToken = tokenFromJSONV3(data, "xrp-main");
@ -358,11 +399,15 @@ QJsonObject AccountData::saveState() const {
} }
else if (type == AccountType::MSA) { else if (type == AccountType::MSA) {
output["type"] = "MSA"; output["type"] = "MSA";
output["msa-client-id"] = msaClientID;
tokenToJSONV3(output, msaToken, "msa"); tokenToJSONV3(output, msaToken, "msa");
tokenToJSONV3(output, userToken, "utoken"); tokenToJSONV3(output, userToken, "utoken");
tokenToJSONV3(output, xboxApiToken, "xrp-main"); tokenToJSONV3(output, xboxApiToken, "xrp-main");
tokenToJSONV3(output, mojangservicesToken, "xrp-mc"); tokenToJSONV3(output, mojangservicesToken, "xrp-mc");
} }
else if (type == AccountType::Offline) {
output["type"] = "Offline";
}
tokenToJSONV3(output, yggdrasilToken, "ygg"); tokenToJSONV3(output, yggdrasilToken, "ygg");
profileToJSONV3(output, minecraftProfile, "profile"); profileToJSONV3(output, minecraftProfile, "profile");
@ -371,7 +416,7 @@ QJsonObject AccountData::saveState() const {
} }
QString AccountData::userName() const { QString AccountData::userName() const {
if(type != AccountType::Mojang) { if(type == AccountType::MSA) {
return QString(); return QString();
} }
return yggdrasilToken.extra["userName"].toString(); return yggdrasilToken.extra["userName"].toString();
@ -427,6 +472,9 @@ QString AccountData::accountDisplayString() const {
case AccountType::Mojang: { case AccountType::Mojang: {
return userName(); return userName();
} }
case AccountType::Offline: {
return userName();
}
case AccountType::MSA: { case AccountType::MSA: {
if(xboxApiToken.extra.contains("gtg")) { if(xboxApiToken.extra.contains("gtg")) {
return xboxApiToken.extra["gtg"].toString(); return xboxApiToken.extra["gtg"].toString();

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 #pragma once
#include <QString> #include <QString>
#include <QByteArray> #include <QByteArray>
@ -38,7 +73,8 @@ struct MinecraftProfile {
enum class AccountType { enum class AccountType {
MSA, MSA,
Mojang Mojang,
Offline
}; };
enum class AccountState { enum class AccountState {
@ -46,6 +82,7 @@ enum class AccountState {
Offline, Offline,
Working, Working,
Online, Online,
Disabled,
Errored, Errored,
Expired, Expired,
Gone Gone
@ -80,6 +117,7 @@ struct AccountData {
bool legacy = false; bool legacy = false;
bool canMigrateToMSA = false; bool canMigrateToMSA = false;
QString msaClientID;
Katabasis::Token msaToken; Katabasis::Token msaToken;
Katabasis::Token userToken; Katabasis::Token userToken;
Katabasis::Token xboxApiToken; Katabasis::Token xboxApiToken;

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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" #include "AccountList.h"
@ -291,6 +311,9 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
case AccountState::Expired: { case AccountState::Expired: {
return tr("Expired", "Account status"); return tr("Expired", "Account status");
} }
case AccountState::Disabled: {
return tr("Disabled", "Account status");
}
case AccountState::Gone: { case AccountState::Gone: {
return tr("Gone", "Account status"); return tr("Gone", "Account status");
} }
@ -302,7 +325,7 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
} }
case MigrationColumn: { case MigrationColumn: {
if(account->isMSA()) { if(account->isMSA() || account->isOffline()) {
return tr("N/A", "Can Migrate?"); return tr("N/A", "Can Migrate?");
} }
if (account->canMigrate()) { if (account->canMigrate()) {

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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 #pragma once
@ -24,7 +44,7 @@
/*! /*!
* List of available Mojang accounts. * List of available Mojang accounts.
* This should be loaded in the background by MultiMC on startup. * This should be loaded in the background by PolyMC on startup.
*/ */
class AccountList : public QAbstractListModel class AccountList : public QAbstractListModel
{ {
@ -158,3 +178,4 @@ protected:
*/ */
bool m_autosave = false; bool m_autosave = false;
}; };

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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" #include "AccountTask.h"
@ -43,6 +63,8 @@ QString AccountTask::getStateMessage() const
return tr("Authentication task succeeded."); return tr("Authentication task succeeded.");
case AccountTaskState::STATE_OFFLINE: case AccountTaskState::STATE_OFFLINE:
return tr("Failed to contact the authentication server."); return tr("Failed to contact the authentication server.");
case AccountTaskState::STATE_DISABLED:
return tr("Client ID has changed. New session needs to be created.");
case AccountTaskState::STATE_FAILED_SOFT: case AccountTaskState::STATE_FAILED_SOFT:
return tr("Encountered an error during authentication."); return tr("Encountered an error during authentication.");
case AccountTaskState::STATE_FAILED_HARD: case AccountTaskState::STATE_FAILED_HARD:
@ -78,6 +100,12 @@ bool AccountTask::changeState(AccountTaskState newState, QString reason)
emitFailed(reason); emitFailed(reason);
return false; return false;
} }
case AccountTaskState::STATE_DISABLED: {
m_data->errorString = reason;
m_data->accountState = AccountState::Disabled;
emitFailed(reason);
return false;
}
case AccountTaskState::STATE_FAILED_SOFT: { case AccountTaskState::STATE_FAILED_SOFT: {
m_data->errorString = reason; m_data->errorString = reason;
m_data->accountState = AccountState::Errored; m_data->accountState = AccountState::Errored;

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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 #pragma once
@ -35,6 +55,7 @@ enum class AccountTaskState
STATE_CREATED, STATE_CREATED,
STATE_WORKING, STATE_WORKING,
STATE_SUCCEEDED, STATE_SUCCEEDED,
STATE_DISABLED, //!< MSA Client ID has changed. Tell user to reloginn
STATE_FAILED_SOFT, //!< soft failure. authentication went through partially STATE_FAILED_SOFT, //!< soft failure. authentication went through partially
STATE_FAILED_HARD, //!< hard failure. main tokens are invalid STATE_FAILED_HARD, //!< hard failure. main tokens are invalid
STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists

View File

@ -44,7 +44,7 @@ void AuthRequest::onRequestFinished() {
if (reply_ != qobject_cast<QNetworkReply *>(sender())) { if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
return; return;
} }
httpStatus_ = 200; httpStatus_ = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
finish(); finish();
} }

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"); * This program is distributed in the hope that it will be useful,
* you may not use this file except in compliance with the License. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* You may obtain a copy of the License at * 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 * This file incorporates work covered by the following copyright and
* distributed under the License is distributed on an "AS IS" BASIS, * permission notice:
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * Copyright 2013-2021 MultiMC Contributors
* limitations under the License. *
* 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" #include "MinecraftAccount.h"
@ -30,6 +50,7 @@
#include "flows/MSA.h" #include "flows/MSA.h"
#include "flows/Mojang.h" #include "flows/Mojang.h"
#include "flows/Offline.h"
MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) { MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) {
data.internalId = QUuid::createUuid().toString().remove(QRegExp("[{}-]")); data.internalId = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
@ -68,6 +89,23 @@ MinecraftAccountPtr MinecraftAccount::createBlankMSA()
return account; return account;
} }
MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username)
{
MinecraftAccountPtr account = new MinecraftAccount();
account->data.type = AccountType::Offline;
account->data.yggdrasilToken.token = "offline";
account->data.yggdrasilToken.validity = Katabasis::Validity::Certain;
account->data.yggdrasilToken.issueInstant = QDateTime::currentDateTimeUtc();
account->data.yggdrasilToken.extra["userName"] = username;
account->data.yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
account->data.minecraftEntitlement.ownsMinecraft = true;
account->data.minecraftEntitlement.canPlayMinecraft = true;
account->data.minecraftProfile.id = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
account->data.minecraftProfile.name = username;
account->data.minecraftProfile.validity = Katabasis::Validity::Certain;
return account;
}
QJsonObject MinecraftAccount::saveToJson() const QJsonObject MinecraftAccount::saveToJson() const
{ {
@ -111,6 +149,16 @@ shared_qobject_ptr<AccountTask> MinecraftAccount::loginMSA() {
return m_currentTask; return m_currentTask;
} }
shared_qobject_ptr<AccountTask> MinecraftAccount::loginOffline() {
Q_ASSERT(m_currentTask.get() == nullptr);
m_currentTask.reset(new OfflineLogin(&data));
connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
emit activityChanged(true);
return m_currentTask;
}
shared_qobject_ptr<AccountTask> MinecraftAccount::refresh() { shared_qobject_ptr<AccountTask> MinecraftAccount::refresh() {
if(m_currentTask) { if(m_currentTask) {
return m_currentTask; return m_currentTask;
@ -119,6 +167,9 @@ shared_qobject_ptr<AccountTask> MinecraftAccount::refresh() {
if(data.type == AccountType::MSA) { if(data.type == AccountType::MSA) {
m_currentTask.reset(new MSASilent(&data)); m_currentTask.reset(new MSASilent(&data));
} }
else if(data.type == AccountType::Offline) {
m_currentTask.reset(new OfflineRefresh(&data));
}
else { else {
m_currentTask.reset(new MojangRefresh(&data)); m_currentTask.reset(new MojangRefresh(&data));
} }
@ -145,6 +196,9 @@ void MinecraftAccount::authFailed(QString reason)
{ {
switch (m_currentTask->taskState()) { switch (m_currentTask->taskState()) {
case AccountTaskState::STATE_OFFLINE: case AccountTaskState::STATE_OFFLINE:
case AccountTaskState::STATE_DISABLED: {
// NOTE: user will need to fix this themselves.
}
case AccountTaskState::STATE_FAILED_SOFT: { case AccountTaskState::STATE_FAILED_SOFT: {
// NOTE: this doesn't do much. There was an error of some sort. // NOTE: this doesn't do much. There was an error of some sort.
} }

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"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * 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 * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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 #pragma once
@ -41,7 +61,7 @@ Q_DECLARE_METATYPE(MinecraftAccountPtr)
* A profile within someone's Mojang account. * A profile within someone's Mojang account.
* *
* Currently, the profile system has not been implemented by Mojang yet, * Currently, the profile system has not been implemented by Mojang yet,
* but we might as well add some things for it in MultiMC right now so * but we might as well add some things for it in PolyMC right now so
* we don't have to rip the code to pieces to add it later. * we don't have to rip the code to pieces to add it later.
*/ */
struct AccountProfile struct AccountProfile
@ -73,6 +93,8 @@ public: /* construction */
static MinecraftAccountPtr createBlankMSA(); static MinecraftAccountPtr createBlankMSA();
static MinecraftAccountPtr createOffline(const QString &username);
static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json); static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json);
static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json); static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json);
@ -89,6 +111,8 @@ public: /* manipulation */
shared_qobject_ptr<AccountTask> loginMSA(); shared_qobject_ptr<AccountTask> loginMSA();
shared_qobject_ptr<AccountTask> loginOffline();
shared_qobject_ptr<AccountTask> refresh(); shared_qobject_ptr<AccountTask> refresh();
shared_qobject_ptr<AccountTask> currentTask(); shared_qobject_ptr<AccountTask> currentTask();
@ -128,6 +152,10 @@ public: /* queries */
return data.type == AccountType::MSA; return data.type == AccountType::MSA;
} }
bool isOffline() const {
return data.type == AccountType::Offline;
}
bool ownsMinecraft() const { bool ownsMinecraft() const {
return data.minecraftEntitlement.ownsMinecraft; return data.minecraftEntitlement.ownsMinecraft;
} }
@ -149,6 +177,10 @@ public: /* queries */
return "msa"; return "msa";
} }
break; break;
case AccountType::Offline: {
return "offline";
}
break;
default: { default: {
return "unknown"; return "unknown";
} }
@ -198,3 +230,4 @@ slots:
void authSucceeded(); void authSucceeded();
void authFailed(QString reason); void authFailed(QString reason);
}; };

View File

@ -94,7 +94,7 @@ bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString na
return false; return false;
} }
if(!getString(obj.value("Token"), output.token)) { if(!getString(obj.value("Token"), output.token)) {
qWarning() << "User Token is not a timestamp"; qWarning() << "User Token is not a string";
return false; return false;
} }
auto arrayVal = obj.value("DisplayClaims").toObject().value("xui"); auto arrayVal = obj.value("DisplayClaims").toObject().value("xui");

View File

@ -0,0 +1,17 @@
#include "Offline.h"
#include "minecraft/auth/steps/OfflineStep.h"
OfflineRefresh::OfflineRefresh(
AccountData *data,
QObject *parent
) : AuthFlow(data, parent) {
m_steps.append(new OfflineStep(m_data));
}
OfflineLogin::OfflineLogin(
AccountData *data,
QObject *parent
) : AuthFlow(data, parent) {
m_steps.append(new OfflineStep(m_data));
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "AuthFlow.h"
class OfflineRefresh : public AuthFlow
{
Q_OBJECT
public:
explicit OfflineRefresh(
AccountData *data,
QObject *parent = 0
);
};
class OfflineLogin : public AuthFlow
{
Q_OBJECT
public:
explicit OfflineLogin(
AccountData *data,
QObject *parent = 0
);
};

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 "MSAStep.h"
#include <QNetworkRequest> #include <QNetworkRequest>
@ -12,9 +47,10 @@ using OAuth2 = Katabasis::DeviceFlow;
using Activity = Katabasis::Activity; using Activity = Katabasis::Activity;
MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) { MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) {
m_clientId = APPLICATION->getMSAClientID();
OAuth2::Options opts; OAuth2::Options opts;
opts.scope = "XboxLive.signin offline_access"; opts.scope = "XboxLive.signin offline_access";
opts.clientIdentifier = BuildConfig.MSA_CLIENT_ID; opts.clientIdentifier = m_clientId;
opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"; opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode";
opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"; opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
@ -48,6 +84,10 @@ void MSAStep::rehydrate() {
void MSAStep::perform() { void MSAStep::perform() {
switch(m_action) { switch(m_action) {
case Refresh: { case Refresh: {
if (m_data->msaClientID != m_clientId) {
emit hideVerificationUriAndCode();
emit finished(AccountTaskState::STATE_DISABLED, tr("Microsoft user authentication failed - client identification has changed."));
}
m_oauth2->refresh(); m_oauth2->refresh();
return; return;
} }
@ -57,6 +97,7 @@ void MSAStep::perform() {
m_oauth2->setExtraRequestParams(extraOpts); m_oauth2->setExtraRequestParams(extraOpts);
*m_data = AccountData(); *m_data = AccountData();
m_data->msaClientID = m_clientId;
m_oauth2->login(); m_oauth2->login();
return; return;
} }

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 #pragma once
#include <QObject> #include <QObject>
@ -29,4 +63,5 @@ private slots:
private: private:
Katabasis::DeviceFlow *m_oauth2 = nullptr; Katabasis::DeviceFlow *m_oauth2 = nullptr;
Action m_action; Action m_action;
QString m_clientId;
}; };

View File

@ -56,6 +56,14 @@ void MinecraftProfileStep::onRequestDone(
return; return;
} }
if (error != QNetworkReply::NoError) { if (error != QNetworkReply::NoError) {
qWarning() << "Error getting profile:";
qWarning() << " HTTP Status: " << requestor->httpStatus_;
qWarning() << " Internal error no.: " << error;
qWarning() << " Error string: " << requestor->errorString_;
qWarning() << " Response:";
qWarning() << QString::fromUtf8(data);
emit finished( emit finished(
AccountTaskState::STATE_FAILED_SOFT, AccountTaskState::STATE_FAILED_SOFT,
tr("Minecraft Java profile acquisition failed.") tr("Minecraft Java profile acquisition failed.")

View File

@ -0,0 +1,18 @@
#include "OfflineStep.h"
#include "Application.h"
OfflineStep::OfflineStep(AccountData* data) : AuthStep(data) {}
OfflineStep::~OfflineStep() noexcept = default;
QString OfflineStep::describe() {
return tr("Creating offline account.");
}
void OfflineStep::rehydrate() {
// NOOP
}
void OfflineStep::perform() {
emit finished(AccountTaskState::STATE_WORKING, tr("Created offline account."));
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <QObject>
#include "QObjectPtr.h"
#include "minecraft/auth/AuthStep.h"
#include <katabasis/DeviceFlow.h>
class OfflineStep : public AuthStep {
Q_OBJECT
public:
explicit OfflineStep(AccountData *data);
virtual ~OfflineStep() noexcept;
void perform() override;
void rehydrate() override;
QString describe() override;
};

View File

@ -65,7 +65,7 @@ void XboxAuthorizationStep::onRequestDone(
if(!processSTSError(error, data, headers)) { if(!processSTSError(error, data, headers)) {
emit finished( emit finished(
AccountTaskState::STATE_FAILED_SOFT, 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; return;

View File

@ -88,7 +88,7 @@ void DirectJavaLaunch::on_state(LoggedProcess::State state)
case LoggedProcess::FailedToStart: case LoggedProcess::FailedToStart:
{ {
//: Error message displayed if instance can't start //: 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); emit logLine(reason, MessageLevel::Fatal);
emitFailed(tr(reason)); emitFailed(tr(reason));
return; return;

View File

@ -17,8 +17,8 @@
#include <minecraft/MinecraftInstance.h> #include <minecraft/MinecraftInstance.h>
#include <launch/LaunchTask.h> #include <launch/LaunchTask.h>
#include <quazip.h> #include <quazip/quazip.h>
#include <quazipdir.h> #include <quazip/quazipdir.h>
#include "MMCZip.h" #include "MMCZip.h"
#include "FileSystem.h" #include "FileSystem.h"
#include <QDir> #include <QDir>

View File

@ -25,6 +25,19 @@
LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent) LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent)
{ {
if (APPLICATION->settings()->get("CloseAfterLaunch").toBool())
{
std::shared_ptr<QMetaObject::Connection> connection{new QMetaObject::Connection};
*connection = connect(&m_process, &LoggedProcess::log, this, [=](QStringList lines, MessageLevel::Enum level) {
qDebug() << lines;
if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0)
{
APPLICATION->closeAllWindows();
disconnect(*connection);
}
});
}
connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines); connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines);
connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state); connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
} }
@ -141,7 +154,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
case LoggedProcess::FailedToStart: case LoggedProcess::FailedToStart:
{ {
//: Error message displayed if instace can't start //: 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); emit logLine(reason, MessageLevel::Fatal);
emitFailed(tr(reason)); emitFailed(tr(reason));
return; return;
@ -155,6 +168,9 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
} }
case LoggedProcess::Finished: case LoggedProcess::Finished:
{ {
if (APPLICATION->settings()->get("CloseAfterLaunch").toBool())
APPLICATION->showMainWindow();
m_parent->setPid(-1); m_parent->setPid(-1);
// if the exit code wasn't 0, report this as a crash // if the exit code wasn't 0, report this as a crash
auto exitCode = m_process.exitCode(); auto exitCode = m_process.exitCode();

View File

@ -23,7 +23,7 @@ MinecraftServerTarget MinecraftServerTarget::parse(const QString &fullAddress) {
// The logic below replicates the exact logic minecraft uses for parsing server addresses. // The logic below replicates the exact logic minecraft uses for parsing server addresses.
// While the conversion is not lossless and eats errors, it ensures the same behavior // While the conversion is not lossless and eats errors, it ensures the same behavior
// within Minecraft and MultiMC when entering server addresses. // within Minecraft and PolyMC when entering server addresses.
if (fullAddress.startsWith("[")) if (fullAddress.startsWith("["))
{ {
int bracket = fullAddress.indexOf("]"); int bracket = fullAddress.indexOf("]");

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 "VerifyJavaInstall.h"
#include <launch/LaunchTask.h> #include "java/JavaVersion.h"
#include <minecraft/MinecraftInstance.h> #include "minecraft/PackProfile.h"
#include <minecraft/PackProfile.h> #include "minecraft/MinecraftInstance.h"
#include <minecraft/VersionFilterData.h>
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif
void VerifyJavaInstall::executeTask() { 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 compatibleMajors = packProfile->getProfile()->getCompatibleJavaMajors();
auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft");
// Java 17 requirement JavaVersion javaVersion(storedVersion);
if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java17BeginsDate) {
if (javaVersion.major() < 17) { if (compatibleMajors.isEmpty() || compatibleMajors.contains(javaVersion.major()))
emit logLine("Minecraft 1.18 Pre Release 2 and above require the use of Java 17", {
MessageLevel::Fatal); emitSucceeded();
emitFailed(tr("Minecraft 1.18 Pre Release 2 and above require the use of Java 17")); return;
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;
}
} }
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 #pragma once
#include <launch/LaunchStep.h> #include <launch/LaunchStep.h>
#include <launch/LaunchTask.h>
class VerifyJavaInstall : public LaunchStep { class VerifyJavaInstall : public LaunchStep {
Q_OBJECT Q_OBJECT

View File

@ -1,256 +0,0 @@
/* 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 <QFileInfo>
#include <minecraft/launch/LauncherPartLaunch.h>
#include <QDir>
#include <settings/Setting.h>
#include "LegacyInstance.h"
#include "minecraft/legacy/LegacyModList.h"
#include "minecraft/WorldList.h"
#include <MMCZip.h>
#include <FileSystem.h>
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: BaseInstance(globalSettings, settings, rootDir)
{
settings->registerSetting("NeedsRebuild", true);
settings->registerSetting("ShouldUpdate", false);
settings->registerSetting("JarVersion", QString());
settings->registerSetting("IntendedJarVersion", QString());
/*
* custom base jar has no default. it is determined in code... see the accessor methods for
*it
*
* for instances that DO NOT have the CustomBaseJar setting (legacy instances),
* [.]minecraft/bin/mcbackup.jar is the default base jar
*/
settings->registerSetting("UseCustomBaseJar", true);
settings->registerSetting("CustomBaseJar", "");
}
QString LegacyInstance::mainJarToPreserve() const
{
bool customJar = m_settings->get("UseCustomBaseJar").toBool();
if(customJar)
{
auto base = baseJar();
if(QFile::exists(base))
{
return base;
}
}
auto runnable = runnableJar();
if(QFile::exists(runnable))
{
return runnable;
}
return QString();
}
QString LegacyInstance::baseJar() const
{
bool customJar = m_settings->get("UseCustomBaseJar").toBool();
if (customJar)
{
return customBaseJar();
}
else
return defaultBaseJar();
}
QString LegacyInstance::customBaseJar() const
{
QString value = m_settings->get("CustomBaseJar").toString();
if (value.isNull() || value.isEmpty())
{
return defaultCustomBaseJar();
}
return value;
}
bool LegacyInstance::shouldUseCustomBaseJar() const
{
return m_settings->get("UseCustomBaseJar").toBool();
}
Task::Ptr LegacyInstance::createUpdateTask(Net::Mode)
{
return nullptr;
}
std::shared_ptr<LegacyModList> LegacyInstance::jarModList() const
{
if (!jar_mod_list)
{
auto list = new LegacyModList(jarModsDir(), modListFile());
jar_mod_list.reset(list);
}
jar_mod_list->update();
return jar_mod_list;
}
QString LegacyInstance::gameRoot() const
{
QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
if (mcDir.exists() && !dotMCDir.exists())
return mcDir.filePath();
else
return dotMCDir.filePath();
}
QString LegacyInstance::binRoot() const
{
return FS::PathCombine(gameRoot(), "bin");
}
QString LegacyInstance::modsRoot() const {
return FS::PathCombine(gameRoot(), "mods");
}
QString LegacyInstance::jarModsDir() const
{
return FS::PathCombine(instanceRoot(), "instMods");
}
QString LegacyInstance::libDir() const
{
return FS::PathCombine(gameRoot(), "lib");
}
QString LegacyInstance::savesDir() const
{
return FS::PathCombine(gameRoot(), "saves");
}
QString LegacyInstance::coreModsDir() const
{
return FS::PathCombine(gameRoot(), "coremods");
}
QString LegacyInstance::resourceDir() const
{
return FS::PathCombine(gameRoot(), "resources");
}
QString LegacyInstance::texturePacksDir() const
{
return FS::PathCombine(gameRoot(), "texturepacks");
}
QString LegacyInstance::runnableJar() const
{
return FS::PathCombine(binRoot(), "minecraft.jar");
}
QString LegacyInstance::modListFile() const
{
return FS::PathCombine(instanceRoot(), "modlist");
}
QString LegacyInstance::instanceConfigFolder() const
{
return FS::PathCombine(gameRoot(), "config");
}
bool LegacyInstance::shouldRebuild() const
{
return m_settings->get("NeedsRebuild").toBool();
}
QString LegacyInstance::currentVersionId() const
{
return m_settings->get("JarVersion").toString();
}
QString LegacyInstance::intendedVersionId() const
{
return m_settings->get("IntendedJarVersion").toString();
}
bool LegacyInstance::shouldUpdate() const
{
QVariant var = settings()->get("ShouldUpdate");
if (!var.isValid() || var.toBool() == false)
{
return intendedVersionId() != currentVersionId();
}
return true;
}
QString LegacyInstance::defaultBaseJar() const
{
return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
}
QString LegacyInstance::defaultCustomBaseJar() const
{
return FS::PathCombine(binRoot(), "mcbackup.jar");
}
std::shared_ptr<WorldList> LegacyInstance::worldList() const
{
if (!m_world_list)
{
m_world_list.reset(new WorldList(savesDir()));
}
return m_world_list;
}
QString LegacyInstance::typeName() const
{
return tr("Legacy");
}
QString LegacyInstance::getStatusbarDescription()
{
return tr("Instance from previous versions.");
}
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
{
QStringList out;
auto alltraits = traits();
if(alltraits.size())
{
out << "Traits:";
for (auto trait : alltraits)
{
out << " " + trait;
}
out << "";
}
QString windowParams;
if (settings()->get("LaunchMaximized").toBool())
{
out << "Window size: max (if available)";
}
else
{
auto width = settings()->get("MinecraftWinWidth").toInt();
auto height = settings()->get("MinecraftWinHeight").toInt();
out << "Window size: " + QString::number(width) + " x " + QString::number(height);
}
out << "";
return out;
}

View File

@ -1,142 +0,0 @@
/* 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 "BaseInstance.h"
#include "launch/LaunchTask.h"
class ModFolderModel;
class LegacyModList;
class WorldList;
class Task;
/*
* WHY: Legacy instances - from MultiMC 3 and 4 - are here only to provide a way to upgrade them to the current format.
*/
class LegacyInstance : public BaseInstance
{
Q_OBJECT
public:
explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual void saveNow() override {}
/// Path to the instance's minecraft.jar
QString runnableJar() const;
//! Path to the instance's modlist file.
QString modListFile() const;
////// Directories //////
QString libDir() const;
QString savesDir() const;
QString texturePacksDir() const;
QString jarModsDir() const;
QString coreModsDir() const;
QString resourceDir() const;
QString instanceConfigFolder() const override;
QString gameRoot() const override; // Path to the instance's minecraft directory.
QString modsRoot() const override; // Path to the instance's minecraft directory.
QString binRoot() const; // Path to the instance's minecraft bin directory.
/// Get the curent base jar of this instance. By default, it's the
/// versions/$version/$version.jar
QString baseJar() const;
/// the default base jar of this instance
QString defaultBaseJar() const;
/// the default custom base jar of this instance
QString defaultCustomBaseJar() const;
// the main jar that we actually want to keep when migrating the instance
QString mainJarToPreserve() const;
/*!
* Whether or not custom base jar is used
*/
bool shouldUseCustomBaseJar() const;
/*!
* The value of the custom base jar
*/
QString customBaseJar() const;
std::shared_ptr<LegacyModList> jarModList() const;
std::shared_ptr<WorldList> worldList() const;
/*!
* Whether or not the instance's minecraft.jar needs to be rebuilt.
* If this is true, when the instance launches, its jar mods will be
* re-added to a fresh minecraft.jar file.
*/
bool shouldRebuild() const;
QString currentVersionId() const;
QString intendedVersionId() const;
QSet<QString> traits() const override
{
return {"legacy-instance", "texturepacks"};
};
virtual bool shouldUpdate() const;
virtual Task::Ptr createUpdateTask(Net::Mode mode) override;
virtual QString typeName() const override;
bool canLaunch() const override
{
return false;
}
bool canEdit() const override
{
return true;
}
bool canExport() const override
{
return false;
}
shared_qobject_ptr<LaunchTask> createLaunchTask(
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override
{
return nullptr;
}
IPathMatcher::Ptr getLogFileMatcher() override
{
return nullptr;
}
QString getLogFileRoot() override
{
return gameRoot();
}
QString getStatusbarDescription() override;
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
QProcessEnvironment createEnvironment() override
{
return QProcessEnvironment();
}
QMap<QString, QString> getVariables() const override
{
return {};
}
protected:
mutable std::shared_ptr<LegacyModList> jar_mod_list;
mutable std::shared_ptr<WorldList> m_world_list;
};

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