Compare commits

...

68 Commits

Author SHA1 Message Date
60234a550b feat: auto install modpack & choise nickname
Some checks failed
CodeQL Code Scanning / CodeQL (push) Has been cancelled
Build Application / Build Debug (push) Has been cancelled
Nix / Build (${{ matrix.system }}) (macos-13, x86_64-darwin) (push) Has been cancelled
Nix / Build (${{ matrix.system }}) (macos-14, aarch64-darwin) (push) Has been cancelled
Nix / Build (${{ matrix.system }}) (ubuntu-22.04, x86_64-linux) (push) Has been cancelled
Nix / Build (${{ matrix.system }}) (ubuntu-22.04-arm, aarch64-linux) (push) Has been cancelled
Update Flake Lockfile / update-flake (push) Has been cancelled
2025-04-15 11:13:45 +03:00
Luna
67bca78946 Delete publish.yml 2025-04-06 18:32:27 -05:00
Luna
2706ec5db6 chore: correct issues left by merge 2025-04-06 18:28:26 -05:00
Evan Goode
48689d1b79 Merge remote-tracking branch 'upstream/release-9.x' into develop 2025-04-06 18:16:05 -05:00
Luna
8940008b41 fix: readme formatting causes nix breakage 2025-04-06 18:03:03 -05:00
Evan Goode
7050d01aab Support authlib-injector skin upload 2025-04-06 17:46:06 -05:00
Evan Goode
b9ba1f1c65 clang-format 2025-04-06 17:46:05 -05:00
Evan Goode
d873774547 Create authlib-injector account with punycoded URL
Related: https://github.com/yushijinhun/authlib-injector/issues/270
2025-04-06 17:46:05 -05:00
Evan Goode
7c6204b5f1 Add back AuthlibInjectorMetadataStep
Apparently this was forgotten during the 9.0 merging.
2025-04-06 17:46:05 -05:00
Evan Goode
dd3a788f7b legacy: handle URL-encoded session ID 2025-04-06 17:46:05 -05:00
Evan Goode
c479712f32 legacy: rewrite http://session.minecraft.net/game/joinserver.jsp 2025-04-06 17:46:05 -05:00
Evan Goode
b43764d355 Show CurseForge in new instance dialog even if no API key 2025-04-06 17:46:05 -05:00
Luna
0565bd7c68
Update README.md 2025-03-04 23:12:53 -06:00
Luna
3e46252058
Adjust README in line of making the project's history more clear eventually 2025-03-04 22:44:12 -06:00
Luna
8239d03e0e
Update authlib-injector to point to local doc rather than fjord's 2025-02-26 15:19:00 -06:00
Luna
62fdcd5c33
Bump to 1.6 2025-02-26 01:27:51 -06:00
Luna
fa9259a167 Revert "README: Don't mention fjordlauncher-bin MPR package"
This reverts commit f66c5b116f.
2025-02-25 23:29:09 -06:00
Luna
11d1952696 Merge branch 'develop' of https://github.com/LunaisLazier/ShatteredPrism into develop 2025-02-25 23:28:28 -06:00
Luna
1220f8fd6e Fix instance launching drm issue + MSA Log-in Dialogue re-appearing
Hopefully fixes #3
2025-02-25 23:28:00 -06:00
Luna
19f5f25540
Merge pull request #2 from LunaisLazier/update_flake_lock_action
chore(nix): update lockfile
2025-02-25 23:07:36 -06:00
Luna
c95eedd72c Update copyright dates to 2025 2025-02-25 22:32:05 -06:00
Alexandru Ionut Tripon
631d465583 Update .github/workflows/build.yml
Co-authored-by: Seth Flynn <getchoo@tuta.io>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
(cherry picked from commit db766574a42a4b7db6b320b6d469b233ce5f3100)
Signed-off-by: Seth Flynn <getchoo@tuta.io>
2025-02-25 22:25:18 -06:00
Alexandru Ionut Tripon
b65d0d1fe6 Update .github/workflows/build.yml
Co-authored-by: seth <getchoo@tuta.io>
Signed-off-by: Alexandru Ionut Tripon <alexandru.tripon97@gmail.com>
(cherry picked from commit 1b5d3c2bf903bbcade7b38c22c0b103a0c6999f8)
Signed-off-by: Seth Flynn <getchoo@tuta.io>
2025-02-25 22:25:17 -06:00
Trial97
f56dfbafb2 remove specific step for qt6
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
(cherry picked from commit be3eca8c97fdbb8daede84cab20fbd7695334242)
Signed-off-by: Seth Flynn <getchoo@tuta.io>
2025-02-25 22:25:17 -06:00
Trial97
de438aea84 fix appimage
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
(cherry picked from commit bca517b8d3cd685540beebf69fbc1f80fe0a6ce4)
Signed-off-by: Seth Flynn <getchoo@tuta.io>
2025-02-25 22:25:17 -06:00
Evan Goode
3ec0820b45 Merge pull request #56 from unmojang/evan-goode/feed-the-beast
Use api.feed-the-beast.com, not modpacks.ch
2025-02-25 22:25:17 -06:00
Evan Goode
07dac3127a Use api.feed-the-beast.com, not modpacks.ch 2025-02-25 22:25:17 -06:00
Evan Goode
67e6e5e7b1 Merge pull request #51 from unmojang/evan-goode/fix-selectedProfile
Only send `selectedProfile` when selecting a profile
2025-02-25 22:25:17 -06:00
Evan Goode
80baecf088 Remove irrelevant FIXME comment 2025-02-25 22:25:17 -06:00
Evan Goode
b1e0b70833 Only send selectedProfile when selecting a profile
Some authentication servers (Blessing Skin) care when selectedProfile is
sent on POST /refresh but the clientToken is already bound to a profile.
We should only include selectedProfile in POST /refresh during the
initial "Add authlib-injector account" process when selecting a profile
from multiple availableProfiles.

For https://github.com/unmojang/FjordLauncher/issues/50
2025-02-25 22:25:17 -06:00
Evan Goode
f66c5b116f README: Don't mention fjordlauncher-bin MPR package
prismlauncher-bin [1] is out of date and so fjordlauncher-bin also hasn't been updated in a while. Not sure whether -bin packages are dangerous on MPR as they are on AUR, so we'll just omit it from the install instructions for now.

[1] https://mpr.makedeb.org/packages/prismlauncher-bin
2025-02-25 22:25:17 -06:00
github-actions[bot]
2c5a869dba chore(nix): update lockfile
Flake lock file updates:

• Updated input 'flake-compat':
    'github:edolstra/flake-compat/9ed2ac151eada2306ca8c418ebd97807bb08f6ac?narHash=sha256-HRJ/18p%2BWoXpWJkcdsk9St5ZiukCqSDgbOGFa8Okehg%3D' (2024-11-27)
  → 'github:edolstra/flake-compat/ff81ac966bb2cae68946d5ed5fc4994f96d0ffec?narHash=sha256-NeCCThCEP3eCl2l/%2B27kNNK7QrwZB1IJCrXfrbv5oqU%3D' (2024-12-04)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/fa42b5a5f401aab8a32bd33c9a4de0738180dc59?narHash=sha256-RzaI1RO0UXqLjydtz3GAXSTzHkpb/lLD1JD8a0W4Wpo%3D' (2024-11-28)
  → 'github:NixOS/nixpkgs/73cf49b8ad837ade2de76f87eb53fc85ed5d4680?narHash=sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64%3D' (2025-02-18)
2025-02-23 01:19:53 +00:00
Evan Goode
31d99a35e7 Fix FetchFlameAPIKey compile error 2025-01-12 12:46:48 -06:00
Evan Goode
491cb1e5a2 Merge remote-tracking branch 'prismlauncher/release-9.x' into develop 2025-01-12 12:46:48 -06:00
Evan Goode
2c014a075d Not yet in nixpkgs
Resolves #46
2025-01-12 12:43:54 -06:00
Evan Goode
6b6da03aa4 chore(nix): nixfmt 2025-01-12 12:43:41 -06:00
Evan Goode
6ec444e0c4 chore(nix): sync with upstream Prism Launcher 2025-01-12 12:38:34 -06:00
Evan Goode
e0088f7811 Merge pull request #42 from ryze312/nix
Nix: Update lock file and switch to addDriverRunpath
2025-01-12 12:30:56 -06:00
Luna
9d66c25d42 Revert "Merge pull request #42 from ryze312/nix"
This reverts commit d7e190cabb.
2025-01-11 14:19:48 -06:00
Luna
41e90afbab Revert "Merge in Changes from Prism 9.2"
This reverts commit b4b9051793.
2025-01-11 14:19:46 -06:00
Luna
32b45d0fd7 Revert "Parity with Upstream towards Nix"
This reverts commit 4de9053c05.
2025-01-11 14:19:43 -06:00
Luna
2129244378 Revert "revert auth parent changes"
This reverts commit cbcbda6d4c.
2025-01-11 14:19:39 -06:00
Luna
cbcbda6d4c revert auth parent changes 2025-01-11 14:11:12 -06:00
Luna
4de9053c05 Parity with Upstream towards Nix 2025-01-11 13:58:43 -06:00
Luna
b4b9051793 Merge in Changes from Prism 9.2 2025-01-11 13:58:12 -06:00
Evan Goode
d7e190cabb Merge pull request #42 from ryze312/nix
Nix: Update lock file and switch to addDriverRunpath
2025-01-11 13:02:27 -06:00
Luna
1a02c19176 correct some instances of "fjord" to "shattered/shattered prism" 2025-01-11 13:00:30 -06:00
Evan Goode
8990841c8b Add dialog to select profile if multiple availableProfiles
Resolves https://github.com/unmojang/FjordLauncher/issues/29 and
obsoletes https://github.com/unmojang/FjordLauncher/pull/34.

