Compare commits

...

1026 Commits

Author SHA1 Message Date
TheKodeToad
baa988ec81
Merge pull request #1739 from Trial97/mod_icons
fixed squished mod icons
2023-11-06 20:49:05 +00:00
Alexandru Ionut Tripon
8eac0d34bd
Merge pull request #1796 from Trial97/dep_global_toggle
Added Global Dependenicies toggle
2023-11-06 20:48:51 +00:00
Alexandru Ionut Tripon
0b1dcb3ea7
Merge pull request #1760 from LocalSpook/sorting
Localize sorting options for resource and shader packs
2023-11-06 20:45:52 +00:00
Alexandru Ionut Tripon
3d529b0c3e
Merge pull request #1772 from Trial97/pixmap_crash
Fix crash with mod icon caching
2023-11-06 20:44:27 +00:00
seth
a2ab4804dd
Merge pull request #1788 from Trial97/readme
Updated the readme
2023-11-06 16:41:56 +00:00
Trial97
ca226d2ab5
Fixed comparation warning
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-06 11:24:19 +02:00
Trial97
670e91cb60
Increased the step to around 10MB
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-06 11:08:18 +02:00
Trial97
cc291219f9
apply suggested changes
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-06 10:51:34 +02:00
Sefa Eyeoglu
0eda2447dc
Merge pull request #1797 from Trial97/fix_mangohub
[Linux] Fix loading MangoHud
2023-11-06 08:14:55 +01:00
Trial97
867e6223ce
Fixed mangoHub loading
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-05 23:48:26 +02:00
Alexandru Ionut Tripon
3e7f9083ca
Update launcher/ui/pages/instance/ModFolderPage.cpp
Co-authored-by: seth <getchoo@tuta.io>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-11-05 23:41:54 +02:00
Alexandru Ionut Tripon
902e861fc6
Apply suggestions from code review
Co-authored-by: seth <getchoo@tuta.io>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-11-05 23:41:26 +02:00
seth
36d2109a15
Merge pull request #1792 from PrismLauncher/renovate/korthout-backport-action-2.x
chore(deps): update korthout/backport-action action to v2.1.0
2023-11-05 21:29:01 +00:00
TheKodeToad
bd9d5e0990
Reword
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-11-05 20:31:48 +00:00
Trial97
9a8667e99c
Added Global Dependenicies toggle
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-05 22:22:49 +02:00
Trial97
710a48fcaf
changed type form double long to long long
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-05 21:41:10 +02:00
TheKodeToad
52807ab279
Merge pull request #1793 from Edgars-Cirulis/develop
visual: Fix spacing.
2023-11-05 17:50:01 +00:00
Edgars Cīrulis
d2a85cb580 visual: Fix spacing.
Signed-off-by: Edgars Cīrulis <edgarsscirulis@gmail.com>
2023-11-05 17:43:12 +00:00
Alexandru Ionut Tripon
d13db1109f
Merge pull request #1789 from acdpsn/develop
Fixed link to Fulmine's website
2023-11-05 16:15:36 +00:00
renovate[bot]
64bbcb2834
chore(deps): update korthout/backport-action action to v2.1.0 2023-11-05 15:57:06 +00:00
Alexandru Ionut Tripon
070d83d887
Merge pull request #1791 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-11-05 07:03:37 +00:00
Alex
cf4144cb50 Fixed link to Fulmine's website
Signed-off-by: Alex <akim8@emich.edu>
2023-11-05 00:46:05 -04:00
github-actions[bot]
40ebae394a chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4' (2023-10-03)
  → 'github:hercules-ci/flake-parts/8c9fa2545007b49a5db5f650ae91f227672c3877' (2023-11-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:NixOS/nixpkgs/f5892ddac112a1e9b3612c39af1b72987ee5783a?dir=lib' (2023-09-29)
  → 'github:NixOS/nixpkgs/0cbe9f69c234a7700596e943bfae7ef27a31b735?dir=lib' (2023-10-29)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/808c0d8c53c7ae50f82aca8e7df263225cf235bf' (2023-10-26)
  → 'github:nixos/nixpkgs/9d5d25bbfe8c0297ebe85324addcb5020ed1a454' (2023-11-04)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/bd38df3d508dfcdff52cd243d297f218ed2257bf' (2023-10-25)
  → 'github:cachix/pre-commit-hooks.nix/dec10399e5b56aa95fcd530e0338be72ad6462a0' (2023-11-01)
2023-11-05 00:18:56 +00:00
Trial97
0f95bf1e42
Updated readme
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-04 12:08:49 +02:00
TheKodeToad
b446bdf4a9
Merge pull request #1783 from Trial97/visual_bug
Fixed visual bug with Modlist export
2023-11-03 15:20:57 +00:00
Sefa Eyeoglu
ef40ba8439
Merge pull request #1782 from Trial97/warn_remove_account 2023-11-03 12:56:13 +01:00
Alexandru Ionut Tripon
1bd69ecbb2
Update launcher/ui/pages/global/AccountListPage.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-11-03 11:42:40 +02:00
Trial97
b18082376d
Fixed visual bug with Modlist export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-03 11:04:13 +02:00
Trial97
127a31ba3a
Added warning for remove account
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-03 10:31:40 +02:00
Trial97
220a1de99a
made sure that we do not relay for undefined behavior
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-02 22:41:56 +02:00
Trial97
2349f29be0
jsut a overflow protection
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-11-02 01:26:04 +02:00
Alexandru Ionut Tripon
f8bb1a872a
Merge pull request #1766 from TheKodeToad/groups-fix
Fix group issues
2023-11-01 15:26:41 +00:00
Tayou
86e2f6c58c
Merge pull request #1685 from Trial97/java
Autodetect Java bundled with official launcher
2023-10-31 18:03:41 +01:00
TheKodeToad
2526275c5e
Better check
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-30 09:51:37 +00:00
TheKodeToad
5a54d80c6e
Fix group issues
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-30 09:26:38 +00:00
Sefa Eyeoglu
ea7dd9cfcc
Merge pull request #1761 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-10-29 09:31:28 +01:00
Alexandru Ionut Tripon
eb3f1ee27a
Merge pull request #1758 from IThundxr/patch-1
[Windows] Remove Windows 7/8 support from app manifest
2023-10-29 07:12:40 +00:00
github-actions[bot]
55ac17c45b chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/44881e03af1c730cbb1d72a4d41274a2c957813a' (2023-10-21)
  → 'github:nixos/nixpkgs/808c0d8c53c7ae50f82aca8e7df263225cf235bf' (2023-10-26)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/8cc349bfd082da8782b989cad2158c9ad5bd70fd' (2023-10-19)
  → 'github:cachix/pre-commit-hooks.nix/bd38df3d508dfcdff52cd243d297f218ed2257bf' (2023-10-25)
2023-10-29 00:18:11 +00:00
LocalSpook
54305397e4 Localize sorting options for resource and shader packs
Signed-off-by: LocalSpook <56512186+LocalSpook@users.noreply.github.com>
2023-10-28 12:50:40 -07:00
Sefa Eyeoglu
736246e6c8
Merge pull request #1759 from PrismLauncher/renovate/korthout-backport-action-2.x 2023-10-28 18:50:45 +02:00
renovate[bot]
9dcb7e9759
chore(deps): update korthout/backport-action action to v2 2023-10-28 16:03:11 +00:00
Tayou
69c2720872
Merge pull request #1691 from Trial97/no_color
Add no_color env variable
2023-10-28 18:02:53 +02:00
IThundxr
364cb4ff6a
chore: remove windows 7/8 support
With 8.0 windows legacy support was dropped, this just removes it from the manifest

Signed-off-by: IThundxr <contact@ithundxr.dev>
2023-10-28 07:39:32 -04:00
Tayou
df2a92d5f4
Merge pull request #1742 from TayouVR/fix-resourcepack-crash
fix switch/case fallthrough in resource parse tasks
2023-10-28 12:44:40 +02:00
Sefa Eyeoglu
3719ea21b0
Merge pull request #1355 from TheKodeToad/env-vars
Custom environment variables
2023-10-26 22:10:26 +02:00
TheKodeToad
bd11b93a0c
Use hidden tab bar like other pages
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-26 21:01:24 +01:00
Trial97
12d567a9b8
made env vars behave like the rest of the settings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-26 22:51:38 +03:00
txtsd
38d77b58cd
Merge pull request #1748 from LocalSpook/using 2023-10-25 16:08:42 +00:00
Tayou
a161f5cfe2
Merge pull request #1747 from Trial97/fix_initial_java
fix: java memory not set on initial setup
2023-10-24 19:04:56 +02:00
LocalSpook
5be80df1ee Replace typedef with using
Signed-off-by: LocalSpook <56512186+LocalSpook@users.noreply.github.com>
2023-10-24 01:36:27 -07:00
Trial97
87f2f88d4c
fix: java memory not set on initial setup
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-23 23:38:03 +03:00
Sefa Eyeoglu
b376888f43
Merge pull request #1515 from TheKodeToad/sysprops 2023-10-22 21:57:11 +02:00
Tayou
0fe3241df6
remove now unneeded Q_ASSERTs
Signed-off-by: Tayou <git@tayou.org>
2023-10-22 21:25:06 +02:00
Tayou
7d5206818b
fix switch/case fallthrough
Signed-off-by: Tayou <git@tayou.org>
2023-10-22 21:25:00 +02:00
Sefa Eyeoglu
db19362a97
feat: add launcher brand and version props
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-10-22 21:19:44 +02:00
Sefa Eyeoglu
cefb96e812
Merge pull request #1743 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-10-22 09:40:49 +02:00
github-actions[bot]
e7e80e704f chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/01441e14af5e29c9d27ace398e6dd0b293e25a54' (2023-10-11)
  → 'github:nixos/nixpkgs/44881e03af1c730cbb1d72a4d41274a2c957813a' (2023-10-21)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/42e1b6095ef80a51f79595d9951eb38e91c4e6ca' (2023-10-09)
  → 'github:cachix/pre-commit-hooks.nix/8cc349bfd082da8782b989cad2158c9ad5bd70fd' (2023-10-19)
2023-10-22 00:18:23 +00:00
Alexandru Ionut Tripon
2c4af7e793
Merge pull request #1290 from Trial97/refactor/NetActions
Refactor ImgurUpload
2023-10-21 12:32:16 +01:00
Alexandru Ionut Tripon
f0fd1bd5e5
Merge pull request #1737 from Trial97/fix_ftb_app_import_icon
Fixed FTBApp import icon
2023-10-21 07:48:21 +01:00
Trial97
5d926582c7
added Image column size hint
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-20 19:08:56 +03:00
Trial97
7b62d14683
fixed squished mod icons
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-20 17:15:12 +03:00
Trial97
80723eeca1
Fixed FTBApp import icon
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-20 16:41:32 +03:00
TheKodeToad
e9fd02baca
Fix code style
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-20 13:12:16 +01:00
Alexandru Ionut Tripon
7ad48d8677
Merge pull request #1692 from Trial97/msa_account
Fix wrong account selection
2023-10-19 20:09:28 +01:00
Tayou
9a0cfbc648
Merge pull request #1733 from Dnyanu76/patch-1
Remove typo
2023-10-19 21:07:51 +02:00
Indrale Dnyaneshwar
1f2483c39e
Remove typo
Signed-off-by: Indrale Dnyaneshwar <118615488+Dnyanu76@users.noreply.github.com>
2023-10-20 00:31:47 +05:30
Tayou
b9c1dc7325
Merge pull request #1374 from Trial97/welcome_background
Added welcome screen
2023-10-19 20:42:47 +02:00
TheKodeToad
cf33927f21
Merge remote-tracking branch 'upstream/develop' into sysprops
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-19 11:28:07 +01:00
TheKodeToad
c638a63a03
Merge pull request #1726 from Trial97/contrib
Added Trial97 as maintainer in about dialog
2023-10-18 09:34:12 +01:00
Sefa Eyeoglu
2081fcd3f5
Merge pull request #1722 from Scrumplex/fix/readonly-themes 2023-10-18 09:25:48 +02:00
Sefa Eyeoglu
90ebbd8e91
Merge pull request #1724 from getchoo/no-default-updater 2023-10-18 09:17:58 +02:00
Trial97
165d218300
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into contrib 2023-10-18 09:07:36 +03:00
seth
069bc887f1
fix: don't always build updater on platforms besides mac
Signed-off-by: seth <getchoo@tuta.io>
2023-10-17 19:12:00 -04:00
Alexandru Ionut Tripon
5aa2b88861
Merge pull request #1721 from Trial97/develop
fixed code signing for appImage
2023-10-17 10:20:44 +01:00
Sefa Eyeoglu
d348f20dd9
fix: allow loading themes with missing resources folder
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-10-17 10:00:17 +02:00
Trial97
b1bd0ceade
fixed code signing for appImage
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-17 09:29:47 +03:00
Alexandru Ionut Tripon
8f2f99801e
Merge pull request #1717 from DioEgizio/update-qt660
chore: bump Qt to Qt 6.6.0
2023-10-16 18:59:29 +01:00
Tayou
aae65e3e4e
Merge branch 'develop' into update-qt660
Signed-off-by: Tayou <git@tayou.org>
2023-10-16 19:57:05 +02:00
Tayou
436db23ffc
Merge pull request #1268 from Ryex/feat/launcher-updater
Feat: Windows (And portable linux / appimage) Auto Updater
2023-10-16 19:53:50 +02:00
DioEgizio
6c9856b9dc chore: bump Qt to Qt 6.6.0
Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
2023-10-16 15:42:16 +02:00
Alexandru Ionut Tripon
0927035a26
Merge pull request #1549 from Trial97/atlauncher_browser
added suport for atlauncher browser download
2023-10-16 06:39:12 +01:00
Tayou
5985d8b118
Merge pull request #1383 from TheKodeToad/rename-groups
Rename groups
2023-10-15 23:38:27 +02:00
TheKodeToad
cc990c4f94
Merge branch 'develop' into env-vars
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-15 21:57:20 +01:00
TheKodeToad
c4882e7162
Merge pull request #443 from TheKodeToad/skinfix
Add legacy skin fix
2023-10-15 21:46:29 +01:00
Trial97
9d15255e0a
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into atlauncher_browser 2023-10-15 20:52:38 +03:00
Trial97
ca9b593483
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions 2023-10-15 20:44:45 +03:00
Trial97
ef0813754b
added explicit qt version for linux portable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-15 20:23:46 +03:00
Trial97
6bbff310bc
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/launcher-updater 2023-10-15 17:42:39 +03:00
TheKodeToad
6fb7a98901
Fix small mistake 😭
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-15 14:45:05 +01:00
Tayou
9705e6325a
Merge pull request #1673 from Trial97/win_attr
fix folder attributes on windows copy
2023-10-15 15:15:36 +02:00
TheKodeToad
7112d04df5
Mark setting as optional
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-15 14:11:08 +01:00
Alexandru Ionut Tripon
2ab48a43dd
Merge pull request #1706 from Trial97/develop
removed the better release for modrinth modpacks
2023-10-15 12:24:20 +01:00
Alexandru Ionut Tripon
682134435d
Merge pull request #1684 from Trial97/remove_legacy
removed windows legacy builds
2023-10-15 12:22:35 +01:00
Alexandru Ionut Tripon
05d7cc31bf
Merge pull request #1709 from Trial97/arch_build
Fix compatibility with Qt 6.6
2023-10-15 12:19:47 +01:00
Sefa Eyeoglu
c498ad1787
Merge pull request #1711 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-10-15 08:55:36 +02:00
github-actions[bot]
4939a33456 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/2de1be5b51c3d6fa833f1c1f222dc867dd054b31' (2023-10-07)
  → 'github:nixos/nixpkgs/01441e14af5e29c9d27ace398e6dd0b293e25a54' (2023-10-11)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/66c352d33e0907239e4a69416334f64af2c685cc' (2023-10-05)
  → 'github:cachix/pre-commit-hooks.nix/42e1b6095ef80a51f79595d9951eb38e91c4e6ca' (2023-10-09)
2023-10-15 00:18:39 +00:00
Trial97
023b3e3c39
Fixed arch build
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-14 09:41:04 +03:00
Tayou
7015b8f7b2
Merge pull request #1563 from Trial97/modrinth_pack
Pack import fixes and improvements
2023-10-13 16:38:37 +02:00
Trial97
32eaaa25d9
removed the better release for modrinth modpacks
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-13 00:04:36 +03:00
Alexandru Ionut Tripon
ca4b58d5d7
Merge pull request #1405 from Trial97/update_file
Allow updating managed packs from local file
2023-10-10 16:17:08 +01:00
Alexandru Ionut Tripon
4eb8db16f1
Merge pull request #1543 from Trial97/packwiz
refactor packwiz file write
2023-10-10 16:16:57 +01:00
Alexandru Ionut Tripon
a7842ecc33
Merge pull request #1591 from Trial97/ftb_import_fix
fix: make cached instead of file for ftb pack import
2023-10-10 16:16:40 +01:00
Alexandru Ionut Tripon
6150908025
Merge pull request #1658 from Trial97/neoforge_version
Added version check for neoforge filter
2023-10-10 16:16:21 +01:00
Trial97
5cb6d93136
fixed updater build
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-09 22:25:45 +03:00
Trial97
7e6a08548d
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/launcher-updater 2023-10-09 19:58:43 +03:00
Sefa Eyeoglu
11a0241b5c
Merge pull request #1699 from GitMuslim/develop 2023-10-09 17:25:11 +02:00
Muslim
8eb8f167ab
oops
Signed-off-by: Muslim <42213155+GitMuslim@users.noreply.github.com>
2023-10-09 18:02:56 +03:00
Muslim
5f5214e5dd
add fullstop
Signed-off-by: Muslim <42213155+GitMuslim@users.noreply.github.com>
2023-10-09 17:00:57 +03:00
Sefa Eyeoglu
04a7275280
Merge pull request #1695 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-10-08 09:31:17 +02:00
github-actions[bot]
05caa874bc chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-compat':
    'github:edolstra/flake-compat/35bb57c0c8d8b62bbfd284272c928ceb64ddbde9' (2023-01-17)
  → 'github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33' (2023-10-04)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/7f53fdb7bdc5bb237da7fefef12d099e4fd611ca' (2023-09-01)
  → 'github:hercules-ci/flake-parts/c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4' (2023-10-03)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:NixOS/nixpkgs/3e52e76b70d5508f3cec70b882a29199f4d1ee85?dir=lib' (2023-08-31)
  → 'github:NixOS/nixpkgs/f5892ddac112a1e9b3612c39af1b72987ee5783a?dir=lib' (2023-09-29)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/bd9b686c0168041aea600222be0805a0de6e6ab8' (2023-09-29)
  → 'github:nixos/nixpkgs/2de1be5b51c3d6fa833f1c1f222dc867dd054b31' (2023-10-07)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/cb770e93516a1609652fa8e945a0f310e98f10c0' (2023-09-24)
  → 'github:cachix/pre-commit-hooks.nix/66c352d33e0907239e4a69416334f64af2c685cc' (2023-10-05)
2023-10-08 00:18:30 +00:00
Trial97
dc74ea7382
fixed wrong account selection
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-06 19:27:26 +03:00
Trial97
8d0a53273f
Add no_color env variable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-06 18:42:54 +03:00
Alexandru Ionut Tripon
bca5e8f395
Update launcher/minecraft/PackProfile.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-10-06 16:16:03 +03:00
TheKodeToad
d49f81d132
Drop leftover mod loader settings
I messed up the merge.

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-10-06 11:27:04 +01:00
Trial97
82461b1113
rename for windows
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-06 08:51:45 +03:00
Trial97
4f1ee85424
check for minecraft java runtime
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-06 00:21:37 +03:00
Trial97
b67c2c71d1
removed windows legacy builds
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-05 22:44:49 +03:00
Sefa Eyeoglu
a7bdfb5f6b
Merge pull request #1682 from romangraef/addmorejavas
Add more Java installation dirs
2023-10-05 00:44:16 +02:00
nea
c6c17036e3
Add more Java installation dirs
Signed-off-by: nea <nea@nea.moe>
2023-10-04 21:20:59 +02:00
Trial97
e913f61305
added a more strict condition for neoforge forge support
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-04 19:29:37 +03:00
Trial97
c78d4e7bb6
added version test for snapshot
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-04 19:16:21 +03:00
Tayou
024c474658
Merge pull request #1678 from Trial97/release_order
fixed quilt dependencies
2023-10-04 10:28:45 +02:00
Sefa Eyeoglu
03ad430699
Merge pull request #1537 from Trial97/warnings 2023-10-04 09:40:38 +02:00
Trial97
ac38585a2a
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into release_order 2023-10-04 09:41:49 +03:00
Trial97
3cba5adb5a
updated dependency cycle
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-04 09:41:40 +03:00
Sefa Eyeoglu
d186c34385
Merge pull request #1676 from Trial97/release_order
revert back the release order
2023-10-04 07:43:21 +02:00
Trial97
77979b4c95
revert back the release order
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-03 17:23:26 +03:00
Trial97
8069de29b2
fix folder attributes on windows copy
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-02 21:53:08 +03:00
Tayou
540fc7d2a8
Merge pull request #1670 from Trial97/seg_fault
Don't update mods if no mod loader is installed
2023-10-02 17:05:07 +02:00
Sefa Eyeoglu
d612ab94a7
Merge pull request #1672 from Trial97/skin_refresh
refresh default account when list changes
2023-10-02 16:06:12 +02:00
Sefa Eyeoglu
bfa9613373
Merge pull request #1657 from Trial97/shader_txt 2023-10-02 11:56:50 +02:00
Trial97
93be8b0735
refresh default account when list changes
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-02 09:13:02 +03:00
Trial97
2cea7454ef
fix: do not update mods if no mod loader is selected
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-10-01 23:04:19 +03:00
Sefa Eyeoglu
eab1180f68
Merge pull request #1090 from Ryex/feat/acknowledge_release_type 2023-10-01 14:32:58 +02:00
Sefa Eyeoglu
e3a147f56d
Merge pull request #1656 from Trial97/remove_mojang2 2023-10-01 14:32:42 +02:00
Sefa Eyeoglu
898a719d3e
Merge pull request #1668 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-10-01 09:28:57 +02:00
github-actions[bot]
be8a9f6541 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e12483116b3b51a185a33a272bf351e357ba9a99' (2023-09-21)
  → 'github:nixos/nixpkgs/bd9b686c0168041aea600222be0805a0de6e6ab8' (2023-09-29)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/4f883a76282bc28eb952570afc3d8a1bf6f481d7' (2023-09-10)
  → 'github:cachix/pre-commit-hooks.nix/cb770e93516a1609652fa8e945a0f310e98f10c0' (2023-09-24)
2023-10-01 00:19:50 +00:00
Sefa Eyeoglu
589ab24f7e
Merge pull request #1666 from getchoo/driverlink
[Linux] Use addOpenGLRunpath.driverLink in Nix wrapper
2023-09-30 23:50:36 +02:00
Alexandru Ionut Tripon
317c7b5544
Update launcher/minecraft/auth/AccountList.cpp
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-10-01 00:32:17 +03:00
Alexandru Ionut Tripon
00bbbdc6e9
Update launcher/LaunchController.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-10-01 00:31:51 +03:00
seth
84269f9596
refactor(nix): use addOpenGLRunpath.driverLink in wrapper
Signed-off-by: seth <getchoo@tuta.io>
2023-09-30 12:50:26 -04:00
Trial97
34294383eb
added version type to dep update
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 23:18:23 +03:00
Trial97
4802f6950e
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/acknowledge_release_type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 23:06:18 +03:00
Sefa Eyeoglu
531b58093e
Merge pull request #1263 from Trial97/develop 2023-09-28 22:03:14 +02:00
Sefa Eyeoglu
2ff9ef0620
Merge pull request #1363 from Trial97/download_threads 2023-09-28 22:02:57 +02:00
Trial97
5b7c5607a9
removed flame consturctor
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 22:53:40 +03:00
Trial97
9acbf98f94
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/acknowledge_release_type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 22:50:12 +03:00
Trial97
bef701eba8
chaged folder again
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 21:27:11 +03:00
Trial97
742384909f
updated portable update
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 21:24:31 +03:00
Trial97
606c12ffeb
more fixing
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 18:47:21 +03:00
Trial97
498c9db1ce
fixed appImageUpdate
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-28 15:14:59 +03:00
Sefa Eyeoglu
59e565ef96
Merge pull request #1643 from bolli24/develop 2023-09-27 17:34:32 +02:00
seth
f370f0d749
chore: cleanup a few more mentions of mojang accounts
Signed-off-by: seth <getchoo@tuta.io>
2023-09-27 05:34:48 -04:00
Trial97
b8d9c3d779
format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-26 20:19:35 +03:00
Trial97
ebde563648
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/launcher-updater 2023-09-26 20:16:46 +03:00
Trial97
4ee6a6711d
Added version check for neoforge filter
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-25 23:04:21 +03:00
Trial97
86b47b3421
Do not display invalid shaders
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-25 22:33:36 +03:00
Trial97
7c636d4608
Removed mojang
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-25 17:44:04 +03:00
TheKodeToad
0406e168e7
Merge pull request #1655 from 0xallie/minecraft-wiki-migration
Update links to Minecraft Wiki
2023-09-25 15:26:37 +01:00
alexia
1684cff7ac
Update links to Minecraft Wiki
Minecraft Wiki has officially moved from Fandom to their own wiki.
I updated some links I found in comments.

Signed-off-by: alexia <me@alexia.lol>
2023-09-25 15:49:12 +02:00
Sefa Eyeoglu
ad9fb7349f
Merge pull request #1647 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-09-24 09:02:43 +02:00
bolli24
14af7044be
Update launcher/ui/dialogs/ModUpdateDialog.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: bolli24 <9805065+bolli24@users.noreply.github.com>
2023-09-24 03:01:47 +02:00
github-actions[bot]
fa65ac3ff7 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nix-filter':
    'github:numtide/nix-filter/ac030bd9ba98e318e1f4c4328d60766ade8ebe8b' (2023-09-04)
  → 'github:numtide/nix-filter/41fd48e00c22b4ced525af521ead8792402de0ea' (2023-09-16)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/46688f8eb5cd6f1298d873d4d2b9cf245e09e88e' (2023-09-15)
  → 'github:nixos/nixpkgs/e12483116b3b51a185a33a272bf351e357ba9a99' (2023-09-21)
2023-09-24 00:18:03 +00:00
bolli24
f3c089792a Skip folders when updating mods.
Previously the mod updater would fail, reporting "The mod updater was aborted!", when trying to update a folder.

Signed-off-by: bolli24 <4827765-bolli24@users.noreply.gitlab.com>
2023-09-22 21:36:19 +02:00
Alexandru Ionut Tripon
81a3ba18bc
Update launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-09-20 18:45:23 +03:00
Sefa Eyeoglu
98bc102f5b
Merge pull request #1618 from getchoo/cool-nix-stuff
filter source in flake & add controller support
2023-09-20 07:47:22 +02:00
seth
97da8892b9
chore(nix): add meta.mainProgram attribute
Signed-off-by: seth <getchoo@tuta.io>
2023-09-19 16:41:40 -04:00
seth
97ced1f459
fix(nix): include libusb1 as a runtime dependency
Signed-off-by: seth <getchoo@tuta.io>
2023-09-19 16:41:37 -04:00
Trial97
a49851cb40
updated blocked mods with empty hash
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-19 15:48:12 +03:00
Sefa Eyeoglu
d72c3aba80
Merge pull request #1632 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-09-17 09:30:30 +02:00
github-actions[bot]
9afe80b0e0 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/b200e0df08f80c32974a6108ce431d8a8a5e6547' (2023-09-07)
  → 'github:nixos/nixpkgs/46688f8eb5cd6f1298d873d4d2b9cf245e09e88e' (2023-09-15)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa' (2023-08-17)
  → 'github:cachix/pre-commit-hooks.nix/4f883a76282bc28eb952570afc3d8a1bf6f481d7' (2023-09-10)
2023-09-17 00:18:04 +00:00
Sefa Eyeoglu
00af385619
Merge pull request #1572 from Trial97/catpacks2 2023-09-16 18:22:13 +02:00
Sefa Eyeoglu
bf6dc10f35
Merge pull request #1605 from TheKodeToad/flame-shaders 2023-09-16 18:20:45 +02:00
seth
4cb424470b
Merge pull request #1619 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-09-10 15:57:03 -04:00
Trial97
9445a555e4
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into packwiz
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-10 16:24:59 +03:00
Trial97
47d1f23568
added side for modrinth mods
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-10 16:22:57 +03:00
github-actions[bot]
82a0a5bca1 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/bfb7dfec93f3b5d7274db109f2990bc889861caf' (2023-09-02)
  → 'github:nixos/nixpkgs/b200e0df08f80c32974a6108ce431d8a8a5e6547' (2023-09-07)
2023-09-10 00:17:57 +00:00
seth
10192c540b
feat(nix): add source filtering
this - along with garnix - should mostly eliminate unneeded (re)builds

Signed-off-by: seth <getchoo@tuta.io>
2023-09-09 15:25:41 -04:00
seth
6aa821df9c
refactor(nix): match inputs value in flake
Signed-off-by: seth <getchoo@tuta.io>
2023-09-09 15:25:39 -04:00
seth
89e434bd5b
refactor(nix): don't concat final attr in fixed point
Signed-off-by: seth <getchoo@tuta.io>
2023-09-09 15:25:33 -04:00
Sefa Eyeoglu
78f8a31cd6
Merge pull request #1613 from PrismLauncher/renovate/actions-cache-3.x 2023-09-08 23:28:03 +02:00
renovate[bot]
e7d6be531f
chore(deps): update actions/cache action to v3.3.2 2023-09-08 17:22:12 +00:00
Sefa Eyeoglu
ba3a1b6280
Merge pull request #1606 from PrismLauncher/renovate/actions-checkout-4.x 2023-09-04 17:11:45 +02:00
Sefa Eyeoglu
d483b613b1
Merge pull request #1578 from TheKodeToad/antialiasing 2023-09-04 17:05:29 +02:00
Sefa Eyeoglu
cf599865f6
Merge pull request #1581 from getchoo/old-gcc 2023-09-04 17:04:10 +02:00
Sefa Eyeoglu
546d49e183
Merge pull request #1530 from Trial97/metadata_delete 2023-09-04 17:02:52 +02:00
renovate[bot]
7dd2530027
chore(deps): update actions/checkout action to v4 2023-09-04 15:02:01 +00:00
Sefa Eyeoglu
e9ecdd05b9
Merge pull request #1574 from Scrumplex/refactor-flake 2023-09-04 17:02:01 +02:00
Sefa Eyeoglu
ad6f15f293
Merge pull request #1604 from PrismLauncher/renovate/cachix-install-nix-action-23.x 2023-09-04 17:01:43 +02:00
TheKodeToad
94c1cd6bcf
CurseForge shader downloading
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-09-04 14:15:37 +01:00
renovate[bot]
e155844671
chore(deps): update cachix/install-nix-action action to v23 2023-09-04 10:22:11 +00:00
Sefa Eyeoglu
2918d61b16
refactor(nix): use pre-commit flake module
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-09-04 08:53:10 +02:00
seth
bbf4e3b04d
refactor(nix): use fixed points over rec
Signed-off-by: seth <getchoo@tuta.io>
2023-09-03 19:07:39 -04:00
Sefa Eyeoglu
caf925cbad
Merge pull request #1601 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-09-03 09:42:31 +02:00
github-actions[bot]
88f3e19f81 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/59cf3f1447cfc75087e7273b04b31e689a8599fb' (2023-08-01)
  → 'github:hercules-ci/flake-parts/7f53fdb7bdc5bb237da7fefef12d099e4fd611ca' (2023-09-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:NixOS/nixpkgs/9e1960bc196baf6881340d53dccb203a951745a2?dir=lib' (2023-08-01)
  → 'github:NixOS/nixpkgs/3e52e76b70d5508f3cec70b882a29199f4d1ee85?dir=lib' (2023-08-31)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/cddebdb60de376c1bdb7a4e6ee3d98355453fe56' (2023-08-27)
  → 'github:nixos/nixpkgs/bfb7dfec93f3b5d7274db109f2990bc889861caf' (2023-09-02)
2023-09-03 00:17:45 +00:00
TheKodeToad
19b5a5e00b
Remove final conflict - kept by mistake
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-09-02 22:38:14 +01:00
TheKodeToad
347228a246
Legacy settings override default -> false
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-09-02 22:29:26 +01:00
TheKodeToad
1213a5ab46
Merge remote-tracking branch 'upstream/develop' into skinfix
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-09-02 22:27:57 +01:00
Trial97
17f696bffc
small tweaks to atl icons
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-01 22:25:15 +03:00
Trial97
e095780cc3
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into modrinth_pack
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-01 21:36:28 +03:00
TheKodeToad
c01e95b79c
Merge pull request #1592 from kumquat-ir/desktop-open-fix
Fix opening files from curseforge:// and file:// links etc on linux
2023-09-01 16:13:48 +01:00
kumquat-ir
984e870bca actually it can handle multiple files just fine
Signed-off-by: kumquat-ir <66188216+kumquat-ir@users.noreply.github.com>
2023-09-01 10:32:35 -04:00
kumquat-ir
eb66e37b83 fix opening files from curseforge: links on linux
Signed-off-by: kumquat-ir <66188216+kumquat-ir@users.noreply.github.com>
2023-09-01 10:29:56 -04:00
Trial97
30ff417074
fix: make cached instead of file for ftb pack import
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-09-01 16:25:49 +03:00
Trial97
7e65aea2ef
format json
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-31 19:04:41 +03:00
Trial97
6cfe2dbc50
moved catpack data to testdata
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-31 17:34:05 +03:00
TheKodeToad
25ce11d85d
Merge pull request #1539 from Trial97/refactor_modpack_ux
Improvements to modpack UX
2023-08-31 14:58:54 +01:00
Sefa Eyeoglu
707da5a25a
fix(nix): include udev dependency
See https://github.com/NixOS/nixpkgs/pull/252425

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-30 21:59:42 +02:00
seth
584e800279
fix: remove -Wextra-semi
this flag is unavailable on gcc versions < 8. we could detect the
version of the compiler here, but i don't think we lose much in this
flags removal and this is a simpler option

Signed-off-by: seth <getchoo@tuta.io>
2023-08-30 11:14:49 -04:00
TheKodeToad
befa3baa6a
Merge branch 'develop' into feat/launcher-updater
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-30 11:47:33 +01:00
TheKodeToad
f23a8e4b4b
Enable antialiasing for mod and pack icons
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-29 23:34:19 +01:00
TheKodeToad
8c30cb3706
Fix CI
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-29 13:27:06 +01:00
TheKodeToad
c1855c6ce3
Merge branch 'develop' into rename-groups
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-29 12:41:40 +01:00
Sefa Eyeoglu
b83fdbd1b7
Merge pull request #1575 from TheKodeToad/more-pack-export-fixes 2023-08-28 22:18:58 +02:00
TheKodeToad
0e67686295
Hide index folder in pack export dialog
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-28 17:25:07 +01:00
TheKodeToad
e98bca4749
Fix cancelling pack save
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-28 17:09:40 +01:00
Sefa Eyeoglu
bdc2fca711
refactor(nix): don't instantiate nixpkgs
See https://zimbatm.com/notes/1000-instances-of-nixpkgs

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-28 15:18:10 +02:00
Trial97
211865a1e1
handle gracefully the upload abort
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-28 13:31:19 +03:00
Trial97
311e36b5d6
added new line
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-28 11:52:26 +03:00
Sefa Eyeoglu
fbf6833124
Merge pull request #1519 from TheKodeToad/better-export-pack 2023-08-28 10:29:32 +02:00
Sefa Eyeoglu
e4e4c4a430
Merge pull request #1573 from PrismLauncher/renovate/lock-file-maintenance 2023-08-28 10:14:45 +02:00
Sefa Eyeoglu
97d932db62
Revert "chore(deps): enable nix lockfile maintenance for renovate"
This reverts commit 5d14724e66.

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-28 10:14:21 +02:00
Trial97
5d70f4dbca
removed if
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-28 08:50:10 +03:00
renovate[bot]
66cbbfec0c
chore(deps): lock file maintenance 2023-08-28 00:23:14 +00:00
Trial97
07d8598638
added catpacks tests
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 23:40:32 +03:00
Trial97
79652799bd
Made text smaller
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 21:30:46 +03:00
Trial97
630145a1d0
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into welcome_background 2023-08-27 21:03:21 +03:00
Trial97
0680d2dceb
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 20:41:56 +03:00
TheKodeToad
9110fbf282
Merge pull request #1560 from Trial97/curse_multiple_loaders2
Add suport for flame multiple loaders
2023-08-27 18:21:14 +01:00
TheKodeToad
e3b04d10cf
Merge pull request #1536 from Trial97/time3
Allow showing playtime in hours
2023-08-27 18:14:04 +01:00
Trial97
8c607ae734
removed extra if
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 20:02:12 +03:00
Trial97
c5aac24a93
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse_multiple_loaders2
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 15:53:35 +03:00
Trial97
4036cecfc0
Added progress widget to some modpack providers
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-27 15:04:42 +03:00
Sefa Eyeoglu
df14f88307
Merge pull request #1532 from Trial97/curseforge-url-handle 2023-08-27 12:26:57 +02:00
seth
29736b3b1f
Merge pull request #1570 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-08-27 01:47:58 -04:00
github-actions[bot]
9735e46a7e chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/ca3c9ac9f4cdd4bea19f592b32bb59b74ab7d783' (2023-08-19)
  → 'github:nixos/nixpkgs/c66ccfa00c643751da2fd9290e096ceaa30493fc' (2023-08-26)
2023-08-27 00:17:22 +00:00
TheKodeToad
479335dfe0
Rewrite optional mod dialog
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-27 00:50:33 +01:00
TheKodeToad
d1566f2610
Merge branch 'develop' into env-vars
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-26 23:12:02 +01:00
Trial97
a2d44744fe
do not update the metadata if mod is invalid
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-26 23:36:46 +03:00
Trial97
288d0d1fd4
Added back api loader filtering if just one is selected
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-26 22:26:01 +03:00
Trial97
abfd1a4205
minor dependency crash fix
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-25 18:35:25 +03:00
Sefa Eyeoglu
094cee8ec6
Merge pull request #1561 from Scrumplex/nix-miscs 2023-08-25 10:08:53 +02:00
Trial97
c54fecf5d9
added condition for empty loader type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-25 09:05:04 +03:00
Trial97
172680abf8
removed aditional header
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 13:42:36 +03:00
Trial97
5f3e9672cd
made the loaders check more generic
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 13:31:57 +03:00
Trial97
f897b14e3e
changed technic icon name retrival
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 13:05:27 +03:00
Trial97
bb4b89470d
fixed icon importing
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 12:46:23 +03:00
Trial97
2990c5d0c9
Added optional mods dialog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 12:44:11 +03:00
Trial97
ea384d59fb
use qt separtor for file path
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-24 12:41:37 +03:00
Sefa Eyeoglu
3e448904a3
Merge pull request #1562 from PrismLauncher/renovate/determinatesystems-update-flake-lock-20.x
chore(deps): update determinatesystems/update-flake-lock action to v20
2023-08-24 08:11:30 +02:00
renovate[bot]
783af2c06a
chore(deps): update determinatesystems/update-flake-lock action to v20 2023-08-24 04:32:25 +00:00
Trial97
6c0492c0d1
return 0 for any
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 21:09:32 +03:00
Trial97
1515607060
updated getMappedModLoader
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 20:16:51 +03:00
Sefa Eyeoglu
41bd008f5d
chore(nix): remove pre-commit tools from shell
use `pre-commit` CLI instead!

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-23 13:49:10 +02:00
Sefa Eyeoglu
d7b6450613
fix(nix): reload direnv if parts change
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-23 13:47:04 +02:00
Sefa Eyeoglu
85c23b26de
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-23 13:46:23 +02:00
Sefa Eyeoglu
095de5ed4b
chore(nix): update clang-format to clang-tools 16
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-23 13:46:04 +02:00
Trial97
6178e5a975
reverted change for optional
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 13:55:38 +03:00
Trial97
aa065f2b51
Updated dependency resolution
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 13:28:23 +03:00
Sefa Eyeoglu
59ec0135d7
Merge pull request #1559 from Scrumplex/nix-canonicalize-jars 2023-08-23 12:23:26 +02:00
Sefa Eyeoglu
2283498ccb
Merge pull request #1552 from Trial97/memory_quick_setup 2023-08-23 11:56:53 +02:00
Trial97
e6ba2f4970
Added loaders check on versions load
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 12:52:51 +03:00
Sefa Eyeoglu
b93cd88292
fix(nix): add canonicalize-jars-hook
See https://github.com/NixOS/nixpkgs/pull/250757

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-23 11:52:32 +02:00
Trial97
f8f9ffa118
added loaders for flame version
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 11:33:45 +03:00
Trial97
4704c522e0
moved modloaderTypes to ModPlatform
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-23 10:26:57 +03:00
TheKodeToad
f7951f6082
Merge pull request #1548 from Trial97/version_label
Reset status label when deleting instance
2023-08-22 15:14:02 +01:00
Alexandru Ionut Tripon
eed7e996da
Update launcher/ui/widgets/JavaSettingsWidget.cpp
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-22 16:17:05 +03:00
Alexandru Ionut Tripon
06dbd381f8
Update launcher/ui/pages/instance/InstanceSettingsPage.cpp
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-22 16:16:57 +03:00
Alexandru Ionut Tripon
3574d89e0f
Update launcher/ui/pages/global/JavaPage.cpp
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-22 16:16:50 +03:00
TheKodeToad
0e96111116
Merge pull request #1556 from Trial97/metacache
Gracefully handle invalid cache metadata
2023-08-22 14:09:44 +01:00
Trial97
09aca7a0b5
Added warning to settings page
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-22 10:52:35 +03:00
Sefa Eyeoglu
b1783d8fb1
Merge pull request #1557 from Trial97/curse_crash 2023-08-21 23:04:45 +02:00
Trial97
c3d03f0c33
added check for valid query items in curse url install
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 22:20:33 +03:00
Trial97
7acfe36a62
fixed httpmetacache load
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 21:30:44 +03:00
Trial97
45dad27a6d
fixed check
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 17:46:50 +03:00
TheKodeToad
fff378b643
Merge pull request #1553 from TheKodeToad/list-fixes
A few boring list-related fixes
2023-08-21 15:33:16 +01:00
TheKodeToad
d7dadabfbf
List fixes
Double-click to toggle profile components.
Restore double-click to toggle resources.
Fix clicking on checkbox to select account.
Double-click to select account.

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-21 14:44:46 +01:00
Trial97
1eb75b6852
fixed build
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 15:34:45 +03:00
Trial97
492bf373c6
updated memory allocation on quick setup
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 15:00:11 +03:00
Trial97
02264f67f3
Fixed codeql
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 14:15:51 +03:00
Sefa Eyeoglu
fcb436f1f4
Merge pull request #1551 from dannydorazio/develop 2023-08-21 08:29:25 +02:00
Danny Dorazio
e2e0a7af45 DCO Remediation Commit for Danny Dorazio <danny@dorazio.me>
I, Danny Dorazio <danny@dorazio.me>, hereby add my Signed-off-by to this commit: 8092c321a9
I, Danny Dorazio <danny@dorazio.me>, hereby add my Signed-off-by to this commit: 3638fc0a7d
I, Danny Dorazio <danny@dorazio.me>, hereby add my Signed-off-by to this commit: c50c3eaa94

Signed-off-by: Danny Dorazio <danny@dorazio.me>
2023-08-21 01:24:23 -04:00
Danny Dorazio
c50c3eaa94 DCO Remediation Commit for Danny Dorazio <hello@dorazio.me>
I, Danny Dorazio <hello@dorazio.me>, hereby add my Signed-off-by to this commit: 8092c321a9
I, Danny Dorazio <hello@dorazio.me>, hereby add my Signed-off-by to this commit: 3638fc0a7d

Signed-off-by: Danny Dorazio <hello@dorazio.me>
2023-08-21 01:21:48 -04:00
Danny Dorazio
3638fc0a7d Update “Welcome” message on account list page 2023-08-20 23:00:50 -04:00
Danny Dorazio
8092c321a9 Replace instances of “Minecraft account” 2023-08-20 23:00:25 -04:00
Trial97
8e5be6f420
added suport for atlauncher browser download
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-21 00:09:46 +03:00
Trial97
19316e22b4
fixed status label after instance remove
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-20 22:46:44 +03:00
Sefa Eyeoglu
5c95448f1f
Merge pull request #1485 from getchoo/nix-darwin 2023-08-20 21:20:09 +02:00
Trial97
254444470f
renamed enum type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-20 16:40:58 +03:00
TheKodeToad
0aaea9bf5d
Merge pull request #1547 from Scrumplex/revert-quilt-beacon
Remove Quilt Beacon toggle
2023-08-20 12:43:49 +01:00
Sefa Eyeoglu
5b4dcae7d9
Revert "feat: add toggle for quilt beacon"
This reverts commit 89aaedc06c.

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-20 13:23:11 +02:00
Sefa Eyeoglu
963627fe98
Revert "chore: better explain quilt loader beacon"
This reverts commit a2a09ffe01.

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-20 13:23:08 +02:00
Sefa Eyeoglu
232bb568da
Merge pull request #1544 from PrismLauncher/update_flake_lock_action 2023-08-20 12:01:37 +02:00
github-actions[bot]
d3c7850f53 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/f0451844bbdf545f696f029d1448de4906c7f753' (2023-08-12)
  → 'github:nixos/nixpkgs/ca3c9ac9f4cdd4bea19f592b32bb59b74ab7d783' (2023-08-19)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/c5ac3aa3324bd8aebe8622a3fc92eeb3975d317a' (2023-08-11)
  → 'github:cachix/pre-commit-hooks.nix/7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa' (2023-08-17)
2023-08-20 00:16:56 +00:00
TheKodeToad
ebbc8838a8
Merge pull request #1541 from Trial97/neoforge_search
feat:neoforge can download forge mods
2023-08-19 23:10:56 +01:00
Trial97
d25e89a4c1
refactor packwiz file write
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-20 00:48:46 +03:00
TheKodeToad
f99b04bd16
Merge pull request #1320 from TheKodeToad/better-launch
Combine launch buttons in instance window, persist profiler
2023-08-19 11:08:02 +01:00
Sefa Eyeoglu
acf586ef82
chore: add fixme about UI code in Minecraftinstance
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-19 10:21:46 +02:00
Trial97
0138cd65cb
feat:neoforge can download forge mods
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-19 09:00:59 +03:00
Trial97
ab6301d5a1
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop 2023-08-19 00:38:40 +03:00
Sefa Eyeoglu
3098aecf97
Merge pull request #1498 from Scrumplex/neoforge 2023-08-18 22:56:55 +02:00
Trial97
05094b7382
more fixes
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 22:24:30 +03:00
Trial97
58efd3e9e2
fixed code scaning
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 21:43:57 +03:00
Trial97
4c52b18bdd
replaced removeFirst with mid
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 20:19:51 +03:00
Trial97
44ff247f5f
feat:refactored modpack ux
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 20:03:02 +03:00
Trial97
fecc1e087a
Add Trial97 to contribuitors list
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 13:35:50 +03:00
Trial97
d3acac16e6
added -Wno-gnu-zero-variadic-macro-arguments and fixed more warnings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 13:10:13 +03:00
Alexandru Ionut Tripon
28ffa8bf44
Update launcher/ui/pages/global/MinecraftPage.ui
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-18 12:57:08 +03:00
TheKodeToad
eb4efa5a9c
Merge pull request #1535 from Scrumplex/fix-skin-browse-btn
Fix browse button size in Skin Upload dialog
2023-08-18 10:47:42 +01:00
Trial97
6d1c67663d
feat:added option to show playtime in hours
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-18 12:24:28 +03:00
Sefa Eyeoglu
f4ebeedc21
fix: fix browse button size in skin upload dialog
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-18 09:01:57 +02:00
Sefa Eyeoglu
be2888d6fb
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-17 22:23:50 +02:00
Trial97
7ab391904a
Flame support for neoforge
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-17 22:23:34 +02:00
Sefa Eyeoglu
aac734d174
fix: add theoretical support for NeoForge in FTB modpacks
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-17 22:21:12 +02:00
TheKodeToad
ffd8ed550f
Reformat
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-17 18:53:32 +01:00
Trial97
c5bac475e8
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop 2023-08-17 17:29:57 +03:00
Sefa Eyeoglu
e88418ab7f
Merge pull request #1392 from Scrumplex/feat-native-override 2023-08-17 16:09:16 +02:00
Trial97
bc0934a19c
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curseforge-url-handle 2023-08-17 15:25:32 +03:00
Trial97
044ce4df32
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into update_file 2023-08-17 15:24:14 +03:00
Trial97
758999fa64
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into welcome_background 2023-08-17 15:23:22 +03:00
Trial97
4a1d85f999
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop 2023-08-17 14:23:37 +03:00
TheKodeToad
6da2e7d3f6
I was forced
/j

Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-17 10:12:38 +01:00
Sefa Eyeoglu
85f36ebed7
Merge pull request #981 from Ryex/curseforge-url-handle 2023-08-17 09:24:35 +02:00
Trial97
f8ffb14619
Merge branch 'curseforge-url-handle' of github.com:Trial97/PrismLauncher into curseforge-url-handle 2023-08-17 00:25:38 +03:00
Trial97
5e2d1ffdfb
removed line
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-17 00:23:53 +03:00
TheKodeToad
3e2733d840
Merge branch 'develop' into better-launch
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-16 22:23:38 +01:00
Trial97
bad44ea264
feat:added flame install mod metadata
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-17 00:14:49 +03:00
Trial97
f0da16a758
removed line
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-17 00:13:12 +03:00
Trial97
b0e197de38
removed warning for one mod selected
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-16 21:26:43 +03:00
Alexandru Ionut Tripon
6c2c724bd9
Update launcher/ui/pages/instance/ExternalResourcesPage.ui
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-16 21:03:09 +03:00
Sefa Eyeoglu
c88088c91a
Merge pull request #1524 from PrismLauncher/renovate/korthout-backport-action-1.x 2023-08-16 19:28:41 +02:00
Trial97
f919d363b7
made safe for vegetarians
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-16 20:02:32 +03:00
Trial97
589d8b6923
feat:Added remove metadata button
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-16 19:53:39 +03:00
Sefa Eyeoglu
a5e7aedb4f
Merge pull request #1523 from Trial97/atlauncher
Fix crash when installing some ATLauncher packs
2023-08-16 07:18:34 +02:00
renovate[bot]
07f25d6cca
chore(deps): update korthout/backport-action action to v1.4.0 2023-08-15 14:19:42 +00:00
Trial97
c22eec8f27
fixed crash on atlauncher pack install
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 17:03:51 +03:00
Trial97
1faf741004
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/launcher-updater
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 13:29:42 +03:00
TheKodeToad
8cff7c4de6
Merge branch 'develop' into rename-groups
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-15 11:03:19 +01:00
Trial97
cf27d2f9ab
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into download_threads
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 12:49:21 +03:00
Trial97
6c362afc21
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 12:41:46 +03:00
Trial97
c94ee67077
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curseforge-url-handle3
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 12:16:00 +03:00
Sefa Eyeoglu
62c14cea2a
fix: allow NeoForge in resource APIs
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 11:06:14 +02:00
Sefa Eyeoglu
01c3750835
feat: support NeoForge mrpack modpacks
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 11:06:14 +02:00
Sefa Eyeoglu
52e5ee7111
feat: add NeoForge to UIs
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 11:06:14 +02:00
Sefa Eyeoglu
3a0aa353cc
feat: add NeoForge to ModLoaderType
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 11:06:13 +02:00
Sefa Eyeoglu
8f5bb982cd
Merge pull request #1513 from lumiscosity/fix/skin_transparency_bug 2023-08-15 10:54:07 +02:00
Sefa Eyeoglu
a360ddbe0b
Merge pull request #1508 from comp500/fix/allow-empty-lines 2023-08-15 10:53:43 +02:00
Sefa Eyeoglu
06aba530d7
fix: add missing header
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:52:40 +02:00
Sefa Eyeoglu
c2d6a137ab
fix: only add native library overrides if files exist
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:52:08 +02:00
Sefa Eyeoglu
b927e58126
fix: improve debug message
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:52:08 +02:00
Sefa Eyeoglu
f1c3da6583
fix: fix typo
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:52:08 +02:00
Sefa Eyeoglu
4c446ccd50
fix: remove meta OpenAL workaround
LWJGL 2 doesn't have a separate zip for OpenAL. So there is no reason
for this code.

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:51:48 +02:00
Sefa Eyeoglu
83aa0062c7
feat: add custom native library path settings
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:51:21 +02:00
Sefa Eyeoglu
ff67fd10c3
feat: implement override for GLFW/OpenAL with split natives
Fixes PrismLauncher/PrismLauncher#513

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:50:38 +02:00
Sefa Eyeoglu
7ba1e7d356
Merge pull request #1407 from TheKodeToad/icon-indexing 2023-08-15 10:43:29 +02:00
Sefa Eyeoglu
f533173b95
Merge pull request #1516 from Trial97/abort_connect 2023-08-15 10:40:12 +02:00
Sefa Eyeoglu
14d5fd7edb
Merge pull request #1520 from PrismLauncher/update_flake_lock_action 2023-08-15 10:39:08 +02:00
Sefa Eyeoglu
740ca54c87
Merge pull request #1462 from getchoo/labels 2023-08-15 10:38:28 +02:00
Sefa Eyeoglu
6ce7e426d2
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 10:38:04 +02:00
Sefa Eyeoglu
0c753619a4
Merge pull request #1467 from Scrumplex/update-nix-docs 2023-08-15 10:36:38 +02:00
Sefa Eyeoglu
4b06255cc2
Merge pull request #1486 from PrismLauncher/staging 2023-08-15 10:36:09 +02:00
Sefa Eyeoglu
1939e3e6ed
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-15 09:02:15 +02:00
Trial97
9546c77113
Some warnings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 00:52:34 +03:00
Trial97
0ba88ff138
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into staging
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-15 00:33:24 +03:00
Sefa Eyeoglu
215d7dbb74
chore: update license headers
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-14 18:17:05 +02:00
Sefa Eyeoglu
91ba4cf75e
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-14 18:16:53 +02:00
Sefa Eyeoglu
779f70057b
Merge commit 'ce2ca1381519a2e261d7f76dffa874d559d979c2' into staging 2023-08-14 18:16:13 +02:00
TheKodeToad
a44cb6430e
Merge pull request #1107 from Ryex/chore/add-compiler-warnings
Introduce more strict compiler warnings and fix them
2023-08-13 13:10:58 +01:00
github-actions[bot]
1aadaa208d chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0d2fb29f5071a12d7983319c2c2576be6a130582' (2023-08-05)
  → 'github:nixos/nixpkgs/f0451844bbdf545f696f029d1448de4906c7f753' (2023-08-12)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/3139c4d1f7732cab89f06492bdd4677b877e3785' (2023-08-05)
  → 'github:cachix/pre-commit-hooks.nix/c5ac3aa3324bd8aebe8622a3fc92eeb3975d317a' (2023-08-11)
2023-08-13 00:16:46 +00:00
TheKodeToad
6d070e8607
"Format"
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-12 21:50:02 +01:00
TheKodeToad
5056a51c18
Improvements and refinements to pack export
- Persist fields
- Toggle optional files

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-12 21:20:51 +01:00
TheKodeToad
3c209ba502
theme -> catpacks
Co-authored-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-12 19:04:34 +01:00
Trial97
71890707c0
format and apply the sugestion
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-12 13:08:39 +03:00
Alexandru Ionut Tripon
b3b2e9df35
Merge branch 'develop' into feat/acknowledge_release_type
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-12 12:42:30 +03:00
Sefa Eyeoglu
3aba7f8fec
Merge pull request #1518 from Scrumplex/asan-develop 2023-08-12 11:38:01 +02:00
Alexandru Ionut Tripon
d6e4fe7c1f
Update CMakeLists.txt
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-12 11:29:08 +02:00
Trial97
c9d628bf18
revert asan on debug on by default
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-12 11:29:08 +02:00
Sefa Eyeoglu
35358f8180
Merge remote-tracking branch 'upstream/staging' into chore/add-compiler-warnings 2023-08-12 11:17:11 +02:00
Sefa Eyeoglu
019e5ca3e8
fix: use ApiDownload for CF URL handling
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-12 11:11:58 +02:00
Sefa Eyeoglu
6423edaa76
Merge remote-tracking branch 'upstream/staging' into curseforge-url-handle 2023-08-12 10:58:27 +02:00
Sefa Eyeoglu
44153a28e3
Merge pull request #1517 from Trial97/revert_asan 2023-08-12 10:57:29 +02:00
Alexandru Ionut Tripon
bcf0635efd
Update CMakeLists.txt
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-12 10:55:53 +02:00
Trial97
92dbe1684e
revert asan on debug on by default
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-12 10:55:53 +02:00
seth
7879091cea
Merge pull request #1512 from Trial97/curseforge_import
Fix importing Quilt/Fabric packs from CurseForge
2023-08-11 10:16:17 -04:00
Sefa Eyeoglu
73adac2501
fix: use QColorConstants in Qt 5.14+
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-11 15:57:12 +02:00
Trial97
d801151d5c
connect the abort signal in concurent task
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-11 15:41:41 +03:00
Sefa Eyeoglu
ea43d0f687
fix: fix more warnings
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-11 10:57:57 +02:00
Sefa Eyeoglu
396f812496
Merge pull request #1230 from TheKodeToad/better-component-installation
Revamp loader installation UI
2023-08-11 08:24:14 +02:00
TheKodeToad
f6d8c9659c
Rework
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-11 00:39:05 +01:00
TheKodeToad
e2d77f21ba
More system properties because yes!! 🎉
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-11 00:02:48 +01:00
Sefa Eyeoglu
ef6f9487f4
Merge remote-tracking branch 'upstream/staging' into chore/add-compiler-warnings 2023-08-10 20:38:32 +02:00
Sefa Eyeoglu
8140374e26
chore: add licensing info to loader logos
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-10 20:18:28 +02:00
Sefa Eyeoglu
d67277a668
chore: replace LiteLoader logo with high quality version
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-10 20:18:16 +02:00
maple!
97ef8e8d0e Fix transparency in skin icon
QPainter has a bug where drawing transparency to a freshly initialized, empty QPixmap causes garbage data to be drawn. This broke the rendering of the skin icon. The fix is simply to fill the QPixmap with empty transparent pixels beforehand.

Signed-off-by: maple! <averyrudelphe@gmail.com>
2023-08-10 15:32:47 +02:00
Sefa Eyeoglu
2090f958c8
Merge pull request #1324 from leia-uwu/ui-tweaks 2023-08-10 12:24:41 +02:00
Sefa Eyeoglu
8731f4ba27
chore: add comment about _kde_side_panel_view
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-10 12:24:33 +02:00
Trial97
b3da35be74
Fixed curseforge import
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-10 12:19:38 +03:00
comp500
1c3449e5a2 Remove unnecessary #if
Signed-off-by: comp500 <comp500@users.noreply.github.com>
2023-08-09 23:04:44 +01:00
comp500
a351d1834a Allow empty lines in log output
Preserving empty lines in the game log ensures that crash reports and debugging information has necessary whitespace - the previous behaviour made crash reports hard to read.

Signed-off-by: comp500 <comp500@users.noreply.github.com>
2023-08-09 20:48:02 +01:00
Sefa Eyeoglu
31ffe79a29
Merge pull request #1505 from PrismLauncher/renovate/hendrikmuhs-ccache-action-1.x
chore(deps): update hendrikmuhs/ccache-action action to v1.2.10
2023-08-09 07:32:11 +02:00
renovate[bot]
d9cd6f9c50
chore(deps): update hendrikmuhs/ccache-action action to v1.2.10 2023-08-08 18:20:26 +00:00
TheKodeToad
e079cbb055
Fix actions
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-07 13:51:26 +01:00
Sefa Eyeoglu
7004388105
Merge pull request #1227 from Ryex/packaging/appimage-updates 2023-08-07 13:18:06 +02:00
Tayou
9afa7cc91f
Merge branch 'develop' into icon-indexing
Signed-off-by: Tayou <31988415+TayouVR@users.noreply.github.com>
2023-08-07 10:32:38 +02:00
Rachel Powers
9a9a4fcfd4
Apply suggestions from code review
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-08-06 13:16:30 -07:00
Sefa Eyeoglu
74fe2fb2a6
Merge remote-tracking branch 'upstream/staging' into curseforge-url-handle 2023-08-06 21:54:00 +02:00
seth
eeb5fdbc9f
feat(nix): add darwin support
Signed-off-by: seth <getchoo@tuta.io>
2023-08-06 15:52:32 -04:00
Sefa Eyeoglu
a83e5be8f2
fix: makeShared for QByteArray
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-06 21:51:03 +02:00
seth
75c7df46a7
Merge pull request #1493 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-08-06 15:41:48 -04:00
seth
efaf4024ab
Merge pull request #1464 from Ryex/fix/windows-console-attach
[Windows] Fix attaching logs to console
2023-08-06 15:37:44 -04:00
Sefa Eyeoglu
99fd1e622c
chore: replace fabricmc icons with SVG
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-06 17:46:33 +02:00
github-actions[bot]
37e5f6af48 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/8e8d955c22df93dbe24f19ea04f47a74adbdc5ec' (2023-07-04)
  → 'github:hercules-ci/flake-parts/59cf3f1447cfc75087e7273b04b31e689a8599fb' (2023-08-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:NixOS/nixpkgs/4bc72cae107788bf3f24f30db2e2f685c9298dc9?dir=lib' (2023-06-29)
  → 'github:NixOS/nixpkgs/9e1960bc196baf6881340d53dccb203a951745a2?dir=lib' (2023-08-01)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/d2b52322f35597c62abf56de91b0236746b2a03d' (2023-07-29)
  → 'github:nixos/nixpkgs/0d2fb29f5071a12d7983319c2c2576be6a130582' (2023-08-05)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/1e2443dd3f669eb65433b2fc26a3065e05a7dc9c' (2023-07-29)
  → 'github:cachix/pre-commit-hooks.nix/3139c4d1f7732cab89f06492bdd4677b877e3785' (2023-08-05)
2023-08-06 00:17:51 +00:00
Sefa Eyeoglu
5b8c997180
Merge pull request #1456 from Trial97/icons 2023-08-05 22:50:52 +02:00
Sefa Eyeoglu
7c547f6452
Merge pull request #1370 from Trial97/pack_changelog 2023-08-05 22:50:38 +02:00
Trial97
f7e8ec1855
format files
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 21:17:38 +03:00
Trial97
72de2d5254
Added missing header
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 21:08:16 +03:00
TheKodeToad
f25d0a4e0e
Merge branch 'develop' into env-vars
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-05 18:01:53 +01:00
Trial97
1d3f2674d1
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 19:21:37 +03:00
Trial97
f9ebcb5d2e
Merge branch 'refactor/net-split-headers-to-proxy-class' of https://github.com/Ryex/PrismLauncher into refactor/NetActions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 19:16:57 +03:00
Trial97
b2fdd83594
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into download_threads
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 19:09:10 +03:00
Trial97
91eb30f037
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into pack_changelog 2023-08-05 19:04:53 +03:00
Trial97
d936b25868
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into welcome_background
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 19:04:15 +03:00
Trial97
e7c2274893
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into update_file 2023-08-05 19:02:11 +03:00
Trial97
377fc0352a
Merge branch 'staging' of https://github.com/PrismLauncher/PrismLauncher into icons 2023-08-05 19:00:12 +03:00
Trial97
939a2d67ed
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop12
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-08-05 18:21:09 +03:00
Sefa Eyeoglu
304e294ea7
Merge pull request #1102 from Ryex/refactor/net-split-headers-to-proxy-class 2023-08-04 20:31:43 +02:00
Sefa Eyeoglu
ae793f6cf1
Merge pull request #1459 from Scrumplex/format 2023-08-04 19:42:36 +02:00
Sefa Eyeoglu
1d638e018a
chore: update license headers
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-04 19:41:47 +02:00
seth
50c7d39e08
Merge pull request #1483 from DioEgizio/update-qt652
[macOS,Windows] Update to Qt 6.5.2
2023-08-04 12:05:45 -04:00
TheKodeToad
c5bffed21e
Merge branch 'PrismLauncher:develop' into skinfix 2023-08-04 16:29:30 +01:00
TheKodeToad
d48dd7eb6a
Use override-based setting for online fixes
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-04 16:00:02 +01:00
DioEgizio
b013133cc1 chore: update to qt 6.5.2
Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
2023-08-03 09:24:47 +02:00
TheKodeToad
1bafa36c17
icon -> iconName
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-02 20:33:01 +01:00
TheKodeToad
afaf6f894c
Merge branch 'PrismLauncher:develop' into better-component-installation 2023-08-02 20:27:37 +01:00
TheKodeToad
8b3c465a50
Use protected inheritance for BasePageProvider
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-02 20:24:15 +01:00
TheKodeToad
40c614b3a5
Pressed -> Clicked (doh)
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-02 20:23:30 +01:00
Sefa Eyeoglu
ac36a2289f
Merge pull request #1452 from getchoo/sparkle-disable 2023-08-02 19:28:01 +02:00
Sefa Eyeoglu
fa2b784f7e
Merge branch 'develop' into sparkle-disable
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 19:27:48 +02:00
Sefa Eyeoglu
01e17806f6
Merge pull request #1391 from Trial97/prism_export2 2023-08-02 19:27:14 +02:00
Sefa Eyeoglu
f561e7febf
Merge pull request #1476 from Scrumplex/fix-saving-metaurl 2023-08-02 19:24:24 +02:00
Sefa Eyeoglu
39d4f0df66
fix: don't reset meta url on launch
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:56:54 +02:00
Sefa Eyeoglu
1d468ac35a
chore: reformat
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:35 +02:00
Sefa Eyeoglu
ce2ca13815
fix: add missing headers
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:08 +02:00
TheKodeToad
f256b836f4
Make more options generic
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-02 18:35:08 +02:00
TheKodeToad
71fb38c91f
Fix alignment properties
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-08-02 18:35:08 +02:00
Sefa Eyeoglu
076c189948
fix: format all languages using clang-format
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:08 +02:00
Sefa Eyeoglu
9f66f6495a
fix: fix undisciplined multiple inheritance
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:07 +02:00
Sefa Eyeoglu
c07a857359
fix: remove irregular enum initialization
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:07 +02:00
Sefa Eyeoglu
76df836378
fix: simplify switch statement
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:07 +02:00
Sefa Eyeoglu
a545f67a21
fix: take JavaCheckResult by const reference
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:07 +02:00
Sefa Eyeoglu
9d5818916a
fix(nix): enable clang-format
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-08-02 18:35:07 +02:00
Sefa Eyeoglu
ea56ff255d
Merge pull request #1339 from TheKodeToad/remove-direct-launch 2023-08-02 18:31:27 +02:00
Sefa Eyeoglu
01d3eea379
Merge pull request #1359 from Trial97/import 2023-08-02 18:25:51 +02:00
Alexandru Ionut Tripon
f13eccb03d
Update launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-08-02 19:24:58 +03:00
Sefa Eyeoglu
39d7bc6c24
Merge pull request #1294 from ashuntu/develop 2023-08-02 18:24:54 +02:00
ashuntu
6a7f63166d DCO Remediation Commit for ashuntu <101582426+ashuntu@users.noreply.github.com>
I, ashuntu <101582426+ashuntu@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 10678096e5
I, ashuntu <101582426+ashuntu@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 51d7a6289e
I, ashuntu <101582426+ashuntu@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 1467072f3d

Signed-off-by: ashuntu <101582426+ashuntu@users.noreply.github.com>
2023-08-02 10:04:53 -05:00
Rachel Powers
bae59a8c07
refactor(windows console): reduce code duplication
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-08-02 06:19:43 -07:00
TheKodeToad
bb039d4bc7
Merge pull request #1445 from Trial97/curse
feat: removed flame quilt warning
2023-08-02 12:55:49 +01:00
Sefa Eyeoglu
92b2f463e3
Merge pull request #1474 from apix0n/develop 2023-08-02 12:08:34 +02:00
Apix
16e6a01881
fix: fix copyright year
Signed-off-by: Apix <apix0n@outlook.com>
2023-08-02 11:35:54 +02:00
Rachel Powers
81bc9e488f
DCO Remediation Commit for Rachel Powers <508861+Ryex@users.noreply.github.com>
I, Rachel Powers <508861+Ryex@users.noreply.github.com>, hereby add my Signed-off-by to this commit: b4ae6e9774

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-08-01 20:27:39 -07:00
Rachel Powers
e64e4d7ef7
Fix: always false comparison
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-08-01 18:57:35 -07:00
Rachel Powers
f19e8dd086
Apply suggestions from code review
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-08-01 18:53:51 -07:00
Rachel Powers
b4ae6e9774
fix(compiler warnings): suppress omtimisation flag conflict warnings. leave optimisation to Byild type defaults
- enable ASan for RelWithDebInfo builds
2023-07-31 23:25:49 -07:00
Rachel Powers
5a9f780cf8
fix(FlameInstanceCreationTask): include Net::Apidownload
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-31 22:36:13 -07:00
Rachel Powers
2d1197f59f
Merge branch 'develop' into refactor/net-split-headers-to-proxy-class
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-31 22:26:20 -07:00
Sefa Eyeoglu
d8f2a1354f
chore: update Nix docs
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-31 19:16:32 +02:00
TheKodeToad
b572f75dba
Merge branch 'PrismLauncher:develop' into icon-indexing 2023-07-31 14:40:27 +01:00
Rachel Powers
14e16db01e
refactor(filelink): drop moved funciton
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 16:02:37 -07:00
Rachel Powers
7091bc81c2
chore(rename): fix unfinshed renames from deshadow changes
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:56:38 -07:00
Rachel Powers
1e947ca893
fix(flame creation task): import ApiDownload
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:42:15 -07:00
Rachel Powers
b9fe37aec1
Merge branch 'develop' into chore/add-compiler-warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:33:46 -07:00
Rachel Powers
5d68a4c992
fix: religate export zip to launcher app only
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

fix(MMCZip): include QUrl

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

fix(FileLink): drop FreeConsole

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

fix(filelink exe): add console sources

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:24:50 -07:00
Rachel Powers
760b80934f
fix(filelink exe): add console sources
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:22:18 -07:00
Rachel Powers
6d564628b7
fix(FileLink): drop FreeConsole
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 15:11:00 -07:00
Rachel Powers
f03924478b
Merge branch 'fix/windows-console-attach' into feat/launcher-updater
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

# Conflicts:
#	launcher/Application.cpp
#	launcher/CMakeLists.txt
#	launcher/filelink/FileLink.cpp
2023-07-30 14:30:16 -07:00
Rachel Powers
7c1a465ec9
Merge branch 'develop' into feat/launcher-updater
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 14:19:31 -07:00
Rachel Powers
a7ef663735
fix(windows console): use new logic in FileLink exe
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 14:03:20 -07:00
Rachel Powers
186211244d
refactor(windows console): move to external file
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 13:38:47 -07:00
Rachel Powers
5740ee0444
fix(windows console): properly bind windows console
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-30 13:38:47 -07:00
seth
945939ba68
chore(actions): add new labels to update-flake
Signed-off-by: seth <getchoo@tuta.io>
2023-07-30 04:46:44 -04:00
seth
9137721e8e
Merge pull request #1461 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-07-30 04:45:10 -04:00
Sefa Eyeoglu
566425166b
Merge pull request #1449 from Trial97/tehnic
Reintroduce parsing of INI files
2023-07-30 09:47:40 +02:00
github-actions[bot]
d1513732be chore(nix): update lockfile
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/f465da166263bc0d4b39dfd4ca28b777c92d4b73' (2023-07-22)
  → 'github:nixos/nixpkgs/d2b52322f35597c62abf56de91b0236746b2a03d' (2023-07-29)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/eb433bff05b285258be76513add6f6c57b441775' (2023-07-18)
  → 'github:cachix/pre-commit-hooks.nix/1e2443dd3f669eb65433b2fc26a3065e05a7dc9c' (2023-07-29)
2023-07-30 00:20:33 +00:00
ashuntu
1467072f3d Removed snapcraft.yaml in favor of dedicated repo: https://github.com/ashuntu/prismlauncher-snap 2023-07-28 16:25:32 -05:00
Ash
d133b40b25
Merge branch 'PrismLauncher:develop' into develop 2023-07-28 21:22:35 +00:00
Trial97
c3eb17db74
removed unneded if condition
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 13:22:04 +03:00
Trial97
4789708cc2
added missing )
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 13:16:57 +03:00
Alexandru Ionut Tripon
83fce74bb1
Update launcher/ui/dialogs/NewInstanceDialog.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-28 13:11:56 +03:00
Trial97
fcac98b367
removed comment
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 10:05:22 +03:00
Trial97
97ff7afbe7
keep the icon suffix
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 08:37:45 +03:00
Trial97
7e58b965b7
refactor icon list
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 01:20:05 +03:00
Trial97
1ca7e5efe9
added license header
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 01:20:05 +03:00
Trial97
d460986de0
format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-28 01:20:05 +03:00
Sefa Eyeoglu
bdec11c501
Merge pull request #1437 from LostLuma/instance-export-ignore-caches-2 2023-07-27 09:40:31 +02:00
Sefa Eyeoglu
b1aa9e5846
refactor: introduce internal Launcher_ENABLE_UPDATER variable
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-27 09:37:56 +02:00
seth
51bfda937d
chore: don't include sparkle when not enabled
Signed-off-by: seth <getchoo@tuta.io>
2023-07-27 02:19:21 -04:00
LostLuma
4a9ea832ff
Ignore cache files entirely, also apply to modpack export
Signed-off-by: LostLuma <lilly@lostluma.net>
2023-07-27 01:42:14 +02:00
seth
a8498b0dab
chore: make INSTALL_BUNDLE a cached variable
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 19:03:14 -04:00
seth
48e5040196
feat: disable sparkle when update url is empty
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 19:01:39 -04:00
seth
928e18b66d
Merge pull request #1446 from getchoo/nix-fixes
disable darwin in flake + cleanup garnix.yaml + fix markdownlint warnings
2023-07-26 17:10:07 -04:00
Trial97
62aa7a52c4
fiexed conflicts
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-27 00:07:38 +03:00
Trial97
3c472fd7e0
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into prism_export2 2023-07-27 00:05:59 +03:00
Trial97
b15f689ccf
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions 2023-07-27 00:03:42 +03:00
Sefa Eyeoglu
d960effb99
Merge pull request #1447 from getchoo/typomoment
fix: typo in task.h
2023-07-26 22:56:31 +02:00
Trial97
1e82cb6a7c
fix: add support for QByteArray inifile
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-26 23:56:01 +03:00
Alexandru Ionut Tripon
31b62203a7
Update launcher/ui/MainWindow.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-26 23:44:35 +03:00
seth
af59c41713
fix: typo in task.h
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 16:20:30 -04:00
seth
f7ffbcca6c
chore(docs): correct markdownlint warnings
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 14:49:09 -04:00
seth
342a0d0091
fix(nix): disable x86_64-darwin
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 14:49:09 -04:00
seth
1974bb7e59
chore(ci): cleanup garnix.yaml
Signed-off-by: seth <getchoo@tuta.io>
2023-07-26 14:49:05 -04:00
Trial97
e6b4fc9182
removed quilt warning
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-26 21:36:40 +03:00
Trial97
c778dcbc9c
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-07-26 21:33:15 +03:00
Sefa Eyeoglu
a0944dab7a
Merge pull request #1438 from Scrumplex/update-docs 2023-07-26 20:30:04 +02:00
TheKodeToad
719d87de3b
Update MainWindow.ui
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-26 17:21:12 +01:00
TheKodeToad
816acc9c76 Open catpak folder action
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-26 17:19:39 +01:00
LostLuma
a9fefb2eeb
Address review comments
Signed-off-by: LostLuma <lilly@lostluma.net>
2023-07-26 15:22:22 +02:00
Sefa Eyeoglu
4ad448993c
fix: fix typo in README
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-26 14:48:53 +02:00
Sefa Eyeoglu
bcadffa0e3
Merge pull request #1434 from getchoo/garnix 2023-07-26 14:47:14 +02:00
TheKodeToad
ce2d2c9f32
Merge pull request #1427 from tjw123hh/develop
Add some missing strings to translations
2023-07-26 13:41:54 +01:00
Sefa Eyeoglu
6f652e1d2f
chore: update information for downstreams
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-26 14:38:34 +02:00
LostLuma
361583edfc
Ignore cache files when exporting instances
Signed-off-by: LostLuma <lilly@lostluma.net>
2023-07-26 04:23:01 +02:00
seth
fbf29274e8
chore(ci): remove nix job
we're using garnix now

Signed-off-by: seth <getchoo@tuta.io>
2023-07-25 19:23:17 -04:00
seth
3c35d647b8
feat(ci): init garnix.yaml
Signed-off-by: seth <getchoo@tuta.io>
2023-07-25 19:18:30 -04:00
TheKodeToad
b4159d30fc Revert permission change
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-25 15:17:20 +01:00
tjw123hh
f843d0732b Merge branch 'develop' of https://github.com/tjw123hh/PrismLauncher into develop 2023-07-25 17:36:38 +08:00
tjw123hh
280f041acb Delete some incorrect notr="true" tags
Signed-off-by: tjw123hh <tjw123hh@outlook.com>
2023-07-25 17:35:31 +08:00
Sefa Eyeoglu
4f00012268
Merge pull request #1426 from TheKodeToad/token-censor-fix 2023-07-24 20:41:23 +02:00
tjw123hh
4ab630b832
Update org.prismlauncher.PrismLauncher.desktop.in
Signed-off-by: tjw123hh <56749271+tjw123hh@users.noreply.github.com>
2023-07-24 20:50:11 +08:00
tjw123hh
a32ca43288 DCO Remediation Commit for tjw123hh <tjw123hh@outlook.com>
I, tjw123hh <tjw123hh@outlook.com>, hereby add my Signed-off-by to this commit: 6a01c277e8

Signed-off-by: tjw123hh <tjw123hh@outlook.com>
2023-07-24 20:48:27 +08:00
TheKodeToad
f505d43fc0 Fix token "0" being replaced
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-24 13:43:26 +01:00
tjw123hh
6a01c277e8 Delete some incorrect tags 2023-07-24 20:41:22 +08:00
Sefa Eyeoglu
684c2ec47a
Merge pull request #1420 from PrismLauncher/update_flake_lock_action 2023-07-23 11:45:31 +02:00
seth
273d75fd51
Merge pull request #1419 from pandaninjas/update-libnbtplusplus
Update libnbtplusplus submodule
2023-07-22 20:41:27 -04:00
github-actions[bot]
6f6b0b9661 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'libnbtplusplus':
    'github:PrismLauncher/libnbtplusplus/2203af7eeb48c45398139b583615134efd8d407f' (2022-04-15)
  → 'github:PrismLauncher/libnbtplusplus/a5e8fd52b8bf4ab5d5bcc042b2a247867589985f' (2023-07-22)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/46ed466081b9cad1125b11f11a2af5cc40b942c7' (2023-07-15)
  → 'github:nixos/nixpkgs/f465da166263bc0d4b39dfd4ca28b777c92d4b73' (2023-07-22)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/5e28316db471d1ac234beb70031b635437421dd6' (2023-07-14)
  → 'github:cachix/pre-commit-hooks.nix/eb433bff05b285258be76513add6f6c57b441775' (2023-07-18)
2023-07-23 00:21:25 +00:00
PandaNinjas
2253100ac6 Update libnbtplusplus submodule
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-22 14:26:49 -04:00
Trial97
b31644e228
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-22 18:16:03 +03:00
TheKodeToad
57430fd189
Merge branch 'develop' into better-launch
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-22 11:26:02 +01:00
TheKodeToad
6ffcfcd7e9
Merge pull request #1402 from Trial97/flame_import
feat:made flame instace creation use metadata for recommended version
2023-07-22 11:14:12 +01:00
TheKodeToad
516ddb22ae More catpack changes :3
This is just embarrasing

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-22 11:05:58 +01:00
Trial97
0b74b3833a
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into import 2023-07-21 19:30:06 +03:00
Trial97
ef21879df4
replaced require with ensure for jvmArgs
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-21 19:30:00 +03:00
Trial97
ad92c30472
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into welcome_background
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-21 19:12:16 +03:00
TheKodeToad
bfafbdc51e
Merge branch 'develop' into env-vars
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-21 14:30:24 +01:00
TheKodeToad
1a7c5693cc Remove redundant methods
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-21 13:01:01 +01:00
TheKodeToad
f8b935ab37 Merge remote-tracking branch 'upstream/develop' into icon-indexing 2023-07-21 12:48:05 +01:00
TheKodeToad
8705e88e91
Fix build on Windows
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-21 11:19:55 +01:00
TheKodeToad
0be4db30eb
Merge branch 'PrismLauncher:develop' into better-component-installation 2023-07-21 11:02:57 +01:00
Sefa Eyeoglu
821dd8400b
Merge pull request #1253 from Trial97/catpacks 2023-07-21 11:11:12 +02:00
TheKodeToad
c37e1fb9f1
Merge branch 'develop' into skinfix
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-20 18:11:27 +01:00
TheKodeToad
5088d33fd2 Finish things :P
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-20 14:17:01 +01:00
TheKodeToad
39f7bea53e
Revert accidental change in MainWindow
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-20 14:13:29 +01:00
TheKodeToad
842f08dcfc (UX) Add open folder button next to combo boxes
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-20 11:54:15 +01:00
Trial97
f8d9cd9a03
use range for
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-19 23:08:16 +03:00
TheKodeToad
960093700a Better theme reset
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 20:57:08 +01:00
TheKodeToad
54d393632d Automatically create theme folders, and add an action to open them
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 16:29:52 +01:00
TheKodeToad
c633c6d083 Colors->Widgets
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 14:19:28 +01:00
TheKodeToad
96ebdfc9a8 Sorting and invalid reset
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 14:12:39 +01:00
TheKodeToad
f55120654a
Merge branch 'PrismLauncher:develop' into icon-indexing 2023-07-19 12:51:26 +01:00
TheKodeToad
44ca7c7d22 Licenses
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 12:29:51 +01:00
TheKodeToad
58c2059e10 Remove recursion
It will add icon packs which aren't available - as QIcon's search paths are not recursed!

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-19 10:38:56 +01:00
Trial97
b7bccb9058
removed subdirectory flag
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-19 12:27:02 +03:00
Trial97
f046bd7d50
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks 2023-07-19 12:26:12 +03:00
TheKodeToad
593f452986
Merge pull request #1399 from Scrumplex/offline-uuid
fix: generate predictable UUIDs for offline accounts
2023-07-19 10:16:27 +01:00
TheKodeToad
97662f5c8e Multiple icon themes!
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-18 22:51:34 +01:00
seth
f8d88cc83d
Merge pull request #1372 from PrismLauncher/update_flake_lock_action
chore(nix): update lockfile
2023-07-18 21:19:58 +00:00
Trial97
f393aa684e
wait to load metadata
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-18 23:59:43 +03:00
Trial97
4c319c8f4f
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into flame_import 2023-07-18 23:49:52 +03:00
Trial97
477b72ad33
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into prism_export2 2023-07-18 23:48:02 +03:00
Sefa Eyeoglu
3728cbb62a
Merge pull request #1397 from Gaming32/develop 2023-07-18 22:47:55 +02:00
Trial97
015f88bf83
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into import
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-18 23:46:19 +03:00
Trial97
02082cda09
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into update_file 2023-07-18 23:40:11 +03:00
Trial97
5eec0f5901
feat:managed packs can update from file
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-18 23:40:03 +03:00
Sefa Eyeoglu
3fbc25155b
Merge pull request #1362 from Trial97/fix_warning 2023-07-18 22:28:27 +02:00
Sefa Eyeoglu
ecac05b2fc
Merge pull request #1378 from Trial97/prism_export
Added progress bar to Prism instance export
2023-07-18 22:26:56 +02:00
seth
5b54475d3e
Merge pull request #1385 from orowith2os/flatpak-updates
Update Flatpak manifest
2023-07-18 20:12:39 +00:00
Trial97
391497645f
feat:made flame instace creation use metadata for recommended version
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-18 22:33:39 +03:00
Sefa Eyeoglu
f8fcb98c68
fix: generate predictable UUIDs for offline accounts
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-18 10:07:35 +02:00
Dallas Strouse
2eff1de560
Update Flatpak manifest
Signed-off-by: Dallas Strouse <dastrouses@gmail.com>
2023-07-17 22:38:12 -05:00
Josiah Glosson
1fbb41f5e2
Make Launch Offline not launch online in 1.6+
Signed-off-by: Josiah Glosson <soujournme@gmail.com>
2023-07-17 17:07:06 -05:00
TheKodeToad
01afa8957f
Merge pull request #1387 from Scrumplex/fix-quilt-beacon
Check if any modloader is installed
2023-07-17 17:40:42 +01:00
Trial97
5162203c7d
Merge branch 'prism_export' of github.com:Trial97/PrismLauncher into prism_export2
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 17:58:42 +03:00
Trial97
b0940d696b
Added QFutureWatcher
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>

abort

forgot

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 17:52:00 +03:00
Trial97
fe73d696cb
replace emplace with insert
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 17:24:29 +03:00
Trial97
2ea4a78541
Upgraded ExportToZipTask
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 17:24:23 +03:00
Trial97
f5891940e0
translate strings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 17:22:35 +03:00
Trial97
cd9310afed
replace emplace with insert
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 16:57:52 +03:00
Trial97
64041a84a2
handle file removal in ExportToZipTask
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 16:55:26 +03:00
Trial97
78ee63af38
simplify modrinth export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 16:40:01 +03:00
Trial97
455c495338
simplify flame export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>

s
2023-07-17 16:27:08 +03:00
Trial97
0bf70d677e
Upgraded ExportToZipTask
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 16:24:43 +03:00
Sefa Eyeoglu
2be630904f
fix: don't take modloaders by reference
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-17 14:33:01 +02:00
TheKodeToad
49cebc2da4 More consistent behaviour
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-17 12:49:12 +01:00
TheKodeToad
049abc9b1a Merge remote-tracking branch 'upstream/develop' into rename-groups 2023-07-17 12:13:58 +01:00
Tayou
e8c44e700d
Merge pull request #1286 from TayouVR/better-instance-group-separator 2023-07-17 11:55:31 +02:00
Sefa Eyeoglu
54a091ca59
fix: check if any modloader is installed
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-17 10:09:01 +02:00
Trial97
ec32618e11
reveted back to add years
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-17 10:20:22 +03:00
Sefa Eyeoglu
aaf1726965
Merge pull request #1357 from getchoo/quilt-beacon
feat: add toggle for quilt beacon
2023-07-17 06:42:46 +02:00
seth
6b970954d6
Merge pull request #1381 from getchoo/backporting-docs
chore(docs): add backporting info to CONTRIBUTING.md
2023-07-16 18:36:51 -04:00
TheKodeToad
fb5aefffb2 Reduce bugginess
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-16 23:36:01 +01:00
TheKodeToad
20e2c70464 Rename groups and janky reference counting map
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-16 23:23:33 +01:00
seth
ed2f680202
chore(docs): add backporting info to CONTRIBUTING.md
Signed-off-by: seth <getchoo@tuta.io>
2023-07-16 17:28:52 -04:00
seth
5e0df9b696
Merge pull request #1276 from Scrumplex/print-build-platform
Print build platform on launch
2023-07-16 17:15:55 -04:00
Alexandru Ionut Tripon
ec41252535
Update launcher/MMCZip.h
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-16 23:47:54 +03:00
Alexandru Ionut Tripon
4df9df03ab
Update launcher/MMCZip.cpp
Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-16 23:47:47 +03:00
Trial97
7441974d9d
Removed icon
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 21:23:22 +03:00
Trial97
79222a56e3
use shared pointer
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>

use shared pointer
2023-07-16 21:14:39 +03:00
Trial97
cadb7142f0
Added progress bar to Prism instance export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 20:57:57 +03:00
Trial97
251055302e
format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 20:53:58 +03:00
Sefa Eyeoglu
b54d1651ab
Merge pull request #1373 from Scrumplex/backport-bot 2023-07-16 19:42:09 +02:00
Trial97
9d0175b81a
Added welcome screen
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 17:46:00 +03:00
Trial97
002430db46
added path to flatpack
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 15:43:47 +03:00
Trial97
de30a72c4e
made the date a object
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 15:16:16 +03:00
Trial97
0a956bbc73
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks 2023-07-16 14:18:26 +03:00
Trial97
1e9a596908
simplified code in cat packs
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 14:18:17 +03:00
Sefa Eyeoglu
b9568279dc
Merge pull request #1010 from TayouVR/add_default_editorconfig 2023-07-16 12:30:22 +02:00
Sefa Eyeoglu
fcdd9ea986
Merge pull request #1246 from Trial97/export 2023-07-16 12:24:42 +02:00
Sefa Eyeoglu
c145bfa524
Merge pull request #1369 from Trial97/autoselect 2023-07-16 12:21:17 +02:00
Sefa Eyeoglu
18ebc858fd
feat(actions): add backport action
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-16 11:47:54 +02:00
github-actions[bot]
6597a5c860 chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/267149c58a14d15f7f81b4d737308421de9d7152' (2023-07-01)
  → 'github:hercules-ci/flake-parts/8e8d955c22df93dbe24f19ea04f47a74adbdc5ec' (2023-07-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/cd99c2b3c9f160cd004318e0697f90bbd5960825' (2023-07-01)
  → 'github:nixos/nixpkgs/46ed466081b9cad1125b11f11a2af5cc40b942c7' (2023-07-15)
• Updated input 'pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/42587d3414d1747999a5f71e92a83cf6547b62da' (2023-07-03)
  → 'github:cachix/pre-commit-hooks.nix/5e28316db471d1ac234beb70031b635437421dd6' (2023-07-14)
2023-07-16 00:23:55 +00:00
Trial97
a3ffa64550
Upgraded pack changelog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-16 01:59:08 +03:00
Tayou
a6305ac891
Merge pull request #1368 from Trial97/crash_curse_import 2023-07-15 23:13:00 +02:00
Trial97
06fc8358d9
auto focus search line on resource download
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-15 23:57:32 +03:00
Trial97
c346d875a2
make FileResolvingTask accept empty modlist
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-15 23:26:52 +03:00
seth
a2a09ffe01
chore: better explain quilt loader beacon
Signed-off-by: seth <getchoo@tuta.io>
2023-07-15 14:25:05 -04:00
Trial97
21ffed3bf5
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-15 20:35:11 +03:00
Trial97
fd7aab466b
Merge branch 'refactor/net-split-headers-to-proxy-class' of https://github.com/Ryex/PrismLauncher into refactor/NetActions 2023-07-15 20:33:48 +03:00
Alexandru Ionut Tripon
da87e825a1
Update launcher/ui/dialogs/ExportToModListDialog.ui
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-15 15:59:19 +03:00
Trial97
7befd63cce
fixed settings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-15 00:28:58 +03:00
Alexandru Ionut Tripon
2c2c39b42c
Update launcher/modplatform/import_ftb/PackInstallTask.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-15 00:17:48 +03:00
Alexandru Ionut Tripon
0692cbe701
Update launcher/modplatform/import_ftb/PackInstallTask.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-07-15 00:17:32 +03:00
Trial97
ab10524cd7
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:45:40 +03:00
Trial97
1ccfba13eb
renames
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:41:51 +03:00
Trial97
b9ed8283b7
Added buttons
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:41:45 +03:00
Trial97
1495bfb73e
Made custom template enabled all time
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:41:37 +03:00
Trial97
9b02c31f8d
escaped text for html export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:35:18 +03:00
Trial97
50dae9d4f3
Moved to separate functions
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:34:28 +03:00
Trial97
9a3931dac6
Added json and csv format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:34:21 +03:00
Trial97
515197fba2
fix: html sintax for modlist export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:34:03 +03:00
Trial97
149b6d59cf
fixed tests
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 23:22:11 +03:00
Rachel Powers
37fb52aada
Merge pull request #1351 from Trial97/ftb_import
fixed substatus on ftb_import
2023-07-14 12:41:21 -07:00
Trial97
db9f5f44e0
Split in two the options
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 22:26:22 +03:00
seth
094af0f78f
Merge pull request #1336 from Ryex/packaging/fix-duplicate-share-directories
packaging: fix duplicate share directories (use only lowercase)
2023-07-14 14:19:44 -04:00
Trial97
cebb4dd17a
made the number of concurrent tasks configurable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 20:39:53 +03:00
Rachel Powers
3487e1cb64
Update launcher/Application.cpp
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-14 03:56:18 -07:00
Trial97
440afcedb0
fixed warning
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 13:32:18 +03:00
Trial97
b0a21c9389
insert header
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 13:31:28 +03:00
Trial97
fc4a1ef193
format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 13:31:13 +03:00
Trial97
c8533c0b0d
fixed substatus on ftb_import
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 12:29:03 +03:00
Trial97
b0a018d823
format
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-14 12:28:23 +03:00
Sefa Eyeoglu
3becd4386b
Merge pull request #1306 from Ryex/ci/address-sanitiser_on_debug_builds 2023-07-14 10:11:34 +02:00
seth
3099a70edc
Merge pull request #1335 from Ryex/fix/gh-1322-old-zip-mods-in-wrong-place
fix(flame install): don't assume .zip is a resource pack. default to mod
2023-07-14 00:16:43 -04:00
Rachel Powers
cde85947c7
Update launcher/minecraft/mod/tasks/LocalResourceParse.cpp
Co-authored-by: seth <getchoo@tuta.io>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-13 21:12:12 -07:00
Rachel Powers
5d10045cc8
Merge pull request #1352 from Trial97/crash_after_abort
Do not reset shared pointer if it's already empty
2023-07-13 21:11:47 -07:00
Rachel Powers
520594e529
Merge branch 'develop' into chore/add-compiler-warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-13 20:05:16 -07:00
Rachel Powers
95b300f1ea
packaging: use PascalCase folder name instead
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-13 19:56:36 -07:00
Trial97
bd6e8533ad
send by reference
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-13 19:58:08 +03:00
Trial97
843c2d67eb
Added FTBAPP Import
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-13 18:41:29 +03:00
seth
89aaedc06c
feat: add toggle for quilt beacon
Signed-off-by: seth <getchoo@tuta.io>
2023-07-12 21:10:48 -04:00
Tayou
94d4d12ee0
Merge pull request #1345 from Trial97/time2
feat:Added option to use system locale
2023-07-13 01:56:12 +02:00
TheKodeToad
997a3709d4 Custom environment variables UI and implementation
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-12 19:21:38 +01:00
Trial97
76cc8ce043
renamed setting
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-12 21:05:13 +03:00
Rachel Powers
9499066375
Merge pull request #1350 from Trial97/fix_managed_pack_crash
fixed crash if no version is loaded on managed page
2023-07-12 09:55:31 -07:00
Trial97
25f7cf23d3
the other place
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-12 19:55:11 +03:00
Trial97
9ee68b9268
small pointer check
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-12 18:12:31 +03:00
leo78913
1208300ddf
i forgor to change skin upload browse button
Signed-off-by: leo78913 <leo3758@riseup.net>
2023-07-12 10:57:40 -03:00
Sefa Eyeoglu
06a7d447f6
Merge pull request #1333 from Ryex/fix/null_instance_edit_crash 2023-07-12 15:53:46 +02:00
Trial97
766e833a73
fixed crash if no version is loaded
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-12 16:25:05 +03:00
Rachel Powers
6d5a2ceefe
fix(flameapi): getFile use shared_ptr
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-11 21:45:23 -07:00
Rachel Powers
149bc8e9ce
cleanup: pull out data object so I'm not repeating myself
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-11 21:42:34 -07:00
Rachel Powers
9957aeb003
Merge branch 'develop' into curseforge-url-handle 2023-07-11 21:42:29 -07:00
Trial97
634612ae81
added missing header
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-11 18:20:44 +03:00
Trial97
f0d2aab784
feat:Added option to use system locale
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-11 18:05:43 +03:00
TheKodeToad
4c69290381
Merge branch 'develop' into better-component-installation
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-11 11:14:06 +01:00
seth
640aaa8c23
Merge pull request #1331 from TheKodeToad/hungry-trash
Fix updating trashing resources
2023-07-10 16:31:43 -04:00
Rachel Powers
1aa5fa03f9
Update launcher/ui/MainWindow.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-10 12:05:01 -07:00
Nathan
99ba02afb6
Shortcuts on macOS (#1081)
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-10 20:26:25 +02:00
TheKodeToad
9aedb5afff
Merge pull request #1334 from TheKodeToad/litemod-dl
LiteMod downloading
2023-07-10 16:42:38 +01:00
TheKodeToad
e21756ea8c Remove direct launch
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-10 16:22:37 +01:00
Trial97
35ccfdb799
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-10 16:25:15 +03:00
TheKodeToad
91c9082d19
Merge pull request #1249 from Trial97/curse
Curseforge modpack export
2023-07-10 14:20:29 +01:00
TheKodeToad
4f4ccdaa59
Merge pull request #1338 from Trial97/unlockVersionPage
feat:unlocked versions page
2023-07-10 13:06:32 +01:00
Rachel Powers
01e058d8c1
Merge pull request #1337 from getchoo/fix-flake-workflow
fix(actions): give update-flake content write perms
2023-07-09 14:11:33 -07:00
TheKodeToad
f816e3cd3f
Merge pull request #1241 from Trial97/settings
Allow editing of running instances
2023-07-09 22:10:43 +01:00
Rachel Powers
49109b9213
Merge pull request #1332 from TheKodeToad/widebar-pain
Fix crash when editing instance and prevent similar crashes in future
2023-07-09 14:07:34 -07:00
Rachel Powers
d43399c2b4
Merge pull request #1321 from TheKodeToad/mr-optional
Optional mods in mrpack export
2023-07-09 14:03:47 -07:00
Trial97
308877aa8f
removed redundant code
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-09 23:18:38 +03:00
Trial97
159f14c076
feat:unlocked versions page
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-09 22:47:38 +03:00
seth
8e4de055b8
chore(actions): only run update-flake in our repo
Signed-off-by: seth <getchoo@tuta.io>
2023-07-09 15:43:54 -04:00
Trial97
d7f4e40f85
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-07-09 19:38:17 +03:00
TheKodeToad
6e2fcc9e11 Replace string manipulation in favour of QFileInfo
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-09 12:08:15 +01:00
seth
0d31e31282
fix(actions): give update-flake content write perms
Signed-off-by: seth <getchoo@tuta.io>
2023-07-09 01:56:21 -04:00
Rachel Powers
4dc4c589ba
packaging: fix duplicate share directories (use only lowercase)
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-08 15:44:09 -07:00
TheKodeToad
d53d58a5d4 LiteMod downloading
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-08 22:16:43 +01:00
Rachel Powers
e704072892
fix(flame install): don't assume .zip is a resource pack. default to mod
let identifier move it if needed

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-08 13:38:00 -07:00
Rachel Powers
a54bbae622
fix(instance edit): don't allow editing if no selected instance or instance doesn't support editing
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-08 12:59:55 -07:00
TheKodeToad
08c140b9b4 Fix actionVisitItemPage insersion, and prevent widebar segfault
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-08 20:55:30 +01:00
TheKodeToad
0c6362f28d Make trash hungry
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-08 18:51:28 +01:00
seth
67d473aab7
Merge pull request #1329 from Ryex/fix/progress_dialog_centering
fix(progress dialog): if there is a parent center on creation
2023-07-08 07:50:13 -04:00
Rachel Powers
20c781b23b
fix(progress dialog): if there is a parent center on creation
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-08 02:28:37 -07:00
Rachel Powers
7f138e3538
Merge branch 'develop' into ci/address-sanitiser_on_debug_builds 2023-07-08 01:27:30 -07:00
Rachel Powers
3211b265d7
Merge pull request #1302 from Ryex/fix/progress-dialog-segfault
fix: segfault in progress dialog
2023-07-07 21:25:14 -07:00
Trial97
bc2940e16a
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into settings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-08 00:14:05 +03:00
Tayou
1131038fdb
Merge pull request #1120 from Trial97/visit_mod_page 2023-07-07 22:23:59 +02:00
seth
d1528c1044
Merge pull request #1325 from Scrumplex/validate-meta-url
Validate Meta URL
2023-07-07 14:31:22 -04:00
ashuntu
51d7a6289e Fix URL open crash (#596) 2023-07-07 13:24:31 -05:00
ashuntu
10678096e5 Persist app data between install versions 2023-07-07 13:20:15 -05:00
Sefa Eyeoglu
51e62761ee
fix: improve QUrl construction
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-07 19:25:12 +02:00
leo78913
d1cceac7d1
disable hiding enable and name columns on folder models
Signed-off-by: leo78913 <leo3758@riseup.net>
2023-07-07 12:37:24 -03:00
TheKodeToad
b8482a5d89
Update ModFolderPage.cpp
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-07 15:53:50 +01:00
Trial97
3139af8487
Made action text simpler
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-07 17:12:10 +03:00
Sefa Eyeoglu
6fcdac0d36
fix: reset invalid meta url on launch
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-07 15:57:25 +02:00
Sefa Eyeoglu
073cb91f88
fix(ui): validate meta override url
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-07-07 15:56:07 +02:00
leo78913
3154c2644a
enable tear off on widebar context menu
Signed-off-by: leo78913 <leo3758@riseup.net>
2023-07-07 10:30:18 -03:00
Sefa Eyeoglu
e225a72180
Merge pull request #1128 from pandaninjas/fix-implicit-fallthrough 2023-07-07 15:19:00 +02:00
TheKodeToad
ec85266860
Memory leak fixes
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-07 12:18:04 +01:00
TheKodeToad
4c25e3ce75 Add keyboard shortcut to Kill action
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-06 21:04:21 +01:00
TheKodeToad
8ae67b84db Optional mods in mrpack export
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-06 20:04:26 +01:00
TheKodeToad
440dcdf022 Import QActionGroup properly :P
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-06 18:31:59 +01:00
TheKodeToad
22327bbe71 Combine launch buttons in Instance window, persist profiler
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-06 18:07:45 +01:00
flow
b8b8c8d4ac fix(tests): Fix abort of Task test on Linux
Not sure exactly what caused the issue, though I suppose using QThread's
exec instead of our own thingie is nice. I can't remember why I didn't
use that before, so I hope there's no issue with that! :^)

Signed-off-by: flow <flowlnlnln@gmail.com>
2023-07-06 09:49:07 -07:00
Trial97
93870c315f
better url handling
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-06 18:46:59 +03:00
PandaNinjas
13d67c6524
Keep formatting consistent
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-06 08:51:42 -04:00
leo78913
e8dc1564b6
add _kde_side_panel_view property to page container
With this the sidebars look better with the breeze theme

Signed-off-by: leo78913 <leo3758@riseup.net>
2023-07-06 01:39:59 -03:00
leo78913
f9578066d6
make "browse" buttons and java pages more consistent
Signed-off-by: leo78913 <leo3758@riseup.net>
2023-07-06 01:39:59 -03:00
Rachel Powers
71e73bb6f8
fix(tests): linux big task memory leak.
- move big_task into function scope

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-05 21:18:49 -07:00
Rachel Powers
8638076aa1
fix(test): tasks test memmory leak. don't store local task copy.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-05 20:19:22 -07:00
Rachel Powers
965ee5687a
fix(test): task test memory leak *again*
- put Big thread on the stack so stack will clean it up.

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-05 20:05:18 -07:00
Rachel Powers
4dbcedd03f
fix: Task test memory leaks again
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-05 11:51:37 -07:00
Rachel Powers
5fe9a7a6c3
fix: extra } in CXX args
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-05 03:02:20 -07:00
Rachel Powers
a028894855
Apply suggestions from code review
Co-authored-by: seth <getchoo@tuta.io>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-04 23:43:39 -07:00
Rachel Powers
183ed7b90b
chore: cleanup compiler type branches
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-04 19:43:22 -07:00
PandaNinjas
817ecf8225
Fix VersionProxyModel.cpp
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-04 17:19:08 -04:00
PandaNinjas
4509fde410
Merge branch 'develop' into fix-implicit-fallthrough
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-04 16:41:34 -04:00
PandaNinjas
34cf28712c
Replace break with return true;
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-04 16:39:24 -04:00
PandaNinjas
1fbc17d275
Remove break and add fallthrough comment in WorldListPage.cpp
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-07-04 16:38:04 -04:00
Trial97
908ac813e0
escaped modlist inner html
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-04 15:16:54 +03:00
Rachel Powers
3c96d5e0d5
fix: memory leaks in tests
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-03 20:28:03 -07:00
Rachel Powers
c5705705d5
fix: memory leaks in ResourceModel Test
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-03 18:35:42 -07:00
Rachel Powers
03a1d68b74
fix: memory leaks in filesystem test
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-03 18:18:48 -07:00
Rachel Powers
50eff80ca1
build: optimize address-sanitizer
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-03 18:07:59 -07:00
Rachel Powers
96c118779d
build: enable address sanitiser in debug builds
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-03 17:48:44 -07:00
TheKodeToad
64c591b234 Better parent version filtering; handle old fabric :P
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-03 20:48:37 +01:00
TheKodeToad
0e5c377680 Various tweaks
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-03 17:39:09 +01:00
Trial97
6d758795af
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-03 17:00:56 +03:00
Trial97
fa7cfc77d8
fixed template
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-03 16:08:20 +03:00
Trial97
f0aab541f8
fixed typo
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-03 15:09:35 +03:00
Trial97
026293f773
updated option text
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-03 14:17:39 +03:00
Trial97
5d5f1b86fd
fixed logic regarding range over multiple years
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-03 09:21:25 +03:00
Trial97
ba159ba971
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks 2023-07-03 09:01:22 +03:00
Rachel Powers
e5b9bfb2e7
fix: update if new size is larger
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-02 22:30:25 -07:00
Rachel Powers
8cb8273e67
fix: update if new size is larger
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-02 22:29:45 -07:00
Rachel Powers
73d8343914
fix: header <qpoint.h> -> <QPoint>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-02 22:27:24 -07:00
Rachel Powers
3960eb7d32
fix: properly calculate min size for progress dialog, apply it at creation
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-02 21:24:43 -07:00
Rachel Powers
4004e0faee
fix: segfault in progress dialog
- dialog tries to resize after unhiding the subtask scroll area
- after resize attempts to recenter on parent
  - `calls parentWidget()->{x|y}()`
  - what if there is no parent? nullptr->() = segfault

- recenter on last pos, don't access parent

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-02 20:22:25 -07:00
Rachel Powers
b47993b736
Merge pull request #3 from Trial97/netRefactor3
Fail NetRequest on connection close from QT
2023-07-02 19:32:47 -07:00
Rachel Powers
ca061080c1
Merge pull request #2 from Trial97/feat/acknowledge_release_type
Feat/acknowledge release type
2023-07-02 19:32:25 -07:00
Trial97
f1bd9700f7
Fail NetRequest on connection close from QT
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-02 22:49:58 +03:00
Trial97
5f63c781b4
resolved local vaiables names
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-02 18:50:29 +03:00
Trial97
aad5ca5474
fixed typos
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-02 16:45:15 +03:00
Trial97
cf2393a509
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into settings 2023-07-02 15:56:39 +03:00
Tayou
81c0a1c4bd
antialiasing for all painting, make hitbox fullwidth
Signed-off-by: Tayou <tayou@gmx.net>
2023-07-02 14:01:56 +02:00
Trial97
6fc745e98c
Merge branch 'catpacks' of github.com:Trial97/PrismLauncher into catpacks 2023-07-02 13:34:41 +03:00
Trial97
7579fff532
Added more options for variants planing
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-02 13:34:04 +03:00
Trial97
7ac2a23bc8
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks 2023-07-02 13:14:19 +03:00
Trial97
6c4cf085e0
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-07-02 12:50:45 +03:00
Rachel Powers
8d7dcdfc5b
chore: fix shadowed member and signed/unsigned mismatch
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: supress unused with [[maybe_unused]]

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: unshadow ^&^& static_cast implicit return

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: deshadow and mark unused in parse task

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: mark unused in folder models

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: deshadow and mark unused with instances

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: more deshadow and unused

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: remove uneeded simicolons

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: mark unused

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

chore: prevent shadow

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 23:39:38 -07:00
Rachel Powers
98d6904e4a
chore: fix propagate mispelling
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 17:03:12 -07:00
Rachel Powers
d7d2d9f612
chore: remove WARNINGS_AS_ERRORS
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 17:03:11 -07:00
Rachel Powers
2a5d291bd9
fix: toml without exceptions usage
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 17:03:11 -07:00
Rachel Powers
e2a65a7077
feat: ensure MSVC using stack unwind semantics
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 17:03:11 -07:00
Rachel Powers
671d3c1c80
Merge branch 'develop' into chore/add-compiler-warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-07-01 17:03:11 -07:00
TheKodeToad
6cc3587da2 Disable as intended
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 20:10:38 +01:00
TheKodeToad
9f9b5254a2 Double-click to install/change version
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 19:39:04 +01:00
TheKodeToad
284e374ae8 Nop
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 19:39:04 +01:00
TheKodeToad
4cdf669154 Modify "Change Version" to use "Install Loader" dialog
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 19:39:04 +01:00
TheKodeToad
4332b62a62 Fix search focusing
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 19:39:04 +01:00
TheKodeToad
7138425c85
Merge branch 'develop' into better-component-installation
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-07-01 13:05:55 +01:00
Rachel Powers
b67844e74c
fix(windows installer): old installers didn't uninstall first.
now they do so ensure shortcuts stay selected by default

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 23:04:55 -07:00
Rachel Powers
cea285f5f5
fix(updater): fix bad exe_name on linux
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 21:33:22 -07:00
Rachel Powers
1fd90e9dd0
fix(updater): ensure updater knows binaries are in ./bin/ on linux and can find them
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 21:24:30 -07:00
Rachel Powers
cd527c44a4
fix(updater): build atrifact fix on linux ci + add qt-ver to artifact name
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 18:17:06 -07:00
Rachel Powers
6476023cf7
fix(updater): check the app root dir for binary
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 10:57:53 -07:00
Rachel Powers
a01a48793c
fix(updater): force asInvoker for updater on windows
- use `__COMPAT_LAYER` env var in windows to bypass Installer Detection and run as a normal user anyway
  - set up updater directly after main windows is created
  - check update locks before main window

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 03:19:21 -07:00
Rachel Powers
00f75e2d54
fix(updater): avoid windows installer detection with "asInvoker" in xml exe.manifest
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-30 00:54:29 -07:00
Rachel Powers
8dd3a02747
Update launcher/Application.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 23:49:31 -07:00
Rachel Powers
3db83a189c
fix(updater): include updater in setup.exe
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 22:38:16 -07:00
ashuntu
b6e9a54951 Add snap github action
Signed-off-by: ashuntu <101582426+ashuntu@users.noreply.github.com>
2023-06-29 21:15:07 -05:00
ashuntu
6c374f5f08 Add snapcraft.yaml
Signed-off-by: ashuntu <101582426+ashuntu@users.noreply.github.com>
2023-06-29 21:09:31 -05:00
Rachel Powers
4320830a86
fix(updater): Explicit conversion to string for QByteArray
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 17:59:14 -07:00
Rachel Powers
603e3e7e2e
fix(updater): set minimum dialog / msgbox sizes
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 15:56:44 -07:00
Rachel Powers
109ae5bae0
fix(updater): convert int to string
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 15:42:36 -07:00
Rachel Powers
41cb8d7ec6
fix: adjust dialog size, add parent to msgboxes
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 15:31:12 -07:00
flow
494483fd2b
fix(updater): add parent to dialog to fix issues in tilling WMs
QProgressDialog without parents in Qt tend to cause graphical issues on
some systems, so we add the main window as a parent here!

Signed-off-by: flow <flowlnlnln@gmail.com>
2023-06-29 15:31:11 -07:00
Rachel Powers
a6c8a37a5d
fixa(updater): better update timer logs
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 14:06:14 -07:00
Rachel Powers
e38adf6006
fix(updater) fixes form first round of testing
- reset update time after check

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-29 14:01:11 -07:00
Trial97
25ffc4c4b0
Refactor ImgurUpload
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-29 17:58:09 +03:00
Tayou
8211befc29
removed magic 5, removed unnecessary QPainter function calls
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 23:24:57 +02:00
Tayou
1dc7f80034
4 clang-tidy changes, update copyright info
while already at it I updated all my emails to use one from my domain
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 23:08:04 +02:00
Rachel Powers
cb7ff81ade
fix: copy needs to overwrite
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 13:51:58 -07:00
Rachel Powers
400a2f7201
fix: final fixes
- use `done(code)` for offer dialog

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 12:46:28 -07:00
Rachel Powers
c123558314
fix: add build config header & trimlines form stdout
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 11:25:59 -07:00
Rachel Powers
f287d9deac
fix add NetRequest source
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 11:09:59 -07:00
Tayou
534d156b12
format VisualGroup.cpp file
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 20:06:17 +02:00
Tayou
54d88e4dbf
use QString.isEmpty()
oops
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 20:05:28 +02:00
Rachel Powers
95969e87a1
Merge branch 'refactor/net-split-headers-to-proxy-class' into feat/launcher-updater 2023-06-28 11:05:11 -07:00
Rachel Powers
e29126ca26
fix: add split markdown source
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 10:56:16 -07:00
Rachel Powers
1b5c78b066
Merge branch 'develop' into feat/launcher-updater 2023-06-28 10:54:39 -07:00
Trial97
1c3402d081
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into refactor/NetActions 2023-06-28 20:23:35 +03:00
Tayou
6b3b119db0
give ungrouped instances a group header
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 18:50:44 +02:00
Tayou
66461ac500
some positioning adjustments, deleted the line
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 18:42:49 +02:00
Rachel Powers
46e840fdf1
fix: add thread sleep to wait for resources - add detail text from logs
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 09:18:07 -07:00
Tayou
7033e28572
update instance group header to more modern style
Signed-off-by: Tayou <tayou@gmx.net>
2023-06-28 18:00:40 +02:00
Trial97
0f64ee6a5f
Added warnings for running instances
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-28 18:28:25 +03:00
Trial97
c23bf2fd22
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into settings 2023-06-28 17:46:01 +03:00
Trial97
3ad559ab22
Added version type to review message dialog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-28 17:43:09 +03:00
Trial97
5f1074471d
Corected variable name
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-28 13:35:42 +03:00
Trial97
c04cee7ff7
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/acknowledge_release_type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-28 13:21:00 +03:00
Rachel Powers
4123343130
no need for pre release tag
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-28 00:25:09 -07:00
Rachel Powers
cb35fb8d0e
add optional pre-release tag
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-27 20:37:42 -07:00
Rachel Powers
6aa30d334c
Merge pull request #1 from Trial97/refactor/net-split-headers-to-proxy-class
Simplify Upload and Download
2023-06-27 12:08:41 -07:00
Rachel Powers
6f7454243e
fix: prep for changes in #1276
- sign updater

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-26 23:25:07 -07:00
Trial97
45c39d078f
More clenup
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-27 09:23:24 +03:00
Trial97
385babb458
Simplify Upload and Download
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-27 08:51:17 +03:00
Sefa Eyeoglu
40fb387185
fix(actions): set all build platforms to official
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-06-26 11:58:47 +02:00
Sefa Eyeoglu
63acf0a7b4
fix: set default platform to "unknown"
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-06-26 11:55:48 +02:00
Sefa Eyeoglu
fce000206f
feat: print build platform in application log
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-06-26 11:55:23 +02:00
Sefa Eyeoglu
f5e4171df4
feat: print build platform in log
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-06-26 11:54:22 +02:00
Sefa Eyeoglu
0aaec9ae4f
chore: remove obsolete macOS warning
We don't support that macOS version. This check also never worked, as we
never set the platform to that value.

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2023-06-26 11:53:48 +02:00
Alexandru Ionut Tripon
22bb260ae3
Update launcher/ui/dialogs/ExportToModListDialog.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-26 11:45:26 +03:00
Alexandru Ionut Tripon
d82ae31fc1
Update launcher/ui/dialogs/ExportToModListDialog.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-26 11:45:05 +03:00
Alexandru Ionut Tripon
cf5c01a5b1
Update launcher/ui/dialogs/ExportToModListDialog.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-26 11:44:55 +03:00
Alexandru Ionut Tripon
f2015eee80
Update launcher/ui/MainWindow.ui
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-26 11:44:47 +03:00
Rachel Powers
c0f0462550
fix(updater): logs/ folder
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-26 01:41:51 -07:00
Rachel Powers
1f70589deb
feat(updater): tie in part 2, let there be UI!
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-26 01:22:33 -07:00
Rachel Powers
b7dd32274c
Proper capture on windows
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 22:30:20 -07:00
Rachel Powers
d8e0b14dc4
feat(updater): tie in updater part 1
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 21:37:47 -07:00
Rachel Powers
90da57a806
Merge branch 'refactor/net-split-headers-to-proxy-class' into feat/launcher-updater 2023-06-25 16:13:51 -07:00
Rachel Powers
b142407b21
fix: ensure finished signal is emited
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 16:13:26 -07:00
Rachel Powers
10266f65e4
fix: include ^<optional^> updater doesn't need to know about mods
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 16:10:06 -07:00
seth
c49ee87857
fix(net): fix emit signals in download & upload task
Signed-off-by: seth <getchoo@tuta.io>
2023-06-25 18:56:54 -04:00
Rachel Powers
5b04a17730
Merge branch 'refactor/net-split-headers-to-proxy-class' into feat/launcher-updater 2023-06-25 14:43:45 -07:00
Rachel Powers
4ea0a567bc
DCO Remediation Commit for Rachel Powers <508861+Ryex@users.noreply.github.com>
I, Rachel Powers <508861+Ryex@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 1ba08f4641

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 14:42:16 -07:00
Rachel Powers
8aeec1d52d
fix: use new shared pointer for repsonse buffer
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 14:36:20 -07:00
Rachel Powers
f39d2de0cc
Merge branch 'refactor/net-split-headers-to-proxy-class' into feat/launcher-updater 2023-06-25 14:31:16 -07:00
Rachel Powers
1ba08f4641
fixup! Merge remote-tracking branch 'upstream/develop' into refactor/net-split-headers-to-proxy-class 2023-06-25 14:25:07 -07:00
Rachel Powers
4b65315cdc
chore: add license to headers
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 14:21:55 -07:00
Rachel Powers
275351e19c
Merge branch 'packaging/appimage-updates' into feat/launcher-updater 2023-06-25 13:51:01 -07:00
Rachel Powers
35c233d4c5
DCO Remediation Commit for Rachel Powers <508861+Ryex@users.noreply.github.com>
I, Rachel Powers <508861+Ryex@users.noreply.github.com>, hereby add my Signed-off-by to this commit: f5729d9a7c

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:32 -07:00
Rachel Powers
e099a3f7e8
feat(updater): packaging - know the updater git repo
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:32 -07:00
Rachel Powers
4313466589
feat(updater): final step for portable install
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:32 -07:00
Rachel Powers
d2a3acd493
fix: filter archive assets from windows non-portable installs
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:31 -07:00
Rachel Powers
516dd6bd1a
support windows console
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:31 -07:00
Rachel Powers
44bc60021d
feat(updater): unpack portable archive
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:31 -07:00
Rachel Powers
50d5eb0621
feat(updater): download new & back up old
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:31 -07:00
Rachel Powers
3d3acb7a92
Merge branch 'packaging/appimage-updates' into feat/launcher-updater 2023-06-25 13:47:31 -07:00
Rachel Powers
bee88b1c7f
feat(updater) select valid asset
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:30 -07:00
Rachel Powers
98174b7a37
refactor: use Net tasks for github api download
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:47:30 -07:00
Rachel Powers
5d03919b59
Merge branch 'packaging/file-manifest-in-portable-install' into feat/windows-updater 2023-06-25 13:47:30 -07:00
Rachel Powers
2357d167b8
Merge branch 'packaging/windows-installer-uninstall-previous' into feat/windows-updater 2023-06-25 13:46:28 -07:00
Rachel Powers
013a26aafe
fix: add ApiUpload to CMakeLists.txt
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 13:23:43 -07:00
Rachel Powers
fe9927d10d
Merge branch 'refactor/net-split-headers-to-proxy-class' into feat/windows-updater 2023-06-25 12:44:25 -07:00
Rachel Powers
df4fd7df7f
Merge remote-tracking branch 'upstream/develop' into refactor/net-split-headers-to-proxy-class 2023-06-25 12:43:48 -07:00
Rachel Powers
c8ff812ab8
feat(net): ApiUpload ^& fix unfired finished signals
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 12:02:46 -07:00
Rachel Powers
3105f314cb
fix: class rename (lsp acitons undid the first rename :P)
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 11:09:26 -07:00
Rachel Powers
6db906d623
chore: format
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 11:09:26 -07:00
Rachel Powers
418677ef31
refactor: override / mask static make functions for ApiDownload
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 11:09:25 -07:00
Rachel Powers
9c10965997
refactor: split out setting api headers for downloads
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-25 11:09:25 -07:00
Trial97
87155e346c
Complicated a little task progress
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 19:44:18 +03:00
Trial97
52dd09bdf7
Merge branch 'curse' of github.com:Trial97/PrismLauncher into curse 2023-06-25 17:51:30 +03:00
Trial97
d344ffe370
Removed some setProgress calls
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 17:50:56 +03:00
TheKodeToad
288ea3d19b Remove metaurl function
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-25 14:52:33 +01:00
TheKodeToad
8ade44c9a3 Simplify
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-25 14:40:22 +01:00
Trial97
fa3a46498f
Removed dupliacte code
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 16:23:50 +03:00
Trial97
3546f57a42
Use internal markdown implementation
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 15:17:09 +03:00
Trial97
8d3bc6b6b9
Added markdown QT version check
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 14:58:54 +03:00
Trial97
d1603f1945
Made it more similar to mrpack export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 14:43:11 +03:00
Trial97
84c63f4f01
Added plantxt export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 14:11:41 +03:00
Trial97
ef0752972a
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into export 2023-06-25 12:26:54 +03:00
Trial97
fd5b155ee7
Added error message when exporting snapshots with curseforge
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 12:24:59 +03:00
Trial97
40fbae8ff6
Fixed links tooltip
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 11:36:37 +03:00
Trial97
ce4a86fbcd
Made custom url function
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 10:41:29 +03:00
Trial97
54d7477679
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into visit_mod_page 2023-06-25 10:12:29 +03:00
Trial97
6f7d901a1f
removed extra variable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 09:17:28 +03:00
Trial97
158b07a39e
moved getRequiredBy
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-25 00:24:08 +03:00
Trial97
932531c8ba
fixed authors
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 23:48:18 +03:00
Trial97
69c21454ec
removed projectID
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 22:15:18 +03:00
Trial97
564e394ec8
feat:Update mods now fills missing dependencies
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 21:48:12 +03:00
Trial97
f0e4e07c05
Updated url function
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 20:43:45 +03:00
Trial97
df932c6587
Updated authors string in modlist
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 20:22:18 +03:00
Trial97
81c1a95166
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-06-24 20:04:56 +03:00
Trial97
f825d7753a
Updated copyright headers
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 15:11:15 +03:00
Trial97
19cb6ad588
Updated Modrinth esport messages
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 15:04:18 +03:00
Trial97
4a84084d9d
Added condition for modlist
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 15:02:00 +03:00
Trial97
25579fbedc
Renamed ExportMrPackDialog to ExportPackDialog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 14:54:39 +03:00
Trial97
59e1e51903
Removed unused files
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 14:51:12 +03:00
Trial97
30ef5475c7
Made sure CurseForge string is corect
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 14:50:05 +03:00
Trial97
9804996db6
Added resource packs to export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 14:37:02 +03:00
Trial97
b774817ada
Merge branch 'curse' of github.com:Trial97/PrismLauncher into curse 2023-06-24 13:24:54 +03:00
Trial97
8939096db6
Fixed windows build
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 13:24:40 +03:00
Alexandru Ionut Tripon
a325d814e2
Update launcher/modplatform/flame/FlamePackExportTask.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-24 11:13:08 +03:00
Trial97
cd1e8dc8cc
Removed modlist checkbox
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 11:12:23 +03:00
Trial97
377707d3db
Merge branch 'curse' of github.com:Trial97/PrismLauncher into curse 2023-06-24 11:02:40 +03:00
Trial97
7ebc8c48a8
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-06-24 11:02:13 +03:00
Alexandru Ionut Tripon
42bc04a0d2
Update launcher/ui/MainWindow.cpp
Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-24 11:01:23 +03:00
Rachel Powers
0e7f435921
echo to correct var for summary
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-23 20:56:07 -07:00
Trial97
cf94adb363
Added some warnings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-24 01:05:49 +03:00
Trial97
31aaa6d1da
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-06-23 22:41:06 +03:00
Trial97
823cd3862d
Fixed hash checking
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 22:41:01 +03:00
Trial97
222a10891c
Fixed merge
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 19:41:55 +03:00
Trial97
cb2671a02c
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-06-23 19:35:47 +03:00
Trial97
0a56631831
Added curseforge search
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 19:35:41 +03:00
Trial97
90df092174
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse 2023-06-23 17:29:58 +03:00
Alexandru Ionut Tripon
c5ea8367aa
Update launcher/ui/themes/CatPack.cpp
Co-authored-by: TheKodeToad <TheKodeToad@proton.me>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
2023-06-23 14:25:21 +03:00
Trial97
f8adb508ab
Made catpack id optional in catpack.json
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 11:44:40 +03:00
Trial97
6613deca0f
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into catpacks 2023-06-23 11:42:28 +03:00
Trial97
718aca3d06
Fixed date constructor
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 09:24:18 +03:00
Trial97
bf95cfb30e
Added CatPacks
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-23 01:37:28 +03:00
Trial97
85495c794d
changed map tipe
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 21:12:02 +03:00
Trial97
049b02cee4
finished up the curesforge export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 21:06:01 +03:00
TheKodeToad
05d2c1f0b0 Dynamic button text
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-22 18:18:33 +01:00
Trial97
3c9c39cb89
Updated slug for url
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 20:04:23 +03:00
Trial97
377f27b16f
Updated slug for url
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 20:04:06 +03:00
Trial97
58321f3491
Added curseforge export
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 20:03:44 +03:00
Trial97
4e07f9574a
Use slug for url
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 18:11:25 +03:00
Trial97
da6f846a49
Use slug for url
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 18:11:03 +03:00
Trial97
9ad356d66f
Added ExportModsToStringTask
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 17:44:12 +03:00
Trial97
836e8d2e28
Fixed code quality
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 17:39:57 +03:00
Trial97
b84dc8551a
Fixed trigger function
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 16:49:19 +03:00
Trial97
f7d502c68c
Added ExportModsToStringDialog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 16:08:04 +03:00
Trial97
9d2516a199
Added ExportModsToStringTask
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-22 16:07:55 +03:00
TheKodeToad
e7ad373d89
Merge branch 'PrismLauncher:develop' into better-component-installation 2023-06-22 13:22:44 +01:00
TheKodeToad
dea33a3c1d Make selectedPage const 🤦‍♀️
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-22 13:13:25 +01:00
TheKodeToad
1f16380efc Fix
I could use rvalue references and fix my brain fart, but i think regular references are more readable and safer here.

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-22 12:56:47 +01:00
Trial97
0063d52952
Merge branch 'settings2' of github.com:Trial97/PrismLauncher into settings 2023-06-21 23:25:37 +03:00
Trial97
820892d7cc
Made settings editable when instance is running
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-21 22:42:08 +03:00
Trial97
0d2105dec4
Made buttons on ModsFolderPage enabled all the time
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-21 21:34:40 +03:00
Trial97
480faca559
Removed unused variable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-21 21:17:17 +03:00
Trial97
ba609f3600
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into visit_mod_page
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-21 09:14:58 +03:00
TheKodeToad
94510edd72 Rework icons (Fabric is blurry now but looks better)
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-20 19:57:15 +01:00
TheKodeToad
a389983d7d Just use the old ordering
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-20 00:28:42 +01:00
TheKodeToad
82d3755e25 License all the things
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-19 23:36:20 +01:00
TheKodeToad
6ccc7e77f9 Basic, unfinished & broken impl
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-06-19 22:42:30 +01:00
Rachel Powers
f8a02a5c9b
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into packaging/appimage-updates 2023-06-19 01:41:14 -07:00
Rachel Powers
6685810081
packaging: sign appimages with gpg
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-19 01:34:14 -07:00
Rachel Powers
53d40df292
packaging: add appimage update capability
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

packaging(linux): use vars when refrencing qt install dir

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

packaging(appimage): dont use rsync

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

packaging: use runner.workspace when copying files

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

packaging(appimage): put zsync in relase:x

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

use with:token insted of env for GITHUB_TOKEN (which is depricated)

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

fix: appimage zsync needs consistant filenames across verisons

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

upload proper zsync

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

fix: non versioned appimage filename

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-19 00:49:03 -07:00
Trial97
be0df38453
Added tooltip for name label
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-15 11:40:39 +03:00
Trial97
fcfb3d2df7
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into visit_mod_page 2023-06-15 10:37:10 +03:00
TheKodeToad
180ed0cc1a
Merge branch 'PrismLauncher:develop' into skinfix 2023-06-13 11:08:21 +01:00
PandaNinjas
95f6860005
Apply suggestions from code review
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-08 10:12:27 -04:00
PandaNinjas
e6872aba75
Readd deleted line
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 22:15:44 -04:00
PandaNinjas
11cbeb8f96
Fix shadowing and add copyright header
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 22:13:57 -04:00
PandaNinjas
886b372ade
Fix accidentally renamed variable
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 20:03:58 -04:00
PandaNinjas
534328f16d
Remove unnecessary switch statement
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>

DCO Remediation Commit for PandaNinjas <admin@malwarefight.wip.la>

I, PandaNinjas <admin@malwarefight.wip.la>, hereby add my Signed-off-by to this commit: 318d11481d

Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 19:46:36 -04:00
PandaNinjas
318d11481d
Resolve other switch fallthrough issues 2023-06-07 19:37:54 -04:00
PandaNinjas
5d425ecc02
Fix the AccountList code
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 18:14:05 -04:00
PandaNinjas
c225ecbb55
Add sensible defaults in AccountList.cpp
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 18:01:39 -04:00
PandaNinjas
a90eaafa70
Make it clear that the statements are meant to fall through in Murmur hash
Signed-off-by: PandaNinjas <admin@malwarefight.wip.la>
2023-06-07 15:18:59 -04:00
Trial97
8abe6b6732
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into visit_mod_page 2023-06-07 20:18:36 +03:00
Trial97
e936bc4c60
Added custom text for multiple selection
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-07 01:38:10 +03:00
Trial97
f724059b88
Added visit mod's page
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
2023-06-07 01:23:53 +03:00
Rachel Powers
df18d8560d chore: fix test & clean up one last warning
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 22:46:05 -07:00
Rachel Powers
3531c5bb8c packaging(appimage): put zsync in relase:x
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 16:58:46 -07:00
Rachel Powers
cc41b039e6 chore: clean up after new compiler warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 14:59:48 -07:00
Rachel Powers
7e0e1ec51d chore: add better default compiler warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 14:10:17 -07:00
Rachel Powers
ab41816265 packaging: use runner.workspace when copying files
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 12:27:01 -07:00
Rachel Powers
2c95973446 packaging(appimage): dont use rsync
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-04 10:36:34 -07:00
Rachel Powers
89d8f9b829 packaging(linux): use vars when refrencing qt install dir
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-03 22:43:41 -07:00
Rachel Powers
0bda885bbf packaging: add appimage update capability
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-03 21:56:46 -07:00
Rachel Powers
74d4a98864 refactor: split out setting api headers for downloads
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-01 16:39:04 -07:00
Rachel Powers
f619a04fe7 refactor: rename app class
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-01 14:55:20 -07:00
Rachel Powers
5627b4a9c5 refactor: rename updater files
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-06-01 13:45:36 -07:00
Rachel Powers
46a13c8767 packaging: fix typo ; in middle of line
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 20:16:58 -07:00
Rachel Powers
3bbe33132a packaging: convert msys paths
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 19:39:14 -07:00
Rachel Powers
b48540dc32 packaging: trim leading working dir from manifest paths
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 16:27:53 -07:00
Rachel Powers
4e0a08345d packaging: add manifest.txt to linux tarballs
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 16:07:29 -07:00
Rachel Powers
9b1e0eb57d packaging: msys2 shell is bash
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 16:01:31 -07:00
Rachel Powers
4cbae0a751 packaging: trim manfest paths to be relative
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 15:36:25 -07:00
Rachel Powers
68c2833552 packaging: use powershell name
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 14:55:13 -07:00
Rachel Powers
dbe14c6be5 packaging: ensure all files are in manifest
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 14:54:06 -07:00
Rachel Powers
7c85462ff3 packaging: include file manifest in portable install
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 14:31:38 -07:00
Rachel Powers
8db4a2a5b9 Merge branch 'packaging/windows-installer-uninstall-previous' into feat/windows-updater 2023-05-31 13:57:56 -07:00
Rachel Powers
2dce08caf1 fix: typo - space before comment
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 13:54:13 -07:00
Rachel Powers
f5729d9a7c Revert "fix: typo - no space before comment"
This reverts commit 0b2044e9a4.
2023-05-31 13:53:44 -07:00
Rachel Powers
0b2044e9a4 fix: typo - no space before comment
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-31 13:52:23 -07:00
Rachel Powers
1c91d2f242 feat: paliminary updater
- can check for need to update
- can select a version to update to
- perform update: TODO

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-30 23:03:44 -07:00
Rachel Powers
eb079c8060
cleanup: msgbox msg editor
Co-authored-by: flow <flowlnlnln@gmail.com>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-28 11:13:53 -07:00
Tayou
c0f9ccc5b5
Use slash_star comment style in .editorconfig
Signed-off-by: Tayou <31988415+TayouVR@users.noreply.github.com>
2023-05-28 19:57:08 +02:00
Rachel Powers
2680dba0aa fix: use <= when compareing release types
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-26 17:16:50 -07:00
Rachel Powers
832a61f886 fix: make codeQl happy
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-26 16:34:30 -07:00
Rachel Powers
cf4df19986 feat: display release type
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-26 16:23:43 -07:00
Rachel Powers
c156034069 feat: add verion_type / release_type to IndexedVersion
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-26 13:50:22 -07:00
Rachel Powers
bd1ea64d02
cleanup
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-16 00:01:52 -07:00
Rachel Powers
649753e97e cleanup: remove unneeded headers
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-15 16:40:56 -07:00
Rachel Powers
fc656b6927 fix: when given a remost resource, download and identify it before import.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-15 16:34:33 -07:00
Rachel Powers
b1ffc8ddab refactor: normalize url fn & cleanup
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-12 16:37:45 -07:00
Rachel Powers
3e11d94829
spelling suggestions from code review
Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net>
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-12 01:47:18 -07:00
Rachel Powers
82287e0407 Merge branch 'develop' into curseforge-url-handle 2023-05-12 01:00:26 -07:00
Rachel Powers
a3173b5371 fix: ensure Application accepts URLs and local files form cmd args
refactor: Move curseforge:// url scheme detection to Import Page
feat: pass along extra CF pack info so pack metadata is established.

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-05-05 15:05:17 -07:00
timoreo
54fb799d95 Fix command line args
Signed-off-by: timoreo <contact@timoreo.fr>
2023-05-05 15:05:17 -07:00
timoreo
565202c990 Added a protection against giving a mod url
Signed-off-by: timoreo <contact@timoreo.fr>
2023-05-05 15:05:17 -07:00
timoreo
63c21c53af Added url handler for curseforge
Signed-off-by: timoreo <contact@timoreo.fr>
2023-05-05 15:05:17 -07:00
Kode
dfc2b9c76a
thanks flowln! :P
Signed-off-by: Kode <TheKodeToad@proton.me>
2023-04-21 20:49:47 +01:00
Tayou
87db723008
add global .editorconfig for doxygen comment style
Signed-off-by: Tayou <tayou@gmx.net>
2023-04-18 20:25:45 +02:00
TheKodeToad
3390e84a9f
Merge branch 'PrismLauncher:develop' into skinfix 2023-03-14 12:07:05 +00:00
TheKodeToad
2e1c123c05
Merge branch 'PrismLauncher:develop' into skinfix 2023-03-10 11:17:06 +00:00
TheKodeToad
83c5264598 Stupidly small skinfixfix as requested by DioEgizio
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-03-10 11:04:15 +00:00
TheKodeToad
6a5e9a59df Fix screwed up ui file
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-02-19 12:00:59 +00:00
TheKodeToad
bb62c62a03 Fix cmark again 🤦
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-02-19 11:37:59 +00:00
TheKodeToad
9cc3d9d4ce Merge remote-tracking branch 'upstream/develop' into skinfix
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-02-19 11:35:26 +00:00
TheKodeToad
d4b346b7ae Fix oversights
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-01-09 10:48:46 +00:00
TheKodeToad
52b3a54e4b
Fix cloaks conflicting with join server endpoint
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-01-08 15:36:36 +00:00
TheKodeToad
be7f81421a Finishing touches
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-01-06 10:46:43 +00:00
TheKodeToad
17317ea308 Move legacy support classes to another jar
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-01-06 09:23:36 +00:00
TheKodeToad
cb32711077 Slim skin fix - thanks to @craftycodie and @DelofJ
!

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2023-01-06 09:21:43 +00:00
TheKodeToad
5c96b1c628
Remove MIT license from JsonParser
I don't mind, and it's my code.

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-25 09:45:42 +00:00
TheKodeToad
884bd85495 Skin fix -> online fixes
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-23 09:35:29 +00:00
TheKodeToad
94067f34cf Try to make some of the suggested changes
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-23 09:34:26 +00:00
TheKodeToad
87bcefd08a Automatically add add-opens if Java version >= 9
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 15:28:24 +00:00
TheKodeToad
8a6776731a Use reflection to access DatatypeConverter
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
bfa5fe1598 Better skin fix error handling
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
ead59c0246 Improve the skin fix code
- Spoof 404 instead of keeping original URL.
- Move JsonParseException to the package.
- Pass proxy as null to reduce code duplication.

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
cfeadf858e Add workaround to warning
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
7534eaf006 Only use DatatypeConverter as a fallback
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
8a81aaaa0a Add separate util class
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:39 +00:00
TheKodeToad
b544661e81 Experimental skin fix, inspired by craftycodie's
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
2022-12-15 14:59:38 +00:00
886 changed files with 39385 additions and 23690 deletions

View File

@ -1,16 +1,17 @@
--- ---
Language: Cpp BasedOnStyle: Chromium
BasedOnStyle: Chromium
IndentWidth: 4 IndentWidth: 4
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
ColumnLimit: 140
---
Language: Cpp
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
BraceWrapping: BraceWrapping:
AfterFunction: true AfterFunction: true
SplitEmptyFunction: false SplitEmptyFunction: false
SplitEmptyRecord: false SplitEmptyRecord: false
SplitEmptyNamespace: false SplitEmptyNamespace: false
BreakBeforeBraces: Custom BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma BreakConstructorInitializers: BeforeComma
ColumnLimit: 140
Cpp11BracedListStyle: false Cpp11BracedListStyle: false

4
.clang-tidy Normal file
View File

@ -0,0 +1,4 @@
Checks:
- modernize-use-using
SystemHeaders: false

8
.editorconfig Normal file
View File

@ -0,0 +1,8 @@
# EditorConfig specs and documentation: https://EditorConfig.org
# top-most EditorConfig file
root = true
# C++ Code Style settings
[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}]
cpp_generate_documentation_comments = doxygen_slash_star

1
.envrc
View File

@ -1 +1,2 @@
use flake use flake
watch_file nix/*.nix

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

@ -0,0 +1,32 @@
name: Backport
on:
pull_request_target:
types: [closed, labeled]
# WARNING:
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
# the GitHub repository. This means that it should not evaluate user input in a
# way that allows code injection.
permissions:
contents: read
jobs:
backport:
permissions:
contents: write # for korthout/backport-action to create branch
pull-requests: write # for korthout/backport-action to create PR to backport
name: Backport Pull Request
if: github.repository_owner == 'PrismLauncher' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
uses: korthout/backport-action@v2.1.0
with:
# Config README: https://github.com/korthout/backport-action#backport-action
pull_description: |-
Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.

View File

@ -24,6 +24,12 @@ on:
CACHIX_AUTH_TOKEN: CACHIX_AUTH_TOKEN:
description: Private token for authenticating against Cachix cache description: Private token for authenticating against Cachix cache
required: false required: false
GPG_PRIVATE_KEY:
description: Private key for AppImage signing
required: false
GPG_PRIVATE_KEY_ID:
description: ID for the GPG_PRIVATE_KEY, to select the signing key
required: false
jobs: jobs:
build: build:
@ -31,56 +37,43 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- os: ubuntu-20.04 - os: ubuntu-20.04
qt_ver: 5 qt_ver: 5
- os: ubuntu-20.04 - os: ubuntu-20.04
qt_ver: 6 qt_ver: 6
qt_host: linux qt_host: linux
qt_arch: '' qt_arch: ""
qt_version: '6.2.4' qt_version: "6.2.4"
qt_modules: 'qt5compat qtimageformats' qt_modules: "qt5compat qtimageformats"
qt_tools: '' qt_tools: ""
- os: windows-2022 - os: windows-2022
name: "Windows-MinGW-w64" name: "Windows-MinGW-w64"
msystem: clang64 msystem: clang64
vcvars_arch: 'amd64_x86' vcvars_arch: "amd64_x86"
- os: windows-2022
name: "Windows-MSVC-Legacy"
msystem: ''
architecture: 'win32'
vcvars_arch: 'amd64_x86'
qt_ver: 5
qt_host: windows
qt_arch: 'win32_msvc2019'
qt_version: '5.15.2'
qt_modules: ''
qt_tools: 'tools_openssl_x86'
- os: windows-2022 - os: windows-2022
name: "Windows-MSVC" name: "Windows-MSVC"
msystem: '' msystem: ""
architecture: 'x64' architecture: "x64"
vcvars_arch: 'amd64' vcvars_arch: "amd64"
qt_ver: 6 qt_ver: 6
qt_host: windows qt_host: windows
qt_arch: '' qt_arch: ''
qt_version: '6.5.1' qt_version: '6.6.0'
qt_modules: 'qt5compat qtimageformats' qt_modules: 'qt5compat qtimageformats'
qt_tools: '' qt_tools: ''
- os: windows-2022 - os: windows-2022
name: "Windows-MSVC-arm64" name: "Windows-MSVC-arm64"
msystem: '' msystem: ""
architecture: 'arm64' architecture: "arm64"
vcvars_arch: 'amd64_arm64' vcvars_arch: "amd64_arm64"
qt_ver: 6 qt_ver: 6
qt_host: windows qt_host: windows
qt_arch: 'win64_msvc2019_arm64' qt_arch: 'win64_msvc2019_arm64'
qt_version: '6.5.1' qt_version: '6.6.0'
qt_modules: 'qt5compat qtimageformats' qt_modules: 'qt5compat qtimageformats'
qt_tools: '' qt_tools: ''
@ -90,7 +83,7 @@ jobs:
qt_ver: 6 qt_ver: 6
qt_host: mac qt_host: mac
qt_arch: '' qt_arch: ''
qt_version: '6.5.0' qt_version: '6.6.0'
qt_modules: 'qt5compat qtimageformats' qt_modules: 'qt5compat qtimageformats'
qt_tools: '' qt_tools: ''
@ -99,9 +92,9 @@ jobs:
macosx_deployment_target: 10.13 macosx_deployment_target: 10.13
qt_ver: 5 qt_ver: 5
qt_host: mac qt_host: mac
qt_version: '5.15.2' qt_version: "5.15.2"
qt_modules: '' qt_modules: ""
qt_tools: '' qt_tools: ""
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -119,11 +112,11 @@ jobs:
# PREPARE # PREPARE
## ##
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
submodules: 'true' submodules: "true"
- name: 'Setup MSYS2' - name: "Setup MSYS2"
if: runner.os == 'Windows' && matrix.msystem != '' if: runner.os == 'Windows' && matrix.msystem != ''
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
with: with:
@ -152,18 +145,18 @@ jobs:
- name: Setup ccache - name: Setup ccache
if: (runner.os != 'Windows' || matrix.msystem == '') && inputs.build_type == 'Debug' if: (runner.os != 'Windows' || matrix.msystem == '') && inputs.build_type == 'Debug'
uses: hendrikmuhs/ccache-action@v1.2.9 uses: hendrikmuhs/ccache-action@v1.2.10
with: with:
key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}-${{ matrix.architecture }} key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}-${{ matrix.architecture }}
- name: Retrieve ccache cache (Windows MinGW-w64) - name: Retrieve ccache cache (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug' if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug'
uses: actions/cache@v3.3.1 uses: actions/cache@v3.3.2
with: with:
path: '${{ github.workspace }}\.ccache' path: '${{ github.workspace }}\.ccache'
key: ${{ matrix.os }}-mingw-w64-ccache-${{ github.run_id }} key: ${{ matrix.os }}-mingw-w64-ccache-${{ github.run_id }}
restore-keys: | restore-keys: |
${{ matrix.os }}-mingw-w64-ccache ${{ matrix.os }}-mingw-w64-ccache
- name: Setup ccache (Windows MinGW-w64) - name: Setup ccache (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug' if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug'
@ -208,35 +201,35 @@ jobs:
if: runner.os == 'Windows' && matrix.architecture == 'arm64' if: runner.os == 'Windows' && matrix.architecture == 'arm64'
uses: jurplel/install-qt-action@v3 uses: jurplel/install-qt-action@v3
with: with:
aqtversion: '==3.1.*' aqtversion: "==3.1.*"
py7zrversion: '>=0.20.2' py7zrversion: ">=0.20.2"
version: ${{ matrix.qt_version }} version: ${{ matrix.qt_version }}
host: 'windows' host: "windows"
target: 'desktop' target: "desktop"
arch: '' arch: ""
modules: ${{ matrix.qt_modules }} modules: ${{ matrix.qt_modules }}
tools: ${{ matrix.qt_tools }} tools: ${{ matrix.qt_tools }}
cache: ${{ inputs.is_qt_cached }} cache: ${{ inputs.is_qt_cached }}
cache-key-prefix: host-qt-arm64-windows cache-key-prefix: host-qt-arm64-windows
dir: ${{ github.workspace }}\HostQt dir: ${{ github.workspace }}\HostQt
set-env: false set-env: false
- name: Install Qt (macOS, Linux, Qt 6 & Windows MSVC) - name: Install Qt (macOS, Linux, Qt 6 & Windows MSVC)
if: runner.os == 'Linux' && matrix.qt_ver == 6 || runner.os == 'macOS' || (runner.os == 'Windows' && matrix.msystem == '') if: runner.os == 'Linux' && matrix.qt_ver == 6 || runner.os == 'macOS' || (runner.os == 'Windows' && matrix.msystem == '')
uses: jurplel/install-qt-action@v3 uses: jurplel/install-qt-action@v3
with: with:
aqtversion: '==3.1.*' aqtversion: "==3.1.*"
py7zrversion: '>=0.20.2' py7zrversion: ">=0.20.2"
version: ${{ matrix.qt_version }} version: ${{ matrix.qt_version }}
host: ${{ matrix.qt_host }} host: ${{ matrix.qt_host }}
target: 'desktop' target: "desktop"
arch: ${{ matrix.qt_arch }} arch: ${{ matrix.qt_arch }}
modules: ${{ matrix.qt_modules }} modules: ${{ matrix.qt_modules }}
tools: ${{ matrix.qt_tools }} tools: ${{ matrix.qt_tools }}
cache: ${{ inputs.is_qt_cached }} cache: ${{ inputs.is_qt_cached }}
- name: Install MSVC (Windows MSVC) - name: Install MSVC (Windows MSVC)
if: runner.os == 'Windows' # We want this for MinGW builds as well, as we need SignTool if: runner.os == 'Windows' # We want this for MinGW builds as well, as we need SignTool
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
with: with:
vsversion: 2022 vsversion: 2022
@ -249,6 +242,8 @@ jobs:
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-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" wget "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage"
wget "https://github.com/AppImageCommunity/AppImageUpdate/releases/download/continuous/AppImageUpdate-x86_64.AppImage"
${{ github.workspace }}/.github/scripts/prepare_JREs.sh ${{ github.workspace }}/.github/scripts/prepare_JREs.sh
sudo apt install libopengl0 sudo apt install libopengl0
@ -264,23 +259,23 @@ jobs:
- name: Configure CMake (macOS) - name: Configure CMake (macOS)
if: runner.os == 'macOS' && matrix.qt_ver == 6 if: runner.os == 'macOS' && matrix.qt_ver == 6
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja
- name: Configure CMake (macOS-Legacy) - name: Configure CMake (macOS-Legacy)
if: runner.os == 'macOS' && matrix.qt_ver == 5 if: runner.os == 'macOS' && matrix.qt_ver == 5
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja
- name: Configure CMake (Windows MinGW-w64) - name: Configure CMake (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != '' if: runner.os == 'Windows' && matrix.msystem != ''
shell: msys2 {0} shell: msys2 {0}
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }} -G Ninja
- name: Configure CMake (Windows MSVC) - name: Configure CMake (Windows MSVC)
if: runner.os == 'Windows' && matrix.msystem == '' if: runner.os == 'Windows' && matrix.msystem == ''
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON -DLauncher_BUILD_ARTIFACT=${{ matrix.name }}-Qt${{ matrix.qt_ver }}
# https://github.com/ccache/ccache/wiki/MS-Visual-Studio (I coudn't figure out the compiler prefix) # https://github.com/ccache/ccache/wiki/MS-Visual-Studio (I coudn't figure out the compiler prefix)
if ("${{ env.CCACHE_VAR }}") if ("${{ env.CCACHE_VAR }}")
{ {
@ -295,7 +290,7 @@ jobs:
- name: Configure CMake (Linux) - name: Configure CMake (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: | run: |
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=Linux -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DLauncher_BUILD_ARTIFACT=Linux-Qt${{ matrix.qt_ver }} -G Ninja
## ##
# BUILD # BUILD
@ -387,17 +382,16 @@ jobs:
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
if ("${{ matrix.qt_ver }}" -eq "5") if ("${{ matrix.qt_ver }}" -eq "5")
{ {
Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll -Destination libcrypto-1_1.dll Copy-Item ${{ runner.workspace }}/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll -Destination libcrypto-1_1.dll
Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll -Destination libssl-1_1.dll Copy-Item ${{ runner.workspace }}/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll -Destination libssl-1_1.dll
} }
cd ${{ github.workspace }} cd ${{ github.workspace }}
Get-ChildItem ${{ env.INSTALL_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt Get-ChildItem ${{ env.INSTALL_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt
- name: Fetch codesign certificate (Windows) - name: Fetch codesign certificate (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: bash # yes, we are not using MSYS2 or PowerShell here shell: bash # yes, we are not using MSYS2 or PowerShell here
run: | run: |
echo '${{ secrets.WINDOWS_CODESIGN_CERT }}' | base64 --decode > codesign.pfx echo '${{ secrets.WINDOWS_CODESIGN_CERT }}' | base64 --decode > codesign.pfx
@ -407,7 +401,7 @@ jobs:
if (Get-Content ./codesign.pfx){ if (Get-Content ./codesign.pfx){
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
# We ship the exact same executable for portable and non-portable editions, so signing just once is fine # We ship the exact same executable for portable and non-portable editions, so signing just once is fine
SignTool sign /fd sha256 /td sha256 /f ../codesign.pfx /p '${{ secrets.WINDOWS_CODESIGN_PASSWORD }}' /tr http://timestamp.digicert.com prismlauncher.exe prismlauncher_filelink.exe SignTool sign /fd sha256 /td sha256 /f ../codesign.pfx /p '${{ secrets.WINDOWS_CODESIGN_PASSWORD }}' /tr http://timestamp.digicert.com prismlauncher.exe prismlauncher_updater.exe prismlauncher_filelink.exe
} else { } else {
":warning: Skipped code signing for Windows, as certificate was not present." >> $env:GITHUB_STEP_SUMMARY ":warning: Skipped code signing for Windows, as certificate was not present." >> $env:GITHUB_STEP_SUMMARY
} }
@ -466,11 +460,15 @@ jobs:
- name: Package AppImage (Linux) - name: Package AppImage (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5 if: runner.os == 'Linux' && matrix.qt_ver != 5
shell: bash shell: bash
env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
run: | run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr
mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.appdata.xml mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.appdata.xml
export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated
export OUTPUT="PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
export OUTPUT="PrismLauncher-Linux-x86_64.AppImage"
chmod +x linuxdeploy-*.AppImage chmod +x linuxdeploy-*.AppImage
@ -481,7 +479,7 @@ jobs:
cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk
cp -r /home/runner/work/PrismLauncher/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines cp -r ${{ runner.workspace }}/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
@ -494,8 +492,25 @@ jobs:
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib"
export LD_LIBRARY_PATH export LD_LIBRARY_PATH
chmod +x AppImageUpdate-x86_64.AppImage
cp AppImageUpdate-x86_64.AppImage ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin
export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|PrismLauncher-Linux-x86_64.AppImage.zsync"
if [ '${{ secrets.GPG_PRIVATE_KEY_ID }}' != '' ]; then
export SIGN=1
export SIGN_KEY=${{ secrets.GPG_PRIVATE_KEY_ID }}
mkdir -p ~/.gnupg/
echo "$GPG_PRIVATE_KEY" > ~/.gnupg/private.key
gpg --import ~/.gnupg/private.key
else
echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
fi
./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.prismlauncher.PrismLauncher.svg ./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.prismlauncher.PrismLauncher.svg
mv "PrismLauncher-Linux-x86_64.AppImage" "PrismLauncher-Linux-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
## ##
# UPLOAD BUILDS # UPLOAD BUILDS
## ##
@ -532,14 +547,14 @@ jobs:
if: runner.os == 'Linux' && matrix.qt_ver != 6 if: runner.os == 'Linux' && matrix.qt_ver != 6
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }} name: PrismLauncher-${{ runner.os }}-Qt5-${{ env.VERSION }}-${{ inputs.build_type }}
path: PrismLauncher.tar.gz path: PrismLauncher.tar.gz
- name: Upload binary tarball (Linux, portable, Qt 5) - name: Upload binary tarball (Linux, portable, Qt 5)
if: runner.os == 'Linux' && matrix.qt_ver != 6 if: runner.os == 'Linux' && matrix.qt_ver != 6
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: PrismLauncher-${{ runner.os }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} name: PrismLauncher-${{ runner.os }}-Qt5-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: PrismLauncher-portable.tar.gz path: PrismLauncher-portable.tar.gz
- name: Upload binary tarball (Linux, Qt 6) - name: Upload binary tarball (Linux, Qt 6)
@ -563,6 +578,13 @@ jobs:
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
path: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage path: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
- name: Upload AppImage Zsync (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5
uses: actions/upload-artifact@v3
with:
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage.zsync
path: PrismLauncher-Linux-x86_64.AppImage.zsync
- name: ccache stats (Windows MinGW-w64) - name: ccache stats (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != '' if: runner.os == 'Windows' && matrix.msystem != ''
shell: msys2 {0} shell: msys2 {0}
@ -576,43 +598,13 @@ jobs:
options: --privileged options: --privileged
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
if: inputs.build_type == 'Debug' if: inputs.build_type == 'Debug'
with: with:
submodules: 'true' submodules: "true"
- name: Build Flatpak (Linux) - name: Build Flatpak (Linux)
if: inputs.build_type == 'Debug' if: inputs.build_type == 'Debug'
uses: flatpak/flatpak-github-actions/flatpak-builder@v6 uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with: with:
bundle: "Prism Launcher.flatpak" bundle: "Prism Launcher.flatpak"
manifest-path: flatpak/org.prismlauncher.PrismLauncher.yml manifest-path: flatpak/org.prismlauncher.PrismLauncher.yml
nix:
runs-on: ubuntu-latest
strategy:
matrix:
package:
- prismlauncher
- prismlauncher-qt5
steps:
- name: Clone repository
if: inputs.build_type == 'Debug'
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Install nix
if: inputs.build_type == 'Debug'
uses: cachix/install-nix-action@v22
with:
install_url: https://nixos.org/nix/install
extra_nix_config: |
auto-optimise-store = true
experimental-features = nix-command flakes
- uses: cachix/cachix-action@v12
if: inputs.build_type == 'Debug'
with:
name: prismlauncher
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build
if: inputs.build_type == 'Debug'
run: nix build .#${{ matrix.package }} --print-build-logs

View File

@ -8,7 +8,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
submodules: 'true' submodules: 'true'

View File

@ -3,26 +3,25 @@ name: Build Application
on: on:
push: push:
branches-ignore: branches-ignore:
- 'renovate/**' - "renovate/**"
paths-ignore: paths-ignore:
- '**.md' - "**.md"
- '**/LICENSE' - "**/LICENSE"
- 'flake.lock' - "flake.lock"
- 'packages/**' - "packages/**"
- '.github/ISSUE_TEMPLATE/**' - ".github/ISSUE_TEMPLATE/**"
- '.markdownlint**' - ".markdownlint**"
pull_request: pull_request:
paths-ignore: paths-ignore:
- '**.md' - "**.md"
- '**/LICENSE' - "**/LICENSE"
- 'flake.lock' - "flake.lock"
- 'packages/**' - "packages/**"
- '.github/ISSUE_TEMPLATE/**' - ".github/ISSUE_TEMPLATE/**"
- '.markdownlint**' - ".markdownlint**"
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build_debug: build_debug:
name: Build Debug name: Build Debug
uses: ./.github/workflows/build.yml uses: ./.github/workflows/build.yml
@ -34,3 +33,5 @@ jobs:
WINDOWS_CODESIGN_CERT: ${{ secrets.WINDOWS_CODESIGN_CERT }} WINDOWS_CODESIGN_CERT: ${{ secrets.WINDOWS_CODESIGN_CERT }}
WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }} WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }}

View File

@ -3,10 +3,9 @@ name: Build Application and Make Release
on: on:
push: push:
tags: tags:
- '*' - "*"
jobs: jobs:
build_release: build_release:
name: Build Release name: Build Release
uses: ./.github/workflows/build.yml uses: ./.github/workflows/build.yml
@ -18,6 +17,8 @@ jobs:
WINDOWS_CODESIGN_CERT: ${{ secrets.WINDOWS_CODESIGN_CERT }} WINDOWS_CODESIGN_CERT: ${{ secrets.WINDOWS_CODESIGN_CERT }}
WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }} WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }}
create_release: create_release:
needs: build_release needs: build_release
@ -26,10 +27,10 @@ jobs:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
submodules: 'true' submodules: "true"
path: 'PrismLauncher-source' path: "PrismLauncher-source"
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
- name: Grab and store version - name: Grab and store version
@ -41,9 +42,10 @@ jobs:
mv ${{ github.workspace }}/PrismLauncher-source PrismLauncher-${{ env.VERSION }} mv ${{ github.workspace }}/PrismLauncher-source PrismLauncher-${{ env.VERSION }}
mv PrismLauncher-Linux-Qt6-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz mv PrismLauncher-Linux-Qt6-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
mv PrismLauncher-Linux-Qt6*/PrismLauncher.tar.gz PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz mv PrismLauncher-Linux-Qt6*/PrismLauncher.tar.gz PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz
mv PrismLauncher-Linux-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Portable-${{ env.VERSION }}.tar.gz mv PrismLauncher-Linux-Qt5-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz
mv PrismLauncher-Linux*/PrismLauncher.tar.gz PrismLauncher-Linux-${{ env.VERSION }}.tar.gz mv PrismLauncher-Linux-Qt5*/PrismLauncher.tar.gz PrismLauncher-Linux-Qt5-${{ env.VERSION }}.tar.gz
mv PrismLauncher-*.AppImage/PrismLauncher-*.AppImage PrismLauncher-Linux-${{ env.VERSION }}-x86_64.AppImage mv PrismLauncher-*.AppImage/PrismLauncher-*.AppImage PrismLauncher-Linux-x86_64.AppImage
mv PrismLauncher-*.AppImage.zsync/PrismLauncher-*.AppImage.zsync PrismLauncher-Linux-x86_64.AppImage.zsync
mv PrismLauncher-macOS-Legacy*/PrismLauncher.tar.gz PrismLauncher-macOS-Legacy-${{ env.VERSION }}.tar.gz mv PrismLauncher-macOS-Legacy*/PrismLauncher.tar.gz PrismLauncher-macOS-Legacy-${{ env.VERSION }}.tar.gz
mv PrismLauncher-macOS*/PrismLauncher.tar.gz PrismLauncher-macOS-${{ env.VERSION }}.tar.gz mv PrismLauncher-macOS*/PrismLauncher.tar.gz PrismLauncher-macOS-${{ env.VERSION }}.tar.gz
@ -78,25 +80,22 @@ jobs:
- name: Create release - name: Create release
id: create_release id: create_release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ github.ref }} tag_name: ${{ github.ref }}
name: Prism Launcher ${{ env.VERSION }} name: Prism Launcher ${{ env.VERSION }}
draft: true draft: true
prerelease: false prerelease: false
files: | files: |
PrismLauncher-Linux-${{ env.VERSION }}.tar.gz PrismLauncher-Linux-Qt5-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-Portable-${{ env.VERSION }}.tar.gz PrismLauncher-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-${{ env.VERSION }}-x86_64.AppImage PrismLauncher-Linux-x86_64.AppImage
PrismLauncher-Linux-x86_64.AppImage.zsync
PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
PrismLauncher-Windows-MinGW-w64-${{ env.VERSION }}.zip PrismLauncher-Windows-MinGW-w64-${{ env.VERSION }}.zip
PrismLauncher-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip PrismLauncher-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip
PrismLauncher-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe PrismLauncher-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe
PrismLauncher-Windows-MSVC-Legacy-${{ env.VERSION }}.zip
PrismLauncher-Windows-MSVC-Legacy-Portable-${{ env.VERSION }}.zip
PrismLauncher-Windows-MSVC-Legacy-Setup-${{ env.VERSION }}.exe
PrismLauncher-Windows-MSVC-arm64-${{ env.VERSION }}.zip PrismLauncher-Windows-MSVC-arm64-${{ env.VERSION }}.zip
PrismLauncher-Windows-MSVC-arm64-Portable-${{ env.VERSION }}.zip PrismLauncher-Windows-MSVC-arm64-Portable-${{ env.VERSION }}.zip
PrismLauncher-Windows-MSVC-arm64-Setup-${{ env.VERSION }}.exe PrismLauncher-Windows-MSVC-arm64-Setup-${{ env.VERSION }}.exe

View File

@ -7,20 +7,24 @@ on:
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: write
pull-requests: write pull-requests: write
jobs: jobs:
update-flake: update-flake:
if: github.repository == 'PrismLauncher/PrismLauncher'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@6a9a9e84a173d90b3ffb42c5ddaf9ea033fad011 # v23
- uses: DeterminateSystems/update-flake-lock@v19 - uses: DeterminateSystems/update-flake-lock@v20
with: with:
commit-msg: "chore(nix): update lockfile" commit-msg: "chore(nix): update lockfile"
pr-title: "chore(nix): update lockfile" pr-title: "chore(nix): update lockfile"
pr-labels: | pr-labels: |
Linux Linux
packaging
simple change simple change
changelog:omit

3
.gitmodules vendored
View File

@ -19,3 +19,6 @@
[submodule "libraries/cmark"] [submodule "libraries/cmark"]
path = libraries/cmark path = libraries/cmark
url = https://github.com/commonmark/cmark.git url = https://github.com/commonmark/cmark.git
[submodule "flatpak/shared-modules"]
path = flatpak/shared-modules
url = https://github.com/flathub/shared-modules.git

View File

@ -33,6 +33,13 @@ if(MSVC)
# Use /W4 as /Wall includes unnesserey warnings such as added padding to structs # Use /W4 as /Wall includes unnesserey warnings such as added padding to structs
set(CMAKE_CXX_FLAGS "/GS /permissive- /W4 ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "/GS /permissive- /W4 ${CMAKE_CXX_FLAGS}")
# /EHs Enables stack unwind semantics for standard C++ exceptions to ensure stackframes are unwound
# and object deconstructors are called when an exception is caught.
# without it memory leaks and a warning is printed
# /EHc tells the compiler to assume that functions declared as extern "C" never throw a C++ exception
# This appears to not always be a defualt compiler option in CMAKE
set(CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}")
# LINK accepts /SUBSYSTEM whics sets if we are a WINDOWS (gui) or a CONSOLE programs # LINK accepts /SUBSYSTEM whics sets if we are a WINDOWS (gui) or a CONSOLE programs
# This implicitly selects an entrypoint specific to the subsystem selected # This implicitly selects an entrypoint specific to the subsystem selected
# qtmain/QtEntryPointLib provides the correct entrypoint (wWinMain) for gui programs # qtmain/QtEntryPointLib provides the correct entrypoint (wWinMain) for gui programs
@ -85,6 +92,39 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0")
# set CXXFLAGS for build targets # set CXXFLAGS for build targets
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}")
option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" OFF)
# If this is a Debug build turn on address sanitiser
if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") AND DEBUG_ADDRESS_SANITIZER)
message(STATUS "Address Sanitizer enabled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
# using clang with clang-cl front end
message(STATUS "Address Sanitizer available on Clang MSVC frontend")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /Oy-")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /Oy-")
else()
# AppleClang and Clang
message(STATUS "Address Sanitizer available on Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# GCC
message(STATUS "Address Sanitizer available on GCC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
link_libraries("asan")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "Address Sanitizer available on MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /Oy-")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /Oy-")
else()
message(STATUS "Address Sanitizer not available on compiler ${CMAKE_CXX_COMPILER_ID}")
endif()
endif()
option(ENABLE_LTO "Enable Link Time Optimization" off) option(ENABLE_LTO "Enable Link Time Optimization" off)
if(ENABLE_LTO) if(ENABLE_LTO)
@ -146,10 +186,13 @@ set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.
set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},0,0") set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},0,0")
# Build platform. # Build platform.
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.") set(Launcher_BUILD_PLATFORM "unknown" 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 # Github repo URL with releases for updater
set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") set(Launcher_UPDATER_GITHUB_REPO "https://github.com/PrismLauncher/PrismLauncher" CACHE STRING "Base github URL for the updater.")
# Name to help updater identify valid artifacts
set(Launcher_BUILD_ARTIFACT "" CACHE STRING "Artifact name to help the updater identify valid artifacts.")
# The metadata server # The metadata server
set(Launcher_META_URL "https://meta.prismlauncher.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") set(Launcher_META_URL "https://meta.prismlauncher.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.")
@ -176,6 +219,18 @@ set(Launcher_SUBREDDIT_URL "https://prismlauncher.org/reddit" CACHE STRING "URL
set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, if they are available as submodules") set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, if they are available as submodules")
set(Launcher_QT_VERSION_MAJOR "6" CACHE STRING "Major Qt version to build against") set(Launcher_QT_VERSION_MAJOR "6" CACHE STRING "Major Qt version to build against")
# Native libraries
if(UNIX AND APPLE)
set(Launcher_GLFW_LIBRARY_NAME "libglfw.dylib" CACHE STRING "Name of native glfw library")
set(Launcher_OPENAL_LIBRARY_NAME "libopenal.dylib" CACHE STRING "Name of native openal library")
elseif(UNIX)
set(Launcher_GLFW_LIBRARY_NAME "libglfw.so" CACHE STRING "Name of native glfw library")
set(Launcher_OPENAL_LIBRARY_NAME "libopenal.so" CACHE STRING "Name of native openal library")
elseif(WIN32)
set(Launcher_GLFW_LIBRARY_NAME "glfw.dll" CACHE STRING "Name of native glfw library")
set(Launcher_OPENAL_LIBRARY_NAME "OpenAL.dll" CACHE STRING "Name of native openal library")
endif()
# API Keys # API Keys
# NOTE: These API keys are here for convenience. If you rebrand this software or intend to break the terms of service # NOTE: These API keys are here for convenience. If you rebrand this software or intend to break the terms of service
# of these platforms, please change these API keys beforehand. # of these platforms, please change these API keys beforehand.
@ -193,6 +248,11 @@ set(Launcher_MSA_CLIENT_ID "c36a9fb6-4f2a-41ff-90bd-ae7cc92031eb" CACHE STRING "
# This key was issued specifically for Prism Launcher # This key was issued specifically for Prism Launcher
set(Launcher_CURSEFORGE_API_KEY "$2a$10$wuAJuNZuted3NORVmpgUC.m8sI.pv1tOPKZyBgLFGjxFp/br0lZCC" CACHE STRING "API key for the CurseForge platform") set(Launcher_CURSEFORGE_API_KEY "$2a$10$wuAJuNZuted3NORVmpgUC.m8sI.pv1tOPKZyBgLFGjxFp/br0lZCC" CACHE STRING "API key for the CurseForge platform")
set(Launcher_COMPILER_NAME ${CMAKE_CXX_COMPILER_ID})
set(Launcher_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})
set(Launcher_COMPILER_TARGET_SYSTEM ${CMAKE_SYSTEM_NAME})
set(Launcher_COMPILER_TARGET_SYSTEM_VERSION ${CMAKE_SYSTEM_VERSION})
set(Launcher_COMPILER_TARGET_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR})
#### Check the current Git commit and branch #### Check the current Git commit and branch
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
@ -286,6 +346,13 @@ add_subdirectory(program_info)
####################################### Install layout ####################################### ####################################### Install layout #######################################
set(Launcher_ENABLE_UPDATER NO)
set(Launcher_BUILD_UPDATER NO)
if (NOT APPLE AND (NOT Launcher_UPDATER_GITHUB_REPO STREQUAL "" AND NOT Launcher_BUILD_ARTIFACT STREQUAL ""))
set(Launcher_BUILD_UPDATER YES)
endif()
if(NOT (UNIX AND APPLE)) if(NOT (UNIX AND APPLE))
# Install "portable.txt" if selected component is "portable" # Install "portable.txt" if selected component is "portable"
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION "." COMPONENT portable EXCLUDE_FROM_ALL) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION "." COMPONENT portable EXCLUDE_FROM_ALL)
@ -310,9 +377,9 @@ if(UNIX AND APPLE)
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}")
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}") set(MACOSX_BUNDLE_COPYRIGHT "© 2022-2023 ${Launcher_Copyright_Mac}")
set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=" CACHE STRING "Public key for Sparkle update feed")
set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml" CACHE STRING "URL for Sparkle update feed")
set(MACOSX_SPARKLE_DOWNLOAD_URL "https://github.com/sparkle-project/Sparkle/releases/download/2.1.0/Sparkle-2.1.0.tar.xz" CACHE STRING "URL to Sparkle release archive") set(MACOSX_SPARKLE_DOWNLOAD_URL "https://github.com/sparkle-project/Sparkle/releases/download/2.1.0/Sparkle-2.1.0.tar.xz" CACHE STRING "URL to Sparkle release archive")
set(MACOSX_SPARKLE_SHA256 "bf6ac1caa9f8d321d5784859c88da874f28412f37fb327bc21b7b14c5d61ef94" CACHE STRING "SHA256 checksum for Sparkle release archive") set(MACOSX_SPARKLE_SHA256 "bf6ac1caa9f8d321d5784859c88da874f28412f37fb327bc21b7b14c5d61ef94" CACHE STRING "SHA256 checksum for Sparkle release archive")
@ -321,8 +388,12 @@ if(UNIX AND APPLE)
# 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} ${MACOSX_SPARKLE_DIR}) set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${MACOSX_SPARKLE_DIR})
if(NOT MACOSX_SPARKLE_UPDATE_PUBLIC_KEY STREQUAL "" AND NOT MACOSX_SPARKLE_UPDATE_FEED_URL STREQUAL "")
set(Launcher_ENABLE_UPDATER YES)
endif()
# install as bundle # install as bundle
set(INSTALL_BUNDLE "full") set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies")
# 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)
@ -332,10 +403,10 @@ elseif(UNIX)
set(BINARY_DEST_DIR "bin") set(BINARY_DEST_DIR "bin")
set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(JARS_DEST_DIR "share/${Launcher_APP_BINARY_NAME}") set(JARS_DEST_DIR "share/${Launcher_Name}")
# install as bundle with no dependencies included # install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps") set(INSTALL_BUNDLE "nodeps" CACHE STRING "Use fixup_bundle to bundle dependencies")
# Set RPATH # Set RPATH
SET(Launcher_BINARY_RPATH "$ORIGIN/") SET(Launcher_BINARY_RPATH "$ORIGIN/")
@ -345,7 +416,7 @@ elseif(UNIX)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_mrpack_MIMEInfo} DESTINATION ${KDE_INSTALL_MIMEDIR}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_mrpack_MIMEInfo} DESTINATION ${KDE_INSTALL_MIMEDIR})
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "${KDE_INSTALL_DATADIR}/${Launcher_Name}") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "share/${Launcher_Name}")
if(Launcher_ManPage) if(Launcher_ManPage)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION "${KDE_INSTALL_MANDIR}/man6") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION "${KDE_INSTALL_MANDIR}/man6")
@ -369,7 +440,7 @@ elseif(WIN32)
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})
# install as bundle # install as bundle
set(INSTALL_BUNDLE "full") set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies")
else() else()
message(FATAL_ERROR "Platform not supported") message(FATAL_ERROR "Platform not supported")
endif() endif()

View File

@ -19,7 +19,7 @@ In an effort to ensure that the code you contribute is actually compatible with
This can be done by appending `-s` to your `git commit` call, or by manually appending the following text to your commit message: This can be done by appending `-s` to your `git commit` call, or by manually appending the following text to your commit message:
``` ```text
<commit message> <commit message>
Signed-off-by: Author name <Author email> Signed-off-by: Author name <Author email>
@ -27,7 +27,7 @@ Signed-off-by: Author name <Author email>
By signing off your work, you agree to the terms below: By signing off your work, you agree to the terms below:
``` ```text
Developer's Certificate of Origin 1.1 Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that: By making a contribution to this project, I certify that:
@ -61,3 +61,9 @@ As a bonus, you can also [cryptographically sign your commits][gh-signing-commit
[gh-signing-commits]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits [gh-signing-commits]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
[gh-vigilant-mode]: https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits [gh-vigilant-mode]: https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits
## Backporting to Release Branches
We use [automated backports](https://github.com/PrismLauncher/PrismLauncher/blob/develop/.github/workflows/backport.yml) to merge specific contributions from develop into `release` branches.
This is done when pull requests are merged and have labels such as `backport release-7.x` - which should be added along with the milestone for the release.

View File

@ -18,11 +18,18 @@
</a> </a>
- All downloads and instructions for Prism Launcher can be found on our [Website](https://prismlauncher.org/download). - All downloads and instructions for Prism Launcher can be found on our [Website](https://prismlauncher.org/download).
- Last build status can be found in the [GitHub Actions](https://github.com/PrismLauncher/PrismLauncher/actions). - Last build status can be found in the [GitHub Actions](https://github.com/PrismLauncher/PrismLauncher/actions) tab (this also includes the pull requests status).
### Development Builds ### Development Builds
There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. Please understand that these builds are not intended for most users. There may be bugs, and other instabilities. You have been warned.
There are development builds available through:
- [GitHub Actions](https://github.com/PrismLauncher/PrismLauncher/actions) (includes builds from pull requests opened by contribuitors)
- [nightly.link](https://nightly.link/PrismLauncher/PrismLauncher/workflows/trigger_builds/develop) (this will always point only to the latest version of develop)
These have debug information in the binaries, so their file sizes are relatively larger.
Prebuilt Development builds are provided for **Linux**, **Windows** and **macOS**. Prebuilt Development builds are provided for **Linux**, **Windows** and **macOS**.
@ -30,7 +37,7 @@ For **Arch**, **Debian**, **Fedora**, **OpenSUSE (Tumbleweed)** and **Gentoo**,
[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?label=MPR&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git)<br />[![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?label=COPR&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?label=Gentoo&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?label=MPR&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git)<br />[![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?label=COPR&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?label=Gentoo&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher)
These packages are also availiable to all the distributions based on the ones mentioned above. These packages are also available to all the distributions based on the ones mentioned above.
## Community & Support ## Community & Support
@ -42,7 +49,7 @@ Feel free to create a GitHub issue if you find a bug or want to suggest a new fe
- **Our Matrix space:** - **Our Matrix space:**
[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&label=Matrix%20Space&logo=matrix&color=purple)](https://prismlauncher.org/matrix) [![Prism Launcher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&label=Matrix%20Space&logo=matrix&color=purple)](https://prismlauncher.org/matrix)
- **Our Subreddit:** - **Our Subreddit:**
@ -50,7 +57,7 @@ Feel free to create a GitHub issue if you find a bug or want to suggest a new fe
## Translations ## Translations
The translation effort for PrismLauncher is hosted on [Weblate](https://hosted.weblate.org/projects/prismlauncher/launcher/) and information about translating Prism Launcher is available at <https://github.com/PrismLauncher/Translations> The translation effort for Prism Launcher is hosted on [Weblate](https://hosted.weblate.org/projects/prismlauncher/launcher/) and information about translating Prism Launcher is available at <https://github.com/PrismLauncher/Translations>.
## Building ## Building
@ -82,14 +89,16 @@ Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/),
## Forking/Redistributing/Custom builds policy ## Forking/Redistributing/Custom builds policy
We don't care what you do with your fork/custom build as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: You are free to fork, redistribute and provide custom builds as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy:
- Make it clear that your fork is not PrismLauncher and is not endorsed by or affiliated with the PrismLauncher project (<https://prismlauncher.org>). - Make it clear that your fork is not Prism Launcher and is not endorsed by or affiliated with the Prism Launcher project (<https://prismlauncher.org>).
- Go through [CMakeLists.txt](CMakeLists.txt) and change PrismLauncher's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled). - Go through [CMakeLists.txt](CMakeLists.txt) and change Prism Launcher's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled).
If you have any questions or want any clarification on the above conditions please make an issue and ask us. If you have any questions or want any clarification on the above conditions please make an issue and ask us.
Be aware that if you build this software without removing the provided API keys in [CMakeLists.txt](CMakeLists.txt) you are accepting the following terms and conditions: If you are just building Prism Launcher for your distribution, please make sure to set the `Launcher_BUILD_PLATFORM` to a slug representing your distribution. Examples are `archlinux`, `fedora` and `nixpkgs`.
Note that if you build this software without removing the provided API keys in [CMakeLists.txt](CMakeLists.txt) you are accepting the following terms and conditions:
- [Microsoft Identity Platform Terms of Use](https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use) - [Microsoft Identity Platform Terms of Use](https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use)
- [CurseForge 3rd Party API Terms and Conditions](https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions) - [CurseForge 3rd Party API Terms and Conditions](https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions)

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -33,6 +33,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <qstringliteral.h>
#include "BuildConfig.h" #include "BuildConfig.h"
#include <QObject> #include <QObject>
@ -59,15 +60,25 @@ Config::Config()
VERSION_MINOR = @Launcher_VERSION_MINOR@; VERSION_MINOR = @Launcher_VERSION_MINOR@;
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
BUILD_ARTIFACT = "@Launcher_BUILD_ARTIFACT@";
BUILD_DATE = "@Launcher_BUILD_TIMESTAMP@"; BUILD_DATE = "@Launcher_BUILD_TIMESTAMP@";
UPDATER_BASE = "@Launcher_UPDATER_BASE@"; UPDATER_GITHUB_REPO = "@Launcher_UPDATER_GITHUB_REPO@";
COMPILER_NAME = "@Launcher_COMPILER_NAME@";
COMPILER_VERSION = "@Launcher_COMPILER_VERSION@";
COMPILER_TARGET_SYSTEM = "@Launcher_COMPILER_TARGET_SYSTEM@";
COMPILER_TARGET_SYSTEM_VERSION = "@Launcher_COMPILER_TARGET_SYSTEM_VERSION@";
COMPILER_TARGET_SYSTEM_PROCESSOR = "@Launcher_COMPILER_TARGET_PROCESSOR@";
MAC_SPARKLE_PUB_KEY = "@MACOSX_SPARKLE_UPDATE_PUBLIC_KEY@"; MAC_SPARKLE_PUB_KEY = "@MACOSX_SPARKLE_UPDATE_PUBLIC_KEY@";
MAC_SPARKLE_APPCAST_URL = "@MACOSX_SPARKLE_UPDATE_FEED_URL@"; MAC_SPARKLE_APPCAST_URL = "@MACOSX_SPARKLE_UPDATE_FEED_URL@";
if (BUILD_PLATFORM == "macOS" && !MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty()) if (!MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty())
{ {
UPDATER_ENABLED = true; UPDATER_ENABLED = true;
} else if(!UPDATER_GITHUB_REPO.isEmpty() && !BUILD_ARTIFACT.isEmpty()) {
UPDATER_ENABLED = true;
} }
GIT_COMMIT = "@Launcher_GIT_COMMIT@"; GIT_COMMIT = "@Launcher_GIT_COMMIT@";
@ -89,9 +100,6 @@ Config::Config()
{ {
VERSION_CHANNEL = GIT_REFSPEC; VERSION_CHANNEL = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/"); VERSION_CHANNEL.remove("refs/heads/");
if(!UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty()) {
UPDATER_ENABLED = true;
}
} }
else if (!GIT_COMMIT.isEmpty()) else if (!GIT_COMMIT.isEmpty())
{ {
@ -110,6 +118,9 @@ Config::Config()
FLAME_API_KEY = "@Launcher_CURSEFORGE_API_KEY@"; FLAME_API_KEY = "@Launcher_CURSEFORGE_API_KEY@";
META_URL = "@Launcher_META_URL@"; META_URL = "@Launcher_META_URL@";
GLFW_LIBRARY_NAME = "@Launcher_GLFW_LIBRARY_NAME@";
OPENAL_LIBRARY_NAME = "@Launcher_OPENAL_LIBRARY_NAME@";
BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@";
TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@"; TRANSLATIONS_URL = "@Launcher_TRANSLATIONS_URL@";
MATRIX_URL = "@Launcher_MATRIX_URL@"; MATRIX_URL = "@Launcher_MATRIX_URL@";
@ -133,3 +144,16 @@ QString Config::printableVersionString() const
} }
return vstr; return vstr;
} }
QString Config::compilerID() const
{
if (COMPILER_VERSION.isEmpty())
return COMPILER_NAME;
return QStringLiteral("%1 - %2").arg(COMPILER_NAME).arg(COMPILER_VERSION);
}
QString Config::systemID() const
{
return QStringLiteral("%1 %2 %3").arg(COMPILER_TARGET_SYSTEM, COMPILER_TARGET_SYSTEM_VERSION, COMPILER_TARGET_SYSTEM_PROCESSOR);
}

View File

@ -36,8 +36,8 @@
*/ */
#pragma once #pragma once
#include <QString>
#include <QList> #include <QList>
#include <QString>
/** /**
* \brief The Config class holds all the build-time information passed from the build system. * \brief The Config class holds all the build-time information passed from the build system.
@ -68,14 +68,32 @@ class Config {
bool UPDATER_ENABLED = false; bool UPDATER_ENABLED = false;
/// A short string identifying this build's platform. For example, "lin64" or "win32". /// A short string identifying this build's platform or distribution.
QString BUILD_PLATFORM; QString BUILD_PLATFORM;
/// A short string identifying this build's valid artifacts int he updater. For example, "lin64" or "win32".
QString BUILD_ARTIFACT;
/// A string containing the build timestamp /// A string containing the build timestamp
QString BUILD_DATE; QString BUILD_DATE;
/// A string identifying the compiler use to build
QString COMPILER_NAME;
/// A string identifying the compiler version used to build
QString COMPILER_VERSION;
/// A string identifying the compiler target system os
QString COMPILER_TARGET_SYSTEM;
/// A String identifying the compiler target system version
QString COMPILER_TARGET_SYSTEM_VERSION;
/// A String identifying the compiler target processor
QString COMPILER_TARGET_SYSTEM_PROCESSOR;
/// URL for the updater's channel /// URL for the updater's channel
QString UPDATER_BASE; QString UPDATER_GITHUB_REPO;
/// The public key used to sign releases for the Sparkle updater appcast /// The public key used to sign releases for the Sparkle updater appcast
QString MAC_SPARKLE_PUB_KEY; QString MAC_SPARKLE_PUB_KEY;
@ -134,6 +152,9 @@ class Config {
*/ */
QString META_URL; QString META_URL;
QString GLFW_LIBRARY_NAME;
QString OPENAL_LIBRARY_NAME;
QString BUG_TRACKER_URL; QString BUG_TRACKER_URL;
QString TRANSLATIONS_URL; QString TRANSLATIONS_URL;
QString MATRIX_URL; QString MATRIX_URL;
@ -145,7 +166,7 @@ class Config {
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.prismlauncher.org/fmllibs/"; // FIXME: move into CMakeLists QString FMLLIBS_BASE_URL = "https://files.prismlauncher.org/fmllibs/"; // FIXME: move into CMakeLists
QString TRANSLATIONS_BASE_URL = "https://i18n.prismlauncher.org/"; // FIXME: move into CMakeLists QString TRANSLATIONS_BASE_URL = "https://i18n.prismlauncher.org/"; // FIXME: move into CMakeLists
QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/"; QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/";
@ -162,7 +183,7 @@ class Config {
QString MODRINTH_STAGING_URL = "https://staging-api.modrinth.com/v2"; QString MODRINTH_STAGING_URL = "https://staging-api.modrinth.com/v2";
QString MODRINTH_PROD_URL = "https://api.modrinth.com/v2"; QString MODRINTH_PROD_URL = "https://api.modrinth.com/v2";
QStringList MODRINTH_MRPACK_HOSTS{"cdn.modrinth.com", "github.com", "raw.githubusercontent.com", "gitlab.com"}; QStringList MODRINTH_MRPACK_HOSTS{ "cdn.modrinth.com", "github.com", "raw.githubusercontent.com", "gitlab.com" };
QString FLAME_BASE_URL = "https://api.curseforge.com/v1"; QString FLAME_BASE_URL = "https://api.curseforge.com/v1";
@ -172,6 +193,18 @@ class Config {
* \return The version number in string format (major.minor.revision.build). * \return The version number in string format (major.minor.revision.build).
*/ */
QString printableVersionString() const; QString printableVersionString() const;
/**
* \brief Compiler ID String
* \return a string of the form "Name - Version" of just "Name" if the version is empty
*/
QString compilerID() const;
/**
* \brief System ID String
* \return a string of the form "OS Verison Processor"
*/
QString systemID() const;
}; };
extern const Config BuildConfig; extern const Config BuildConfig;

View File

@ -0,0 +1,155 @@
#
# Function to set compiler warnings with reasonable defaults at the project level.
# Taken from https://github.com/aminya/project_options/blob/main/src/CompilerWarnings.cmake
# under the folowing license:
#
# MIT License
#
# Copyright (c) 2022-2100 Amin Yahyaabadi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
include_guard()
function(_set_project_warnings_add_target_link_option TARGET OPTIONS)
target_link_options(${_project_name} INTERFACE ${OPTIONS})
endfunction()
# Set the compiler warnings
#
# https://clang.llvm.org/docs/DiagnosticsReference.html
# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md
function(
set_project_warnings
_project_name
MSVC_WARNINGS
CLANG_WARNINGS
GCC_WARNINGS
)
if("${MSVC_WARNINGS}" STREQUAL "")
set(MSVC_WARNINGS
/W4 # Baseline reasonable warnings
/w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data
/w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/w14263 # 'function': member function does not override any base class virtual member function
/w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not
# be destructed correctly
/w14287 # 'operator': unsigned/negative constant mismatch
/we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside
# the for-loop scope
/w14296 # 'operator': expression is always 'boolean_value'
/w14311 # 'variable': pointer truncation from 'type1' to 'type2'
/w14545 # expression before comma evaluates to a function which is missing an argument list
/w14546 # function call before comma missing argument list
/w14547 # 'operator': operator before comma has no effect; expected operator with side-effect
/w14549 # 'operator': operator before comma has no effect; did you intend 'operator'?
/w14555 # expression has no effect; expected expression with side- effect
/w14619 # pragma warning: there is no warning number 'number'
/w14640 # Enable warning on thread un-safe static member initialization
/w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
/w14905 # wide string literal cast to 'LPSTR'
/w14906 # string literal cast to 'LPWSTR'
/w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
/permissive- # standards conformance mode for MSVC compiler.
)
endif()
if("${CLANG_WARNINGS}" STREQUAL "")
set(CLANG_WARNINGS
-Wall
-Wextra # reasonable and standard
-Wshadow # warn the user if a variable declaration shadows one from a parent context
-Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps
# catch hard to track down memory errors
-Wold-style-cast # warn for c-style casts
-Wcast-align # warn for potential performance problem casts
-Wunused # warn on anything being unused
-Woverloaded-virtual # warn if you overload (not override) a virtual function
-Wpedantic # warn if non-standard C++ is used
-Wconversion # warn on type conversions that may lose data
-Wsign-conversion # warn on sign conversions
-Wnull-dereference # warn if a null dereference is detected
-Wdouble-promotion # warn if float is implicit promoted to double
-Wformat=2 # warn on security issues around functions that format output (ie printf)
-Wimplicit-fallthrough # warn on statements that fallthrough without an explicit annotation
# -Wgnu-zero-variadic-macro-arguments (part of -pedantic) is triggered by every qCDebug() call and therefore results
# in a lot of noise. This warning is only notifying us that clang is emulating the GCC behaviour
# instead of the exact standard wording so we can safely ignore it
-Wno-gnu-zero-variadic-macro-arguments
)
endif()
if("${GCC_WARNINGS}" STREQUAL "")
set(GCC_WARNINGS
${CLANG_WARNINGS}
-Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist
-Wduplicated-cond # warn if if / else chain has duplicated conditions
-Wduplicated-branches # warn if if / else branches have duplicated code
-Wlogical-op # warn about logical operations being used where bitwise were probably wanted
-Wuseless-cast # warn if you perform a cast to the same type
)
endif()
if(MSVC)
set(PROJECT_WARNINGS_CXX ${MSVC_WARNINGS})
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
set(PROJECT_WARNINGS_CXX ${CLANG_WARNINGS})
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(PROJECT_WARNINGS_CXX ${GCC_WARNINGS})
else()
message(AUTHOR_WARNING "No compiler warnings set for CXX compiler: '${CMAKE_CXX_COMPILER_ID}'")
# TODO support Intel compiler
endif()
# Add C warnings
set(PROJECT_WARNINGS_C "${PROJECT_WARNINGS_CXX}")
list(
REMOVE_ITEM
PROJECT_WARNINGS_C
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wuseless-cast
-Wextra-semi
)
target_compile_options(
${_project_name}
INTERFACE # C++ warnings
$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_WARNINGS_CXX}>
# C warnings
$<$<COMPILE_LANGUAGE:C>:${PROJECT_WARNINGS_C}>
)
# If we are using the compiler as a linker driver pass the warnings to it
# (most useful when using LTO or warnings as errors)
if(CMAKE_CXX_LINK_EXECUTABLE MATCHES "^<CMAKE_CXX_COMPILER>")
_set_project_warnings_add_target_link_option(
${_project_name} "$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_WARNINGS_CXX}>"
)
endif()
if(CMAKE_C_LINK_EXECUTABLE MATCHES "^<CMAKE_C_COMPILER>")
_set_project_warnings_add_target_link_option(
${_project_name} "$<$<COMPILE_LANGUAGE:C>:${PROJECT_WARNINGS_C}>"
)
endif()
endfunction()

View File

@ -67,5 +67,16 @@
<string>Alternate</string> <string>Alternate</string>
</dict> </dict>
</array> </array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Curseforge</string>
<key>CFBundleURLSchemes</key>
<array>
<string>curseforge</string>
</array>
</dict>
</array>
</dict> </dict>
</plist> </plist>

52
flake.lock generated
View File

@ -3,11 +3,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1673956053, "lastModified": 1696426674,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -21,11 +21,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1688254665, "lastModified": 1698882062,
"narHash": "sha256-8FHEgBrr7gYNiS/NzCxIO3m4hvtLRW9YY1nYo1ivm3o=", "narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "267149c58a14d15f7f81b4d737308421de9d7152", "rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -76,11 +76,11 @@
"libnbtplusplus": { "libnbtplusplus": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1650031308, "lastModified": 1690036783,
"narHash": "sha256-TvVOjkUobYJD9itQYueELJX3wmecvEdCbJ0FinW2mL4=", "narHash": "sha256-A5kTgICnx+Qdq3Fir/bKTfdTt/T1NQP2SC+nhN1ENug=",
"owner": "PrismLauncher", "owner": "PrismLauncher",
"repo": "libnbtplusplus", "repo": "libnbtplusplus",
"rev": "2203af7eeb48c45398139b583615134efd8d407f", "rev": "a5e8fd52b8bf4ab5d5bcc042b2a247867589985f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -89,13 +89,28 @@
"type": "github" "type": "github"
} }
}, },
"nix-filter": {
"locked": {
"lastModified": 1694857738,
"narHash": "sha256-bxxNyLHjhu0N8T3REINXQ2ZkJco0ABFPn6PIe2QUfqo=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "41fd48e00c22b4ced525af521ead8792402de0ea",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-filter",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1688221086, "lastModified": 1699094435,
"narHash": "sha256-cdW6qUL71cNWhHCpMPOJjlw0wzSRP0pVlRn2vqX/VVg=", "narHash": "sha256-YLZ5/KKZ1PyLrm2MO8UxRe4H3M0/oaYqNhSlq6FDeeA=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "cd99c2b3c9f160cd004318e0697f90bbd5960825", "rev": "9d5d25bbfe8c0297ebe85324addcb5020ed1a454",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -108,11 +123,11 @@
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"lastModified": 1688049487, "lastModified": 1698611440,
"narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", "narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", "rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -138,11 +153,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1688386108, "lastModified": 1698852633,
"narHash": "sha256-Vffto9QaVonzYAcPlAzd0soqWYpPpKk60dfNLSIXcFA=", "narHash": "sha256-Hsc/cCHud8ZXLvmm8pxrXpuaPEeNaaUttaCvtdX/Wug=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "42587d3414d1747999a5f71e92a83cf6547b62da", "rev": "dec10399e5b56aa95fcd530e0338be72ad6462a0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -156,6 +171,7 @@
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"libnbtplusplus": "libnbtplusplus", "libnbtplusplus": "libnbtplusplus",
"nix-filter": "nix-filter",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks" "pre-commit-hooks": "pre-commit-hooks"
} }

View File

@ -4,6 +4,7 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
nix-filter.url = "github:numtide/nix-filter";
pre-commit-hooks = { pre-commit-hooks = {
url = "github:cachix/pre-commit-hooks.nix"; url = "github:cachix/pre-commit-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -20,8 +21,24 @@
}; };
}; };
outputs = inputs: outputs = {
inputs.flake-parts.lib.mkFlake flake-parts,
{inherit inputs;} pre-commit-hooks,
{imports = [./nix];}; ...
} @ inputs:
flake-parts.lib.mkFlake {inherit inputs;} {
imports = [
pre-commit-hooks.flakeModule
./nix/dev.nix
./nix/distribution.nix
];
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
};
} }

22
flatpak/libdecor.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "libdecor",
"buildsystem": "meson",
"config-opts": [
"-Ddemo=false"
],
"sources": [
{
"type": "git",
"url": "https://gitlab.freedesktop.org/libdecor/libdecor.git",
"commit": "73260393a97291c887e1074ab7f318e031be0ac6"
},
{
"type": "patch",
"path": "patches/weird_libdecor.patch"
}
],
"cleanup": [
"/include",
"/lib/pkgconfig"
]
}

View File

@ -5,13 +5,6 @@ sdk: org.kde.Sdk
sdk-extensions: sdk-extensions:
- org.freedesktop.Sdk.Extension.openjdk17 - org.freedesktop.Sdk.Extension.openjdk17
- org.freedesktop.Sdk.Extension.openjdk8 - org.freedesktop.Sdk.Extension.openjdk8
add-extensions:
com.valvesoftware.Steam.Utility.gamescope:
version: stable
add-ld-path: lib
no-autodownload: true
autodelete: false
directory: utils/gamescope
command: prismlauncher command: prismlauncher
finish-args: finish-args:
@ -25,22 +18,34 @@ finish-args:
- --filesystem=xdg-run/app/com.discordapp.Discord:create - --filesystem=xdg-run/app/com.discordapp.Discord:create
# Mod drag&drop # Mod drag&drop
- --filesystem=xdg-download:ro - --filesystem=xdg-download:ro
# FTBApp import
- --filesystem=~/.ftba:ro
cleanup:
- /lib/libGLU*
modules: modules:
# Might be needed by some Controller mods (see https://github.com/isXander/Controlify/issues/31)
- shared-modules/libusb/libusb.json
# Needed for proper Wayland support
- libdecor.json
- name: prismlauncher - name: prismlauncher
buildsystem: cmake-ninja buildsystem: cmake-ninja
builddir: true
config-opts: config-opts:
- -DLauncher_BUILD_PLATFORM=flatpak - -DLauncher_BUILD_PLATFORM=flatpak
- -DCMAKE_BUILD_TYPE=Debug - -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DLauncher_QT_VERSION_MAJOR=5 - -DLauncher_QT_VERSION_MAJOR=5
build-options: build-options:
env: env:
JAVA_HOME: /usr/lib/sdk/openjdk17/jvm/openjdk-17 JAVA_HOME: /usr/lib/sdk/openjdk17/jvm/openjdk-17
JAVA_COMPILER: /usr/lib/sdk/openjdk17/jvm/openjdk-17/bin/javac JAVA_COMPILER: /usr/lib/sdk/openjdk17/jvm/openjdk-17/bin/javac
sources: sources:
- type: dir - type: dir
path: ../ path: ../
builddir: true
- name: openjdk - name: openjdk
buildsystem: simple buildsystem: simple
build-commands: build-commands:
@ -49,14 +54,45 @@ modules:
- mv /app/jre /app/jdk/17 - mv /app/jre /app/jdk/17
- /usr/lib/sdk/openjdk8/install.sh - /usr/lib/sdk/openjdk8/install.sh
- mv /app/jre /app/jdk/8 - mv /app/jre /app/jdk/8
cleanup: [/jre] cleanup:
- /jre
- name: glfw
buildsystem: cmake-ninja
config-opts:
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DBUILD_SHARED_LIBS:BOOL=ON
- -DGLFW_USE_WAYLAND=ON
sources:
- type: git
url: https://github.com/glfw/glfw.git
commit: 3fa2360720eeba1964df3c0ecf4b5df8648a8e52
- type: patch
path: patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch
- type: patch
path: patches/0005-Add-warning-about-being-an-unofficial-patch.patch
- type: patch
path: patches/0007-Platform-Prefer-Wayland-over-X11.patch
cleanup:
- /include
- /lib/cmake
- /lib/pkgconfig
- name: xrandr - name: xrandr
buildsystem: autotools buildsystem: autotools
sources: sources:
- type: archive - type: archive
url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.1.tar.xz url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.2.tar.xz
sha256: 7bc76daf9d72f8aff885efad04ce06b90488a1a169d118dea8a2b661832e8762 sha256: c8bee4790d9058bacc4b6246456c58021db58a87ddda1a9d0139bf5f18f1f240
cleanup: [/share/man, /bin/xkeystone] x-checker-data:
type: anitya
project-id: 14957
stable-only: true
url-template: https://xorg.freedesktop.org/archive/individual/app/xrandr-$version.tar.xz
cleanup:
- /share/man
- /bin/xkeystone
- name: gamemode - name: gamemode
buildsystem: meson buildsystem: meson
config-opts: config-opts:
@ -67,19 +103,56 @@ modules:
# post-install is running inside the build dir, we need it from the source though # post-install is running inside the build dir, we need it from the source though
- install -Dm755 ../data/gamemoderun -t /app/bin - install -Dm755 ../data/gamemoderun -t /app/bin
sources: sources:
- type: git - type: archive
url: https://github.com/FeralInteractive/gamemode archive-type: tar-gzip
tag: "1.7" url: https://api.github.com/repos/FeralInteractive/gamemode/tarball/1.7
commit: 4dc99dff76218718763a6b07fc1900fa6d1dafd9 sha256: 57ce73ba605d1cf12f8d13725006a895182308d93eba0f69f285648449641803
x-checker-data:
type: json
url: https://api.github.com/repos/FeralInteractive/gamemode/releases/latest
version-query: .tag_name
url-query: .tarball_url
timestamp-query: .published_at
cleanup:
- /include
- /lib/pkgconfig
- /lib/libgamemodeauto.a
- name: glxinfo
buildsystem: meson
config-opts:
- --bindir=/app/mesa-demos
- -Degl=disabled
- -Dglut=disabled
- -Dosmesa=disabled
- -Dvulkan=disabled
- -Dwayland=disabled
post-install:
- mv -v /app/mesa-demos/glxinfo /app/bin
sources:
- type: archive
url: https://archive.mesa3d.org/demos/mesa-demos-9.0.0.tar.xz
sha256: 3046a3d26a7b051af7ebdd257a5f23bfeb160cad6ed952329cdff1e9f1ed496b
x-checker-data:
type: anitya
project-id: 16781
stable-only: true
url-template: https://archive.mesa3d.org/demos/mesa-demos-$version.tar.xz
cleanup:
- /include
- /mesa-demos
- /share
modules:
- shared-modules/glu/glu-9.json
- name: enhance - name: enhance
buildsystem: simple buildsystem: simple
build-commands: build-commands:
- mkdir -p /app/utils/gamescope
- install -Dm755 prime-run /app/bin/prime-run - install -Dm755 prime-run /app/bin/prime-run
- mv /app/bin/prismlauncher /app/bin/prismrun - mv /app/bin/prismlauncher /app/bin/prismrun
- install -Dm755 prismlauncher /app/bin/prismlauncher - install -Dm755 prismlauncher /app/bin/prismlauncher
sources: sources:
- type: file - type: file
path: ../flatpak/prime-run path: prime-run
- type: file - type: file
path: ../flatpak/prismlauncher path: prismlauncher

View File

@ -0,0 +1,24 @@
diff --git a/src/wl_window.c b/src/wl_window.c
index 52d3b9eb..4ac4eb5d 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -2117,8 +2117,7 @@ void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
void _glfwSetWindowIconWayland(_GLFWwindow* window,
int count, const GLFWimage* images)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the window icon");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window icon\n");
}
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)
@@ -2361,8 +2360,7 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)
void _glfwFocusWindowWayland(_GLFWwindow* window)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the input focus");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the input focus\n");
}
void _glfwSetWindowMonitorWayland(_GLFWwindow* window,

View File

@ -0,0 +1,17 @@
diff --git a/src/init.c b/src/init.c
index 06dbb3f2..a7c6da86 100644
--- a/src/init.c
+++ b/src/init.c
@@ -449,6 +449,12 @@ GLFWAPI int glfwInit(void)
_glfw.initialized = GLFW_TRUE;
glfwDefaultWindowHints();
+
+ fprintf(stderr, "!!! Patched GLFW from https://github.com/Admicos/minecraft-wayland\n"
+ "!!! If any issues with the window, or some issues with rendering, occur, "
+ "first try with the built-in GLFW, and if that solves the issue, report there first.\n"
+ "!!! Use outside Minecraft is untested, and things might break.\n");
+
return GLFW_TRUE;
}

View File

@ -0,0 +1,20 @@
diff --git a/src/platform.c b/src/platform.c
index c5966ae7..3e7442f9 100644
--- a/src/platform.c
+++ b/src/platform.c
@@ -49,12 +49,12 @@ static const struct
#if defined(_GLFW_COCOA)
{ GLFW_PLATFORM_COCOA, _glfwConnectCocoa },
#endif
-#if defined(_GLFW_X11)
- { GLFW_PLATFORM_X11, _glfwConnectX11 },
-#endif
#if defined(_GLFW_WAYLAND)
{ GLFW_PLATFORM_WAYLAND, _glfwConnectWayland },
#endif
+#if defined(_GLFW_X11)
+ { GLFW_PLATFORM_X11, _glfwConnectX11 },
+#endif
};
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)

View File

@ -0,0 +1,40 @@
diff --git a/src/libdecor.c b/src/libdecor.c
index a9c1106..1aa38b3 100644
--- a/src/libdecor.c
+++ b/src/libdecor.c
@@ -1391,22 +1391,32 @@ calculate_priority(const struct libdecor_plugin_description *plugin_description)
static bool
check_symbol_conflicts(const struct libdecor_plugin_description *plugin_description)
{
+ bool ret = true;
char * const *symbol;
+ void* main_prog = dlopen(NULL, RTLD_LAZY);
+ if (!main_prog) {
+ fprintf(stderr, "Plugin \"%s\" couldn't check conflicting symbols: \"%s\".\n",
+ plugin_description->description, dlerror());
+ return false;
+ }
+
symbol = plugin_description->conflicting_symbols;
while (*symbol) {
dlerror();
- dlsym (RTLD_DEFAULT, *symbol);
+ dlsym (main_prog, *symbol);
if (!dlerror()) {
fprintf(stderr, "Plugin \"%s\" uses conflicting symbol \"%s\".\n",
plugin_description->description, *symbol);
- return false;
+ ret = false;
+ break;
}
symbol++;
}
- return true;
+ dlclose(main_prog);
+ return ret;
}
static struct plugin_loader *

View File

@ -5,7 +5,7 @@ for i in {0..9}; do
test -S "$XDG_RUNTIME_DIR"/discord-ipc-"$i" || ln -sf {app/com.discordapp.Discord,"$XDG_RUNTIME_DIR"}/discord-ipc-"$i"; test -S "$XDG_RUNTIME_DIR"/discord-ipc-"$i" || ln -sf {app/com.discordapp.Discord,"$XDG_RUNTIME_DIR"}/discord-ipc-"$i";
done done
export PATH="${PATH}${PATH:+:}/app/utils/gamescope/bin:/usr/lib/extensions/vulkan/MangoHud/bin" export PATH="${PATH}${PATH:+:}/usr/lib/extensions/vulkan/gamescope/bin:/usr/lib/extensions/vulkan/MangoHud/bin"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${LD_LIBRARY_PATH:+:}/usr/lib/extensions/vulkan/MangoHud/\$LIB/" export VK_LAYER_PATH="/usr/lib/extensions/vulkan/share/vulkan/implicit_layer.d/"
exec /app/bin/prismrun "$@" exec /app/bin/prismrun "$@"

@ -0,0 +1 @@
Subproject commit 45094ca570be383d06df729b6972830ec63bd3df

6
garnix.yaml Normal file
View File

@ -0,0 +1,6 @@
builds:
exclude: []
include:
- "checks.x86_64-linux.*"
- "devShells.*.*"
- "packages.*.*"

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
/* /*
* Prism Launcher - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 Tayou <tayou@gmx.net> * Copyright (C) 2022 Tayou <git@tayou.org>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me> * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -38,16 +38,17 @@
#pragma once #pragma once
#include <QApplication> #include <QApplication>
#include <memory> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QFlag> #include <QFlag>
#include <QIcon> #include <QIcon>
#include <QDateTime>
#include <QUrl> #include <QUrl>
#include <memory>
#include <BaseInstance.h> #include <BaseInstance.h>
#include "minecraft/launch/MinecraftServerTarget.h" #include "minecraft/launch/MinecraftServerTarget.h"
#include "ui/themes/CatPack.h"
class LaunchController; class LaunchController;
class LocalPeer; class LocalPeer;
@ -70,27 +71,22 @@ class TranslationsModel;
class ITheme; class ITheme;
class MCEditTool; class MCEditTool;
class ThemeManager; class ThemeManager;
class IconTheme;
namespace Meta { namespace Meta {
class Index; class Index;
} }
#if defined(APPLICATION) #if defined(APPLICATION)
#undef APPLICATION #undef APPLICATION
#endif #endif
#define APPLICATION (static_cast<Application *>(QCoreApplication::instance())) #define APPLICATION (static_cast<Application*>(QCoreApplication::instance()))
class Application : public QApplication class Application : public QApplication {
{
// friends for the purpose of limiting access to deprecated stuff // friends for the purpose of limiting access to deprecated stuff
Q_OBJECT Q_OBJECT
public: public:
enum Status { enum Status { StartingUp, Failed, Succeeded, Initialized };
StartingUp,
Failed,
Succeeded,
Initialized
};
enum Capability { enum Capability {
None = 0, None = 0,
@ -102,33 +98,21 @@ public:
}; };
Q_DECLARE_FLAGS(Capabilities, Capability) Q_DECLARE_FLAGS(Capabilities, Capability)
public: public:
Application(int &argc, char **argv); Application(int& argc, char** argv);
virtual ~Application(); virtual ~Application();
bool event(QEvent* event) override; bool event(QEvent* event) override;
std::shared_ptr<SettingsObject> settings() const { std::shared_ptr<SettingsObject> settings() const { return m_settings; }
return m_settings;
}
qint64 timeSinceStart() const { qint64 timeSinceStart() const { return startTime.msecsTo(QDateTime::currentDateTime()); }
return startTime.msecsTo(QDateTime::currentDateTime());
}
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
void setIconTheme(const QString& name); ThemeManager* themeManager() { return m_themeManager.get(); }
void applyCurrentlySelectedTheme(bool initial = false); shared_qobject_ptr<ExternalUpdater> updater() { return m_updater; }
QList<ITheme*> getValidApplicationThemes();
void setApplicationTheme(const QString& name);
shared_qobject_ptr<ExternalUpdater> updater() {
return m_updater;
}
void triggerUpdateCheck(); void triggerUpdateCheck();
@ -136,29 +120,17 @@ public:
std::shared_ptr<JavaInstallList> javalist(); std::shared_ptr<JavaInstallList> javalist();
std::shared_ptr<InstanceList> instances() const { std::shared_ptr<InstanceList> instances() const { return m_instances; }
return m_instances;
}
std::shared_ptr<IconList> icons() const { std::shared_ptr<IconList> icons() const { return m_icons; }
return m_icons;
}
MCEditTool *mcedit() const { MCEditTool* mcedit() const { return m_mcedit.get(); }
return m_mcedit.get();
}
shared_qobject_ptr<AccountList> accounts() const { shared_qobject_ptr<AccountList> accounts() const { return m_accounts; }
return m_accounts;
}
Status status() const { Status status() const { return m_status; }
return m_status;
}
const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const { const QMap<QString, std::shared_ptr<BaseProfilerFactory>>& profilers() const { return m_profilers; }
return m_profilers;
}
void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password);
@ -170,6 +142,8 @@ public:
void updateCapabilities(); void updateCapabilities();
void detectLibraries();
/*! /*!
* Finds and returns the full path to a jar file. * Finds and returns the full path to a jar file.
* Returns a null-string if it could not be found. * Returns a null-string if it could not be found.
@ -183,35 +157,37 @@ public:
QString getUserAgentUncached(); QString getUserAgentUncached();
/// 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;
}
bool isPortable() { /// the data path the application is using
return m_portable; const QString& dataRoot() { return m_dataPath; }
}
const Capabilities capabilities() { bool isPortable() { return m_portable; }
return m_capabilities;
} const Capabilities capabilities() { return m_capabilities; }
/*! /*!
* Opens a json file using either a system default editor, or, if not empty, the editor * Opens a json file using either a system default editor, or, if not empty, the editor
* specified in the settings * specified in the settings
*/ */
bool openJsonEditor(const QString &filename); bool openJsonEditor(const QString& filename);
InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); InstanceWindow* showInstanceWindow(InstancePtr instance, QString page = QString());
MainWindow *showMainWindow(bool minimized = false); MainWindow* showMainWindow(bool minimized = false);
void updateIsRunning(bool running); void updateIsRunning(bool running);
bool updatesAreAllowed(); bool updatesAreAllowed();
void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); void ShowGlobalSettings(class QWidget* parent, QString open_page = QString());
int suitableMaxMem(); int suitableMaxMem();
signals: bool updaterEnabled();
QString updaterBinaryName();
QUrl normalizeImportUrl(QString const& url);
signals:
void updateAllowedChanged(bool status); void updateAllowedChanged(bool status);
void globalSettingsAboutToOpen(); void globalSettingsAboutToOpen();
void globalSettingsClosed(); void globalSettingsClosed();
@ -221,39 +197,36 @@ signals:
void clickedOnDock(); void clickedOnDock();
#endif #endif
public slots: public slots:
bool launch( bool launch(InstancePtr instance,
InstancePtr instance, bool online = true,
bool online = true, bool demo = false,
bool demo = false, MinecraftServerTargetPtr serverToJoin = nullptr,
BaseProfilerFactory *profiler = nullptr, MinecraftAccountPtr accountToUse = nullptr);
MinecraftServerTargetPtr serverToJoin = nullptr,
MinecraftAccountPtr accountToUse = nullptr
);
bool kill(InstancePtr instance); bool kill(InstancePtr instance);
void closeCurrentWindow(); void closeCurrentWindow();
private slots: private slots:
void on_windowClose(); void on_windowClose();
void messageReceived(const QByteArray & message); void messageReceived(const QByteArray& message);
void controllerSucceeded(); void controllerSucceeded();
void controllerFailed(const QString & error); void controllerFailed(const QString& error);
void setupWizardFinished(int status); void setupWizardFinished(int status);
private: private:
bool handleDataMigration(const QString & currentData, const QString & oldData, const QString & name, const QString & configFile) const; bool handleDataMigration(const QString& currentData, const QString& oldData, const QString& name, const QString& configFile) const;
bool createSetupWizard(); bool createSetupWizard();
void performMainStartupAction(); void performMainStartupAction();
// sets the fatal error message and m_status to Failed. // sets the fatal error message and m_status to Failed.
void showFatalErrorMessage(const QString & title, const QString & content); void showFatalErrorMessage(const QString& title, const QString& content);
private: private:
void addRunningInstance(); void addRunningInstance();
void subRunningInstance(); void subRunningInstance();
bool shouldExitNow() const; bool shouldExitNow() const;
private: private:
QDateTime startTime; QDateTime startTime;
shared_qobject_ptr<QNetworkAccessManager> m_network; shared_qobject_ptr<QNetworkAccessManager> m_network;
@ -277,6 +250,7 @@ private:
QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers; QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
QString m_rootPath; QString m_rootPath;
QString m_dataPath;
Status m_status = Application::StartingUp; Status m_status = Application::StartingUp;
Capabilities m_capabilities; Capabilities m_capabilities;
bool m_portable = false; bool m_portable = false;
@ -292,7 +266,7 @@ private:
// FIXME: attach to instances instead. // FIXME: attach to instances instead.
struct InstanceXtras { struct InstanceXtras {
InstanceWindow * window = nullptr; InstanceWindow* window = nullptr;
shared_qobject_ptr<LaunchController> controller; shared_qobject_ptr<LaunchController> controller;
}; };
std::map<QString, InstanceXtras> m_instanceExtras; std::map<QString, InstanceXtras> m_instanceExtras;
@ -303,18 +277,21 @@ private:
bool m_updateRunning = false; bool m_updateRunning = false;
// main window, if any // main window, if any
MainWindow * m_mainWindow = nullptr; MainWindow* m_mainWindow = nullptr;
// peer launcher instance connector - used to implement single instance launcher and signalling // peer launcher instance connector - used to implement single instance launcher and signalling
LocalPeer * m_peerInstance = nullptr; LocalPeer* m_peerInstance = nullptr;
SetupWizard * m_setupWizard = nullptr; SetupWizard* m_setupWizard = nullptr;
public:
public:
QString m_detectedGLFWPath;
QString m_detectedOpenALPath;
QString m_instanceIdToLaunch; QString m_instanceIdToLaunch;
QString m_serverToJoin; QString m_serverToJoin;
QString m_profileToUse; QString m_profileToUse;
bool m_liveCheck = false; bool m_liveCheck = false;
QList<QUrl> m_zipsToImport; QList<QUrl> m_urlsToImport;
QString m_instanceIdToShowWindowOf; QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile; std::unique_ptr<QFile> logFile;
}; };

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -39,7 +39,8 @@
#include <QJsonObject> #include <QJsonObject>
#include "Json.h" #include "Json.h"
void ApplicationMessage::parse(const QByteArray & input) { void ApplicationMessage::parse(const QByteArray& input)
{
auto doc = Json::requireDocument(input, "ApplicationMessage"); auto doc = Json::requireDocument(input, "ApplicationMessage");
auto root = Json::requireObject(doc, "ApplicationMessage"); auto root = Json::requireObject(doc, "ApplicationMessage");
@ -47,12 +48,13 @@ void ApplicationMessage::parse(const QByteArray & input) {
args.clear(); args.clear();
auto parsedArgs = root.value("args").toObject(); auto parsedArgs = root.value("args").toObject();
for(auto iter = parsedArgs.constBegin(); iter != parsedArgs.constEnd(); iter++) { for (auto iter = parsedArgs.constBegin(); iter != parsedArgs.constEnd(); iter++) {
args.insert(iter.key(), iter.value().toString()); args.insert(iter.key(), iter.value().toString());
} }
} }
QByteArray ApplicationMessage::serialize() { QByteArray ApplicationMessage::serialize()
{
QJsonObject root; QJsonObject root;
root.insert("command", command); root.insert("command", command);
QJsonObject outArgs; QJsonObject outArgs;

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <QString>
#include <QHash>
#include <QByteArray> #include <QByteArray>
#include <QHash>
#include <QString>
struct ApplicationMessage { struct ApplicationMessage {
QString command; QString command;
QHash<QString, QString> args; QHash<QString, QString> args;
QByteArray serialize(); QByteArray serialize();
void parse(const QByteArray & input); void parse(const QByteArray& input);
}; };

View File

@ -18,27 +18,21 @@
#include "BaseInstaller.h" #include "BaseInstaller.h"
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
BaseInstaller::BaseInstaller() BaseInstaller::BaseInstaller() {}
{
} bool BaseInstaller::isApplied(MinecraftInstance* on)
bool BaseInstaller::isApplied(MinecraftInstance *on)
{ {
return QFile::exists(filename(on->instanceRoot())); return QFile::exists(filename(on->instanceRoot()));
} }
bool BaseInstaller::add(MinecraftInstance *to) bool BaseInstaller::add(MinecraftInstance* to)
{ {
if (!patchesDir(to->instanceRoot()).exists()) if (!patchesDir(to->instanceRoot()).exists()) {
{
QDir(to->instanceRoot()).mkdir("patches"); QDir(to->instanceRoot()).mkdir("patches");
} }
if (isApplied(to)) if (isApplied(to)) {
{ if (!remove(to)) {
if (!remove(to))
{
return false; return false;
} }
} }
@ -46,16 +40,16 @@ bool BaseInstaller::add(MinecraftInstance *to)
return true; return true;
} }
bool BaseInstaller::remove(MinecraftInstance *from) bool BaseInstaller::remove(MinecraftInstance* from)
{ {
return QFile::remove(filename(from->instanceRoot())); return QFile::remove(filename(from->instanceRoot()));
} }
QString BaseInstaller::filename(const QString &root) const QString BaseInstaller::filename(const QString& root) const
{ {
return patchesDir(root).absoluteFilePath(id() + ".json"); return patchesDir(root).absoluteFilePath(id() + ".json");
} }
QDir BaseInstaller::patchesDir(const QString &root) const QDir BaseInstaller::patchesDir(const QString& root) const
{ {
return QDir(root + "/patches/"); return QDir(root + "/patches/");
} }

View File

@ -26,20 +26,19 @@ class QObject;
class Task; class Task;
class BaseVersion; class BaseVersion;
class BaseInstaller class BaseInstaller {
{ public:
public:
BaseInstaller(); BaseInstaller();
virtual ~BaseInstaller(){}; virtual ~BaseInstaller(){};
bool isApplied(MinecraftInstance *on); bool isApplied(MinecraftInstance* on);
virtual bool add(MinecraftInstance *to); virtual bool add(MinecraftInstance* to);
virtual bool remove(MinecraftInstance *from); virtual bool remove(MinecraftInstance* from);
virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersion::Ptr version, QObject *parent) = 0; virtual Task* createInstallTask(MinecraftInstance* instance, BaseVersion::Ptr version, QObject* parent) = 0;
protected: protected:
virtual QString id() const = 0; virtual QString id() const = 0;
QString filename(const QString &root) const; QString filename(const QString& root) const;
QDir patchesDir(const QString &root) const; QDir patchesDir(const QString& root) const;
}; };

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
@ -36,23 +37,22 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include <QFileInfo>
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QRegularExpression> #include <QDir>
#include <QFileInfo>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QRegularExpression>
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "settings/Setting.h"
#include "settings/OverrideSetting.h" #include "settings/OverrideSetting.h"
#include "settings/Setting.h"
#include "FileSystem.h"
#include "Commandline.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "Commandline.h"
#include "FileSystem.h"
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : QObject()
: QObject()
{ {
m_settings = settings; m_settings = settings;
m_global_settings = globalSettings; m_global_settings = globalSettings;
@ -79,7 +79,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("InstanceType", ""); m_settings->registerSetting("InstanceType", "");
// Custom Commands // Custom Commands
auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); auto commandSetting = m_settings->registerSetting({ "OverrideCommands", "OverrideLaunchCmd" }, false);
m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting); m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting);
m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting); m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting);
m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting); m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting);
@ -101,6 +101,8 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("ManagedPackName", ""); m_settings->registerSetting("ManagedPackName", "");
m_settings->registerSetting("ManagedPackVersionID", ""); m_settings->registerSetting("ManagedPackVersionID", "");
m_settings->registerSetting("ManagedPackVersionName", ""); m_settings->registerSetting("ManagedPackVersionName", "");
m_settings->registerSetting("Profiler", "");
} }
QString BaseInstance::getPreLaunchCommand() QString BaseInstance::getPreLaunchCommand()
@ -148,7 +150,11 @@ QString BaseInstance::getManagedPackVersionName() const
return m_settings->get("ManagedPackVersionName").toString(); return m_settings->get("ManagedPackVersionName").toString();
} }
void BaseInstance::setManagedPack(const QString& type, const QString& id, const QString& name, const QString& versionId, const QString& version) void BaseInstance::setManagedPack(const QString& type,
const QString& id,
const QString& name,
const QString& versionId,
const QString& version)
{ {
m_settings->set("ManagedPack", true); m_settings->set("ManagedPack", true);
m_settings->set("ManagedPackType", type); m_settings->set("ManagedPackType", type);
@ -173,8 +179,7 @@ int BaseInstance::getConsoleMaxLines() const
auto lineSetting = m_settings->getSetting("ConsoleMaxLines"); auto lineSetting = m_settings->getSetting("ConsoleMaxLines");
bool conversionOk = false; bool conversionOk = false;
int maxLines = lineSetting->get().toInt(&conversionOk); int maxLines = lineSetting->get().toInt(&conversionOk);
if(!conversionOk) if (!conversionOk) {
{
maxLines = lineSetting->defValue().toInt(); maxLines = lineSetting->defValue().toInt();
qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines; qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
} }
@ -220,8 +225,7 @@ bool BaseInstance::isLinkedToInstanceId(const QString& id) const
void BaseInstance::iconUpdated(QString key) void BaseInstance::iconUpdated(QString key)
{ {
if(iconKey() == key) if (iconKey() == key) {
{
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
@ -235,8 +239,7 @@ void BaseInstance::invalidate()
void BaseInstance::changeStatus(BaseInstance::Status newStatus) void BaseInstance::changeStatus(BaseInstance::Status newStatus)
{ {
Status status = currentStatus(); Status status = currentStatus();
if(status != newStatus) if (status != newStatus) {
{
m_status = newStatus; m_status = newStatus;
emit statusChanged(status, newStatus); emit statusChanged(status, newStatus);
} }
@ -259,23 +262,19 @@ bool BaseInstance::isRunning() const
void BaseInstance::setRunning(bool running) void BaseInstance::setRunning(bool running)
{ {
if(running == m_isRunning) if (running == m_isRunning)
return; return;
m_isRunning = running; m_isRunning = running;
if(!m_settings->get("RecordGameTime").toBool()) if (!m_settings->get("RecordGameTime").toBool()) {
{
emit runningStatusChanged(running); emit runningStatusChanged(running);
return; return;
} }
if(running) if (running) {
{
m_timeStarted = QDateTime::currentDateTime(); m_timeStarted = QDateTime::currentDateTime();
} } else {
else
{
QDateTime timeEnded = QDateTime::currentDateTime(); QDateTime timeEnded = QDateTime::currentDateTime();
qint64 current = settings()->get("totalTimePlayed").toLongLong(); qint64 current = settings()->get("totalTimePlayed").toLongLong();
@ -291,8 +290,7 @@ void BaseInstance::setRunning(bool running)
int64_t BaseInstance::totalTimePlayed() const int64_t BaseInstance::totalTimePlayed() const
{ {
qint64 current = m_settings->get("totalTimePlayed").toLongLong(); qint64 current = m_settings->get("totalTimePlayed").toLongLong();
if(m_isRunning) if (m_isRunning) {
{
QDateTime timeNow = QDateTime::currentDateTime(); QDateTime timeNow = QDateTime::currentDateTime();
return current + m_timeStarted.secsTo(timeNow); return current + m_timeStarted.secsTo(timeNow);
} }
@ -301,8 +299,7 @@ int64_t BaseInstance::totalTimePlayed() const
int64_t BaseInstance::lastTimePlayed() const int64_t BaseInstance::lastTimePlayed() const
{ {
if(m_isRunning) if (m_isRunning) {
{
QDateTime timeNow = QDateTime::currentDateTime(); QDateTime timeNow = QDateTime::currentDateTime();
return m_timeStarted.secsTo(timeNow); return m_timeStarted.secsTo(timeNow);
} }
@ -349,14 +346,14 @@ qint64 BaseInstance::lastLaunch() const
void BaseInstance::setLastLaunch(qint64 val) void BaseInstance::setLastLaunch(qint64 val)
{ {
//FIXME: if no change, do not set. setting involves saving a file. // FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("lastLaunchTime", val); m_settings->set("lastLaunchTime", val);
emit propertiesChanged(this); emit propertiesChanged(this);
} }
void BaseInstance::setNotes(QString val) void BaseInstance::setNotes(QString val)
{ {
//FIXME: if no change, do not set. setting involves saving a file. // FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("notes", val); m_settings->set("notes", val);
} }
@ -367,7 +364,7 @@ QString BaseInstance::notes() const
void BaseInstance::setIconKey(QString val) void BaseInstance::setIconKey(QString val)
{ {
//FIXME: if no change, do not set. setting involves saving a file. // FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("iconKey", val); m_settings->set("iconKey", val);
emit propertiesChanged(this); emit propertiesChanged(this);
} }
@ -379,7 +376,7 @@ QString BaseInstance::iconKey() const
void BaseInstance::setName(QString val) void BaseInstance::setName(QString val)
{ {
//FIXME: if no change, do not set. setting involves saving a file. // FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("name", val); m_settings->set("name", val);
emit propertiesChanged(this); emit propertiesChanged(this);
} }
@ -391,7 +388,7 @@ QString BaseInstance::name() const
QString BaseInstance::windowTitle() const QString BaseInstance::windowTitle() const
{ {
return BuildConfig.LAUNCHER_DISPLAYNAME + ": " + name().replace(QRegularExpression("\\s+"), " "); return BuildConfig.LAUNCHER_DISPLAYNAME + ": " + name();
} }
// FIXME: why is this here? move it to MinecraftInstance!!! // FIXME: why is this here? move it to MinecraftInstance!!!

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
@ -37,24 +38,25 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <QObject>
#include "QObjectPtr.h"
#include <QDateTime> #include <QDateTime>
#include <QSet> #include <QMenu>
#include <QObject>
#include <QProcess> #include <QProcess>
#include <QSet>
#include "QObjectPtr.h"
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "settings/INIFile.h"
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "MessageLevel.h" #include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "pathmatcher/IPathMatcher.h" #include "pathmatcher/IPathMatcher.h"
#include "settings/INIFile.h"
#include "net/Mode.h" #include "net/Mode.h"
#include "minecraft/launch/MinecraftServerTarget.h"
#include "RuntimeContext.h" #include "RuntimeContext.h"
#include "minecraft/launch/MinecraftServerTarget.h"
class QDir; class QDir;
class Task; class Task;
@ -62,7 +64,7 @@ class LaunchTask;
class BaseInstance; class BaseInstance;
// pointer for lazy people // pointer for lazy people
typedef std::shared_ptr<BaseInstance> InstancePtr; using InstancePtr = std::shared_ptr<BaseInstance>;
/*! /*!
* \brief Base class for instances. * \brief Base class for instances.
@ -72,23 +74,21 @@ typedef std::shared_ptr<BaseInstance> InstancePtr;
* To create a new instance type, create a new class inheriting from this class * To create a new instance type, create a new class inheriting from this class
* and implement the pure virtual functions. * and implement the pure virtual functions.
*/ */
class BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance> class BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance> {
{
Q_OBJECT Q_OBJECT
protected: protected:
/// no-touchy! /// no-touchy!
BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir);
public: /* types */ public: /* types */
enum class Status enum class Status {
{
Present, Present,
Gone // either nuked or invalidated Gone // either nuked or invalidated
}; };
public: public:
/// virtual destructor to make sure the destruction is COMPLETE /// virtual destructor to make sure the destruction is COMPLETE
virtual ~BaseInstance() {}; virtual ~BaseInstance() {}
virtual void saveNow() = 0; virtual void saveNow() = 0;
@ -117,10 +117,7 @@ public:
QString instanceRoot() const; QString instanceRoot() const;
/// Path to the instance's game root directory. /// Path to the instance's game root directory.
virtual QString gameRoot() const virtual QString gameRoot() const { return instanceRoot(); }
{
return instanceRoot();
}
/// Path to the instance's mods directory. /// Path to the instance's mods directory.
virtual QString modsRoot() const = 0; virtual QString modsRoot() const = 0;
@ -151,15 +148,12 @@ public:
void copyManagedPack(BaseInstance& other); void copyManagedPack(BaseInstance& other);
/// guess log level from a line of game log /// guess log level from a line of game log
virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString &line, MessageLevel::Enum level) virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString& line, MessageLevel::Enum level) { return level; }
{
return level;
};
virtual QStringList extraArguments(); virtual QStringList extraArguments();
/// Traits. Normally inside the version, depends on instance implementation. /// Traits. Normally inside the version, depends on instance implementation.
virtual QSet <QString> traits() const = 0; virtual QSet<QString> traits() const = 0;
/** /**
* Gets the time that the instance was last launched. * Gets the time that the instance was last launched.
@ -189,8 +183,7 @@ public:
virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0; virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0;
/// returns a valid launcher (task container) /// returns a valid launcher (task container)
virtual shared_qobject_ptr<LaunchTask> createLaunchTask( virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
/// returns the current launch task (if any) /// returns the current launch task (if any)
shared_qobject_ptr<LaunchTask> getLaunchTask(); shared_qobject_ptr<LaunchTask> getLaunchTask();
@ -222,45 +215,30 @@ public:
virtual QString typeName() const = 0; virtual QString typeName() const = 0;
void updateRuntimeContext(); void updateRuntimeContext();
RuntimeContext runtimeContext() const RuntimeContext runtimeContext() const { return m_runtimeContext; }
{
return m_runtimeContext;
}
bool hasVersionBroken() const bool hasVersionBroken() const { return m_hasBrokenVersion; }
{
return m_hasBrokenVersion;
}
void setVersionBroken(bool value) void setVersionBroken(bool value)
{ {
if(m_hasBrokenVersion != value) if (m_hasBrokenVersion != value) {
{
m_hasBrokenVersion = value; m_hasBrokenVersion = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
bool hasUpdateAvailable() const bool hasUpdateAvailable() const { return m_hasUpdate; }
{
return m_hasUpdate;
}
void setUpdateAvailable(bool value) void setUpdateAvailable(bool value)
{ {
if(m_hasUpdate != value) if (m_hasUpdate != value) {
{
m_hasUpdate = value; m_hasUpdate = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
bool hasCrashed() const bool hasCrashed() const { return m_crashed; }
{
return m_crashed;
}
void setCrashed(bool value) void setCrashed(bool value)
{ {
if(m_crashed != value) if (m_crashed != value) {
{
m_crashed = value; m_crashed = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
@ -270,6 +248,8 @@ public:
virtual bool canEdit() const = 0; virtual bool canEdit() const = 0;
virtual bool canExport() const = 0; virtual bool canExport() const = 0;
virtual void populateLaunchMenu(QMenu* menu) = 0;
bool reloadSettings(); bool reloadSettings();
/** /**
@ -288,30 +268,32 @@ public:
bool removeLinkedInstanceId(const QString& id); bool removeLinkedInstanceId(const QString& id);
bool isLinkedToInstanceId(const QString& id) const; bool isLinkedToInstanceId(const QString& id) const;
protected: protected:
void changeStatus(Status newStatus); void changeStatus(Status newStatus);
SettingsObjectPtr globalSettings() const { return m_global_settings.lock(); }; SettingsObjectPtr globalSettings() const { return m_global_settings.lock(); }
bool isSpecificSettingsLoaded() const { return m_specific_settings_loaded; } bool isSpecificSettingsLoaded() const { return m_specific_settings_loaded; }
void setSpecificSettingsLoaded(bool loaded) { m_specific_settings_loaded = loaded; } void setSpecificSettingsLoaded(bool loaded) { m_specific_settings_loaded = loaded; }
signals: signals:
/*! /*!
* \brief Signal emitted when properties relevant to the instance view change * \brief Signal emitted when properties relevant to the instance view change
*/ */
void propertiesChanged(BaseInstance *inst); void propertiesChanged(BaseInstance* inst);
void launchTaskChanged(shared_qobject_ptr<LaunchTask>); void launchTaskChanged(shared_qobject_ptr<LaunchTask>);
void runningStatusChanged(bool running); void runningStatusChanged(bool running);
void profilerChanged();
void statusChanged(Status from, Status to); void statusChanged(Status from, Status to);
protected slots: protected slots:
void iconUpdated(QString key); void iconUpdated(QString key);
protected: /* data */ protected: /* data */
QString m_rootDir; QString m_rootDir;
SettingsObjectPtr m_settings; SettingsObjectPtr m_settings;
// InstanceFlags m_flags; // InstanceFlags m_flags;
@ -320,7 +302,7 @@ protected: /* data */
QDateTime m_timeStarted; QDateTime m_timeStarted;
RuntimeContext m_runtimeContext; RuntimeContext m_runtimeContext;
private: /* data */ private: /* data */
Status m_status = Status::Present; Status m_status = Status::Present;
bool m_crashed = false; bool m_crashed = false;
bool m_hasUpdate = false; bool m_hasUpdate = false;
@ -328,9 +310,8 @@ private: /* data */
SettingsObjectWeakPtr m_global_settings; SettingsObjectWeakPtr m_global_settings;
bool m_specific_settings_loaded = false; bool m_specific_settings_loaded = false;
}; };
Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>) Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>)
//Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) // Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
//Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) // Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags)

View File

@ -15,16 +15,15 @@
#pragma once #pragma once
#include <memory>
#include <QString>
#include <QMetaType> #include <QMetaType>
#include <QString>
#include <memory>
/*! /*!
* An abstract base class for versions. * An abstract base class for versions.
*/ */
class BaseVersion class BaseVersion {
{ public:
public:
using Ptr = std::shared_ptr<BaseVersion>; using Ptr = std::shared_ptr<BaseVersion>;
virtual ~BaseVersion() {} virtual ~BaseVersion() {}
/*! /*!
@ -44,15 +43,8 @@ public:
* the kind of version this is (Stable, Beta, Snapshot, whatever) * the kind of version this is (Stable, Beta, Snapshot, whatever)
*/ */
virtual QString typeString() const = 0; virtual QString typeString() const = 0;
virtual bool operator<(BaseVersion& a) { return name() < a.name(); }
virtual bool operator<(BaseVersion &a) virtual bool operator>(BaseVersion& a) { return name() > a.name(); }
{
return name() < a.name();
};
virtual bool operator>(BaseVersion &a)
{
return name() > a.name();
};
}; };
Q_DECLARE_METATYPE(BaseVersion::Ptr) Q_DECLARE_METATYPE(BaseVersion::Ptr)

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -36,14 +36,11 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "BaseVersion.h" #include "BaseVersion.h"
BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent) BaseVersionList::BaseVersionList(QObject* parent) : QAbstractListModel(parent) {}
{
}
BaseVersion::Ptr BaseVersionList::findVersion(const QString &descriptor) BaseVersion::Ptr BaseVersionList::findVersion(const QString& descriptor)
{ {
for (int i = 0; i < count(); i++) for (int i = 0; i < count(); i++) {
{
if (at(i)->descriptor() == descriptor) if (at(i)->descriptor() == descriptor)
return at(i); return at(i);
} }
@ -58,7 +55,7 @@ BaseVersion::Ptr BaseVersionList::getRecommended() const
return at(0); return at(0);
} }
QVariant BaseVersionList::data(const QModelIndex &index, int role) const QVariant BaseVersionList::data(const QModelIndex& index, int role) const
{ {
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
@ -68,37 +65,36 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const
BaseVersion::Ptr version = at(index.row()); BaseVersion::Ptr version = at(index.row());
switch (role) switch (role) {
{ case VersionPointerRole:
case VersionPointerRole: return QVariant::fromValue(version);
return QVariant::fromValue(version);
case VersionRole: case VersionRole:
return version->name(); return version->name();
case VersionIdRole: case VersionIdRole:
return version->descriptor(); return version->descriptor();
case TypeRole: case TypeRole:
return version->typeString(); return version->typeString();
default: default:
return QVariant(); return QVariant();
} }
} }
BaseVersionList::RoleList BaseVersionList::providesRoles() const BaseVersionList::RoleList BaseVersionList::providesRoles() const
{ {
return {VersionPointerRole, VersionRole, VersionIdRole, TypeRole}; return { VersionPointerRole, VersionRole, VersionIdRole, TypeRole };
} }
int BaseVersionList::rowCount(const QModelIndex &parent) const int BaseVersionList::rowCount(const QModelIndex& parent) const
{ {
// Return count // Return count
return parent.isValid() ? 0 : count(); return parent.isValid() ? 0 : count();
} }
int BaseVersionList::columnCount(const QModelIndex &parent) const int BaseVersionList::columnCount(const QModelIndex& parent) const
{ {
return parent.isValid() ? 0 : 1; return parent.isValid() ? 0 : 1;
} }

View File

@ -15,13 +15,13 @@
#pragma once #pragma once
#include <QAbstractListModel>
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include <QAbstractListModel>
#include "BaseVersion.h" #include "BaseVersion.h"
#include "tasks/Task.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
#include "tasks/Task.h"
/*! /*!
* \brief Class that each instance type's version list derives from. * \brief Class that each instance type's version list derives from.
@ -35,12 +35,10 @@
* all have a default implementation, but they can be overridden by plugins to * all have a default implementation, but they can be overridden by plugins to
* change the behavior of the list. * change the behavior of the list.
*/ */
class BaseVersionList : public QAbstractListModel class BaseVersionList : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
public: public:
enum ModelRoles enum ModelRoles {
{
VersionPointerRole = Qt::UserRole, VersionPointerRole = Qt::UserRole,
VersionRole, VersionRole,
VersionIdRole, VersionIdRole,
@ -53,9 +51,9 @@ public:
ArchitectureRole, ArchitectureRole,
SortRole SortRole
}; };
typedef QList<int> RoleList; using RoleList = QList<int>;
explicit BaseVersionList(QObject *parent = 0); explicit BaseVersionList(QObject* parent = 0);
/*! /*!
* \brief Gets a task that will reload the version list. * \brief Gets a task that will reload the version list.
@ -66,7 +64,7 @@ public:
virtual Task::Ptr getLoadTask() = 0; virtual Task::Ptr getLoadTask() = 0;
//! Checks whether or not the list is loaded. If this returns false, the list should be //! Checks whether or not the list is loaded. If this returns false, the list should be
//loaded. // loaded.
virtual bool isLoaded() = 0; virtual bool isLoaded() = 0;
//! Gets the version at the given index. //! Gets the version at the given index.
@ -76,9 +74,9 @@ public:
virtual int count() const = 0; virtual int count() const = 0;
//////// List Model Functions //////// //////// List Model Functions ////////
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex& index, int role) const override;
int rowCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex& parent) const override;
int columnCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex& parent) const override;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
//! which roles are provided by this version list? //! which roles are provided by this version list?
@ -90,7 +88,7 @@ public:
* \return A const pointer to the version with the given descriptor. NULL if * \return A const pointer to the version with the given descriptor. NULL if
* one doesn't exist. * one doesn't exist.
*/ */
virtual BaseVersion::Ptr findVersion(const QString &descriptor); virtual BaseVersion::Ptr findVersion(const QString& descriptor);
/*! /*!
* \brief Gets the recommended version from this list * \brief Gets the recommended version from this list
@ -103,8 +101,7 @@ public:
*/ */
virtual void sortVersions() = 0; virtual void sortVersions() = 0;
protected protected slots:
slots:
/*! /*!
* Updates this list with the given list of versions. * Updates this list with the given list of versions.
* This is done by copying each version in the given list and inserting it * This is done by copying each version in the given list and inserting it

View File

@ -136,6 +136,16 @@ set(NET_SOURCES
net/Validator.h net/Validator.h
net/Upload.cpp net/Upload.cpp
net/Upload.h net/Upload.h
net/HeaderProxy.h
net/RawHeaderProxy.h
net/ApiHeaderProxy.h
net/StaticHeaderProxy.h
net/ApiDownload.h
net/ApiDownload.cpp
net/ApiUpload.cpp
net/ApiUpload.h
net/NetRequest.cpp
net/NetRequest.h
) )
# Game launch logic # Game launch logic
@ -172,6 +182,11 @@ set(MAC_UPDATE_SOURCES
updater/MacSparkleUpdater.mm updater/MacSparkleUpdater.mm
) )
set(PRISM_UPDATE_SOURCES
updater/PrismExternalUpdater.h
updater/PrismExternalUpdater.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
@ -207,13 +222,9 @@ set(MINECRAFT_SOURCES
minecraft/auth/MinecraftAccount.h minecraft/auth/MinecraftAccount.h
minecraft/auth/Parsers.cpp minecraft/auth/Parsers.cpp
minecraft/auth/Parsers.h minecraft/auth/Parsers.h
minecraft/auth/Yggdrasil.cpp
minecraft/auth/Yggdrasil.h
minecraft/auth/flows/AuthFlow.cpp minecraft/auth/flows/AuthFlow.cpp
minecraft/auth/flows/AuthFlow.h minecraft/auth/flows/AuthFlow.h
minecraft/auth/flows/Mojang.cpp
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.cpp
@ -227,12 +238,8 @@ set(MINECRAFT_SOURCES
minecraft/auth/steps/GetSkinStep.h minecraft/auth/steps/GetSkinStep.h
minecraft/auth/steps/LauncherLoginStep.cpp minecraft/auth/steps/LauncherLoginStep.cpp
minecraft/auth/steps/LauncherLoginStep.h minecraft/auth/steps/LauncherLoginStep.h
minecraft/auth/steps/MigrationEligibilityStep.cpp
minecraft/auth/steps/MigrationEligibilityStep.h
minecraft/auth/steps/MinecraftProfileStep.cpp minecraft/auth/steps/MinecraftProfileStep.cpp
minecraft/auth/steps/MinecraftProfileStep.h minecraft/auth/steps/MinecraftProfileStep.h
minecraft/auth/steps/MinecraftProfileStepMojang.cpp
minecraft/auth/steps/MinecraftProfileStepMojang.h
minecraft/auth/steps/MSAStep.cpp minecraft/auth/steps/MSAStep.cpp
minecraft/auth/steps/MSAStep.h minecraft/auth/steps/MSAStep.h
minecraft/auth/steps/XboxAuthorizationStep.cpp minecraft/auth/steps/XboxAuthorizationStep.cpp
@ -241,8 +248,6 @@ set(MINECRAFT_SOURCES
minecraft/auth/steps/XboxProfileStep.h minecraft/auth/steps/XboxProfileStep.h
minecraft/auth/steps/XboxUserStep.cpp minecraft/auth/steps/XboxUserStep.cpp
minecraft/auth/steps/XboxUserStep.h minecraft/auth/steps/XboxUserStep.h
minecraft/auth/steps/YggdrasilStep.cpp
minecraft/auth/steps/YggdrasilStep.h
minecraft/gameoptions/GameOptions.h minecraft/gameoptions/GameOptions.h
minecraft/gameoptions/GameOptions.cpp minecraft/gameoptions/GameOptions.cpp
@ -262,8 +267,6 @@ set(MINECRAFT_SOURCES
minecraft/launch/CreateGameFolders.h minecraft/launch/CreateGameFolders.h
minecraft/launch/ModMinecraftJar.cpp minecraft/launch/ModMinecraftJar.cpp
minecraft/launch/ModMinecraftJar.h minecraft/launch/ModMinecraftJar.h
minecraft/launch/DirectJavaLaunch.cpp
minecraft/launch/DirectJavaLaunch.h
minecraft/launch/ExtractNatives.cpp minecraft/launch/ExtractNatives.cpp
minecraft/launch/ExtractNatives.h minecraft/launch/ExtractNatives.h
minecraft/launch/LauncherPartLaunch.cpp minecraft/launch/LauncherPartLaunch.cpp
@ -487,6 +490,9 @@ set(API_SOURCES
modplatform/helpers/HashUtils.cpp modplatform/helpers/HashUtils.cpp
modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.h
modplatform/helpers/OverrideUtils.cpp modplatform/helpers/OverrideUtils.cpp
modplatform/helpers/ExportToModList.h
modplatform/helpers/ExportToModList.cpp
) )
set(FTB_SOURCES set(FTB_SOURCES
@ -498,6 +504,11 @@ set(FTB_SOURCES
modplatform/legacy_ftb/PrivatePackManager.cpp modplatform/legacy_ftb/PrivatePackManager.cpp
modplatform/legacy_ftb/PackHelpers.h modplatform/legacy_ftb/PackHelpers.h
modplatform/import_ftb/PackInstallTask.h
modplatform/import_ftb/PackInstallTask.cpp
modplatform/import_ftb/PackHelpers.h
modplatform/import_ftb/PackHelpers.cpp
) )
set(FLAME_SOURCES set(FLAME_SOURCES
@ -514,6 +525,8 @@ set(FLAME_SOURCES
modplatform/flame/FlameCheckUpdate.h modplatform/flame/FlameCheckUpdate.h
modplatform/flame/FlameInstanceCreationTask.h modplatform/flame/FlameInstanceCreationTask.h
modplatform/flame/FlameInstanceCreationTask.cpp modplatform/flame/FlameInstanceCreationTask.cpp
modplatform/flame/FlamePackExportTask.h
modplatform/flame/FlamePackExportTask.cpp
) )
set(MODRINTH_SOURCES set(MODRINTH_SOURCES
@ -558,6 +571,9 @@ set(ATLAUNCHER_SOURCES
) )
set(LINKEXE_SOURCES set(LINKEXE_SOURCES
WindowsConsole.cpp
WindowsConsole.h
filelink/FileLink.h filelink/FileLink.h
filelink/FileLink.cpp filelink/FileLink.cpp
FileSystem.h FileSystem.h
@ -569,6 +585,63 @@ set(LINKEXE_SOURCES
DesktopServices.cpp DesktopServices.cpp
) )
set(PRISMUPDATER_SOURCES
updater/prismupdater/PrismUpdater.h
updater/prismupdater/PrismUpdater.cpp
updater/prismupdater/UpdaterDialogs.h
updater/prismupdater/UpdaterDialogs.cpp
updater/prismupdater/GitHubRelease.h
updater/prismupdater/GitHubRelease.cpp
Json.h
Json.cpp
FileSystem.h
FileSystem.cpp
StringUtils.h
StringUtils.cpp
DesktopServices.h
DesktopServices.cpp
Version.h
Version.cpp
Markdown.h
Markdown.cpp
# Zip
MMCZip.h
MMCZip.cpp
# Time
MMCTime.h
MMCTime.cpp
net/ByteArraySink.h
net/ChecksumValidator.h
net/Download.cpp
net/Download.h
net/FileSink.cpp
net/FileSink.h
net/HttpMetaCache.cpp
net/HttpMetaCache.h
net/Logging.h
net/Logging.cpp
net/NetAction.h
net/NetRequest.cpp
net/NetRequest.h
net/NetJob.cpp
net/NetJob.h
net/NetUtils.h
net/Sink.h
net/Validator.h
net/HeaderProxy.h
net/RawHeaderProxy.h
ui/dialogs/ProgressDialog.cpp
ui/dialogs/ProgressDialog.h
ui/widgets/SubTaskProgressBar.h
ui/widgets/SubTaskProgressBar.cpp
)
######## Logging categories ######## ######## Logging categories ########
ecm_qt_declare_logging_category(CORE_SOURCES ecm_qt_declare_logging_category(CORE_SOURCES
@ -663,8 +736,10 @@ set(LOGIC_SOURCES
${ATLAUNCHER_SOURCES} ${ATLAUNCHER_SOURCES}
) )
if(APPLE) if(APPLE AND Launcher_ENABLE_UPDATER)
set (LOGIC_SOURCES ${LOGIC_SOURCES} ${MAC_UPDATE_SOURCES}) set (LOGIC_SOURCES ${LOGIC_SOURCES} ${MAC_UPDATE_SOURCES})
else()
set (LOGIC_SOURCES ${LOGIC_SOURCES} ${PRISM_UPDATE_SOURCES})
endif() endif()
SET(LAUNCHER_SOURCES SET(LAUNCHER_SOURCES
@ -754,8 +829,12 @@ SET(LAUNCHER_SOURCES
ui/themes/ITheme.h ui/themes/ITheme.h
ui/themes/SystemTheme.cpp ui/themes/SystemTheme.cpp
ui/themes/SystemTheme.h ui/themes/SystemTheme.h
ui/themes/IconTheme.cpp
ui/themes/IconTheme.h
ui/themes/ThemeManager.cpp ui/themes/ThemeManager.cpp
ui/themes/ThemeManager.h ui/themes/ThemeManager.h
ui/themes/CatPack.cpp
ui/themes/CatPack.h
# Processes # Processes
LaunchController.h LaunchController.h
@ -810,6 +889,8 @@ SET(LAUNCHER_SOURCES
ui/pages/global/AccountListPage.h ui/pages/global/AccountListPage.h
ui/pages/global/CustomCommandsPage.cpp ui/pages/global/CustomCommandsPage.cpp
ui/pages/global/CustomCommandsPage.h ui/pages/global/CustomCommandsPage.h
ui/pages/global/EnvironmentVariablesPage.cpp
ui/pages/global/EnvironmentVariablesPage.h
ui/pages/global/ExternalToolsPage.cpp ui/pages/global/ExternalToolsPage.cpp
ui/pages/global/ExternalToolsPage.h ui/pages/global/ExternalToolsPage.h
ui/pages/global/JavaPage.cpp ui/pages/global/JavaPage.cpp
@ -865,6 +946,11 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/legacy_ftb/ListModel.h ui/pages/modplatform/legacy_ftb/ListModel.h
ui/pages/modplatform/legacy_ftb/ListModel.cpp ui/pages/modplatform/legacy_ftb/ListModel.cpp
ui/pages/modplatform/import_ftb/ImportFTBPage.cpp
ui/pages/modplatform/import_ftb/ImportFTBPage.h
ui/pages/modplatform/import_ftb/ListModel.h
ui/pages/modplatform/import_ftb/ListModel.cpp
ui/pages/modplatform/flame/FlameModel.cpp ui/pages/modplatform/flame/FlameModel.cpp
ui/pages/modplatform/flame/FlameModel.h ui/pages/modplatform/flame/FlameModel.h
ui/pages/modplatform/flame/FlamePage.cpp ui/pages/modplatform/flame/FlamePage.cpp
@ -887,6 +973,9 @@ 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/OptionalModDialog.cpp
ui/pages/modplatform/OptionalModDialog.h
ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
ui/pages/modplatform/modrinth/ModrinthResourceModels.h ui/pages/modplatform/modrinth/ModrinthResourceModels.h
ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
@ -907,14 +996,14 @@ SET(LAUNCHER_SOURCES
ui/dialogs/EditAccountDialog.h ui/dialogs/EditAccountDialog.h
ui/dialogs/ExportInstanceDialog.cpp ui/dialogs/ExportInstanceDialog.cpp
ui/dialogs/ExportInstanceDialog.h ui/dialogs/ExportInstanceDialog.h
ui/dialogs/ExportMrPackDialog.cpp ui/dialogs/ExportPackDialog.cpp
ui/dialogs/ExportMrPackDialog.h ui/dialogs/ExportPackDialog.h
ui/dialogs/ExportToModListDialog.cpp
ui/dialogs/ExportToModListDialog.h
ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.cpp
ui/dialogs/IconPickerDialog.h ui/dialogs/IconPickerDialog.h
ui/dialogs/ImportResourceDialog.cpp ui/dialogs/ImportResourceDialog.cpp
ui/dialogs/ImportResourceDialog.h ui/dialogs/ImportResourceDialog.h
ui/dialogs/LoginDialog.cpp
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.cpp
@ -945,12 +1034,16 @@ SET(LAUNCHER_SOURCES
ui/dialogs/ChooseProviderDialog.cpp ui/dialogs/ChooseProviderDialog.cpp
ui/dialogs/ModUpdateDialog.cpp ui/dialogs/ModUpdateDialog.cpp
ui/dialogs/ModUpdateDialog.h ui/dialogs/ModUpdateDialog.h
ui/dialogs/InstallLoaderDialog.cpp
ui/dialogs/InstallLoaderDialog.h
# GUI - widgets # GUI - widgets
ui/widgets/Common.cpp ui/widgets/Common.cpp
ui/widgets/Common.h ui/widgets/Common.h
ui/widgets/CustomCommands.cpp ui/widgets/CustomCommands.cpp
ui/widgets/CustomCommands.h ui/widgets/CustomCommands.h
ui/widgets/EnvironmentVariables.cpp
ui/widgets/EnvironmentVariables.h
ui/widgets/DropLabel.cpp ui/widgets/DropLabel.cpp
ui/widgets/DropLabel.h ui/widgets/DropLabel.h
ui/widgets/FocusLineEdit.cpp ui/widgets/FocusLineEdit.cpp
@ -1009,6 +1102,23 @@ SET(LAUNCHER_SOURCES
ui/instanceview/VisualGroup.h ui/instanceview/VisualGroup.h
) )
if (NOT Apple)
set(LAUNCHER_SOURCES
${LAUNCHER_SOURCES}
ui/dialogs/UpdateAvailableDialog.h
ui/dialogs/UpdateAvailableDialog.cpp
)
endif()
if(WIN32)
set(LAUNCHER_SOURCES
WindowsConsole.cpp
WindowsConsole.h
${LAUNCHER_SOURCES}
)
endif()
qt_wrap_ui(LAUNCHER_UI qt_wrap_ui(LAUNCHER_UI
ui/MainWindow.ui ui/MainWindow.ui
ui/setupwizard/PasteWizardPage.ui ui/setupwizard/PasteWizardPage.ui
@ -1037,11 +1147,14 @@ qt_wrap_ui(LAUNCHER_UI
ui/pages/modplatform/ResourcePage.ui ui/pages/modplatform/ResourcePage.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/import_ftb/ImportFTBPage.ui
ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/ImportPage.ui
ui/pages/modplatform/OptionalModDialog.ui
ui/pages/modplatform/modrinth/ModrinthPage.ui ui/pages/modplatform/modrinth/ModrinthPage.ui
ui/pages/modplatform/technic/TechnicPage.ui ui/pages/modplatform/technic/TechnicPage.ui
ui/widgets/InstanceCardWidget.ui ui/widgets/InstanceCardWidget.ui
ui/widgets/CustomCommands.ui ui/widgets/CustomCommands.ui
ui/widgets/EnvironmentVariables.ui
ui/widgets/InfoFrame.ui ui/widgets/InfoFrame.ui
ui/widgets/ModFilterWidget.ui ui/widgets/ModFilterWidget.ui
ui/widgets/SubTaskProgressBar.ui ui/widgets/SubTaskProgressBar.ui
@ -1055,13 +1168,13 @@ qt_wrap_ui(LAUNCHER_UI
ui/dialogs/ProfileSelectDialog.ui ui/dialogs/ProfileSelectDialog.ui
ui/dialogs/SkinUploadDialog.ui ui/dialogs/SkinUploadDialog.ui
ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportInstanceDialog.ui
ui/dialogs/ExportMrPackDialog.ui ui/dialogs/ExportPackDialog.ui
ui/dialogs/ExportToModListDialog.ui
ui/dialogs/IconPickerDialog.ui ui/dialogs/IconPickerDialog.ui
ui/dialogs/ImportResourceDialog.ui ui/dialogs/ImportResourceDialog.ui
ui/dialogs/MSALoginDialog.ui ui/dialogs/MSALoginDialog.ui
ui/dialogs/OfflineLoginDialog.ui ui/dialogs/OfflineLoginDialog.ui
ui/dialogs/AboutDialog.ui ui/dialogs/AboutDialog.ui
ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui ui/dialogs/EditAccountDialog.ui
ui/dialogs/ReviewMessageBox.ui ui/dialogs/ReviewMessageBox.ui
ui/dialogs/ScrollMessageBox.ui ui/dialogs/ScrollMessageBox.ui
@ -1069,6 +1182,14 @@ qt_wrap_ui(LAUNCHER_UI
ui/dialogs/ChooseProviderDialog.ui ui/dialogs/ChooseProviderDialog.ui
) )
qt_wrap_ui(PRISM_UPDATE_UI
ui/dialogs/UpdateAvailableDialog.ui
)
if (NOT Apple)
set (LAUNCHER_UI ${LAUNCHER_UI} ${PRISM_UPDATE_UI})
endif()
qt_add_resources(LAUNCHER_RESOURCES qt_add_resources(LAUNCHER_RESOURCES
resources/backgrounds/backgrounds.qrc resources/backgrounds/backgrounds.qrc
resources/multimc/multimc.qrc resources/multimc/multimc.qrc
@ -1085,14 +1206,31 @@ qt_add_resources(LAUNCHER_RESOURCES
../${Launcher_Branding_LogoQRC} ../${Launcher_Branding_LogoQRC}
) )
qt_wrap_ui(PRISMUPDATER_UI
updater/prismupdater/SelectReleaseDialog.ui
ui/widgets/SubTaskProgressBar.ui
ui/dialogs/ProgressDialog.ui
)
######## Windows resource files ######## ######## Windows resource files ########
if(WIN32) if(WIN32)
set(LAUNCHER_RCS ${CMAKE_CURRENT_BINARY_DIR}/../${Launcher_Branding_WindowsRC}) set(LAUNCHER_RCS ${CMAKE_CURRENT_BINARY_DIR}/../${Launcher_Branding_WindowsRC})
endif() endif()
include(CompilerWarnings)
# Add executable # Add executable
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})
if(BUILD_TESTING)
target_compile_definitions(Launcher_logic PUBLIC LAUNCHER_TEST)
endif()
set_project_warnings(Launcher_logic
"${Launcher_MSVC_WARNINGS}"
"${Launcher_CLANG_WARNINGS}"
"${Launcher_GCC_WARNINGS}")
target_compile_definitions(Launcher_logic PUBLIC LAUNCHER_APPLICATION)
target_include_directories(Launcher_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(Launcher_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(Launcher_logic PUBLIC LAUNCHER_APPLICATION)
target_link_libraries(Launcher_logic target_link_libraries(Launcher_logic
systeminfo systeminfo
Launcher_murmur2 Launcher_murmur2
@ -1131,17 +1269,23 @@ if(APPLE)
set(CMAKE_MACOSX_RPATH 1) set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/") set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/")
file(DOWNLOAD ${MACOSX_SPARKLE_DOWNLOAD_URL} ${CMAKE_BINARY_DIR}/Sparkle.tar.xz EXPECTED_HASH SHA256=${MACOSX_SPARKLE_SHA256}) if(Launcher_ENABLE_UPDATER)
file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle) file(DOWNLOAD ${MACOSX_SPARKLE_DOWNLOAD_URL} ${CMAKE_BINARY_DIR}/Sparkle.tar.xz EXPECTED_HASH SHA256=${MACOSX_SPARKLE_SHA256})
file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle)
find_library(SPARKLE_FRAMEWORK Sparkle "${CMAKE_BINARY_DIR}/frameworks/Sparkle")
add_compile_definitions(SPARKLE_ENABLED)
endif()
find_library(SPARKLE_FRAMEWORK Sparkle "${CMAKE_BINARY_DIR}/frameworks/Sparkle")
target_link_libraries(Launcher_logic target_link_libraries(Launcher_logic
"-framework AppKit" "-framework AppKit"
"-framework Carbon" "-framework Carbon"
"-framework Foundation" "-framework Foundation"
"-framework ApplicationServices" "-framework ApplicationServices"
) )
target_link_libraries(Launcher_logic ${SPARKLE_FRAMEWORK}) if(Launcher_ENABLE_UPDATER)
target_link_libraries(Launcher_logic ${SPARKLE_FRAMEWORK})
endif()
endif() endif()
target_link_libraries(Launcher_logic) target_link_libraries(Launcher_logic)
@ -1168,8 +1312,51 @@ install(TARGETS ${Launcher_Name}
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
) )
if(WIN32) if(Launcher_BUILD_UPDATER)
# Updater
add_library(prism_updater_logic STATIC ${PRISMUPDATER_SOURCES} ${TASKS_SOURCES} ${PRISMUPDATER_UI})
target_include_directories(prism_updater_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(prism_updater_logic
QuaZip::QuaZip
${ZLIB_LIBRARIES}
systeminfo
BuildConfig
ghcFilesystem::ghc_filesystem
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
${Launcher_QT_LIBS}
cmark::cmark
Katabasis
)
add_executable("${Launcher_Name}_updater" WIN32 updater/prismupdater/updater_main.cpp)
target_sources("${Launcher_Name}_updater" PRIVATE updater/prismupdater/updater.exe.manifest)
target_link_libraries("${Launcher_Name}_updater" prism_updater_logic)
if(DEFINED Launcher_APP_BINARY_NAME)
set_target_properties("${Launcher_Name}_updater" PROPERTIES OUTPUT_NAME "${Launcher_APP_BINARY_NAME}_updater")
endif()
if(DEFINED Launcher_BINARY_RPATH)
SET_TARGET_PROPERTIES("${Launcher_Name}_updater" PROPERTIES INSTALL_RPATH "${Launcher_BINARY_RPATH}")
endif()
install(TARGETS "${Launcher_Name}_updater"
BUNDLE DESTINATION "." COMPONENT Runtime
LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
)
endif()
if(WIN32 OR (DEFINED Launcher_BUILD_FILELINKER AND Launcher_BUILD_FILELINKER))
# File link
add_library(filelink_logic STATIC ${LINKEXE_SOURCES}) add_library(filelink_logic STATIC ${LINKEXE_SOURCES})
set_project_warnings(filelink_logic
"${Launcher_MSVC_WARNINGS}"
"${Launcher_CLANG_WARNINGS}"
"${Launcher_GCC_WARNINGS}")
target_include_directories(filelink_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(filelink_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(filelink_logic target_link_libraries(filelink_logic
systeminfo systeminfo
@ -1182,7 +1369,7 @@ if(WIN32)
${Launcher_QT_LIBS} ${Launcher_QT_LIBS}
) )
add_executable("${Launcher_Name}_filelink" WIN32 filelink/main.cpp) add_executable("${Launcher_Name}_filelink" WIN32 filelink/filelink_main.cpp)
target_sources("${Launcher_Name}_filelink" PRIVATE filelink/filelink.exe.manifest) target_sources("${Launcher_Name}_filelink" PRIVATE filelink/filelink.exe.manifest)
@ -1203,7 +1390,7 @@ if(WIN32)
) )
endif() endif()
if (UNIX AND APPLE) if (UNIX AND APPLE AND Launcher_ENABLE_UPDATER)
# Add Sparkle updater # Add Sparkle updater
# It has to be copied here instead of just allowing fixup_bundle to install it, otherwise essential parts of # It has to be copied here instead of just allowing fixup_bundle to install it, otherwise essential parts of
# the framework aren't installed # the framework aren't installed

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -41,8 +41,7 @@
* @file libutil/src/cmdutils.cpp * @file libutil/src/cmdutils.cpp
*/ */
namespace Commandline namespace Commandline {
{
// commandline splitter // commandline splitter
QStringList splitArgs(QString args) QStringList splitArgs(QString args)
@ -51,19 +50,15 @@ QStringList splitArgs(QString args)
QString current; QString current;
bool escape = false; bool escape = false;
QChar inquotes; QChar inquotes;
for (int i = 0; i < args.length(); i++) for (int i = 0; i < args.length(); i++) {
{
QChar cchar = args.at(i); QChar cchar = args.at(i);
// \ escaped // \ escaped
if (escape) if (escape) {
{
current += cchar; current += cchar;
escape = false; escape = false;
// in "quotes" // in "quotes"
} } else if (!inquotes.isNull()) {
else if (!inquotes.isNull())
{
if (cchar == '\\') if (cchar == '\\')
escape = true; escape = true;
else if (cchar == inquotes) else if (cchar == inquotes)
@ -71,18 +66,13 @@ QStringList splitArgs(QString args)
else else
current += cchar; current += cchar;
// otherwise // otherwise
} } else {
else if (cchar == ' ') {
{ if (!current.isEmpty()) {
if (cchar == ' ')
{
if (!current.isEmpty())
{
argv << current; argv << current;
current.clear(); current.clear();
} }
} } else if (cchar == '"' || cchar == '\'')
else if (cchar == '"' || cchar == '\'')
inquotes = cchar; inquotes = cchar;
else else
current += cchar; current += cchar;
@ -92,4 +82,4 @@ QStringList splitArgs(QString args)
argv << current; argv << current;
return argv; return argv;
} }
} } // namespace Commandline

View File

@ -25,8 +25,7 @@
* @brief commandline parsing and processing utilities * @brief commandline parsing and processing utilities
*/ */
namespace Commandline namespace Commandline {
{
/** /**
* @brief split a string into argv items like a shell would do * @brief split a string into argv items like a shell would do
@ -34,4 +33,4 @@ namespace Commandline
* @return a QStringList containing all arguments * @return a QStringList containing all arguments
*/ */
QStringList splitArgs(QString args); QStringList splitArgs(QString args);
} } // namespace Commandline

View File

@ -1,33 +1,21 @@
#pragma once #pragma once
template <typename T> template <typename T>
class DefaultVariable class DefaultVariable {
{ public:
public: DefaultVariable(const T& value) { defaultValue = value; }
DefaultVariable(const T & value) DefaultVariable<T>& operator=(const T& value)
{
defaultValue = value;
}
DefaultVariable<T> & operator =(const T & value)
{ {
currentValue = value; currentValue = value;
is_default = currentValue == defaultValue; is_default = currentValue == defaultValue;
is_explicit = true; is_explicit = true;
return *this; return *this;
} }
operator const T &() const operator const T&() const { return is_default ? defaultValue : currentValue; }
{ bool isDefault() const { return is_default; }
return is_default ? defaultValue : currentValue; bool isExplicit() const { return is_explicit; }
}
bool isDefault() const private:
{
return is_default;
}
bool isExplicit() const
{
return is_explicit;
}
private:
T currentValue; T currentValue;
T defaultValue; T defaultValue;
bool is_default = true; bool is_default = true;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 dada513 <dada513@protonmail.com> * Copyright (C) 2022 dada513 <dada513@protonmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -33,40 +33,37 @@
* limitations under the License. * limitations under the License.
*/ */
#include "DesktopServices.h" #include "DesktopServices.h"
#include <QDir>
#include <QDesktopServices>
#include <QProcess>
#include <QDebug> #include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QProcess>
/** /**
* 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.
*/ */
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h>
template <typename T> template <typename T>
bool IndirectOpen(T callable, qint64 *pid_forked = nullptr) bool IndirectOpen(T callable, qint64* pid_forked = nullptr)
{ {
auto pid = fork(); auto pid = fork();
if(pid_forked) if (pid_forked) {
{ if (pid > 0)
if(pid > 0)
*pid_forked = pid; *pid_forked = pid;
else else
*pid_forked = 0; *pid_forked = 0;
} }
if(pid == -1) if (pid == -1) {
{
qWarning() << "IndirectOpen failed to fork: " << errno; qWarning() << "IndirectOpen failed to fork: " << errno;
return false; return false;
} }
// child - do the stuff // child - do the stuff
if(pid == 0) if (pid == 0) {
{
// unset all this garbage so it doesn't get passed to the child process // unset all this garbage so it doesn't get passed to the child process
qunsetenv("LD_PRELOAD"); qunsetenv("LD_PRELOAD");
qunsetenv("LD_LIBRARY_PATH"); qunsetenv("LD_LIBRARY_PATH");
@ -82,19 +79,14 @@ bool IndirectOpen(T callable, qint64 *pid_forked = nullptr)
// die. now. do not clean up anything, it would just hang forever. // die. now. do not clean up anything, it would just hang forever.
_exit(status ? 0 : 1); _exit(status ? 0 : 1);
} } else {
else // parent - assume it worked.
{
//parent - assume it worked.
int status; int status;
while (waitpid(pid, &status, 0)) while (waitpid(pid, &status, 0)) {
{ if (WIFEXITED(status)) {
if(WIFEXITED(status))
{
return WEXITSTATUS(status) == 0; return WEXITSTATUS(status) == 0;
} }
if(WIFSIGNALED(status)) if (WIFSIGNALED(status)) {
{
return false; return false;
} }
} }
@ -104,26 +96,19 @@ bool IndirectOpen(T callable, qint64 *pid_forked = nullptr)
#endif #endif
namespace DesktopServices { namespace DesktopServices {
bool openDirectory(const QString &path, bool ensureExists) bool openDirectory(const QString& path, [[maybe_unused]] bool ensureExists)
{ {
qDebug() << "Opening directory" << path; qDebug() << "Opening directory" << path;
QDir parentPath; QDir parentPath;
QDir dir(path); QDir dir(path);
if (!dir.exists()) if (ensureExists && !dir.exists()) {
{
parentPath.mkpath(dir.absolutePath()); parentPath.mkpath(dir.absolutePath());
} }
auto f = [&]() auto f = [&]() { 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)
if(!isFlatpak()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -131,20 +116,14 @@ bool openDirectory(const QString &path, bool ensureExists)
#endif #endif
} }
bool openFile(const QString &path) bool openFile(const QString& path)
{ {
qDebug() << "Opening file" << path; qDebug() << "Opening file" << path;
auto f = [&]() auto f = [&]() { 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)
if(!isFlatpak()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -152,41 +131,29 @@ bool openFile(const QString &path)
#endif #endif
} }
bool openFile(const QString &application, const QString &path, const QString &workingDirectory, qint64 *pid) bool openFile(const QString& application, const QString& path, const QString& workingDirectory, qint64* pid)
{ {
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
if(!isFlatpak()) if (!isSandbox()) {
{ return IndirectOpen([&]() { return QProcess::startDetached(application, QStringList() << path, workingDirectory); }, pid);
return IndirectOpen([&]() } else {
{ return QProcess::startDetached(application, QStringList() << path, workingDirectory, 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
} }
bool run(const QString &application, const QStringList &args, const QString &workingDirectory, qint64 *pid) bool run(const QString& application, const QStringList& args, const QString& workingDirectory, qint64* pid)
{ {
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(!isFlatpak()) if (!isSandbox()) {
{ // 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 QProcess::startDetached(application, args, workingDirectory); }, pid);
return IndirectOpen([&]() } else {
{
return QProcess::startDetached(application, args, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, args, workingDirectory, pid); return QProcess::startDetached(application, args, workingDirectory, pid);
} }
#else #else
@ -194,20 +161,14 @@ bool run(const QString &application, const QStringList &args, const QString &wor
#endif #endif
} }
bool openUrl(const QUrl &url) bool openUrl(const QUrl& url)
{ {
qDebug() << "Opening URL" << url.toString(); qDebug() << "Opening URL" << url.toString();
auto f = [&]() auto f = [&]() { 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)
if(!isFlatpak()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -224,4 +185,18 @@ bool isFlatpak()
#endif #endif
} }
bool isSnap()
{
#ifdef Q_OS_LINUX
return getenv("SNAP");
#else
return false;
#endif
} }
bool isSandbox()
{
return isSnap() || isFlatpak();
}
} // namespace DesktopServices

View File

@ -1,38 +1,50 @@
#pragma once #pragma once
#include <QUrl>
#include <QString> #include <QString>
#include <QUrl>
/** /**
* This wraps around QDesktopServices and adds workarounds where needed * This wraps around QDesktopServices and adds workarounds where needed
* Use this instead of QDesktopServices! * Use this instead of QDesktopServices!
*/ */
namespace DesktopServices namespace DesktopServices {
{ /**
/** * Open a file in whatever application is applicable
* Open a file in whatever application is applicable */
*/ bool openFile(const QString& path);
bool openFile(const QString &path);
/** /**
* Open a file in the specified application * Open a file in the specified application
*/ */
bool openFile(const QString &application, const QString &path, const QString & workingDirectory = QString(), qint64 *pid = 0); bool openFile(const QString& application, const QString& path, const QString& workingDirectory = QString(), qint64* pid = 0);
/** /**
* Run an application * Run an application
*/ */
bool run(const QString &application,const QStringList &args, const QString & workingDirectory = QString(), qint64 *pid = 0); bool run(const QString& application, const QStringList& args, const QString& workingDirectory = QString(), qint64* pid = 0);
/** /**
* Open a directory * Open a directory
*/ */
bool openDirectory(const QString &path, bool ensureExists = false); bool openDirectory(const QString& path, bool ensureExists = false);
/** /**
* Open the URL, most likely in a browser. Maybe. * Open the URL, most likely in a browser. Maybe.
*/ */
bool openUrl(const QUrl &url); bool openUrl(const QUrl& url);
bool isFlatpak(); /**
} * Determine whether the launcher is running in a Flatpak environment
*/
bool isFlatpak();
/**
* Determine whether the launcher is running in a Snap environment
*/
bool isSnap();
/**
* Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment
*/
bool isSandbox();
} // namespace DesktopServices

View File

@ -2,31 +2,18 @@
#pragma once #pragma once
#include <QString>
#include <QDebug> #include <QDebug>
#include <QString>
#include <exception> #include <exception>
class Exception : public std::exception class Exception : public std::exception {
{ public:
public: Exception(const QString& message) : std::exception(), m_message(message) { qCritical() << "Exception:" << message; }
Exception(const QString &message) : std::exception(), m_message(message) Exception(const Exception& other) : std::exception(), m_message(other.cause()) {}
{
qCritical() << "Exception:" << message;
}
Exception(const Exception &other)
: std::exception(), m_message(other.cause())
{
}
virtual ~Exception() noexcept {} virtual ~Exception() noexcept {}
const char *what() const noexcept const char* what() const noexcept { return m_message.toLatin1().constData(); }
{ QString cause() const { return m_message; }
return m_message.toLatin1().constData();
}
QString cause() const
{
return m_message;
}
private: private:
QString m_message; QString m_message;
}; };

View File

@ -4,31 +4,24 @@
template <typename T> template <typename T>
inline void clamp(T& current, T min, T max) inline void clamp(T& current, T min, T max)
{ {
if (current < min) if (current < min) {
{
current = min; current = min;
} } else if (current > max) {
else if(current > max)
{
current = max; current = max;
} }
} }
// List of numbers from min to max. Next is exponent times bigger than previous. // List of numbers from min to max. Next is exponent times bigger than previous.
class ExponentialSeries class ExponentialSeries {
{ public:
public:
ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2) ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2)
{ {
m_current = m_min = min; m_current = m_min = min;
m_max = max; m_max = max;
m_exponent = exponent; m_exponent = exponent;
} }
void reset() void reset() { m_current = m_min; }
{
m_current = m_min;
}
unsigned operator()() unsigned operator()()
{ {
unsigned retval = m_current; unsigned retval = m_current;

View File

@ -267,10 +267,7 @@ bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceP
bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const
{ {
auto fileName = fileInfo.fileName(); return m_ignoreFiles.contains(fileInfo.fileName()) || m_ignoreFilePaths.covers(relPath(fileInfo.absoluteFilePath()));
auto path = relPath(fileInfo.absoluteFilePath());
return std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) ||
m_ignoreFilePaths.covers(path);
} }
bool FileIgnoreProxy::filterFile(const QString& fileName) const bool FileIgnoreProxy::filterFile(const QString& fileName) const

View File

@ -123,26 +123,35 @@ namespace fs = ghc::filesystem;
#if defined(__MINGW32__) #if defined(__MINGW32__)
typedef struct _DUPLICATE_EXTENTS_DATA { struct _DUPLICATE_EXTENTS_DATA {
HANDLE FileHandle; HANDLE FileHandle;
LARGE_INTEGER SourceFileOffset; LARGE_INTEGER SourceFileOffset;
LARGE_INTEGER TargetFileOffset; LARGE_INTEGER TargetFileOffset;
LARGE_INTEGER ByteCount; LARGE_INTEGER ByteCount;
} DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; };
typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { using DUPLICATE_EXTENTS_DATA = _DUPLICATE_EXTENTS_DATA;
using PDUPLICATE_EXTENTS_DATA = _DUPLICATE_EXTENTS_DATA*;
struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {
WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32 WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32
WORD Reserved; // Must be 0 WORD Reserved; // Must be 0
DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx
DWORD ChecksumChunkSizeInBytes; DWORD ChecksumChunkSizeInBytes;
DWORD ClusterSizeInBytes; DWORD ClusterSizeInBytes;
} FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; };
typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { using FSCTL_GET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER;
using PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER*;
struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32 WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32
WORD Reserved; // Must be 0 WORD Reserved; // Must be 0
DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx
} FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; };
using FSCTL_SET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER;
using PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER*;
#endif #endif
@ -194,6 +203,40 @@ void write(const QString& filename, const QByteArray& data)
} }
} }
void appendSafe(const QString& filename, const QByteArray& data)
{
ensureExists(QFileInfo(filename).dir());
QByteArray buffer;
try {
buffer = read(filename);
} catch (FileSystemException&) {
buffer = QByteArray();
}
buffer.append(data);
QSaveFile file(filename);
if (!file.open(QSaveFile::WriteOnly)) {
throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString());
}
if (buffer.size() != file.write(buffer)) {
throw FileSystemException("Error writing data to " + filename + ": " + file.errorString());
}
if (!file.commit()) {
throw FileSystemException("Error while committing data to " + filename + ": " + file.errorString());
}
}
void append(const QString& filename, const QByteArray& data)
{
ensureExists(QFileInfo(filename).dir());
QFile file(filename);
if (!file.open(QFile::Append)) {
throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString());
}
if (data.size() != file.write(data)) {
throw FileSystemException("Error writing data to " + filename + ": " + file.errorString());
}
}
QByteArray read(const QString& filename) QByteArray read(const QString& filename)
{ {
QFile file(filename); QFile file(filename);
@ -238,6 +281,28 @@ bool ensureFolderPathExists(QString foldernamepath)
return success; return success;
} }
bool copyFileAttributes(QString src, QString dst)
{
#ifdef Q_OS_WIN32
auto attrs = GetFileAttributesW(src.toStdWString().c_str());
if (attrs == INVALID_FILE_ATTRIBUTES)
return false;
return SetFileAttributesW(dst.toStdWString().c_str(), attrs);
#endif
return true;
}
// needs folders to exists
void copyFolderAttributes(QString src, QString dst, QString relative)
{
auto path = PathCombine(src, relative);
QDir dsrc(src);
while ((path = QFileInfo(path).path()).length() >= src.length()) {
auto dst_path = PathCombine(dst, dsrc.relativeFilePath(path));
copyFileAttributes(path, dst_path);
}
}
/** /**
* @brief Copies a directory and it's contents from src to dest * @brief Copies a directory and it's contents from src to dest
* @param offset subdirectory form src to copy to dest * @param offset subdirectory form src to copy to dest
@ -265,6 +330,9 @@ bool copy::operator()(const QString& offset, bool dryRun)
if (!m_followSymlinks) if (!m_followSymlinks)
opt |= copy_opts::copy_symlinks; opt |= copy_opts::copy_symlinks;
if (m_overwrite)
opt |= copy_opts::overwrite_existing;
// Function that'll do the actual copying // Function that'll do the actual copying
auto copy_file = [&](QString src_path, QString relative_dst_path) { auto copy_file = [&](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist))
@ -273,6 +341,9 @@ bool copy::operator()(const QString& offset, bool dryRun)
auto dst_path = PathCombine(dst, relative_dst_path); auto dst_path = PathCombine(dst, relative_dst_path);
if (!dryRun) { if (!dryRun) {
ensureFilePathExists(dst_path); ensureFilePathExists(dst_path);
#ifdef Q_OS_WIN32
copyFolderAttributes(src, dst, relative_dst_path);
#endif
fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err); fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err);
} }
if (err) { if (err) {
@ -778,9 +849,44 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name));
} }
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
destination += ".command"; // Create the Application
QDir applicationDirectory =
QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/";
QFile f(destination); if (!applicationDirectory.mkpath(".")) {
qWarning() << "Couldn't create application directory";
return false;
}
QDir application = applicationDirectory.path() + "/" + name + ".app/";
if (application.exists()) {
qWarning() << "Application already exists!";
return false;
}
if (!application.mkpath(".")) {
qWarning() << "Couldn't create application";
return false;
}
QDir content = application.path() + "/Contents/";
QDir resources = content.path() + "/Resources/";
QDir binaryDir = content.path() + "/MacOS/";
QFile info = content.path() + "/Info.plist";
if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) {
qWarning() << "Couldn't create directories within application";
return false;
}
info.open(QIODevice::WriteOnly | QIODevice::Text);
QFile(icon).rename(resources.path() + "/Icon.icns");
// Create the Command file
QString exec = binaryDir.path() + "/Run.command";
QFile f(exec);
f.open(QIODevice::WriteOnly | QIODevice::Text); f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f); QTextStream stream(&f);
@ -797,6 +903,30 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
// Generate the Info.plist
QTextStream infoStream(&info);
infoStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n"
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
"<plist version=\"1.0\">\n"
"<dict>\n"
" <key>CFBundleExecutable</key>\n"
" <string>Run.command</string>\n" // The path to the executable
" <key>CFBundleIconFile</key>\n"
" <string>Icon.icns</string>\n"
" <key>CFBundleName</key>\n"
" <string>"
<< name
<< "</string>\n" // Name of the application
" <key>CFBundlePackageType</key>\n"
" <string>APPL</string>\n"
" <key>CFBundleShortVersionString</key>\n"
" <string>1.0</string>\n"
" <key>CFBundleVersion</key>\n"
" <string>1.0</string>\n"
"</dict>\n"
"</plist>";
return true; return true;
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated

View File

@ -43,10 +43,10 @@
#include <system_error> #include <system_error>
#include <QDir> #include <QDir>
#include <QPair>
#include <QFlags> #include <QFlags>
#include <QLocalServer> #include <QLocalServer>
#include <QObject> #include <QObject>
#include <QPair>
#include <QThread> #include <QThread>
namespace FS { namespace FS {
@ -61,6 +61,16 @@ class FileSystemException : public ::Exception {
*/ */
void write(const QString& filename, const QByteArray& data); void write(const QString& filename, const QByteArray& data);
/**
* append data to a file safely
*/
void appendSafe(const QString& filename, const QByteArray& data);
/**
* append data to a file
*/
void append(const QString& filename, const QByteArray& data);
/** /**
* read data from a file safely\ * read data from a file safely\
*/ */
@ -109,11 +119,16 @@ class copy : public QObject {
m_whitelist = whitelist; m_whitelist = whitelist;
return *this; return *this;
} }
copy& overwrite(const bool overwrite)
{
m_overwrite = overwrite;
return *this;
}
bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); } bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
int totalCopied() { return m_copied; } qsizetype totalCopied() { return m_copied; }
int totalFailed() { return m_failedPaths.length(); } qsizetype totalFailed() { return m_failedPaths.length(); }
QStringList failed() { return m_failedPaths; } QStringList failed() { return m_failedPaths; }
signals: signals:
@ -128,9 +143,10 @@ class copy : public QObject {
bool m_followSymlinks = true; bool m_followSymlinks = true;
const IPathMatcher* m_matcher = nullptr; const IPathMatcher* m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
bool m_overwrite = false;
QDir m_src; QDir m_src;
QDir m_dst; QDir m_dst;
int m_copied; qsizetype m_copied;
QStringList m_failedPaths; QStringList m_failedPaths;
}; };
@ -365,25 +381,24 @@ enum class FilesystemType {
* QMap is ordered * QMap is ordered
* *
*/ */
static const QMap<FilesystemType, QStringList> s_filesystem_type_names = { static const QMap<FilesystemType, QStringList> s_filesystem_type_names = { { FilesystemType::FAT, { "FAT" } },
{FilesystemType::FAT, { "FAT" }}, { FilesystemType::NTFS, { "NTFS" } },
{FilesystemType::NTFS, { "NTFS" }}, { FilesystemType::REFS, { "REFS" } },
{FilesystemType::REFS, { "REFS" }}, { FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" } },
{FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" }}, { FilesystemType::EXT_2_3_4,
{FilesystemType::EXT_2_3_4, { "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" }}, { "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" } },
{FilesystemType::EXT, { "EXT" }}, { FilesystemType::EXT, { "EXT" } },
{FilesystemType::XFS, { "XFS" }}, { FilesystemType::XFS, { "XFS" } },
{FilesystemType::BTRFS, { "BTRFS" }}, { FilesystemType::BTRFS, { "BTRFS" } },
{FilesystemType::NFS, { "NFS" }}, { FilesystemType::NFS, { "NFS" } },
{FilesystemType::ZFS, { "ZFS" }}, { FilesystemType::ZFS, { "ZFS" } },
{FilesystemType::APFS, { "APFS" }}, { FilesystemType::APFS, { "APFS" } },
{FilesystemType::HFS, { "HFS" }}, { FilesystemType::HFS, { "HFS" } },
{FilesystemType::HFSPLUS, { "HFSPLUS" }}, { FilesystemType::HFSPLUS, { "HFSPLUS" } },
{FilesystemType::HFSX, { "HFSX" }}, { FilesystemType::HFSX, { "HFSX" } },
{FilesystemType::FUSEBLK, { "FUSEBLK" }}, { FilesystemType::FUSEBLK, { "FUSEBLK" } },
{FilesystemType::F2FS, { "F2FS" }}, { FilesystemType::F2FS, { "F2FS" } },
{FilesystemType::UNKNOWN, { "UNKNOWN" }} { FilesystemType::UNKNOWN, { "UNKNOWN" } } };
};
/** /**
* @brief Get the string name of Filesystem enum object * @brief Get the string name of Filesystem enum object
@ -475,8 +490,8 @@ class clone : public QObject {
bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); } bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
int totalCloned() { return m_cloned; } qsizetype totalCloned() { return m_cloned; }
int totalFailed() { return m_failedClones.length(); } qsizetype totalFailed() { return m_failedClones.length(); }
QList<QPair<QString, QString>> failed() { return m_failedClones; } QList<QPair<QString, QString>> failed() { return m_failedClones; }
@ -492,7 +507,7 @@ class clone : public QObject {
bool m_whitelist = false; bool m_whitelist = false;
QDir m_src; QDir m_src;
QDir m_dst; QDir m_dst;
int m_cloned; qsizetype m_cloned;
QList<QPair<QString, QString>> m_failedClones; QList<QPair<QString, QString>> m_failedClones;
}; };

View File

@ -1,28 +1,33 @@
#include "Filter.h" #include "Filter.h"
Filter::~Filter(){} Filter::~Filter() {}
ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern){} ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern) {}
ContainsFilter::~ContainsFilter(){} ContainsFilter::~ContainsFilter() {}
bool ContainsFilter::accepts(const QString& value) bool ContainsFilter::accepts(const QString& value)
{ {
return value.contains(pattern); return value.contains(pattern);
} }
ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern){} ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern) {}
ExactFilter::~ExactFilter(){} ExactFilter::~ExactFilter() {}
bool ExactFilter::accepts(const QString& value) bool ExactFilter::accepts(const QString& value)
{ {
return value == pattern; return value == pattern;
} }
RegexpFilter::RegexpFilter(const QString& regexp, bool invert) ExactIfPresentFilter::ExactIfPresentFilter(const QString& pattern) : pattern(pattern) {}
:invert(invert) bool ExactIfPresentFilter::accepts(const QString& value)
{
return value.isEmpty() || value == pattern;
}
RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert)
{ {
pattern.setPattern(regexp); pattern.setPattern(regexp);
pattern.optimize(); pattern.optimize();
} }
RegexpFilter::~RegexpFilter(){} RegexpFilter::~RegexpFilter() {}
bool RegexpFilter::accepts(const QString& value) bool RegexpFilter::accepts(const QString& value)
{ {
auto match = pattern.match(value); auto match = pattern.match(value);

View File

@ -1,42 +1,51 @@
#pragma once #pragma once
#include <QString>
#include <QRegularExpression> #include <QRegularExpression>
#include <QString>
class Filter class Filter {
{ public:
public:
virtual ~Filter(); virtual ~Filter();
virtual bool accepts(const QString & value) = 0; virtual bool accepts(const QString& value) = 0;
}; };
class ContainsFilter: public Filter class ContainsFilter : public Filter {
{ public:
public: ContainsFilter(const QString& pattern);
ContainsFilter(const QString &pattern);
virtual ~ContainsFilter(); virtual ~ContainsFilter();
bool accepts(const QString & value) override; bool accepts(const QString& value) override;
private:
private:
QString pattern; QString pattern;
}; };
class ExactFilter: public Filter class ExactFilter : public Filter {
{ public:
public: ExactFilter(const QString& pattern);
ExactFilter(const QString &pattern);
virtual ~ExactFilter(); virtual ~ExactFilter();
bool accepts(const QString & value) override; bool accepts(const QString& value) override;
private:
private:
QString pattern; QString pattern;
}; };
class RegexpFilter: public Filter class ExactIfPresentFilter : public Filter {
{ public:
public: ExactIfPresentFilter(const QString& pattern);
RegexpFilter(const QString &regexp, bool invert); ~ExactIfPresentFilter() override = default;
bool accepts(const QString& value) override;
private:
QString pattern;
};
class RegexpFilter : public Filter {
public:
RegexpFilter(const QString& regexp, bool invert);
virtual ~RegexpFilter(); virtual ~RegexpFilter();
bool accepts(const QString & value) override; bool accepts(const QString& value) override;
private:
private:
QRegularExpression pattern; QRegularExpression pattern;
bool invert = false; bool invert = false;
}; };

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -37,10 +37,9 @@
#include <zlib.h> #include <zlib.h>
#include <QByteArray> #include <QByteArray>
bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes) bool GZip::unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes)
{ {
if (compressedBytes.size() == 0) if (compressedBytes.size() == 0) {
{
uncompressedBytes = compressedBytes; uncompressedBytes = compressedBytes;
return true; return true;
} }
@ -51,42 +50,37 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
z_stream strm; z_stream strm;
memset(&strm, 0, sizeof(strm)); memset(&strm, 0, sizeof(strm));
strm.next_in = (Bytef *)compressedBytes.data(); strm.next_in = (Bytef*)compressedBytes.data();
strm.avail_in = compressedBytes.size(); strm.avail_in = compressedBytes.size();
bool done = false; bool done = false;
if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
{
return false; return false;
} }
int err = Z_OK; int err = Z_OK;
while (!done) while (!done) {
{
// If our output buffer is too small // If our output buffer is too small
if (strm.total_out >= uncompLength) if (strm.total_out >= uncompLength) {
{
uncompressedBytes.resize(uncompLength * 2); uncompressedBytes.resize(uncompLength * 2);
uncompLength *= 2; uncompLength *= 2;
} }
strm.next_out = reinterpret_cast<Bytef *>((uncompressedBytes.data() + strm.total_out)); strm.next_out = reinterpret_cast<Bytef*>((uncompressedBytes.data() + strm.total_out));
strm.avail_out = uncompLength - strm.total_out; strm.avail_out = uncompLength - strm.total_out;
// Inflate another chunk. // Inflate another chunk.
err = inflate(&strm, Z_SYNC_FLUSH); err = inflate(&strm, Z_SYNC_FLUSH);
if (err == Z_STREAM_END) if (err == Z_STREAM_END)
done = true; done = true;
else if (err != Z_OK) else if (err != Z_OK) {
{
break; break;
} }
} }
if (inflateEnd(&strm) != Z_OK || !done) if (inflateEnd(&strm) != Z_OK || !done) {
{
return false; return false;
} }
@ -94,10 +88,9 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
return true; return true;
} }
bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) bool GZip::zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes)
{ {
if (uncompressedBytes.size() == 0) if (uncompressedBytes.size() == 0) {
{
compressedBytes = uncompressedBytes; compressedBytes = uncompressedBytes;
return true; return true;
} }
@ -109,8 +102,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
z_stream zs; z_stream zs;
memset(&zs, 0, sizeof(zs)); memset(&zs, 0, sizeof(zs));
if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) {
{
return false; return false;
} }
@ -122,11 +114,9 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
unsigned offset = 0; unsigned offset = 0;
unsigned temp = 0; unsigned temp = 0;
do do {
{
auto remaining = compressedBytes.size() - offset; auto remaining = compressedBytes.size() - offset;
if(remaining < 1) if (remaining < 1) {
{
compressedBytes.resize(compressedBytes.size() * 2); compressedBytes.resize(compressedBytes.size() * 2);
} }
zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset)); zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset));
@ -137,13 +127,11 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
compressedBytes.resize(offset); compressedBytes.resize(offset);
if (deflateEnd(&zs) != Z_OK) if (deflateEnd(&zs) != Z_OK) {
{
return false; return false;
} }
if (ret != Z_STREAM_END) if (ret != Z_STREAM_END) {
{
return false; return false;
} }
return true; return true;

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <QByteArray> #include <QByteArray>
class GZip class GZip {
{ public:
public: static bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes);
static bool unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes); static bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes);
static bool zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes);
}; };

View File

@ -6,17 +6,10 @@
bool InstanceCopyPrefs::allTrue() const bool InstanceCopyPrefs::allTrue() const
{ {
return copySaves && return copySaves && keepPlaytime && copyGameOptions && copyResourcePacks && copyShaderPacks && copyServers && copyMods &&
keepPlaytime && copyScreenshots;
copyGameOptions &&
copyResourcePacks &&
copyShaderPacks &&
copyServers &&
copyMods &&
copyScreenshots;
} }
// Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat") // Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat")
QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const
{ {
@ -26,25 +19,30 @@ QString InstanceCopyPrefs::getSelectedFiltersAsRegex(const QStringList& addition
{ {
QStringList filters; QStringList filters;
if(!copySaves) if (!copySaves)
filters << "saves"; filters << "saves";
if(!copyGameOptions) if (!copyGameOptions)
filters << "options.txt"; filters << "options.txt";
if(!copyResourcePacks) if (!copyResourcePacks)
filters << "resourcepacks" << "texturepacks"; filters << "resourcepacks"
<< "texturepacks";
if(!copyShaderPacks) if (!copyShaderPacks)
filters << "shaderpacks"; filters << "shaderpacks";
if(!copyServers) if (!copyServers)
filters << "servers.dat" << "servers.dat_old" << "server-resource-packs"; filters << "servers.dat"
<< "servers.dat_old"
<< "server-resource-packs";
if(!copyMods) if (!copyMods)
filters << "coremods" << "mods" << "config"; filters << "coremods"
<< "mods"
<< "config";
if(!copyScreenshots) if (!copyScreenshots)
filters << "screenshots"; filters << "screenshots";
for (auto filter : additionalFilters) { for (auto filter : additionalFilters) {

View File

@ -40,7 +40,7 @@ struct InstanceCopyPrefs {
void enableDontLinkSaves(bool b); void enableDontLinkSaves(bool b);
void enableUseClone(bool b); void enableUseClone(bool b);
protected: // data protected: // data
bool copySaves = true; bool copySaves = true;
bool keepPlaytime = true; bool keepPlaytime = true;
bool copyGameOptions = true; bool copyGameOptions = true;

View File

@ -156,8 +156,9 @@ void InstanceCopyTask::copyFinished()
allowed_symlinks.append(m_origInstance->gameRoot().toUtf8()); allowed_symlinks.append(m_origInstance->gameRoot().toUtf8());
allowed_symlinks.append("\n"); allowed_symlinks.append("\n");
if (allowed_symlinks_file.isSymLink()) if (allowed_symlinks_file.isSymLink())
FS::deletePath(allowed_symlinks_file FS::deletePath(
.filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link. allowed_symlinks_file
.filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link.
FS::write(allowed_symlinks_file.filePath(), allowed_symlinks); FS::write(allowed_symlinks_file.filePath(), allowed_symlinks);
} }

View File

@ -11,19 +11,18 @@
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "tasks/Task.h" #include "tasks/Task.h"
class InstanceCopyTask : public InstanceTask class InstanceCopyTask : public InstanceTask {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs); explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs);
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
virtual void executeTask() override; virtual void executeTask() override;
void copyFinished(); void copyFinished();
void copyAborted(); void copyAborted();
private: private:
/* data */ /* data */
InstancePtr m_origInstance; InstancePtr m_origInstance;
QFuture<bool> m_copyFuture; QFuture<bool> m_copyFuture;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
* *
@ -45,11 +45,14 @@
#include "icons/IconList.h" #include "icons/IconList.h"
#include "icons/IconUtils.h" #include "icons/IconUtils.h"
#include "modplatform/technic/TechnicPackProcessor.h"
#include "modplatform/modrinth/ModrinthInstanceCreationTask.h"
#include "modplatform/flame/FlameInstanceCreationTask.h" #include "modplatform/flame/FlameInstanceCreationTask.h"
#include "modplatform/modrinth/ModrinthInstanceCreationTask.h"
#include "modplatform/technic/TechnicPackProcessor.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "tasks/Task.h"
#include "net/ApiDownload.h"
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <algorithm> #include <algorithm>
@ -88,25 +91,27 @@ void InstanceImportTask::executeTask()
setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));
m_downloadRequired = true; m_downloadRequired = true;
const QString path(m_sourceUrl.host() + '/' + m_sourceUrl.path()); downloadFromUrl();
auto entry = APPLICATION->metacache()->resolveEntry("general", path);
entry->setStale(true);
m_archivePath = entry->getFullPath();
m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network()));
m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged);
connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress);
connect(m_filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::downloadFailed);
connect(m_filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::downloadAborted);
m_filesNetJob->start();
} }
} }
void InstanceImportTask::downloadFromUrl()
{
const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
auto entry = APPLICATION->metacache()->resolveEntry("general", path);
entry->setStale(true);
m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network()));
m_filesNetJob->addNetAction(Net::ApiDownload::makeCached(m_sourceUrl, entry));
m_archivePath = entry->getFullPath();
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged);
connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(m_filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::downloadFailed);
connect(m_filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::downloadAborted);
m_filesNetJob->start();
}
void InstanceImportTask::downloadSucceeded() void InstanceImportTask::downloadSucceeded()
{ {
processZipPack(); processZipPack();
@ -138,8 +143,7 @@ void InstanceImportTask::processZipPack()
// open the zip and find relevant files in it // open the zip and find relevant files in it
m_packZip.reset(new QuaZip(m_archivePath)); m_packZip.reset(new QuaZip(m_archivePath));
if (!m_packZip->open(QuaZip::mdUnzip)) if (!m_packZip->open(QuaZip::mdUnzip)) {
{
emitFailed(tr("Unable to open supplied modpack zip file.")); emitFailed(tr("Unable to open supplied modpack zip file."));
return; return;
} }
@ -153,44 +157,40 @@ void InstanceImportTask::processZipPack()
// NOTE: Prioritize modpack platforms that aren't searched for recursively. // NOTE: Prioritize modpack platforms that aren't searched for recursively.
// Especially Flame has a very common filename for its manifest, which may appear inside overrides for example // Especially Flame has a very common filename for its manifest, which may appear inside overrides for example
if(modrinthFound) if (modrinthFound) {
{
// process as Modrinth pack // process as Modrinth pack
qDebug() << "Modrinth:" << modrinthFound; qDebug() << "Modrinth:" << modrinthFound;
m_modpackType = ModpackType::Modrinth; m_modpackType = ModpackType::Modrinth;
} } else if (technicFound) {
else if (technicFound)
{
// process as Technic pack // process as Technic pack
qDebug() << "Technic:" << technicFound; qDebug() << "Technic:" << technicFound;
extractDir.mkpath(".minecraft"); extractDir.mkpath(".minecraft");
extractDir.cd(".minecraft"); extractDir.cd(".minecraft");
m_modpackType = ModpackType::Technic; m_modpackType = ModpackType::Technic;
} } else {
else QStringList paths_to_ignore{ "overrides/" };
{
QStringList paths_to_ignore { "overrides/" };
if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) { if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) {
// process as MultiMC instance/pack // process as MultiMC instance/pack
qDebug() << "MultiMC:" << mmcRoot; qDebug() << "MultiMC:" << mmcRoot;
root = mmcRoot; root = mmcRoot;
m_modpackType = ModpackType::MultiMC; m_modpackType = ModpackType::MultiMC;
} else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore); !flameRoot.isNull()) { } else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore);
!flameRoot.isNull()) {
// process as Flame pack // process as Flame pack
qDebug() << "Flame:" << flameRoot; qDebug() << "Flame:" << flameRoot;
root = flameRoot; root = flameRoot;
m_modpackType = ModpackType::Flame; m_modpackType = ModpackType::Flame;
} }
} }
if(m_modpackType == ModpackType::Unknown) if (m_modpackType == ModpackType::Unknown) {
{
emitFailed(tr("Archive does not contain a recognized modpack type.")); emitFailed(tr("Archive does not contain a recognized modpack type."));
return; return;
} }
// make sure we extract just the pack // make sure we extract just the pack
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath()); m_extractFuture =
QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath());
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished); connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished);
m_extractFutureWatcher.setFuture(m_extractFuture); m_extractFutureWatcher.setFuture(m_extractFuture);
} }
@ -210,37 +210,28 @@ void InstanceImportTask::extractFinished()
qDebug() << "Fixing permissions for extracted pack files..."; qDebug() << "Fixing permissions for extracted pack files...";
QDirIterator it(extractDir, QDirIterator::Subdirectories); QDirIterator it(extractDir, QDirIterator::Subdirectories);
while (it.hasNext()) while (it.hasNext()) {
{
auto filepath = it.next(); auto filepath = it.next();
QFileInfo file(filepath); QFileInfo file(filepath);
auto permissions = QFile::permissions(filepath); auto permissions = QFile::permissions(filepath);
auto origPermissions = permissions; auto origPermissions = permissions;
if(file.isDir()) if (file.isDir()) {
{
// Folder +rwx for current user // Folder +rwx for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser; permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
} } else {
else
{
// File +rw for current user // File +rw for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser; permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
} }
if(origPermissions != permissions) if (origPermissions != permissions) {
{ if (!QFile::setPermissions(filepath, permissions)) {
if(!QFile::setPermissions(filepath, permissions))
{
logWarning(tr("Could not fix permissions for %1").arg(filepath)); logWarning(tr("Could not fix permissions for %1").arg(filepath));
} } else {
else
{
qDebug() << "Fixed" << filepath; qDebug() << "Fixed" << filepath;
} }
} }
} }
switch(m_modpackType) switch (m_modpackType) {
{
case ModpackType::MultiMC: case ModpackType::MultiMC:
processMultiMC(); processMultiMC();
return; return;
@ -276,7 +267,8 @@ void InstanceImportTask::processFlame()
if (original_instance_id_it != m_extra_info.constEnd()) if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); inst_creation_task =
makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
} else { } else {
// FIXME: Find a way to get IDs in directly imported ZIPs // FIXME: Find a way to get IDs in directly imported ZIPs
inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString()); inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString());
@ -293,7 +285,7 @@ void InstanceImportTask::processFlame()
}); });
connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress); connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propogateStepProgress); connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
@ -362,7 +354,8 @@ void InstanceImportTask::processModrinth()
if (original_instance_id_it != m_extra_info.constEnd()) if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); inst_creation_task =
new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
} else { } else {
QString pack_id; QString pack_id;
if (!m_sourceUrl.isEmpty()) { if (!m_sourceUrl.isEmpty()) {
@ -385,7 +378,7 @@ void InstanceImportTask::processModrinth()
}); });
connect(inst_creation_task, &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task, &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task, &Task::progress, this, &InstanceImportTask::setProgress); connect(inst_creation_task, &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propogateStepProgress); connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task, &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task, &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task, &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task, &Task::details, this, &InstanceImportTask::setDetails);
connect(inst_creation_task, &Task::finished, inst_creation_task, &InstanceCreationTask::deleteLater); connect(inst_creation_task, &Task::finished, inst_creation_task, &InstanceCreationTask::deleteLater);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -35,54 +35,49 @@
#pragma once #pragma once
#include "InstanceTask.h"
#include "net/NetJob.h"
#include <QUrl>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher> #include <QFutureWatcher>
#include "settings/SettingsObject.h" #include <QUrl>
#include "InstanceTask.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
#include "modplatform/flame/PackManifest.h" #include "modplatform/flame/PackManifest.h"
#include "net/NetJob.h"
#include "settings/SettingsObject.h"
#include <optional> #include <optional>
class QuaZip; class QuaZip;
namespace Flame namespace Flame {
{ class FileResolvingTask;
class FileResolvingTask;
} }
class InstanceImportTask : public InstanceTask class InstanceImportTask : public InstanceTask {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {}); explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {});
bool abort() override; bool abort() override;
const QVector<Flame::File> &getBlockedFiles() const const QVector<Flame::File>& getBlockedFiles() const { return m_blockedMods; }
{
return m_blockedMods;
}
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
virtual void executeTask() override; virtual void executeTask() override;
private: private:
void processZipPack(); void processZipPack();
void processMultiMC(); void processMultiMC();
void processTechnic(); void processTechnic();
void processFlame(); void processFlame();
void processModrinth(); void processModrinth();
private slots: private slots:
void downloadSucceeded(); void downloadSucceeded();
void downloadFailed(QString reason); void downloadFailed(QString reason);
void downloadProgressChanged(qint64 current, qint64 total); void downloadProgressChanged(qint64 current, qint64 total);
void downloadAborted(); void downloadAborted();
void extractFinished(); void extractFinished();
private: /* data */ private: /* data */
NetJob::Ptr m_filesNetJob; NetJob::Ptr m_filesNetJob;
shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver; shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver;
QUrl m_sourceUrl; QUrl m_sourceUrl;
@ -92,7 +87,7 @@ private: /* data */
QFuture<std::optional<QStringList>> m_extractFuture; QFuture<std::optional<QStringList>> m_extractFuture;
QFutureWatcher<std::optional<QStringList>> m_extractFutureWatcher; QFutureWatcher<std::optional<QStringList>> m_extractFutureWatcher;
QVector<Flame::File> m_blockedMods; QVector<Flame::File> m_blockedMods;
enum class ModpackType{ enum class ModpackType {
Unknown, Unknown,
MultiMC, MultiMC,
Technic, Technic,
@ -104,6 +99,7 @@ private: /* data */
// the source URL / the resource it points to alone. // the source URL / the resource it points to alone.
QMap<QString, QString> m_extra_info; QMap<QString, QString> m_extra_info;
//FIXME: nuke // FIXME: nuke
QWidget* m_parent; QWidget* m_parent;
void downloadFromUrl();
}; };

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
@ -41,9 +42,9 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QMimeData> #include <QMimeData>
#include <QPair>
#include <QSet> #include <QSet>
#include <QStack> #include <QStack>
#include <QPair>
#include <QTextStream> #include <QTextStream>
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
@ -96,7 +97,11 @@ Qt::DropActions InstanceList::supportedDropActions() const
return Qt::MoveAction; return Qt::MoveAction;
} }
bool InstanceList::canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const bool InstanceList::canDropMimeData(const QMimeData* data,
[[maybe_unused]] Qt::DropAction action,
[[maybe_unused]] int row,
[[maybe_unused]] int column,
[[maybe_unused]] const QModelIndex& parent) const
{ {
if (data && data->hasFormat("application/x-instanceid")) { if (data && data->hasFormat("application/x-instanceid")) {
return true; return true;
@ -104,7 +109,11 @@ bool InstanceList::canDropMimeData(const QMimeData* data, Qt::DropAction action,
return false; return false;
} }
bool InstanceList::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) bool InstanceList::dropMimeData(const QMimeData* data,
[[maybe_unused]] Qt::DropAction action,
[[maybe_unused]] int row,
[[maybe_unused]] int column,
[[maybe_unused]] const QModelIndex& parent)
{ {
if (data && data->hasFormat("application/x-instanceid")) { if (data && data->hasFormat("application/x-instanceid")) {
return true; return true;
@ -129,7 +138,7 @@ QMimeData* InstanceList::mimeData(const QModelIndexList& indexes) const
return mimeData; return mimeData;
} }
QStringList InstanceList::getLinkedInstancesById(const QString &id) const QStringList InstanceList::getLinkedInstancesById(const QString& id) const
{ {
QStringList linkedInstances; QStringList linkedInstances;
for (auto inst : m_instances) { for (auto inst : m_instances) {
@ -158,42 +167,34 @@ QVariant InstanceList::data(const QModelIndex& index, int role) const
if (!index.isValid()) { if (!index.isValid()) {
return QVariant(); return QVariant();
} }
BaseInstance *pdata = static_cast<BaseInstance *>(index.internalPointer()); BaseInstance* pdata = static_cast<BaseInstance*>(index.internalPointer());
switch (role) switch (role) {
{ case InstancePointerRole: {
case InstancePointerRole: QVariant v = QVariant::fromValue((void*)pdata);
{ return v;
QVariant v = QVariant::fromValue((void *)pdata); }
return v; case InstanceIDRole: {
} return pdata->id();
case InstanceIDRole: }
{ case Qt::EditRole:
return pdata->id(); case Qt::DisplayRole: {
} return pdata->name();
case Qt::EditRole: }
case Qt::DisplayRole: case Qt::AccessibleTextRole: {
{ return tr("%1 Instance").arg(pdata->name());
return pdata->name(); }
} case Qt::ToolTipRole: {
case Qt::AccessibleTextRole: return pdata->instanceRoot();
{ }
return tr("%1 Instance").arg(pdata->name()); case Qt::DecorationRole: {
} return pdata->iconKey();
case Qt::ToolTipRole: }
{ // HACK: see InstanceView.h in gui!
return pdata->instanceRoot(); case GroupRole: {
} return getInstanceGroup(pdata->id());
case Qt::DecorationRole: }
{ default:
return pdata->iconKey(); break;
}
// HACK: see InstanceView.h in gui!
case GroupRole:
{
return getInstanceGroup(pdata->id());
}
default:
break;
} }
return QVariant(); return QVariant();
} }
@ -237,8 +238,11 @@ GroupId InstanceList::getInstanceGroup(const InstanceId& id) const
return GroupId(); return GroupId();
} }
void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name) void InstanceList::setInstanceGroup(const InstanceId& id, GroupId name)
{ {
if (name.isEmpty() && !name.isNull())
name = QString();
auto inst = getInstanceById(id); auto inst = getInstanceById(id);
if (!inst) { if (!inst) {
qDebug() << "Attempt to set a null instance's group"; qDebug() << "Attempt to set a null instance's group";
@ -249,6 +253,7 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
auto iter = m_instanceGroupIndex.find(inst->id()); auto iter = m_instanceGroupIndex.find(inst->id());
if (iter != m_instanceGroupIndex.end()) { if (iter != m_instanceGroupIndex.end()) {
if (*iter != name) { if (*iter != name) {
decreaseGroupCount(*iter);
*iter = name; *iter = name;
changed = true; changed = true;
} }
@ -258,7 +263,7 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
} }
if (changed) { if (changed) {
m_groupNameCache.insert(name); increaseGroupCount(name);
auto idx = getInstIndex(inst.get()); auto idx = getInstIndex(inst.get());
emit dataChanged(index(idx), index(idx), { GroupRole }); emit dataChanged(index(idx), index(idx), { GroupRole });
saveGroupList(); saveGroupList();
@ -267,29 +272,55 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
QStringList InstanceList::getGroups() QStringList InstanceList::getGroups()
{ {
return m_groupNameCache.values(); return m_groupNameCache.keys();
} }
void InstanceList::deleteGroup(const QString& name) void InstanceList::deleteGroup(const GroupId& name)
{ {
m_groupNameCache.remove(name);
m_collapsedGroups.remove(name);
bool removed = false; bool removed = false;
qDebug() << "Delete group" << name; qDebug() << "Delete group" << name;
for (auto& instance : m_instances) { for (auto& instance : m_instances) {
const auto& instID = instance->id(); const QString& instID = instance->id();
auto instGroupName = getInstanceGroup(instID); const QString instGroupName = getInstanceGroup(instID);
if (instGroupName == name) { if (instGroupName == name) {
m_instanceGroupIndex.remove(instID); m_instanceGroupIndex.remove(instID);
qDebug() << "Remove" << instID << "from group" << name; qDebug() << "Remove" << instID << "from group" << name;
removed = true; removed = true;
auto idx = getInstIndex(instance.get()); auto idx = getInstIndex(instance.get());
if (idx > 0) { if (idx >= 0)
emit dataChanged(index(idx), index(idx), { GroupRole }); emit dataChanged(index(idx), index(idx), { GroupRole });
}
} }
} }
if (removed) { if (removed)
saveGroupList(); saveGroupList();
}
void InstanceList::renameGroup(const QString& src, const QString& dst)
{
m_groupNameCache.remove(src);
if (m_collapsedGroups.remove(src))
m_collapsedGroups.insert(dst);
bool modified = false;
qDebug() << "Rename group" << src << "to" << dst;
for (auto& instance : m_instances) {
const QString& instID = instance->id();
const QString instGroupName = getInstanceGroup(instID);
if (instGroupName == src) {
m_instanceGroupIndex[instID] = dst;
increaseGroupCount(dst);
qDebug() << "Set" << instID << "group to" << dst;
modified = true;
auto idx = getInstIndex(instance.get());
if (idx >= 0)
emit dataChanged(index(idx), index(idx), { GroupRole });
}
} }
if (modified)
saveGroupList();
} }
bool InstanceList::isGroupCollapsed(const QString& group) bool InstanceList::isGroupCollapsed(const QString& group)
@ -305,12 +336,13 @@ bool InstanceList::trashInstance(const InstanceId& id)
return false; return false;
} }
auto cachedGroupId = m_instanceGroupIndex[id]; QString cachedGroupId = m_instanceGroupIndex[id];
qDebug() << "Will trash instance" << id; qDebug() << "Will trash instance" << id;
QString trashedLoc; QString trashedLoc;
if (m_instanceGroupIndex.remove(id)) { if (m_instanceGroupIndex.remove(id)) {
decreaseGroupCount(cachedGroupId);
saveGroupList(); saveGroupList();
} }
@ -320,16 +352,18 @@ bool InstanceList::trashInstance(const InstanceId& id)
} }
qDebug() << "Instance" << id << "has been trashed by the launcher."; qDebug() << "Instance" << id << "has been trashed by the launcher.";
m_trashHistory.push({id, inst->instanceRoot(), trashedLoc, cachedGroupId}); m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId });
return true; return true;
} }
bool InstanceList::trashedSomething() { bool InstanceList::trashedSomething()
{
return !m_trashHistory.empty(); return !m_trashHistory.empty();
} }
void InstanceList::undoTrashInstance() { void InstanceList::undoTrashInstance()
{
if (m_trashHistory.empty()) { if (m_trashHistory.empty()) {
qWarning() << "Nothing to recover from trash."; qWarning() << "Nothing to recover from trash.";
return; return;
@ -346,7 +380,7 @@ void InstanceList::undoTrashInstance() {
QFile(top.trashPath).rename(top.polyPath); QFile(top.trashPath).rename(top.polyPath);
m_instanceGroupIndex[top.id] = top.groupName; m_instanceGroupIndex[top.id] = top.groupName;
m_groupNameCache.insert(top.groupName); increaseGroupCount(top.groupName);
saveGroupList(); saveGroupList();
emit instancesChanged(); emit instancesChanged();
@ -360,7 +394,10 @@ void InstanceList::deleteInstance(const InstanceId& id)
return; return;
} }
QString cachedGroupId = m_instanceGroupIndex[id];
if (m_instanceGroupIndex.remove(id)) { if (m_instanceGroupIndex.remove(id)) {
decreaseGroupCount(cachedGroupId);
saveGroupList(); saveGroupList();
} }
@ -558,7 +595,7 @@ InstancePtr InstanceList::getInstanceByManagedName(const QString& managed_name)
return {}; return {};
} }
QModelIndex InstanceList::getInstanceIndexById(const QString &id) const QModelIndex InstanceList::getInstanceIndexById(const QString& id) const
{ {
return index(getInstIndex(getInstanceById(id).get())); return index(getInstIndex(getInstanceById(id).get()));
} }
@ -597,19 +634,36 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
QString inst_type = instanceSettings->get("InstanceType").toString(); QString inst_type = instanceSettings->get("InstanceType").toString();
// NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix instance // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix
if (inst_type == "OneSix" || inst_type.isEmpty()) // instance
{ if (inst_type == "OneSix" || inst_type.isEmpty()) {
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
} } else {
else
{
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); 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;
} }
void InstanceList::increaseGroupCount(const QString& group)
{
if (group.isEmpty())
return;
++m_groupNameCache[group];
}
void InstanceList::decreaseGroupCount(const QString& group)
{
if (group.isEmpty())
return;
if (--m_groupNameCache[group] < 1) {
m_groupNameCache.remove(group);
m_collapsedGroups.remove(group);
}
}
void InstanceList::saveGroupList() void InstanceList::saveGroupList()
{ {
qDebug() << "Will save group list now."; qDebug() << "Will save group list now.";
@ -621,7 +675,7 @@ void InstanceList::saveGroupList()
QString groupFileName = m_instDir + "/instgroups.json"; QString groupFileName = m_instDir + "/instgroups.json";
QMap<QString, QSet<QString>> reverseGroupMap; QMap<QString, QSet<QString>> reverseGroupMap;
for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++) { for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++) {
QString id = iter.key(); const QString& id = iter.key();
QString group = iter.value(); QString group = iter.value();
if (group.isEmpty()) if (group.isEmpty())
continue; continue;
@ -711,17 +765,22 @@ void InstanceList::loadGroupList()
return; return;
} }
QSet<QString> groupSet;
m_instanceGroupIndex.clear(); m_instanceGroupIndex.clear();
m_groupNameCache.clear();
// Iterate through all the groups. // Iterate through all the groups.
QJsonObject groupMapping = rootObj.value("groups").toObject(); QJsonObject groupMapping = rootObj.value("groups").toObject();
for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++) { for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++) {
QString groupName = iter.key(); QString groupName = iter.key();
if (iter.key().isEmpty()) {
qWarning() << "Redundant empty group found";
continue;
}
// If not an object, complain and skip to the next one. // If not an object, complain and skip to the next one.
if (!iter.value().isObject()) { if (!iter.value().isObject()) {
qWarning() << QString("Group '%1' in the group list should be an object.").arg(groupName).toUtf8(); qWarning() << QString("Group '%1' in the group list should be an object").arg(groupName).toUtf8();
continue; continue;
} }
@ -733,23 +792,19 @@ void InstanceList::loadGroupList()
continue; continue;
} }
// keep a list/set of groups for choosing
groupSet.insert(groupName);
auto hidden = groupObj.value("hidden").toBool(false); auto hidden = groupObj.value("hidden").toBool(false);
if (hidden) { if (hidden)
m_collapsedGroups.insert(groupName); m_collapsedGroups.insert(groupName);
}
// Iterate through the list of instances in the group. // Iterate through the list of instances in the group.
QJsonArray instancesArray = groupObj.value("instances").toArray(); QJsonArray instancesArray = groupObj.value("instances").toArray();
for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end(); iter2++) { for (auto value : instancesArray) {
m_instanceGroupIndex[(*iter2).toString()] = groupName; m_instanceGroupIndex[value.toString()] = groupName;
increaseGroupCount(groupName);
} }
} }
m_groupsLoaded = true; m_groupsLoaded = true;
m_groupNameCache.unite(groupSet);
qDebug() << "Group list loaded."; qDebug() << "Group list loaded.";
} }
@ -759,7 +814,7 @@ void InstanceList::instanceDirContentsChanged(const QString& path)
emit instancesChanged(); emit instancesChanged();
} }
void InstanceList::on_InstFolderChanged(const Setting& setting, QVariant value) void InstanceList::on_InstFolderChanged([[maybe_unused]] const Setting& setting, QVariant value)
{ {
QString newInstDir = QDir(value.toString()).canonicalPath(); QString newInstDir = QDir(value.toString()).canonicalPath();
if (newInstDir != m_instDir) { if (newInstDir != m_instDir) {
@ -787,20 +842,25 @@ class InstanceStaging : public Task {
Q_OBJECT Q_OBJECT
const unsigned minBackoff = 1; const unsigned minBackoff = 1;
const unsigned maxBackoff = 16; const unsigned maxBackoff = 16;
public: public:
InstanceStaging(InstanceList* parent, InstanceTask* child, QString stagingPath, InstanceName const& instanceName, QString groupName) InstanceStaging(InstanceList* parent, InstanceTask* child, QString stagingPath, InstanceName const& instanceName, QString groupName)
: m_parent(parent), backoff(minBackoff, maxBackoff), m_stagingPath(std::move(stagingPath)), m_instance_name(std::move(instanceName)), m_groupName(std::move(groupName)) : m_parent(parent)
, backoff(minBackoff, maxBackoff)
, m_stagingPath(std::move(stagingPath))
, m_instance_name(std::move(instanceName))
, m_groupName(std::move(groupName))
{ {
m_child.reset(child); m_child.reset(child);
connect(child, &Task::succeeded, this, &InstanceStaging::childSucceded); connect(child, &Task::succeeded, this, &InstanceStaging::childSucceeded);
connect(child, &Task::failed, this, &InstanceStaging::childFailed); connect(child, &Task::failed, this, &InstanceStaging::childFailed);
connect(child, &Task::aborted, this, &InstanceStaging::childAborted); connect(child, &Task::aborted, this, &InstanceStaging::childAborted);
connect(child, &Task::abortStatusChanged, this, &InstanceStaging::setAbortable); connect(child, &Task::abortStatusChanged, this, &InstanceStaging::setAbortable);
connect(child, &Task::status, this, &InstanceStaging::setStatus); connect(child, &Task::status, this, &InstanceStaging::setStatus);
connect(child, &Task::details, this, &InstanceStaging::setDetails); connect(child, &Task::details, this, &InstanceStaging::setDetails);
connect(child, &Task::progress, this, &InstanceStaging::setProgress); connect(child, &Task::progress, this, &InstanceStaging::setProgress);
connect(child, &Task::stepProgress, this, &InstanceStaging::propogateStepProgress); connect(child, &Task::stepProgress, this, &InstanceStaging::propagateStepProgress);
connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceded); connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceeded);
} }
virtual ~InstanceStaging(){}; virtual ~InstanceStaging(){};
@ -815,21 +875,17 @@ class InstanceStaging : public Task {
return Task::abort(); return Task::abort();
} }
bool canAbort() const override bool canAbort() const override { return (m_child && m_child->canAbort()); }
{
return (m_child && m_child->canAbort());
}
protected: protected:
virtual void executeTask() override { m_child->start(); } virtual void executeTask() override { m_child->start(); }
QStringList warnings() const override { return m_child->warnings(); } QStringList warnings() const override { return m_child->warnings(); }
private slots: private slots:
void childSucceded() void childSucceeded()
{ {
unsigned sleepTime = backoff(); unsigned sleepTime = backoff();
if (m_parent->commitStagedInstance(m_stagingPath, m_instance_name, m_groupName, *m_child.get())) if (m_parent->commitStagedInstance(m_stagingPath, m_instance_name, m_groupName, *m_child.get())) {
{
emitSucceeded(); emitSucceeded();
return; return;
} }
@ -847,13 +903,10 @@ class InstanceStaging : public Task {
emitFailed(reason); emitFailed(reason);
} }
void childAborted() void childAborted() { emitAborted(); }
{
emitAborted();
}
private: private:
InstanceList * m_parent; InstanceList* m_parent;
/* /*
* WHY: the whole reason why this uses an exponential backoff retry scheme is antivirus on Windows. * WHY: the whole reason why this uses an exponential backoff retry scheme is antivirus on Windows.
* Basically, it starts messing things up while the launcher is extracting/creating instances * Basically, it starts messing things up while the launcher is extracting/creating instances
@ -892,8 +945,14 @@ QString InstanceList::getStagedInstancePath()
return path; return path;
} }
bool InstanceList::commitStagedInstance(const QString& path, InstanceName const& instanceName, const QString& groupName, InstanceTask const& commiting) bool InstanceList::commitStagedInstance(const QString& path,
InstanceName const& instanceName,
QString groupName,
InstanceTask const& commiting)
{ {
if (groupName.isEmpty() && !groupName.isNull())
groupName = QString();
QDir dir; QDir dir;
QString instID; QString instID;
InstancePtr inst; InstancePtr inst;
@ -924,7 +983,7 @@ bool InstanceList::commitStagedInstance(const QString& path, InstanceName const&
} }
m_instanceGroupIndex[instID] = groupName; m_instanceGroupIndex[instID] = groupName;
m_groupNameCache.insert(groupName); increaseGroupCount(groupName);
} }
instanceSet.insert(instID); instanceSet.insert(instID);

View File

@ -1,26 +1,46 @@
/* Copyright 2013-2021 MultiMC Contributors // SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
#include <QObject>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QSet>
#include <QList> #include <QList>
#include <QStack> #include <QObject>
#include <QPair> #include <QPair>
#include <QSet>
#include <QStack>
#include "BaseInstance.h" #include "BaseInstance.h"
@ -32,21 +52,9 @@ using InstanceId = QString;
using GroupId = QString; using GroupId = QString;
using InstanceLocator = std::pair<InstancePtr, int>; using InstanceLocator = std::pair<InstancePtr, int>;
enum class InstCreateError enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateError, InstExists, CantCreateDir };
{
NoCreateError = 0,
NoSuchVersion,
UnknownCreateError,
InstExists,
CantCreateDir
};
enum class GroupsState enum class GroupsState { NotLoaded, Steady, Dirty };
{
NotLoaded,
Steady,
Dirty
};
struct TrashHistoryItem { struct TrashHistoryItem {
QString id; QString id;
@ -55,48 +63,36 @@ struct TrashHistoryItem {
QString groupName; QString groupName;
}; };
class InstanceList : public QAbstractListModel class InstanceList : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceList(SettingsObjectPtr settings, const QString & instDir, QObject *parent = 0); explicit InstanceList(SettingsObjectPtr settings, const QString& instDir, QObject* parent = 0);
virtual ~InstanceList(); virtual ~InstanceList();
public: public:
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override; QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex& index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex& index) const override;
bool setData(const QModelIndex & index, const QVariant & value, int role) override; bool setData(const QModelIndex& index, const QVariant& value, int role) override;
enum AdditionalRoles enum AdditionalRoles {
{
GroupRole = Qt::UserRole, GroupRole = Qt::UserRole,
InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
InstanceIDRole = 0x34B1CB49 ///< Return id if the instance InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
}; };
/*! /*!
* \brief Error codes returned by functions in the InstanceList class. * \brief Error codes returned by functions in the InstanceList class.
* NoError Indicates that no error occurred. * NoError Indicates that no error occurred.
* UnknownError indicates that an unspecified error occurred. * UnknownError indicates that an unspecified error occurred.
*/ */
enum InstListError enum InstListError { NoError = 0, UnknownError };
{
NoError = 0,
UnknownError
};
InstancePtr at(int i) const InstancePtr at(int i) const { return m_instances.at(i); }
{
return m_instances.at(i);
}
int count() const int count() const { return m_instances.count(); }
{
return m_instances.count();
}
InstListError loadList(); InstListError loadList();
void saveNow(); void saveNow();
@ -105,21 +101,22 @@ public:
InstancePtr getInstanceById(QString id) const; InstancePtr getInstanceById(QString id) const;
/* O(n) */ /* O(n) */
InstancePtr getInstanceByManagedName(const QString& managed_name) const; InstancePtr getInstanceByManagedName(const QString& managed_name) const;
QModelIndex getInstanceIndexById(const QString &id) const; QModelIndex getInstanceIndexById(const QString& id) const;
QStringList getGroups(); QStringList getGroups();
bool isGroupCollapsed(const QString &groupName); bool isGroupCollapsed(const QString& groupName);
GroupId getInstanceGroup(const InstanceId & id) const; GroupId getInstanceGroup(const InstanceId& id) const;
void setInstanceGroup(const InstanceId & id, const GroupId& name); void setInstanceGroup(const InstanceId& id, GroupId name);
void deleteGroup(const GroupId & name); void deleteGroup(const GroupId& name);
bool trashInstance(const InstanceId &id); void renameGroup(const GroupId& src, const GroupId& dst);
bool trashInstance(const InstanceId& id);
bool trashedSomething(); bool trashedSomething();
void undoTrashInstance(); void undoTrashInstance();
void deleteInstance(const InstanceId & id); void deleteInstance(const InstanceId& id);
// Wrap an instance creation task in some more task machinery and make it ready to be used // Wrap an instance creation task in some more task machinery and make it ready to be used
Task * wrapInstanceTask(InstanceTask * task); Task* wrapInstanceTask(InstanceTask* task);
/** /**
* Create a new empty staging area for instance creation and @return a path/key top commit it later. * Create a new empty staging area for instance creation and @return a path/key top commit it later.
@ -133,13 +130,13 @@ public:
* should_override is used when another similar instance already exists, and we want to override it * should_override is used when another similar instance already exists, and we want to override it
* - for instance, when updating it. * - for instance, when updating it.
*/ */
bool commitStagedInstance(const QString& keyPath, const InstanceName& instanceName, const QString& groupName, const InstanceTask&); bool commitStagedInstance(const QString& keyPath, const InstanceName& instanceName, QString groupName, const InstanceTask&);
/** /**
* Destroy a previously created staging area given by @keyPath - used when creation fails. * Destroy a previously created staging area given by @keyPath - used when creation fails.
* Used by instance manipulation tasks. * Used by instance manipulation tasks.
*/ */
bool destroyStagingPath(const QString & keyPath); bool destroyStagingPath(const QString& keyPath);
int getTotalPlayTime(); int getTotalPlayTime();
@ -147,51 +144,55 @@ public:
Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDropActions() const override;
bool canDropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) const override; bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override;
bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
QStringList mimeTypes() const override; QStringList mimeTypes() const override;
QMimeData *mimeData(const QModelIndexList &indexes) const override; QMimeData* mimeData(const QModelIndexList& indexes) const override;
QStringList getLinkedInstancesById(const QString &id) const; QStringList getLinkedInstancesById(const QString& id) const;
signals: signals:
void dataIsInvalid(); void dataIsInvalid();
void instancesChanged(); void instancesChanged();
void instanceSelectRequest(QString instanceId); void instanceSelectRequest(QString instanceId);
void groupsChanged(QSet<QString> groups); void groupsChanged(QSet<QString> groups);
public slots: public slots:
void on_InstFolderChanged(const Setting &setting, QVariant value); void on_InstFolderChanged(const Setting& setting, QVariant value);
void on_GroupStateChanged(const QString &group, bool collapsed); void on_GroupStateChanged(const QString& group, bool collapsed);
private slots: private slots:
void propertiesChanged(BaseInstance *inst); void propertiesChanged(BaseInstance* inst);
void providerUpdated(); void providerUpdated();
void instanceDirContentsChanged(const QString &path); void instanceDirContentsChanged(const QString& path);
private: private:
int getInstIndex(BaseInstance *inst) const; int getInstIndex(BaseInstance* inst) const;
void updateTotalPlayTime(); void updateTotalPlayTime();
void suspendWatch(); void suspendWatch();
void resumeWatch(); void resumeWatch();
void add(const QList<InstancePtr> &list); void add(const QList<InstancePtr>& list);
void loadGroupList(); void loadGroupList();
void saveGroupList(); void saveGroupList();
QList<InstanceId> discoverInstances(); QList<InstanceId> discoverInstances();
InstancePtr loadInstance(const InstanceId& id); InstancePtr loadInstance(const InstanceId& id);
private: void increaseGroupCount(const QString& group);
void decreaseGroupCount(const QString& group);
private:
int m_watchLevel = 0; int m_watchLevel = 0;
int totalPlayTime = 0; int totalPlayTime = 0;
bool m_dirty = false; bool m_dirty = false;
QList<InstancePtr> m_instances; QList<InstancePtr> m_instances;
QSet<QString> m_groupNameCache; // id -> refs
QMap<QString, int> m_groupNameCache;
SettingsObjectPtr m_globalSettings; SettingsObjectPtr m_globalSettings;
QString m_instDir; QString m_instDir;
QFileSystemWatcher * m_watcher; QFileSystemWatcher* m_watcher;
// FIXME: this is so inefficient that looking at it is almost painful. // FIXME: this is so inefficient that looking at it is almost painful.
QSet<QString> m_collapsedGroups; QSet<QString> m_collapsedGroups;
QMap<InstanceId, GroupId> m_instanceGroupIndex; QMap<InstanceId, GroupId> m_instanceGroupIndex;

View File

@ -1,36 +1,31 @@
#pragma once #pragma once
#include "minecraft/MinecraftInstance.h"
#include <FileSystem.h> #include <FileSystem.h>
#include "minecraft/MinecraftInstance.h"
#include "ui/pages/BasePage.h" #include "ui/pages/BasePage.h"
#include "ui/pages/BasePageProvider.h" #include "ui/pages/BasePageProvider.h"
#include "ui/pages/instance/InstanceSettingsPage.h"
#include "ui/pages/instance/LogPage.h" #include "ui/pages/instance/LogPage.h"
#include "ui/pages/instance/VersionPage.h"
#include "ui/pages/instance/ManagedPackPage.h" #include "ui/pages/instance/ManagedPackPage.h"
#include "ui/pages/instance/ModFolderPage.h" #include "ui/pages/instance/ModFolderPage.h"
#include "ui/pages/instance/ResourcePackPage.h"
#include "ui/pages/instance/TexturePackPage.h"
#include "ui/pages/instance/ShaderPackPage.h"
#include "ui/pages/instance/NotesPage.h" #include "ui/pages/instance/NotesPage.h"
#include "ui/pages/instance/ScreenshotsPage.h"
#include "ui/pages/instance/InstanceSettingsPage.h"
#include "ui/pages/instance/OtherLogsPage.h" #include "ui/pages/instance/OtherLogsPage.h"
#include "ui/pages/instance/WorldListPage.h" #include "ui/pages/instance/ResourcePackPage.h"
#include "ui/pages/instance/ScreenshotsPage.h"
#include "ui/pages/instance/ServersPage.h" #include "ui/pages/instance/ServersPage.h"
#include "ui/pages/instance/GameOptionsPage.h" #include "ui/pages/instance/ShaderPackPage.h"
#include "ui/pages/instance/TexturePackPage.h"
#include "ui/pages/instance/VersionPage.h"
#include "ui/pages/instance/WorldListPage.h"
class InstancePageProvider : public QObject, public BasePageProvider class InstancePageProvider : protected QObject, public BasePageProvider {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstancePageProvider(InstancePtr parent) explicit InstancePageProvider(InstancePtr parent) { inst = parent; }
{
inst = parent;
}
virtual ~InstancePageProvider() {}; virtual ~InstancePageProvider(){};
virtual QList<BasePage *> getPages() override virtual QList<BasePage*> getPages() override
{ {
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);
values.append(new VersionPage(onesix.get())); values.append(new VersionPage(onesix.get()));
@ -50,18 +45,14 @@ public:
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots"))); values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get())); values.append(new InstanceSettingsPage(onesix.get()));
auto logMatcher = inst->getLogFileMatcher(); auto logMatcher = inst->getLogFileMatcher();
if(logMatcher) if (logMatcher) {
{
values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher)); values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher));
} }
return values; return values;
} }
virtual QString dialogTitle() override virtual QString dialogTitle() override { return tr("Edit Instance (%1)").arg(inst->name()); }
{
return tr("Edit Instance (%1)").arg(inst->name()); protected:
}
protected:
InstancePtr inst; InstancePtr inst;
}; };

View File

@ -18,13 +18,14 @@ InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& ol
return InstanceNameChange::ShouldKeep; return InstanceNameChange::ShouldKeep;
} }
ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name) ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name)
{ {
auto info = CustomMessageBox::selectable( auto info = CustomMessageBox::selectable(
parent, QObject::tr("Similar modpack was found!"), parent, QObject::tr("Similar modpack was found!"),
QObject::tr("One or more of your instances are from this same modpack%1. Do you want to create a " QObject::tr(
"separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " "One or more of your instances are from this same modpack%1. Do you want to create a "
"updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before "
"updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).")
.arg(original_version_name), .arg(original_version_name),
QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort);
info->setButtonText(QMessageBox::Ok, QObject::tr("Update existing instance")); info->setButtonText(QMessageBox::Ok, QObject::tr("Update existing instance"));
@ -38,7 +39,6 @@ ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name)
if (info->clickedButton() == info->button(QMessageBox::Abort)) if (info->clickedButton() == info->button(QMessageBox::Abort))
return ShouldUpdate::SkipUpdating; return ShouldUpdate::SkipUpdating;
return ShouldUpdate::Cancel; return ShouldUpdate::Cancel;
} }
QString InstanceName::name() const QString InstanceName::name() const

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -39,43 +39,39 @@
#include <QRegularExpression> #include <QRegularExpression>
bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent) bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget* parent)
{ {
if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) || jvmargs.contains("-XX-MaxHeapSize") ||
|| jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize")) 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(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec();
parent, QObject::tr("JVM arguments warning"),
warnStr,
QMessageBox::Warning)->exec();
return false; return false;
} }
// block lunacy with passing required version to the JVM // block lunacy with passing required version to the JVM
if (jvmargs.contains(QRegularExpression("-version:.*"))) { if (jvmargs.contains(QRegularExpression("-version:.*"))) {
auto warnStr = QObject::tr( 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" "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."); "This message will be displayed until you remove this from the JVM arguments.");
CustomMessageBox::selectable( CustomMessageBox::selectable(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec();
parent, QObject::tr("JVM arguments warning"),
warnStr,
QMessageBox::Warning)->exec();
return false; return false;
} }
return true; return true;
} }
void JavaCommon::javaWasOk(QWidget *parent, JavaCheckResult result) void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result)
{ {
QString text; QString text;
text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version " text += QObject::tr(
"reported: %2<br />Java vendor " "Java test succeeded!<br />Platform reported: %1<br />Java version "
"reported: %3<br />").arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor); "reported: %2<br />Java vendor "
if (result.errorLog.size()) "reported: %3<br />")
{ .arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor);
if (result.errorLog.size()) {
auto htmlError = result.errorLog; auto htmlError = result.errorLog;
htmlError.replace('\n', "<br />"); htmlError.replace('\n', "<br />");
text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError); text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError);
@ -83,7 +79,7 @@ void JavaCommon::javaWasOk(QWidget *parent, JavaCheckResult result)
CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show(); CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show();
} }
void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result) void JavaCommon::javaArgsWereBad(QWidget* parent, const JavaCheckResult& result)
{ {
auto htmlError = result.errorLog; auto htmlError = result.errorLog;
QString text; QString text;
@ -93,7 +89,7 @@ void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result)
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
} }
void JavaCommon::javaBinaryWasBad(QWidget *parent, JavaCheckResult result) void JavaCommon::javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result)
{ {
QString text; QString text;
text += QObject::tr( text += QObject::tr(
@ -102,7 +98,7 @@ void JavaCommon::javaBinaryWasBad(QWidget *parent, JavaCheckResult result)
CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
} }
void JavaCommon::javaCheckNotFound(QWidget *parent) void JavaCommon::javaCheckNotFound(QWidget* parent)
{ {
QString text; QString text;
text += QObject::tr("Java checker library could not be found. Please check your installation."); text += QObject::tr("Java checker library could not be found. Please check your installation.");
@ -111,8 +107,7 @@ void JavaCommon::javaCheckNotFound(QWidget *parent)
void JavaCommon::TestCheck::run() void JavaCommon::TestCheck::run()
{ {
if (!JavaCommon::checkJVMArgs(m_args, m_parent)) if (!JavaCommon::checkJVMArgs(m_args, m_parent)) {
{
emit finished(); emit finished();
return; return;
} }
@ -129,8 +124,7 @@ void JavaCommon::TestCheck::run()
void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
{ {
if (result.validity != JavaCheckResult::Validity::Valid) if (result.validity != JavaCheckResult::Validity::Valid) {
{
javaBinaryWasBad(m_parent, result); javaBinaryWasBad(m_parent, result);
emit finished(); emit finished();
return; return;
@ -141,8 +135,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
checker->m_args = m_args; checker->m_args = m_args;
checker->m_minMem = m_minMem; checker->m_minMem = m_minMem;
checker->m_maxMem = m_maxMem; checker->m_maxMem = m_maxMem;
if (result.javaVersion.requiresPermGen()) if (result.javaVersion.requiresPermGen()) {
{
checker->m_permGen = m_permGen; checker->m_permGen = m_permGen;
} }
checker->performCheck(); checker->performCheck();
@ -150,8 +143,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result) void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result)
{ {
if (result.validity == JavaCheckResult::Validity::Valid) if (result.validity == JavaCheckResult::Validity::Valid) {
{
javaWasOk(m_parent, result); javaWasOk(m_parent, result);
emit finished(); emit finished();
return; return;
@ -159,4 +151,3 @@ void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result)
javaArgsWereBad(m_parent, result); javaArgsWereBad(m_parent, result);
emit finished(); emit finished();
} }

View File

@ -6,45 +6,42 @@ class QWidget;
/** /**
* Common UI bits for the java pages to use. * Common UI bits for the java pages to use.
*/ */
namespace JavaCommon namespace JavaCommon {
{ bool checkJVMArgs(QString args, QWidget* parent);
bool checkJVMArgs(QString args, QWidget *parent);
// Show a dialog saying that the Java binary was usable // Show a dialog saying that the Java binary was usable
void javaWasOk(QWidget *parent, JavaCheckResult result); void javaWasOk(QWidget* parent, const JavaCheckResult& result);
// Show a dialog saying that the Java binary was not usable because of bad options // Show a dialog saying that the Java binary was not usable because of bad options
void javaArgsWereBad(QWidget *parent, JavaCheckResult result); void javaArgsWereBad(QWidget* parent, const JavaCheckResult& result);
// Show a dialog saying that the Java binary was not usable // Show a dialog saying that the Java binary was not usable
void javaBinaryWasBad(QWidget *parent, JavaCheckResult result); void javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result);
// Show a dialog if we couldn't find Java Checker // Show a dialog if we couldn't find Java Checker
void javaCheckNotFound(QWidget *parent); void javaCheckNotFound(QWidget* parent);
class TestCheck : public QObject class TestCheck : public QObject {
{ Q_OBJECT
Q_OBJECT public:
public: TestCheck(QWidget* parent, QString path, QString args, int minMem, int maxMem, int permGen)
TestCheck(QWidget *parent, QString path, QString args, int minMem, int maxMem, int permGen) : m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen)
:m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen) {}
{ virtual ~TestCheck(){};
}
virtual ~TestCheck() {};
void run(); void run();
signals: signals:
void finished(); void finished();
private slots: private slots:
void checkFinished(JavaCheckResult result); void checkFinished(JavaCheckResult result);
void checkFinishedWithArgs(JavaCheckResult result); void checkFinishedWithArgs(JavaCheckResult result);
private: private:
std::shared_ptr<JavaChecker> checker; std::shared_ptr<JavaChecker> checker;
QWidget *m_parent = nullptr; QWidget* m_parent = nullptr;
QString m_path; QString m_path;
QString m_args; QString m_args;
int m_minMem = 0; int m_minMem = 0;
int m_maxMem = 0; int m_maxMem = 0;
int m_permGen = 64; int m_permGen = 64;
}; };
} } // namespace JavaCommon

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -37,257 +37,246 @@
#include <QFile> #include <QFile>
#include "FileSystem.h"
#include <math.h> #include <math.h>
#include "FileSystem.h"
namespace Json namespace Json {
{ void write(const QJsonDocument& doc, const QString& filename)
void write(const QJsonDocument &doc, const QString &filename)
{ {
FS::write(filename, doc.toJson()); FS::write(filename, doc.toJson());
} }
void write(const QJsonObject &object, const QString &filename) void write(const QJsonObject& object, const QString& filename)
{ {
write(QJsonDocument(object), filename); write(QJsonDocument(object), filename);
} }
void write(const QJsonArray &array, const QString &filename) void write(const QJsonArray& array, const QString& filename)
{ {
write(QJsonDocument(array), filename); write(QJsonDocument(array), filename);
} }
QByteArray toText(const QJsonObject &obj) QByteArray toText(const QJsonObject& obj)
{ {
return QJsonDocument(obj).toJson(QJsonDocument::Compact); return QJsonDocument(obj).toJson(QJsonDocument::Compact);
} }
QByteArray toText(const QJsonArray &array) QByteArray toText(const QJsonArray& array)
{ {
return QJsonDocument(array).toJson(QJsonDocument::Compact); return QJsonDocument(array).toJson(QJsonDocument::Compact);
} }
static bool isBinaryJson(const QByteArray &data) static bool isBinaryJson(const QByteArray& data)
{ {
decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag; decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag;
return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0; return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0;
} }
QJsonDocument requireDocument(const QByteArray &data, const QString &what) QJsonDocument requireDocument(const QByteArray& data, const QString& what)
{ {
if (isBinaryJson(data)) if (isBinaryJson(data)) {
{
// FIXME: Is this needed? // FIXME: Is this needed?
throw JsonException(what + ": Invalid JSON. Binary JSON unsupported"); throw JsonException(what + ": Invalid JSON. Binary JSON unsupported");
} } else {
else
{
QJsonParseError error; QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(data, &error); QJsonDocument doc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError) {
{
throw JsonException(what + ": Error parsing JSON: " + error.errorString()); throw JsonException(what + ": Error parsing JSON: " + error.errorString());
} }
return doc; return doc;
} }
} }
QJsonDocument requireDocument(const QString &filename, const QString &what) QJsonDocument requireDocument(const QString& filename, const QString& what)
{ {
return requireDocument(FS::read(filename), what); return requireDocument(FS::read(filename), what);
} }
QJsonObject requireObject(const QJsonDocument &doc, const QString &what) QJsonObject requireObject(const QJsonDocument& doc, const QString& what)
{ {
if (!doc.isObject()) if (!doc.isObject()) {
{
throw JsonException(what + " is not an object"); throw JsonException(what + " is not an object");
} }
return doc.object(); return doc.object();
} }
QJsonArray requireArray(const QJsonDocument &doc, const QString &what) QJsonArray requireArray(const QJsonDocument& doc, const QString& what)
{ {
if (!doc.isArray()) if (!doc.isArray()) {
{
throw JsonException(what + " is not an array"); throw JsonException(what + " is not an array");
} }
return doc.array(); return doc.array();
} }
void writeString(QJsonObject &to, const QString &key, const QString &value) void writeString(QJsonObject& to, const QString& key, const QString& value)
{ {
if (!value.isEmpty()) if (!value.isEmpty()) {
{
to.insert(key, value); to.insert(key, value);
} }
} }
void writeStringList(QJsonObject &to, const QString &key, const QStringList &values) void writeStringList(QJsonObject& to, const QString& key, const QStringList& values)
{ {
if (!values.isEmpty()) if (!values.isEmpty()) {
{
QJsonArray array; QJsonArray array;
for(auto value: values) for (auto value : values) {
{
array.append(value); array.append(value);
} }
to.insert(key, array); to.insert(key, array);
} }
} }
template<> template <>
QJsonValue toJson<QUrl>(const QUrl &url) QJsonValue toJson<QUrl>(const QUrl& url)
{ {
return QJsonValue(url.toString(QUrl::FullyEncoded)); return QJsonValue(url.toString(QUrl::FullyEncoded));
} }
template<> template <>
QJsonValue toJson<QByteArray>(const QByteArray &data) QJsonValue toJson<QByteArray>(const QByteArray& data)
{ {
return QJsonValue(QString::fromLatin1(data.toHex())); return QJsonValue(QString::fromLatin1(data.toHex()));
} }
template<> template <>
QJsonValue toJson<QDateTime>(const QDateTime &datetime) QJsonValue toJson<QDateTime>(const QDateTime& datetime)
{ {
return QJsonValue(datetime.toString(Qt::ISODate)); return QJsonValue(datetime.toString(Qt::ISODate));
} }
template<> template <>
QJsonValue toJson<QDir>(const QDir &dir) QJsonValue toJson<QDir>(const QDir& dir)
{ {
return QDir::current().relativeFilePath(dir.absolutePath()); return QDir::current().relativeFilePath(dir.absolutePath());
} }
template<> template <>
QJsonValue toJson<QUuid>(const QUuid &uuid) QJsonValue toJson<QUuid>(const QUuid& uuid)
{ {
return uuid.toString(); return uuid.toString();
} }
template<> template <>
QJsonValue toJson<QVariant>(const QVariant &variant) QJsonValue toJson<QVariant>(const QVariant& variant)
{ {
return QJsonValue::fromVariant(variant); return QJsonValue::fromVariant(variant);
} }
template <>
template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what) QByteArray requireIsType<QByteArray>(const QJsonValue& value, const QString& what)
{ {
const QString string = ensureIsType<QString>(value, what); const QString string = ensureIsType<QString>(value, what);
// ensure that the string can be safely cast to Latin1 // ensure that the string can be safely cast to Latin1
if (string != QString::fromLatin1(string.toLatin1())) if (string != QString::fromLatin1(string.toLatin1())) {
{
throw JsonException(what + " is not encodable as Latin1"); throw JsonException(what + " is not encodable as Latin1");
} }
return QByteArray::fromHex(string.toLatin1()); return QByteArray::fromHex(string.toLatin1());
} }
template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what) template <>
QJsonArray requireIsType<QJsonArray>(const QJsonValue& value, const QString& what)
{ {
if (!value.isArray()) if (!value.isArray()) {
{
throw JsonException(what + " is not an array"); throw JsonException(what + " is not an array");
} }
return value.toArray(); return value.toArray();
} }
template <>
template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what) QString requireIsType<QString>(const QJsonValue& value, const QString& what)
{ {
if (!value.isString()) if (!value.isString()) {
{
throw JsonException(what + " is not a string"); throw JsonException(what + " is not a string");
} }
return value.toString(); return value.toString();
} }
template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what) template <>
bool requireIsType<bool>(const QJsonValue& value, const QString& what)
{ {
if (!value.isBool()) if (!value.isBool()) {
{
throw JsonException(what + " is not a bool"); throw JsonException(what + " is not a bool");
} }
return value.toBool(); return value.toBool();
} }
template<> double requireIsType<double>(const QJsonValue &value, const QString &what) template <>
double requireIsType<double>(const QJsonValue& value, const QString& what)
{ {
if (!value.isDouble()) if (!value.isDouble()) {
{
throw JsonException(what + " is not a double"); throw JsonException(what + " is not a double");
} }
return value.toDouble(); return value.toDouble();
} }
template<> int requireIsType<int>(const QJsonValue &value, const QString &what) template <>
int requireIsType<int>(const QJsonValue& value, const QString& what)
{ {
const double doubl = requireIsType<double>(value, what); const double doubl = requireIsType<double>(value, what);
if (fmod(doubl, 1) != 0) if (fmod(doubl, 1) != 0) {
{
throw JsonException(what + " is not an integer"); throw JsonException(what + " is not an integer");
} }
return int(doubl); return int(doubl);
} }
template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what) template <>
QDateTime requireIsType<QDateTime>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate); const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate);
if (!datetime.isValid()) if (!datetime.isValid()) {
{
throw JsonException(what + " is not a ISO formatted date/time value"); throw JsonException(what + " is not a ISO formatted date/time value");
} }
return datetime; return datetime;
} }
template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what) template <>
QUrl requireIsType<QUrl>(const QJsonValue& value, const QString& what)
{ {
const QString string = ensureIsType<QString>(value, what); const QString string = ensureIsType<QString>(value, what);
if (string.isEmpty()) if (string.isEmpty()) {
{
return QUrl(); return QUrl();
} }
const QUrl url = QUrl(string, QUrl::StrictMode); const QUrl url = QUrl(string, QUrl::StrictMode);
if (!url.isValid()) if (!url.isValid()) {
{
throw JsonException(what + " is not a correctly formatted URL"); throw JsonException(what + " is not a correctly formatted URL");
} }
return url; return url;
} }
template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what) template <>
QDir requireIsType<QDir>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
// FIXME: does not handle invalid characters! // FIXME: does not handle invalid characters!
return QDir::current().absoluteFilePath(string); return QDir::current().absoluteFilePath(string);
} }
template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what) template <>
QUuid requireIsType<QUuid>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
const QUuid uuid = QUuid(string); const QUuid uuid = QUuid(string);
if (uuid.toString() != string) // converts back => valid if (uuid.toString() != string) // converts back => valid
{ {
throw JsonException(what + " is not a valid UUID"); throw JsonException(what + " is not a valid UUID");
} }
return uuid; return uuid;
} }
template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what) template <>
QJsonObject requireIsType<QJsonObject>(const QJsonValue& value, const QString& what)
{ {
if (!value.isObject()) if (!value.isObject()) {
{
throw JsonException(what + " is not an object"); throw JsonException(what + " is not an object");
} }
return value.toObject(); return value.toObject();
} }
template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what) template <>
QVariant requireIsType<QVariant>(const QJsonValue& value, const QString& what)
{ {
if (value.isNull() || value.isUndefined()) if (value.isNull() || value.isUndefined()) {
{
throw JsonException(what + " is null or undefined"); throw JsonException(what + " is null or undefined");
} }
return value.toVariant(); return value.toVariant();
} }
template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what) template <>
QJsonValue requireIsType<QJsonValue>(const QJsonValue& value, const QString& what)
{ {
if (value.isNull() || value.isUndefined()) if (value.isNull() || value.isUndefined()) {
{
throw JsonException(what + " is null or undefined"); throw JsonException(what + " is null or undefined");
} }
return value; return value;
} }
} } // namespace Json

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -35,74 +35,71 @@
#pragma once #pragma once
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDateTime> #include <QDateTime>
#include <QUrl>
#include <QDir> #include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QUrl>
#include <QUuid> #include <QUuid>
#include <QVariant> #include <QVariant>
#include <memory> #include <memory>
#include "Exception.h" #include "Exception.h"
namespace Json namespace Json {
{ class JsonException : public ::Exception {
class JsonException : public ::Exception public:
{ JsonException(const QString& message) : Exception(message) {}
public:
JsonException(const QString &message) : Exception(message) {}
}; };
/// @throw FileSystemException /// @throw FileSystemException
void write(const QJsonDocument &doc, const QString &filename); void write(const QJsonDocument& doc, const QString& filename);
/// @throw FileSystemException /// @throw FileSystemException
void write(const QJsonObject &object, const QString &filename); void write(const QJsonObject& object, const QString& filename);
/// @throw FileSystemException /// @throw FileSystemException
void write(const QJsonArray &array, const QString &filename); void write(const QJsonArray& array, const QString& filename);
QByteArray toText(const QJsonObject &obj); QByteArray toText(const QJsonObject& obj);
QByteArray toText(const QJsonArray &array); QByteArray toText(const QJsonArray& array);
/// @throw JsonException /// @throw JsonException
QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document"); QJsonDocument requireDocument(const QByteArray& data, const QString& what = "Document");
/// @throw JsonException /// @throw JsonException
QJsonDocument requireDocument(const QString &filename, const QString &what = "Document"); QJsonDocument requireDocument(const QString& filename, const QString& what = "Document");
/// @throw JsonException /// @throw JsonException
QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document"); QJsonObject requireObject(const QJsonDocument& doc, const QString& what = "Document");
/// @throw JsonException /// @throw JsonException
QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document"); QJsonArray requireArray(const QJsonDocument& doc, const QString& what = "Document");
/////////////////// WRITING //////////////////// /////////////////// WRITING ////////////////////
void writeString(QJsonObject & to, const QString &key, const QString &value); void writeString(QJsonObject& to, const QString& key, const QString& value);
void writeStringList(QJsonObject & to, const QString &key, const QStringList &values); void writeStringList(QJsonObject& to, const QString& key, const QStringList& values);
template<typename T> template <typename T>
QJsonValue toJson(const T &t) QJsonValue toJson(const T& t)
{ {
return QJsonValue(t); return QJsonValue(t);
} }
template<> template <>
QJsonValue toJson<QUrl>(const QUrl &url); QJsonValue toJson<QUrl>(const QUrl& url);
template<> template <>
QJsonValue toJson<QByteArray>(const QByteArray &data); QJsonValue toJson<QByteArray>(const QByteArray& data);
template<> template <>
QJsonValue toJson<QDateTime>(const QDateTime &datetime); QJsonValue toJson<QDateTime>(const QDateTime& datetime);
template<> template <>
QJsonValue toJson<QDir>(const QDir &dir); QJsonValue toJson<QDir>(const QDir& dir);
template<> template <>
QJsonValue toJson<QUuid>(const QUuid &uuid); QJsonValue toJson<QUuid>(const QUuid& uuid);
template<> template <>
QJsonValue toJson<QVariant>(const QVariant &variant); QJsonValue toJson<QVariant>(const QVariant& variant);
template<typename T> template <typename T>
QJsonArray toJsonArray(const QList<T> &container) QJsonArray toJsonArray(const QList<T>& container)
{ {
QJsonArray array; QJsonArray array;
for (const T item : container) for (const T item : container) {
{
array.append(toJson<T>(item)); array.append(toJson<T>(item));
} }
return array; return array;
@ -112,106 +109,110 @@ QJsonArray toJsonArray(const QList<T> &container)
/// @throw JsonException /// @throw JsonException
template <typename T> template <typename T>
T requireIsType(const QJsonValue &value, const QString &what = "Value"); T requireIsType(const QJsonValue& value, const QString& what = "Value");
/// @throw JsonException /// @throw JsonException
template<> double requireIsType<double>(const QJsonValue &value, const QString &what); template <>
double requireIsType<double>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what); template <>
bool requireIsType<bool>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> int requireIsType<int>(const QJsonValue &value, const QString &what); template <>
int requireIsType<int>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what); template <>
QJsonObject requireIsType<QJsonObject>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what); template <>
QJsonArray requireIsType<QJsonArray>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what); template <>
QJsonValue requireIsType<QJsonValue>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what); template <>
QByteArray requireIsType<QByteArray>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what); template <>
QDateTime requireIsType<QDateTime>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what); template <>
QVariant requireIsType<QVariant>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what); template <>
QString requireIsType<QString>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what); template <>
QUuid requireIsType<QUuid>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what); template <>
QDir requireIsType<QDir>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what); template <>
QUrl requireIsType<QUrl>(const QJsonValue& value, const QString& what);
// the following functions are higher level functions, that make use of the above functions for // the following functions are higher level functions, that make use of the above functions for
// type conversion // type conversion
template <typename T> template <typename T>
T ensureIsType(const QJsonValue &value, const T default_ = T(), const QString &what = "Value") T ensureIsType(const QJsonValue& value, const T default_ = T(), const QString& what = "Value")
{ {
if (value.isUndefined() || value.isNull()) if (value.isUndefined() || value.isNull()) {
{
return default_; return default_;
} }
try try {
{
return requireIsType<T>(value, what); return requireIsType<T>(value, what);
} } catch (const JsonException&) {
catch (const JsonException &)
{
return default_; return default_;
} }
} }
/// @throw JsonException /// @throw JsonException
template <typename T> template <typename T>
T requireIsType(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") T requireIsType(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
throw JsonException(localWhat + "s parent does not contain " + localWhat); throw JsonException(localWhat + "s parent does not contain " + localWhat);
} }
return requireIsType<T>(parent.value(key), localWhat); return requireIsType<T>(parent.value(key), localWhat);
} }
template <typename T> template <typename T>
T ensureIsType(const QJsonObject &parent, const QString &key, const T default_ = T(), const QString &what = "__placeholder__") T ensureIsType(const QJsonObject& parent, const QString& key, const T default_ = T(), const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
return default_; return default_;
} }
return ensureIsType<T>(parent.value(key), default_, localWhat); return ensureIsType<T>(parent.value(key), default_, localWhat);
} }
template <typename T> template <typename T>
QVector<T> requireIsArrayOf(const QJsonDocument &doc) QVector<T> requireIsArrayOf(const QJsonDocument& doc)
{ {
const QJsonArray array = requireArray(doc); const QJsonArray array = requireArray(doc);
QVector<T> out; QVector<T> out;
for (const QJsonValue val : array) for (const QJsonValue val : array) {
{
out.append(requireIsType<T>(val, "Document")); out.append(requireIsType<T>(val, "Document"));
} }
return out; return out;
} }
template <typename T> template <typename T>
QVector<T> ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value") QVector<T> ensureIsArrayOf(const QJsonValue& value, const QString& what = "Value")
{ {
const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what); const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what);
QVector<T> out; QVector<T> out;
for (const QJsonValue val : array) for (const QJsonValue val : array) {
{
out.append(requireIsType<T>(val, what)); out.append(requireIsType<T>(val, what));
} }
return out; return out;
} }
template <typename T> template <typename T>
QVector<T> ensureIsArrayOf(const QJsonValue &value, const QVector<T> default_, const QString &what = "Value") QVector<T> ensureIsArrayOf(const QJsonValue& value, const QVector<T> default_, const QString& what = "Value")
{ {
if (value.isUndefined()) if (value.isUndefined()) {
{
return default_; return default_;
} }
return ensureIsArrayOf<T>(value, what); return ensureIsArrayOf<T>(value, what);
@ -219,45 +220,46 @@ QVector<T> ensureIsArrayOf(const QJsonValue &value, const QVector<T> default_, c
/// @throw JsonException /// @throw JsonException
template <typename T> template <typename T>
QVector<T> requireIsArrayOf(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") QVector<T> requireIsArrayOf(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
throw JsonException(localWhat + "s parent does not contain " + localWhat); throw JsonException(localWhat + "s parent does not contain " + localWhat);
} }
return ensureIsArrayOf<T>(parent.value(key), localWhat); return ensureIsArrayOf<T>(parent.value(key), localWhat);
} }
template <typename T> template <typename T>
QVector<T> ensureIsArrayOf(const QJsonObject &parent, const QString &key, QVector<T> ensureIsArrayOf(const QJsonObject& parent,
const QVector<T> &default_ = QVector<T>(), const QString &what = "__placeholder__") const QString& key,
const QVector<T>& default_ = QVector<T>(),
const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
return default_; return default_;
} }
return ensureIsArrayOf<T>(parent.value(key), default_, localWhat); return ensureIsArrayOf<T>(parent.value(key), default_, localWhat);
} }
// this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers // this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers
#define JSON_HELPERFUNCTIONS(NAME, TYPE) \ #define JSON_HELPERFUNCTIONS(NAME, TYPE) \
inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \ inline TYPE require##NAME(const QJsonValue& value, const QString& what = "Value") \
{ \ { \
return requireIsType<TYPE>(value, what); \ return requireIsType<TYPE>(value, what); \
} \ } \
inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_ = TYPE(), const QString &what = "Value") \ inline TYPE ensure##NAME(const QJsonValue& value, const TYPE default_ = TYPE(), const QString& what = "Value") \
{ \ { \
return ensureIsType<TYPE>(value, default_, what); \ return ensureIsType<TYPE>(value, default_, what); \
} \ } \
inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \ inline TYPE require##NAME(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") \
{ \ { \
return requireIsType<TYPE>(parent, key, what); \ return requireIsType<TYPE>(parent, key, what); \
} \ } \
inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \ inline TYPE ensure##NAME(const QJsonObject& parent, const QString& key, const TYPE default_ = TYPE(), \
{ \ const QString& what = "__placeholder") \
return ensureIsType<TYPE>(parent, key, default_, what); \ { \
return ensureIsType<TYPE>(parent, key, default_, what); \
} }
JSON_HELPERFUNCTIONS(Array, QJsonArray) JSON_HELPERFUNCTIONS(Array, QJsonArray)
@ -276,5 +278,5 @@ JSON_HELPERFUNCTIONS(Variant, QVariant)
#undef JSON_HELPERFUNCTIONS #undef JSON_HELPERFUNCTIONS
} } // namespace Json
using JSONValidationError = Json::JsonException; using JSONValidationError = Json::JsonException;

View File

@ -1,42 +1,26 @@
#include "KonamiCode.h" #include "KonamiCode.h"
#include <array>
#include <QDebug> #include <QDebug>
#include <array>
namespace { namespace {
const std::array<Qt::Key, 10> konamiCode = const std::array<Qt::Key, 10> konamiCode = { { Qt::Key_Up, Qt::Key_Up, Qt::Key_Down, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right,
{ Qt::Key_Left, Qt::Key_Right, Qt::Key_B, Qt::Key_A } };
{
Qt::Key_Up, Qt::Key_Up,
Qt::Key_Down, Qt::Key_Down,
Qt::Key_Left, Qt::Key_Right,
Qt::Key_Left, Qt::Key_Right,
Qt::Key_B, Qt::Key_A
}
};
}
KonamiCode::KonamiCode(QObject* parent) : QObject(parent)
{
} }
KonamiCode::KonamiCode(QObject* parent) : QObject(parent) {}
void KonamiCode::input(QEvent* event) void KonamiCode::input(QEvent* event)
{ {
if( event->type() == QEvent::KeyPress ) if (event->type() == QEvent::KeyPress) {
{ QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
auto key = Qt::Key(keyEvent->key()); auto key = Qt::Key(keyEvent->key());
if(key == konamiCode[m_progress]) if (key == konamiCode[m_progress]) {
{ m_progress++;
m_progress ++; } else {
}
else
{
m_progress = 0; m_progress = 0;
} }
if(m_progress == static_cast<int>(konamiCode.size())) if (m_progress == static_cast<int>(konamiCode.size())) {
{
m_progress = 0; m_progress = 0;
emit triggered(); emit triggered();
} }

View File

@ -2,16 +2,15 @@
#include <QKeyEvent> #include <QKeyEvent>
class KonamiCode : public QObject class KonamiCode : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
KonamiCode(QObject *parent = 0); KonamiCode(QObject* parent = 0);
void input(QEvent *event); void input(QEvent* event);
signals: signals:
void triggered(); void triggered();
private: private:
int m_progress = 0; int m_progress = 0;
}; };

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
@ -34,44 +35,41 @@
*/ */
#include "LaunchController.h" #include "LaunchController.h"
#include "minecraft/auth/AccountList.h"
#include "Application.h" #include "Application.h"
#include "minecraft/auth/AccountList.h"
#include "ui/MainWindow.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
#include "ui/MainWindow.h"
#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ProfileSelectDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/EditAccountDialog.h"
#include "ui/dialogs/ProfileSelectDialog.h"
#include "ui/dialogs/ProfileSetupDialog.h" #include "ui/dialogs/ProfileSetupDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include <QLineEdit>
#include <QInputDialog>
#include <QStringList>
#include <QHostInfo>
#include <QList>
#include <QHostAddress> #include <QHostAddress>
#include <QHostInfo>
#include <QInputDialog>
#include <QLineEdit>
#include <QList>
#include <QPushButton> #include <QPushButton>
#include <QStringList>
#include "BuildConfig.h" #include "BuildConfig.h"
#include "JavaCommon.h" #include "JavaCommon.h"
#include "tasks/Task.h"
#include "minecraft/auth/AccountTask.h"
#include "launch/steps/TextPrint.h" #include "launch/steps/TextPrint.h"
#include "minecraft/auth/AccountTask.h"
#include "tasks/Task.h"
LaunchController::LaunchController(QObject *parent) : Task(parent) LaunchController::LaunchController(QObject* parent) : Task(parent) {}
{
}
void LaunchController::executeTask() void LaunchController::executeTask()
{ {
if (!m_instance) if (!m_instance) {
{
emitFailed(tr("No instance specified!")); emitFailed(tr("No instance specified!"));
return; return;
} }
if(!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.")); emitFailed(tr("Invalid Java arguments specified. Please fix this first."));
return; return;
} }
@ -81,32 +79,25 @@ void LaunchController::executeTask()
void LaunchController::decideAccount() void LaunchController::decideAccount()
{ {
if(m_accountToUse) { if (m_accountToUse) {
return; return;
} }
// Find an account to use. // Find an account to use.
auto accounts = APPLICATION->accounts(); auto accounts = APPLICATION->accounts();
if (accounts->count() <= 0) if (accounts->count() <= 0) {
{
// Tell the user they need to log in at least one account in order to play. // Tell the user they need to log in at least one account in order to play.
auto reply = CustomMessageBox::selectable( auto reply = CustomMessageBox::selectable(m_parentWidget, tr("No Accounts"),
m_parentWidget, tr("In order to play Minecraft, you must have at least one Microsoft "
tr("No Accounts"), "account which owns Minecraft logged in. "
tr("In order to play Minecraft, you must have at least one Microsoft or Mojang " "Would you like to open the account manager to add an account now?"),
"account logged in. Mojang accounts can only be used offline. " QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)
"Would you like to open the account manager to add an account now?"), ->exec();
QMessageBox::Information,
QMessageBox::Yes | QMessageBox::No
)->exec();
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes) {
{
// Open the account manager. // Open the account manager.
APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts"); APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts");
} } else if (reply == QMessageBox::No) {
else if (reply == QMessageBox::No)
{
// Do not open "profile select" dialog. // Do not open "profile select" dialog.
return; return;
} }
@ -115,20 +106,16 @@ void LaunchController::decideAccount()
// Select the account to use. If the instance has a specific account set, that will be used. Otherwise, the default account will be used // Select the account to use. If the instance has a specific account set, that will be used. Otherwise, the default account will be used
auto instanceAccountId = m_instance->settings()->get("InstanceAccountId").toString(); auto instanceAccountId = m_instance->settings()->get("InstanceAccountId").toString();
auto instanceAccountIndex = accounts->findAccountByProfileId(instanceAccountId); auto instanceAccountIndex = accounts->findAccountByProfileId(instanceAccountId);
if (instanceAccountIndex == -1) { if (instanceAccountIndex == -1 || instanceAccountId.isEmpty()) {
m_accountToUse = accounts->defaultAccount(); m_accountToUse = accounts->defaultAccount();
} else { } else {
m_accountToUse = accounts->at(instanceAccountIndex); m_accountToUse = accounts->at(instanceAccountIndex);
} }
if (!m_accountToUse) if (!m_accountToUse) {
{
// If no default account is set, ask the user which one to use. // If no default account is set, ask the user which one to use.
ProfileSelectDialog selectDialog( ProfileSelectDialog selectDialog(tr("Which account would you like to use?"), ProfileSelectDialog::GlobalDefaultCheckbox,
tr("Which account would you like to use?"), m_parentWidget);
ProfileSelectDialog::GlobalDefaultCheckbox,
m_parentWidget
);
selectDialog.exec(); selectDialog.exec();
@ -142,13 +129,12 @@ void LaunchController::decideAccount()
} }
} }
void LaunchController::login()
void LaunchController::login() { {
decideAccount(); decideAccount();
// if no account is selected, we bail // if no account is selected, we bail
if (!m_accountToUse) if (!m_accountToUse) {
{
emitFailed(tr("No account selected for launch.")); emitFailed(tr("No account selected for launch."));
return; return;
} }
@ -157,15 +143,11 @@ void LaunchController::login() {
bool tryagain = true; bool tryagain = true;
unsigned int tries = 0; unsigned int tries = 0;
while (tryagain) while (tryagain) {
{
if (tries > 0 && tries % 3 == 0) { if (tries > 0 && tries % 3 == 0) {
auto result = QMessageBox::question( auto result =
m_parentWidget, QMessageBox::question(m_parentWidget, tr("Continue launch?"),
tr("Continue launch?"), tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?").arg(tries));
tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?")
.arg(tries)
);
if (result == QMessageBox::No) { if (result == QMessageBox::No) {
emitAborted(); emitAborted();
@ -179,60 +161,48 @@ void LaunchController::login() {
m_accountToUse->fillSession(m_session); m_accountToUse->fillSession(m_session);
// Launch immediately in true offline mode // Launch immediately in true offline mode
if(m_accountToUse->isOffline()) { if (m_accountToUse->isOffline()) {
launchInstance(); launchInstance();
return; 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;
// NOTE: fallthrough is intentional
} }
/* fallthrough */
case AccountState::Online: { case AccountState::Online: {
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 message = tr("Choose your offline mode player name."); QString message = tr("Choose your offline mode player name.");
if(m_session->demo) { if (m_session->demo) {
message = tr("Choose your demo mode player name."); message = tr("Choose your demo mode player name.");
} }
QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString(); QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString();
QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName; QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName;
QString name = QInputDialog::getText( QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), message, QLineEdit::Normal, usedname, &ok);
m_parentWidget, if (!ok) {
tr("Player name"),
message,
QLineEdit::Normal,
usedname,
&ok
);
if (!ok)
{
tryagain = false; tryagain = false;
break; break;
} }
if (name.length()) if (name.length()) {
{
usedname = name; usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname); 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
} }
if(m_accountToUse->ownsMinecraft()) { if (m_accountToUse->ownsMinecraft()) {
if(!m_accountToUse->hasProfile()) { if (!m_accountToUse->hasProfile()) {
// Now handle setting up a profile name here... // Now handle setting up a profile name here...
ProfileSetupDialog dialog(m_accountToUse, m_parentWidget); ProfileSetupDialog dialog(m_accountToUse, m_parentWidget);
if (dialog.exec() == QDialog::Accepted) if (dialog.exec() == QDialog::Accepted) {
{
tryagain = true; tryagain = true;
continue; continue;
} } else {
else
{
emitFailed(tr("Received undetermined session status during login.")); emitFailed(tr("Received undetermined session status during login."));
return; return;
} }
@ -240,24 +210,24 @@ void LaunchController::login() {
// we own Minecraft, there is a profile, it's all ready to go! // we own Minecraft, there is a profile, it's all ready to go!
launchInstance(); launchInstance();
return; return;
} } else {
else {
// play demo ? // play demo ?
QMessageBox box(m_parentWidget); QMessageBox box(m_parentWidget);
box.setWindowTitle(tr("Play demo?")); box.setWindowTitle(tr("Play demo?"));
box.setText(tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play the demo?")); box.setText(
tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play "
"the demo?"));
box.setIcon(QMessageBox::Warning); box.setIcon(QMessageBox::Warning);
auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole); auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole);
auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole); auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole);
box.setDefaultButton(cancelButton); box.setDefaultButton(cancelButton);
box.exec(); box.exec();
if(box.clickedButton() == demoButton) { if (box.clickedButton() == demoButton) {
// play demo here // play demo here
m_session->MakeDemo(); m_session->MakeDemo();
launchInstance(); launchInstance();
} } else {
else {
emitFailed(tr("Launch cancelled - account does not own Minecraft.")); emitFailed(tr("Launch cancelled - account does not own Minecraft."));
} }
} }
@ -267,13 +237,12 @@ void LaunchController::login() {
// This means some sort of soft error that we can fix with a refresh ... so let's refresh. // This means some sort of soft error that we can fix with a refresh ... so let's refresh.
case AccountState::Unchecked: { case AccountState::Unchecked: {
m_accountToUse->refresh(); m_accountToUse->refresh();
// NOTE: fallthrough intentional
} }
/* fallthrough */
case AccountState::Working: { case AccountState::Working: {
// refresh is in progress, we need to wait for it to finish to proceed. // refresh is in progress, we need to wait for it to finish to proceed.
ProgressDialog progDialog(m_parentWidget); ProgressDialog progDialog(m_parentWidget);
if (m_online) if (m_online) {
{
progDialog.setSkipButton(true, tr("Play Offline")); progDialog.setSkipButton(true, tr("Play Offline"));
} }
auto task = m_accountToUse->currentTask(); auto task = m_accountToUse->currentTask();
@ -288,37 +257,24 @@ void LaunchController::login() {
*/ */
case AccountState::Expired: { case AccountState::Expired: {
auto errorString = tr("The account has expired and needs to be logged into manually again."); auto errorString = tr("The account has expired and needs to be logged into manually again.");
QMessageBox::warning( QMessageBox::warning(m_parentWidget, tr("Account refresh failed"), errorString, QMessageBox::StandardButton::Ok,
m_parentWidget, QMessageBox::StandardButton::Ok);
tr("Account refresh failed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
case AccountState::Disabled: { case AccountState::Disabled: {
auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again."); auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again.");
QMessageBox::warning( QMessageBox::warning(m_parentWidget, tr("Client identification changed"), errorString, QMessageBox::StandardButton::Ok,
m_parentWidget, QMessageBox::StandardButton::Ok);
tr("Client identification changed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; 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 =
QMessageBox::warning( tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account "
m_parentWidget, "you migrated this one to.");
tr("Account gone"), QMessageBox::warning(m_parentWidget, tr("Account gone"), errorString, QMessageBox::StandardButton::Ok,
errorString, QMessageBox::StandardButton::Ok);
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
@ -332,48 +288,45 @@ void LaunchController::launchInstance()
Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL"); Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL");
Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL"); Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL");
if(!m_instance->reloadSettings()) if (!m_instance->reloadSettings()) {
{
QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't load the instance profile.")); QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't load the instance profile."));
emitFailed(tr("Couldn't load the instance profile.")); emitFailed(tr("Couldn't load the instance profile."));
return; return;
} }
m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin); m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin);
if (!m_launcher) if (!m_launcher) {
{
emitFailed(tr("Couldn't instantiate a launcher.")); emitFailed(tr("Couldn't instantiate a launcher."));
return; return;
} }
auto console = qobject_cast<InstanceWindow *>(m_parentWidget); auto console = qobject_cast<InstanceWindow*>(m_parentWidget);
auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); auto showConsole = m_instance->settings()->get("ShowConsole").toBool();
if(!console && showConsole) if (!console && showConsole) {
{
APPLICATION->showInstanceWindow(m_instance); APPLICATION->showInstanceWindow(m_instance);
} }
connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch);
connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded); connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded);
connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed); connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed);
connect(m_launcher.get(), &LaunchTask::requestProgress, this, &LaunchController::onProgressRequested); connect(m_launcher.get(), &LaunchTask::requestProgress, this, &LaunchController::onProgressRequested);
// Prepend Online and Auth Status // Prepend Online and Auth Status
QString online_mode; QString online_mode;
if(m_session->wants_online) { if (m_session->wants_online) {
online_mode = "online"; online_mode = "online";
// Prepend Server Status // Prepend Server Status
QStringList servers = {"authserver.mojang.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com"}; QStringList servers = { "authserver.mojang.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" };
QString resolved_servers = ""; QString resolved_servers = "";
QHostInfo host_info; QHostInfo host_info;
for(QString server : servers) { for (QString server : servers) {
host_info = QHostInfo::fromName(server); host_info = QHostInfo::fromName(server);
resolved_servers = resolved_servers + server + " resolves to:\n ["; resolved_servers = resolved_servers + server + " resolves to:\n [";
if(!host_info.addresses().isEmpty()) { if (!host_info.addresses().isEmpty()) {
for(QHostAddress address : host_info.addresses()) { for (QHostAddress address : host_info.addresses()) {
resolved_servers = resolved_servers + address.toString(); resolved_servers = resolved_servers + address.toString();
if(!host_info.addresses().endsWith(address)) { if (!host_info.addresses().endsWith(address)) {
resolved_servers = resolved_servers + ", "; resolved_servers = resolved_servers + ", ";
} }
} }
@ -387,46 +340,47 @@ void LaunchController::launchInstance()
online_mode = m_demo ? "demo" : "offline"; online_mode = m_demo ? "demo" : "offline";
} }
m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher)); m_launcher->prependStep(
makeShared<TextPrint>(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher));
// Prepend Version // Prepend Version
m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), BuildConfig.LAUNCHER_DISPLAYNAME + " version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::Launcher)); {
auto versionString = QString("%1 version: %2 (%3)")
.arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM);
m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), versionString + "\n\n", MessageLevel::Launcher));
}
m_launcher->start(); m_launcher->start();
} }
void LaunchController::readyForLaunch() void LaunchController::readyForLaunch()
{ {
if (!m_profiler) if (!m_profiler) {
{
m_launcher->proceed(); m_launcher->proceed();
return; return;
} }
QString error; QString error;
if (!m_profiler->check(&error)) if (!m_profiler->check(&error)) {
{
m_launcher->abort(); m_launcher->abort();
QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error));
emitFailed("Profiler startup failed!"); emitFailed("Profiler startup failed!");
QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Profiler check for %1 failed: %2").arg(m_profiler->name(), error));
return; return;
} }
BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); BaseProfiler* profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this);
connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message) connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString& message) {
{ QMessageBox msg(m_parentWidget);
QMessageBox msg;
msg.setText(tr("The game launch is delayed until you press the " msg.setText(tr("The game launch is delayed until you press the "
"button. This is the right time to setup the profiler, as the " "button. This is the right time to setup the profiler, as the "
"profiler server is running now.\n\n%1").arg(message)); "profiler server is running now.\n\n%1")
.arg(message));
msg.setWindowTitle(tr("Waiting.")); msg.setWindowTitle(tr("Waiting."));
msg.setIcon(QMessageBox::Information); msg.setIcon(QMessageBox::Information);
msg.addButton(tr("Launch"), QMessageBox::AcceptRole); msg.addButton(tr("&Launch"), QMessageBox::AcceptRole);
msg.setModal(true);
msg.exec(); msg.exec();
m_launcher->proceed(); m_launcher->proceed();
}); });
connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message) connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString& message) {
{
QMessageBox msg; QMessageBox msg;
msg.setText(tr("Couldn't start the profiler: %1").arg(message)); msg.setText(tr("Couldn't start the profiler: %1").arg(message));
msg.setWindowTitle(tr("Error")); msg.setWindowTitle(tr("Error"));
@ -447,8 +401,7 @@ void LaunchController::onSucceeded()
void LaunchController::onFailed(QString reason) void LaunchController::onFailed(QString reason)
{ {
if(m_instance->settings()->get("ShowConsoleOnError").toBool()) if (m_instance->settings()->get("ShowConsoleOnError").toBool()) {
{
APPLICATION->showInstanceWindow(m_instance, "console"); APPLICATION->showInstanceWindow(m_instance, "console");
} }
emitFailed(reason); emitFailed(reason);
@ -464,21 +417,18 @@ void LaunchController::onProgressRequested(Task* task)
bool LaunchController::abort() bool LaunchController::abort()
{ {
if(!m_launcher) if (!m_launcher) {
{
return true; return true;
} }
if(!m_launcher->canAbort()) if (!m_launcher->canAbort()) {
{
return false; return false;
} }
auto response = CustomMessageBox::selectable( auto response = CustomMessageBox::selectable(m_parentWidget, tr("Kill Minecraft?"),
m_parentWidget, tr("Kill Minecraft?"), tr("This can cause the instance to get corrupted and should only be used if Minecraft "
tr("This can cause the instance to get corrupted and should only be used if Minecraft " "is frozen for some reason"),
"is frozen for some reason"), QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); ->exec();
if (response == QMessageBox::Yes) if (response == QMessageBox::Yes) {
{
return m_launcher->abort(); return m_launcher->abort();
} }
return false; return false;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -34,81 +34,61 @@
*/ */
#pragma once #pragma once
#include <QObject>
#include <BaseInstance.h> #include <BaseInstance.h>
#include <tools/BaseProfiler.h> #include <tools/BaseProfiler.h>
#include <QObject>
#include "minecraft/launch/MinecraftServerTarget.h"
#include "minecraft/auth/MinecraftAccount.h" #include "minecraft/auth/MinecraftAccount.h"
#include "minecraft/launch/MinecraftServerTarget.h"
class InstanceWindow; class InstanceWindow;
class LaunchController: public Task class LaunchController : public Task {
{
Q_OBJECT Q_OBJECT
public: public:
void executeTask() override; void executeTask() override;
LaunchController(QObject * parent = nullptr); LaunchController(QObject* parent = nullptr);
virtual ~LaunchController(){}; virtual ~LaunchController(){};
void setInstance(InstancePtr instance) { void setInstance(InstancePtr instance) { m_instance = instance; }
m_instance = instance;
}
InstancePtr instance() { InstancePtr instance() { return m_instance; }
return m_instance;
}
void setOnline(bool online) { void setOnline(bool online) { m_online = online; }
m_online = online;
}
void setDemo(bool demo) { void setDemo(bool demo) { m_demo = demo; }
m_demo = demo;
}
void setProfiler(BaseProfilerFactory *profiler) { void setProfiler(BaseProfilerFactory* profiler) { m_profiler = profiler; }
m_profiler = profiler;
}
void setParentWidget(QWidget * widget) { void setParentWidget(QWidget* widget) { m_parentWidget = widget; }
m_parentWidget = widget;
}
void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); }
m_serverToJoin = std::move(serverToJoin);
}
void setAccountToUse(MinecraftAccountPtr accountToUse) { void setAccountToUse(MinecraftAccountPtr accountToUse) { m_accountToUse = std::move(accountToUse); }
m_accountToUse = std::move(accountToUse);
}
QString id() QString id() { return m_instance->id(); }
{
return m_instance->id();
}
bool abort() override; bool abort() override;
private: private:
void login(); void login();
void launchInstance(); void launchInstance();
void decideAccount(); void decideAccount();
private slots: private slots:
void readyForLaunch(); void readyForLaunch();
void onSucceeded(); void onSucceeded();
void onFailed(QString reason); void onFailed(QString reason);
void onProgressRequested(Task *task); void onProgressRequested(Task* task);
private: private:
BaseProfilerFactory *m_profiler = nullptr; BaseProfilerFactory* m_profiler = nullptr;
bool m_online = true; bool m_online = true;
bool m_demo = false; bool m_demo = false;
InstancePtr m_instance; InstancePtr m_instance;
QWidget * m_parentWidget = nullptr; QWidget* m_parentWidget = nullptr;
InstanceWindow *m_console = nullptr; InstanceWindow* m_console = nullptr;
MinecraftAccountPtr m_accountToUse = nullptr; MinecraftAccountPtr m_accountToUse = nullptr;
AuthSessionPtr m_session; AuthSessionPtr m_session;
shared_qobject_ptr<LaunchTask> m_launcher; shared_qobject_ptr<LaunchTask> m_launcher;

View File

@ -39,7 +39,7 @@
#include <QTextDecoder> #include <QTextDecoder>
#include "MessageLevel.h" #include "MessageLevel.h"
LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent) LoggedProcess::LoggedProcess(QObject* parent) : QProcess(parent)
{ {
// QProcess has a strange interface... let's map a lot of those into a few. // QProcess has a strange interface... let's map a lot of those into a few.
connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut); connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
@ -51,8 +51,7 @@ LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent)
LoggedProcess::~LoggedProcess() LoggedProcess::~LoggedProcess()
{ {
if(m_is_detachable) if (m_is_detachable) {
{
setProcessState(QProcess::NotRunning); setProcessState(QProcess::NotRunning);
} }
} }
@ -66,14 +65,9 @@ QStringList LoggedProcess::reprocess(const QByteArray& data, QTextDecoder& decod
m_leftover_line = ""; m_leftover_line = "";
} }
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) auto lines = str.remove(QChar::CarriageReturn).split(QChar::LineFeed);
auto lines = str.remove(QChar::CarriageReturn).split(QChar::LineFeed, QString::SkipEmptyParts);
#else
auto lines = str.remove(QChar::CarriageReturn).split(QChar::LineFeed, Qt::SkipEmptyParts);
#endif
if (!str.endsWith(QChar::LineFeed)) m_leftover_line = lines.takeLast();
m_leftover_line = lines.takeLast();
return lines; return lines;
} }
@ -95,39 +89,31 @@ void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
m_exit_code = exit_code; m_exit_code = exit_code;
// based on state, send signals // based on state, send signals
if (!m_is_aborting) if (!m_is_aborting) {
{ if (status == QProcess::NormalExit) {
if (status == QProcess::NormalExit)
{
//: Message displayed on instance exit //: Message displayed on instance exit
emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::Launcher); emit log({ tr("Process exited with code %1.").arg(exit_code) }, MessageLevel::Launcher);
changeState(LoggedProcess::Finished); changeState(LoggedProcess::Finished);
} } else {
else
{
//: Message displayed on instance crashed //: Message displayed on instance crashed
if(exit_code == -1) if (exit_code == -1)
emit log({tr("Process crashed.")}, MessageLevel::Launcher); emit log({ tr("Process crashed.") }, MessageLevel::Launcher);
else else
emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::Launcher); emit log({ tr("Process crashed with exitcode %1.").arg(exit_code) }, MessageLevel::Launcher);
changeState(LoggedProcess::Crashed); changeState(LoggedProcess::Crashed);
} }
} } else {
else
{
//: Message displayed after the instance exits due to kill request //: Message displayed after the instance exits due to kill request
emit log({tr("Process was killed by user.")}, MessageLevel::Error); emit log({ tr("Process was killed by user.") }, MessageLevel::Error);
changeState(LoggedProcess::Aborted); changeState(LoggedProcess::Aborted);
} }
} }
void LoggedProcess::on_error(QProcess::ProcessError error) void LoggedProcess::on_error(QProcess::ProcessError error)
{ {
switch(error) switch (error) {
{ case QProcess::FailedToStart: {
case QProcess::FailedToStart: emit log({ tr("The process failed to start.") }, MessageLevel::Fatal);
{
emit log({tr("The process failed to start.")}, MessageLevel::Fatal);
changeState(LoggedProcess::FailedToStart); changeState(LoggedProcess::FailedToStart);
break; break;
} }
@ -154,7 +140,7 @@ int LoggedProcess::exitCode() const
void LoggedProcess::changeState(LoggedProcess::State state) void LoggedProcess::changeState(LoggedProcess::State state)
{ {
if(state == m_state) if (state == m_state)
return; return;
m_state = state; m_state = state;
emit stateChanged(m_state); emit stateChanged(m_state);
@ -167,24 +153,19 @@ LoggedProcess::State LoggedProcess::state() const
void LoggedProcess::on_stateChange(QProcess::ProcessState state) void LoggedProcess::on_stateChange(QProcess::ProcessState state)
{ {
switch(state) switch (state) {
{
case QProcess::NotRunning: case QProcess::NotRunning:
break; // let's not - there are too many that handle this already. break; // let's not - there are too many that handle this already.
case QProcess::Starting: case QProcess::Starting: {
{ if (m_state != LoggedProcess::NotRunning) {
if(m_state != LoggedProcess::NotRunning) qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Starting;
{
qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting;
} }
changeState(LoggedProcess::Starting); changeState(LoggedProcess::Starting);
return; return;
} }
case QProcess::Running: case QProcess::Running: {
{ if (m_state != LoggedProcess::Starting) {
if(m_state != LoggedProcess::Starting) qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Running;
{
qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running;
} }
changeState(LoggedProcess::Running); changeState(LoggedProcess::Running);
return; return;

View File

@ -43,22 +43,12 @@
* This is a basic process. * This is a basic process.
* It has line-based logging support and hides some of the nasty bits. * It has line-based logging support and hides some of the nasty bits.
*/ */
class LoggedProcess : public QProcess class LoggedProcess : public QProcess {
{ Q_OBJECT
Q_OBJECT public:
public: enum State { NotRunning, Starting, FailedToStart, Running, Finished, Crashed, Aborted };
enum State
{
NotRunning,
Starting,
FailedToStart,
Running,
Finished,
Crashed,
Aborted
};
public: public:
explicit LoggedProcess(QObject* parent = 0); explicit LoggedProcess(QObject* parent = 0);
virtual ~LoggedProcess(); virtual ~LoggedProcess();
@ -67,30 +57,29 @@ public:
void setDetachable(bool detachable); void setDetachable(bool detachable);
signals: signals:
void log(QStringList lines, MessageLevel::Enum level); void log(QStringList lines, MessageLevel::Enum level);
void stateChanged(LoggedProcess::State state); void stateChanged(LoggedProcess::State state);
public slots: public slots:
/** /**
* @brief kill the process - equivalent to kill -9 * @brief kill the process - equivalent to kill -9
*/ */
void kill(); void kill();
private slots:
private slots:
void on_stdErr(); void on_stdErr();
void on_stdOut(); void on_stdOut();
void on_exit(int exit_code, QProcess::ExitStatus status); void on_exit(int exit_code, QProcess::ExitStatus status);
void on_error(QProcess::ProcessError error); void on_error(QProcess::ProcessError error);
void on_stateChange(QProcess::ProcessState); void on_stateChange(QProcess::ProcessState);
private: private:
void changeState(LoggedProcess::State state); void changeState(LoggedProcess::State state);
QStringList reprocess(const QByteArray& data, QTextDecoder& decoder); QStringList reprocess(const QByteArray& data, QTextDecoder& decoder);
private: private:
QTextDecoder m_err_decoder = QTextDecoder(QTextCodec::codecForLocale()); QTextDecoder m_err_decoder = QTextDecoder(QTextCodec::codecForLocale());
QTextDecoder m_out_decoder = QTextDecoder(QTextCodec::codecForLocale()); QTextDecoder m_out_decoder = QTextDecoder(QTextCodec::codecForLocale());
QString m_leftover_line; QString m_leftover_line;

View File

@ -16,31 +16,31 @@
*/ */
#include <MMCTime.h> #include <MMCTime.h>
#include <qobject.h>
#include <QObject>
#include <QDateTime> #include <QDateTime>
#include <QObject>
#include <QTextStream> #include <QTextStream>
QString Time::prettifyDuration(int64_t duration) { QString Time::prettifyDuration(int64_t duration, bool noDays)
int seconds = (int) (duration % 60); {
int seconds = (int)(duration % 60);
duration /= 60; duration /= 60;
int minutes = (int) (duration % 60); int minutes = (int)(duration % 60);
duration /= 60; duration /= 60;
int hours = (int) (duration % 24); int hours = (int)(noDays ? duration : (duration % 24));
int days = (int) (duration / 24); int days = (int)(noDays ? 0 : (duration / 24));
if((hours == 0)&&(days == 0)) if ((hours == 0) && (days == 0)) {
{
return QObject::tr("%1min %2s").arg(minutes).arg(seconds); return QObject::tr("%1min %2s").arg(minutes).arg(seconds);
} }
if (days == 0) if (days == 0) {
{
return QObject::tr("%1h %2min").arg(hours).arg(minutes); return QObject::tr("%1h %2min").arg(hours).arg(minutes);
} }
return QObject::tr("%1d %2h %3min").arg(days).arg(hours).arg(minutes); return QObject::tr("%1d %2h %3min").arg(days).arg(hours).arg(minutes);
} }
QString Time::humanReadableDuration(double duration, int precision) { QString Time::humanReadableDuration(double duration, int precision)
{
using days = std::chrono::duration<int, std::ratio<86400>>; using days = std::chrono::duration<int, std::ratio<86400>>;
QString outStr; QString outStr;
@ -48,8 +48,8 @@ QString Time::humanReadableDuration(double duration, int precision) {
bool neg = false; bool neg = false;
if (duration < 0) { if (duration < 0) {
neg = true; // flag neg = true; // flag
duration *= -1; // invert duration *= -1; // invert
} }
auto std_duration = std::chrono::duration<double>(duration); auto std_duration = std::chrono::duration<double>(duration);
@ -78,22 +78,22 @@ QString Time::humanReadableDuration(double duration, int precision) {
if (hc) { if (hc) {
if (dc) if (dc)
os << " "; os << " ";
os << qSetFieldWidth(2) << hc << QObject::tr("h"); // hours os << qSetFieldWidth(2) << hc << QObject::tr("h"); // hours
} }
if (mc) { if (mc) {
if (dc || hc) if (dc || hc)
os << " "; os << " ";
os << qSetFieldWidth(2) << mc << QObject::tr("m"); // minutes os << qSetFieldWidth(2) << mc << QObject::tr("m"); // minutes
} }
if (dc || hc || mc || sc) { if (dc || hc || mc || sc) {
if (dc || hc || mc) if (dc || hc || mc)
os << " "; os << " ";
os << qSetFieldWidth(2) << sc << QObject::tr("s"); // seconds os << qSetFieldWidth(2) << sc << QObject::tr("s"); // seconds
} }
if ((msc && (precision > 0)) || !(dc || hc || mc || sc)) { if ((msc && (precision > 0)) || !(dc || hc || mc || sc)) {
if (dc || hc || mc || sc) if (dc || hc || mc || sc)
os << " "; os << " ";
os << qSetFieldWidth(0) << qSetRealNumberPrecision(precision) << msc << QObject::tr("ms"); // miliseconds os << qSetFieldWidth(0) << qSetRealNumberPrecision(precision) << msc << QObject::tr("ms"); // miliseconds
} }
os.flush(); os.flush();

View File

@ -20,7 +20,7 @@
namespace Time { namespace Time {
QString prettifyDuration(int64_t duration); QString prettifyDuration(int64_t duration, bool noDays = false);
/** /**
* @brief Returns a string with short form time duration ie. `2days 1h3m4s56.0ms`. * @brief Returns a string with short form time duration ie. `2days 1h3m4s56.0ms`.
@ -31,4 +31,4 @@ QString prettifyDuration(int64_t duration);
* @return QString * @return QString
*/ */
QString humanReadableDuration(double duration, int precision = 0); QString humanReadableDuration(double duration, int precision = 0);
} } // namespace Time

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
* *
* 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
@ -33,56 +34,54 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MMCZip.h"
#include <quazip/quazip.h> #include <quazip/quazip.h>
#include <quazip/quazipdir.h> #include <quazip/quazipdir.h>
#include <quazip/quazipfile.h> #include <quazip/quazipfile.h>
#include "MMCZip.h"
#include "FileSystem.h" #include "FileSystem.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QUrl>
#if defined(LAUNCHER_APPLICATION)
#include <QtConcurrentRun>
#endif
namespace MMCZip {
// ours // ours
bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, const FilterFunction filter) bool 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);
QuaZipFile fileInsideMod(&modZip); QuaZipFile fileInsideMod(&modZip);
QuaZipFile zipOutFile(into); QuaZipFile zipOutFile(into);
for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) {
{
QString filename = modZip.getCurrentFileName(); QString filename = modZip.getCurrentFileName();
if (filter && !filter(filename)) if (filter && !filter(filename)) {
{ qDebug() << "Skipping file " << filename << " from " << from.fileName() << " - filtered";
qDebug() << "Skipping file " << filename << " from "
<< from.fileName() << " - filtered";
continue; continue;
} }
if (contained.contains(filename)) if (contained.contains(filename)) {
{ qDebug() << "Skipping already contained file " << filename << " from " << from.fileName();
qDebug() << "Skipping already contained file " << filename << " from "
<< from.fileName();
continue; continue;
} }
contained.insert(filename); contained.insert(filename);
if (!fileInsideMod.open(QIODevice::ReadOnly)) if (!fileInsideMod.open(QIODevice::ReadOnly)) {
{
qCritical() << "Failed to open " << filename << " from " << from.fileName(); qCritical() << "Failed to open " << filename << " from " << from.fileName();
return false; return false;
} }
QuaZipNewInfo info_out(fileInsideMod.getActualFileName()); QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) {
{
qCritical() << "Failed to open " << filename << " in the jar"; qCritical() << "Failed to open " << filename << " in the jar";
fileInsideMod.close(); fileInsideMod.close();
return false; return false;
} }
if (!JlCompress::copyData(fileInsideMod, zipOutFile)) if (!JlCompress::copyData(fileInsideMod, zipOutFile)) {
{
zipOutFile.close(); zipOutFile.close();
fileInsideMod.close(); fileInsideMod.close();
qCritical() << "Failed to copy data of " << filename << " into the jar"; qCritical() << "Failed to copy data of " << filename << " into the jar";
@ -94,10 +93,11 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &containe
return true; return true;
} }
bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks) bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks)
{ {
QDir directory(dir); QDir directory(dir);
if (!directory.exists()) return false; if (!directory.exists())
return false;
for (auto e : files) { for (auto e : files) {
auto filePath = directory.relativeFilePath(e.absoluteFilePath()); auto filePath = directory.relativeFilePath(e.absoluteFilePath());
@ -109,17 +109,18 @@ bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, boo
srcPath = e.canonicalFilePath(); srcPath = e.canonicalFilePath();
} }
} }
if( !JlCompress::compressFile(zip, srcPath, filePath)) return false; if (!JlCompress::compressFile(zip, srcPath, filePath))
return false;
} }
return true; return true;
} }
bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks)
{ {
QuaZip zip(fileCompressed); QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) { if (!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed); QFile::remove(fileCompressed);
return false; return false;
} }
@ -127,7 +128,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList
auto result = compressDirFiles(&zip, dir, files, followSymlinks); auto result = compressDirFiles(&zip, dir, files, followSymlinks);
zip.close(); zip.close();
if(zip.getZipError()!=0) { if (zip.getZipError() != 0) {
QFile::remove(fileCompressed); QFile::remove(fileCompressed);
return false; return false;
} }
@ -135,12 +136,12 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList
return result; return result;
} }
#if defined(LAUNCHER_APPLICATION)
// ours // ours
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods) bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods)
{ {
QuaZip zipOut(targetJarPath); QuaZip zipOut(targetJarPath);
if (!zipOut.open(QuaZip::mdCreate)) if (!zipOut.open(QuaZip::mdCreate)) {
{
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to open the minecraft.jar for modding"; qCritical() << "Failed to open the minecraft.jar for modding";
return false; return false;
@ -151,37 +152,29 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
// Modify the jar // Modify the jar
// This needs to be done in reverse-order to ensure we respect the loading order of components // This needs to be done in reverse-order to ensure we respect the loading order of components
for (auto i = mods.crbegin(); i != mods.crend(); i++) for (auto i = mods.crbegin(); i != mods.crend(); i++) {
{
const auto* mod = *i; const auto* mod = *i;
// do not merge disabled mods. // do not merge disabled mods.
if (!mod->enabled()) if (!mod->enabled())
continue; continue;
if (mod->type() == ResourceType::ZIPFILE) if (mod->type() == ResourceType::ZIPFILE) {
{ if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles)) {
if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles))
{
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
return false; return false;
} }
} } else if (mod->type() == ResourceType::SINGLEFILE) {
else if (mod->type() == ResourceType::SINGLEFILE)
{
// FIXME: buggy - does not work with addedFiles // FIXME: buggy - does not work with addedFiles
auto filename = mod->fileinfo(); auto filename = mod->fileinfo();
if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) {
{
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
return false; return false;
} }
addedFiles.insert(filename.fileName()); addedFiles.insert(filename.fileName());
} } else if (mod->type() == ResourceType::FOLDER) {
else if (mod->type() == ResourceType::FOLDER)
{
// untested, but seems to be unused / not possible to reach // 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->fileinfo(); auto filename = mod->fileinfo();
@ -190,25 +183,21 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
dir.cdUp(); dir.cdUp();
QString parent_dir = dir.absolutePath(); QString parent_dir = dir.absolutePath();
auto files = QFileInfoList(); auto files = QFileInfoList();
MMCZip::collectFileListRecursively(what_to_zip, nullptr, &files, nullptr); collectFileListRecursively(what_to_zip, nullptr, &files, nullptr);
for (auto e : files) { for (auto e : files) {
if (addedFiles.contains(e.filePath())) if (addedFiles.contains(e.filePath()))
files.removeAll(e); files.removeAll(e);
} }
if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) if (!compressDirFiles(&zipOut, parent_dir, files)) {
{
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar.";
return false; return false;
} }
qDebug() << "Adding folder " << filename.fileName() << " from " qDebug() << "Adding folder " << filename.fileName() << " from " << filename.absoluteFilePath();
<< filename.absoluteFilePath(); } else {
}
else
{
// Make sure we do not continue launching when something is missing or undefined... // Make sure we do not continue launching when something is missing or undefined...
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
@ -217,8 +206,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
} }
} }
if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key){return !key.contains("META-INF");})) if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key) { return !key.contains("META-INF"); })) {
{
zipOut.close(); zipOut.close();
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to insert minecraft.jar contents."; qCritical() << "Failed to insert minecraft.jar contents.";
@ -227,17 +215,17 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
// Recompress the jar // Recompress the jar
zipOut.close(); zipOut.close();
if (zipOut.getZipError() != 0) if (zipOut.getZipError() != 0) {
{
QFile::remove(targetJarPath); QFile::remove(targetJarPath);
qCritical() << "Failed to finalize minecraft.jar!"; qCritical() << "Failed to finalize minecraft.jar!";
return false; return false;
} }
return true; return true;
} }
#endif
// ours // ours
QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root)
{ {
QuaZipDir rootDir(zip, root); QuaZipDir rootDir(zip, root);
for (auto&& fileName : rootDir.entryList(QDir::Files)) { for (auto&& fileName : rootDir.entryList(QDir::Files)) {
@ -261,27 +249,23 @@ QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QS
} }
// ours // ours
bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root) bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root)
{ {
QuaZipDir rootDir(zip, root); QuaZipDir rootDir(zip, root);
for(auto fileName: rootDir.entryList(QDir::Files)) for (auto fileName : rootDir.entryList(QDir::Files)) {
{ if (fileName == what) {
if(fileName == what)
{
result.append(root); result.append(root);
return true; return true;
} }
} }
for(auto fileName: rootDir.entryList(QDir::Dirs)) for (auto fileName : rootDir.entryList(QDir::Dirs)) {
{
findFilesInZip(zip, what, result, root + fileName); findFilesInZip(zip, what, result, root + fileName);
} }
return !result.isEmpty(); return !result.isEmpty();
} }
// ours // ours
std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target) std::optional<QStringList> extractSubDir(QuaZip* zip, const QString& subdir, const QString& target)
{ {
auto target_top_dir = QUrl::fromLocalFile(target); auto target_top_dir = QUrl::fromLocalFile(target);
@ -289,16 +273,13 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target; qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
auto numEntries = zip->getEntriesCount(); auto numEntries = zip->getEntriesCount();
if(numEntries < 0) { if (numEntries < 0) {
qWarning() << "Failed to enumerate files in archive"; qWarning() << "Failed to enumerate files in archive";
return std::nullopt; return std::nullopt;
} } else if (numEntries == 0) {
else if(numEntries == 0) {
qDebug() << "Extracting empty archives seems odd..."; qDebug() << "Extracting empty archives seems odd...";
return extracted; return extracted;
} } else if (!zip->goToFirstFile()) {
else if (!zip->goToFirstFile())
{
qWarning() << "Failed to seek to first file in zip"; qWarning() << "Failed to seek to first file in zip";
return std::nullopt; return std::nullopt;
} }
@ -334,7 +315,8 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
} }
if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) { if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) {
qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" << target; qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path"
<< target;
return std::nullopt; return std::nullopt;
} }
@ -345,7 +327,8 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
} }
extracted.append(target_file_path); extracted.append(target_file_path);
QFile::setPermissions(target_file_path, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); QFile::setPermissions(target_file_path,
QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser);
qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path; qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path;
} while (zip->goToNextFile()); } while (zip->goToNextFile());
@ -354,66 +337,66 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
} }
// ours // ours
bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &target) bool extractRelFile(QuaZip* zip, const QString& file, const QString& target)
{ {
return JlCompress::extractFile(zip, file, target); return JlCompress::extractFile(zip, file, target);
} }
// ours // ours
std::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString dir) std::optional<QStringList> extractDir(QString fileCompressed, QString dir)
{ {
QuaZip zip(fileCompressed); QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip)) if (!zip.open(QuaZip::mdUnzip)) {
{
// check if this is a minimum size empty zip file... // check if this is a minimum size empty zip file...
QFileInfo fileInfo(fileCompressed); QFileInfo fileInfo(fileCompressed);
if(fileInfo.size() == 22) { if (fileInfo.size() == 22) {
return QStringList(); return QStringList();
} }
qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();
;
return std::nullopt; return std::nullopt;
} }
return MMCZip::extractSubDir(&zip, "", dir); return extractSubDir(&zip, "", dir);
} }
// ours // ours
std::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir) std::optional<QStringList> extractDir(QString fileCompressed, QString subdir, QString dir)
{ {
QuaZip zip(fileCompressed); QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip)) if (!zip.open(QuaZip::mdUnzip)) {
{
// check if this is a minimum size empty zip file... // check if this is a minimum size empty zip file...
QFileInfo fileInfo(fileCompressed); QFileInfo fileInfo(fileCompressed);
if(fileInfo.size() == 22) { if (fileInfo.size() == 22) {
return QStringList(); return QStringList();
} }
qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();
;
return std::nullopt; return std::nullopt;
} }
return MMCZip::extractSubDir(&zip, subdir, dir); return extractSubDir(&zip, subdir, dir);
} }
// ours // ours
bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) bool extractFile(QString fileCompressed, QString file, QString target)
{ {
QuaZip zip(fileCompressed); QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip)) if (!zip.open(QuaZip::mdUnzip)) {
{
// check if this is a minimum size empty zip file... // check if this is a minimum size empty zip file...
QFileInfo fileInfo(fileCompressed); QFileInfo fileInfo(fileCompressed);
if(fileInfo.size() == 22) { if (fileInfo.size() == 22) {
return true; return true;
} }
qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();
return false; return false;
} }
return MMCZip::extractRelFile(&zip, file, target); return extractRelFile(&zip, file, target);
} }
bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList *files, bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter)
MMCZip::FilterFunction excludeFilter) { {
QDir rootDirectory(rootDir); QDir rootDirectory(rootDir);
if (!rootDirectory.exists()) return false; if (!rootDirectory.exists())
return false;
QDir directory; QDir directory;
if (subDir == nullptr) if (subDir == nullptr)
@ -421,25 +404,109 @@ bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& s
else else
directory = QDir(subDir); directory = QDir(subDir);
if (!directory.exists()) return false; // shouldn't ever happen if (!directory.exists())
return false; // shouldn't ever happen
// recurse directories // recurse directories
QFileInfoList entries = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); QFileInfoList entries = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
for (const auto& e: entries) { for (const auto& e : entries) {
if (!collectFileListRecursively(rootDir, e.filePath(), files, excludeFilter)) if (!collectFileListRecursively(rootDir, e.filePath(), files, excludeFilter))
return false; return false;
} }
// collect files // collect files
entries = directory.entryInfoList(QDir::Files); entries = directory.entryInfoList(QDir::Files);
for (const auto& e: entries) { for (const auto& e : entries) {
QString relativeFilePath = rootDirectory.relativeFilePath(e.absoluteFilePath()); QString relativeFilePath = rootDirectory.relativeFilePath(e.absoluteFilePath());
if (excludeFilter && excludeFilter(relativeFilePath)) { if (excludeFilter && excludeFilter(relativeFilePath)) {
qDebug() << "Skipping file " << relativeFilePath; qDebug() << "Skipping file " << relativeFilePath;
continue; continue;
} }
files->append(e); // we want the original paths for MMCZip::compressDirFiles files->append(e); // we want the original paths for compressDirFiles
} }
return true; return true;
} }
#if defined(LAUNCHER_APPLICATION)
void ExportToZipTask::executeTask()
{
setStatus("Adding files...");
setProgress(0, m_files.length());
m_build_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return exportZip(); });
connect(&m_build_zip_watcher, &QFutureWatcher<ZipResult>::finished, this, &ExportToZipTask::finish);
m_build_zip_watcher.setFuture(m_build_zip_future);
}
auto ExportToZipTask::exportZip() -> ZipResult
{
if (!m_dir.exists()) {
return ZipResult(tr("Folder doesn't exist"));
}
if (!m_output.isOpen() && !m_output.open(QuaZip::mdCreate)) {
return ZipResult(tr("Could not create file"));
}
for (auto fileName : m_extra_files.keys()) {
if (m_build_zip_future.isCanceled())
return ZipResult();
QuaZipFile indexFile(&m_output);
if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))) {
return ZipResult(tr("Could not create:") + fileName);
}
indexFile.write(m_extra_files[fileName]);
}
for (const QFileInfo& file : m_files) {
if (m_build_zip_future.isCanceled())
return ZipResult();
auto absolute = file.absoluteFilePath();
auto relative = m_dir.relativeFilePath(absolute);
setStatus("Compresing: " + relative);
setProgress(m_progress + 1, m_progressTotal);
if (m_follow_symlinks) {
if (file.isSymLink())
absolute = file.symLinkTarget();
else
absolute = file.canonicalFilePath();
}
if (!m_exclude_files.contains(relative) && !JlCompress::compressFile(&m_output, absolute, m_destination_prefix + relative)) {
return ZipResult(tr("Could not read and compress %1").arg(relative));
}
}
m_output.close();
if (m_output.getZipError() != 0) {
return ZipResult(tr("A zip error occurred"));
}
return ZipResult();
}
void ExportToZipTask::finish()
{
if (m_build_zip_future.isCanceled()) {
QFile::remove(m_output_path);
emitAborted();
} else if (auto result = m_build_zip_future.result(); result.has_value()) {
QFile::remove(m_output_path);
emitFailed(result.value());
} else {
emitSucceeded();
}
}
bool ExportToZipTask::abort()
{
if (m_build_zip_future.isRunning()) {
m_build_zip_future.cancel();
// NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not occur
// immediately.
return true;
}
return false;
}
#endif
} // namespace MMCZip

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
* *
* 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
@ -35,110 +36,163 @@
#pragma once #pragma once
#include <QString> #include <quazip.h>
#include <QFileInfo>
#include <QSet>
#include "minecraft/mod/Mod.h"
#include <functional>
#include <quazip/JlCompress.h> #include <quazip/JlCompress.h>
#include <QDir>
#include <QFileInfo>
#include <QFuture>
#include <QFutureWatcher>
#include <QHash>
#include <QSet>
#include <QString>
#include <functional>
#include <memory>
#include <optional> #include <optional>
namespace MMCZip #if defined(LAUNCHER_APPLICATION)
{ #include "minecraft/mod/Mod.h"
using FilterFunction = std::function<bool(const QString &)>; #endif
#include "tasks/Task.h"
/** namespace MMCZip {
* Merge two zip files, using a filter function using FilterFunction = std::function<bool(const QString&)>;
*/
bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
const FilterFunction filter = nullptr);
/** /**
* Compress directory, by providing a list of files to compress * Merge two zip files, using a filter function
* \param zip target archive */
* \param dir directory that will be compressed (to compress with relative paths) bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const FilterFunction filter = nullptr);
* \param files list of files to compress
* \param followSymlinks should follow symlinks when compressing file data
* \return true for success or false for failure
*/
bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks = false);
/** /**
* Compress directory, by providing a list of files to compress * Compress directory, by providing a list of files to compress
* \param fileCompressed target archive file * \param zip target archive
* \param dir directory that will be compressed (to compress with relative paths) * \param dir directory that will be compressed (to compress with relative paths)
* \param files list of files to compress * \param files list of files to compress
* \param followSymlinks should follow symlinks when compressing file data * \param followSymlinks should follow symlinks when compressing file data
* \return true for success or false for failure * \return true for success or false for failure
*/ */
bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks = false);
/** /**
* take a source jar, add mods to it, resulting in target jar * Compress directory, by providing a list of files to compress
*/ * \param fileCompressed target archive file
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods); * \param dir directory that will be compressed (to compress with relative paths)
* \param files list of files to compress
* \param followSymlinks should follow symlinks when compressing file data
* \return true for success or false for failure
*/
bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false);
/** #if defined(LAUNCHER_APPLICATION)
* Find a single file in archive by file name (not path) /**
* * take a source jar, add mods to it, resulting in target jar
* \param ignore_paths paths to skip when recursing the search */
* bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods);
* \return the path prefix where the file is #endif
*/ /**
QString findFolderOfFileInZip(QuaZip * zip, const QString & what, const QStringList& ignore_paths = {}, const QString &root = QString("")); * Find a single file in archive by file name (not path)
*
* \param ignore_paths paths to skip when recursing the search
*
* \return the path prefix where the file is
*/
QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths = {}, const QString& root = QString(""));
/** /**
* Find a multiple files of the same name in archive by file name * Find a multiple files of the same name in archive by file name
* If a file is found in a path, no deeper paths are searched * If a file is found in a path, no deeper paths are searched
* *
* \return true if anything was found * \return true if anything was found
*/ */
bool findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString()); bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root = QString());
/** /**
* Extract a subdirectory from an archive * Extract a subdirectory from an archive
*/ */
std::optional<QStringList> extractSubDir(QuaZip *zip, const QString & subdir, const QString &target); std::optional<QStringList> extractSubDir(QuaZip* zip, const QString& subdir, const QString& target);
bool extractRelFile(QuaZip *zip, const QString & file, const QString &target); bool extractRelFile(QuaZip* zip, const QString& file, const QString& target);
/** /**
* Extract a whole archive. * Extract a whole archive.
* *
* \param fileCompressed The name of the archive. * \param fileCompressed The name of the archive.
* \param dir The directory to extract to, the current directory if left empty. * \param dir The directory to extract to, the current directory if left empty.
* \return The list of the full paths of the files extracted, empty on failure. * \return The list of the full paths of the files extracted, empty on failure.
*/ */
std::optional<QStringList> extractDir(QString fileCompressed, QString dir); std::optional<QStringList> extractDir(QString fileCompressed, QString dir);
/** /**
* Extract a subdirectory from an archive * Extract a subdirectory from an archive
* *
* \param fileCompressed The name of the archive. * \param fileCompressed The name of the archive.
* \param subdir The directory within the archive to extract * \param subdir The directory within the archive to extract
* \param dir The directory to extract to, the current directory if left empty. * \param dir The directory to extract to, the current directory if left empty.
* \return The list of the full paths of the files extracted, empty on failure. * \return The list of the full paths of the files extracted, empty on failure.
*/ */
std::optional<QStringList> extractDir(QString fileCompressed, QString subdir, QString dir); std::optional<QStringList> extractDir(QString fileCompressed, QString subdir, QString dir);
/** /**
* Extract a single file from an archive into a directory * Extract a single file from an archive into a directory
* *
* \param fileCompressed The name of the archive. * \param fileCompressed The name of the archive.
* \param file The file within the archive to extract * \param file The file within the archive to extract
* \param dir The directory to extract to, the current directory if left empty. * \param dir The directory to extract to, the current directory if left empty.
* \return true for success or false for failure * \return true for success or false for failure
*/ */
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. * Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included.
* \param rootDir directory to start off * \param rootDir directory to start off
* \param subDir subdirectory, should be nullptr for first invocation * \param subDir subdirectory, should be nullptr for first invocation
* \param files resulting list of QFileInfo * \param files resulting list of QFileInfo
* \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude) * \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude)
* \return true for success or false for failure * \return true for success or false for failure
*/ */
bool collectFileListRecursively(const QString &rootDir, const QString &subDir, QFileInfoList *files, FilterFunction excludeFilter); bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter);
}
#if defined(LAUNCHER_APPLICATION)
class ExportToZipTask : public Task {
public:
ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false)
: m_output_path(outputPath)
, m_output(outputPath)
, m_dir(dir)
, m_files(files)
, m_destination_prefix(destinationPrefix)
, m_follow_symlinks(followSymlinks)
{
setAbortable(true);
};
ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false)
: ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks){};
virtual ~ExportToZipTask() = default;
void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; }
void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); }
using ZipResult = std::optional<QString>;
protected:
virtual void executeTask() override;
bool abort() override;
ZipResult exportZip();
void finish();
private:
QString m_output_path;
QuaZip m_output;
QDir m_dir;
QFileInfoList m_files;
QString m_destination_prefix;
bool m_follow_symlinks;
QStringList m_exclude_files;
QHash<QString, QByteArray> m_extra_files;
QFuture<ZipResult> m_build_zip_future;
QFutureWatcher<ZipResult> m_build_zip_watcher;
};
#endif
} // namespace MMCZip

View File

@ -1,10 +1,11 @@
#pragma once #pragma once
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug>
#include <QPixmapCache> #include <QPixmapCache>
#include <QThread> #include <QThread>
#include <QTime> #include <QTime>
#include <QDebug> #include <limits>
#define GET_TYPE() \ #define GET_TYPE() \
Qt::ConnectionType type; \ Qt::ConnectionType type; \
@ -100,10 +101,14 @@ class PixmapCache final : public QObject {
*/ */
bool _markCacheMissByEviciton() bool _markCacheMissByEviciton()
{ {
static constexpr uint maxInt = static_cast<uint>(std::numeric_limits<int>::max());
static constexpr uint step = 10240;
static constexpr int oneSecond = 1000;
auto now = QTime::currentTime(); auto now = QTime::currentTime();
if (!m_last_cache_miss_by_eviciton.isNull()) { if (!m_last_cache_miss_by_eviciton.isNull()) {
auto diff = m_last_cache_miss_by_eviciton.msecsTo(now); auto diff = m_last_cache_miss_by_eviciton.msecsTo(now);
if (diff < 1000) { // less than a second ago if (diff < oneSecond) { // less than a second ago
++m_consecutive_fast_evicitons; ++m_consecutive_fast_evicitons;
} else { } else {
m_consecutive_fast_evicitons = 0; m_consecutive_fast_evicitons = 0;
@ -111,11 +116,17 @@ class PixmapCache final : public QObject {
} }
m_last_cache_miss_by_eviciton = now; m_last_cache_miss_by_eviciton = now;
if (m_consecutive_fast_evicitons >= m_consecutive_fast_evicitons_threshold) { if (m_consecutive_fast_evicitons >= m_consecutive_fast_evicitons_threshold) {
// double the cache size // increase the cache size
auto newSize = _cacheLimit() * 2; uint newSize = _cacheLimit() + step;
qDebug() << m_consecutive_fast_evicitons << "pixmap cache misses by eviction happened too fast, doubling cache size to" if (newSize >= maxInt) { // increase it until you overflow :D
<< newSize; newSize = maxInt;
_setCacheLimit(newSize); qDebug() << m_consecutive_fast_evicitons
<< tr("pixmap cache misses by eviction happened too fast, doing nothing as the cache size reached it's limit");
} else {
qDebug() << m_consecutive_fast_evicitons
<< tr("pixmap cache misses by eviction happened too fast, increasing cache size to") << static_cast<int>(newSize);
}
_setCacheLimit(static_cast<int>(newSize));
m_consecutive_fast_evicitons = 0; m_consecutive_fast_evicitons = 0;
return true; return true;
} }

View File

@ -16,15 +16,25 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <QStringList> #include <QDebug>
#include <QDir> #include <QDir>
#include <QString> #include <QString>
#include <QStringList>
#include <QSysInfo> #include <QSysInfo>
#include <QtGlobal> #include <QtGlobal>
#include "MangoHud.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "Json.h" #include "Json.h"
#include "MangoHud.h"
#ifdef __GLIBC__
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#define UNDEF_GNU_SOURCE
#endif
#include <dlfcn.h>
#include <linux/limits.h>
#endif
namespace MangoHud { namespace MangoHud {
@ -106,4 +116,37 @@ QString getLibraryString()
return QString(); return QString();
} }
QString findLibrary(QString libName)
{
#ifdef __GLIBC__
const char* library = libName.toLocal8Bit().constData();
void* handle = dlopen(library, RTLD_NOW);
if (!handle) {
qCritical() << "dlopen() failed:" << dlerror();
return {};
}
char path[PATH_MAX];
if (dlinfo(handle, RTLD_DI_ORIGIN, path) == -1) {
qCritical() << "dlinfo() failed:" << dlerror();
dlclose(handle);
return {};
}
auto fullPath = FS::PathCombine(QString(path), libName);
dlclose(handle);
return fullPath;
#else
qWarning() << "MangoHud::findLibrary is not implemented on this platform";
return {};
#endif
}
} // namespace MangoHud } // namespace MangoHud
#ifdef UNDEF_GNU_SOURCE
#undef _GNU_SOURCE
#undef UNDEF_GNU_SOURCE
#endif

View File

@ -24,4 +24,6 @@
namespace MangoHud { namespace MangoHud {
QString getLibraryString(); QString getLibraryString();
}
QString findLibrary(QString libName);
} // namespace MangoHud

View File

@ -18,7 +18,7 @@
#pragma once #pragma once
#include <QString>
#include <cmark.h> #include <cmark.h>
#include <QString>
QString markdownToHTML(const QString& markdown); QString markdownToHTML(const QString& markdown);

View File

@ -22,12 +22,11 @@ MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
return MessageLevel::Unknown; return MessageLevel::Unknown;
} }
MessageLevel::Enum MessageLevel::fromLine(QString &line) MessageLevel::Enum MessageLevel::fromLine(QString& line)
{ {
// Level prefix // Level prefix
int endmark = line.indexOf("]!"); int endmark = line.indexOf("]!");
if (line.startsWith("!![") && endmark != -1) if (line.startsWith("!![") && endmark != -1) {
{
auto level = MessageLevel::getLevel(line.left(endmark).mid(3)); auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
line = line.mid(endmark + 2); line = line.mid(endmark + 2);
return level; return level;

View File

@ -6,23 +6,21 @@
* @brief the MessageLevel Enum * @brief the MessageLevel Enum
* defines what level a log message is * defines what level a log message is
*/ */
namespace MessageLevel namespace MessageLevel {
{ enum Enum {
enum Enum Unknown, /**< No idea what this is or where it came from */
{ StdOut, /**< Undetermined stderr messages */
Unknown, /**< No idea what this is or where it came from */ StdErr, /**< Undetermined stdout messages */
StdOut, /**< Undetermined stderr messages */
StdErr, /**< Undetermined stdout messages */
Launcher, /**< Launcher Messages */ Launcher, /**< Launcher Messages */
Debug, /**< Debug Messages */ Debug, /**< Debug Messages */
Info, /**< Info Messages */ Info, /**< Info Messages */
Message, /**< Standard Messages */ Message, /**< Standard Messages */
Warning, /**< Warnings */ Warning, /**< Warnings */
Error, /**< Errors */ Error, /**< Errors */
Fatal, /**< Fatal Errors */ Fatal, /**< Fatal Errors */
}; };
MessageLevel::Enum getLevel(const QString &levelName); MessageLevel::Enum getLevel(const QString& levelName);
/* Get message level from a line. Line is modified if it was successful. */ /* Get message level from a line. Line is modified if it was successful. */
MessageLevel::Enum fromLine(QString &line); MessageLevel::Enum fromLine(QString& line);
} } // namespace MessageLevel

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* *
* 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
@ -37,88 +38,39 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
class NullInstance: public BaseInstance class NullInstance : public BaseInstance {
{
Q_OBJECT Q_OBJECT
public: public:
NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir)
:BaseInstance(globalSettings, settings, rootDir) : BaseInstance(globalSettings, settings, rootDir)
{ {
setVersionBroken(true); setVersionBroken(true);
} }
virtual ~NullInstance() {}; virtual ~NullInstance(){};
void saveNow() override void saveNow() override {}
{ void loadSpecificSettings() override { setSpecificSettingsLoaded(true); }
} QString getStatusbarDescription() override { return tr("Unknown instance type"); };
void loadSpecificSettings() override QSet<QString> traits() const override { return {}; };
{ QString instanceConfigFolder() const override { return instanceRoot(); };
setSpecificSettingsLoaded(true); shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override { return nullptr; }
} shared_qobject_ptr<Task> createUpdateTask([[maybe_unused]] Net::Mode mode) override { return nullptr; }
QString getStatusbarDescription() override QProcessEnvironment createEnvironment() override { return QProcessEnvironment(); }
{ QProcessEnvironment createLaunchEnvironment() override { return QProcessEnvironment(); }
return tr("Unknown instance type"); QMap<QString, QString> getVariables() override { return QMap<QString, QString>(); }
}; IPathMatcher::Ptr getLogFileMatcher() override { return nullptr; }
QSet< QString > traits() const override QString getLogFileRoot() override { return instanceRoot(); }
{ QString typeName() const override { return "Null"; }
return {}; bool canExport() const override { return false; }
}; bool canEdit() const override { return false; }
QString instanceConfigFolder() const override bool canLaunch() const override { return false; }
{ void populateLaunchMenu(QMenu* menu) override {}
return instanceRoot();
};
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override
{
return nullptr;
}
shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override
{
return nullptr;
}
QProcessEnvironment createEnvironment() override
{
return QProcessEnvironment();
}
QProcessEnvironment createLaunchEnvironment() override
{
return QProcessEnvironment();
}
QMap<QString, QString> getVariables() override
{
return QMap<QString, QString>();
}
IPathMatcher::Ptr getLogFileMatcher() override
{
return nullptr;
}
QString getLogFileRoot() override
{
return instanceRoot();
}
QString typeName() const override
{
return "Null";
}
bool canExport() const override
{
return false;
}
bool canEdit() const override
{
return false;
}
bool canLaunch() const override
{
return false;
}
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override
{ {
QStringList out; QStringList out;
out << "Null instance - placeholder."; out << "Null instance - placeholder.";
return out; return out;
} }
QString modsRoot() const override { QString modsRoot() const override { return QString(); }
return QString();
}
void updateRuntimeContext() void updateRuntimeContext()
{ {
// NOOP // NOOP

View File

@ -1,47 +1,35 @@
#pragma once #pragma once
enum class ProblemSeverity #include <QList>
{ #include <QString>
None,
Warning,
Error
};
struct PatchProblem enum class ProblemSeverity { None, Warning, Error };
{
struct PatchProblem {
ProblemSeverity m_severity; ProblemSeverity m_severity;
QString m_description; QString m_description;
}; };
class ProblemProvider class ProblemProvider {
{ public:
public: virtual ~ProblemProvider() {}
virtual ~ProblemProvider() {};
virtual const QList<PatchProblem> getProblems() const = 0; virtual const QList<PatchProblem> getProblems() const = 0;
virtual ProblemSeverity getProblemSeverity() const = 0; virtual ProblemSeverity getProblemSeverity() const = 0;
}; };
class ProblemContainer : public ProblemProvider class ProblemContainer : public ProblemProvider {
{ public:
public: const QList<PatchProblem> getProblems() const override { return m_problems; }
const QList<PatchProblem> getProblems() const override ProblemSeverity getProblemSeverity() const override { return m_problemSeverity; }
virtual void addProblem(ProblemSeverity severity, const QString& description)
{ {
return m_problems; if (severity > m_problemSeverity) {
}
ProblemSeverity getProblemSeverity() const override
{
return m_problemSeverity;
}
virtual void addProblem(ProblemSeverity severity, const QString &description)
{
if(severity > m_problemSeverity)
{
m_problemSeverity = severity; m_problemSeverity = severity;
} }
m_problems.append({severity, description}); m_problems.append({ severity, description });
} }
private: private:
QList<PatchProblem> m_problems; QList<PatchProblem> m_problems;
ProblemSeverity m_problemSeverity = ProblemSeverity::None; ProblemSeverity m_problemSeverity = ProblemSeverity::None;
}; };

View File

@ -36,35 +36,34 @@
#pragma once #pragma once
#include <QVariant>
#include <QList> #include <QList>
#include <QVariant>
namespace QVariantUtils { namespace QVariantUtils {
template <typename T> template <typename T>
inline QList<T> toList(QVariant src) { inline QList<T> toList(QVariant src)
{
QVariantList variantList = src.toList(); QVariantList variantList = src.toList();
QList<T> list_t; QList<T> list_t;
list_t.reserve(variantList.size()); list_t.reserve(variantList.size());
for (const QVariant& v : variantList) for (const QVariant& v : variantList) {
{
list_t.append(v.value<T>()); list_t.append(v.value<T>());
} }
return list_t; return list_t;
} }
template <typename T> template <typename T>
inline QVariant fromList(QList<T> val) { inline QVariant fromList(QList<T> val)
{
QVariantList variantList; QVariantList variantList;
variantList.reserve(val.size()); variantList.reserve(val.size());
for (const T& v : val) for (const T& v : val) {
{
variantList.append(v); variantList.append(v);
} }
return variantList; return variantList;
} }
} } // namespace QVariantUtils

View File

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <QWriteLocker>
#include <QReadLocker>
#include <QMap> #include <QMap>
#include <QReadLocker>
#include <QSet> #include <QSet>
#include <QWriteLocker>
template <typename K, typename V> template <typename K, typename V>
class RWStorage class RWStorage {
{ public:
public:
void add(K key, V value) void add(K key, V value)
{ {
QWriteLocker l(&lock); QWriteLocker l(&lock);
@ -17,21 +16,19 @@ public:
V get(K key) V get(K key)
{ {
QReadLocker l(&lock); QReadLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
return cache[key]; return cache[key];
} } else
else return V(); return V();
} }
bool get(K key, V& value) bool get(K key, V& value)
{ {
QReadLocker l(&lock); QReadLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
value = cache[key]; value = cache[key];
return true; return true;
} } else
else return false; return false;
} }
bool has(K key) bool has(K key)
{ {
@ -41,15 +38,14 @@ public:
bool stale(K key) bool stale(K key)
{ {
QReadLocker l(&lock); QReadLocker l(&lock);
if(!cache.contains(key)) if (!cache.contains(key))
return true; return true;
return stale_entries.contains(key); return stale_entries.contains(key);
} }
void setStale(K key) void setStale(K key)
{ {
QWriteLocker l(&lock); QWriteLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
stale_entries.insert(key); stale_entries.insert(key);
} }
} }
@ -59,7 +55,8 @@ public:
cache.clear(); cache.clear();
stale_entries.clear(); stale_entries.clear();
} }
private:
private:
QReadWriteLock lock; QReadWriteLock lock;
QMap<K, V> cache; QMap<K, V> cache;
QSet<K> stale_entries; QSet<K> stale_entries;

View File

@ -1,25 +1,21 @@
#include "RecursiveFileSystemWatcher.h" #include "RecursiveFileSystemWatcher.h"
#include <QRegularExpression>
#include <QDebug> #include <QDebug>
#include <QRegularExpression>
RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent) RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject* parent) : QObject(parent), m_watcher(new QFileSystemWatcher(this))
: QObject(parent), m_watcher(new QFileSystemWatcher(this))
{ {
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RecursiveFileSystemWatcher::fileChange);
&RecursiveFileSystemWatcher::fileChange); connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveFileSystemWatcher::directoryChange);
connect(m_watcher, &QFileSystemWatcher::directoryChanged, this,
&RecursiveFileSystemWatcher::directoryChange);
} }
void RecursiveFileSystemWatcher::setRootDir(const QDir &root) void RecursiveFileSystemWatcher::setRootDir(const QDir& root)
{ {
bool wasEnabled = m_isEnabled; bool wasEnabled = m_isEnabled;
disable(); disable();
m_root = root; m_root = root;
setFiles(scanRecursive(m_root)); setFiles(scanRecursive(m_root));
if (wasEnabled) if (wasEnabled) {
{
enable(); enable();
} }
} }
@ -28,16 +24,14 @@ void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles)
bool wasEnabled = m_isEnabled; bool wasEnabled = m_isEnabled;
disable(); disable();
m_watchFiles = watchFiles; m_watchFiles = watchFiles;
if (wasEnabled) if (wasEnabled) {
{
enable(); enable();
} }
} }
void RecursiveFileSystemWatcher::enable() void RecursiveFileSystemWatcher::enable()
{ {
if (m_isEnabled) if (m_isEnabled) {
{
return; return;
} }
Q_ASSERT(m_root != QDir::root()); Q_ASSERT(m_root != QDir::root());
@ -46,8 +40,7 @@ void RecursiveFileSystemWatcher::enable()
} }
void RecursiveFileSystemWatcher::disable() void RecursiveFileSystemWatcher::disable()
{ {
if (!m_isEnabled) if (!m_isEnabled) {
{
return; return;
} }
m_isEnabled = false; m_isEnabled = false;
@ -55,57 +48,49 @@ void RecursiveFileSystemWatcher::disable()
m_watcher->removePaths(m_watcher->directories()); m_watcher->removePaths(m_watcher->directories());
} }
void RecursiveFileSystemWatcher::setFiles(const QStringList &files) void RecursiveFileSystemWatcher::setFiles(const QStringList& files)
{ {
if (files != m_files) if (files != m_files) {
{
m_files = files; m_files = files;
emit filesChanged(); emit filesChanged();
} }
} }
void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir) void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir& dir)
{ {
m_watcher->addPath(dir.absolutePath()); m_watcher->addPath(dir.absolutePath());
for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) for (const QString& directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
{
addFilesToWatcherRecursive(dir.absoluteFilePath(directory)); addFilesToWatcherRecursive(dir.absoluteFilePath(directory));
} }
if (m_watchFiles) if (m_watchFiles) {
{ for (const QFileInfo& info : dir.entryInfoList(QDir::Files)) {
for (const QFileInfo &info : dir.entryInfoList(QDir::Files))
{
m_watcher->addPath(info.absoluteFilePath()); m_watcher->addPath(info.absoluteFilePath());
} }
} }
} }
QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &directory) QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory)
{ {
QStringList ret; QStringList ret;
if(!m_matcher) if (!m_matcher) {
{
return {}; return {};
} }
for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) for (const QString& dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) {
{
ret.append(scanRecursive(directory.absoluteFilePath(dir))); ret.append(scanRecursive(directory.absoluteFilePath(dir)));
} }
for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden)) for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) {
{
auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file)); auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
if (m_matcher->matches(relPath)) if (m_matcher->matches(relPath)) {
{
ret.append(relPath); ret.append(relPath);
} }
} }
return ret; return ret;
} }
void RecursiveFileSystemWatcher::fileChange(const QString &path) void RecursiveFileSystemWatcher::fileChange(const QString& path)
{ {
emit fileChanged(path); emit fileChanged(path);
} }
void RecursiveFileSystemWatcher::directoryChange(const QString &path) void RecursiveFileSystemWatcher::directoryChange([[maybe_unused]] const QString& path)
{ {
setFiles(scanRecursive(m_root)); setFiles(scanRecursive(m_root));
} }

View File

@ -1,61 +1,48 @@
#pragma once #pragma once
#include <QFileSystemWatcher>
#include <QDir> #include <QDir>
#include <QFileSystemWatcher>
#include "pathmatcher/IPathMatcher.h" #include "pathmatcher/IPathMatcher.h"
class RecursiveFileSystemWatcher : public QObject class RecursiveFileSystemWatcher : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
RecursiveFileSystemWatcher(QObject *parent); RecursiveFileSystemWatcher(QObject* parent);
void setRootDir(const QDir &root); void setRootDir(const QDir& root);
QDir rootDir() const QDir rootDir() const { return m_root; }
{
return m_root;
}
// WARNING: setting this to true may be bad for performance // WARNING: setting this to true may be bad for performance
void setWatchFiles(const bool watchFiles); void setWatchFiles(const bool watchFiles);
bool watchFiles() const bool watchFiles() const { return m_watchFiles; }
{
return m_watchFiles;
}
void setMatcher(IPathMatcher::Ptr matcher) void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; }
{
m_matcher = matcher;
}
QStringList files() const QStringList files() const { return m_files; }
{
return m_files;
}
signals: signals:
void filesChanged(); void filesChanged();
void fileChanged(const QString &path); void fileChanged(const QString& path);
public slots: public slots:
void enable(); void enable();
void disable(); void disable();
private: private:
QDir m_root; QDir m_root;
bool m_watchFiles = false; bool m_watchFiles = false;
bool m_isEnabled = false; bool m_isEnabled = false;
IPathMatcher::Ptr m_matcher; IPathMatcher::Ptr m_matcher;
QFileSystemWatcher *m_watcher; QFileSystemWatcher* m_watcher;
QStringList m_files; QStringList m_files;
void setFiles(const QStringList &files); void setFiles(const QStringList& files);
void addFilesToWatcherRecursive(const QDir &dir); void addFilesToWatcherRecursive(const QDir& dir);
QStringList scanRecursive(const QDir &dir); QStringList scanRecursive(const QDir& dir);
private slots: private slots:
void fileChange(const QString &path); void fileChange(const QString& path);
void directoryChange(const QString &path); void directoryChange(const QString& path);
}; };

View File

@ -24,6 +24,8 @@
#include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ModFolderModel.h"
#include "minecraft/mod/ResourceFolderModel.h" #include "minecraft/mod/ResourceFolderModel.h"
#include "net/ApiDownload.h"
ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack,
ModPlatform::IndexedVersion version, ModPlatform::IndexedVersion version,
const std::shared_ptr<ResourceFolderModel> packs, const std::shared_ptr<ResourceFolderModel> packs,
@ -51,10 +53,10 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack,
} }
} }
m_filesNetJob->addNetAction(Net::Download::makeFile(m_pack_version.downloadUrl, dir.absoluteFilePath(getFilename()))); m_filesNetJob->addNetAction(Net::ApiDownload::makeFile(m_pack_version.downloadUrl, dir.absoluteFilePath(getFilename())));
connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ResourceDownloadTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ResourceDownloadTask::downloadSucceeded);
connect(m_filesNetJob.get(), &NetJob::progress, this, &ResourceDownloadTask::downloadProgressChanged); connect(m_filesNetJob.get(), &NetJob::progress, this, &ResourceDownloadTask::downloadProgressChanged);
connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &ResourceDownloadTask::propogateStepProgress); connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &ResourceDownloadTask::propagateStepProgress);
connect(m_filesNetJob.get(), &NetJob::failed, this, &ResourceDownloadTask::downloadFailed); connect(m_filesNetJob.get(), &NetJob::failed, this, &ResourceDownloadTask::downloadFailed);
addTask(m_filesNetJob); addTask(m_filesNetJob);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify

View File

@ -1,44 +1,32 @@
#pragma once #pragma once
#include <QString>
#include <QMap> #include <QMap>
#include <QString>
#include <QStringList> #include <QStringList>
template <char Tseparator> template <char Tseparator>
class SeparatorPrefixTree class SeparatorPrefixTree {
{ public:
public: SeparatorPrefixTree(QStringList paths) { insert(paths); }
SeparatorPrefixTree(QStringList paths)
{
insert(paths);
}
SeparatorPrefixTree(bool contained = false) SeparatorPrefixTree(bool contained = false) { m_contained = contained; }
{
m_contained = contained;
}
void insert(QStringList paths) void insert(QStringList paths)
{ {
for(auto &path: paths) for (auto& path : paths) {
{
insert(path); insert(path);
} }
} }
/// insert an exact path into the tree /// insert an exact path into the tree
SeparatorPrefixTree & insert(QString path) SeparatorPrefixTree& insert(QString path)
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
children[path] = SeparatorPrefixTree(true); children[path] = SeparatorPrefixTree(true);
return children[path]; return children[path];
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
if(!children.contains(prefix)) if (!children.contains(prefix)) {
{
children[prefix] = SeparatorPrefixTree(false); children[prefix] = SeparatorPrefixTree(false);
} }
return children[prefix].insert(path.mid(sepIndex + 1)); return children[prefix].insert(path.mid(sepIndex + 1));
@ -56,26 +44,20 @@ public:
bool covers(QString path) const bool covers(QString path) const
{ {
// if we found some valid node, it's good enough. the tree covers the path // if we found some valid node, it's good enough. the tree covers the path
if(m_contained) if (m_contained) {
{
return true; return true;
} }
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).covers(QString()); return (*found).covers(QString());
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).covers(path.mid(sepIndex + 1)); return (*found).covers(path.mid(sepIndex + 1));
@ -86,41 +68,33 @@ public:
QString cover(QString path) const QString cover(QString path) const
{ {
// if we found some valid node, it's good enough. the tree covers the path // if we found some valid node, it's good enough. the tree covers the path
if(m_contained) if (m_contained) {
{
return QString(""); return QString("");
} }
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return QString(); return QString();
} }
auto nested = (*found).cover(QString()); auto nested = (*found).cover(QString());
if(nested.isNull()) if (nested.isNull()) {
{
return nested; return nested;
} }
if(nested.isEmpty()) if (nested.isEmpty())
return path; return path;
return path + Tseparator + nested; return path + Tseparator + nested;
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return QString(); return QString();
} }
auto nested = (*found).cover(path.mid(sepIndex + 1)); auto nested = (*found).cover(path.mid(sepIndex + 1));
if(nested.isNull()) if (nested.isNull()) {
{
return nested; return nested;
} }
if(nested.isEmpty()) if (nested.isEmpty())
return prefix; return prefix;
return prefix + Tseparator + nested; return prefix + Tseparator + nested;
} }
@ -130,21 +104,16 @@ public:
bool exists(QString path) const bool exists(QString path) const
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return true; return true;
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).exists(path.mid(sepIndex + 1)); return (*found).exists(path.mid(sepIndex + 1));
@ -152,24 +121,19 @@ public:
} }
/// find a node in the tree by name /// find a node in the tree by name
const SeparatorPrefixTree * find(QString path) const const SeparatorPrefixTree* find(QString path) const
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return nullptr; return nullptr;
} }
return &(*found); return &(*found);
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return nullptr; return nullptr;
} }
return (*found).find(path.mid(sepIndex + 1)); return (*found).find(path.mid(sepIndex + 1));
@ -177,70 +141,48 @@ public:
} }
/// is this a leaf node? /// is this a leaf node?
bool leaf() const bool leaf() const { return children.isEmpty(); }
{
return children.isEmpty();
}
/// is this node actually contained in the tree, or is it purely structural? /// is this node actually contained in the tree, or is it purely structural?
bool contained() const bool contained() const { return m_contained; }
{
return m_contained;
}
/// Remove a path from the tree /// Remove a path from the tree
bool remove(QString path) bool remove(QString path) { return removeInternal(path) != Failed; }
{
return removeInternal(path) != Failed;
}
/// Clear all children of this node tree node /// Clear all children of this node tree node
void clear() void clear() { children.clear(); }
{
children.clear();
}
QStringList toStringList() const QStringList toStringList() const
{ {
QStringList collected; QStringList collected;
// collecting these is more expensive. // collecting these is more expensive.
auto iter = children.begin(); auto iter = children.begin();
while(iter != children.end()) while (iter != children.end()) {
{
QStringList list = iter.value().toStringList(); QStringList list = iter.value().toStringList();
for(int i = 0; i < list.size(); i++) for (int i = 0; i < list.size(); i++) {
{
list[i] = iter.key() + Tseparator + list[i]; list[i] = iter.key() + Tseparator + list[i];
} }
collected.append(list); collected.append(list);
if((*iter).m_contained) if ((*iter).m_contained) {
{
collected.append(iter.key()); collected.append(iter.key());
} }
iter++; iter++;
} }
return collected; return collected;
} }
private:
enum Removal private:
{ enum Removal { Failed, Succeeded, HasChildren };
Failed,
Succeeded,
HasChildren
};
Removal removeInternal(QString path = QString()) Removal removeInternal(QString path = QString())
{ {
if(path.isEmpty()) if (path.isEmpty()) {
{ if (!m_contained) {
if(!m_contained)
{
// remove all children - we are removing a prefix // remove all children - we are removing a prefix
clear(); clear();
return Succeeded; return Succeeded;
} }
m_contained = false; m_contained = false;
if(children.size()) if (children.size()) {
{
return HasChildren; return HasChildren;
} }
return Succeeded; return Succeeded;
@ -248,42 +190,32 @@ private:
Removal remStatus = Failed; Removal remStatus = Failed;
QString childToRemove; QString childToRemove;
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
childToRemove = path; childToRemove = path;
auto found = children.find(childToRemove); auto found = children.find(childToRemove);
if(found == children.end()) if (found == children.end()) {
{
return Failed; return Failed;
} }
remStatus = (*found).removeInternal(); remStatus = (*found).removeInternal();
} } else {
else
{
childToRemove = path.left(sepIndex); childToRemove = path.left(sepIndex);
auto found = children.find(childToRemove); auto found = children.find(childToRemove);
if(found == children.end()) if (found == children.end()) {
{
return Failed; return Failed;
} }
remStatus = (*found).removeInternal(path.mid(sepIndex + 1)); remStatus = (*found).removeInternal(path.mid(sepIndex + 1));
} }
switch (remStatus) switch (remStatus) {
{
case Failed: case Failed:
case HasChildren: case HasChildren: {
{
return remStatus; return remStatus;
} }
case Succeeded: case Succeeded: {
{
children.remove(childToRemove); children.remove(childToRemove);
if(m_contained) if (m_contained) {
{
return HasChildren; return HasChildren;
} }
if(children.size()) if (children.size()) {
{
return HasChildren; return HasChildren;
} }
return Succeeded; return Succeeded;
@ -292,7 +224,7 @@ private:
return Failed; return Failed;
} }
private: private:
QMap<QString,SeparatorPrefixTree<Tseparator>> children; QMap<QString, SeparatorPrefixTree<Tseparator>> children;
bool m_contained = false; bool m_contained = false;
}; };

View File

@ -14,17 +14,16 @@
*/ */
#include "SkinUtils.h" #include "SkinUtils.h"
#include "net/HttpMetaCache.h"
#include "Application.h" #include "Application.h"
#include "net/HttpMetaCache.h"
#include <QFile> #include <QFile>
#include <QPainter> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QPainter>
namespace SkinUtils namespace SkinUtils {
{
/* /*
* Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise * Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise
*/ */
@ -32,12 +31,15 @@ QPixmap getFaceFromCache(QString username, int height, int width)
{ {
QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath()); QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath());
if (fskin.exists()) if (fskin.exists()) {
{
QPixmap skinTexture(fskin.fileName()); QPixmap skinTexture(fskin.fileName());
if(!skinTexture.isNull()) if (!skinTexture.isNull()) {
{
QPixmap skin = QPixmap(8, 8); QPixmap skin = QPixmap(8, 8);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
skin.fill(QColorConstants::Transparent);
#else
skin.fill(QColor(0, 0, 0, 0));
#endif
QPainter painter(&skin); QPainter painter(&skin);
painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8)); painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8));
painter.drawPixmap(0, 0, skinTexture.copy(40, 8, 8, 8)); painter.drawPixmap(0, 0, skinTexture.copy(40, 8, 8, 8));
@ -47,4 +49,4 @@ QPixmap getFaceFromCache(QString username, int height, int width)
return QPixmap(); return QPixmap();
} }
} } // namespace SkinUtils

View File

@ -17,7 +17,6 @@
#include <QPixmap> #include <QPixmap>
namespace SkinUtils namespace SkinUtils {
{
QPixmap getFaceFromCache(QString id, int height = 64, int width = 64); QPixmap getFaceFromCache(QString id, int height = 64, int width = 64);
} }

View File

@ -35,6 +35,7 @@
*/ */
#include "StringUtils.h" #include "StringUtils.h"
#include <qpair.h>
#include <QRegularExpression> #include <QRegularExpression>
#include <QUuid> #include <QUuid>
@ -149,7 +150,7 @@ QString StringUtils::truncateUrlHumanFriendly(QUrl& url, int max_len, bool hard_
} }
if ((url_compact.length() >= max_len) && hard_limit) { if ((url_compact.length() >= max_len) && hard_limit) {
// still too long, truncate normaly // still too long, truncate normally
url_compact = QString(str_url); url_compact = QString(str_url);
auto to_remove = url_compact.length() - max_len + 3; auto to_remove = url_compact.length() - max_len + 3;
url_compact.remove(url_compact.length() - to_remove - 1, to_remove); url_compact.remove(url_compact.length() - to_remove - 1, to_remove);
@ -182,3 +183,32 @@ QString StringUtils::getRandomAlphaNumeric()
{ {
return QUuid::createUuid().toString(QUuid::Id128); return QUuid::createUuid().toString(QUuid::Id128);
} }
QPair<QString, QString> StringUtils::splitFirst(const QString& s, const QString& sep, Qt::CaseSensitivity cs)
{
QString left, right;
auto index = s.indexOf(sep, 0, cs);
left = s.mid(0, index);
right = s.mid(index + sep.length());
return qMakePair(left, right);
}
QPair<QString, QString> StringUtils::splitFirst(const QString& s, QChar sep, Qt::CaseSensitivity cs)
{
QString left, right;
auto index = s.indexOf(sep, 0, cs);
left = s.mid(0, index);
right = s.mid(left.length() + 1);
return qMakePair(left, right);
}
QPair<QString, QString> StringUtils::splitFirst(const QString& s, const QRegularExpression& re)
{
QString left, right;
QRegularExpressionMatch match;
auto index = s.indexOf(re, 0, &match);
left = s.mid(0, index);
auto end = match.hasMatch() ? left.length() + match.capturedLength() : left.length() + 1;
right = s.mid(end);
return qMakePair(left, right);
}

View File

@ -36,8 +36,10 @@
#pragma once #pragma once
#include <QPair>
#include <QString> #include <QString>
#include <QUrl> #include <QUrl>
#include <utility>
namespace StringUtils { namespace StringUtils {
@ -70,13 +72,17 @@ int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs)
/** /**
* @brief Truncate a url while keeping its readability py placing the `...` in the middle of the path * @brief Truncate a url while keeping its readability py placing the `...` in the middle of the path
* @param url Url to truncate * @param url Url to truncate
* @param max_len max lenght of url in charaters * @param max_len max length of url in characters
* @param hard_limit if truncating the path can't get the url short enough, truncate it normaly. * @param hard_limit if truncating the path can't get the url short enough, truncate it normally.
*/ */
QString truncateUrlHumanFriendly(QUrl &url, int max_len, bool hard_limit = false); QString truncateUrlHumanFriendly(QUrl& url, int max_len, bool hard_limit = false);
QString humanReadableFileSize(double bytes, bool use_si = false, int decimal_points = 1); QString humanReadableFileSize(double bytes, bool use_si = false, int decimal_points = 1);
QString getRandomAlphaNumeric(); QString getRandomAlphaNumeric();
QPair<QString, QString> splitFirst(const QString& s, const QString& sep, Qt::CaseSensitivity cs = Qt::CaseSensitive);
QPair<QString, QString> splitFirst(const QString& s, QChar sep, Qt::CaseSensitivity cs = Qt::CaseSensitive);
QPair<QString, QString> splitFirst(const QString& s, const QRegularExpression& re);
} // namespace StringUtils } // namespace StringUtils

View File

@ -12,28 +12,20 @@ class Usable;
* *
* @see UseLock * @see UseLock
*/ */
class Usable class Usable {
{
friend class UseLock; friend class UseLock;
public:
std::size_t useCount() const public:
{ virtual ~Usable() {}
return m_useCount;
} std::size_t useCount() const { return m_useCount; }
bool isInUse() const bool isInUse() const { return m_useCount > 0; }
{
return m_useCount > 0; protected:
} virtual void decrementUses() { m_useCount--; }
protected: virtual void incrementUses() { m_useCount++; }
virtual void decrementUses()
{ private:
m_useCount--;
}
virtual void incrementUses()
{
m_useCount++;
}
private:
std::size_t m_useCount = 0; std::size_t m_useCount = 0;
}; };
@ -42,19 +34,15 @@ private:
* *
* @see Usable * @see Usable
*/ */
class UseLock class UseLock {
{ public:
public: UseLock(shared_qobject_ptr<Usable> usable) : m_usable(usable)
UseLock(shared_qobject_ptr<Usable> usable)
: m_usable(usable)
{ {
// this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate. // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate.
m_usable->incrementUses(); m_usable->incrementUses();
} }
~UseLock() ~UseLock() { m_usable->decrementUses(); }
{
m_usable->decrementUses(); private:
}
private:
shared_qobject_ptr<Usable> m_usable; shared_qobject_ptr<Usable> m_usable;
}; };

View File

@ -117,12 +117,14 @@ QDebug operator<<(QDebug debug, const Version& v)
bool first = true; bool first = true;
for (auto s : v.m_sections) { for (auto s : v.m_sections) {
if (!first) debug.nospace() << ", "; if (!first)
debug.nospace() << ", ";
debug.nospace() << s.m_fullString; debug.nospace() << s.m_fullString;
first = false; first = false;
} }
debug.nospace() << " ]" << " }"; debug.nospace() << " ]"
<< " }";
return debug; return debug;
} }

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