This implementation follows the authlib-injector specification:
https://github.com/yushijinhun/authlib-injector/wiki/%E5%90%AF%E5%8A%A8%E5%99%A8%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#%E8%B4%A6%E6%88%B7%E7%9A%84%E6%B7%BB%E5%8A%A0
([Google translate to English](https://github-com.translate.goog/yushijinhun/authlib-injector/wiki/%E5%90%AF%E5%8A%A8%E5%99%A8%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-US))
2024-11-29 08:32:14 -06:00
Evan Goode
a1537bf42d Add Spaceship and Phoebe catpack 2024-11-29 08:32:14 -06:00
Luna
d08118b05a restore original versioning without causing nix breakage(?) 2024-11-29 08:31:50 -06:00
Luna
72a8ff070e Revert "Remove patch system as updater breaks."
This reverts commit fec49be639.
2024-11-29 08:31:27 -06:00
Luna
6f8fc48839 Revert "fix nix builds again(?)"
This reverts commit 25d90beb12.
2024-11-29 08:31:13 -06:00
Luna
25d90beb12 fix nix builds again(?) 2024-10-30 03:48:52 -05:00
Luna
fec49be639 Remove patch system as updater breaks. 2024-10-30 00:11:37 -05:00
Luna
f70084972a Fix builds, restore PollyMC to contributors list. 2024-10-29 23:00:35 -05:00
Luna
2921db3e19 Add Pseurae to in-launcher Contributors list, revert readme changes 2024-10-29 19:44:51 -05:00
Luna
4d0b910ead
Merge pull request #1 from Pseurae/merge-9.0
Possible fix for failing Nix builds
2024-10-29 19:35:54 -05:00
Adhith Chand Thiruvath
4ae137c8d3
Update .markdownlint.yaml 2024-10-30 05:46:43 +05:30
Luna
f8469afe2b test if nix readme is the breakage for nix builds 2024-10-29 18:36:52 -05:00
Luna
02a60f97c3 adjust missed fjords to shattered in hopes of fixing builds 2024-10-29 03:48:04 -05:00
Luna
a03b3d8c7a Fix overlooked branding errors 2024-10-29 03:36:32 -05:00
Luna
707f9026f3 Update README.md 2024-10-29 03:33:18 -05:00
Luna
10991d9556 Update README.md 2024-10-29 03:33:17 -05:00
Luna
e5e86a1211 Update README.md 2024-10-29 03:33:17 -05:00
Luna
f6c44570af correct copyright and license 2024-10-29 03:33:17 -05:00
Luna
ea7d9c0a8d fix typo preventing linux builds 2024-10-29 03:30:29 -05:00
Luna
1b95061bcf Adjust branding to that of ShatteredPrism 2024-10-29 03:29:24 -05:00
Luna
168b980d7a Remove DRM, Bump Version, Re-enable Updater.
Doing this in hopes it is easier to base upon the new version, alongside hopes of the patch system not breaking the updater.
2024-10-29 02:57:00 -05:00
1671 changed files with 13093 additions and 2348 deletions

View File

@ -6,9 +6,9 @@ body:
attributes: attributes:
value: | value: |
Before submitting a bug report, please make sure you have read this *entire* form, and that: Before submitting a bug report, please make sure you have read this *entire* form, and that:
* You have read the [Fjord Launcher wiki](https://fjordlauncher.org/wiki/) and it has not answered your question. * You have read the [Prism Launcher wiki](https://prismlauncher.org/wiki/) and it has not answered your question.
* Your bug is not caused by Minecraft or any mods you have installed. * Your bug is not caused by Minecraft or any mods you have installed.
* Your issue has not been reported before, [make sure to use the search function!](https://github.com/unmojang/FjordLauncher/issues) * Your issue has not been reported before, [make sure to use the search function!](https://github.com/lunaislazier/ShatteredPrism/issues)
**Do not forget to give your issue a descriptive title.** "Bug in the instance screen" makes it hard to distinguish issues at a glance. **Do not forget to give your issue a descriptive title.** "Bug in the instance screen" makes it hard to distinguish issues at a glance.
- type: dropdown - type: dropdown
@ -23,15 +23,15 @@ body:
- Other - Other
- type: textarea - type: textarea
attributes: attributes:
label: Version of Fjord Launcher label: Version of Shattered Prism
description: The version of Fjord Launcher used in the bug report. description: The version of Shattered Prism used in the bug report.
placeholder: Fjord Launcher 5.1 placeholder: Shattered Prism 1.3
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Version of Qt label: Version of Qt
description: The version of Qt used in the bug report. You can find it in Help -> About Fjord Launcher -> About Qt. description: The version of Qt used in the bug report. You can find it in Help -> About Shattered Prism -> About Qt.
placeholder: Qt 6.3.0 placeholder: Qt 6.3.0
validations: validations:
required: true required: true
@ -39,7 +39,7 @@ body:
attributes: attributes:
label: Description of bug label: Description of bug
description: What did you expect to happen, what happened, and why is it incorrect? description: What did you expect to happen, what happened, and why is it incorrect?
placeholder: The parrot button should show a parrot, but it showed a cat instead! placeholder: The cat button should show a cat, but it showed a parrot instead!
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@ -6,38 +6,38 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
### Use this form to suggest a larger change for Fjord Launcher. ### Use this form to suggest a larger change for Shattered Prism.
- type: textarea - type: textarea
attributes: attributes:
label: Goal label: Goal
description: Short description, 1-2 sentences. description: Short description, 1-2 sentences.
placeholder: Remove the parrot from the launcher. placeholder: Remove the cat from the launcher.
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Motivation label: Motivation
description: | description: |
Introduce the topic. If this is a not-well-known section of Fjord Launcher, a detailed explanation of the background is recommended. Introduce the topic. If this is a not-well-known section of Shattered Prism, a detailed explanation of the background is recommended.
Some example points of discussion: Some example points of discussion:
- What specific problems are you facing right now that you're trying to address? - What specific problems are you facing right now that you're trying to address?
- Are there any previous discussions? Link to them and summarize them (don't force your readers to read them though!). - Are there any previous discussions? Link to them and summarize them (don't force your readers to read them though!).
- Is there any precedent set by other software? If so, link to resources. - Is there any precedent set by other software? If so, link to resources.
placeholder: I don't like parrots. I think many users also don't like parrots. placeholder: I don't like cats. I think many users also don't like cats.
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Specification label: Specification
description: A concrete, thorough explanation of what is being planned. description: A concrete, thorough explanation of what is being planned.
placeholder: Remove the parrot button and all references to the parrot from the codebase. Including resource files. placeholder: Remove the cat button and all references to the cat from the codebase. Including resource files.
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Drawbacks label: Drawbacks
description: Carefully consider every possible objection and issue with your proposal. This section should be updated as feedback comes in from discussion. description: Carefully consider every possible objection and issue with your proposal. This section should be updated as feedback comes in from discussion.
placeholder: Some users might like parrots. placeholder: Some users might like cats.
validations: validations:
required: true required: true
- type: textarea - type: textarea
@ -47,14 +47,14 @@ body:
Are there any portions of your proposal which need to be discussed with the community before the RFC can proceed? Are there any portions of your proposal which need to be discussed with the community before the RFC can proceed?
Be careful here -- an RFC with a lot of remaining questions is likely to be stalled. Be careful here -- an RFC with a lot of remaining questions is likely to be stalled.
If your RFC is mostly unresolved questions and not too much substance, it may not be ready. If your RFC is mostly unresolved questions and not too much substance, it may not be ready.
placeholder: Do a lot of users care about the parrot? placeholder: Do a lot of users care about the cat?
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Alternatives Considered label: Alternatives Considered
description: A list of alternatives, that have been considered and offer equal or similar features to the proposed change. description: A list of alternatives, that have been considered and offer equal or similar features to the proposed change.
placeholder: Maybe the parrot could be replaced with a dog? placeholder: Maybe the cat could be replaced with a dog?
validations: validations:
required: true required: true
- type: checkboxes - type: checkboxes

View File

@ -5,26 +5,26 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
### Use this form to suggest a feature for Fjord Launcher. ### Use this form to suggest a feature for Shattered Prism.
- type: input - type: input
attributes: attributes:
label: Role label: Role
description: In what way do you use Fjord Launcher that needs this feature? description: In what way do you use Shattered Prism that needs this feature?
placeholder: I play modded Minecraft. placeholder: I play modded Minecraft.
validations: validations:
required: true required: true
- type: input - type: input
attributes: attributes:
label: Suggestion label: Suggestion
description: What do you want Fjord Launcher to do? description: What do you want Shattered Prism to do?
placeholder: I want the parrot button to squawk. placeholder: I want the cat button to meow.
validations: validations:
required: true required: true
- type: input - type: input
attributes: attributes:
label: Benefit label: Benefit
description: Why do you need Fjord Launcher to do this? description: Why do you need Shattered Prism to do this?
placeholder: so that I can always hear a parrot when I need to. placeholder: so that I can always hear a cat when I need to.
validations: validations:
required: true required: true
- type: checkboxes - type: checkboxes

View File

@ -2,7 +2,7 @@
Hey there! Thanks for your contribution. Hey there! Thanks for your contribution.
Please make sure that your commits are signed off first. Please make sure that your commits are signed off first.
If you don't know how that works, check out our contribution guidelines: https://github.com/unmojang/FjordLauncher/blob/develop/CONTRIBUTING.md#signing-your-work If you don't know how that works, check out our contribution guidelines: https://github.com/lunaislazier/ShatteredPrism/blob/develop/CONTRIBUTING.md#signing-your-work
If you already created your commits, you can run `git rebase --signoff develop` to retroactively sign-off all your commits and `git push --force` to override what you have pushed already. If you already created your commits, you can run `git rebase --signoff develop` to retroactively sign-off all your commits and `git push --force` to override what you have pushed already.
Note that signing and signing-off are two different things! Note that signing and signing-off are two different things!

View File

@ -39,9 +39,6 @@ on:
APPLE_NOTARIZE_PASSWORD: APPLE_NOTARIZE_PASSWORD:
description: Password used for notarizing macOS builds description: Password used for notarizing macOS builds
required: false required: false
CACHIX_AUTH_TOKEN:
description: Private token for authenticating against Cachix cache
required: false
GPG_PRIVATE_KEY: GPG_PRIVATE_KEY:
description: Private key for AppImage signing description: Private key for AppImage signing
required: false required: false
@ -59,15 +56,18 @@ jobs:
qt_ver: 5 qt_ver: 5
qt_host: linux qt_host: linux
qt_arch: "" qt_arch: ""
qt_version: "5.12.8" qt_version: "5.15.2"
qt_modules: "qtnetworkauth" qt_modules: "qtnetworkauth"
- os: ubuntu-20.04 - os: ubuntu-22.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.5.3"
qt_modules: "qt5compat qtimageformats qtnetworkauth" qt_modules: "qt5compat qtimageformats qtnetworkauth"
linuxdeploy_hash: "4648f278ab3ef31f819e67c30d50f462640e5365a77637d7e6f2ad9fd0b4522a linuxdeploy-x86_64.AppImage"
linuxdeploy_qt_hash: "15106be885c1c48a021198e7e1e9a48ce9d02a86dd0a1848f00bdbf3c1c92724 linuxdeploy-plugin-qt-x86_64.AppImage"
appimageupdate_hash: "f1747cf60058e99f1bb9099ee9787d16c10241313b7acec81810ea1b1e568c11 AppImageUpdate-x86_64.AppImage"
- os: windows-2022 - os: windows-2022
name: "Windows-MinGW-w64" name: "Windows-MinGW-w64"
@ -80,9 +80,9 @@ jobs:
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: "win64_msvc2022_64"
qt_version: "6.7.3" qt_version: "6.8.1"
qt_modules: "qt5compat qtimageformats qtnetworkauth" qt_modules: "qt5compat qtimageformats qtnetworkauth"
nscurl_tag: "v24.9.26.122" nscurl_tag: "v24.9.26.122"
nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0" nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0"
@ -93,9 +93,9 @@ jobs:
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_msvc2022_arm64_cross_compiled"
qt_version: "6.7.3" qt_version: "6.8.1"
qt_modules: "qt5compat qtimageformats qtnetworkauth" qt_modules: "qt5compat qtimageformats qtnetworkauth"
nscurl_tag: "v24.9.26.122" nscurl_tag: "v24.9.26.122"
nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0" nscurl_sha256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0"
@ -106,7 +106,7 @@ jobs:
qt_ver: 6 qt_ver: 6
qt_host: mac qt_host: mac
qt_arch: "" qt_arch: ""
qt_version: "6.7.3" qt_version: "6.8.1"
qt_modules: "qt5compat qtimageformats qtnetworkauth" qt_modules: "qt5compat qtimageformats qtnetworkauth"
- os: macos-14 - os: macos-14
@ -173,7 +173,7 @@ jobs:
- 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@v4.1.1 uses: actions/cache@v4.2.0
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 }}
@ -206,7 +206,7 @@ jobs:
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: | run: |
sudo apt-get -y update sudo apt-get -y update
sudo apt-get -y install ninja-build extra-cmake-modules scdoc appstream sudo apt-get -y install ninja-build extra-cmake-modules scdoc appstream libxcb-cursor-dev
- name: Install Dependencies (macOS) - name: Install Dependencies (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
@ -216,14 +216,14 @@ jobs:
- name: Install host Qt (Windows MSVC arm64) - name: Install host Qt (Windows MSVC arm64)
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@v4
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: ${{ matrix.qt_arch }}
modules: ${{ matrix.qt_modules }} modules: ${{ matrix.qt_modules }}
cache: ${{ inputs.is_qt_cached }} cache: ${{ inputs.is_qt_cached }}
cache-key-prefix: host-qt-arm64-windows cache-key-prefix: host-qt-arm64-windows
@ -232,7 +232,7 @@ jobs:
- name: Install Qt (macOS, Linux & Windows MSVC) - name: Install Qt (macOS, Linux & Windows MSVC)
if: matrix.msystem == '' if: matrix.msystem == ''
uses: jurplel/install-qt-action@v3 uses: jurplel/install-qt-action@v4
with: with:
aqtversion: "==3.1.*" aqtversion: "==3.1.*"
py7zrversion: ">=0.20.2" py7zrversion: ">=0.20.2"
@ -252,19 +252,26 @@ jobs:
- name: Prepare AppImage (Linux) - name: Prepare AppImage (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5 if: runner.os == 'Linux' && matrix.qt_ver != 5
env:
APPIMAGEUPDATE_HASH: ${{ matrix.appimageupdate_hash }}
LINUXDEPLOY_HASH: ${{ matrix.linuxdeploy_hash }}
LINUXDEPLOY_QT_HASH: ${{ matrix.linuxdeploy_qt_hash }}
run: | run: |
wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-x86_64.AppImage"
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage" wget "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/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" wget "https://github.com/AppImageCommunity/AppImageUpdate/releases/download/2.0.0-alpha-1-20241225/AppImageUpdate-x86_64.AppImage"
sudo apt install libopengl0 sha256sum -c - <<< "$LINUXDEPLOY_HASH"
sha256sum -c - <<< "$LINUXDEPLOY_QT_HASH"
sha256sum -c - <<< "$APPIMAGEUPDATE_HASH"
sudo apt install libopengl0 libfuse2
- name: Add QT_HOST_PATH var (Windows MSVC arm64) - name: Add QT_HOST_PATH var (Windows MSVC arm64)
if: runner.os == 'Windows' && matrix.architecture == 'arm64' if: runner.os == 'Windows' && matrix.architecture == 'arm64'
run: | run: |
echo "QT_HOST_PATH=${{ github.workspace }}\HostQt\Qt\${{ matrix.qt_version }}\msvc2019_64" >> $env:GITHUB_ENV echo "QT_HOST_PATH=${{ github.workspace }}\HostQt\Qt\${{ matrix.qt_version }}\msvc2022_64" >> $env:GITHUB_ENV
- name: Setup java (macOS) - name: Setup java (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
@ -376,7 +383,7 @@ jobs:
cmake --install ${{ env.BUILD_DIR }} cmake --install ${{ env.BUILD_DIR }}
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
chmod +x "FjordLauncher.app/Contents/MacOS/fjordlauncher" chmod +x "ShatteredPrism.app/Contents/MacOS/ShatteredPrism"
if [ -n '${{ secrets.APPLE_CODESIGN_ID }}' ]; then if [ -n '${{ secrets.APPLE_CODESIGN_ID }}' ]; then
APPLE_CODESIGN_ID='${{ secrets.APPLE_CODESIGN_ID }}' APPLE_CODESIGN_ID='${{ secrets.APPLE_CODESIGN_ID }}'
@ -384,8 +391,8 @@ jobs:
APPLE_CODESIGN_ID='-' APPLE_CODESIGN_ID='-'
fi fi
sudo codesign --sign "$APPLE_CODESIGN_ID" --deep --force --entitlements "../program_info/App.entitlements" --options runtime "FjordLauncher.app/Contents/MacOS/fjordlauncher" sudo codesign --sign "$APPLE_CODESIGN_ID" --deep --force --entitlements "../program_info/App.entitlements" --options runtime "ShatteredPrism.app/Contents/MacOS/ShatteredPrism"
mv "FjordLauncher.app" "Fjord Launcher.app" mv "ShatteredPrism.app" "Shattered Prism.app"
- name: Notarize (macOS) - name: Notarize (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
@ -393,25 +400,25 @@ jobs:
cd ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }}
if [ -n '${{ secrets.APPLE_NOTARIZE_PASSWORD }}' ]; then if [ -n '${{ secrets.APPLE_NOTARIZE_PASSWORD }}' ]; then
ditto -c -k --sequesterRsrc --keepParent "Fjord Launcher.app" ../FjordLauncher.zip ditto -c -k --sequesterRsrc --keepParent "Shattered Prism.app" ../ShatteredPrism.zip
xcrun notarytool submit ../FjordLauncher.zip \ xcrun notarytool submit ../ShatteredPrism.zip \
--wait --progress \ --wait --progress \
--apple-id '${{ secrets.APPLE_NOTARIZE_APPLE_ID }}' \ --apple-id '${{ secrets.APPLE_NOTARIZE_APPLE_ID }}' \
--team-id '${{ secrets.APPLE_NOTARIZE_TEAM_ID }}' \ --team-id '${{ secrets.APPLE_NOTARIZE_TEAM_ID }}' \
--password '${{ secrets.APPLE_NOTARIZE_PASSWORD }}' --password '${{ secrets.APPLE_NOTARIZE_PASSWORD }}'
xcrun stapler staple "Fjord Launcher.app" xcrun stapler staple "Shattered Prism.app"
else else
echo ":warning: Skipping notarization as credentials are not present." >> $GITHUB_STEP_SUMMARY echo ":warning: Skipping notarization as credentials are not present." >> $GITHUB_STEP_SUMMARY
fi fi
ditto -c -k --sequesterRsrc --keepParent "Fjord Launcher.app" ../FjordLauncher.zip ditto -c -k --sequesterRsrc --keepParent "Shattered Prism.app" ../ShatteredPrism.zip
- name: Make Sparkle signature (macOS) - name: Make Sparkle signature (macOS)
if: matrix.name == 'macOS' if: matrix.name == 'macOS'
run: | run: |
if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then
echo '${{ secrets.SPARKLE_ED25519_KEY }}' > ed25519-priv.pem echo '${{ secrets.SPARKLE_ED25519_KEY }}' > ed25519-priv.pem
signature=$(/opt/homebrew/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/FjordLauncher.zip -inkey ed25519-priv.pem | openssl base64 | tr -d \\n) signature=$(/opt/homebrew/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/ShatteredPrism.zip -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
rm ed25519-priv.pem rm ed25519-priv.pem
cat >> $GITHUB_STEP_SUMMARY << EOF cat >> $GITHUB_STEP_SUMMARY << EOF
### Artifact Information :information_source: ### Artifact Information :information_source:
@ -453,7 +460,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 fjordlauncher.exe fjordlauncher_updater.exe fjordlauncher_filelink.exe SignTool sign /fd sha256 /td sha256 /f ../codesign.pfx /p '${{ secrets.WINDOWS_CODESIGN_PASSWORD }}' /tr http://timestamp.digicert.com ShatteredPrism.exe ShatteredPrism_updater.exe ShatteredPrism_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
} }
@ -494,7 +501,7 @@ jobs:
if: runner.os == 'Windows' if: runner.os == 'Windows'
run: | run: |
if (Get-Content ./codesign.pfx){ if (Get-Content ./codesign.pfx){
SignTool sign /fd sha256 /td sha256 /f codesign.pfx /p '${{ secrets.WINDOWS_CODESIGN_PASSWORD }}' /tr http://timestamp.digicert.com FjordLauncher-Setup.exe SignTool sign /fd sha256 /td sha256 /f codesign.pfx /p '${{ secrets.WINDOWS_CODESIGN_PASSWORD }}' /tr http://timestamp.digicert.com ShatteredPrism-Setup.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
} }
@ -507,10 +514,10 @@ jobs:
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.unmojang.FjordLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.fjordlauncher.FjordLauncher.appdata.xml mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.lunaislazier.ShatteredPrism.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.lunaislazier.ShatteredPrism.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="FjordLauncher-Linux-x86_64.AppImage" export OUTPUT="ShatteredPrism-Linux-x86_64.AppImage"
chmod +x linuxdeploy-*.AppImage chmod +x linuxdeploy-*.AppImage
@ -519,8 +526,8 @@ jobs:
cp -r ${{ runner.workspace }}/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.* ${{ 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.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
@ -529,7 +536,7 @@ jobs:
chmod +x AppImageUpdate-x86_64.AppImage chmod +x AppImageUpdate-x86_64.AppImage
cp AppImageUpdate-x86_64.AppImage ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin 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|FjordLauncher-Linux-x86_64.AppImage.zsync" export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|ShatteredPrism-Linux-x86_64.AppImage.zsync"
if [ '${{ secrets.GPG_PRIVATE_KEY_ID }}' != '' ]; then if [ '${{ secrets.GPG_PRIVATE_KEY_ID }}' != '' ]; then
export SIGN=1 export SIGN=1
@ -541,9 +548,9 @@ jobs:
echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
fi 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.unmojang.FjordLauncher.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.lunaislazier.ShatteredPrism.svg
mv "FjordLauncher-Linux-x86_64.AppImage" "FjordLauncher-Linux-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage" mv "ShatteredPrism-Linux-x86_64.AppImage" "ShatteredPrism-Linux-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
- name: Package (Linux, portable) - name: Package (Linux, portable)
if: runner.os == 'Linux' if: runner.os == 'Linux'
@ -555,14 +562,14 @@ jobs:
mkdir ${{ env.INSTALL_PORTABLE_DIR }}/lib mkdir ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /lib/x86_64-linux-gnu/libbz2.so.1.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib cp /lib/x86_64-linux-gnu/libbz2.so.1.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib cp /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_PORTABLE_DIR }}/lib cp /usr/lib/x86_64-linux-gnu/libcrypto.so.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_PORTABLE_DIR }}/lib cp /usr/lib/x86_64-linux-gnu/libssl.so.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libffi.so.7 ${{ env.INSTALL_PORTABLE_DIR }}/lib cp /usr/lib/x86_64-linux-gnu/libffi.so.*.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
mv ${{ env.INSTALL_PORTABLE_DIR }}/bin/*.so* ${{ env.INSTALL_PORTABLE_DIR }}/lib mv ${{ env.INSTALL_PORTABLE_DIR }}/bin/*.so* ${{ env.INSTALL_PORTABLE_DIR }}/lib
for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
cd ${{ env.INSTALL_PORTABLE_DIR }} cd ${{ env.INSTALL_PORTABLE_DIR }}
tar -czf ../FjordLauncher-portable.tar.gz * tar -czf ../ShatteredPrism-portable.tar.gz *
## ##
# UPLOAD BUILDS # UPLOAD BUILDS
@ -572,128 +579,60 @@ jobs:
if: runner.os == 'macOS' if: runner.os == 'macOS'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: FjordLauncher.zip path: ShatteredPrism.zip
- name: Upload binary zip (Windows) - name: Upload binary zip (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }}
path: ${{ env.INSTALL_DIR }}/** path: ${{ env.INSTALL_DIR }}/**
- name: Upload binary zip (Windows, portable) - name: Upload binary zip (Windows, portable)
if: runner.os == 'Windows' if: runner.os == 'Windows'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ matrix.name }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ matrix.name }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: ${{ env.INSTALL_PORTABLE_DIR }}/** path: ${{ env.INSTALL_PORTABLE_DIR }}/**
- name: Upload installer (Windows) - name: Upload installer (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }}
path: FjordLauncher-Setup.exe path: ShatteredPrism-Setup.exe
- 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@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ runner.os }}-Qt5-Portable-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ runner.os }}-Qt5-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: FjordLauncher-portable.tar.gz path: ShatteredPrism-portable.tar.gz
- name: Upload binary tarball (Linux, portable, Qt 6) - name: Upload binary tarball (Linux, portable, Qt 6)
if: runner.os == 'Linux' && matrix.qt_ver != 5 if: runner.os == 'Linux' && matrix.qt_ver != 5
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }} name: ShatteredPrism-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
path: FjordLauncher-portable.tar.gz path: ShatteredPrism-portable.tar.gz
- name: Upload AppImage (Linux) - name: Upload AppImage (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5 if: runner.os == 'Linux' && matrix.qt_ver != 5
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage name: ShatteredPrism-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
path: FjordLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage path: ShatteredPrism-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
- name: Upload AppImage Zsync (Linux) - name: Upload AppImage Zsync (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5 if: runner.os == 'Linux' && matrix.qt_ver != 5
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: FjordLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage.zsync name: ShatteredPrism-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage.zsync
path: FjordLauncher-Linux-x86_64.AppImage.zsync path: ShatteredPrism-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}
run: | run: |
ccache -s ccache -s
flatpak:
runs-on: ubuntu-latest
container:
image: bilelmoussaoui/flatpak-github-actions:kde-6.7
options: --privileged
steps:
- name: Checkout
uses: actions/checkout@v4
if: inputs.build_type == 'Debug'
with:
submodules: "true"
- name: Build Flatpak (Linux)
if: inputs.build_type == 'Debug'
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: "Fjord Launcher.flatpak"
manifest-path: flatpak/org.unmojang.FjordLauncher.yml
nix:
name: Nix (${{ matrix.system }})
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
system: x86_64-linux
- os: macos-13
system: x86_64-darwin
- os: macos-14
system: aarch64-darwin
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v30
# For PRs
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@v8
# For in-tree builds
- name: Setup Cachix
uses: cachix/cachix-action@v15
with:
name: unmojang
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Run flake checks
run: |
nix flake check --print-build-logs --show-trace
- name: Build debug package
if: ${{ inputs.build_type == 'Debug' }}
run: |
nix build --print-build-logs .#fjordlauncher-debug
- name: Build release package
if: ${{ inputs.build_type != 'Debug' }}
run: |
nix build --print-build-logs .#fjordlauncher

62
.github/workflows/flatpak.yml vendored Normal file
View File

@ -0,0 +1,62 @@
name: Flatpak
on:
push:
paths-ignore:
- "**.md"
- "**/LICENSE"
- ".github/ISSUE_TEMPLATE/**"
- ".markdownlint**"
- "nix/**"
# We don't do anything with these artifacts on releases. They go to Flathub
tags-ignore:
- "*"
pull_request:
paths-ignore:
- "**.md"
- "**/LICENSE"
- ".github/ISSUE_TEMPLATE/**"
- ".markdownlint**"
- "nix/**"
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: Build (${{ matrix.arch }})
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
arch: x86_64
- os: ubuntu-22.04-arm
arch: aarch64
runs-on: ${{ matrix.os }}
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.8
options: --privileged
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Set short version
shell: bash
run: |
echo "VERSION=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
- name: Build Flatpak
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: ShatteredPrism-${{ runner.os }}-${{ env.VERSION }}-Flatpak.flatpak
manifest-path: flatpak/org.lunaislazier.ShatteredPrism.yml
arch: ${{ matrix.arch }}

88
.github/workflows/nix.yml vendored Normal file
View File

@ -0,0 +1,88 @@
name: Nix
on:
push:
paths-ignore:
- "**.md"
- "**/LICENSE"
- ".github/ISSUE_TEMPLATE/**"
- ".markdownlint**"
- "flatpak/**"
tags:
- "*"
pull_request_target:
paths-ignore:
- "**.md"
- "**/LICENSE"
- ".github/ISSUE_TEMPLATE/**"
- ".markdownlint**"
- "flatpak/**"
workflow_dispatch:
permissions:
contents: read
env:
DEBUG: ${{ github.ref_type != 'tag' }}
USE_DETERMINATE: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: Build (${{ matrix.system }})
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
system: x86_64-linux
- os: ubuntu-22.04-arm
system: aarch64-linux
- os: macos-13
system: x86_64-darwin
- os: macos-14
system: aarch64-darwin
runs-on: ${{ matrix.os }}
permissions:
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v16
with:
determinate: ${{ env.USE_DETERMINATE }}
# For PRs
- name: Setup Nix Magic Cache
if: ${{ env.USE_DETERMINATE }}
uses: DeterminateSystems/flakehub-cache-action@v1
# For in-tree builds
- name: Setup Cachix
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
uses: cachix/cachix-action@v15
with:
name: lunaislazier
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Run Flake checks
run: |
nix flake check --print-build-logs --show-trace
- name: Build debug package
if: ${{ env.DEBUG }}
run: |
nix build --print-build-logs .#shatteredprism-debug
- name: Build release package
if: ${{ !env.DEBUG }}
run: |
nix build --print-build-logs .#shatteredprism

View File

@ -38,6 +38,5 @@ jobs:
APPLE_NOTARIZE_APPLE_ID: ${{ secrets.APPLE_NOTARIZE_APPLE_ID }} APPLE_NOTARIZE_APPLE_ID: ${{ secrets.APPLE_NOTARIZE_APPLE_ID }}
APPLE_NOTARIZE_TEAM_ID: ${{ secrets.APPLE_NOTARIZE_TEAM_ID }} APPLE_NOTARIZE_TEAM_ID: ${{ secrets.APPLE_NOTARIZE_TEAM_ID }}
APPLE_NOTARIZE_PASSWORD: ${{ secrets.APPLE_NOTARIZE_PASSWORD }} APPLE_NOTARIZE_PASSWORD: ${{ secrets.APPLE_NOTARIZE_PASSWORD }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }} GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }}

View File

@ -1,6 +1,7 @@
name: Build Application and Make Release name: Build Application and Make Release
on: on:
workflow_dispatch:
push: push:
tags: tags:
- "*" - "*"
@ -22,7 +23,6 @@ jobs:
APPLE_NOTARIZE_APPLE_ID: ${{ secrets.APPLE_NOTARIZE_APPLE_ID }} APPLE_NOTARIZE_APPLE_ID: ${{ secrets.APPLE_NOTARIZE_APPLE_ID }}
APPLE_NOTARIZE_TEAM_ID: ${{ secrets.APPLE_NOTARIZE_TEAM_ID }} APPLE_NOTARIZE_TEAM_ID: ${{ secrets.APPLE_NOTARIZE_TEAM_ID }}
APPLE_NOTARIZE_PASSWORD: ${{ secrets.APPLE_NOTARIZE_PASSWORD }} APPLE_NOTARIZE_PASSWORD: ${{ secrets.APPLE_NOTARIZE_PASSWORD }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }} GPG_PRIVATE_KEY_ID: ${{ secrets.GPG_PRIVATE_KEY_ID }}
@ -36,7 +36,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: "true" submodules: "true"
path: "FjordLauncher-source" path: "ShatteredPrism-source"
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
- name: Grab and store version - name: Grab and store version
@ -45,38 +45,38 @@ jobs:
echo "VERSION=$tag_name" >> $GITHUB_ENV echo "VERSION=$tag_name" >> $GITHUB_ENV
- name: Package artifacts properly - name: Package artifacts properly
run: | run: |
mv ${{ github.workspace }}/FjordLauncher-source FjordLauncher-${{ env.VERSION }} mv ${{ github.workspace }}/ShatteredPrism-source ShatteredPrism-${{ env.VERSION }}
mv FjordLauncher-Linux-Qt6-Portable*/FjordLauncher-portable.tar.gz FjordLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz mv ShatteredPrism-Linux-Qt6-Portable*/ShatteredPrism-portable.tar.gz ShatteredPrism-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
mv FjordLauncher-Linux-Qt5-Portable*/FjordLauncher-portable.tar.gz FjordLauncher-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz mv ShatteredPrism-Linux-Qt5-Portable*/ShatteredPrism-portable.tar.gz ShatteredPrism-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz
mv FjordLauncher-*.AppImage/FjordLauncher-*.AppImage FjordLauncher-Linux-x86_64.AppImage mv ShatteredPrism-*.AppImage/ShatteredPrism-*.AppImage ShatteredPrism-Linux-x86_64.AppImage
mv FjordLauncher-*.AppImage.zsync/FjordLauncher-*.AppImage.zsync FjordLauncher-Linux-x86_64.AppImage.zsync mv ShatteredPrism-*.AppImage.zsync/ShatteredPrism-*.AppImage.zsync ShatteredPrism-Linux-x86_64.AppImage.zsync
mv FjordLauncher-macOS-Legacy*/FjordLauncher.zip FjordLauncher-macOS-Legacy-${{ env.VERSION }}.zip mv ShatteredPrism-macOS-Legacy*/ShatteredPrism.zip ShatteredPrism-macOS-Legacy-${{ env.VERSION }}.zip
mv FjordLauncher-macOS*/FjordLauncher.zip FjordLauncher-macOS-${{ env.VERSION }}.zip mv ShatteredPrism-macOS*/ShatteredPrism.zip ShatteredPrism-macOS-${{ env.VERSION }}.zip
tar --exclude='.git' -czf FjordLauncher-${{ env.VERSION }}.tar.gz FjordLauncher-${{ env.VERSION }} tar --exclude='.git' -czf ShatteredPrism-${{ env.VERSION }}.tar.gz ShatteredPrism-${{ env.VERSION }}
for d in FjordLauncher-Windows-MSVC*; do for d in ShatteredPrism-Windows-MSVC*; do
cd "${d}" || continue cd "${d}" || continue
LEGACY="$(echo -n ${d} | grep -o Legacy || true)" LEGACY="$(echo -n ${d} | grep -o Legacy || true)"
ARM64="$(echo -n ${d} | grep -o arm64 || true)" ARM64="$(echo -n ${d} | grep -o arm64 || true)"
INST="$(echo -n ${d} | grep -o Setup || true)" INST="$(echo -n ${d} | grep -o Setup || true)"
PORT="$(echo -n ${d} | grep -o Portable || true)" PORT="$(echo -n ${d} | grep -o Portable || true)"
NAME="FjordLauncher-Windows-MSVC" NAME="ShatteredPrism-Windows-MSVC"
test -z "${LEGACY}" || NAME="${NAME}-Legacy" test -z "${LEGACY}" || NAME="${NAME}-Legacy"
test -z "${ARM64}" || NAME="${NAME}-arm64" test -z "${ARM64}" || NAME="${NAME}-arm64"
test -z "${PORT}" || NAME="${NAME}-Portable" test -z "${PORT}" || NAME="${NAME}-Portable"
test -z "${INST}" || mv FjordLauncher-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe test -z "${INST}" || mv ShatteredPrism-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe
test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" * test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
cd .. cd ..
done done
for d in FjordLauncher-Windows-MinGW-w64*; do for d in ShatteredPrism-Windows-MinGW-w64*; do
cd "${d}" || continue cd "${d}" || continue
INST="$(echo -n ${d} | grep -o Setup || true)" INST="$(echo -n ${d} | grep -o Setup || true)"
PORT="$(echo -n ${d} | grep -o Portable || true)" PORT="$(echo -n ${d} | grep -o Portable || true)"
NAME="FjordLauncher-Windows-MinGW-w64" NAME="ShatteredPrism-Windows-MinGW-w64"
test -z "${PORT}" || NAME="${NAME}-Portable" test -z "${PORT}" || NAME="${NAME}-Portable"
test -z "${INST}" || mv FjordLauncher-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe test -z "${INST}" || mv ShatteredPrism-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe
test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" * test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
cd .. cd ..
done done
@ -87,23 +87,23 @@ jobs:
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ github.ref }} tag_name: ${{ github.ref }}
name: Fjord Launcher ${{ env.VERSION }} name: Shattered Prism ${{ env.VERSION }}
draft: true draft: true
prerelease: false prerelease: false
files: | files: |
FjordLauncher-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz ShatteredPrism-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz
FjordLauncher-Linux-x86_64.AppImage ShatteredPrism-Linux-x86_64.AppImage
FjordLauncher-Linux-x86_64.AppImage.zsync ShatteredPrism-Linux-x86_64.AppImage.zsync
FjordLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz ShatteredPrism-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
FjordLauncher-Windows-MinGW-w64-${{ env.VERSION }}.zip ShatteredPrism-Windows-MinGW-w64-${{ env.VERSION }}.zip
FjordLauncher-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip ShatteredPrism-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip
FjordLauncher-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe ShatteredPrism-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe
FjordLauncher-Windows-MSVC-arm64-${{ env.VERSION }}.zip ShatteredPrism-Windows-MSVC-arm64-${{ env.VERSION }}.zip
FjordLauncher-Windows-MSVC-arm64-Portable-${{ env.VERSION }}.zip ShatteredPrism-Windows-MSVC-arm64-Portable-${{ env.VERSION }}.zip
FjordLauncher-Windows-MSVC-arm64-Setup-${{ env.VERSION }}.exe ShatteredPrism-Windows-MSVC-arm64-Setup-${{ env.VERSION }}.exe
FjordLauncher-Windows-MSVC-${{ env.VERSION }}.zip ShatteredPrism-Windows-MSVC-${{ env.VERSION }}.zip
FjordLauncher-Windows-MSVC-Portable-${{ env.VERSION }}.zip ShatteredPrism-Windows-MSVC-Portable-${{ env.VERSION }}.zip
FjordLauncher-Windows-MSVC-Setup-${{ env.VERSION }}.exe ShatteredPrism-Windows-MSVC-Setup-${{ env.VERSION }}.exe
FjordLauncher-macOS-${{ env.VERSION }}.zip ShatteredPrism-macOS-${{ env.VERSION }}.zip
FjordLauncher-macOS-Legacy-${{ env.VERSION }}.zip ShatteredPrism-macOS-Legacy-${{ env.VERSION }}.zip
FjordLauncher-${{ env.VERSION }}.tar.gz ShatteredPrism-${{ env.VERSION }}.tar.gz

View File

@ -12,7 +12,7 @@ permissions:
jobs: jobs:
update-flake: update-flake:
if: github.repository == 'unmojang/FjordLauncher' if: github.repository == 'lunaislazier/ShatteredPrism'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@ -1,15 +0,0 @@
name: Publish to WinGet
on:
release:
types: [released]
jobs:
publish:
runs-on: windows-latest
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: PrismLauncher.PrismLauncher
version: ${{ github.event.release.tag_name }}
installers-regex: 'PrismLauncher-Windows-MSVC(:?-arm64|-Legacy)?-Setup-.+\.exe$'
token: ${{ secrets.WINGET_TOKEN }}

6
.gitignore vendored
View File

@ -47,8 +47,12 @@ run/
# Nix/NixOS # Nix/NixOS
.direnv/ .direnv/
.pre-commit-config.yaml ## Used when manually invoking stdenv phases
outputs/
## Regular artifacts
result result
result-*
repl-result-*
# Flatpak # Flatpak
.flatpak-builder .flatpak-builder

View File

@ -1,6 +1,12 @@
# MD012/no-multiple-blanks - Multiple consecutive blank lines
MD012: false
# MD013/line-length - Line length # MD013/line-length - Line length
MD013: false MD013: false
# MD022/blanks-around-headings
MD022: false
# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content # MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content
MD024: MD024:
siblings-only: true siblings-only: true

View File

@ -78,6 +78,13 @@ else()
# ATL's pack list needs more than the default 1 Mib stack on windows # ATL's pack list needs more than the default 1 Mib stack on windows
if(WIN32) if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,8388608 ${CMAKE_EXE_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,8388608 ${CMAKE_EXE_LINKER_FLAGS}")
# -ffunction-sections and -fdata-sections help reduce binary size
# -mguard=cf enables Control Flow Guard
# TODO: Look into -gc-sections to further reduce binary size
foreach(lang C CXX)
set("CMAKE_${lang}_FLAGS_RELEASE" "-ffunction-sections -fdata-sections -mguard=cf")
endforeach()
endif() endif()
endif() endif()
@ -106,14 +113,14 @@ if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebI
else() else()
# AppleClang and Clang # AppleClang and Clang
message(STATUS "Address Sanitizer available on Clang") message(STATUS "Address Sanitizer available on Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=null")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=null")
endif() endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# GCC # GCC
message(STATUS "Address Sanitizer available on GCC") message(STATUS "Address Sanitizer available on GCC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover")
link_libraries("asan") link_libraries("asan")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "Address Sanitizer available on MSVC") message(STATUS "Address Sanitizer available on MSVC")
@ -180,19 +187,18 @@ set(Launcher_LOGIN_CALLBACK_URL "https://prismlauncher.org/successful-login" CAC
set(Launcher_FMLLIBS_BASE_URL "https://files.prismlauncher.org/fmllibs/" CACHE STRING "URL for FML Libraries.") set(Launcher_FMLLIBS_BASE_URL "https://files.prismlauncher.org/fmllibs/" CACHE STRING "URL for FML Libraries.")
######## Set version numbers ######## ######## Set version numbers ########
set(Launcher_VERSION_MAJOR 9) set(Launcher_VERSION_MAJOR 1)
set(Launcher_VERSION_MINOR 1) set(Launcher_VERSION_MINOR 7)
set(Launcher_VERSION_PATCH 0)
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}") set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_PATCH}.0") set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0")
set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},${Launcher_VERSION_PATCH},0") set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},0,0")
# Build platform. # Build platform.
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.") 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.")
# Github repo URL with releases for updater # Github repo URL with releases for updater
set(Launcher_UPDATER_GITHUB_REPO "" CACHE STRING "Base github URL for the updater.") set(Launcher_UPDATER_GITHUB_REPO "https://github.com/lunaislazier/ShatteredPrism" CACHE STRING "Base github URL for the updater.")
# Name to help updater identify valid artifacts # Name to help updater identify valid artifacts
set(Launcher_BUILD_ARTIFACT "" CACHE STRING "Artifact name to help the updater identify valid artifacts.") set(Launcher_BUILD_ARTIFACT "" CACHE STRING "Artifact name to help the updater identify valid artifacts.")
@ -204,7 +210,7 @@ set(Launcher_META_URL "https://meta.unmojang.org/v1/" CACHE STRING "URL to fetch
set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application")
# Bug tracker URL # Bug tracker URL
set(Launcher_BUG_TRACKER_URL "https://github.com/unmojang/FjordLauncher/issues" CACHE STRING "URL for the bug tracker.") set(Launcher_BUG_TRACKER_URL "https://github.com/lunaislazier/ShatteredPrism/issues" CACHE STRING "URL for the bug tracker.")
# Translations Platform URL # Translations Platform URL
set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/prismlauncher/launcher/" CACHE STRING "URL for the translations platform.") set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/prismlauncher/launcher/" CACHE STRING "URL for the translations platform.")
@ -350,7 +356,7 @@ include(ECMQtDeclareLoggingCategory)
####################################### Program Info ####################################### ####################################### Program Info #######################################
set(Launcher_APP_BINARY_NAME "fjordlauncher" CACHE STRING "Name of the Launcher binary") set(Launcher_APP_BINARY_NAME "shatteredprism" CACHE STRING "Name of the Launcher binary")
add_subdirectory(program_info) add_subdirectory(program_info)
####################################### Install layout ####################################### ####################################### Install layout #######################################
@ -390,8 +396,8 @@ if(UNIX AND APPLE)
set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "" CACHE STRING "Public key for Sparkle update feed") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "" CACHE STRING "Public key for Sparkle update feed")
set(MACOSX_SPARKLE_UPDATE_FEED_URL "" CACHE STRING "URL for Sparkle update feed") set(MACOSX_SPARKLE_UPDATE_FEED_URL "" CACHE STRING "URL for Sparkle update feed")
set(MACOSX_SPARKLE_DOWNLOAD_URL "https://github.com/sparkle-project/Sparkle/releases/download/2.5.2/Sparkle-2.5.2.tar.xz" CACHE STRING "URL to Sparkle release archive") set(MACOSX_SPARKLE_DOWNLOAD_URL "https://github.com/sparkle-project/Sparkle/releases/download/2.6.4/Sparkle-2.6.4.tar.xz" CACHE STRING "URL to Sparkle release archive")
set(MACOSX_SPARKLE_SHA256 "572dd67ae398a466f19f343a449e1890bac1ef74885b4739f68f979a8a89884b" CACHE STRING "SHA256 checksum for Sparkle release archive") set(MACOSX_SPARKLE_SHA256 "50612a06038abc931f16011d7903b8326a362c1074dabccb718404ce8e585f0b" CACHE STRING "SHA256 checksum for Sparkle release archive")
set(MACOSX_SPARKLE_DIR "${CMAKE_BINARY_DIR}/frameworks/Sparkle") set(MACOSX_SPARKLE_DIR "${CMAKE_BINARY_DIR}/frameworks/Sparkle")
# directories to look for dependencies # directories to look for dependencies

View File

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

112
README.md
View File

@ -1,104 +1,44 @@
# <img src="./program_info/org.unmojang.FjordLauncher.svg" alt="Fjord Launcher logo" width="96"/> Fjord Launcher <p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="/program_info/shatteredprism-header.svg">
<source media="(prefers-color-scheme: light)" srcset="/program_info/shatteredprism-header.svg">
<img alt="ShatteredPrism" src="/program_info/shatteredprism-header.svg" width="40%">
</picture>
</p>
Fjord Launcher is a **fork** of [Prism Launcher](https://github.com/PrismLauncher/PrismLauncher). It was based on [PollyMC](https://github.com/fn2006/PollyMC), which is now unmaintained. It is **not** endorsed by or affiliated with Prism Launcher or PollyMC. <p align="center">
Shattered Prism is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.<br />
<br />This is a <b>fork</b> of FjordLauncher and is <b>not</b> endorsed by it or Prism.
</p>
## Advantages of this fork over Prism Launcher ## Why does this exist?
- [Support for alternative auth servers](doc/alternative-auth-servers.md) This project was originally a direct fork of upstream Prism, but spent most of it's time as a small group-oriented continuation of fn2006's PollyMC, except with continued support for Microsoft authentication and being without branding that would get it confused for a uh... *similarly named project*. Luckily though, [@evan-goode](https://github.com/evan-goode) eventually created Fjord and this project has been based upon it ever since!
## Differences from PrismLauncher
- Ability to download FTB modpacks from within the launcher - Fully removed PrismLauncher's DRM.
- Restores the ability to download modpacks from FTB.
- [Support for alternative auth servers](doc/alternative-auth-servers.md).
## Having a problem with the launcher?
You **will not** open an issue in the Prism Launcher repo.
You **will not** ask about Fjord Launcher in the Prism Launcher discord.
You **will** ask in #fjord-launcher in our [Matrix space](https://matrix.to/#/#unmojang:matrix.org).
You **will** open an issue [here](https://github.com/unmojang/FjordLauncher/issues).
## Installation ## Installation
### Windows - Downloads can be found on the [GitHub Releases](https://github.com/LunaisLazier/ShatteredPrism/releases).
- Last build status can be found in the [GitHub Actions](https://github.com/LunaisLazier/ShatteredPrism/actions) tab (this also includes the pull requests status).
#### [Scoop](https://scoop.sh) (recommended) ## Community & Support
```PowerShell Feel free to create a GitHub issue if you find a bug or want to suggest something.
scoop bucket add unmojang https://github.com/unmojang/scoop-unmojang
scoop install unmojang/fjordlauncher
```
#### Windows (Manual) For any other project-related inquiries, reach me at either my [Bluesky](https://bsky.app/profile/moonlitvtuber.org) or [Twitter](https://twitter.com/lunasc_ope).
You can get installers or portable builds from the [releases section](https://github.com/unmojang/FjordLauncher/releases/latest), MSVC builds are recommended over MinGW builds, but there's no real difference. Do **not** ask for support on any of the official PrismLauncher channels, please refer to the FjordLauncher ones **only** if the issue is shared between these two projects.
### macOS ## License [![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?label=License&logo=gnu&color=C4282D)](LICENSE)
#### [Homebrew](https://brew.sh) (recommended) All launcher code is available under the GPL-3.0-only license.
```Shell The logo and related assets are under the CC BY-NC-SA 4.0 license.
brew tap unmojang/homebrew-unmojang
brew install --cask fjordlauncher
```
#### macOS (Manual)
There are builds for macOS in the [releases section](https://github.com/unmojang/FjordLauncher/releases/latest).
### Flatpak
```Shell
flatpak remote-add --user --if-not-exists unmojang https://unmojang.github.io/unmojang-flatpak/index.flatpakrepo
flatpak install org.unmojang.FjordLauncher
```
### Arch Linux
Fjord Launcher is [available](https://aur.archlinux.org/packages?O=0&K=fjordlauncher) from the AUR:
```Shell
paru -S fjordlauncher
paru -S fjordlauncher-git # build latest Git commit from source
```
`fjordlauncher` is available in [Chaotic-AUR](https://aur.chaotic.cx/).
The `fjordlauncher-bin` AUR package is broken; see [https://github.com/unmojang/FjordLauncher/issues/20](https://github.com/unmojang/FjordLauncher/issues/20).
### Debian/Ubuntu
Install from the MPR with [Mist](https://docs.makedeb.org/using-the-mpr/mist-the-mpr-cli/#installing-mist):
```Shell
mist install fjordlauncher
mist install fjordlauncher-bin # binary package
mist install fjordlauncher-git # build latest Git commit from source
```
### Nix
This repository contains a Nix flake:
```Shell
nix run github:unmojang/FjordLauncher
```
See [nix/README.md](nix/README.md) for details.
### Gentoo
Install from the [unmojang overlay](https://github.com/unmojang/unmojang-overlay):
```Shell
eselect repository add unmojang-overlay git https://github.com/unmojang/unmojang-overlay
emerge --sync unmojang-overlay
emerge -av games-action/fjordlauncher
```
### Other Linux
AppImages are available in the [releases section](https://github.com/unmojang/FjordLauncher/releases/latest).
## Building ## Building

View File

@ -58,7 +58,6 @@ Config::Config()
// Version information // Version information
VERSION_MAJOR = @Launcher_VERSION_MAJOR@; VERSION_MAJOR = @Launcher_VERSION_MAJOR@;
VERSION_MINOR = @Launcher_VERSION_MINOR@; VERSION_MINOR = @Launcher_VERSION_MINOR@;
VERSION_PATCH = @Launcher_VERSION_PATCH@;
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
BUILD_ARTIFACT = "@Launcher_BUILD_ARTIFACT@"; BUILD_ARTIFACT = "@Launcher_BUILD_ARTIFACT@";
@ -137,7 +136,7 @@ Config::Config()
QString Config::versionString() const QString Config::versionString() const
{ {
return QString("%1.%2.%3").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_PATCH); return QString("%1.%2").arg(VERSION_MAJOR).arg(VERSION_MINOR);
} }
QString Config::printableVersionString() const QString Config::printableVersionString() const

View File

@ -59,8 +59,6 @@ class Config {
int VERSION_MAJOR; int VERSION_MAJOR;
/// The minor version number. /// The minor version number.
int VERSION_MINOR; int VERSION_MINOR;
/// The patch version number.
int VERSION_PATCH;
/** /**
* The version channel * The version channel
@ -181,7 +179,7 @@ class Config {
QString FMLLIBS_BASE_URL; QString FMLLIBS_BASE_URL;
QString TRANSLATION_FILES_URL; QString TRANSLATION_FILES_URL;
QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/"; QString MODPACKSCH_API_BASE_URL = "https://api.feed-the-beast.com/v1/modpacks/";
QString LEGACY_FTB_CDN_BASE_URL = "https://dist.creeper.host/FTB2/"; QString LEGACY_FTB_CDN_BASE_URL = "https://dist.creeper.host/FTB2/";

View File

@ -7,7 +7,9 @@
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>A Minecraft mod wants to access your microphone.</string> <string>A Minecraft mod wants to access your microphone.</string>
<key>NSDownloadsFolderUsageDescription</key> <key>NSDownloadsFolderUsageDescription</key>
<string>Fjord uses access to your Downloads folder to help you more quickly add mods that can't be automatically downloaded to your instance. You can change where Fjord scans for downloaded mods in Settings or the prompt that appears.</string> <string>Shattered Prism uses access to your Downloads folder to help you more quickly add mods that can't be automatically downloaded to your instance. You can change where Shattered Prism scans for downloaded mods in Settings or the prompt that appears.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Minecraft uses the local network to find and connect to LAN servers.</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
@ -55,7 +57,7 @@
<string>mrpack</string> <string>mrpack</string>
</array> </array>
<key>CFBundleTypeName</key> <key>CFBundleTypeName</key>
<string>Fjord Launcher instance</string> <string>Shattered Prism instance</string>
<key>CFBundleTypeOSTypes</key> <key>CFBundleTypeOSTypes</key>
<array> <array>
<string>TEXT</string> <string>TEXT</string>
@ -81,10 +83,10 @@
</dict> </dict>
<dict> <dict>
<key>CFBundleURLName</key> <key>CFBundleURLName</key>
<string>FjordLauncher</string> <string>ShatteredPrism</string>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>fjordlauncher</string> <string>shatteredprism</string>
</array> </array>
</dict> </dict>
</array> </array>

View File

@ -1,9 +1,4 @@
(import ( (import (fetchTarball {
let url = "https://github.com/edolstra/flake-compat/archive/ff81ac966bb2cae68946d5ed5fc4994f96d0ffec.tar.gz";
lock = builtins.fromJSON (builtins.readFile ./flake.lock); sha256 = "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=";
in }) { src = ./.; }).defaultNix
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
) { src = ./.; }).defaultNix

18
flake.lock generated
View File

@ -3,11 +3,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1696426674, "lastModified": 1733328505,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -34,11 +34,11 @@
}, },
"nix-filter": { "nix-filter": {
"locked": { "locked": {
"lastModified": 1710156097, "lastModified": 1731533336,
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=", "narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
"owner": "numtide", "owner": "numtide",
"repo": "nix-filter", "repo": "nix-filter",
"rev": "3342559a24e85fc164b295c3444e8a139924675b", "rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -49,11 +49,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1729256560, "lastModified": 1739866667,
"narHash": "sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c+cHUJwA=", "narHash": "sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0", "rev": "73cf49b8ad837ade2de76f87eb53fc85ed5d4680",
"type": "github" "type": "github"
}, },
"original": { "original": {

161
flake.nix
View File

@ -15,28 +15,6 @@
url = "github:PrismLauncher/libnbtplusplus"; url = "github:PrismLauncher/libnbtplusplus";
flake = false; flake = false;
}; };
nix-filter.url = "github:numtide/nix-filter";
/*
Inputs below this are optional and can be removed
```
{
inputs.fjordlauncher = {
url = "github:unmojang/FjordLauncher";
inputs = {
flake-compat.follows = "";
};
};
}
```
*/
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
}; };
outputs = outputs =
@ -44,9 +22,8 @@
self, self,
nixpkgs, nixpkgs,
libnbtplusplus, libnbtplusplus,
nix-filter,
...
}: }:
let let
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
@ -58,65 +35,141 @@
forAllSystems = lib.genAttrs systems; forAllSystems = lib.genAttrs systems;
nixpkgsFor = forAllSystems (system: nixpkgs.legacyPackages.${system}); nixpkgsFor = forAllSystems (system: nixpkgs.legacyPackages.${system});
in in
{ {
checks = forAllSystems ( checks = forAllSystems (
system: system:
let let
checks' = nixpkgsFor.${system}.callPackage ./nix/checks.nix { inherit self; }; pkgs = nixpkgsFor.${system};
llvm = pkgs.llvmPackages_19;
in in
lib.filterAttrs (_: lib.isDerivation) checks'
{
formatting =
pkgs.runCommand "check-formatting"
{
nativeBuildInputs = with pkgs; [
deadnix
llvm.clang-tools
markdownlint-cli
nixfmt-rfc-style
statix
];
}
''
cd ${self}
echo "Running clang-format...."
clang-format --dry-run --style='file' --Werror */**.{c,cc,cpp,h,hh,hpp}
echo "Running deadnix..."
deadnix --fail
echo "Running markdownlint..."
markdownlint --dot .
echo "Running nixfmt..."
find -type f -name '*.nix' -exec nixfmt --check {} +
echo "Running statix"
statix check .
touch $out
'';
}
); );
devShells = forAllSystems ( devShells = forAllSystems (
system: system:
let let
pkgs = nixpkgsFor.${system}; pkgs = nixpkgsFor.${system};
llvm = pkgs.llvmPackages_19;
packages' = self.packages.${system};
# Re-use our package wrapper to wrap our development environment
qt-wrapper-env = packages'.shatteredprism.overrideAttrs (old: {
name = "qt-wrapper-env";
# Required to use script-based makeWrapper below
strictDeps = true;
# We don't need/want the unwrapped Fjord package
paths = [ ];
nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [
# Ensure the wrapper is script based so it can be sourced
pkgs.makeWrapper
];
# Inspired by https://discourse.nixos.org/t/python-qt-woes/11808/10
buildCommand = ''
makeQtWrapper ${lib.getExe pkgs.runtimeShellPackage} "$out"
sed -i '/^exec/d' "$out"
'';
});
in in
{ {
default = pkgs.mkShell { default = pkgs.mkShell {
inputsFrom = [ self.packages.${system}.fjordlauncher-unwrapped ]; inputsFrom = [ packages'.shatteredprism-unwrapped ];
buildInputs = with pkgs; [
packages = with pkgs; [
ccache ccache
ninja llvm.clang-tools
]; ];
cmakeBuildType = "Debug";
cmakeFlags = [ "-GNinja" ] ++ packages'.shatteredprism.cmakeFlags;
dontFixCmake = true;
shellHook = ''
echo "Sourcing ${qt-wrapper-env}"
source ${qt-wrapper-env}
git submodule update --init --force
if [ ! -f compile_commands.json ]; then
cmakeConfigurePhase
cd ..
ln -s "$cmakeBuildDir"/compile_commands.json compile_commands.json
fi
'';
}; };
} }
); );
formatter = forAllSystems (system: nixpkgsFor.${system}.nixfmt-rfc-style); formatter = forAllSystems (system: nixpkgsFor.${system}.nixfmt-rfc-style);
overlays.default = overlays.default = final: prev: {
final: prev: shatteredprism-unwrapped = prev.callPackage ./nix/unwrapped.nix {
let inherit
version = builtins.substring 0 8 self.lastModifiedDate or "dirty"; libnbtplusplus
in self
{ ;
fjordlauncher-unwrapped = prev.callPackage ./nix/unwrapped.nix {
inherit
libnbtplusplus
nix-filter
self
version
;
};
fjordlauncher = final.callPackage ./nix/wrapper.nix { };
}; };
shatteredprism = final.callPackage ./nix/wrapper.nix { };
};
packages = forAllSystems ( packages = forAllSystems (
system: system:
let let
pkgs = nixpkgsFor.${system}; pkgs = nixpkgsFor.${system};
# Build a scope from our overlay # Build a scope from our overlay
fjordPackages = lib.makeScope pkgs.newScope (final: self.overlays.default final pkgs); shatteredPackages = lib.makeScope pkgs.newScope (final: self.overlays.default final pkgs);
# Grab our packages from it and set the default # Grab our packages from it and set the default
packages = { packages = {
inherit (fjordPackages) fjordlauncher-unwrapped fjordlauncher; inherit (shatteredPackages) shatteredprism-unwrapped shatteredprism;
default = fjordPackages.fjordlauncher; default = shatteredPackages.shatteredprism;
}; };
in in
# Only output them if they're available on the current system # Only output them if they're available on the current system
lib.filterAttrs (_: lib.meta.availableOn pkgs.stdenv.hostPlatform) packages lib.filterAttrs (_: lib.meta.availableOn pkgs.stdenv.hostPlatform) packages
); );
@ -124,16 +177,18 @@
# We put these under legacyPackages as they are meant for CI, not end user consumption # We put these under legacyPackages as they are meant for CI, not end user consumption
legacyPackages = forAllSystems ( legacyPackages = forAllSystems (
system: system:
let let
fjordPackages = self.packages.${system}; packages' = self.packages.${system};
legacyPackages = self.legacyPackages.${system}; legacyPackages' = self.legacyPackages.${system};
in in
{ {
fjordlauncher-debug = fjordPackages.fjordlauncher.override { shatteredprism-debug = packages'.shatteredprism.override {
fjordlauncher-unwrapped = legacyPackages.fjordlauncher-unwrapped-debug; shatteredprism-unwrapped = legacyPackages'.shatteredprism-unwrapped-debug;
}; };
fjordlauncher-unwrapped-debug = fjordPackages.fjordlauncher-unwrapped.overrideAttrs { shatteredprism-unwrapped-debug = packages'.shatteredprism-unwrapped.overrideAttrs {
cmakeBuildType = "Debug"; cmakeBuildType = "Debug";
dontStrip = true; dontStrip = true;
}; };

20
flatpak/flite.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "flite",
"config-opts": [
"--enable-shared",
"--with-audio=pulseaudio"
],
"no-parallel-make": true,
"sources": [
{
"type": "git",
"url": "https://github.com/festvox/flite.git",
"tag": "v2.2",
"commit": "e9e2e37c329dbe98bfeb27a1828ef9a71fa84f88",
"x-checker-data": {
"type": "git",
"tag-pattern": "^v([\\d.]+)$"
}
}
]
}

View File

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

View File

@ -1,11 +1,11 @@
id: org.unmojang.FjordLauncher id: org.lunaislazier.ShatteredPrism
runtime: org.kde.Platform runtime: org.kde.Platform
runtime-version: 6.7 runtime-version: '6.8'
sdk: org.kde.Sdk sdk: org.kde.Sdk
sdk-extensions: sdk-extensions:
- org.freedesktop.Sdk.Extension.openjdk17 - org.freedesktop.Sdk.Extension.openjdk17
command: fjordlauncher command: shatteredprism
finish-args: finish-args:
- --share=ipc - --share=ipc
- --socket=x11 - --socket=x11
@ -19,6 +19,12 @@ finish-args:
- --filesystem=xdg-download:ro - --filesystem=xdg-download:ro
# FTBApp import # FTBApp import
- --filesystem=~/.ftba:ro - --filesystem=~/.ftba:ro
# Userspace visibility for manual hugepages configuration
# Required for -XX:+UseLargePages
- --filesystem=/sys/kernel/mm/hugepages:ro
# Userspace visibility for transparent hugepages configuration
# Required for -XX:+UseTransparentHugePages
- --filesystem=/sys/kernel/mm/transparent_hugepage:ro
modules: modules:
# Might be needed by some Controller mods (see https://github.com/isXander/Controlify/issues/31) # Might be needed by some Controller mods (see https://github.com/isXander/Controlify/issues/31)
@ -27,11 +33,16 @@ modules:
# Needed for proper Wayland support # Needed for proper Wayland support
- libdecor.json - libdecor.json
- name: fjordlauncher # Text to Speech in the game
- flite.json
- name: shatteredprism
buildsystem: cmake-ninja buildsystem: cmake-ninja
builddir: true builddir: true
config-opts: config-opts:
- -DLauncher_BUILD_PLATFORM=flatpak - -DLauncher_BUILD_PLATFORM=flatpak
# This allows us to manage and update Java independently of this Flatpak
- -DLauncher_ENABLE_JAVA_DOWNLOADER=ON
- -DCMAKE_BUILD_TYPE=RelWithDebInfo - -DCMAKE_BUILD_TYPE=RelWithDebInfo
build-options: build-options:
env: env:
@ -47,18 +58,14 @@ modules:
config-opts: config-opts:
- -DCMAKE_BUILD_TYPE=RelWithDebInfo - -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DBUILD_SHARED_LIBS:BOOL=ON - -DBUILD_SHARED_LIBS:BOOL=ON
- -DGLFW_USE_WAYLAND:BOOL=ON - -DGLFW_BUILD_WAYLAND:BOOL=ON
- -DGLFW_BUILD_DOCS:BOOL=OFF - -DGLFW_BUILD_DOCS:BOOL=OFF
sources: sources:
- type: git - type: git
url: https://github.com/glfw/glfw.git url: https://github.com/glfw/glfw.git
commit: 3fa2360720eeba1964df3c0ecf4b5df8648a8e52 commit: 7b6aead9fb88b3623e3b3725ebb42670cbe4c579 # 3.4
- type: patch - type: patch
path: patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch path: patches/0009-Defer-setting-cursor-position-until-the-cursor-is-lo.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: cleanup:
- /include - /include
- /lib/cmake - /lib/cmake
@ -68,8 +75,8 @@ modules:
buildsystem: autotools buildsystem: autotools
sources: sources:
- type: archive - type: archive
url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.2.tar.xz url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.3.tar.xz
sha256: c8bee4790d9058bacc4b6246456c58021db58a87ddda1a9d0139bf5f18f1f240 sha256: f8dd7566adb74147fab9964680b6bbadee87cf406a7fcff51718a5e6949b841c
x-checker-data: x-checker-data:
type: anitya type: anitya
project-id: 14957 project-id: 14957
@ -91,8 +98,8 @@ modules:
sources: sources:
- type: archive - type: archive
dest-filename: gamemode.tar.gz dest-filename: gamemode.tar.gz
url: https://api.github.com/repos/FeralInteractive/gamemode/tarball/1.8.1 url: https://api.github.com/repos/FeralInteractive/gamemode/tarball/1.8.2
sha256: 969cf85b5ca3944f3e315cd73a0ee9bea4f9c968cd7d485e9f4745bc1e679c4e sha256: 2886d4ce543c78bd2a364316d5e7fd59ef06b71de63f896b37c6d3dc97658f60
x-checker-data: x-checker-data:
type: json type: json
url: https://api.github.com/repos/FeralInteractive/gamemode/releases/latest url: https://api.github.com/repos/FeralInteractive/gamemode/releases/latest
@ -135,10 +142,10 @@ modules:
buildsystem: simple buildsystem: simple
build-commands: build-commands:
- install -Dm755 prime-run /app/bin/prime-run - install -Dm755 prime-run /app/bin/prime-run
- mv /app/bin/fjordlauncher /app/bin/fjordrun - mv /app/bin/shatteredprism /app/bin/shatteredrun
- install -Dm755 fjordlauncher /app/bin/fjordlauncher - install -Dm755 shatteredprism /app/bin/shatteredprism
sources: sources:
- type: file - type: file
path: prime-run path: prime-run
- type: file - type: file
path: fjordlauncher path: shatteredprism

View File

@ -1,24 +0,0 @@
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

@ -1,17 +0,0 @@
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

@ -1,20 +0,0 @@
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,59 @@
From 9997ae55a47de469ea26f8437c30b51483abda5f Mon Sep 17 00:00:00 2001
From: Dan Klishch <danilklishch@gmail.com>
Date: Sat, 30 Sep 2023 23:38:05 -0400
Subject: Defer setting cursor position until the cursor is locked
---
src/wl_platform.h | 3 +++
src/wl_window.c | 14 ++++++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/wl_platform.h b/src/wl_platform.h
index ca34f66e..cd1f227f 100644
--- a/src/wl_platform.h
+++ b/src/wl_platform.h
@@ -403,6 +403,9 @@ typedef struct _GLFWwindowWayland
int scaleSize;
int compositorPreferredScale;
+ double askedCursorPosX, askedCursorPosY;
+ GLFWbool didAskForSetCursorPos;
+
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
struct zwp_confined_pointer_v1* confinedPointer;
diff --git a/src/wl_window.c b/src/wl_window.c
index 1de26558..0df16747 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -2586,8 +2586,9 @@ void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the cursor position");
+ window->wl.didAskForSetCursorPos = true;
+ window->wl.askedCursorPosX = x;
+ window->wl.askedCursorPosY = y;
}
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
@@ -2819,6 +2820,15 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener =
static void lockedPointerHandleLocked(void* userData,
struct zwp_locked_pointer_v1* lockedPointer)
{
+ _GLFWwindow* window = userData;
+
+ if (window->wl.didAskForSetCursorPos)
+ {
+ window->wl.didAskForSetCursorPos = false;
+ zwp_locked_pointer_v1_set_cursor_position_hint(window->wl.lockedPointer,
+ wl_fixed_from_double(window->wl.askedCursorPosX),
+ wl_fixed_from_double(window->wl.askedCursorPosY));
+ }
}
static void lockedPointerHandleUnlocked(void* userData,
--
2.42.0

View File

@ -1,40 +0,0 @@
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

@ -8,4 +8,4 @@ done
export PATH="${PATH}${PATH:+:}/usr/lib/extensions/vulkan/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 VK_LAYER_PATH="/usr/lib/extensions/vulkan/share/vulkan/implicit_layer.d/" export VK_LAYER_PATH="/usr/lib/extensions/vulkan/share/vulkan/implicit_layer.d/"
exec /app/bin/fjordrun "$@" exec /app/bin/shatteredrun "$@"

66
launcher/Application.cpp Normal file → Executable file
View File

@ -48,6 +48,7 @@
#include "net/PasteUpload.h" #include "net/PasteUpload.h"
#include "pathmatcher/MultiMatcher.h" #include "pathmatcher/MultiMatcher.h"
#include "pathmatcher/SimplePrefixMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h"
#include "tasks/Task.h"
#include "tools/GenericProfiler.h" #include "tools/GenericProfiler.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
#include "ui/MainWindow.h" #include "ui/MainWindow.h"
@ -165,6 +166,8 @@
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x) #define TOSTRING(x) STRINGIFY(x)
#include "onimai.h"
static const QLatin1String liveCheckFile("live.check"); static const QLatin1String liveCheckFile("live.check");
PixmapCache* PixmapCache::s_instance = nullptr; PixmapCache* PixmapCache::s_instance = nullptr;
@ -931,6 +934,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
connect(this, &Application::clickedOnDock, [this]() { this->showMainWindow(); }); connect(this, &Application::clickedOnDock, [this]() { this->showMainWindow(); });
#endif #endif
onimaiLoadLauncher(this);
connect(this, &Application::aboutToQuit, [this]() { connect(this, &Application::aboutToQuit, [this]() {
if (m_instances) { if (m_instances) {
// save any remaining instance state // save any remaining instance state
@ -948,7 +953,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// check update locks // check update locks
{ {
auto update_log_path = FS::PathCombine(m_dataPath, "logs", "fjordlauncher_update.log"); auto update_log_path = FS::PathCombine(m_dataPath, "logs", "shatteredprism_update.log");
auto update_lock = QFileInfo(FS::PathCombine(m_dataPath, ".prism_launcher_update.lock")); auto update_lock = QFileInfo(FS::PathCombine(m_dataPath, ".prism_launcher_update.lock"));
if (update_lock.exists()) { if (update_lock.exists()) {
@ -962,7 +967,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
"\n" "\n"
"This likely means that a update attempt failed. Please ensure your installation is in working order before " "This likely means that a update attempt failed. Please ensure your installation is in working order before "
"proceeding.\n" "proceeding.\n"
"Check the Fjord Launcher updater log at: \n" "Check the Shattered Prism updater log at: \n"
"%7\n" "%7\n"
"for details on the last update attempt.\n" "for details on the last update attempt.\n"
"\n" "\n"
@ -998,7 +1003,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
"\n" "\n"
"Please ensure your installation is in working order before " "Please ensure your installation is in working order before "
"proceeding.\n" "proceeding.\n"
"Check the Fjord Launcher updater log at: \n" "Check the Shattered Prism updater log at: \n"
"%1\n" "%1\n"
"for details on the last update attempt.") "for details on the last update attempt.")
.arg(update_log_path); .arg(update_log_path);
@ -1029,7 +1034,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
auto infoMsg = tr("Update succeeded\n" auto infoMsg = tr("Update succeeded\n"
"\n" "\n"
"You are now running %1 .\n" "You are now running %1 .\n"
"Check the Fjord Launcher updater log at: \n" "Check the Shattered Prism updater log at: \n"
"%2\n" "%2\n"
"for details.") "for details.")
.arg(BuildConfig.printableVersionString()) .arg(BuildConfig.printableVersionString())
@ -1092,6 +1097,9 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
bool Application::createSetupWizard() bool Application::createSetupWizard()
{ {
bool javaRequired = [&]() { bool javaRequired = [&]() {
if (BuildConfig.JAVA_DOWNLOADER_ENABLED && m_settings->get("AutomaticJavaDownload").toBool()) {
return false;
}
bool ignoreJavaWizard = m_settings->get("IgnoreJavaWizard").toBool(); bool ignoreJavaWizard = m_settings->get("IgnoreJavaWizard").toBool();
if (ignoreJavaWizard) { if (ignoreJavaWizard) {
return false; return false;
@ -1104,10 +1112,7 @@ bool Application::createSetupWizard()
} }
QString currentJavaPath = settings()->get("JavaPath").toString(); QString currentJavaPath = settings()->get("JavaPath").toString();
QString actualPath = FS::ResolveExecutable(currentJavaPath); QString actualPath = FS::ResolveExecutable(currentJavaPath);
if (actualPath.isNull()) { return actualPath.isNull();
return true;
}
return false;
}(); }();
bool askjava = BuildConfig.JAVA_DOWNLOADER_ENABLED && !javaRequired && !m_settings->get("AutomaticJavaDownload").toBool() && bool askjava = BuildConfig.JAVA_DOWNLOADER_ENABLED && !javaRequired && !m_settings->get("AutomaticJavaDownload").toBool() &&
!m_settings->get("AutomaticJavaSwitch").toBool() && !m_settings->get("UserAskedAboutAutomaticJavaDownload").toBool(); !m_settings->get("AutomaticJavaSwitch").toBool() && !m_settings->get("UserAskedAboutAutomaticJavaDownload").toBool();
@ -1116,6 +1121,7 @@ bool Application::createSetupWizard()
bool validWidgets = m_themeManager->isValidApplicationTheme(settings()->get("ApplicationTheme").toString()); bool validWidgets = m_themeManager->isValidApplicationTheme(settings()->get("ApplicationTheme").toString());
bool validIcons = m_themeManager->isValidIconTheme(settings()->get("IconTheme").toString()); bool validIcons = m_themeManager->isValidIconTheme(settings()->get("IconTheme").toString());
bool login = !m_accounts->anyAccountIsValid() && capabilities() & Application::SupportsMSA; bool login = !m_accounts->anyAccountIsValid() && capabilities() & Application::SupportsMSA;
login = false;
bool themeInterventionRequired = !validWidgets || !validIcons; bool themeInterventionRequired = !validWidgets || !validIcons;
bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired || askjava || login; bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired || askjava || login;
if (wizardRequired) { if (wizardRequired) {
@ -1249,7 +1255,7 @@ void Application::performMainStartupAction()
msgBox.setWindowTitle(tr("Fetch CurseForge Core API key?")); msgBox.setWindowTitle(tr("Fetch CurseForge Core API key?"));
msgBox.setText(tr("Would you like to fetch the official CurseForge app's API key now?")); msgBox.setText(tr("Would you like to fetch the official CurseForge app's API key now?"));
msgBox.setInformativeText( msgBox.setInformativeText(
tr("Using the official CurseForge app's API key may break CurseForge's terms of service but should allow Fjord Launcher " tr("Using the official CurseForge app's API key may break CurseForge's terms of service but should allow Shattered Prism "
"to download all mods in a modpack without you needing to download any of them manually.")); "to download all mods in a modpack without you needing to download any of them manually."));
msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setDefaultButton(QMessageBox::Yes);
@ -1426,6 +1432,7 @@ bool Application::launch(InstancePtr instance, bool online, bool demo, Minecraft
if (m_updateRunning) { if (m_updateRunning) {
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
} else if (instance->canLaunch()) { } else if (instance->canLaunch()) {
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[instance->id()]; auto& extras = m_instanceExtras[instance->id()];
auto window = extras.window; auto window = extras.window;
if (window) { if (window) {
@ -1450,7 +1457,7 @@ bool Application::launch(InstancePtr instance, bool online, bool demo, Minecraft
connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed);
connect(controller.get(), &LaunchController::aborted, this, [this] { controllerFailed(tr("Aborted")); }); connect(controller.get(), &LaunchController::aborted, this, [this] { controllerFailed(tr("Aborted")); });
addRunningInstance(); addRunningInstance();
controller->start(); QMetaObject::invokeMethod(controller.get(), &Task::start, Qt::QueuedConnection);
return true; return true;
} else if (instance->isRunning()) { } else if (instance->isRunning()) {
showInstanceWindow(instance, "console"); showInstanceWindow(instance, "console");
@ -1468,9 +1475,11 @@ bool Application::kill(InstancePtr instance)
qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running.";
return false; return false;
} }
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[instance->id()]; auto& extras = m_instanceExtras[instance->id()];
// NOTE: copy of the shared pointer keeps it alive // NOTE: copy of the shared pointer keeps it alive
auto controller = extras.controller; auto controller = extras.controller;
locker.unlock();
if (controller) { if (controller) {
return controller->abort(); return controller->abort();
} }
@ -1524,12 +1533,14 @@ void Application::controllerSucceeded()
if (!controller) if (!controller)
return; return;
auto id = controller->id(); auto id = controller->id();
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[id]; auto& extras = m_instanceExtras[id];
// on success, do... // on success, do...
if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) { if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) {
if (extras.window) { if (extras.window) {
extras.window->close(); QMetaObject::invokeMethod(extras.window, &QWidget::close, Qt::QueuedConnection);
} }
} }
extras.controller.reset(); extras.controller.reset();
@ -1549,6 +1560,7 @@ void Application::controllerFailed(const QString& error)
if (!controller) if (!controller)
return; return;
auto id = controller->id(); auto id = controller->id();
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[id]; auto& extras = m_instanceExtras[id];
// on failure, do... nothing // on failure, do... nothing
@ -1606,6 +1618,7 @@ InstanceWindow* Application::showInstanceWindow(InstancePtr instance, QString pa
if (!instance) if (!instance)
return nullptr; return nullptr;
auto id = instance->id(); auto id = instance->id();
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[id]; auto& extras = m_instanceExtras[id];
auto& window = extras.window; auto& window = extras.window;
@ -1643,6 +1656,7 @@ void Application::on_windowClose()
m_openWindows--; m_openWindows--;
auto instWindow = qobject_cast<InstanceWindow*>(QObject::sender()); auto instWindow = qobject_cast<InstanceWindow*>(QObject::sender());
if (instWindow) { if (instWindow) {
QMutexLocker locker(&m_instanceExtrasMutex);
auto& extras = m_instanceExtras[instWindow->instanceId()]; auto& extras = m_instanceExtras[instWindow->instanceId()];
extras.window = nullptr; extras.window = nullptr;
if (extras.controller) { if (extras.controller) {
@ -1890,7 +1904,7 @@ bool Application::handleDataMigration(const QString& currentData,
matcher->add(std::make_shared<SimplePrefixMatcher>("themes/")); matcher->add(std::make_shared<SimplePrefixMatcher>("themes/"));
ProgressDialog diag; ProgressDialog diag;
DataMigrationTask task(nullptr, oldData, currentData, matcher); DataMigrationTask task(oldData, currentData, matcher);
if (diag.execWithTask(&task)) { if (diag.execWithTask(&task)) {
qDebug() << "<> Migration succeeded"; qDebug() << "<> Migration succeeded";
setDoNotMigrate(); setDoNotMigrate();
@ -1929,3 +1943,31 @@ const QString Application::javaPath()
{ {
return m_settings->get("JavaDir").toString(); return m_settings->get("JavaDir").toString();
} }
void Application::addQSavePath(QString path)
{
QMutexLocker locker(&m_qsaveResourcesMutex);
m_qsaveResources[path] = m_qsaveResources.value(path, 0) + 1;
}
void Application::removeQSavePath(QString path)
{
QMutexLocker locker(&m_qsaveResourcesMutex);
auto count = m_qsaveResources.value(path, 0) - 1;
if (count <= 0) {
m_qsaveResources.remove(path);
} else {
m_qsaveResources[path] = count;
}
}
bool Application::checkQSavePath(QString path)
{
QMutexLocker locker(&m_qsaveResourcesMutex);
for (auto partialPath : m_qsaveResources.keys()) {
if (path.startsWith(partialPath) && m_qsaveResources.value(partialPath, 0) > 0) {
return true;
}
}
return false;
}

11
launcher/Application.h Normal file → Executable file
View File

@ -42,6 +42,7 @@
#include <QDebug> #include <QDebug>
#include <QFlag> #include <QFlag>
#include <QIcon> #include <QIcon>
#include <QMutex>
#include <QUrl> #include <QUrl>
#include <memory> #include <memory>
@ -278,6 +279,7 @@ class Application : public QApplication {
shared_qobject_ptr<LaunchController> controller; shared_qobject_ptr<LaunchController> controller;
}; };
std::map<QString, InstanceXtras> m_instanceExtras; std::map<QString, InstanceXtras> m_instanceExtras;
mutable QMutex m_instanceExtrasMutex;
// main state variables // main state variables
size_t m_openWindows = 0; size_t m_openWindows = 0;
@ -303,4 +305,13 @@ class Application : public QApplication {
QList<QUrl> m_urlsToImport; QList<QUrl> m_urlsToImport;
QString m_instanceIdToShowWindowOf; QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile; std::unique_ptr<QFile> logFile;
public:
void addQSavePath(QString);
void removeQSavePath(QString);
bool checkQSavePath(QString);
private:
QHash<QString, int> m_qsaveResources;
mutable QMutex m_qsaveResourcesMutex;
}; };

0
launcher/ApplicationMessage.cpp Normal file → Executable file
View File

0
launcher/ApplicationMessage.h Normal file → Executable file
View File

0
launcher/BaseInstaller.cpp Normal file → Executable file
View File

0
launcher/BaseInstaller.h Normal file → Executable file
View File

2
launcher/BaseInstance.cpp Normal file → Executable file
View File

@ -58,6 +58,8 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_global_settings = globalSettings; m_global_settings = globalSettings;
m_rootDir = rootDir; m_rootDir = rootDir;
qDebug() << "BaseInstance: " << rootDir;
m_settings->registerSetting("name", "Unnamed Instance"); m_settings->registerSetting("name", "Unnamed Instance");
m_settings->registerSetting("iconKey", "default"); m_settings->registerSetting("iconKey", "default");
m_settings->registerSetting("notes", ""); m_settings->registerSetting("notes", "");

0
launcher/BaseInstance.h Normal file → Executable file
View File

0
launcher/BaseVersion.h Normal file → Executable file
View File

0
launcher/BaseVersionList.cpp Normal file → Executable file
View File

0
launcher/BaseVersionList.h Normal file → Executable file
View File

2
launcher/CMakeLists.txt Normal file → Executable file
View File

@ -5,6 +5,7 @@ project(application)
######## Sources and headers ######## ######## Sources and headers ########
set(CORE_SOURCES set(CORE_SOURCES
onimai.cpp
# LOGIC - Base classes and infrastructure # LOGIC - Base classes and infrastructure
BaseInstaller.h BaseInstaller.h
BaseInstaller.cpp BaseInstaller.cpp
@ -30,6 +31,7 @@ set(CORE_SOURCES
StringUtils.cpp StringUtils.cpp
QVariantUtils.h QVariantUtils.h
RuntimeContext.h RuntimeContext.h
PSaveFile.h
# Basic instance manipulation tasks (derived from InstanceTask) # Basic instance manipulation tasks (derived from InstanceTask)
InstanceCreationTask.h InstanceCreationTask.h

0
launcher/Commandline.cpp Normal file → Executable file
View File

0
launcher/Commandline.h Normal file → Executable file
View File

7
launcher/DataMigrationTask.cpp Normal file → Executable file
View File

@ -12,11 +12,8 @@
#include <QtConcurrent> #include <QtConcurrent>
DataMigrationTask::DataMigrationTask(QObject* parent, DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathMatcher)
const QString& sourcePath, : Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
const QString& targetPath,
const IPathMatcher::Ptr pathMatcher)
: Task(parent), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
{ {
m_copy.matcher(m_pathMatcher.get()).whitelist(true); m_copy.matcher(m_pathMatcher.get()).whitelist(true);
} }

2
launcher/DataMigrationTask.h Normal file → Executable file
View File

@ -18,7 +18,7 @@
class DataMigrationTask : public Task { class DataMigrationTask : public Task {
Q_OBJECT Q_OBJECT
public: public:
explicit DataMigrationTask(QObject* parent, const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher); explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher);
~DataMigrationTask() override = default; ~DataMigrationTask() override = default;
protected: protected:

0
launcher/DefaultVariable.h Normal file → Executable file
View File

0
launcher/DesktopServices.cpp Normal file → Executable file
View File

0
launcher/DesktopServices.h Normal file → Executable file
View File

0
launcher/Exception.h Normal file → Executable file
View File

0
launcher/ExponentialSeries.h Normal file → Executable file
View File

0
launcher/FastFileIconProvider.cpp Normal file → Executable file
View File

0
launcher/FastFileIconProvider.h Normal file → Executable file
View File

0
launcher/FileIgnoreProxy.cpp Normal file → Executable file
View File

0
launcher/FileIgnoreProxy.h Normal file → Executable file
View File

22
launcher/FileSystem.cpp Normal file → Executable file
View File

@ -45,7 +45,6 @@
#include <QDirIterator> #include <QDirIterator>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QSaveFile>
#include <QStandardPaths> #include <QStandardPaths>
#include <QStorageInfo> #include <QStorageInfo>
#include <QTextStream> #include <QTextStream>
@ -54,6 +53,7 @@
#include <system_error> #include <system_error>
#include "DesktopServices.h" #include "DesktopServices.h"
#include "PSaveFile.h"
#include "StringUtils.h" #include "StringUtils.h"
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
@ -191,8 +191,8 @@ void ensureExists(const QDir& dir)
void write(const QString& filename, const QByteArray& data) void write(const QString& filename, const QByteArray& data)
{ {
ensureExists(QFileInfo(filename).dir()); ensureExists(QFileInfo(filename).dir());
QSaveFile file(filename); PSaveFile file(filename);
if (!file.open(QSaveFile::WriteOnly)) { if (!file.open(PSaveFile::WriteOnly)) {
throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString()); throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString());
} }
if (data.size() != file.write(data)) { if (data.size() != file.write(data)) {
@ -213,8 +213,8 @@ void appendSafe(const QString& filename, const QByteArray& data)
buffer = QByteArray(); buffer = QByteArray();
} }
buffer.append(data); buffer.append(data);
QSaveFile file(filename); PSaveFile file(filename);
if (!file.open(QSaveFile::WriteOnly)) { if (!file.open(PSaveFile::WriteOnly)) {
throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString()); throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString());
} }
if (buffer.size() != file.write(buffer)) { if (buffer.size() != file.write(buffer)) {
@ -971,8 +971,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
if (!args.empty()) if (!args.empty())
argstring = " \"" + args.join("\" \"") + "\""; argstring = " \"" + args.join("\" \"") + "\"";
stream << "#!/bin/bash" stream << "#!/bin/bash" << "\n";
<< "\n";
stream << "\"" << target << "\" " << argstring << "\n"; stream << "\"" << target << "\" " << argstring << "\n";
stream.flush(); stream.flush();
@ -1016,12 +1015,9 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
if (!args.empty()) if (!args.empty())
argstring = " '" + args.join("' '") + "'"; argstring = " '" + args.join("' '") + "'";
stream << "[Desktop Entry]" stream << "[Desktop Entry]" << "\n";
<< "\n"; stream << "Type=Application" << "\n";
stream << "Type=Application" stream << "Categories=Game;ActionGame;AdventureGame;Simulation" << "\n";
<< "\n";
stream << "Categories=Game;ActionGame;AdventureGame;Simulation"
<< "\n";
stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n"; stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n"; stream << "Name=" << name.toLocal8Bit() << "\n";
if (!icon.isEmpty()) { if (!icon.isEmpty()) {

0
launcher/FileSystem.h Normal file → Executable file
View File

0
launcher/Filter.cpp Normal file → Executable file
View File

0
launcher/Filter.h Normal file → Executable file
View File

0
launcher/GZip.cpp Normal file → Executable file
View File

0
launcher/GZip.h Normal file → Executable file
View File

0
launcher/GetAuthlibInjectorApiLocation.cpp Normal file → Executable file
View File

0
launcher/GetAuthlibInjectorApiLocation.h Normal file → Executable file
View File

0
launcher/InstanceCopyPrefs.cpp Normal file → Executable file
View File

0
launcher/InstanceCopyPrefs.h Normal file → Executable file
View File

0
launcher/InstanceCopyTask.cpp Normal file → Executable file
View File

0
launcher/InstanceCopyTask.h Normal file → Executable file
View File

4
launcher/InstanceCreationTask.cpp Normal file → Executable file
View File

@ -61,6 +61,6 @@ void InstanceCreationTask::executeTask()
return; return;
} }
} }
if (!m_abort)
emitSucceeded(); emitSucceeded();
} }

0
launcher/InstanceCreationTask.h Normal file → Executable file
View File

68
launcher/InstanceImportTask.cpp Normal file → Executable file
View File

@ -69,9 +69,11 @@ bool InstanceImportTask::abort()
if (!canAbort()) if (!canAbort())
return false; return false;
if (task) bool wasAborted = false;
task->abort(); if (m_task)
return Task::abort(); wasAborted = m_task->abort();
Task::abort();
return wasAborted;
} }
void InstanceImportTask::executeTask() void InstanceImportTask::executeTask()
@ -104,7 +106,7 @@ void InstanceImportTask::downloadFromUrl()
connect(filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::emitFailed); connect(filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::emitFailed);
connect(filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::emitAborted); connect(filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::emitAborted);
task.reset(filesNetJob); m_task.reset(filesNetJob);
filesNetJob->start(); filesNetJob->start();
} }
@ -157,7 +159,7 @@ void InstanceImportTask::processZipPack()
} }
QuaZipDir packZipDir(packZip.get()); QuaZipDir packZipDir(packZip.get());
qDebug() << "Attempting to determine instance type"; qDebug() << "Attempting to determine instance type ";
QString root; QString root;
@ -193,7 +195,7 @@ void InstanceImportTask::processZipPack()
stepProgress(*progressStep); stepProgress(*progressStep);
}); });
connect(zipTask.get(), &Task::succeeded, this, &InstanceImportTask::extractFinished); connect(zipTask.get(), &Task::succeeded, this, &InstanceImportTask::extractFinished, Qt::QueuedConnection);
connect(zipTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted); connect(zipTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
progressStep->state = TaskStepState::Failed; progressStep->state = TaskStepState::Failed;
@ -210,12 +212,13 @@ void InstanceImportTask::processZipPack()
progressStep->status = status; progressStep->status = status;
stepProgress(*progressStep); stepProgress(*progressStep);
}); });
task.reset(zipTask); m_task.reset(zipTask);
zipTask->start(); zipTask->start();
} }
void InstanceImportTask::extractFinished() void InstanceImportTask::extractFinished()
{ {
setAbortable(false);
QDir extractDir(m_stagingPath); QDir extractDir(m_stagingPath);
qDebug() << "Fixing permissions for extracted pack files..."; qDebug() << "Fixing permissions for extracted pack files...";
@ -241,6 +244,8 @@ void InstanceImportTask::extractFinished()
} }
} }
qDebug() << "extractFinished " << static_cast<int>(m_modpackType);
switch (m_modpackType) { switch (m_modpackType) {
case ModpackType::MultiMC: case ModpackType::MultiMC:
processMultiMC(); processMultiMC();
@ -289,8 +294,11 @@ void InstanceImportTask::processFlame()
inst_creation_task->setGroup(m_instGroup); inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
connect(inst_creation_task.get(), &Task::succeeded, this, [this, inst_creation_task] { auto weak = inst_creation_task.toWeakRef();
setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded(); emitSucceeded();
}); });
connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
@ -299,11 +307,12 @@ void InstanceImportTask::processFlame()
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);
connect(this, &Task::aborted, inst_creation_task.get(), &InstanceCreationTask::abort);
connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort); connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort);
connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable); connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
inst_creation_task->start(); m_task.reset(inst_creation_task);
setAbortable(true);
m_task->start();
} }
void InstanceImportTask::processTechnic() void InstanceImportTask::processTechnic()
@ -319,6 +328,8 @@ void InstanceImportTask::processMultiMC()
QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg"); QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
auto instanceSettings = std::make_shared<INISettingsObject>(configPath); auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
qDebug() << "processMultiMC: " << m_stagingPath;
NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath); NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
// reset time played on import... because packs. // reset time played on import... because packs.
@ -327,6 +338,8 @@ void InstanceImportTask::processMultiMC()
// set a new nice name // set a new nice name
instance.setName(name()); instance.setName(name());
qDebug() << "processMultiMC2 " << instance.instanceRoot() << name();
// if the icon was specified by user, use that. otherwise pull icon from the pack // if the icon was specified by user, use that. otherwise pull icon from the pack
if (m_instIcon != "default") { if (m_instIcon != "default") {
instance.setIconKey(m_instIcon); instance.setIconKey(m_instIcon);
@ -350,7 +363,7 @@ void InstanceImportTask::processMultiMC()
void InstanceImportTask::processModrinth() void InstanceImportTask::processModrinth()
{ {
ModrinthCreationTask* inst_creation_task = nullptr; shared_qobject_ptr<ModrinthCreationTask> inst_creation_task = nullptr;
if (!m_extra_info.isEmpty()) { if (!m_extra_info.isEmpty()) {
auto pack_id_it = m_extra_info.constFind("pack_id"); auto pack_id_it = m_extra_info.constFind("pack_id");
Q_ASSERT(pack_id_it != m_extra_info.constEnd()); Q_ASSERT(pack_id_it != m_extra_info.constEnd());
@ -367,7 +380,7 @@ void InstanceImportTask::processModrinth()
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = inst_creation_task =
new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); makeShared<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()) {
@ -376,7 +389,7 @@ void InstanceImportTask::processModrinth()
} }
// FIXME: Find a way to get the ID in directly imported ZIPs // FIXME: Find a way to get the ID in directly imported ZIPs
inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id); inst_creation_task = makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id);
} }
inst_creation_task->setName(*this); inst_creation_task->setName(*this);
@ -384,20 +397,23 @@ void InstanceImportTask::processModrinth()
inst_creation_task->setGroup(m_instGroup); inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
connect(inst_creation_task, &Task::succeeded, this, [this, inst_creation_task] { auto weak = inst_creation_task.toWeakRef();
setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded(); emitSucceeded();
}); });
connect(inst_creation_task, &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task, &Task::progress, this, &InstanceImportTask::setProgress); connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task, &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task, &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(inst_creation_task, &Task::finished, inst_creation_task, &InstanceCreationTask::deleteLater);
connect(this, &Task::aborted, inst_creation_task, &InstanceCreationTask::abort); connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort);
connect(inst_creation_task, &Task::aborted, this, &Task::abort); connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(inst_creation_task, &Task::abortStatusChanged, this, &Task::setAbortable);
inst_creation_task->start(); m_task.reset(inst_creation_task);
setAbortable(true);
m_task->start();
} }

7
launcher/InstanceImportTask.h Normal file → Executable file
View File

@ -40,16 +40,13 @@
#include <QUrl> #include <QUrl>
#include "InstanceTask.h" #include "InstanceTask.h"
#include <memory>
#include <optional>
class QuaZip; class QuaZip;
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 = {});
virtual ~InstanceImportTask() = default;
bool abort() override; bool abort() override;
protected: protected:
@ -70,7 +67,7 @@ class InstanceImportTask : public InstanceTask {
private: /* data */ private: /* data */
QUrl m_sourceUrl; QUrl m_sourceUrl;
QString m_archivePath; QString m_archivePath;
Task::Ptr task; Task::Ptr m_task;
enum class ModpackType { enum class ModpackType {
Unknown, Unknown,
MultiMC, MultiMC,

5
launcher/InstanceList.cpp Normal file → Executable file
View File

@ -449,6 +449,7 @@ QList<InstanceId> InstanceList::discoverInstances()
out.append(id); out.append(id);
qDebug() << "Found instance ID" << id; qDebug() << "Found instance ID" << id;
} }
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
instanceSet = QSet<QString>(out.begin(), out.end()); instanceSet = QSet<QString>(out.begin(), out.end());
#else #else
@ -977,6 +978,7 @@ QString InstanceList::getStagedInstancePath()
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
SetFileAttributesA(tempRoot.toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); SetFileAttributesA(tempRoot.toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
#endif #endif
qDebug() << "get Debug" << result;
return result; return result;
} }
@ -994,7 +996,7 @@ bool InstanceList::commitStagedInstance(const QString& path,
auto should_override = commiting.shouldOverride(); auto should_override = commiting.shouldOverride();
if (should_override) { if (should_override) {
instID = commiting.originalInstanceID(); instID = instanceName.modifiedName();
} else { } else {
instID = FS::DirNameFromString(instanceName.modifiedName(), m_instDir); instID = FS::DirNameFromString(instanceName.modifiedName(), m_instDir);
} }
@ -1010,6 +1012,7 @@ bool InstanceList::commitStagedInstance(const QString& path,
qWarning() << "Failed to override" << path << "to" << destination; qWarning() << "Failed to override" << path << "to" << destination;
return false; return false;
} }
FS::deletePath(path);
} else { } else {
if (!FS::move(path, destination)) { if (!FS::move(path, destination)) {
qWarning() << "Failed to move" << path << "to" << destination; qWarning() << "Failed to move" << path << "to" << destination;

0
launcher/InstanceList.h Normal file → Executable file
View File

0
launcher/InstancePageProvider.h Normal file → Executable file
View File

0
launcher/InstanceTask.cpp Normal file → Executable file
View File

31
launcher/InstanceTask.h Normal file → Executable file
View File

@ -30,26 +30,31 @@ struct InstanceName {
}; };
class InstanceTask : public Task, public InstanceName { class InstanceTask : public Task, public InstanceName {
Q_OBJECT Q_OBJECT
public: public:
InstanceTask(); InstanceTask();
~InstanceTask() override = default; ~InstanceTask() override = default;
void setParentSettings(SettingsObjectPtr settings) { m_globalSettings = settings; } void setParentSettings(SettingsObjectPtr settings) { m_globalSettings = settings; }
void setStagingPath(const QString& stagingPath) { m_stagingPath = stagingPath; } void setStagingPath(const QString& stagingPath) { m_stagingPath = stagingPath; }
void setIcon(const QString& icon) { m_instIcon = icon; } void setIcon(const QString& icon) { m_instIcon = icon; }
void setGroup(const QString& group) { m_instGroup = group; } void setGroup(const QString& group) { m_instGroup = group; }
QString group() const { return m_instGroup; } QString group() const { return m_instGroup; }
[[nodiscard]] bool shouldConfirmUpdate() const { return m_confirm_update; } [[nodiscard]] bool shouldConfirmUpdate() const { return m_confirm_update; }
void setConfirmUpdate(bool confirm) { m_confirm_update = confirm; } void setConfirmUpdate(bool confirm) { m_confirm_update = confirm; }
bool shouldOverride() const { return m_override_existing; } bool shouldOverride() const { return m_override_existing; }
[[nodiscard]] QString originalInstanceID() const { return m_original_instance_id; }; [[nodiscard]] QString originalInstanceID() const { return m_original_instance_id; };
void setShouldOverride(bool should)
{
m_override_existing = should;
}
protected: protected:
void setOverride(bool override, QString instance_id_to_override = {}) void setOverride(bool override, QString instance_id_to_override = {})

4
launcher/JavaCommon.cpp Normal file → Executable file
View File

@ -116,7 +116,7 @@ void JavaCommon::TestCheck::run()
emit finished(); emit finished();
return; return;
} }
checker.reset(new JavaChecker(m_path, "", 0, 0, 0, 0, this)); checker.reset(new JavaChecker(m_path, "", 0, 0, 0, 0));
connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinished); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinished);
checker->start(); checker->start();
} }
@ -128,7 +128,7 @@ void JavaCommon::TestCheck::checkFinished(const JavaChecker::Result& result)
emit finished(); emit finished();
return; return;
} }
checker.reset(new JavaChecker(m_path, m_args, m_maxMem, m_maxMem, result.javaVersion.requiresPermGen() ? m_permGen : 0, 0, this)); checker.reset(new JavaChecker(m_path, m_args, m_maxMem, m_maxMem, result.javaVersion.requiresPermGen() ? m_permGen : 0, 0));
connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinishedWithArgs); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinishedWithArgs);
checker->start(); checker->start();
} }

0
launcher/JavaCommon.h Normal file → Executable file
View File

0
launcher/Json.cpp Normal file → Executable file
View File

0
launcher/Json.h Normal file → Executable file
View File

0
launcher/KonamiCode.cpp Normal file → Executable file
View File

0
launcher/KonamiCode.h Normal file → Executable file
View File

6
launcher/LaunchController.cpp Normal file → Executable file
View File

@ -64,7 +64,7 @@
#include "launch/steps/TextPrint.h" #include "launch/steps/TextPrint.h"
#include "tasks/Task.h" #include "tasks/Task.h"
LaunchController::LaunchController(QObject* parent) : Task(parent) {} LaunchController::LaunchController() : Task() {}
void LaunchController::executeTask() void LaunchController::executeTask()
{ {
@ -92,8 +92,8 @@ void LaunchController::decideAccount()
if (accounts->count() <= 0 || !accounts->anyAccountIsValid()) { if (accounts->count() <= 0 || !accounts->anyAccountIsValid()) {
// 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(m_parentWidget, tr("No Accounts"), auto reply = CustomMessageBox::selectable(m_parentWidget, tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Microsoft " tr("In order to play Minecraft, you must choose a username or "
"account which owns Minecraft logged in. " "have an account logged in. "
"Would you like to open the account manager to add an account now?"), "Would you like to open the account manager to add an account now?"),
QMessageBox::Information, QMessageBox::Yes | QMessageBox::No) QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)
->exec(); ->exec();

2
launcher/LaunchController.h Normal file → Executable file
View File

@ -49,7 +49,7 @@ class LaunchController : public Task {
public: public:
void executeTask() override; void executeTask() override;
LaunchController(QObject* parent = nullptr); LaunchController();
virtual ~LaunchController() = default; virtual ~LaunchController() = default;
void setInstance(InstancePtr instance) { m_instance = instance; } void setInstance(InstancePtr instance) { m_instance = instance; }

View File

@ -39,8 +39,16 @@ if [ "x$DEPS_LIST" = "x" ]; then
# Just to be sure... # Just to be sure...
chmod +x "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" chmod +x "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}"
ARGS=("${LAUNCHER_DIR}/${LAUNCHER_NAME}" "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}")
if [ -f portable.txt ]; then
ARGS+=("-d" "${LAUNCHER_DIR}")
fi
ARGS+=("$@")
# Run the launcher # Run the launcher
exec -a "${LAUNCHER_DIR}/${LAUNCHER_NAME}" "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@" exec -a "${ARGS[@]}"
# Run the launcher in valgrind # Run the launcher in valgrind
# valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@" # valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@"

0
launcher/LoggedProcess.cpp Normal file → Executable file
View File

0
launcher/LoggedProcess.h Normal file → Executable file
View File

7
launcher/Logging.cpp Normal file
View File

@ -0,0 +1,7 @@
// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT!
#include "Logging.h"
Q_LOGGING_CATEGORY(authCredentials, "launcher.auth.credentials", QtWarningMsg)

11
launcher/Logging.h Normal file
View File

@ -0,0 +1,11 @@
// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT!
#ifndef ECM_QLOGGINGCATEGORY_AUTHCREDENTIALS_LOGGING_H
#define ECM_QLOGGINGCATEGORY_AUTHCREDENTIALS_LOGGING_H
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(authCredentials)
#endif

0
launcher/MMCTime.cpp Normal file → Executable file
View File

0
launcher/MMCTime.h Normal file → Executable file
View File

8
launcher/MMCZip.cpp Normal file → Executable file
View File

@ -378,7 +378,7 @@ std::optional<QStringList> extractDir(QString fileCompressed, QString dir)
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 unpacking:" << fileCompressed << "Error:" << zip.getZipError();
; ;
return std::nullopt; return std::nullopt;
} }
@ -395,7 +395,7 @@ std::optional<QStringList> extractDir(QString fileCompressed, QString subdir, QS
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 unpacking:" << fileCompressed << "Error:" << zip.getZipError();
; ;
return std::nullopt; return std::nullopt;
} }
@ -412,7 +412,7 @@ bool extractFile(QString fileCompressed, QString file, QString target)
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 unpacking:" << fileCompressed << "Error:" << zip.getZipError();
return false; return false;
} }
return extractRelFile(&zip, file, target); return extractRelFile(&zip, file, target);
@ -577,7 +577,7 @@ auto ExtractZipTask::extractZip() -> ZipResult
auto relative_file_name = QDir::fromNativeSeparators(file_name.mid(m_subdirectory.size())); auto relative_file_name = QDir::fromNativeSeparators(file_name.mid(m_subdirectory.size()));
auto original_name = relative_file_name; auto original_name = relative_file_name;
setStatus("Unziping: " + relative_file_name); setStatus("Unpacking: " + relative_file_name);
// Fix subdirs/files ending with a / getting transformed into absolute paths // Fix subdirs/files ending with a / getting transformed into absolute paths
if (relative_file_name.startsWith('/')) if (relative_file_name.startsWith('/'))

0
launcher/MMCZip.h Normal file → Executable file
View File

0
launcher/MTPixmapCache.h Normal file → Executable file
View File

10388
launcher/Makefile Executable file

File diff suppressed because it is too large Load Diff

0
launcher/MangoHud.cpp Normal file → Executable file
View File

0
launcher/MangoHud.h Normal file → Executable file
View File

0
launcher/Manifest.cpp Normal file → Executable file
View File

0
launcher/Manifest.h Normal file → Executable file
View File

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