mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-08-10 00:52:16 +00:00
Compare commits
327 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dfbcfdbc4 | ||
|
|
e113ac6918 | ||
|
|
77deff12a6 | ||
|
|
e5d5256aed | ||
|
|
956341930b | ||
|
|
032680ca9d | ||
|
|
446825b73d | ||
|
|
0d100a57a6 | ||
|
|
55a225d21c | ||
|
|
ae12424279 | ||
|
|
3c223eb289 | ||
|
|
9ac1e3dcd6 | ||
|
|
a21e231cae | ||
|
|
2c4e293e21 | ||
|
|
1b45b57d07 | ||
|
|
905904960d | ||
|
|
48559a5876 | ||
|
|
d2461e1908 | ||
|
|
f8819d32e3 | ||
|
|
09dff34105 | ||
|
|
16e2789197 | ||
|
|
08ac580bc6 | ||
|
|
cdfcdf2dc7 | ||
|
|
fb7c9e22ff | ||
|
|
b2c5da2cfc | ||
|
|
98d61b16f6 | ||
|
|
df6e15f1f7 | ||
|
|
6cc13b8ef6 | ||
|
|
592f3a70a3 | ||
|
|
9155e39e91 | ||
|
|
142f06714f | ||
|
|
a3e2c4fa31 | ||
|
|
8b507d2b30 | ||
|
|
0698210ce1 | ||
|
|
d33e3a2882 | ||
|
|
bcd5188ac5 | ||
|
|
1f2ad8da00 | ||
|
|
5a60090ddc | ||
|
|
3bb784b379 | ||
|
|
35b660851c | ||
|
|
d625dda4ea | ||
|
|
9181028bcf | ||
|
|
fa6c279efc | ||
|
|
9d6d59aa55 | ||
|
|
9df6283da4 | ||
|
|
c8c80807da | ||
|
|
3f202be09a | ||
|
|
4b642f6e01 | ||
|
|
da390c37db | ||
|
|
7242202291 | ||
|
|
f213aae7b8 | ||
|
|
bfd1e81a25 | ||
|
|
c81aa99c38 | ||
|
|
c4c0413f9e | ||
|
|
49fc618682 | ||
|
|
1fbbab9df7 | ||
|
|
7f6383833c | ||
|
|
4ef97c755a | ||
|
|
fa14b6ead7 | ||
|
|
42f6634e85 | ||
|
|
e88dec22ee | ||
|
|
f44ae4cc8d | ||
|
|
3510b8636a | ||
|
|
9fe539f87d | ||
|
|
4fc444b5b3 | ||
|
|
5480d3d59d | ||
|
|
696a11942c | ||
|
|
43d47c6f3c | ||
|
|
b405888088 | ||
|
|
3771062499 | ||
|
|
44ad28ebf4 | ||
|
|
5477f58f18 | ||
|
|
7dbd5b41b2 | ||
|
|
f210b89dd7 | ||
|
|
6ff236727f | ||
|
|
3af1744c9b | ||
|
|
b2fe0423d2 | ||
|
|
009975dc7b | ||
|
|
23ef23159a | ||
|
|
d51afbe19d | ||
|
|
a26877a917 | ||
|
|
6607062648 | ||
|
|
77d3a7e2ab | ||
|
|
7770b5f708 | ||
|
|
e2fce257b5 | ||
|
|
c95f54f874 | ||
|
|
9b6d0b7a06 | ||
|
|
effa98f76a | ||
|
|
65574a02d4 | ||
|
|
5980e520b9 | ||
|
|
00aa23b342 | ||
|
|
f1c225fccc | ||
|
|
08cb5fc2f2 | ||
|
|
1a929cc37b | ||
|
|
c72aeef67b | ||
|
|
76896eba88 | ||
|
|
1c1a7fa8c0 | ||
|
|
ff883058e6 | ||
|
|
a3922d9eef | ||
|
|
cc688c7845 | ||
|
|
997e8c6e5a | ||
|
|
e410426257 | ||
|
|
30a790ba40 | ||
|
|
052297a1a5 | ||
|
|
12efe96297 | ||
|
|
952e142ffa | ||
|
|
0439d7a83a | ||
|
|
76ffa2a0b5 | ||
|
|
f9963ed39b | ||
|
|
a7a9df3b9d | ||
|
|
cfe7129100 | ||
|
|
97b1790d0c | ||
|
|
9ae46e1325 | ||
|
|
e5dedbbe46 | ||
|
|
17cd230c55 | ||
|
|
a5213c6225 | ||
|
|
248b1bfa19 | ||
|
|
0c6d0edacf | ||
|
|
03b62730ae | ||
|
|
91f4f15c49 | ||
|
|
3b53734eab | ||
|
|
2dc150761c | ||
|
|
8aaf9fd141 | ||
|
|
8b3b00059e | ||
|
|
e00aa4f0f3 | ||
|
|
a95a553970 | ||
|
|
d6db10afb4 | ||
|
|
8ad7af86c0 | ||
|
|
dc5571ba98 | ||
|
|
88a450bf1f | ||
|
|
27919697a7 | ||
|
|
a996902a33 | ||
|
|
ad20572dde | ||
|
|
f4a48f44e4 | ||
|
|
c7fe8f65bd | ||
|
|
215c86455f | ||
|
|
05f5370efe | ||
|
|
c1f0daa024 | ||
|
|
c0b042fa8a | ||
|
|
d69d540031 | ||
|
|
95437d15f3 | ||
|
|
cbb5ec3f29 | ||
|
|
c3ec53c0ae | ||
|
|
5adbd2988c | ||
|
|
1e037db7bd | ||
|
|
bb092c0723 | ||
|
|
1041f87a5d | ||
|
|
2b1514b547 | ||
|
|
8a99187562 | ||
|
|
b1ac4bc57c | ||
|
|
6c5a323b4a | ||
|
|
dfb8d9d87f | ||
|
|
7a23d6aa81 | ||
|
|
302bf58631 | ||
|
|
66f1ac664a | ||
|
|
223e87f30b | ||
|
|
633f0035c2 | ||
|
|
66f46ab341 | ||
|
|
f4edce318c | ||
|
|
a54830cf39 | ||
|
|
63c105bfb1 | ||
|
|
a1d07ff0e0 | ||
|
|
5e6a42abb2 | ||
|
|
3fd38b3a2e | ||
|
|
cb406bce06 | ||
|
|
a4a5d30603 | ||
|
|
5e40248fdf | ||
|
|
08d623ce44 | ||
|
|
12f1ec6b25 | ||
|
|
8c8a7bb886 | ||
|
|
37c0f794b0 | ||
|
|
fe1321f33c | ||
|
|
5b239c17d0 | ||
|
|
c60ebb76b9 | ||
|
|
6f369398b3 | ||
|
|
84fdc7ee08 | ||
|
|
e8aa7499af | ||
|
|
a7b19f48fe | ||
|
|
a6e47ff033 | ||
|
|
dbe56ee583 | ||
|
|
ed5ee24efb | ||
|
|
97716fa0c8 | ||
|
|
7648496b89 | ||
|
|
5ed17fb89d | ||
|
|
e39d9bc662 | ||
|
|
d912cce5ba | ||
|
|
fbd6807eb8 | ||
|
|
f0cfc4aa8a | ||
|
|
67a569c0b8 | ||
|
|
981d878082 | ||
|
|
4c1371aaeb | ||
|
|
9af770e217 | ||
|
|
4cbf8c01d2 | ||
|
|
8132c82b07 | ||
|
|
4a924acbc3 | ||
|
|
390c664e84 | ||
|
|
01b8ba353a | ||
|
|
66615a0be0 | ||
|
|
e924e2eedb | ||
|
|
4190667d94 | ||
|
|
0bdb887e2c | ||
|
|
92f5c49685 | ||
|
|
89a0109fa7 | ||
|
|
cf2de6e81e | ||
|
|
6a2a485435 | ||
|
|
b310436bdb | ||
|
|
bea78dd3eb | ||
|
|
447a00936b | ||
|
|
ca3bab3242 | ||
|
|
e1b112cafd | ||
|
|
949506208e | ||
|
|
84ae033a37 | ||
|
|
8509ee72c3 | ||
|
|
8a853fc79d | ||
|
|
c665e211cd | ||
|
|
1e6d9da2d6 | ||
|
|
71d249b32e | ||
|
|
bfdcfbb357 | ||
|
|
660d8e191c | ||
|
|
5af39cbbb0 | ||
|
|
f34e3b03fb | ||
|
|
4428054d03 | ||
|
|
b210356dfd | ||
|
|
1905163b26 | ||
|
|
3cab7e1067 | ||
|
|
42a990a12b | ||
|
|
5f3a466631 | ||
|
|
e1efdadce1 | ||
|
|
2183f8eb0f | ||
|
|
3df9f3de17 | ||
|
|
cf5460bd80 | ||
|
|
3113de6bfe | ||
|
|
6e9aac3b83 | ||
|
|
f932d6c18c | ||
|
|
d0ce0a67f2 | ||
|
|
a82a9f8ada | ||
|
|
548eeb8889 | ||
|
|
dcdd716a57 | ||
|
|
dc491fa5d4 | ||
|
|
322da7ea30 | ||
|
|
a043dfcf6c | ||
|
|
3ee511cabb | ||
|
|
c9c93a265a | ||
|
|
b484060831 | ||
|
|
894cb6507e | ||
|
|
4769a9348b | ||
|
|
7ad91e2dab | ||
|
|
c1b4dccd7e | ||
|
|
166f9f73e0 | ||
|
|
1295096568 | ||
|
|
db55ff8ea1 | ||
|
|
88d67277f6 | ||
|
|
83c8a460e1 | ||
|
|
cc0ac47f29 | ||
|
|
272368b59c | ||
|
|
87856862dd | ||
|
|
b5ec178cd6 | ||
|
|
49afefc43f | ||
|
|
e2bb1a720a | ||
|
|
cd89808a21 | ||
|
|
9f0af0f8ae | ||
|
|
afd52ba5e0 | ||
|
|
87f01fc0b8 | ||
|
|
952d961871 | ||
|
|
ef2ca538a3 | ||
|
|
f9b2686547 | ||
|
|
35cdc2c89b | ||
|
|
3baace6711 | ||
|
|
afe661db56 | ||
|
|
b6ae848bb5 | ||
|
|
64b52205ab | ||
|
|
93315f280e | ||
|
|
9b66a5a16b | ||
|
|
09c9a1a16b | ||
|
|
b4703efbef | ||
|
|
264c9272df | ||
|
|
79ce11fe72 | ||
|
|
9213037ad4 | ||
|
|
25a64bff44 | ||
|
|
f51a84c9ec | ||
|
|
907798f9da | ||
|
|
7f53388304 | ||
|
|
43525415fd | ||
|
|
96b3bf30f6 | ||
|
|
8e63b2523a | ||
|
|
e1f0e3a719 | ||
|
|
6800fc00f4 | ||
|
|
e0f2d3affc | ||
|
|
ac1feb386c | ||
|
|
de091570b9 | ||
|
|
99f9174353 | ||
|
|
b40d414346 | ||
|
|
eedcd49713 | ||
|
|
418d3cc76c | ||
|
|
cf6107971d | ||
|
|
62af7d255c | ||
|
|
d4a4096bba | ||
|
|
5e5ae0b4b8 | ||
|
|
636a928fc0 | ||
|
|
5f9101f72d | ||
|
|
f9040a55d5 | ||
|
|
674a9da166 | ||
|
|
2298cbbe20 | ||
|
|
58ed5ba3ce | ||
|
|
f7d4f49809 | ||
|
|
43fa4100d2 | ||
|
|
b3a1615170 | ||
|
|
b421c8e2e9 | ||
|
|
977a4d3d4a | ||
|
|
642c4a9ed7 | ||
|
|
83ea433857 | ||
|
|
0ac67f13d7 | ||
|
|
f32387f67e | ||
|
|
6980ee36b3 | ||
|
|
e04ed497a6 | ||
|
|
7b8abc49e2 | ||
|
|
53bd9ea82b | ||
|
|
adeb99f8c2 | ||
|
|
65b557d003 | ||
|
|
ccd568af3e | ||
|
|
749bfa89ef | ||
|
|
663a92ce33 | ||
|
|
8b0e6a28c2 | ||
|
|
9a95ce5132 | ||
|
|
7dc8546c25 | ||
|
|
30c178baa1 | ||
|
|
911035c711 |
@@ -1,3 +1,4 @@
|
||||
---
|
||||
# This file is centrally managed in https://github.com/<organization>/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
@@ -6,7 +7,7 @@
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignOperands: Align
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
@@ -14,7 +15,7 @@ AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Always
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
@@ -62,7 +63,7 @@ SpaceBeforeParens: Never
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
|
||||
18
.dockerignore
Normal file
18
.dockerignore
Normal file
@@ -0,0 +1,18 @@
|
||||
# ignore git files
|
||||
.git*
|
||||
|
||||
# ignore hidden files
|
||||
.*
|
||||
|
||||
# ignore repo directories and files
|
||||
docs/
|
||||
scripts/
|
||||
tools/
|
||||
crowdin.yml
|
||||
|
||||
# ignore dev directories
|
||||
build/
|
||||
venv/
|
||||
|
||||
# ignore artifacts
|
||||
artifacts/
|
||||
3
.flake8
3
.flake8
@@ -1,6 +1,7 @@
|
||||
[flake8]
|
||||
filename =
|
||||
*.py
|
||||
*.py,
|
||||
*.pys
|
||||
max-line-length = 120
|
||||
extend-exclude =
|
||||
venv/
|
||||
|
||||
109
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
109
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -6,7 +6,29 @@ body:
|
||||
attributes:
|
||||
value: >
|
||||
**THIS IS NOT THE PLACE TO ASK FOR SUPPORT!**
|
||||
Please use [Discord](https://docs.lizardbyte.dev/en/latest/about/support.html#discord) for support issues.
|
||||
Please use our [Support Center](https://app.lizardbyte.dev/support) for support issues.
|
||||
Non actionable bug reports will be locked and closed!
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is your issue described in the documentation?
|
||||
description: Please read our [documentation](https://docs.lizardbyte.dev/projects/sunshine)
|
||||
options:
|
||||
- label: I have read the documentation
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is your issue present in the nightly release?
|
||||
description: Please test the [nightly](https://github.com/LizardByte/Sunshine/releases/tag/nightly-dev) release
|
||||
options:
|
||||
- label: This issue is present in the nightly release
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -30,10 +52,13 @@ body:
|
||||
label: Host Operating System
|
||||
description: What version operating system are you running the software on?
|
||||
options:
|
||||
- Docker
|
||||
- Linux
|
||||
- macOS
|
||||
- Windows
|
||||
- other
|
||||
- other, n/a
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-version
|
||||
attributes:
|
||||
@@ -41,26 +66,63 @@ body:
|
||||
description: Provide the version of the operating system. Additionally a build number would be helpful.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
- type: dropdown
|
||||
id: os-architecture
|
||||
attributes:
|
||||
label: Architecture
|
||||
placeholder: e.g. 32 bit, 64 bit, arm
|
||||
options:
|
||||
- 32 bit
|
||||
- 64 bit
|
||||
- arm
|
||||
- other, n/a
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Sunshine Version
|
||||
placeholder: eg. 0.14.0
|
||||
label: Sunshine commit or version
|
||||
placeholder: eg. 0.18.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
- type: dropdown
|
||||
id: package_type
|
||||
attributes:
|
||||
label: Package
|
||||
description: The package you installed
|
||||
options:
|
||||
- Linux - AppImage
|
||||
- Linux - AUR (Third Party)
|
||||
- Linux - deb
|
||||
- Linux - Docker
|
||||
- Linux - flatpak
|
||||
- Linux - nixpkgs (Third Party)
|
||||
- Linux - PKGBUILD
|
||||
- Linux - pkg.tar.zst
|
||||
- Linux - rpm
|
||||
- Linux - solus (Third Party)
|
||||
- macOS - dmg
|
||||
- macOS - Portfile
|
||||
- macOS - pkg
|
||||
- Windows - Chocolatey (Third Party)
|
||||
- Windows - installer
|
||||
- Windows - portable
|
||||
- Windows - Scoop (Third Party)
|
||||
- Windows - Winget (Third Party)
|
||||
- other (not listed)
|
||||
- other (self built)
|
||||
- other (fork of this repo)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: graphics_type
|
||||
attributes:
|
||||
label: GPU Type
|
||||
description: The type of the installed graphics card.
|
||||
placeholder: e.g. Intel, AMD, Nvidia
|
||||
options:
|
||||
- AMD
|
||||
- Intel
|
||||
- Nvidia
|
||||
- none (software encoding)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
@@ -83,8 +145,26 @@ body:
|
||||
id: capture_method
|
||||
attributes:
|
||||
label: Capture Method (Linux Only)
|
||||
description: The driver/mesa version of the installed graphics card.
|
||||
placeholder: e.g. PipeWire/KVM/X11
|
||||
description: If on Linux, the capture method being used.
|
||||
placeholder: e.g. PipeWire/KVM/X11/KMS
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Config
|
||||
description: |
|
||||
Please copy and paste your config (`sunshine.conf`) file.
|
||||
render: Shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: apps
|
||||
attributes:
|
||||
label: Apps
|
||||
description: |
|
||||
If this is an issue with launching a game or app, please copy and paste your `apps.json` file.
|
||||
render: json
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
@@ -94,9 +174,6 @@ body:
|
||||
description: |
|
||||
Please copy and paste any relevant log output. This will be automatically formatted into code,
|
||||
so no need for backticks.
|
||||
render: Shell
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Make sure to close your issue when it's solved! If you found the solution yourself please comment
|
||||
so that others benefit from it.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
14
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -5,15 +5,9 @@
|
||||
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discord support
|
||||
url: https://docs.lizardbyte.dev/about/support.html#discord
|
||||
about: Ask questions in Discord
|
||||
- name: Reddit support
|
||||
url: https://www.reddit.com/r/LizardByte
|
||||
about: Get community support on Reddit
|
||||
- name: Facebook support
|
||||
url: https://www.facebook.com/groups/lizardbyte
|
||||
about: Get community support on Facebook
|
||||
- name: Support Center
|
||||
url: https://app.lizardbyte.dev/support
|
||||
about: Official LizardByte support
|
||||
- name: Feature request
|
||||
url: https://feedback.lizardbyte.dev
|
||||
url: https://app.lizardbyte.dev/feedback
|
||||
about: Share your suggestions or ideas to help us improve
|
||||
|
||||
30
.github/dependabot.yml
vendored
30
.github/dependabot.yml
vendored
@@ -5,11 +5,19 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "08:00"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "00:00"
|
||||
time: "08:30"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
@@ -17,7 +25,15 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "00:00"
|
||||
time: "09:00"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "nuget"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "09:30"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
@@ -25,6 +41,14 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "00:00"
|
||||
time: "10:00"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "10:30"
|
||||
target-branch: "nightly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
4
.github/label-actions.yml
vendored
4
.github/label-actions.yml
vendored
@@ -25,8 +25,8 @@ invalid:duplicate:
|
||||
invalid:support:
|
||||
comment: >
|
||||
:wave: @{issue-author}, we use the issue tracker exclusively for bug reports.
|
||||
However, this issue appears to be a support request. Please use
|
||||
[Discord](https://docs.lizardbyte.dev/about/support.html#discord) for support issues. Thanks.
|
||||
However, this issue appears to be a support request. Please use our
|
||||
[Support Center](https://app.lizardbyte.dev/support) for support issues. Thanks.
|
||||
close: true
|
||||
lock: true
|
||||
lock-reason: 'off-topic'
|
||||
|
||||
6
.github/pr_release_template.md
vendored
6
.github/pr_release_template.md
vendored
@@ -17,8 +17,12 @@ This PR was created automatically.
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Dependency update (updates to dependencies)
|
||||
- [ ] Documentation update (changes to documentation)
|
||||
- [ ] Repository update (changes to repository files)
|
||||
- [ ] Repository update (changes to repository files, e.g. `.github/...`)
|
||||
|
||||
## Branch Updates
|
||||
- [x] I want maintainers to keep my branch updated
|
||||
|
||||
## Changelog Summary
|
||||
<!--- Summarize all the changes in a bulleted list. --->
|
||||
|
||||
22
.github/pull_request_template.md
vendored
22
.github/pull_request_template.md
vendored
@@ -1,22 +0,0 @@
|
||||
## Description
|
||||
<!--- Please include a summary of the changes. --->
|
||||
|
||||
### Screenshot
|
||||
<!--- Include screenshots if the changes are UI-related. --->
|
||||
|
||||
### Issues Fixed or Closed
|
||||
<!--- Delete if not relevant. --->
|
||||
- Fixes #(issue)
|
||||
|
||||
## Type of Change
|
||||
<!--- Please delete options that are not relevant. --->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
|
||||
## Checklist
|
||||
<!--- DO NOT delete any options here. It is okay to have items unchecked! --->
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have added or updated the docstring/documentation-blocks for new or existing methods/components
|
||||
486
.github/workflows/CI.yml
vendored
486
.github/workflows/CI.yml
vendored
@@ -6,9 +6,13 @@ on:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [master, nightly]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
github_env:
|
||||
name: GitHub Env Debug
|
||||
@@ -26,6 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Verify Changelog
|
||||
@@ -66,114 +71,89 @@ jobs:
|
||||
"project(Sunshine [VERSION ${{ needs.check_changelog.outputs.next_version_bare }}]"
|
||||
exit 1
|
||||
|
||||
build_linux_aur:
|
||||
name: Linux AUR
|
||||
runs-on: ubuntu-latest
|
||||
setup_release:
|
||||
name: Setup Release
|
||||
needs: check_changelog
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Dependencies Linux AUR
|
||||
- name: Set release details
|
||||
id: release_details
|
||||
env:
|
||||
RELEASE_BODY: ${{ needs.check_changelog.outputs.release_body }}
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
cmake
|
||||
|
||||
- name: Configure PKGBUILD files
|
||||
run: |
|
||||
# variables for manifest
|
||||
echo "aur_publish=false" >> $GITHUB_ENV
|
||||
aur_pkg=sunshine-dev
|
||||
sub_version=""
|
||||
conflicts="'sunshine'"
|
||||
provides="'sunshine'"
|
||||
|
||||
branch=${GITHUB_HEAD_REF}
|
||||
|
||||
# check the branch variable
|
||||
if [ -z "$branch" ]
|
||||
then
|
||||
echo "This is a PUSH event"
|
||||
commit=${{ github.sha }}
|
||||
clone_url=${{ github.event.repository.clone_url }}
|
||||
|
||||
if [[ ${{ github.ref == 'refs/heads/master' }} ]]; then
|
||||
aur_pkg=sunshine
|
||||
conflicts=""
|
||||
provides=""
|
||||
|
||||
echo "aur_publish=true" >> $GITHUB_ENV
|
||||
elif [[ ${{ github.ref == 'refs/heads/nightly' }} ]]; then
|
||||
aur_pkg=sunshine-git
|
||||
sub_version=".r${commit}"
|
||||
|
||||
echo "aur_publish=true" >> $GITHUB_ENV
|
||||
fi
|
||||
# determine to create a release or not
|
||||
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
|
||||
RELEASE=true
|
||||
else
|
||||
echo "This is a PR event"
|
||||
commit=${{ github.event.pull_request.head.sha }}
|
||||
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
|
||||
|
||||
sub_version=".r${commit}"
|
||||
RELEASE=false
|
||||
fi
|
||||
echo "Commit: ${commit}"
|
||||
echo "Clone URL: ${clone_url}"
|
||||
|
||||
echo "aur_pkg=${aur_pkg}" >> $GITHUB_ENV
|
||||
# set the release tag
|
||||
COMMIT=${{ github.sha }}
|
||||
if [[ $GITHUB_REF == refs/heads/master ]]; then
|
||||
TAG="${{ needs.check_changelog.outputs.next_version }}"
|
||||
RELEASE_NAME="${{ needs.check_changelog.outputs.next_version }}"
|
||||
RELEASE_BODY="$RELEASE_BODY"
|
||||
PRE_RELEASE="false"
|
||||
elif [[ $GITHUB_REF == refs/heads/nightly ]]; then
|
||||
TAG="nightly-dev"
|
||||
RELEASE_NAME="nightly"
|
||||
RELEASE_BODY="automated nightly release - $(date -u +'%Y-%m-%dT%H:%M:%SZ') - ${COMMIT}"
|
||||
PRE_RELEASE="true"
|
||||
fi
|
||||
|
||||
mkdir -p artifacts
|
||||
mkdir -p build
|
||||
echo "create_release=${RELEASE}" >> $GITHUB_OUTPUT
|
||||
echo "release_tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
echo "release_commit=${COMMIT}" >> $GITHUB_OUTPUT
|
||||
echo "release_name=${RELEASE_NAME}" >> $GITHUB_OUTPUT
|
||||
echo "pre_release=${PRE_RELEASE}" >> $GITHUB_OUTPUT
|
||||
|
||||
cd build
|
||||
cmake -DSUNSHINE_CONFIGURE_AUR=ON \
|
||||
-DSUNSHINE_AUR_PKG=${aur_pkg} \
|
||||
-DSUNSHINE_SUB_VERSION=${sub_version} \
|
||||
-DSUNSHINE_AUR_CONFLICTS=${conflicts} \
|
||||
-DSUNSHINE_AUR_PROVIDES=${provides} \
|
||||
-DGITHUB_CLONE_URL=${clone_url} \
|
||||
-DGITHUB_COMMIT=${commit} \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON \
|
||||
..
|
||||
cd ..
|
||||
# this is stupid but works for multiline strings
|
||||
echo "RELEASE_BODY<<EOF" >> $GITHUB_ENV
|
||||
echo "$RELEASE_BODY" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
mv ./build/PKGBUILD ./artifacts/
|
||||
outputs:
|
||||
create_release: ${{ steps.release_details.outputs.create_release }}
|
||||
release_tag: ${{ steps.release_details.outputs.release_tag }}
|
||||
release_commit: ${{ steps.release_details.outputs.release_commit }}
|
||||
release_name: ${{ steps.release_details.outputs.release_name }}
|
||||
release_body: ${{ env.RELEASE_BODY }}
|
||||
pre_release: ${{ steps.release_details.outputs.pre_release }}
|
||||
|
||||
- name: Validate package
|
||||
uses: hapakaien/archlinux-package-action@v2.2.0
|
||||
with:
|
||||
path: artifacts
|
||||
flags: '--syncdeps --noconfirm'
|
||||
namcap: true
|
||||
srcinfo: true
|
||||
aur: true # workaround mirror problem
|
||||
setup_flatpak_matrix:
|
||||
name: Setup Flatpak Matrix
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set release details
|
||||
id: flatpak_matrix
|
||||
# https://www.cynkra.com/blog/2020-12-23-dynamic-gha
|
||||
run: |
|
||||
# determine which architectures to build
|
||||
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
|
||||
matrix=$((
|
||||
echo '{ "arch" : ["x86_64", "aarch64"] }'
|
||||
) | jq -c .)
|
||||
else
|
||||
matrix=$((
|
||||
echo '{ "arch" : ["x86_64"] }'
|
||||
) | jq -c .)
|
||||
fi
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: sunshine-linux-aur
|
||||
path: artifacts/
|
||||
echo $matrix
|
||||
echo $matrix | jq .
|
||||
echo "matrix=$matrix" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish AUR package
|
||||
if: ${{ env.aur_publish == 'true' }}
|
||||
uses: KSXGitHub/github-actions-deploy-aur@v2.4.1
|
||||
with:
|
||||
pkgname: ${{ env.aur_pkg }}
|
||||
pkgbuild: ./artifacts/PKGBUILD
|
||||
assets: |
|
||||
./artifacts/*
|
||||
commit_username: ${{ secrets.AUR_USERNAME }}
|
||||
commit_email: ${{ secrets.AUR_EMAIL }}
|
||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
commit_message: Automatic update from GitHub ${{ github.repository }} per ${{ github.ref }}
|
||||
allow_empty_commits: false
|
||||
outputs:
|
||||
matrix: ${{ steps.flatpak_matrix.outputs.matrix }}
|
||||
|
||||
build_linux_flatpak:
|
||||
name: Linux Flatpak
|
||||
runs-on: ubuntu-latest
|
||||
needs: check_changelog
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [setup_release, setup_flatpak_matrix]
|
||||
strategy:
|
||||
fail-fast: false # false to test all, true to fail entire job if any fail
|
||||
matrix: ${{fromJson(needs.setup_flatpak_matrix.outputs.matrix)}}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -181,14 +161,29 @@ jobs:
|
||||
|
||||
- name: Setup Dependencies Linux Flatpak
|
||||
run: |
|
||||
PLATFORM_VERSION=21.08
|
||||
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
cmake \
|
||||
flatpak
|
||||
sudo su $(whoami) -c 'flatpak remote-add --user --if-not-exists flathub \
|
||||
https://flathub.org/repo/flathub.flatpakrepo'
|
||||
sudo su $(whoami) -c 'flatpak install --user flathub \
|
||||
org.flatpak.Builder org.freedesktop.Platform//21.08 org.freedesktop.Sdk//21.08 -y'
|
||||
flatpak \
|
||||
qemu-user-static
|
||||
sudo su $(whoami) -c "flatpak --user remote-add --if-not-exists flathub \
|
||||
https://flathub.org/repo/flathub.flatpakrepo"
|
||||
sudo su $(whoami) -c "flatpak --user install -y flathub \
|
||||
org.flatpak.Builder \
|
||||
org.freedesktop.Platform/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
org.freedesktop.Sdk/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
org.freedesktop.Sdk.Extension.node18/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
"
|
||||
|
||||
- name: Cache Flatpak build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./build/.flatpak-builder
|
||||
key: flatpak-${{ matrix.arch }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
flatpak-${{ matrix.arch }}-
|
||||
|
||||
- name: Configure Flatpak Manifest
|
||||
run: |
|
||||
@@ -218,50 +213,56 @@ jobs:
|
||||
cmake -DGITHUB_CLONE_URL=${clone_url} \
|
||||
-DGITHUB_BRANCH=${branch} \
|
||||
-DGITHUB_COMMIT=${commit} \
|
||||
-DSUNSHINE_CONFIGURE_FLATPAK=ON \
|
||||
-DSUNSHINE_CONFIGURE_FLATPAK_MAN=ON \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON \
|
||||
..
|
||||
|
||||
- name: Build Linux Flatpak
|
||||
working-directory: build
|
||||
run: |
|
||||
sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --repo=repo --force-clean build-sunshine \
|
||||
dev.lizardbyte.sunshine.yml'
|
||||
sudo su $(whoami) -c 'flatpak build-bundle ./repo ../artifacts/sunshine.flatpak dev.lizardbyte.sunshine'
|
||||
sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \
|
||||
--stop-at=cuda build-sunshine dev.lizardbyte.sunshine.yml'
|
||||
cp -r .flatpak-builder copy-of-flatpak-builder
|
||||
sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \
|
||||
build-sunshine dev.lizardbyte.sunshine.yml'
|
||||
rm -rf .flatpak-builder
|
||||
mv copy-of-flatpak-builder .flatpak-builder
|
||||
sudo su $(whoami) -c 'flatpak build-bundle --arch=${{ matrix.arch }} ./repo \
|
||||
../artifacts/sunshine_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine'
|
||||
sudo su $(whoami) -c 'flatpak build-bundle --runtime --arch=${{ matrix.arch }} ./repo \
|
||||
../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine.Debug'
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: sunshine-linux-flatpak
|
||||
name: sunshine-linux-flatpak-${{ matrix.arch }}
|
||||
path: artifacts/
|
||||
|
||||
- name: Create Release
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: LizardByte/.github/actions/create_release@master
|
||||
- name: Create/Update GitHub Release
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ needs.setup_release.outputs.release_name }}
|
||||
tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
artifacts: "*artifacts/*"
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
next_version: ${{ needs.check_changelog.outputs.next_version }}
|
||||
last_version: ${{ needs.check_changelog.outputs.last_version }}
|
||||
release_body: ${{ needs.check_changelog.outputs.release_body }}
|
||||
allowUpdates: true
|
||||
body: ${{ needs.setup_release.outputs.release_body }}
|
||||
discussionCategory: announcements
|
||||
prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
build_linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-20.04
|
||||
needs: check_changelog
|
||||
runs-on: ubuntu-${{ matrix.dist }}
|
||||
needs: [check_changelog, setup_release]
|
||||
strategy:
|
||||
fail-fast: false # false to test all, true to fail entire job if any fail
|
||||
matrix:
|
||||
include: # package these differently
|
||||
- type: cpack
|
||||
CMAKE_INSTALL_PREFIX: '/usr'
|
||||
SUNSHINE_ASSETS_DIR: 'local/sunshine/assets'
|
||||
SUNSHINE_CONFIG_DIR: 'local/sunshine/config'
|
||||
EXTRA_ARGS: ''
|
||||
- type: appimage
|
||||
CMAKE_INSTALL_PREFIX: '/usr'
|
||||
SUNSHINE_ASSETS_DIR: 'sunshine.AppImage.config'
|
||||
SUNSHINE_CONFIG_DIR: 'sunshine.AppImage.home'
|
||||
EXTRA_ARGS: '-DSUNSHINE_CONFIGURE_APPIMAGE=ON'
|
||||
dist: 20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -271,27 +272,62 @@ jobs:
|
||||
|
||||
- name: Setup Dependencies Linux
|
||||
run: |
|
||||
sudo add-apt-repository ppa:savoury1/ffmpeg4 -y
|
||||
# sudo add-apt-repository ppa:savoury1/boost-defaults-1.71 -y
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
|
||||
sudo apt-get update -y
|
||||
if [[ ${{ matrix.dist }} == "18.04" ]]; then
|
||||
# Ubuntu 18.04 packages
|
||||
sudo add-apt-repository ppa:savoury1/boost-defaults-1.71 -y
|
||||
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
libboost-filesystem1.71-dev \
|
||||
libboost-log1.71-dev \
|
||||
libboost-regex1.71-dev \
|
||||
libboost-thread1.71-dev \
|
||||
libboost-program-options1.71-dev
|
||||
|
||||
# Install cmake
|
||||
wget https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh
|
||||
chmod +x cmake-3.22.2-linux-x86_64.sh
|
||||
mkdir /opt/cmake
|
||||
./cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license
|
||||
ln --force --symbolic /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
cmake --version
|
||||
|
||||
# install newer tar from focal... appimagelint fails on 18.04 without this
|
||||
echo "original tar version"
|
||||
tar --version
|
||||
wget -O tar.deb http://security.ubuntu.com/ubuntu/pool/main/t/tar/tar_1.30+dfsg-7ubuntu0.20.04.2_amd64.deb
|
||||
sudo apt-get -y install -f ./tar.deb
|
||||
echo "new tar version"
|
||||
tar --version
|
||||
else
|
||||
# Ubuntu 20.04+ packages
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
cmake \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libboost-program-options-dev
|
||||
fi
|
||||
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
gcc-10 \
|
||||
git \
|
||||
g++-10 \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libcap-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libmfx-dev \
|
||||
libnuma-dev \
|
||||
libopus-dev \
|
||||
libpulse-dev \
|
||||
libssl-dev \
|
||||
libva-dev \
|
||||
libvdpau-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
@@ -301,51 +337,39 @@ jobs:
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
wget
|
||||
# # Ubuntu 20.04+ packages
|
||||
# libboost-filesystem-dev
|
||||
# libboost-log-dev
|
||||
# libboost-thread-dev
|
||||
|
||||
# # Ubuntu 18.04 packages
|
||||
# libboost-filesystem1.71-dev \
|
||||
# libboost-log1.71-dev \
|
||||
# libboost-regex1.71-dev \
|
||||
# libboost-thread1.71-dev \
|
||||
|
||||
# clean apt cache
|
||||
sudo apt-get clean
|
||||
sudo rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Update gcc alias
|
||||
# https://stackoverflow.com/a/70653945/11214013
|
||||
sudo update-alternatives --install \
|
||||
/usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
||||
/usr/bin/gcc gcc /usr/bin/gcc-10 100 \
|
||||
--slave /usr/bin/g++ g++ /usr/bin/g++-10 \
|
||||
--slave /usr/bin/gcov gcov /usr/bin/gcov-10 \
|
||||
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-10 \
|
||||
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-10
|
||||
|
||||
# Install CuDA
|
||||
# Install CUDA
|
||||
sudo wget \
|
||||
https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run \
|
||||
https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run \
|
||||
--progress=bar:force:noscroll -q --show-progress -O /root/cuda.run
|
||||
sudo chmod a+x /root/cuda.run
|
||||
sudo /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm
|
||||
sudo rm /root/cuda.run
|
||||
|
||||
# # Install cmake (necessary for 18.04)
|
||||
# wget https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh
|
||||
# chmod +x cmake-3.22.2-linux-x86_64.sh
|
||||
# mkdir /opt/cmake
|
||||
# ./cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license
|
||||
# ln --force --symbolic /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
# cmake --version
|
||||
|
||||
- name: Build Linux
|
||||
run: |
|
||||
mkdir -p build
|
||||
mkdir -p artifacts
|
||||
|
||||
npm install
|
||||
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${{ matrix.CMAKE_INSTALL_PREFIX }} \
|
||||
-DSUNSHINE_ASSETS_DIR=${{ matrix.SUNSHINE_ASSETS_DIR }} \
|
||||
-DSUNSHINE_CONFIG_DIR=${{ matrix.SUNSHINE_CONFIG_DIR }} \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
@@ -359,16 +383,16 @@ jobs:
|
||||
if: ${{ matrix.type == 'cpack' }}
|
||||
working-directory: build
|
||||
run: |
|
||||
# package
|
||||
cpack -G DEB
|
||||
cpack -G RPM
|
||||
mv ./cpack_artifacts/Sunshine.deb ../artifacts/sunshine-${{ matrix.dist }}.deb
|
||||
|
||||
# move
|
||||
mv ./cpack_artifacts/Sunshine.deb ../artifacts/sunshine.deb
|
||||
mv ./cpack_artifacts/Sunshine.rpm ../artifacts/sunshine.rpm
|
||||
if [[ ${{ matrix.dist }} == "20.04" ]]; then
|
||||
cpack -G RPM
|
||||
mv ./cpack_artifacts/Sunshine.rpm ../artifacts/sunshine.rpm
|
||||
fi
|
||||
|
||||
- name: Set AppImage Version
|
||||
if: ${{ matrix.type == 'appimage' && ( needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.latest_version ) }} # yamllint disable-line rule:line-length
|
||||
if: ${{ matrix.type == 'appimage' && ( needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.last_version ) }} # yamllint disable-line rule:line-length
|
||||
run: |
|
||||
version=${{ needs.check_changelog.outputs.next_version_bare }}
|
||||
echo "VERSION=${version}" >> $GITHUB_ENV
|
||||
@@ -380,12 +404,9 @@ jobs:
|
||||
# install sunshine to the DESTDIR
|
||||
make install DESTDIR=AppDir
|
||||
|
||||
# portable home and config
|
||||
# todo - this is ugly... we should use a custom AppRun script to take care of this
|
||||
mv ./AppDir${{ matrix.CMAKE_INSTALL_PREFIX }}/sunshine.AppImage.* ../artifacts/
|
||||
mkdir -p ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }}
|
||||
cp ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/apps.json \
|
||||
../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }}/
|
||||
# custom AppRun file
|
||||
cp -f ../packaging/linux/AppImage/AppRun ./AppDir/
|
||||
chmod +x ./AppDir/AppRun
|
||||
|
||||
# variables
|
||||
DESKTOP_FILE="${DESKTOP_FILE:-sunshine.desktop}"
|
||||
@@ -396,12 +417,6 @@ jobs:
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
|
||||
# # https://github.com/linuxdeploy/linuxdeploy-plugin-gtk
|
||||
# sudo apt-get install libgtk-3-dev librsvg2-dev -y
|
||||
# wget https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh
|
||||
# chmod +x linuxdeploy-plugin-gtk.sh
|
||||
# export DEPLOY_GTK_VERSION=3
|
||||
|
||||
./linuxdeploy-x86_64.AppImage \
|
||||
--appdir ./AppDir \
|
||||
--executable ./sunshine \
|
||||
@@ -411,8 +426,6 @@ jobs:
|
||||
--library /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 \
|
||||
--library /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 \
|
||||
--output appimage
|
||||
# # add this argument back if using gtk plugin
|
||||
# --plugin gtk \
|
||||
|
||||
# move
|
||||
mv Sunshine*.AppImage ../artifacts/sunshine.AppImage
|
||||
@@ -430,33 +443,30 @@ jobs:
|
||||
|
||||
./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage
|
||||
|
||||
- name: Archive AppImage
|
||||
if: ${{ matrix.type == 'appimage' }}
|
||||
working-directory: artifacts
|
||||
run: |
|
||||
chmod +x ./sunshine.AppImage
|
||||
|
||||
zip --recurse-paths --move --test ./sunshine-appimage.zip ./*
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: sunshine-linux-${{ matrix.type }}
|
||||
name: sunshine-linux-${{ matrix.type }}-${{ matrix.dist }}
|
||||
path: artifacts/
|
||||
|
||||
- name: Create Release
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: LizardByte/.github/actions/create_release@master
|
||||
- name: Create/Update GitHub Release
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ needs.setup_release.outputs.release_name }}
|
||||
tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
artifacts: "*artifacts/*"
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
next_version: ${{ needs.check_changelog.outputs.next_version }}
|
||||
last_version: ${{ needs.check_changelog.outputs.last_version }}
|
||||
release_body: ${{ needs.check_changelog.outputs.release_body }}
|
||||
allowUpdates: true
|
||||
body: ${{ needs.setup_release.outputs.release_body }}
|
||||
discussionCategory: announcements
|
||||
prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
build_mac:
|
||||
name: MacOS
|
||||
runs-on: macos-11
|
||||
needs: check_changelog
|
||||
needs: setup_release
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -467,19 +477,21 @@ jobs:
|
||||
- name: Setup Dependencies MacOS
|
||||
run: |
|
||||
# install dependencies using homebrew
|
||||
brew install boost cmake ffmpeg opus
|
||||
brew install boost cmake curl node opus pkg-config
|
||||
|
||||
# fix openssl header not found
|
||||
ln -sf /usr/local/opt/openssl/include/openssl /usr/local/include/openssl
|
||||
|
||||
- name: Build MacOS
|
||||
run: |
|
||||
npm install
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=local/sunshine/assets \
|
||||
-DSUNSHINE_CONFIG_DIR=local/sunshine/config \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
..
|
||||
make -j ${nproc}
|
||||
|
||||
@@ -513,19 +525,24 @@ jobs:
|
||||
rm -f ./sunshine-macos-experimental-bundle.dmg
|
||||
rm -f ./sunshine-macos-experimental-archive.zip
|
||||
|
||||
## no artifacts to release currently
|
||||
# - name: Create Release
|
||||
# if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
# uses: LizardByte/.github/actions/create_release@master
|
||||
# with:
|
||||
# token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
# next_version: ${{ needs.check_changelog.outputs.next_version }}
|
||||
# last_version: ${{ needs.check_changelog.outputs.last_version }}
|
||||
# release_body: ${{ needs.check_changelog.outputs.release_body }}
|
||||
# # no artifacts to release currently
|
||||
# - name: Create/Update GitHub Release
|
||||
# if: ${{ needs.setup_release.outputs.create_release == 'true' }}
|
||||
# uses: ncipollo/release-action@v1
|
||||
# with:
|
||||
# name: ${{ needs.setup_release.outputs.release_name }}
|
||||
# tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
# commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
# artifacts: "*artifacts/*"
|
||||
# token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
# allowUpdates: true
|
||||
# body: ${{ needs.setup_release.outputs.release_body }}
|
||||
# discussionCategory: announcements
|
||||
# prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
build_mac_port:
|
||||
name: Macports
|
||||
needs: check_changelog
|
||||
needs: setup_release
|
||||
runs-on: macos-11
|
||||
|
||||
steps:
|
||||
@@ -619,7 +636,7 @@ jobs:
|
||||
echo "$subport"
|
||||
subportlist="$subportlist $subport"
|
||||
done
|
||||
echo "::set-output name=subportlist::${subportlist}"
|
||||
echo "subportlist=${subportlist}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run port lint for all subports
|
||||
run: |
|
||||
@@ -723,19 +740,24 @@ jobs:
|
||||
name: sunshine-macports
|
||||
path: artifacts/
|
||||
|
||||
- name: Create Release
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: LizardByte/.github/actions/create_release@master
|
||||
- name: Create/Update GitHub Release
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ needs.setup_release.outputs.release_name }}
|
||||
tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
artifacts: "*artifacts/*"
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
next_version: ${{ needs.check_changelog.outputs.next_version }}
|
||||
last_version: ${{ needs.check_changelog.outputs.last_version }}
|
||||
release_body: ${{ needs.check_changelog.outputs.release_body }}
|
||||
allowUpdates: true
|
||||
body: ${{ needs.setup_release.outputs.release_body }}
|
||||
discussionCategory: announcements
|
||||
prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
build_win:
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
needs: check_changelog
|
||||
needs: setup_release
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -755,14 +777,20 @@ jobs:
|
||||
mingw-w64-x86_64-binutils
|
||||
mingw-w64-x86_64-boost
|
||||
mingw-w64-x86_64-cmake
|
||||
mingw-w64-x86_64-curl
|
||||
mingw-w64-x86_64-libmfx
|
||||
mingw-w64-x86_64-nsis
|
||||
mingw-w64-x86_64-openssl
|
||||
mingw-w64-x86_64-opus
|
||||
mingw-w64-x86_64-toolchain
|
||||
mingw-w64-x86_64-x265
|
||||
nasm
|
||||
wget
|
||||
yasm
|
||||
|
||||
- name: Install npm packages
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Build Windows
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
@@ -770,10 +798,9 @@ jobs:
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DSUNSHINE_ASSETS_DIR=assets \
|
||||
-DSUNSHINE_CONFIG_DIR=config \
|
||||
-G "MinGW Makefiles" \
|
||||
..
|
||||
mingw32-make -j2
|
||||
mingw32-make -j$(nproc)
|
||||
|
||||
- name: Package Windows
|
||||
shell: msys2 {0}
|
||||
@@ -786,8 +813,8 @@ jobs:
|
||||
cpack -G ZIP
|
||||
|
||||
# move
|
||||
mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows.exe
|
||||
mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows.zip
|
||||
mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows-installer.exe
|
||||
mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows-portable.zip
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -795,11 +822,30 @@ jobs:
|
||||
name: sunshine-windows
|
||||
path: artifacts/
|
||||
|
||||
- name: Create Release
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: LizardByte/.github/actions/create_release@master
|
||||
- name: Create/Update GitHub Release
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ needs.setup_release.outputs.release_name }}
|
||||
tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
artifacts: "*artifacts/*"
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
allowUpdates: true
|
||||
body: ${{ needs.setup_release.outputs.release_body }}
|
||||
discussionCategory: announcements
|
||||
prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
release-winget:
|
||||
name: Release to WinGet
|
||||
needs: [setup_release, build_win]
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' && github.ref == 'refs/heads/master' }}
|
||||
runs-on: windows-latest # the required action can only be run on Windows
|
||||
steps:
|
||||
- name: Release to WinGet
|
||||
uses: vedantmgoyal2009/winget-releaser@v2
|
||||
with:
|
||||
identifier: LizardByte.Sunshine
|
||||
release-tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
installers-regex: '\.exe$' # only .exe files
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
next_version: ${{ needs.check_changelog.outputs.next_version }}
|
||||
last_version: ${{ needs.check_changelog.outputs.last_version }}
|
||||
release_body: ${{ needs.check_changelog.outputs.release_body }}
|
||||
|
||||
4
.github/workflows/auto-create-pr.yml
vendored
4
.github/workflows/auto-create-pr.yml
vendored
@@ -3,6 +3,9 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# This workflow creates a PR automatically when anything is merged/pushed into the `nightly` branch. The PR is created
|
||||
# against the `master` (default) branch.
|
||||
|
||||
name: Auto create PR
|
||||
|
||||
on:
|
||||
@@ -12,6 +15,7 @@ on:
|
||||
|
||||
jobs:
|
||||
create_pr:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
21
.github/workflows/automerge.yml
vendored
21
.github/workflows/automerge.yml
vendored
@@ -3,6 +3,8 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# This workflow will, first, automatically approve PRs created by @LizardByte-bot. Then it will automerge relevant PRs.
|
||||
|
||||
name: Automerge PR
|
||||
|
||||
on:
|
||||
@@ -11,15 +13,20 @@ on:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
autoapprove:
|
||||
if: >
|
||||
if: >-
|
||||
contains(fromJson('["LizardByte-bot"]'), github.event.pull_request.user.login) &&
|
||||
contains(fromJson('["LizardByte-bot"]'), github.actor)
|
||||
contains(fromJson('["LizardByte-bot"]'), github.actor) &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Autoapproving
|
||||
uses: hmarr/auto-approve-action@v2
|
||||
uses: hmarr/auto-approve-action@v3
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -36,20 +43,18 @@ jobs:
|
||||
})
|
||||
|
||||
automerge:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
needs: [autoapprove]
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: automerge-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Automerging
|
||||
uses: pascalgn/automerge-action@v0.15.3
|
||||
uses: pascalgn/automerge-action@v0.15.5
|
||||
env:
|
||||
BASE_BRANCHES: nightly
|
||||
GITHUB_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
GITHUB_LOGIN: ${{ secrets.GH_BOT_NAME }}
|
||||
MERGE_LABELS: ""
|
||||
MERGE_LABELS: "!dependencies"
|
||||
MERGE_METHOD: "squash"
|
||||
MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})"
|
||||
MERGE_DELETE_BRANCH: true
|
||||
|
||||
72
.github/workflows/autoupdate-labeler.yml
vendored
Normal file
72
.github/workflows/autoupdate-labeler.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
# This action is centrally managed in https://github.com/<organization>/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Label PRs with `autoupdate` if various conditions are met, otherwise, remove the label.
|
||||
|
||||
name: Label PR autoupdate
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
label_pr:
|
||||
if: >-
|
||||
startsWith(github.repository, 'LizardByte/') &&
|
||||
contains(github.event.pull_request.body, fromJSON('"] I want maintainers to keep my branch updated"'))
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
steps:
|
||||
- name: Check if member
|
||||
id: org_member
|
||||
run: |
|
||||
status="true"
|
||||
gh api \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
/orgs/${{ github.repository_owner }}/members/${{ github.actor }} || status="false"
|
||||
|
||||
echo "result=${status}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Label autoupdate
|
||||
if: >-
|
||||
steps.org_member.outputs.result == 'true' &&
|
||||
contains(github.event.pull_request.labels.*.name, 'autoupdate') == false &&
|
||||
contains(github.event.pull_request.body,
|
||||
fromJSON('"\n- [x] I want maintainers to keep my branch updated"')) == true
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['autoupdate']
|
||||
})
|
||||
|
||||
- name: Unlabel autoupdate
|
||||
if: >-
|
||||
contains(github.event.pull_request.labels.*.name, 'autoupdate') &&
|
||||
(
|
||||
(github.event.action == 'synchronize' && steps.org_member.outputs.result == 'false') ||
|
||||
(contains(github.event.pull_request.body,
|
||||
fromJSON('"\n- [x] I want maintainers to keep my branch updated"')) == false
|
||||
)
|
||||
)
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['autoupdate']
|
||||
})
|
||||
31
.github/workflows/autoupdate.yml
vendored
31
.github/workflows/autoupdate.yml
vendored
@@ -3,11 +3,13 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# This workflow is designed to work with:
|
||||
# - automerge workflows
|
||||
# This workflow is designed to work with the following workflows:
|
||||
# - automerge
|
||||
# - autoupdate-labeler
|
||||
|
||||
# It uses GitHub Action that auto-updates pull requests branches, when changes are pushed to their destination branch.
|
||||
# It uses an action that auto-updates pull requests branches, when changes are pushed to their destination branch.
|
||||
# Auto-updating to the latest destination branch works only in the context of upstream repo and not forks.
|
||||
# Dependabot PRs are updated by an action that comments `@depdenabot rebase` on dependabot PRs. (disabled)
|
||||
|
||||
name: autoupdate
|
||||
|
||||
@@ -17,7 +19,7 @@ on:
|
||||
- 'nightly'
|
||||
|
||||
jobs:
|
||||
autoupdate-for-bot:
|
||||
autoupdate:
|
||||
name: Autoupdate autoapproved PR created in the upstream
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
@@ -25,8 +27,25 @@ jobs:
|
||||
- name: Update
|
||||
uses: docker://chinthakagodawita/autoupdate-action:v1
|
||||
env:
|
||||
EXCLUDED_LABELS: "central_dependency,dependencies"
|
||||
GITHUB_TOKEN: '${{ secrets.GH_BOT_TOKEN }}'
|
||||
PR_FILTER: "labelled"
|
||||
PR_LABELS: "autoupdate"
|
||||
PR_READY_STATE: "ready_for_review"
|
||||
MERGE_CONFLICT_ACTION: "ignore"
|
||||
PR_READY_STATE: "all"
|
||||
MERGE_CONFLICT_ACTION: "fail"
|
||||
|
||||
# Disabled due to:
|
||||
# - no major version tag, resulting in constant nagging to update this action
|
||||
# - additionally, the code is sketchy, 16k+ lines of code?
|
||||
# https://github.com/bbeesley/gha-auto-dependabot-rebase/blob/main/dist/main.cjs
|
||||
#
|
||||
# dependabot-rebase:
|
||||
# name: Dependabot Rebase
|
||||
# if: >-
|
||||
# startsWith(github.repository, 'LizardByte/')
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: rebase
|
||||
# uses: "bbeesley/gha-auto-dependabot-rebase@v1.3.18"
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
415
.github/workflows/ci-docker.yml
vendored
Normal file
415
.github/workflows/ci-docker.yml
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
---
|
||||
# This action is centrally managed in https://github.com/<organization>/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# This workflow is intended to work with all our organization Docker projects. A readme named `DOCKER_README.md`
|
||||
# will be used to update the description on Docker hub.
|
||||
|
||||
# custom comments in dockerfiles:
|
||||
|
||||
# `# platforms: `
|
||||
# Comma separated list of platforms, i.e. `# platforms: linux/386,linux/amd64`. Docker platforms can alternatively
|
||||
# be listed in a file named `.docker_platforms`.
|
||||
# `# platforms_pr: `
|
||||
# Comma separated list of platforms to run for PR events, i.e. `# platforms_pr: linux/amd64`. This will take
|
||||
# precedence over the `# platforms: ` directive.
|
||||
# `# artifacts: `
|
||||
# `true` to build in two steps, stopping at `artifacts` build stage and extracting the image from there to the
|
||||
# GitHub runner.
|
||||
|
||||
name: CI Docker
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
push:
|
||||
branches: [master, nightly]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check_dockerfiles:
|
||||
name: Check Dockerfiles
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Find dockerfiles
|
||||
id: find
|
||||
run: |
|
||||
dockerfiles=$(find . -type f -iname "Dockerfile" -o -iname "*.dockerfile")
|
||||
|
||||
echo "found dockerfiles: ${dockerfiles}"
|
||||
|
||||
# do not quote to keep this as a single line
|
||||
echo dockerfiles=${dockerfiles} >> $GITHUB_OUTPUT
|
||||
|
||||
MATRIX_COMBINATIONS=""
|
||||
for FILE in ${dockerfiles}; do
|
||||
# extract tag from file name
|
||||
tag=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*\/(Dockerfile)/None/gm')
|
||||
if [[ $tag == "None" ]]; then
|
||||
MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS {\"dockerfile\": \"$FILE\"},"
|
||||
else
|
||||
tag=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*\/(.+)(\.dockerfile)/-\2/gm')
|
||||
MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS {\"dockerfile\": \"$FILE\", \"tag\": \"$tag\"},"
|
||||
fi
|
||||
done
|
||||
|
||||
# removes the last character (i.e. comma)
|
||||
MATRIX_COMBINATIONS=${MATRIX_COMBINATIONS::-1}
|
||||
|
||||
# setup matrix for later jobs
|
||||
matrix=$((
|
||||
echo "{ \"include\": [$MATRIX_COMBINATIONS] }"
|
||||
) | jq -c .)
|
||||
|
||||
echo $matrix
|
||||
echo $matrix | jq .
|
||||
echo "matrix=$matrix" >> $GITHUB_OUTPUT
|
||||
|
||||
outputs:
|
||||
dockerfiles: ${{ steps.find.outputs.dockerfiles }}
|
||||
matrix: ${{ steps.find.outputs.matrix }}
|
||||
|
||||
check_changelog:
|
||||
name: Check Changelog
|
||||
needs: [check_dockerfiles]
|
||||
if: ${{ needs.check_dockerfiles.outputs.dockerfiles }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Verify Changelog
|
||||
id: verify_changelog
|
||||
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
|
||||
# base_ref for pull request check, ref for push
|
||||
uses: LizardByte/.github/actions/verify_changelog@master
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
outputs:
|
||||
next_version: ${{ steps.verify_changelog.outputs.changelog_parser_version }}
|
||||
next_version_bare: ${{ steps.verify_changelog.outputs.changelog_parser_version_bare }}
|
||||
last_version: ${{ steps.verify_changelog.outputs.latest_release_tag_name }}
|
||||
release_body: ${{ steps.verify_changelog.outputs.changelog_parser_description }}
|
||||
|
||||
setup_release:
|
||||
name: Setup Release
|
||||
needs: check_changelog
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set release details
|
||||
id: release_details
|
||||
env:
|
||||
RELEASE_BODY: ${{ needs.check_changelog.outputs.release_body }}
|
||||
run: |
|
||||
# determine to create a release or not
|
||||
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
|
||||
RELEASE=true
|
||||
else
|
||||
RELEASE=false
|
||||
fi
|
||||
|
||||
# set the release tag
|
||||
COMMIT=${{ github.sha }}
|
||||
if [[ $GITHUB_REF == refs/heads/master ]]; then
|
||||
TAG="${{ needs.check_changelog.outputs.next_version }}"
|
||||
RELEASE_NAME="${{ needs.check_changelog.outputs.next_version }}"
|
||||
RELEASE_BODY="$RELEASE_BODY"
|
||||
PRE_RELEASE="false"
|
||||
elif [[ $GITHUB_REF == refs/heads/nightly ]]; then
|
||||
TAG="nightly-dev"
|
||||
RELEASE_NAME="nightly"
|
||||
RELEASE_BODY="automated nightly release - $(date -u +'%Y-%m-%dT%H:%M:%SZ') - ${COMMIT}"
|
||||
PRE_RELEASE="true"
|
||||
fi
|
||||
|
||||
echo "create_release=${RELEASE}" >> $GITHUB_OUTPUT
|
||||
echo "release_tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
echo "release_commit=${COMMIT}" >> $GITHUB_OUTPUT
|
||||
echo "release_name=${RELEASE_NAME}" >> $GITHUB_OUTPUT
|
||||
echo "pre_release=${PRE_RELEASE}" >> $GITHUB_OUTPUT
|
||||
|
||||
# this is stupid but works for multiline strings
|
||||
echo "RELEASE_BODY<<EOF" >> $GITHUB_ENV
|
||||
echo "$RELEASE_BODY" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
outputs:
|
||||
create_release: ${{ steps.release_details.outputs.create_release }}
|
||||
release_tag: ${{ steps.release_details.outputs.release_tag }}
|
||||
release_commit: ${{ steps.release_details.outputs.release_commit }}
|
||||
release_name: ${{ steps.release_details.outputs.release_name }}
|
||||
release_body: ${{ env.RELEASE_BODY }}
|
||||
pre_release: ${{ steps.release_details.outputs.pre_release }}
|
||||
|
||||
lint_dockerfile:
|
||||
needs: [check_dockerfiles]
|
||||
if: ${{ needs.check_dockerfiles.outputs.dockerfiles }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.check_dockerfiles.outputs.matrix) }}
|
||||
name: Lint Dockerfile${{ matrix.tag }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Hadolint
|
||||
id: hadolint
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: ${{ matrix.dockerfile }}
|
||||
ignore: DL3008,DL3013,DL3016,DL3018,DL3028,DL3059
|
||||
output-file: ./hadolint.log
|
||||
verbose: true
|
||||
|
||||
- name: Log
|
||||
if: failure()
|
||||
run: |
|
||||
echo "Hadolint outcome: ${{ steps.hadolint.outcome }}" >> $GITHUB_STEP_SUMMARY
|
||||
cat "./hadolint.log" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
docker:
|
||||
needs: [check_dockerfiles, check_changelog, setup_release]
|
||||
if: ${{ needs.check_dockerfiles.outputs.dockerfiles }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.check_dockerfiles.outputs.matrix) }}
|
||||
name: Docker${{ matrix.tag }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare
|
||||
id: prepare
|
||||
env:
|
||||
NV: ${{ needs.check_changelog.outputs.next_version }}
|
||||
run: |
|
||||
# get branch name
|
||||
BRANCH=${GITHUB_HEAD_REF}
|
||||
|
||||
RELEASE=false
|
||||
|
||||
if [ -z "$BRANCH" ]; then
|
||||
echo "This is a PUSH event"
|
||||
BRANCH=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
CLONE_URL=${{ github.event.repository.clone_url }}
|
||||
if [[ $BRANCH == "master" ]]; then
|
||||
RELEASE=true
|
||||
fi
|
||||
else
|
||||
echo "This is a PULL REQUEST event"
|
||||
COMMIT=${{ github.event.pull_request.head.sha }}
|
||||
CLONE_URL=${{ github.event.pull_request.head.repo.clone_url }}
|
||||
fi
|
||||
|
||||
# determine to push image to dockerhub and ghcr or not
|
||||
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
|
||||
PUSH=true
|
||||
else
|
||||
PUSH=false
|
||||
fi
|
||||
|
||||
# setup the tags
|
||||
REPOSITORY=${{ github.repository }}
|
||||
BASE_TAG=$(echo $REPOSITORY | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
TAGS="${BASE_TAG}:${COMMIT:0:7}${{ matrix.tag }},ghcr.io/${BASE_TAG}:${COMMIT:0:7}${{ matrix.tag }}"
|
||||
|
||||
if [[ $GITHUB_REF == refs/heads/master ]]; then
|
||||
TAGS="${TAGS},${BASE_TAG}:latest${{ matrix.tag }},ghcr.io/${BASE_TAG}:latest${{ matrix.tag }}"
|
||||
TAGS="${TAGS},${BASE_TAG}:master${{ matrix.tag }},ghcr.io/${BASE_TAG}:master${{ matrix.tag }}"
|
||||
elif [[ $GITHUB_REF == refs/heads/nightly ]]; then
|
||||
TAGS="${TAGS},${BASE_TAG}:nightly${{ matrix.tag }},ghcr.io/${BASE_TAG}:nightly${{ matrix.tag }}"
|
||||
else
|
||||
TAGS="${TAGS},${BASE_TAG}:test${{ matrix.tag }},ghcr.io/${BASE_TAG}:test${{ matrix.tag }}"
|
||||
fi
|
||||
|
||||
if [[ ${NV} != "" ]]; then
|
||||
TAGS="${TAGS},${BASE_TAG}:${NV}${{ matrix.tag }},ghcr.io/${BASE_TAG}:${NV}${{ matrix.tag }}"
|
||||
fi
|
||||
|
||||
# parse custom directives out of dockerfile
|
||||
# try to get the platforms from the dockerfile custom directive, i.e. `# platforms: xxx,yyy`
|
||||
# directives for PR event, i.e. not push event
|
||||
if [[ ${PUSH} == "false" ]]; then
|
||||
while read -r line; do
|
||||
if [[ $line == "# platforms_pr: "* && $PLATFORMS == "" ]]; then
|
||||
# echo the line and use `sed` to remove the custom directive
|
||||
PLATFORMS=$(echo -e "$line" | sed 's/# platforms_pr: //')
|
||||
elif [[ $PLATFORMS != "" ]]; then
|
||||
# break while loop once all custom "PR" event directives are found
|
||||
break
|
||||
fi
|
||||
done <"${{ matrix.dockerfile }}"
|
||||
fi
|
||||
# directives for all events... above directives will not be parsed if they were already found
|
||||
while read -r line; do
|
||||
if [[ $line == "# platforms: "* && $PLATFORMS == "" ]]; then
|
||||
# echo the line and use `sed` to remove the custom directive
|
||||
PLATFORMS=$(echo -e "$line" | sed 's/# platforms: //')
|
||||
elif [[ $line == "# artifacts: "* && $ARTIFACTS == "" ]]; then
|
||||
# echo the line and use `sed` to remove the custom directive
|
||||
ARTIFACTS=$(echo -e "$line" | sed 's/# artifacts: //')
|
||||
elif [[ $line == "# no-cache-filters: "* && $NO_CACHE_FILTERS == "" ]]; then
|
||||
# echo the line and use `sed` to remove the custom directive
|
||||
NO_CACHE_FILTERS=$(echo -e "$line" | sed 's/# no-cache-filters: //')
|
||||
elif [[ $PLATFORMS != "" && $ARTIFACTS != "" && $NO_CACHE_FILTERS != "" ]]; then
|
||||
# break while loop once all custom directives are found
|
||||
break
|
||||
fi
|
||||
done <"${{ matrix.dockerfile }}"
|
||||
# if PLATFORMS is blank, fall back to the legacy method of reading from the `.docker_platforms` file
|
||||
if [[ $PLATFORMS == "" ]]; then
|
||||
# read the platforms from `.docker_platforms`
|
||||
PLATFORMS=$(<.docker_platforms)
|
||||
fi
|
||||
# if PLATFORMS is still blank, fall back to `linux/amd64`
|
||||
if [[ $PLATFORMS == "" ]]; then
|
||||
PLATFORMS="linux/amd64"
|
||||
fi
|
||||
|
||||
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
|
||||
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
||||
echo "commit=${COMMIT}" >> $GITHUB_OUTPUT
|
||||
echo "clone_url=${CLONE_URL}" >> $GITHUB_OUTPUT
|
||||
echo "release=${RELEASE}" >> $GITHUB_OUTPUT
|
||||
echo "artifacts=${ARTIFACTS}" >> $GITHUB_OUTPUT
|
||||
echo "no_cache_filters=${NO_CACHE_FILTERS}" >> $GITHUB_OUTPUT
|
||||
echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT
|
||||
echo "push=${PUSH}" >> $GITHUB_OUTPUT
|
||||
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set Up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
id: buildx
|
||||
|
||||
- name: Cache Docker Layers
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: Docker-buildx${{ matrix.tag }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
Docker-buildx${{ matrix.tag }}-
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
if: ${{ steps.prepare.outputs.push == 'true' }} # PRs do not have access to secrets
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Log in to the Container registry
|
||||
if: ${{ steps.prepare.outputs.push == 'true' }} # PRs do not have access to secrets
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GH_BOT_NAME }}
|
||||
password: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
- name: Build artifacts
|
||||
if: ${{ steps.prepare.outputs.artifacts == 'true' }}
|
||||
id: build_artifacts
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: ./
|
||||
file: ${{ matrix.dockerfile }}
|
||||
target: artifacts
|
||||
outputs: type=local,dest=artifacts
|
||||
push: false
|
||||
platforms: ${{ steps.prepare.outputs.platforms }}
|
||||
build-args: |
|
||||
BRANCH=${{ steps.prepare.outputs.branch }}
|
||||
BUILD_DATE=${{ steps.prepare.outputs.build_date }}
|
||||
BUILD_VERSION=${{ needs.check_changelog.outputs.next_version }}
|
||||
COMMIT=${{ steps.prepare.outputs.commit }}
|
||||
CLONE_URL=${{ steps.prepare.outputs.clone_url }}
|
||||
RELEASE=${{ steps.prepare.outputs.release }}
|
||||
tags: ${{ steps.prepare.outputs.tags }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
no-cache-filters: ${{ steps.prepare.outputs.no_cache_filters }}
|
||||
|
||||
- name: Build and push
|
||||
id: build
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: ./
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: ${{ steps.prepare.outputs.push }}
|
||||
platforms: ${{ steps.prepare.outputs.platforms }}
|
||||
build-args: |
|
||||
BRANCH=${{ steps.prepare.outputs.branch }}
|
||||
BUILD_DATE=${{ steps.prepare.outputs.build_date }}
|
||||
BUILD_VERSION=${{ needs.check_changelog.outputs.next_version }}
|
||||
COMMIT=${{ steps.prepare.outputs.commit }}
|
||||
CLONE_URL=${{ steps.prepare.outputs.clone_url }}
|
||||
RELEASE=${{ steps.prepare.outputs.release }}
|
||||
tags: ${{ steps.prepare.outputs.tags }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
no-cache-filters: ${{ steps.prepare.outputs.no_cache_filters }}
|
||||
|
||||
- name: Arrange Artifacts
|
||||
if: ${{ steps.prepare.outputs.artifacts == 'true' }}
|
||||
working-directory: artifacts
|
||||
run: |
|
||||
# artifacts will be in sub directories named after the docker target platform, e.g. `linux_amd64`
|
||||
# so move files to the artifacts directory
|
||||
# https://unix.stackexchange.com/a/52816
|
||||
find ./ -type f -exec mv -t ./ -n '{}' +
|
||||
|
||||
# remove provenance file
|
||||
rm -f ./provenance.json
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: ${{ steps.prepare.outputs.artifacts == 'true' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Docker${{ matrix.tag }}
|
||||
path: artifacts/
|
||||
|
||||
- name: Create/Update GitHub Release
|
||||
if: ${{ needs.setup_release.outputs.create_release == 'true' && steps.prepare.outputs.artifacts == 'true' }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ needs.setup_release.outputs.release_name }}
|
||||
tag: ${{ needs.setup_release.outputs.release_tag }}
|
||||
commit: ${{ needs.setup_release.outputs.release_commit }}
|
||||
artifacts: "*artifacts/*"
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
allowUpdates: true
|
||||
body: ${{ needs.setup_release.outputs.release_body }}
|
||||
discussionCategory: announcements
|
||||
prerelease: ${{ needs.setup_release.outputs.pre_release }}
|
||||
|
||||
- name: Update Docker Hub Description
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: peter-evans/dockerhub-description@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }} # token is not currently supported
|
||||
repository: ${{ env.BASE_TAG }}
|
||||
short-description: ${{ github.event.repository.description }}
|
||||
readme-filepath: ./DOCKER_README.md
|
||||
60
.github/workflows/cpp-clang-format-lint.yml
vendored
60
.github/workflows/cpp-clang-format-lint.yml
vendored
@@ -1,60 +0,0 @@
|
||||
---
|
||||
# This action is centrally managed in https://github.com/<organization>/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
name: Clang Format Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
check_src:
|
||||
name: Check src
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check
|
||||
id: check
|
||||
run: |
|
||||
if [ -d "./src" ]
|
||||
then
|
||||
FOUND=true
|
||||
else
|
||||
FOUND=false
|
||||
fi
|
||||
|
||||
echo "::set-output name=src::${FOUND}"
|
||||
|
||||
outputs:
|
||||
src: ${{ steps.check.outputs.src }}
|
||||
|
||||
lint:
|
||||
name: Clang Format Lint
|
||||
needs: [check_src]
|
||||
if: ${{ needs.check_src.outputs.src == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Clang format lint
|
||||
uses: DoozyX/clang-format-lint-action@v0.14
|
||||
with:
|
||||
source: './src'
|
||||
extensions: 'cpp,h,m,mm'
|
||||
clangFormatVersion: 13
|
||||
style: file
|
||||
inplace: false
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: clang-format-fixes
|
||||
path: src/
|
||||
84
.github/workflows/cpp-lint.yml
vendored
Normal file
84
.github/workflows/cpp-lint.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
# This action is centrally managed in https://github.com/<organization>/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Lint c++ source files and cmake files.
|
||||
|
||||
name: C++ Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
name: Clang Format Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Find cpp files
|
||||
id: cpp_files
|
||||
run: |
|
||||
cpp_files=$(find . -type f -iname "*.cpp" -o -iname "*.h" -o -iname "*.m" -o -iname "*.mm")
|
||||
|
||||
echo "found cpp files: ${cpp_files}"
|
||||
|
||||
# do not quote to keep this as a single line
|
||||
echo cpp_files=${cpp_files} >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Clang format lint
|
||||
if: ${{ steps.cpp_files.outputs.cpp_files }}
|
||||
uses: DoozyX/clang-format-lint-action@v0.15
|
||||
with:
|
||||
source: ${{ steps.cpp_files.outputs.cpp_files }}
|
||||
extensions: 'cpp,h,m,mm'
|
||||
clangFormatVersion: 15
|
||||
style: file
|
||||
inplace: false
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: clang-format-fixes
|
||||
path: ${{ steps.cpp_files.outputs.cpp_files }}
|
||||
|
||||
cmake-lint:
|
||||
name: CMake Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools cmakelang
|
||||
|
||||
- name: Find cmake files
|
||||
id: cmake_files
|
||||
run: |
|
||||
cmake_files=$(find . -type f -iname "CMakeLists.txt" -o -iname "*.cmake")
|
||||
|
||||
echo "found cmake files: ${cmake_files}"
|
||||
|
||||
# do not quote to keep this as a single line
|
||||
echo cmake_files=${cmake_files} >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Test with cmake-lint
|
||||
run: |
|
||||
cmake-lint --line-width 120 --tab-size 4 ${{ steps.cmake_files.outputs.cmake_files }}
|
||||
17
.github/workflows/issues-stale.yml
vendored
17
.github/workflows/issues-stale.yml
vendored
@@ -3,22 +3,25 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Manage stale issues and PRs.
|
||||
|
||||
name: Stale Issues / PRs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 00 * * *'
|
||||
- cron: '00 10 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
name: Check Stale Issues / PRs
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Stale
|
||||
uses: actions/stale@v5
|
||||
uses: actions/stale@v7
|
||||
with:
|
||||
close-issue-message: >
|
||||
This issue was closed because it has been stalled for 5 days with no activity.
|
||||
This issue was closed because it has been stalled for 10 days with no activity.
|
||||
close-pr-message: >
|
||||
This PR was closed because it has been stalled for 10 days with no activity.
|
||||
days-before-stale: 90
|
||||
@@ -28,15 +31,16 @@ jobs:
|
||||
exempt-pr-labels: 'dependencies,l10n'
|
||||
stale-issue-label: 'stale'
|
||||
stale-issue-message: >
|
||||
This issue is stale because it has been open for 30 days with no activity.
|
||||
Comment or remove the stale label, otherwise this will be closed in 5 days.
|
||||
This issue is stale because it has been open for 90 days with no activity.
|
||||
Comment or remove the stale label, otherwise this will be closed in 10 days.
|
||||
stale-pr-label: 'stale'
|
||||
stale-pr-message: >
|
||||
This PR is stale because it has been open for 90 days with no activity.
|
||||
Comment or remove the stale label, otherwise this will be closed in 10 days.
|
||||
repo-token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
- name: Invalid Template
|
||||
uses: actions/stale@v5
|
||||
uses: actions/stale@v7
|
||||
with:
|
||||
close-issue-message: >
|
||||
This issue was closed because the the template was not completed after 5 days.
|
||||
@@ -52,3 +56,4 @@ jobs:
|
||||
stale-pr-label: 'invalid:template-incomplete'
|
||||
stale-pr-message: >
|
||||
Invalid PR template.
|
||||
repo-token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
7
.github/workflows/issues.yml
vendored
7
.github/workflows/issues.yml
vendored
@@ -3,6 +3,8 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Label and un-label actions using `../label-actions.yml`.
|
||||
|
||||
name: Issues
|
||||
|
||||
on:
|
||||
@@ -14,9 +16,10 @@ on:
|
||||
jobs:
|
||||
label:
|
||||
name: Label Actions
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Label Actions
|
||||
uses: dessant/label-actions@v2
|
||||
uses: dessant/label-actions@v3
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
github-token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
13
.github/workflows/localize.yml
vendored
13
.github/workflows/localize.yml
vendored
@@ -62,17 +62,20 @@ jobs:
|
||||
# print the git diff
|
||||
git diff locale/sunshine.po
|
||||
|
||||
# set the variable with minimal output
|
||||
OUTPUT=$(git diff --numstat locale/sunshine.po)
|
||||
# set the variable with minimal output, replacing `\t` with ` `
|
||||
OUTPUT=$(git diff --numstat locale/sunshine.po | sed -e "s#\t# #g")
|
||||
echo "git_diff=${OUTPUT}" >> $GITHUB_ENV
|
||||
|
||||
- name: git reset
|
||||
# only run if a single line changed (date/time) and file already existed
|
||||
# \t in next line is a tab character
|
||||
if: ${{ env.git_diff == '1\t1\tlocale/sunshine.po' && env.new_file == 'false' }}
|
||||
if: ${{ env.git_diff == '1 1 locale/sunshine.po' && env.new_file == 'false' }}
|
||||
run: |
|
||||
git reset --hard
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create/Update Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
@@ -86,7 +89,7 @@ jobs:
|
||||
title: New Babel Updates
|
||||
body: |
|
||||
Update report
|
||||
- Updated with *today's* date
|
||||
- Updated ${{ steps.date.outputs.date }}
|
||||
- Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
|
||||
5
.github/workflows/pull-requests.yml
vendored
5
.github/workflows/pull-requests.yml
vendored
@@ -3,15 +3,20 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Ensure PRs are made against `nightly` branch.
|
||||
|
||||
name: Pull Requests
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, edited, reopened]
|
||||
|
||||
# no concurrency for pull_request_target events
|
||||
|
||||
jobs:
|
||||
check-pull-request:
|
||||
name: Check Pull Request
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Vankka/pr-target-branch-action@v2
|
||||
|
||||
9
.github/workflows/python-flake8.yml
vendored
9
.github/workflows/python-flake8.yml
vendored
@@ -3,6 +3,8 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Lint python files with flake8.
|
||||
|
||||
name: flake8
|
||||
|
||||
on:
|
||||
@@ -10,6 +12,10 @@ on:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
flake8:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -24,7 +30,8 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools flake8
|
||||
# pin flake8 before v6.0.0 due to removal of support for type comments (required for Python 2.7 type hints)
|
||||
python -m pip install --upgrade pip setuptools "flake8<6"
|
||||
|
||||
- name: Test with flake8
|
||||
run: |
|
||||
|
||||
22
.github/workflows/release-notifier-moonlight.yml
vendored
Normal file
22
.github/workflows/release-notifier-moonlight.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Release Notifications (Moonlight)
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
discord:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: discord
|
||||
uses: sarisia/actions-status-discord@v1 # https://github.com/sarisia/actions-status-discord
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_RELEASE_WEBHOOK_MOONLIGHT }}
|
||||
nodetail: true
|
||||
nofail: false
|
||||
username: ${{ secrets.DISCORD_USERNAME }}
|
||||
avatar_url: ${{ secrets.ORG_LOGO_URL }}
|
||||
title: ${{ github.event.repository.name }} ${{ github.ref_name }} Released
|
||||
description: ${{ github.event.release.body }}
|
||||
color: 0xFF4500
|
||||
9
.github/workflows/release-notifier.yml
vendored
9
.github/workflows/release-notifier.yml
vendored
@@ -3,6 +3,8 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Send release notification to various platforms.
|
||||
|
||||
name: Release Notifications
|
||||
|
||||
on:
|
||||
@@ -12,6 +14,7 @@ on:
|
||||
|
||||
jobs:
|
||||
discord:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: discord
|
||||
@@ -27,6 +30,7 @@ jobs:
|
||||
color: 0xFF4500
|
||||
|
||||
facebook_group:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: facebook-post-action
|
||||
@@ -40,6 +44,7 @@ jobs:
|
||||
url: ${{ github.event.release.html_url }}
|
||||
|
||||
facebook_page:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: facebook-post-action
|
||||
@@ -53,10 +58,11 @@ jobs:
|
||||
url: ${{ github.event.release.html_url }}
|
||||
|
||||
reddit:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: reddit
|
||||
uses: bluwy/release-for-reddit-action@v1 # https://github.com/bluwy/release-for-reddit-action
|
||||
uses: bluwy/release-for-reddit-action@v2 # https://github.com/bluwy/release-for-reddit-action
|
||||
with:
|
||||
username: ${{ secrets.REDDIT_USERNAME }}
|
||||
password: ${{ secrets.REDDIT_PASSWORD }}
|
||||
@@ -69,6 +75,7 @@ jobs:
|
||||
comment: ${{ github.event.release.body }}
|
||||
|
||||
twitter:
|
||||
if: startsWith(github.repository, 'LizardByte/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: twitter
|
||||
|
||||
17
.github/workflows/winget.yml
vendored
17
.github/workflows/winget.yml
vendored
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Publish to WinGet
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
jobs:
|
||||
winget-releaser:
|
||||
name: winget releaser
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: winget releaser
|
||||
uses: vedantmgoyal2009/winget-releaser@latest
|
||||
with:
|
||||
identifier: LizardByte.Sunshine
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
42
.github/workflows/yaml-lint.yml
vendored
42
.github/workflows/yaml-lint.yml
vendored
@@ -3,6 +3,8 @@
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
# Lint yaml files.
|
||||
|
||||
name: yaml lint
|
||||
|
||||
on:
|
||||
@@ -10,12 +12,34 @@ on:
|
||||
branches: [master, nightly]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
yaml-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Find additional files
|
||||
id: find-files
|
||||
run: |
|
||||
# space separated list of files
|
||||
FILES=.clang-format
|
||||
|
||||
# empty placeholder
|
||||
FOUND=""
|
||||
|
||||
for FILE in ${FILES}; do
|
||||
if [ -f "$FILE" ]
|
||||
then
|
||||
FOUND="$FOUND $FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "found=${FOUND}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: yaml lint
|
||||
id: yaml-lint
|
||||
@@ -30,17 +54,13 @@ jobs:
|
||||
line-length:
|
||||
max: 120
|
||||
truthy:
|
||||
allowed-values: ['true', 'false', 'on'] # GitHub uses "on" for workflow event triggers
|
||||
# GitHub uses "on" for workflow event triggers
|
||||
# .clang-format file has options of "Yes" "No" that will be caught by this, so changed to "warning"
|
||||
allowed-values: ['true', 'false', 'on']
|
||||
check-keys: true
|
||||
level: error
|
||||
level: warning
|
||||
file_or_dir: . ${{ steps.find-files.outputs.found }}
|
||||
|
||||
- name: Log
|
||||
run: |
|
||||
echo ${{ steps.yaml-lint.outputs.logfile }}
|
||||
|
||||
- name: Upload logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: yamllint-logfile
|
||||
path: ${{ steps.yaml-lint.outputs.logfile }}
|
||||
cat "${{ steps.yaml-lint.outputs.logfile }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -9,15 +9,9 @@ cmake-build*
|
||||
.cache
|
||||
.idea
|
||||
|
||||
# Extra FontAwesome files
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/css/*.css
|
||||
!/src_assets/common/assets/web/fonts/fontawesome-free-web/css/*min.css
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/js/
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/less/
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/metadata/
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/scss/
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/sprites/
|
||||
/src_assets/common/assets/web/fonts/fontawesome-free-web/svgs/
|
||||
# npm
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
38
.gitmodules
vendored
38
.gitmodules
vendored
@@ -1,18 +1,48 @@
|
||||
[submodule "moonlight-common-c"]
|
||||
[submodule "third-party/moonlight-common-c"]
|
||||
path = third-party/moonlight-common-c
|
||||
url = https://github.com/moonlight-stream/moonlight-common-c.git
|
||||
[submodule "Simple-Web-Server"]
|
||||
branch = master
|
||||
[submodule "third-party/Simple-Web-Server"]
|
||||
path = third-party/Simple-Web-Server
|
||||
url = https://github.com/loki-47-6F-64/Simple-Web-Server.git
|
||||
[submodule "ViGEmClient"]
|
||||
url = https://gitlab.com/eidheim/Simple-Web-Server.git
|
||||
branch = master
|
||||
[submodule "third-party/ViGEmClient"]
|
||||
path = third-party/ViGEmClient
|
||||
url = https://github.com/ViGEm/ViGEmClient
|
||||
branch = master
|
||||
[submodule "third-party/miniupnp"]
|
||||
path = third-party/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp
|
||||
branch = master
|
||||
[submodule "third-party/nv-codec-headers"]
|
||||
path = third-party/nv-codec-headers
|
||||
url = https://github.com/FFmpeg/nv-codec-headers
|
||||
branch = sdk/11.1
|
||||
[submodule "third-party/TPCircularBuffer"]
|
||||
path = third-party/TPCircularBuffer
|
||||
url = https://github.com/michaeltyson/TPCircularBuffer
|
||||
branch = master
|
||||
[submodule "third-party/ffmpeg-windows-x86_64"]
|
||||
path = third-party/ffmpeg-windows-x86_64
|
||||
url = https://github.com/LizardByte/build-deps
|
||||
branch = ffmpeg-windows-x86_64
|
||||
[submodule "third-party/ffmpeg-macos-x86_64"]
|
||||
path = third-party/ffmpeg-macos-x86_64
|
||||
url = https://github.com/LizardByte/build-deps
|
||||
branch = ffmpeg-macos-x86_64
|
||||
[submodule "third-party/ffmpeg-linux-x86_64"]
|
||||
path = third-party/ffmpeg-linux-x86_64
|
||||
url = https://github.com/LizardByte/build-deps
|
||||
branch = ffmpeg-linux-x86_64
|
||||
[submodule "third-party/ffmpeg-linux-aarch64"]
|
||||
path = third-party/ffmpeg-linux-aarch64
|
||||
url = https://github.com/LizardByte/build-deps
|
||||
branch = ffmpeg-linux-aarch64
|
||||
[submodule "third-party/ffmpeg-macos-aarch64"]
|
||||
path = third-party/ffmpeg-macos-aarch64
|
||||
url = https://github.com/LizardByte/build-deps
|
||||
branch = ffmpeg-macos-aarch64
|
||||
[submodule "third-party/nanors"]
|
||||
path = third-party/nanors
|
||||
url = https://github.com/sleepybishop/nanors.git
|
||||
branch = master
|
||||
|
||||
@@ -10,12 +10,11 @@ version: 2
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.9"
|
||||
python: "3.10"
|
||||
|
||||
## apt packages required packages to run cmake on sunshine, note that additional packages are required
|
||||
# apt_packages:
|
||||
# - cmake
|
||||
# - ffmpeg
|
||||
# - libboost-filesystem-dev
|
||||
# - libboost-log-dev
|
||||
# - libboost-thread-dev
|
||||
@@ -41,5 +40,5 @@ formats: all
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: ./scripts/requirements.txt
|
||||
- requirements: ./docs/requirements.txt
|
||||
system_packages: true
|
||||
|
||||
185
CHANGELOG.md
185
CHANGELOG.md
@@ -1,5 +1,155 @@
|
||||
# Changelog
|
||||
|
||||
## [0.18.4] - 2023-02-20
|
||||
### Fixed
|
||||
- (Linux/AUR) Drop support of AUR package
|
||||
- (Docker) General enhancements to docker images
|
||||
|
||||
## [0.18.3] - 2023-02-13
|
||||
### Added
|
||||
- (Linux) Added PKGBUILD for Archlinux based distros to releases
|
||||
- (Linux) Added precompiled package for Archlinux based distros to releases
|
||||
- (Docker) Added archlinux docker image (x86_64 only)
|
||||
|
||||
## [0.18.2] - 2023-02-13
|
||||
### Fixed
|
||||
- (Video/KMV/Linux) Fixed wayland capture on Nvidia for KMS
|
||||
- (Video/Linux) Implement vaSyncBuffer stuf for libva <2.9.0
|
||||
- (UI) Fix issue where mime type was not being set for node_modules when using a reverse proxy
|
||||
- (UI/macOS) Added missing audio sink config options
|
||||
- (Linux) Specify correct Boost dependency versions
|
||||
- (Video/AMF) Add missing encoder tunables
|
||||
|
||||
## [0.18.1] - 2023-01-31
|
||||
### Fixed
|
||||
- (Linux) Fixed missing dependencies for deb and rpm packages
|
||||
- (Linux) Use dynamic boost
|
||||
|
||||
## [0.18.0] - 2023-01-29
|
||||
Attention, this release contains critical security fixes. Please update as soon as possible. Additionally, we are
|
||||
encouraging users to change your Sunshine password, especially if you expose the web UI (i.e. port 47790 by default)
|
||||
to the internet, or have ever uploaded your logs with verbose output to a public resource.
|
||||
|
||||
### Added
|
||||
- (Windows) Add support for Intel QuickSync
|
||||
- (Linux) Added aarch64 deb and rpm packages
|
||||
- (Windows) Add support for hybrid graphics systems, such as laptops with both integrated and discrete GPUs
|
||||
- (Linux) Add support for streaming from Steam Deck Gaming Mode
|
||||
- (Windows) Add HDR support, see https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/usage.html#hdr-support
|
||||
### Fixed
|
||||
- (Network) Refactor code for UPnP port forwarding
|
||||
- (Video) Enforce 10 FPS encoding frame rate minimum to improve static image quality
|
||||
- (Linux) deb and rpm packages are now specific to destination distro and version
|
||||
- (Docs) Add nvidia/nvenc preset migration guide
|
||||
- (Network) Performance optimizations
|
||||
- (Video/Windows) Fix streaming to multiple clients from hardware encoder
|
||||
- (Linux) Fix child process spawning
|
||||
- (Security) Fix security vulnerability in implementation of SimpleWebServer
|
||||
- (Misc) Rename "Steam BigPicture" to "Steam Big Picture" in default apps.json
|
||||
- (Security) Scrub basic authorization header from logs
|
||||
- (Linux) The systemd service will now restart in the event of a crash
|
||||
- (Video/KMS/Linux) Fixed error: `couldn't import RGB Image: 00003002 and 00003004`
|
||||
- (Video/Windows) Fix stream freezing triggered by the resolution changed
|
||||
- (Installer/Windows) Fixes silent installation and other miscellaneous improvements
|
||||
- (CPU) Significantly improved CPU usage
|
||||
|
||||
## [0.17.0] - 2023-01-08
|
||||
If you are running Sunshine as a service on Windows, we are strongly urging you to update to v0.17.0 as soon as
|
||||
possible. Older Windows versions of Sunshine had a security flaw in which the binary was located in a user-writable
|
||||
location which is problematic when running as a service or on a multi-user system. Additionally, when running Sunshine
|
||||
as a service, games and applications were launched as SYSTEM. This could lead to issues with save files and other game
|
||||
settings. In v0.17.0, games now run under your user account without elevated privileges.
|
||||
|
||||
### Breaking
|
||||
- (Apps) Removed automatic desktop entry (Re-add by adding an empty application named "Desktop" with no commands, "desktop.png" can be added as the image.)
|
||||
- (Windows) Improved user upgrade experience (Suggest to manually uninstall existing Sunshine version before this upgrade. Do NOT select to remove everything, if prompted. Make a backup of config files before uninstall.)
|
||||
- (Windows) Move config files to specific directory (files will be migrated automatically if using Windows installer)
|
||||
- (Dependencies) Fix npm path (breaking change for package maintainers)
|
||||
### Added
|
||||
- (macOS) Added initial support for arm64 on macOS through Macports portfile
|
||||
- (Input) Added support for foreign keyboard input
|
||||
- (Misc) Logs inside the WebUI and log to file
|
||||
- (UI/Windows) Added an Apply button to configuration page when running as a service
|
||||
- (Input/Windows) Enable Mouse Keys while streaming for systems with no physical mouse
|
||||
### Fixed
|
||||
- (Video) Improved capture performance
|
||||
- (Audio) Improved audio bitrate and quality handling
|
||||
- (Apps/Windows) Fixed PATH environment variable handling
|
||||
- (Apps/Windows) Use the proper environment variable for the Program Files (x86) folder
|
||||
- (Service/Windows) Fix SunshineSvc hanging if an error occurs during startup
|
||||
- (Service/Windows) Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies
|
||||
- (Video) windows/vram: fix fringing in NV12 colour conversion
|
||||
- (Apps/Windows) Launch games under the correct user account
|
||||
- (Video) nvenc, amdvce: rework all user presets/options
|
||||
- (Network) Generate certificates with unique serial numbers
|
||||
- (Service/Windows) Graceful termination on shutdown, logoff, and service stop
|
||||
- (Apps/Windows) Fix launching apps when Sunshine is running as admin
|
||||
- (Misc) Remove/fix calls to std::abort()
|
||||
- (Misc) Remove prompt to press enter after Sunshine exits
|
||||
- (Misc) Make log priority consistent for execution messages
|
||||
- (Apps) Applications in Moonlight clients are now updated automatically after editing
|
||||
- (Video/Linux) Fix wayland capture on nvidia
|
||||
- (Audio) Fix 7.1 surround channel mapping
|
||||
- (Video) Fix NVENC profile values not applying
|
||||
- (Network) Fix origin_web_ui_allowed binding
|
||||
- (Service/Windows) Self terminate/restart service if process hangs for 10 seconds
|
||||
- (Input/Windows) Fix Windows masked cursor blending with GPU encoders
|
||||
- (Video) Color conversion fixes and BT.2020 support
|
||||
### Dependencies
|
||||
- Bump ffmpeg from 4.4 to 5.1
|
||||
- ffmpeg_patches: add amfenc delay/buffering fix
|
||||
- CBS moved to ffmpeg submodules
|
||||
- Migrate to upstream Simple-Web-Server submodule
|
||||
- Bump third-party/TPCircularBuffer from `bce9170` to `8833b3a`
|
||||
- Bump third-party/moonlight-common-c from `8169a31` to `ef9ad52`
|
||||
- Bump third-party/miniupnp from `6f848ae` to `207cf44`
|
||||
- Bump third-party/ViGEmClient from `f719a1d` to `9e842ba`
|
||||
- Bump bootstrap from 5.0.0 to 5.2.3
|
||||
- Bump @fortawesome/fontawesome-free from 6.2.0 to 6.2.1
|
||||
|
||||
## [0.16.0] - 2022-12-13
|
||||
### Added
|
||||
- Add cover finder
|
||||
- (Docker) Add arm64 docker image
|
||||
- (Flatpak) Add installation helper scripts
|
||||
- (Windows) Add support for Unicode input messages
|
||||
### Fixed
|
||||
- (Linux) Reintroduce Ubuntu 20.04 and 22.04 specific deb packages
|
||||
- (Linux) Fixed udev and systemd file locations
|
||||
### Dependencies
|
||||
- Bump babel from 2.10.3 to 2.11.0
|
||||
- Bump sphinx-copybutton from 0.5.0 to 0.5.1
|
||||
- Bump KSXGitHub/github-actions-deploy-aur from 2.5.0 to 2.6.0
|
||||
- Use npm for web dependencies (breaking change for third-party package maintainers)
|
||||
- Update moonlight-common-c
|
||||
- Use pre-built ffmpeg from LizardByte/build-deps for all sunshine builds (breaking change for third-party package maintainers)
|
||||
- Bump furo from 2022.9.29 to 2022.12.7
|
||||
### Misc
|
||||
- Misc org level workflow updates
|
||||
- Fix misc typos in docs
|
||||
- Fix winget release
|
||||
|
||||
## [0.15.0] - 2022-10-30
|
||||
### Added
|
||||
- (Windows) Add firewall rules scripts
|
||||
- (Windows) Automatically add and remove firewall rules at install/uninstall
|
||||
- (Windows) Automatically add and remove service at install/uninstall
|
||||
- (Docker) Official image added
|
||||
- (Linux) Add aarch64 flatpak package
|
||||
### Changed
|
||||
- (Windows/Linux/MacOS) - Move default config and apps file to assets directory
|
||||
- (MacOS) Bump boost to 1.80 for macport builds
|
||||
- (Linux) Remove backup and restore of config files
|
||||
### Fixed
|
||||
- (Linux) - Create sunshine config directory if it doesn't exist
|
||||
- (Linux) Remove portable home and config directories for AppImage
|
||||
- (Windows) Include service install and uninstall scripts again
|
||||
- (Windows) Automatically delete start menu entry upon uninstall
|
||||
- (Windows) Automatically delete program install directory upon uninstall, with user prompt
|
||||
- (Linux) Handle the case of no default audio sink
|
||||
- (Windows/Linux/MacOS) Fix default image paths
|
||||
- (Linux) Fix CUDA RGBA to NV12 conversion
|
||||
|
||||
## [0.14.1] - 2022-08-09
|
||||
### Added
|
||||
- (Linux) Flatpak package added
|
||||
@@ -18,7 +168,7 @@
|
||||
- (Documentation) Added Sphinx documentation available at https://sunshinestream.readthedocs.io/en/latest/
|
||||
- (Development) Initial support for Localization
|
||||
- (Linux) Add rpm package as release asset
|
||||
- (MacOS) Add Portfile as release asset
|
||||
- (macOS) Add Portfile as release asset
|
||||
- (Windows) Add DwmFlush() call to improve capture
|
||||
- (Windows) Add Windows installer
|
||||
### Fixed
|
||||
@@ -27,13 +177,13 @@
|
||||
- (Linux) Fixed rumble events causing game to freeze
|
||||
- (Linux) Improved Pulse/Pipewire compatibility
|
||||
- (Linux) Moved to single deb package
|
||||
- (MacOS) Fixed missing TPCircularBuffer submodule
|
||||
- (macOS) Fixed missing TPCircularBuffer submodule
|
||||
- (Stream) Properly catch exceptions in stream broadcast handlers
|
||||
- (Stream/Video) AVPacket fix
|
||||
|
||||
## [0.13.0] - 2022-02-27
|
||||
### Added
|
||||
- (MacOS) Initial support for MacOS (#40)
|
||||
- (macOS) Initial support for macOS (#40)
|
||||
|
||||
## [0.12.0] - 2022-02-13
|
||||
### Added
|
||||
@@ -150,3 +300,32 @@
|
||||
## [0.1.0] - 2020-01-27
|
||||
### Added
|
||||
- The first official release for Sunshine!
|
||||
|
||||
[0.1.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.0
|
||||
[0.1.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.1
|
||||
[0.2.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.2.0
|
||||
[0.3.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.0
|
||||
[0.3.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.1
|
||||
[0.4.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.4.0
|
||||
[0.5.0]: https://github.com/LizardByte/Sunshine/releases/tag/0.5.0
|
||||
[0.6.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.6.0
|
||||
[0.7.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.0
|
||||
[0.7.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.1
|
||||
[0.7.7]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.7
|
||||
[0.8.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.8.0
|
||||
[0.9.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.9.0
|
||||
[0.10.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.0
|
||||
[0.10.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.1
|
||||
[0.11.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.0
|
||||
[0.11.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.1
|
||||
[0.12.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.12.0
|
||||
[0.13.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.13.0
|
||||
[0.14.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.0
|
||||
[0.14.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.1
|
||||
[0.15.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.15.0
|
||||
[0.16.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.16.0
|
||||
[0.17.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.17.0
|
||||
[0.18.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.0
|
||||
[0.18.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.1
|
||||
[0.18.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.2
|
||||
[0.18.3]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.3
|
||||
|
||||
1135
CMakeLists.txt
1135
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
132
DOCKER_README.md
132
DOCKER_README.md
@@ -1,44 +1,77 @@
|
||||
# Docker
|
||||
|
||||
## Using docker run
|
||||
## Important note
|
||||
Starting with v0.18.0, tag names have changed. You may no longer use `latest`, `master`, `vX.X.X`.
|
||||
|
||||
## Build your own containers
|
||||
This image provides a method for you to easily use the latest Sunshine release in your own docker projects. It is not
|
||||
intended to use as a standalone container at this point, and should be considered experimental.
|
||||
|
||||
```dockerfile
|
||||
ARG SUNSHINE_VERSION=latest
|
||||
ARG SUNSHINE_OS=ubuntu-22.04
|
||||
FROM lizardbyte/sunshine:${SUNSHINE_VERSION}-${SUNSHINE_OS}
|
||||
|
||||
# install Steam, Wayland, etc.
|
||||
|
||||
ENTRYPOINT steam && sunshine
|
||||
```
|
||||
|
||||
### SUNSHINE_VERSION
|
||||
- `latest`, `master`, `vX.X.X`
|
||||
- `nightly`
|
||||
- commit hash
|
||||
|
||||
### SUNSHINE_OS
|
||||
Sunshine images are available with the following tag suffixes, based on their respective base images.
|
||||
|
||||
- `archlinux`
|
||||
- `debian-bullseye`
|
||||
- `fedora-36`
|
||||
- `fedora-37`
|
||||
- `ubuntu-20.04`
|
||||
- `ubuntu-22.04`
|
||||
|
||||
### Tags
|
||||
You must combine the `SUNSHINE_VERSION` and `SUNSHINE_OS` to determine the tag to pull. The format should be
|
||||
`<SUNSHINE_VERSION>-<SUNSHINE_OS>`. For example, `latest-ubuntu-22.04`.
|
||||
|
||||
See all our available tags on [docker hub](https://hub.docker.com/r/lizardbyte/sunshine/tags) or
|
||||
[ghcr](https://github.com/LizardByte/Sunshine/pkgs/container/sunshine/versions) for more info.
|
||||
|
||||
## Where used
|
||||
This is a list of docker projects using Sunshine. Something missing? Let us know about it!
|
||||
|
||||
- [Games on Whales](https://games-on-whales.github.io)
|
||||
|
||||
## Port and Volume mappings
|
||||
Examples are below of the required mappings. The configuration file will be saved to `/config` in the container.
|
||||
|
||||
### Using docker run
|
||||
Create and run the container (substitute your `<values>`):
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name=sunshine \
|
||||
--name=<image_name> \
|
||||
--restart=unless-stopped
|
||||
-v <path to data>:/config \
|
||||
-e PUID=<uid> \
|
||||
-e PGID=<gid> \
|
||||
-e TZ=<timezone> \
|
||||
-v <path to data>:/config \
|
||||
-p 47984-47990:47984-47990/tcp \
|
||||
-p 48010:48010 \
|
||||
-p 47998-48000:47998-48000/udp \
|
||||
lizardbyte/sunshine
|
||||
<image>
|
||||
```
|
||||
|
||||
To update the container it must be removed and recreated:
|
||||
|
||||
```bash
|
||||
# Stop the container
|
||||
docker stop sunshine
|
||||
# Remove the container
|
||||
docker rm sunshine
|
||||
# Pull the latest update
|
||||
docker pull lizardbyte/sunshine
|
||||
# Run the container with the same parameters as before
|
||||
docker run -d ...
|
||||
```
|
||||
|
||||
## Using docker-compose
|
||||
|
||||
### Using docker-compose
|
||||
Create a `docker-compose.yml` file with the following contents (substitute your `<values>`):
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
sunshine:
|
||||
image: lizardbyte/sunshine
|
||||
<image_name>:
|
||||
image: <image>
|
||||
container_name: sunshine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
@@ -48,26 +81,12 @@ services:
|
||||
- PGID=<gid>
|
||||
- TZ=<timezone>
|
||||
ports:
|
||||
- 47984-47990:47984-47990/tcp
|
||||
- 48010:48010
|
||||
- 47998-48000:47998-48000/udp
|
||||
- "47984-47990:47984-47990/tcp"
|
||||
- "48010:48010"
|
||||
- "47998-48000:47998-48000/udp"
|
||||
```
|
||||
|
||||
Create and start the container (run the command from the same folder as your `docker-compose.yml` file):
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
To update the container:
|
||||
```bash
|
||||
# Pull the latest update
|
||||
docker-compose pull
|
||||
# Update and restart the container
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Parameters
|
||||
### Parameters
|
||||
You must substitute the `<values>` with your own settings.
|
||||
|
||||
Parameters are split into two halves separated by a colon. The left side represents the host and the right side the
|
||||
@@ -79,16 +98,17 @@ port `47990` (e.g. `http://<host_ip>:47990`). The internal port must be `47990`,
|
||||
(e.g. `-p 8080:47990`). All the ports listed in the `docker run` and `docker-compose` examples are required.
|
||||
|
||||
|
||||
| Parameter | Function | Example Value | Required |
|
||||
| --------------------------- | -------------------- | ------------------- | -------- |
|
||||
| `-p <port>:47990` | Web UI Port | `47990` | True |
|
||||
| `-v <path to data>:/config` | Volume mapping | `/home/sunshine` | True |
|
||||
| `-e PUID=<uid>` | User ID | `1001` | False |
|
||||
| `-e PGID=<gid>` | Group ID | `1001` | False |
|
||||
| `-e TZ=<timezone>` | Lookup TZ value [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `America/New_York` | True |
|
||||
| Parameter | Function | Example Value | Required |
|
||||
|-----------------------------|----------------------|--------------------|----------|
|
||||
| `-p <port>:47990` | Web UI Port | `47990` | True |
|
||||
| `-v <path to data>:/config` | Volume mapping | `/home/sunshine` | True |
|
||||
| `-e PUID=<uid>` | User ID | `1001` | False |
|
||||
| `-e PGID=<gid>` | Group ID | `1001` | False |
|
||||
| `-e TZ=<timezone>` | Lookup [TZ value][1] | `America/New_York` | False |
|
||||
|
||||
### User / Group Identifiers:
|
||||
[1]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
|
||||
#### User / Group Identifiers:
|
||||
When using data volumes (-v flags) permissions issues can arise between the host OS and the container. To avoid this
|
||||
issue you can specify the user PUID and group PGID. Ensure the data volume directory on the host is owned by the same
|
||||
user you specify.
|
||||
@@ -99,3 +119,21 @@ In this instance `PUID=1001` and `PGID=1001`. To find yours use id user as below
|
||||
$ id dockeruser
|
||||
uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup)
|
||||
```
|
||||
|
||||
If you want to change the PUID or PGID after the image has been built, it will require rebuilding the image.
|
||||
|
||||
## Supported Architectures
|
||||
|
||||
Specifying `lizardbyte/sunshine:latest-<SUNSHINE_OS>` or `ghcr.io/lizardbyte/sunshine:latest-<SUNSHINE_OS>` should
|
||||
retrieve the correct image for your architecture.
|
||||
|
||||
The architectures supported by these images are shown in the table below.
|
||||
|
||||
| tag suffix | amd64/x86_64 | arm64/aarch64 |
|
||||
|-----------------|--------------|---------------|
|
||||
| archlinux | ✅ | ❌ |
|
||||
| debian-bullseye | ✅ | ✅ |
|
||||
| fedora-36 | ✅ | ✅ |
|
||||
| fedora-37 | ✅ | ✅ |
|
||||
| ubuntu-20.04 | ✅ | ✅ |
|
||||
| ubuntu-22.04 | ✅ | ✅ |
|
||||
|
||||
117
README.rst
117
README.rst
@@ -1,39 +1,94 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/README.rst
|
||||
|
||||
Overview
|
||||
========
|
||||
LizardByte has the full documentation hosted on `Read the Docs <https://docs.lizardbyte.dev/projects/sunshine/>`_.
|
||||
LizardByte has the full documentation hosted on `Read the Docs <https://sunshinestream.readthedocs.io/>`_.
|
||||
|
||||
About
|
||||
-----
|
||||
Sunshine is a Game stream host for Moonlight.
|
||||
Sunshine is a self hosted, low latency, cloud gaming solution with support for AMD, Intel, and Nvidia gpus.
|
||||
It is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
|
||||
Connect to Sunshine from any Moonlight client, available for nearly any device imaginable.
|
||||
Sunshine is a self-hosted game stream host for Moonlight.
|
||||
Offering low latency, cloud gaming server capabilities with support for AMD, Intel, and Nvidia GPUs for hardware
|
||||
encoding. Software encoding is also available. You can connect to Sunshine from any Moonlight client on a variety of
|
||||
devices. A web UI is provided to allow configuration, and client pairing, from your favorite web browser. Pair from
|
||||
the local server or any mobile device.
|
||||
|
||||
These are the advantages of Sunshine over GeForce Experience.
|
||||
System Requirements
|
||||
-------------------
|
||||
|
||||
- FOSS (Free and Open Source Software)
|
||||
- Multi-platform
|
||||
.. warning:: This table is a work in progress. Do not purchase hardware based on this.
|
||||
|
||||
- Linux
|
||||
- macOS
|
||||
- Windows
|
||||
**Minimum Requirements**
|
||||
|
||||
- Pair over web ui
|
||||
- Supports AMD, Intel, and Nvidia GPUs for encoding
|
||||
- Supports software encoding
|
||||
- Supports streaming to multiple clients
|
||||
- Web UI for configuration
|
||||
+------------+------------------------------------------------------------+
|
||||
| GPU | AMD: VCE 1.0 or higher, see `obs-amd hardware support`_ |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: VAAPI-compatible, see: `VAAPI hardware support`_ |
|
||||
| +------------------------------------------------------------+
|
||||
| | Nvidia: NVENC enabled cards, see `nvenc support matrix`_ |
|
||||
+------------+------------------------------------------------------------+
|
||||
| CPU | AMD: Ryzen 3 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: Core i3 or higher |
|
||||
+------------+------------------------------------------------------------+
|
||||
| RAM | 4GB or more |
|
||||
+------------+------------------------------------------------------------+
|
||||
| OS | Windows: 10+ (Windows Server not supported) |
|
||||
| +------------------------------------------------------------+
|
||||
| | macOS: 11.7+ |
|
||||
| +------------------------------------------------------------+
|
||||
| | Linux/Debian: 11 (bullseye) |
|
||||
| +------------------------------------------------------------+
|
||||
| | Linux/Fedora: 36+ |
|
||||
| +------------------------------------------------------------+
|
||||
| | Linux/Ubuntu: 20.04+ (focal) |
|
||||
+------------+------------------------------------------------------------+
|
||||
| Network | Host: 5GHz, 802.11ac |
|
||||
| +------------------------------------------------------------+
|
||||
| | Client: 5GHz, 802.11ac |
|
||||
+------------+------------------------------------------------------------+
|
||||
|
||||
**4k Suggestions**
|
||||
|
||||
+------------+------------------------------------------------------------+
|
||||
| GPU | AMD: Video Coding Engine 3.1 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: HD Graphics 510 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Nvidia: GeForce GTX 1080 or higher |
|
||||
+------------+------------------------------------------------------------+
|
||||
| CPU | AMD: Ryzen 5 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: Core i5 or higher |
|
||||
+------------+------------------------------------------------------------+
|
||||
| Network | Host: CAT5e ethernet or better |
|
||||
| +------------------------------------------------------------+
|
||||
| | Client: CAT5e ethernet or better |
|
||||
+------------+------------------------------------------------------------+
|
||||
|
||||
**HDR Suggestions**
|
||||
|
||||
+------------+------------------------------------------------------------+
|
||||
| GPU | AMD: Video Coding Engine 3.4 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: UHD Graphics 730 or higher |
|
||||
| +------------------------------------------------------------+
|
||||
| | Nvidia: Pascal-based GPU (GTX 10-series) or higher |
|
||||
+------------+------------------------------------------------------------+
|
||||
| CPU | AMD: todo |
|
||||
| +------------------------------------------------------------+
|
||||
| | Intel: todo |
|
||||
+------------+------------------------------------------------------------+
|
||||
| Network | Host: CAT5e ethernet or better |
|
||||
| +------------------------------------------------------------+
|
||||
| | Client: CAT5e ethernet or better |
|
||||
+------------+------------------------------------------------------------+
|
||||
|
||||
Integrations
|
||||
------------
|
||||
|
||||
.. image:: https://img.shields.io/github/workflow/status/lizardbyte/sunshine/CI/master?label=CI%20build&logo=github&style=for-the-badge
|
||||
.. image:: https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/CI.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge
|
||||
:alt: GitHub Workflow Status (CI)
|
||||
:target: https://github.com/LizardByte/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster
|
||||
|
||||
.. image:: https://img.shields.io/github/workflow/status/lizardbyte/sunshine/localize/nightly?label=localize%20build&logo=github&style=for-the-badge
|
||||
.. image:: https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=nightly&label=localize%20build&logo=github&style=for-the-badge
|
||||
:alt: GitHub Workflow Status (localize)
|
||||
:target: https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Anightly
|
||||
|
||||
@@ -46,9 +101,10 @@ Integrations
|
||||
:target: https://crowdin.com/project/sunshinestream
|
||||
|
||||
Support
|
||||
---------
|
||||
-------
|
||||
|
||||
Our support methods are listed in our `LizardByte Docs <https://docs.lizardbyte.dev/en/latest/about/support.html>`_.
|
||||
Our support methods are listed in our
|
||||
`LizardByte Docs <https://lizardbyte.readthedocs.io/en/latest/about/support.html>`_.
|
||||
|
||||
Downloads
|
||||
---------
|
||||
@@ -57,11 +113,16 @@ Downloads
|
||||
:alt: GitHub Releases
|
||||
:target: https://github.com/LizardByte/Sunshine/releases/latest
|
||||
|
||||
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=AUR&style=for-the-badge&query=$.results.0.NumVotes&url=https%3A%2F%2Fapp.lizardbyte.dev%2Funo%2Faur%2Fsunshine.json&logo=archlinux
|
||||
:alt: AUR votes
|
||||
:target: https://aur.archlinux.org/packages/sunshine
|
||||
|
||||
.. comment
|
||||
image:: https://img.shields.io/docker/pulls/lizardbyte/sunshine?style=for-the-badge&logo=docker
|
||||
.. image:: https://img.shields.io/docker/pulls/lizardbyte/sunshine?style=for-the-badge&logo=docker
|
||||
:alt: Docker
|
||||
:target: https://hub.docker.com/r/lizardbyte/sunshine
|
||||
|
||||
Stats
|
||||
------
|
||||
.. image:: https://img.shields.io/github/stars/lizardbyte/sunshine?logo=github&style=for-the-badge
|
||||
:alt: GitHub stars
|
||||
:target: https://github.com/LizardByte/Sunshine
|
||||
|
||||
.. _nvenc support matrix: https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
|
||||
.. _obs-amd hardware support: https://github.com/obsproject/obs-amd-encoder/wiki/Hardware-Support
|
||||
.. _VAAPI hardware support: https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# - Try to find FFMPEG
|
||||
# Once done this will define
|
||||
# FFMPEG_FOUND - System has FFMPEG
|
||||
# FFMPEG_INCLUDE_DIRS - The FFMPEG include directories
|
||||
# FFMPEG_LIBRARIES - The libraries needed to use FFMPEG
|
||||
# FFMPEG_LIBRARY_DIRS - The directory to find FFMPEG libraries
|
||||
#
|
||||
# written by Roy Shilkrot 2013 http://www.morethantechnical.com/
|
||||
#
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
||||
MACRO(FFMPEG_FIND varname shortname headername)
|
||||
|
||||
IF(NOT WIN32)
|
||||
PKG_CHECK_MODULES(PC_${varname} ${shortname})
|
||||
|
||||
FIND_PATH(${varname}_INCLUDE_DIR "${shortname}/${headername}"
|
||||
HINTS ${PC_${varname}_INCLUDEDIR} ${PC_${varname}_INCLUDE_DIRS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
ELSE()
|
||||
FIND_PATH(${varname}_INCLUDE_DIR "${shortname}/${headername}")
|
||||
ENDIF()
|
||||
|
||||
IF(${varname}_INCLUDE_DIR STREQUAL "${varname}_INCLUDE_DIR-NOTFOUND")
|
||||
message(STATUS "look for newer strcture")
|
||||
IF(NOT WIN32)
|
||||
PKG_CHECK_MODULES(PC_${varname} "lib${shortname}")
|
||||
|
||||
FIND_PATH(${varname}_INCLUDE_DIR "lib${shortname}/${headername}"
|
||||
HINTS ${PC_${varname}_INCLUDEDIR} ${PC_${varname}_INCLUDE_DIRS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
ELSE()
|
||||
FIND_PATH(${varname}_INCLUDE_DIR "lib${shortname}/${headername}")
|
||||
IF(${${varname}_INCLUDE_DIR} STREQUAL "${varname}_INCLUDE_DIR-NOTFOUND")
|
||||
#Desperate times call for desperate measures
|
||||
MESSAGE(STATUS "globbing...")
|
||||
FILE(GLOB_RECURSE ${varname}_INCLUDE_DIR "/ffmpeg*/${headername}")
|
||||
MESSAGE(STATUS "found: ${${varname}_INCLUDE_DIR}")
|
||||
IF(${varname}_INCLUDE_DIR)
|
||||
GET_FILENAME_COMPONENT(${varname}_INCLUDE_DIR "${${varname}_INCLUDE_DIR}" PATH)
|
||||
GET_FILENAME_COMPONENT(${varname}_INCLUDE_DIR "${${varname}_INCLUDE_DIR}" PATH)
|
||||
ELSE()
|
||||
SET(${varname}_INCLUDE_DIR "${varname}_INCLUDE_DIR-NOTFOUND")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(${${varname}_INCLUDE_DIR} STREQUAL "${varname}_INCLUDE_DIR-NOTFOUND")
|
||||
MESSAGE(STATUS "Can't find includes for ${shortname}...")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Found ${shortname} include dirs: ${${varname}_INCLUDE_DIR}")
|
||||
|
||||
#GET_DIRECTORY_PROPERTY(FFMPEG_PARENT DIRECTORY ${${varname}_INCLUDE_DIR} PARENT_DIRECTORY)
|
||||
GET_FILENAME_COMPONENT(FFMPEG_PARENT ${${varname}_INCLUDE_DIR} PATH)
|
||||
MESSAGE(STATUS "Using FFMpeg dir parent as hint: ${FFMPEG_PARENT}")
|
||||
|
||||
IF(NOT WIN32)
|
||||
FIND_LIBRARY(${varname}_LIBRARIES NAMES ${shortname}
|
||||
HINTS ${PC_${varname}_LIBDIR} ${PC_${varname}_LIBRARY_DIR} ${FFMPEG_PARENT})
|
||||
ELSE()
|
||||
FIND_PATH(${varname}_LIBRARIES "${shortname}.dll.a" HINTS ${FFMPEG_PARENT})
|
||||
# FILE(GLOB_RECURSE ${varname}_LIBRARIES "${FFMPEG_PARENT}/*${shortname}.lib")
|
||||
# GLOBing is very bad... but windows sux, this is the only thing that works
|
||||
ENDIF()
|
||||
|
||||
IF(${varname}_LIBRARIES STREQUAL "${varname}_LIBRARIES-NOTFOUND")
|
||||
MESSAGE(STATUS "look for newer structure for library")
|
||||
FIND_LIBRARY(${varname}_LIBRARIES NAMES lib${shortname}
|
||||
HINTS ${PC_${varname}_LIBDIR} ${PC_${varname}_LIBRARY_DIR} ${FFMPEG_PARENT})
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(${varname}_LIBRARIES STREQUAL "${varname}_LIBRARIES-NOTFOUND")
|
||||
MESSAGE(STATUS "Can't find lib for ${shortname}...")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Found ${shortname} libs: ${${varname}_LIBRARIES}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(NOT ${varname}_INCLUDE_DIR STREQUAL "${varname}_INCLUDE_DIR-NOTFOUND"
|
||||
AND NOT ${varname}_LIBRARIES STREQUAL ${varname}_LIBRARIES-NOTFOUND)
|
||||
|
||||
MESSAGE(STATUS "found ${shortname}: include ${${varname}_INCLUDE_DIR} lib ${${varname}_LIBRARIES}")
|
||||
SET(FFMPEG_${varname}_FOUND 1)
|
||||
SET(FFMPEG_${varname}_INCLUDE_DIRS ${${varname}_INCLUDE_DIR})
|
||||
SET(FFMPEG_${varname}_LIBS ${${varname}_LIBRARIES})
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Can't find ${shortname}")
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO(FFMPEG_FIND)
|
||||
|
||||
FFMPEG_FIND(LIBAVFORMAT avformat avformat.h)
|
||||
FFMPEG_FIND(LIBAVDEVICE avdevice avdevice.h)
|
||||
FFMPEG_FIND(LIBAVCODEC avcodec avcodec.h)
|
||||
FFMPEG_FIND(LIBAVUTIL avutil avutil.h)
|
||||
FFMPEG_FIND(LIBSWSCALE swscale swscale.h)
|
||||
|
||||
SET(FFMPEG_FOUND "NO")
|
||||
IF (FFMPEG_LIBAVFORMAT_FOUND AND
|
||||
FFMPEG_LIBAVDEVICE_FOUND AND
|
||||
FFMPEG_LIBAVCODEC_FOUND AND
|
||||
FFMPEG_LIBAVUTIL_FOUND AND
|
||||
FFMPEG_LIBSWSCALE_FOUND
|
||||
)
|
||||
|
||||
|
||||
SET(FFMPEG_FOUND "YES")
|
||||
|
||||
SET(FFMPEG_INCLUDE_DIRS ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS})
|
||||
|
||||
SET(FFMPEG_LIBRARY_DIRS ${FFMPEG_LIBAVFORMAT_LIBRARY_DIRS})
|
||||
|
||||
SET(FFMPEG_LIBRARIES
|
||||
${FFMPEG_LIBAVFORMAT_LIBS}
|
||||
${FFMPEG_LIBAVDEVICE_LIBS}
|
||||
${FFMPEG_LIBAVCODEC_LIBS}
|
||||
${FFMPEG_LIBAVUTIL_LIBS}
|
||||
${FFMPEG_LIBSWSCALE_LIBS}
|
||||
)
|
||||
|
||||
ELSE ()
|
||||
|
||||
MESSAGE(STATUS "Could not find FFMPEG")
|
||||
|
||||
ENDIF()
|
||||
|
||||
message(STATUS ${FFMPEG_LIBRARIES} ${FFMPEG_LIBAVFORMAT_LIBRARIES})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(FFMPEG DEFAULT_MSG
|
||||
FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARY_DIRS FFMPEG_LIBRARIES)
|
||||
@@ -18,4 +18,4 @@ find_library(LIBDRM_LIBRARIES NAMES libdrm.so PATHS ${PC_LIBDRM_LIBDIR} ${PC_LIB
|
||||
mark_as_advanced(LIBDRM_INCLUDE_DIRS LIBDRM_LIBRARIES)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LIBDRM REQUIRED_VARS LIBDRM_LIBRARIES LIBDRM_INCLUDE_DIRS)
|
||||
find_package_handle_standard_args(LIBDRM REQUIRED_VARS LIBDRM_LIBRARIES LIBDRM_INCLUDE_DIRS)
|
||||
|
||||
@@ -22,57 +22,59 @@
|
||||
|
||||
IF (NOT WIN32)
|
||||
|
||||
# Use pkg-config to get the directories and then use these values
|
||||
# in the find_path() and find_library() calls
|
||||
find_package(PkgConfig)
|
||||
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
|
||||
# Use pkg-config to get the directories and then use these values
|
||||
# in the find_path() and find_library() calls
|
||||
find_package(PkgConfig)
|
||||
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
|
||||
|
||||
set(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
||||
set(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
||||
|
||||
find_path(WAYLAND_CLIENT_INCLUDE_DIRS NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_CLIENT_INCLUDE_DIRS AND WAYLAND_CLIENT_LIBRARIES)
|
||||
set(Wayland_Client_FOUND TRUE)
|
||||
else()
|
||||
set(Wayland_Client_FOUND FALSE)
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES)
|
||||
find_path(WAYLAND_CLIENT_INCLUDE_DIRS NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_CLIENT_INCLUDE_DIRS AND WAYLAND_CLIENT_LIBRARIES)
|
||||
set(Wayland_Client_FOUND TRUE) # cmake-lint: disable=C0103
|
||||
else()
|
||||
set(Wayland_Client_FOUND FALSE) # cmake-lint: disable=C0103
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES)
|
||||
|
||||
find_path(WAYLAND_CURSOR_INCLUDE_DIRS NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_CURSOR_INCLUDE_DIRS AND WAYLAND_CURSOR_LIBRARIES)
|
||||
set(Wayland_Cursor_FOUND TRUE)
|
||||
else()
|
||||
set(Wayland_Cursor_FOUND FALSE)
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_CURSOR_INCLUDE_DIRS WAYLAND_CURSOR_LIBRARIES)
|
||||
find_path(WAYLAND_CURSOR_INCLUDE_DIRS NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_CURSOR_INCLUDE_DIRS AND WAYLAND_CURSOR_LIBRARIES)
|
||||
set(Wayland_Cursor_FOUND TRUE) # cmake-lint: disable=C0103
|
||||
else()
|
||||
set(Wayland_Cursor_FOUND FALSE) # cmake-lint: disable=C0103
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_CURSOR_INCLUDE_DIRS WAYLAND_CURSOR_LIBRARIES)
|
||||
|
||||
find_path(WAYLAND_EGL_INCLUDE_DIRS NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_EGL_INCLUDE_DIRS AND WAYLAND_EGL_LIBRARIES)
|
||||
set(Wayland_EGL_FOUND TRUE)
|
||||
else()
|
||||
set(Wayland_EGL_FOUND FALSE)
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES)
|
||||
find_path(WAYLAND_EGL_INCLUDE_DIRS NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_EGL_INCLUDE_DIRS AND WAYLAND_EGL_LIBRARIES)
|
||||
set(Wayland_EGL_FOUND TRUE) # cmake-lint: disable=C0103
|
||||
else()
|
||||
set(Wayland_EGL_FOUND FALSE) # cmake-lint: disable=C0103
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES)
|
||||
|
||||
find_path(WAYLAND_SERVER_INCLUDE_DIRS NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_SERVER_INCLUDE_DIRS AND WAYLAND_SERVER_LIBRARIES)
|
||||
set(Wayland_Server_FOUND TRUE)
|
||||
else()
|
||||
set(Wayland_Server_FOUND FALSE)
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES)
|
||||
find_path(WAYLAND_SERVER_INCLUDE_DIRS NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
find_library(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
if(WAYLAND_SERVER_INCLUDE_DIRS AND WAYLAND_SERVER_LIBRARIES)
|
||||
set(Wayland_Server_FOUND TRUE) # cmake-lint: disable=C0103
|
||||
else()
|
||||
set(Wayland_Server_FOUND FALSE) # cmake-lint: disable=C0103
|
||||
endif()
|
||||
mark_as_advanced(WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES)
|
||||
|
||||
set(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIRS} ${WAYLAND_SERVER_INCLUDE_DIRS} ${WAYLAND_EGL_INCLUDE_DIRS} ${WAYLAND_CURSOR_INCLUDE_DIRS})
|
||||
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
|
||||
mark_as_advanced(WAYLAND_INCLUDE_DIRS WAYLAND_LIBRARIES)
|
||||
set(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIRS} ${WAYLAND_SERVER_INCLUDE_DIRS}
|
||||
${WAYLAND_EGL_INCLUDE_DIRS} ${WAYLAND_CURSOR_INCLUDE_DIRS})
|
||||
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES}
|
||||
${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
|
||||
mark_as_advanced(WAYLAND_INCLUDE_DIRS WAYLAND_LIBRARIES)
|
||||
|
||||
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(Wayland REQUIRED_VARS WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS HANDLE_COMPONENTS)
|
||||
find_package_handle_standard_args(Wayland REQUIRED_VARS WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS HANDLE_COMPONENTS)
|
||||
|
||||
ENDIF ()
|
||||
|
||||
138
docker/archlinux.dockerfile
Normal file
138
docker/archlinux.dockerfile
Normal file
@@ -0,0 +1,138 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64
|
||||
# archlinux does not have an arm64 base image
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=archlinux
|
||||
ARG TAG=base-devel
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
# install dependencies
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
pacman -Syu --noconfirm \
|
||||
archlinux-keyring
|
||||
_DEPS
|
||||
|
||||
# Setup builder user, arch prevents running makepkg as root
|
||||
RUN useradd -m builder && \
|
||||
echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
# makepkg is used in sunshine-build and uploader build stages
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG BUILD_VERSION
|
||||
ARG COMMIT
|
||||
ARG CLONE_URL
|
||||
# note: BUILD_VERSION may be blank
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
# cuda, libcap, and libdrm are optional dependencies for PKGBUILD
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
pacman -Syu --noconfirm \
|
||||
base-devel \
|
||||
cmake \
|
||||
cuda \
|
||||
libcap \
|
||||
libdrm \
|
||||
namcap
|
||||
_DEPS
|
||||
|
||||
# Setup builder user
|
||||
USER builder
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# configure PKGBUILD file
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
if [[ "${BUILD_VERSION}" == '' ]]; then
|
||||
sub_version=".r${COMMIT}"
|
||||
else
|
||||
sub_version=""
|
||||
fi
|
||||
cmake \
|
||||
-DSUNSHINE_CONFIGURE_AUR=ON \
|
||||
-DSUNSHINE_SUB_VERSION="${sub_version}" \
|
||||
-DGITHUB_CLONE_URL="${CLONE_URL}" \
|
||||
-DGITHUB_COMMIT="${COMMIT}" \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON \
|
||||
/build/sunshine
|
||||
_MAKE
|
||||
|
||||
WORKDIR /build/sunshine/pkg
|
||||
RUN mv /build/sunshine/build/PKGBUILD .
|
||||
|
||||
# namcap and build PKGBUILD file
|
||||
RUN <<_PKGBUILD
|
||||
#!/bin/bash
|
||||
set -e
|
||||
namcap -i PKGBUILD
|
||||
makepkg -si --noconfirm
|
||||
ls -a
|
||||
_PKGBUILD
|
||||
|
||||
FROM scratch as artifacts
|
||||
|
||||
COPY --link --from=sunshine-build /build/sunshine/pkg/PKGBUILD /PKGBUILD
|
||||
COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /sunshine.pkg.tar.zst
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy from uploader instead of artifacts or uploader stage will not run
|
||||
COPY --link --from=artifacts /sunshine.pkg.tar.zst /
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
pacman -U --noconfirm \
|
||||
/sunshine.pkg.tar.zst
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# first delete the builder user
|
||||
userdel -r builder
|
||||
|
||||
# then create the lizard user
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
163
docker/debian-bullseye.dockerfile
Normal file
163
docker/debian-bullseye.dockerfile
Normal file
@@ -0,0 +1,163 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64,linux/arm64/v8
|
||||
# platforms_pr: linux/amd64
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=debian
|
||||
ARG TAG=bullseye
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "target_platform: ${TARGETPLATFORM}"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential=12.9* \
|
||||
cmake=3.18.4* \
|
||||
libavdevice-dev=7:4.3.* \
|
||||
libboost-filesystem-dev=1.74.0* \
|
||||
libboost-log-dev=1.74.0* \
|
||||
libboost-program-options-dev=1.74.0* \
|
||||
libboost-thread-dev=1.74.0* \
|
||||
libcap-dev=1:2.44* \
|
||||
libcurl4-openssl-dev=7.74.0* \
|
||||
libdrm-dev=2.4.104* \
|
||||
libevdev-dev=1.11.0* \
|
||||
libnuma-dev=2.0.12* \
|
||||
libopus-dev=1.3.1* \
|
||||
libpulse-dev=14.2* \
|
||||
libssl-dev=1.1.1* \
|
||||
libva-dev=2.10.0* \
|
||||
libvdpau-dev=1.4* \
|
||||
libwayland-dev=1.18.0* \
|
||||
libx11-dev=2:1.7.2* \
|
||||
libxcb-shm0-dev=1.14* \
|
||||
libxcb-xfixes0-dev=1.14* \
|
||||
libxcb1-dev=1.14* \
|
||||
libxfixes-dev=1:5.0.3* \
|
||||
libxrandr-dev=2:1.5.1* \
|
||||
libxtst-dev=2:1.2.3* \
|
||||
nodejs=12.22* \
|
||||
npm=7.5.2* \
|
||||
wget=1.21*
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
apt-get install -y --no-install-recommends \
|
||||
libmfx-dev=21.1.0*
|
||||
fi
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_DEPS
|
||||
|
||||
# install cuda
|
||||
WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="11.8.0"
|
||||
ENV CUDA_BUILD="520.61.05"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
|
||||
cuda_suffix=""
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cuda_suffix="_sbsa"
|
||||
fi
|
||||
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
|
||||
echo "cuda url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
_INSTALL_CUDA
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup npm dependencies
|
||||
RUN npm install
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# cmake and cpack
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake \
|
||||
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_ENABLE_DRM=ON \
|
||||
-DSUNSHINE_ENABLE_CUDA=ON \
|
||||
/build/sunshine
|
||||
make -j "$(nproc)"
|
||||
cpack -G DEB
|
||||
_MAKE
|
||||
|
||||
FROM scratch AS artifacts
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends /sunshine.deb
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
161
docker/fedora-36.dockerfile
Normal file
161
docker/fedora-36.dockerfile
Normal file
@@ -0,0 +1,161 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64,linux/arm64/v8
|
||||
# platforms_pr: linux/amd64
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=fedora
|
||||
ARG TAG=36
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "target_platform: ${TARGETPLATFORM}"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
# hadolint ignore=DL3041
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
dnf -y update
|
||||
dnf -y group install "Development Tools"
|
||||
dnf -y install \
|
||||
boost-devel-1.76.0* \
|
||||
cmake-3.22.2* \
|
||||
gcc-12.0.1* \
|
||||
gcc-c++-12.0.1* \
|
||||
libcap-devel-2.48* \
|
||||
libcurl-devel-7.82.0* \
|
||||
libdrm-devel-2.4.110* \
|
||||
libevdev-devel-1.12.0* \
|
||||
libva-devel-2.14.0* \
|
||||
libvdpau-devel-1.5* \
|
||||
libX11-devel-1.7.3* \
|
||||
libxcb-devel-1.13.1* \
|
||||
libXcursor-devel-1.2.0* \
|
||||
libXfixes-devel-6.0.0* \
|
||||
libXi-devel-1.8* \
|
||||
libXinerama-devel-1.1.4* \
|
||||
libXrandr-devel-1.5.2* \
|
||||
libXtst-devel-1.2.3* \
|
||||
mesa-libGL-devel-22.0.1* \
|
||||
npm-8.3.1* \
|
||||
numactl-devel-2.0.14* \
|
||||
openssl-devel-3.0.2* \
|
||||
opus-devel-1.3.1* \
|
||||
pulseaudio-libs-devel-15.0* \
|
||||
rpm-build-4.17.0* \
|
||||
wget-1.21.3* \
|
||||
which-2.21*
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
dnf -y install intel-mediasdk-devel-22.3.0*
|
||||
fi
|
||||
dnf clean all
|
||||
rm -rf /var/cache/yum
|
||||
_DEPS
|
||||
|
||||
# install cuda
|
||||
WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="12.0.0"
|
||||
ENV CUDA_BUILD="525.60.13"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
|
||||
cuda_suffix=""
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cuda_suffix="_sbsa"
|
||||
fi
|
||||
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
|
||||
echo "cuda url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
_INSTALL_CUDA
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup npm dependencies
|
||||
RUN npm install
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# cmake and cpack
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake \
|
||||
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_ENABLE_DRM=ON \
|
||||
-DSUNSHINE_ENABLE_CUDA=ON \
|
||||
/build/sunshine
|
||||
make -j "$(nproc)"
|
||||
cpack -G RPM
|
||||
_MAKE
|
||||
|
||||
FROM scratch AS artifacts
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.rpm /sunshine-${BASE}-${TAG}-${TARGETARCH}.rpm
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.rpm /sunshine.rpm
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
dnf -y update
|
||||
dnf -y install /sunshine.rpm
|
||||
dnf clean all
|
||||
rm -rf /var/cache/yum
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
161
docker/fedora-37.dockerfile
Normal file
161
docker/fedora-37.dockerfile
Normal file
@@ -0,0 +1,161 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64,linux/arm64/v8
|
||||
# platforms_pr: linux/amd64
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=fedora
|
||||
ARG TAG=37
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "target_platform: ${TARGETPLATFORM}"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
# hadolint ignore=DL3041
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
dnf -y update
|
||||
dnf -y group install "Development Tools"
|
||||
dnf -y install \
|
||||
boost-devel-1.78.0* \
|
||||
cmake-3.24.1* \
|
||||
gcc-12.2.1* \
|
||||
gcc-c++-12.2.1* \
|
||||
libcap-devel-2.48* \
|
||||
libcurl-devel-7.85.0* \
|
||||
libdrm-devel-2.4.112* \
|
||||
libevdev-devel-1.13.0* \
|
||||
libva-devel-2.15.0* \
|
||||
libvdpau-devel-1.5* \
|
||||
libX11-devel-1.8.1* \
|
||||
libxcb-devel-1.13.1* \
|
||||
libXcursor-devel-1.2.1* \
|
||||
libXfixes-devel-6.0.0* \
|
||||
libXi-devel-1.8* \
|
||||
libXinerama-devel-1.1.4* \
|
||||
libXrandr-devel-1.5.2* \
|
||||
libXtst-devel-1.2.3* \
|
||||
mesa-libGL-devel-22.2.2* \
|
||||
npm-8.15.0* \
|
||||
numactl-devel-2.0.14* \
|
||||
openssl-devel-3.0.5* \
|
||||
opus-devel-1.3.1* \
|
||||
pulseaudio-libs-devel-16.1* \
|
||||
rpm-build-4.18.0* \
|
||||
wget-1.21.3* \
|
||||
which-2.21*
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
dnf -y install intel-mediasdk-devel-22.4.4*
|
||||
fi
|
||||
dnf clean all
|
||||
rm -rf /var/cache/yum
|
||||
_DEPS
|
||||
|
||||
# install cuda
|
||||
WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="12.0.0"
|
||||
ENV CUDA_BUILD="525.60.13"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
|
||||
cuda_suffix=""
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cuda_suffix="_sbsa"
|
||||
fi
|
||||
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
|
||||
echo "cuda url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
_INSTALL_CUDA
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup npm dependencies
|
||||
RUN npm install
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# cmake and cpack
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake \
|
||||
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_ENABLE_DRM=ON \
|
||||
-DSUNSHINE_ENABLE_CUDA=ON \
|
||||
/build/sunshine
|
||||
make -j "$(nproc)"
|
||||
cpack -G RPM
|
||||
_MAKE
|
||||
|
||||
FROM scratch AS artifacts
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.rpm /sunshine-${BASE}-${TAG}-${TARGETARCH}.rpm
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.rpm /sunshine.rpm
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
dnf -y update
|
||||
dnf -y install /sunshine.rpm
|
||||
dnf clean all
|
||||
rm -rf /var/cache/yum
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
199
docker/ubuntu-20.04.dockerfile
Normal file
199
docker/ubuntu-20.04.dockerfile
Normal file
@@ -0,0 +1,199 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64,linux/arm64/v8
|
||||
# platforms_pr: linux/amd64
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=ubuntu
|
||||
ARG TAG=20.04
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "target_platform: ${TARGETPLATFORM}"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential=12.8* \
|
||||
gcc-10=10.3.0* \
|
||||
g++-10=10.3.0* \
|
||||
libavdevice-dev=7:4.2.* \
|
||||
libboost-filesystem-dev=1.71.0* \
|
||||
libboost-log-dev=1.71.0* \
|
||||
libboost-program-options-dev=1.71.0* \
|
||||
libboost-thread-dev=1.71.0* \
|
||||
libcap-dev=1:2.32* \
|
||||
libcurl4-openssl-dev=7.68.0* \
|
||||
libdrm-dev=2.4.107* \
|
||||
libevdev-dev=1.9.0* \
|
||||
libnuma-dev=2.0.12* \
|
||||
libopus-dev=1.3.1* \
|
||||
libpulse-dev=1:13.99.1* \
|
||||
libssl-dev=1.1.1* \
|
||||
libva-dev=2.7.0* \
|
||||
libvdpau-dev=1.3* \
|
||||
libwayland-dev=1.18.0* \
|
||||
libx11-dev=2:1.6.9* \
|
||||
libxcb-shm0-dev=1.14* \
|
||||
libxcb-xfixes0-dev=1.14* \
|
||||
libxcb1-dev=1.14* \
|
||||
libxfixes-dev=1:5.0.3* \
|
||||
libxrandr-dev=2:1.5.2* \
|
||||
libxtst-dev=2:1.2.3* \
|
||||
nodejs=10.19.0* \
|
||||
npm=6.14.4* \
|
||||
wget=1.20.3*
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
apt-get install -y --no-install-recommends \
|
||||
libmfx-dev=20.1.0*
|
||||
fi
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_DEPS
|
||||
|
||||
# Update gcc alias
|
||||
# https://stackoverflow.com/a/70653945/11214013
|
||||
RUN <<_GCC_ALIAS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
update-alternatives --install \
|
||||
/usr/bin/gcc gcc /usr/bin/gcc-10 100 \
|
||||
--slave /usr/bin/g++ g++ /usr/bin/g++-10 \
|
||||
--slave /usr/bin/gcov gcov /usr/bin/gcov-10 \
|
||||
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-10 \
|
||||
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-10
|
||||
_GCC_ALIAS
|
||||
|
||||
# install cmake
|
||||
# sunshine requires cmake >= 3.18
|
||||
WORKDIR /build/cmake
|
||||
# https://cmake.org/download/
|
||||
ENV CMAKE_VERSION="3.25.1"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CMAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake_prefix="https://github.com/Kitware/CMake/releases/download/v"
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
cmake_arch="x86_64"
|
||||
elif [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cmake_arch="aarch64"
|
||||
fi
|
||||
url="${cmake_prefix}${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-${cmake_arch}.sh"
|
||||
echo "cmake url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cmake.sh
|
||||
sh ./cmake.sh --prefix=/usr/local --skip-license
|
||||
cmake --version
|
||||
_INSTALL_CMAKE
|
||||
|
||||
# install cuda
|
||||
WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="11.8.0"
|
||||
ENV CUDA_BUILD="520.61.05"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
|
||||
cuda_suffix=""
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cuda_suffix="_sbsa"
|
||||
fi
|
||||
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
|
||||
echo "cuda url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
_INSTALL_CUDA
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup npm dependencies
|
||||
RUN npm install
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# cmake and cpack
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake \
|
||||
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_ENABLE_DRM=ON \
|
||||
-DSUNSHINE_ENABLE_CUDA=ON \
|
||||
/build/sunshine
|
||||
make -j "$(nproc)"
|
||||
cpack -G DEB
|
||||
_MAKE
|
||||
|
||||
FROM scratch AS artifacts
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends /sunshine.deb
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
163
docker/ubuntu-22.04.dockerfile
Normal file
163
docker/ubuntu-22.04.dockerfile
Normal file
@@ -0,0 +1,163 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# artifacts: true
|
||||
# platforms: linux/amd64,linux/arm64/v8
|
||||
# platforms_pr: linux/amd64
|
||||
# no-cache-filters: sunshine-base,artifacts,sunshine
|
||||
ARG BASE=ubuntu
|
||||
ARG TAG=22.04
|
||||
FROM ${BASE}:${TAG} AS sunshine-base
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
FROM sunshine-base as sunshine-build
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "target_platform: ${TARGETPLATFORM}"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# install dependencies
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential=12.9* \
|
||||
cmake=3.22.1* \
|
||||
libavdevice-dev=7:4.4.* \
|
||||
libboost-filesystem-dev=1.74.0* \
|
||||
libboost-log-dev=1.74.0* \
|
||||
libboost-program-options-dev=1.74.0* \
|
||||
libboost-thread-dev=1.74.0* \
|
||||
libcap-dev=1:2.44* \
|
||||
libcurl4-openssl-dev=7.81.0* \
|
||||
libdrm-dev=2.4.113* \
|
||||
libevdev-dev=1.12.1* \
|
||||
libnuma-dev=2.0.14* \
|
||||
libopus-dev=1.3.1* \
|
||||
libpulse-dev=1:15.99.1* \
|
||||
libssl-dev=3.0.2* \
|
||||
libva-dev=2.14.0* \
|
||||
libvdpau-dev=1.4* \
|
||||
libwayland-dev=1.20.0* \
|
||||
libx11-dev=2:1.7.5* \
|
||||
libxcb-shm0-dev=1.14* \
|
||||
libxcb-xfixes0-dev=1.14* \
|
||||
libxcb1-dev=1.14* \
|
||||
libxfixes-dev=1:6.0.0* \
|
||||
libxrandr-dev=2:1.5.2* \
|
||||
libxtst-dev=2:1.2.3* \
|
||||
nodejs=12.22.9* \
|
||||
npm=8.5.1* \
|
||||
wget=1.21.2*
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then
|
||||
apt-get install -y --no-install-recommends \
|
||||
libmfx-dev=22.3.0*
|
||||
fi
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_DEPS
|
||||
|
||||
# install cuda
|
||||
WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="11.8.0"
|
||||
ENV CUDA_BUILD="520.61.05"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
|
||||
cuda_suffix=""
|
||||
if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
|
||||
cuda_suffix="_sbsa"
|
||||
fi
|
||||
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
|
||||
echo "cuda url: ${url}"
|
||||
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
_INSTALL_CUDA
|
||||
|
||||
# copy repository
|
||||
WORKDIR /build/sunshine/
|
||||
COPY --link .. .
|
||||
|
||||
# setup npm dependencies
|
||||
RUN npm install
|
||||
|
||||
# setup build directory
|
||||
WORKDIR /build/sunshine/build
|
||||
|
||||
# cmake and cpack
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cmake \
|
||||
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DSUNSHINE_ASSETS_DIR=share/sunshine \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_ENABLE_DRM=ON \
|
||||
-DSUNSHINE_ENABLE_CUDA=ON \
|
||||
/build/sunshine
|
||||
make -j "$(nproc)"
|
||||
cpack -G DEB
|
||||
_MAKE
|
||||
|
||||
FROM scratch AS artifacts
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base as sunshine
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends /sunshine.deb
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
_INSTALL_SUNSHINE
|
||||
|
||||
# network setup
|
||||
EXPOSE 47984-47990/tcp
|
||||
EXPOSE 48010
|
||||
EXPOSE 47998-48000/udp
|
||||
|
||||
# setup user
|
||||
ARG PGID=1000
|
||||
ENV PGID=${PGID}
|
||||
ARG PUID=1000
|
||||
ENV PUID=${PUID}
|
||||
ENV TZ="UTC"
|
||||
ARG UNAME=lizard
|
||||
ENV UNAME=${UNAME}
|
||||
|
||||
ENV HOME=/home/$UNAME
|
||||
|
||||
# setup user
|
||||
RUN <<_SETUP_USER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
groupadd -f -g "${PGID}" "${UNAME}"
|
||||
useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"
|
||||
mkdir -p ${HOME}/.config/sunshine
|
||||
ln -s ${HOME}/.config/sunshine /config
|
||||
chown -R ${UNAME} ${HOME}
|
||||
_SETUP_USER
|
||||
|
||||
USER ${UNAME}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# entrypoint
|
||||
ENTRYPOINT ["/usr/bin/sunshine"]
|
||||
4
docs/requirements.txt
Normal file
4
docs/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
furo==2022.12.7
|
||||
m2r2==0.3.3.post2
|
||||
Sphinx==6.1.3
|
||||
sphinx-copybutton==0.5.1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,3 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/DOCKER_README.md
|
||||
|
||||
.. Todo:: This is a planned feature. Currently no Dockerfile or image exists for Sunshine.
|
||||
|
||||
.. mdinclude:: ../../../DOCKER_README.md
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/about/installation.rst
|
||||
|
||||
Installation
|
||||
============
|
||||
The recommended method for running Sunshine is to use the `binaries`_ bundled with the `latest release`_.
|
||||
|
||||
.. Attention:: Additional setup is required after installation. See
|
||||
:ref:`Setup <about/usage:setup>`.
|
||||
|
||||
Binaries
|
||||
--------
|
||||
Binaries of Sunshine are created for each release. They are available for Linux, and Windows.
|
||||
Binaries of Sunshine are created for each release. They are available for Linux, macOS, and Windows.
|
||||
Binaries can be found in the `latest release`_.
|
||||
|
||||
.. Tip:: Some third party packages also exist. See
|
||||
@@ -14,82 +15,157 @@ Binaries can be found in the `latest release`_.
|
||||
|
||||
Docker
|
||||
------
|
||||
.. Todo:: Docker images of Sunshine are planned to be included in the future.
|
||||
They will be available on `Dockerhub.io`_ and `ghcr.io`_.
|
||||
Docker images are available on `Dockerhub.io`_ and `ghcr.io`_.
|
||||
|
||||
See :ref:`Docker <about/docker:docker>` for additional information.
|
||||
|
||||
Linux
|
||||
-----
|
||||
Follow the instructions for your preferred package type below.
|
||||
|
||||
**CUDA Compatibility**
|
||||
|
||||
CUDA is used for NVFBC capture.
|
||||
|
||||
.. Tip:: See `CUDA GPUS <https://developer.nvidia.com/cuda-gpus>`_ to cross reference Compute Capability to your GPU.
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
=========================================== ============== ============== ================================
|
||||
Package CUDA Version Min Driver CUDA Compute Capabilities
|
||||
=========================================== ============== ============== ================================
|
||||
PKGBUILD User dependent User dependent User dependent
|
||||
sunshine.AppImage 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
sunshine.pkg.tar.zst 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
sunshine_{arch}.flatpak 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
sunshine-debian-bullseye-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
sunshine-fedora-36-{arch}.rpm 12.0.0 525.60.13 50;52;60;61;62;70;75;80;86;90
|
||||
sunshine-fedora-37-{arch}.rpm 12.0.0 525.60.13 50;52;60;61;62;70;75;80;86;90
|
||||
sunshine-ubuntu-20.04-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
sunshine-ubuntu-22.04-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35
|
||||
=========================================== ============== ============== ================================
|
||||
|
||||
AppImage
|
||||
^^^^^^^^
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:appimage?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
According to AppImageLint the supported distro matrix of the AppImage is below.
|
||||
|
||||
According to AppImageLint the AppImage can run on the following distros.
|
||||
- [✖] Debian oldstable (buster)
|
||||
- [✔] Debian stable (bullseye)
|
||||
- [✔] Debian testing (bookworm)
|
||||
- [✔] Debian unstable (sid)
|
||||
- [✔] Ubuntu kinetic
|
||||
- [✔] Ubuntu jammy
|
||||
- [✔] Ubuntu focal
|
||||
- [✖] Ubuntu bionic
|
||||
- [✖] Ubuntu xenial
|
||||
- [✖] Ubuntu trusty
|
||||
- [✖] CentOS 7
|
||||
|
||||
- [✖] Debian oldstable (buster)
|
||||
- [✔] Debian stable (bullseye)
|
||||
- [✔] Debian testing (bookworm)
|
||||
- [✔] Debian unstable (sid)
|
||||
- [✔] Ubuntu jammy
|
||||
- [✔] Ubuntu impish
|
||||
- [✔] Ubuntu focal
|
||||
- [✖] Ubuntu bionic
|
||||
- [✖] Ubuntu xenial
|
||||
- [✖] Ubuntu trusty
|
||||
- [✖] CentOS 7
|
||||
|
||||
#. Download ``sunshine-appimage.zip`` and extract the contents to your home directory.
|
||||
|
||||
AUR Package
|
||||
^^^^^^^^^^^
|
||||
#. Download ``sunshine.AppImage`` to your home directory.
|
||||
#. Open terminal and run the following code.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://aur.archlinux.org/sunshine-git.git
|
||||
cd sunshine-git
|
||||
makepkg -fi
|
||||
./sunshine.AppImage --install
|
||||
|
||||
Debian Package
|
||||
^^^^^^^^^^^^^^
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:deb?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
Start:
|
||||
.. code-block:: bash
|
||||
|
||||
#. Download ``sunshine.deb`` and run the following code.
|
||||
./sunshine.AppImage --install && ./sunshine.AppImage
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
./sunshine.AppImage --remove
|
||||
|
||||
Archlinux PKGBUILD
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
#. Open terminal and run the following code.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt install -f ./sunshine.deb
|
||||
wget https://github.com/LizardByte/Sunshine/releases/latest/download/PKGBUILD
|
||||
makepkg -fi
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
pacman -R sunshine
|
||||
|
||||
Archlinux pkg
|
||||
^^^^^^^^^^^^^
|
||||
#. Open terminal and run the following code.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine.pkg.tar.zst
|
||||
pacman -U --noconfirm sunshine.pkg.tar.zst
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
pacman -R sunshine
|
||||
|
||||
Debian Package
|
||||
^^^^^^^^^^^^^^
|
||||
#. Download ``sunshine-{ubuntu-version}.deb`` and run the following code.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt install -f ./sunshine-{ubuntu-version}.deb
|
||||
|
||||
.. Note:: The ``{ubuntu-version}`` is the version of ubuntu we built the package on. If you are not using Ubuntu and
|
||||
have an issue with one package, you can try another.
|
||||
|
||||
.. Tip:: You can double click the deb file to see details about the package and begin installation.
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt remove sunshine
|
||||
|
||||
Flatpak Package
|
||||
^^^^^^^^^^^^^^^
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:flatpak?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
|
||||
.. Todo:: This package needs to have CUDA added.
|
||||
|
||||
#. Install `Flatpak <https://flatpak.org/setup/>`_ as required.
|
||||
#. Download ``sunshine.flatpak`` and run the following code.
|
||||
#. Download ``sunshine_{arch}.flatpak`` and run the following code.
|
||||
|
||||
.. Note:: Be sure to replace ``{arch}`` with the architecture for your operating system.
|
||||
|
||||
System level (recommended)
|
||||
.. code-block:: bash
|
||||
|
||||
flatpak install --system sunshine.flatpak
|
||||
flatpak install --system ./sunshine_{arch}.flatpak
|
||||
|
||||
User level
|
||||
.. code-block:: bash
|
||||
|
||||
flatpak install --user sunshine.flatpak
|
||||
flatpak install --user ./sunshine_{arch}.flatpak
|
||||
|
||||
Additional installation (required)
|
||||
.. code-block:: bash
|
||||
|
||||
flatpak run --command=additional-install.sh dev.lizardbyte.sunshine
|
||||
|
||||
Start:
|
||||
X11 and NVFBC capture (X11 Only)
|
||||
.. code-block:: bash
|
||||
|
||||
flatpak run dev.lizardbyte.sunshine
|
||||
|
||||
KMS capture (Wayland & X11)
|
||||
.. code-block:: bash
|
||||
|
||||
sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run dev.lizardbyte.sunshine
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
flatpak run --command=remove-additional-install.sh dev.lizardbyte.sunshine
|
||||
flatpak uninstall --delete-data dev.lizardbyte.sunshine
|
||||
|
||||
RPM Package
|
||||
^^^^^^^^^^^
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:rpm?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
|
||||
#. Add `rpmfusion` repositories by running the following code.
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -105,55 +181,76 @@ RPM Package
|
||||
|
||||
.. Tip:: You can double click the rpm file to see details about the package and begin installation.
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
sudo dnf remove sunshine
|
||||
|
||||
macOS
|
||||
-----
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/os:macos?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
Sunshine on macOS is experimental. Gamepads do not work. Other features may not work as expected.
|
||||
|
||||
pkg
|
||||
.. Warning:: The `pkg` does not include runtime dependencies and should be considered experimental.
|
||||
^^^
|
||||
.. Warning:: The `pkg` does not include runtime dependencies.
|
||||
|
||||
#. Download the ``sunshine.pkg`` file and install it as normal.
|
||||
#. Download the ``sunshine.pkg`` file and install it as normal.
|
||||
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
cd /etc/sunshine/assets
|
||||
uninstall_pkg.sh
|
||||
|
||||
Portfile
|
||||
#. Install `MacPorts <https://www.macports.org>`_
|
||||
#. Update the Macports sources.
|
||||
^^^^^^^^
|
||||
#. Install `MacPorts <https://www.macports.org>`_
|
||||
#. Update the Macports sources.
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
sudo nano /opt/local/etc/macports/sources.conf
|
||||
sudo nano /opt/local/etc/macports/sources.conf
|
||||
|
||||
Add this line, replacing your username, below the line that starts with ``rsync``.
|
||||
Add this line, replacing your username, below the line that starts with ``rsync``.
|
||||
``file:///Users/<username>/ports``
|
||||
|
||||
file://Users/<username>/ports
|
||||
``Ctrl+x``, then ``Y`` to exit and save changes.
|
||||
|
||||
``Ctrl+x``, then ``Y`` to exit and save changes.
|
||||
#. Download the ``Portfile`` to ``~/Downloads`` and run the following code.
|
||||
|
||||
#. Download the ``Portfile`` to ``~/Downloads`` and run the following code.
|
||||
.. code-block:: bash
|
||||
|
||||
.. code-block:: bash
|
||||
mkdir -p ~/ports/multimedia/sunshine
|
||||
mv ~/Downloads/Portfile ~/ports/multimedia/sunshine/
|
||||
cd ~/ports
|
||||
portindex
|
||||
sudo port install sunshine
|
||||
|
||||
mkdir -p ~/ports/multimedia/sunshine
|
||||
mv ~/Downlaods/Portfile ~/ports/multimedia/sunshine
|
||||
cd ~/ports
|
||||
portindex
|
||||
sudo port install sunshine
|
||||
#. The first time you start Sunshine, you will be asked to grant access to screen recording and your microphone.
|
||||
|
||||
#. The first time you start Sunshine, you will be asked to grant access to screen recording and your microphone.
|
||||
Uninstall:
|
||||
.. code-block:: bash
|
||||
|
||||
sudo port uninstall sunshine
|
||||
|
||||
Windows
|
||||
-------
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/os:windows:10?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
|
||||
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/os:windows:11?logo=github&style=for-the-badge
|
||||
:alt: GitHub issues by-label
|
||||
Installer
|
||||
^^^^^^^^^
|
||||
#. Download and install ``sunshine-windows-installer.exe``
|
||||
|
||||
Installed option:
|
||||
#. Download and install ``sunshine-windows.exe``
|
||||
.. Attention:: You should carefully select or unselect the options you want to install. Do not blindly install or enable
|
||||
features.
|
||||
|
||||
Standalone option:
|
||||
#. Download and extract ``sunshine-windows.zip``
|
||||
To uninstall, find Sunshine in the list `here <ms-settings:installed-apps>`_ and select "Uninstall" from the overflow
|
||||
menu. Different versions of Windows may provide slightly different steps for uninstall.
|
||||
|
||||
Standalone
|
||||
^^^^^^^^^^
|
||||
#. Download and extract ``sunshine-windows-portable.zip``
|
||||
|
||||
To uninstall, delete the extracted directory which contains the ``sunshine.exe`` file.
|
||||
|
||||
.. _latest release: https://github.com/LizardByte/Sunshine/releases/latest
|
||||
.. _Dockerhub.io: https://hub.docker.com/repository/docker/lizardbyte/sunshine
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/about/third_party_packages.rst
|
||||
|
||||
Third Party Packages
|
||||
====================
|
||||
|
||||
.. Danger:: These packages are not maintained by LizardByte. Use at your own risk.
|
||||
|
||||
AUR
|
||||
---
|
||||
|
||||
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=AUR&style=for-the-badge&query=$.results.0.NumVotes&url=https%3A%2F%2Fapp.lizardbyte.dev%2Funo%2Faur%2Fsunshine.json&logo=archlinux
|
||||
:alt: AUR votes
|
||||
:target: https://aur.archlinux.org/packages/sunshine
|
||||
|
||||
Chocolatey
|
||||
----------
|
||||
|
||||
.. image:: https://img.shields.io/chocolatey/v/Sunshine?style=for-the-badge&logo=chocolatey
|
||||
.. image:: https://img.shields.io/chocolatey/v/sunshine?style=for-the-badge&logo=chocolatey
|
||||
:alt: Chocolatey Version
|
||||
:target: https://community.chocolatey.org/packages/sunshine
|
||||
|
||||
.. image:: https://img.shields.io/chocolatey/dt/sunshine?style=for-the-badge&logo=chocolatey
|
||||
:alt: Chocolatey
|
||||
|
||||
nixpkgs
|
||||
-------
|
||||
.. image:: https://img.shields.io/badge/dynamic/xml?color=orange&label=nixpkgs&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27nix_unstable%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=nixos
|
||||
:alt: nixpgs Version
|
||||
:target: https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/sunshine/default.nix
|
||||
|
||||
Scoop
|
||||
-----
|
||||
|
||||
@@ -22,6 +33,12 @@ Scoop
|
||||
:alt: Scoop Version (extras bucket)
|
||||
:target: https://scoop.sh/#/apps?s=0&d=1&o=true&q=sunshine
|
||||
|
||||
Solus
|
||||
-----
|
||||
.. image:: https://img.shields.io/badge/dynamic/xml?color=orange&label=Solus&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27solus%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=solus
|
||||
:alt: Solus Version
|
||||
:target: https://dev.getsol.us/source/sunshine
|
||||
|
||||
Winget
|
||||
------
|
||||
.. image:: https://img.shields.io/badge/dynamic/xml?color=orange&label=Winget&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27winget%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=microsoft
|
||||
@@ -42,6 +59,3 @@ Legacy GitHub Repo
|
||||
|
||||
.. image:: https://img.shields.io/github/release-date/loki-47-6F-64/sunshine?style=for-the-badge&logo=github
|
||||
:alt: GitHub Release Date
|
||||
|
||||
.. image:: https://img.shields.io/github/downloads/loki-47-6F-64/sunshine/total?style=for-the-badge&logo=github
|
||||
:alt: GitHub Releases
|
||||
|
||||
@@ -1,33 +1,42 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/about/usage.rst
|
||||
|
||||
Usage
|
||||
=====
|
||||
#. See the `setup`_ section for your specific OS.
|
||||
#. Run ``sunshine <directory of conf file>/sunshine.conf``.
|
||||
#. If you did not install the service, then start sunshine with the following command, unless a start command is listed
|
||||
in the specified package :ref:`installation <about/installation:installation>` instructions.
|
||||
|
||||
.. Note:: You do not need to specify a config file. If no config file is entered the default location will be used.
|
||||
.. Note:: A service is a process that runs in the background. Running multiple instances of Sunshine is not
|
||||
advised.
|
||||
|
||||
.. Attention:: The configuration file specified will be created if it doesn't exist.
|
||||
**Basic usage**
|
||||
.. code-block:: bash
|
||||
|
||||
.. Tip:: If using the Linux AppImage, replace ``sunshine`` with ``./sunshine.AppImage``
|
||||
sunshine
|
||||
|
||||
**Specify config file**
|
||||
.. code-block:: bash
|
||||
|
||||
sunshine <directory of conf file>/sunshine.conf
|
||||
|
||||
.. Note:: You do not need to specify a config file. If no config file is entered the default location will be used.
|
||||
|
||||
.. Attention:: The configuration file specified will be created if it doesn't exist.
|
||||
|
||||
#. Configure Sunshine in the web ui
|
||||
|
||||
The web ui is available on `https://localhost:47990 <https://localhost:47990>`_ by default. You may replace
|
||||
`localhost` with your internal ip address.
|
||||
|
||||
.. Attention:: Ignore any warning given by your browser about "insecure website".
|
||||
.. Attention:: Ignore any warning given by your browser about "insecure website". This is due to the SSL certificate
|
||||
being self signed.
|
||||
|
||||
.. Caution:: If running for the first time, make sure to note the username and password Sunshine showed to you,
|
||||
since you cannot get back later!
|
||||
.. Caution:: If running for the first time, make sure to note the username and password that you created.
|
||||
|
||||
Add games and applications.
|
||||
This can be configured in the web ui.
|
||||
**Add games and applications.**
|
||||
This can be configured in the web ui.
|
||||
|
||||
.. Note:: Additionally, apps can be configured manually. `src_assets/<os>/config/apps.json` is an example of a
|
||||
list of applications that are started just before running a stream. This is the directory within the GitHub
|
||||
repo.
|
||||
|
||||
.. Attention:: Application list is not fully supported on macOS
|
||||
.. Note:: Additionally, apps can be configured manually. `src_assets/<os>/config/apps.json` is an example of a
|
||||
list of applications that are started just before running a stream. This is the directory within the GitHub
|
||||
repo.
|
||||
|
||||
#. In Moonlight, you may need to add the PC manually.
|
||||
#. When Moonlight request you insert the correct pin on sunshine:
|
||||
@@ -39,14 +48,13 @@ Usage
|
||||
|
||||
Network
|
||||
-------
|
||||
Sunshine will be available on port 47990 by default.
|
||||
The Sunshine user interface will be available on port 47990 by default.
|
||||
|
||||
.. Danger:: Do not expose port 47990, or the web ui, to the internet!
|
||||
.. Warning:: Exposing ports to the internet can be dangerous. Do this at your own risk.
|
||||
|
||||
Arguments
|
||||
---------
|
||||
To get a list of available arguments run the following:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sunshine --help
|
||||
@@ -56,7 +64,7 @@ Setup
|
||||
|
||||
Linux
|
||||
^^^^^
|
||||
The deb and rpm packages handle these steps automatically. The AppImage does not, third party packages may not as well.
|
||||
The `deb`, `rpm`, `Flatpak` and `AppImage` packages handle these steps automatically. Third party packages may not.
|
||||
|
||||
Sunshine needs access to `uinput` to create mouse and gamepad events.
|
||||
|
||||
@@ -66,32 +74,28 @@ Sunshine needs access to `uinput` to create mouse and gamepad events.
|
||||
sudo usermod -a -G input $USER
|
||||
|
||||
#. Create `udev` rules.
|
||||
.. code-block:: bash
|
||||
|
||||
sudo nano /etc/udev/rules.d/85-sunshine.rules
|
||||
|
||||
Input the following contents.
|
||||
|
||||
.. code-block::
|
||||
|
||||
KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"
|
||||
|
||||
Save the file and exit:
|
||||
|
||||
#. ``CTRL+X`` to start exit.
|
||||
#. ``Y`` to save modifications.
|
||||
echo 'KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"' | \
|
||||
sudo tee /etc/udev/rules.d/85-sunshine-input.rules
|
||||
|
||||
#. Optionally, configure autostart service
|
||||
- filename: ``~/.config/systemd/user/sunshine.service``
|
||||
- contents:
|
||||
|
||||
- filename: ``~/.config/systemd/user/sunshine.service``
|
||||
- contents:
|
||||
.. code-block::
|
||||
|
||||
[Unit]
|
||||
Description=Sunshine Gamestream Server for Moonlight
|
||||
Description=Sunshine self-hosted game stream host for Moonlight.
|
||||
StartLimitIntervalSec=500
|
||||
StartLimitBurst=5
|
||||
|
||||
[Service]
|
||||
ExecStart=<see table>
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
#Flatpak Only
|
||||
#ExecStop=flatpak kill dev.lizardbyte.sunshine
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
@@ -105,16 +109,16 @@ Sunshine needs access to `uinput` to create mouse and gamepad events.
|
||||
aur /usr/bin/sunshine ✔
|
||||
deb /usr/bin/sunshine ✔
|
||||
rpm /usr/bin/sunshine ✔
|
||||
AppImage ~/sunshine.AppImage ✖
|
||||
Flatpak flatpak run dev.lizardbyte.sunshine ✖
|
||||
AppImage ~/sunshine.AppImage ✔
|
||||
Flatpak flatpak run dev.lizardbyte.sunshine ✔
|
||||
======== ============================================== ===============
|
||||
|
||||
Start once
|
||||
**Start once**
|
||||
.. code-block:: bash
|
||||
|
||||
systemctl --user start sunshine
|
||||
|
||||
Start on boot
|
||||
**Start on boot**
|
||||
.. code-block:: bash
|
||||
|
||||
systemctl --user enable sunshine
|
||||
@@ -123,12 +127,12 @@ Sunshine needs access to `uinput` to create mouse and gamepad events.
|
||||
.. Note:: ``cap_sys_admin`` may as well be root, except you don't need to be root to run it. It is necessary to
|
||||
allow Sunshine to use KMS.
|
||||
|
||||
Enable
|
||||
**Enable**
|
||||
.. code-block:: bash
|
||||
|
||||
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
|
||||
|
||||
Disable
|
||||
**Disable (for Xorg/X11)**
|
||||
.. code-block:: bash
|
||||
|
||||
sudo setcap -r $(readlink -f $(which sunshine))
|
||||
@@ -142,16 +146,14 @@ macOS
|
||||
^^^^^
|
||||
Sunshine can only access microphones on macOS due to system limitations. To stream system audio use
|
||||
`Soundflower <https://github.com/mattingalls/Soundflower>`_ or
|
||||
`BlackHole <https://github.com/ExistentialAudio/BlackHole>`_ and
|
||||
select their sink as audio device in `sunshine.conf`.
|
||||
`BlackHole <https://github.com/ExistentialAudio/BlackHole>`_.
|
||||
|
||||
.. Note:: Command Keys are not forwarded by Moonlight. Right Option-Key is mapped to CMD-Key.
|
||||
|
||||
.. Caution:: Gamepads are not currently supported.
|
||||
|
||||
Configure autostart service
|
||||
|
||||
MacPorts
|
||||
**MacPorts**
|
||||
.. code-block:: bash
|
||||
|
||||
sudo port load Sunshine
|
||||
@@ -160,62 +162,120 @@ Windows
|
||||
^^^^^^^
|
||||
For gamepad support, install `ViGEmBus <https://github.com/ViGEm/ViGEmBus/releases/latest>`_
|
||||
|
||||
Sunshine firewall
|
||||
**Add rule**
|
||||
.. code-block:: batch
|
||||
|
||||
cd /d "C:\Program Files\Sunshine\scripts"
|
||||
add-firewall-rule.bat
|
||||
|
||||
**Remove rule**
|
||||
.. code-block:: batch
|
||||
|
||||
cd /d "C:\Program Files\Sunshine\scripts"
|
||||
remove-firewall-rule.bat
|
||||
|
||||
Sunshine service
|
||||
**Enable**
|
||||
.. code-block:: batch
|
||||
|
||||
cd /d "C:\Program Files\Sunshine\scripts"
|
||||
install-service.bat
|
||||
|
||||
**Disable**
|
||||
.. code-block:: batch
|
||||
|
||||
cd /d "C:\Program Files\Sunshine\scripts"
|
||||
uninstall-service.bat
|
||||
|
||||
Shortcuts
|
||||
---------
|
||||
All shortcuts start with CTRL + ALT + SHIFT, just like Moonlight
|
||||
All shortcuts start with ``CTRL + ALT + SHIFT``, just like Moonlight
|
||||
|
||||
- ``CTRL + ALT + SHIFT + N`` - Hide/Unhide the cursor (This may be useful for Remote Desktop Mode for Moonlight)
|
||||
- ``CTRL + ALT + SHIFT + F1/F13`` - Switch to different monitor for Streaming
|
||||
- ``CTRL + ALT + SHIFT + N`` - Hide/Unhide the cursor (This may be useful for Remote Desktop Mode for Moonlight)
|
||||
- ``CTRL + ALT + SHIFT + F1/F12`` - Switch to different monitor for Streaming
|
||||
|
||||
Application List
|
||||
----------------
|
||||
- Applications should be configured via the web UI.
|
||||
- A basic understanding of working directories and commands is required.
|
||||
- You can use Environment variables in place of values
|
||||
- ``$(HOME)`` will be replaced by the value of ``$HOME``
|
||||
- ``$$`` will be replaced by ``$``, e.g. ``$$(HOME)`` will be replaced by ``$(HOME)``
|
||||
- ``$$`` will be replaced by ``$``, e.g. ``$$(HOME)`` will be become ``$(HOME)``
|
||||
- ``env`` - Adds or overwrites Environment variables for the commands/applications run by Sunshine
|
||||
- ``"Variable name":"Variable value"``
|
||||
- ``apps`` - The list of applications
|
||||
- Advanced users may want to edit the application list manually. The format is ``json``.
|
||||
- Example application:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"name":"An App",
|
||||
"cmd":"command to open app",
|
||||
"prep-cmd":[
|
||||
{
|
||||
"do":"some-command",
|
||||
"undo":"undo-that-command"
|
||||
}
|
||||
],
|
||||
"detached":[
|
||||
"some-command",
|
||||
"another-command"
|
||||
]
|
||||
"cmd": "command to open app",
|
||||
"detached": [
|
||||
"some-command",
|
||||
"another-command"
|
||||
],
|
||||
"image-path": "/full-path/to/png-image",
|
||||
"name": "An App",
|
||||
"output": "/full-path/to/command-log-file",
|
||||
"prep-cmd": [
|
||||
{
|
||||
"do": "some-command",
|
||||
"undo": "undo-that-command"
|
||||
}
|
||||
],
|
||||
"working-dir": "/full-path/to/working-directory"
|
||||
}
|
||||
|
||||
- ``cmd`` - The main application
|
||||
- ``detached`` - A list of commands to be run and forgotten about
|
||||
|
||||
- If not specified, a process is started that sleeps indefinitely
|
||||
|
||||
- ``image-path`` - The full path to the cover art image to use.
|
||||
- ``name`` - The name of the application/game
|
||||
- ``output`` - The file where the output of the command is stored
|
||||
- ``detached`` - A list of commands to be run and forgotten about
|
||||
- ``prep-cmd`` - A list of commands to be run before/after the application
|
||||
|
||||
- If any of the prep-commands fail, starting the application is aborted
|
||||
- ``do`` - Run before the application
|
||||
- If any of the prep-commands fail, starting the application is aborted
|
||||
- ``do`` - Run before the application
|
||||
|
||||
- If it fails, all ``undo`` commands of the previously succeeded ``do`` commands are run
|
||||
- If it fails, all ``undo`` commands of the previously succeeded ``do`` commands are run
|
||||
|
||||
- ``undo`` - Run after the application has terminated
|
||||
- ``undo`` - Run after the application has terminated
|
||||
|
||||
- This should not fail considering it is supposed to undo the ``do`` commands
|
||||
- If it fails, Sunshine is terminated
|
||||
- Failures of ``undo`` commands are ignored
|
||||
|
||||
- ``cmd`` - The main application
|
||||
|
||||
- If not specified, a process is started that sleeps indefinitely
|
||||
- ``working-dir`` - The working directory to use. If not specified, Sunshine will use the application directory.
|
||||
|
||||
Considerations
|
||||
--------------
|
||||
- When an application is started, if there is an application already running, it will be terminated.
|
||||
- When the application has been shutdown, the stream shuts down as well.
|
||||
|
||||
- For example, if you attempt to run ``steam`` as a ``cmd`` instead of ``detached`` the stream will immediately fail.
|
||||
This is due to the method in which the steam process is executed. Other applications may behave similarly.
|
||||
|
||||
- In addition to the apps listed, one app "Desktop" is hardcoded into Sunshine. It does not start an application,
|
||||
instead it simply starts a stream.
|
||||
- For the Linux flatpak you must prepend commands with ``flatpak-spawn --host``.
|
||||
|
||||
HDR Support
|
||||
-----------
|
||||
Streaming HDR content is supported for Windows hosts with NVIDIA, AMD, or Intel GPUs that support encoding HEVC Main 10.
|
||||
You must have an HDR-capable display or EDID emulator dongle connected to your host PC to activate HDR in Windows.
|
||||
|
||||
- Ensure you enable the HDR option in your Moonlight client settings, otherwise the stream will be SDR.
|
||||
- A good HDR experience relies on proper HDR display calibration both in Windows and in game. HDR calibration can differ significantly between client and host displays.
|
||||
- We recommend calibrating the display by streaming the Windows HDR Calibration app to your client device and saving an HDR calibration profile to use while streaming.
|
||||
- You may also need to tune the brightness slider or HDR calibration options in game to the different HDR brightness capabilities of your client's display.
|
||||
- Older games that use NVIDIA-specific NVAPI HDR rather than native Windows 10 OS HDR support may not display in HDR.
|
||||
- Some GPUs can produce lower image quality or encoding performance when streaming in HDR compared to SDR.
|
||||
|
||||
Tutorials
|
||||
---------
|
||||
Tutorial videos are available `here <https://www.youtube.com/playlist?list=PLMYr5_xSeuXAbhxYHz86hA1eCDugoxXY0>`_.
|
||||
|
||||
.. admonition:: Community!
|
||||
|
||||
Tutorials are community generated. Want to contribute? Reach out to us on our discord server.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/building/build.rst
|
||||
|
||||
Build
|
||||
=====
|
||||
Sunshine binaries are built using `CMake <https://cmake.org/>`_. Cross compilation is not
|
||||
@@ -11,7 +9,6 @@ Building Locally
|
||||
Clone
|
||||
^^^^^
|
||||
Ensure `git <https://git-scm.com/>`_ is installed and run the following:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/lizardbyte/sunshine.git --recurse-submodules
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/building/linux.rst
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Requirements
|
||||
------------
|
||||
.. Danger:: Installing these dependencies may break your distribution. It is recommended to build in a virtual machine
|
||||
or to use the `Dockerfile builds`_ located in the `./scripts` directory.
|
||||
|
||||
Debian Bullseye
|
||||
^^^^^^^^^^^^^^^
|
||||
@@ -18,17 +14,22 @@ Install Requirements
|
||||
sudo apt update && sudo apt install \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-program-options-dev \
|
||||
libboost-thread-dev \
|
||||
libcap-dev \ # KMS
|
||||
libcurl4-openssl-dev \
|
||||
libdrm-dev \ # KMS
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libmfx-dev \ # x86_64 only
|
||||
libnuma-dev \
|
||||
libopus-dev \
|
||||
libpulse-dev \
|
||||
libssl-dev \
|
||||
libva-dev \
|
||||
libvdpau-dev \
|
||||
libwayland-dev \ # Wayland
|
||||
libx11-dev \ # X11
|
||||
libxcb-shm0-dev \ # X11
|
||||
@@ -37,108 +38,49 @@ Install Requirements
|
||||
libxfixes-dev \ # X11
|
||||
libxrandr-dev \ # X11
|
||||
libxtst-dev \ # X11
|
||||
nodejs \
|
||||
npm \
|
||||
nvidia-cuda-dev \ # Cuda, NvFBC
|
||||
nvidia-cuda-toolkit \ # Cuda, NvFBC
|
||||
nvidia-cuda-toolkit # Cuda, NvFBC
|
||||
|
||||
Fedora 35
|
||||
^^^^^^^^^
|
||||
Fedora 36, 37
|
||||
^^^^^^^^^^^^^
|
||||
End of Life: TBD
|
||||
|
||||
Install Repositories
|
||||
.. code-block:: bash
|
||||
|
||||
sudo dnf update && \
|
||||
sudo dnf group install "Development Tools" && \
|
||||
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
|
||||
Install Requirements
|
||||
.. code-block:: bash
|
||||
|
||||
sudo dnf update && \
|
||||
sudo dnf group install "Development Tools" && \
|
||||
sudo dnf install \
|
||||
boost-devel \
|
||||
boost-static.x86_64 \
|
||||
cmake \
|
||||
ffmpeg-devel \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
intel-mediasdk-devel \ # x86_64 only
|
||||
libcap-devel \
|
||||
libcurl-devel \
|
||||
libdrm-devel \
|
||||
libevdev-devel \
|
||||
libva-devel \
|
||||
libvdpau-devel \
|
||||
libX11-devel \ # X11
|
||||
libxcb-devel \ # X11
|
||||
libXcursor-devel \ # X11
|
||||
libXfixes-devel \ # X11
|
||||
libXinerama-devel \ # X11
|
||||
libXi-devel \ # X11
|
||||
libXinerama-devel \ # X11
|
||||
libXrandr-devel \ # X11
|
||||
libXtst-devel \ # X11
|
||||
mesa-libGL-devel \
|
||||
npm \
|
||||
numactl-devel \
|
||||
openssl-devel \
|
||||
opus-devel \
|
||||
pulseaudio-libs-devel \
|
||||
rpm-build \ # if you want to build an RPM binary package
|
||||
|
||||
Ubuntu 18.04
|
||||
^^^^^^^^^^^^
|
||||
End of Life: April 2028
|
||||
|
||||
Install Repositories
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt update && sudo apt install \
|
||||
software-properties-common \
|
||||
&& add-apt-repository ppa:savoury1/graphics && \
|
||||
add-apt-repository ppa:savoury1/multimedia && \
|
||||
add-apt-repository ppa:savoury1/ffmpeg4 && \
|
||||
add-apt-repository ppa:savoury1/boost-defaults-1.71 && \
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test && \
|
||||
|
||||
Install Requirements
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt install \
|
||||
build-essential \
|
||||
cmake \
|
||||
gcc-10 \
|
||||
git \
|
||||
g++-10 \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem1.71-dev \
|
||||
libboost-log1.71-dev \
|
||||
libboost-regex1.71-dev \
|
||||
libboost-thread1.71-dev \
|
||||
libcap-dev \ # KMS
|
||||
libdrm-dev \ # KMS
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \ # Wayland
|
||||
libx11-dev \ # X11
|
||||
libxcb-shm0-dev \ # X11
|
||||
libxcb-xfixes0-dev \ # X11
|
||||
libxcb1-dev \ # X11
|
||||
libxfixes-dev \ # X11
|
||||
libxrandr-dev \ # X11
|
||||
libxtst-dev \ # X11
|
||||
wget \
|
||||
|
||||
Update gcc alias
|
||||
.. code-block:: bash
|
||||
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
||||
|
||||
Install CuDA
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O ./cuda.run && chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm ./cuda.run
|
||||
|
||||
Install CMake
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh
|
||||
mkdir /opt/cmake
|
||||
sh /cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license
|
||||
ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
cmake --version
|
||||
wget \ # necessary for cuda install with `run` file
|
||||
which # necessary for cuda install with `run` file
|
||||
|
||||
Ubuntu 20.04
|
||||
^^^^^^^^^^^^
|
||||
@@ -150,18 +92,22 @@ Install Requirements
|
||||
sudo apt update && sudo apt install \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
g++-10 \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libboost-program-options-dev \
|
||||
libcap-dev \ # KMS
|
||||
libdrm-dev \ # KMS
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libmfx-dev \ # x86_64 only
|
||||
libnuma-dev \
|
||||
libopus-dev \
|
||||
libpulse-dev \
|
||||
libssl-dev \
|
||||
libva-dev \
|
||||
libvdpau-dev \
|
||||
libwayland-dev \ # Wayland
|
||||
libx11-dev \ # X11
|
||||
libxcb-shm0-dev \ # X11
|
||||
@@ -170,22 +116,23 @@ Install Requirements
|
||||
libxfixes-dev \ # X11
|
||||
libxrandr-dev \ # X11
|
||||
libxtst-dev \ # X11
|
||||
wget \
|
||||
nodejs \
|
||||
npm \
|
||||
wget # necessary for cuda install with `run` file
|
||||
|
||||
Update gcc alias
|
||||
.. code-block:: bash
|
||||
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
||||
update-alternatives --install \
|
||||
/usr/bin/gcc gcc /usr/bin/gcc-10 100 \
|
||||
--slave /usr/bin/g++ g++ /usr/bin/g++-10 \
|
||||
--slave /usr/bin/gcov gcov /usr/bin/gcov-10 \
|
||||
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-10 \
|
||||
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-10
|
||||
|
||||
Install CuDA
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O ./cuda.run && chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm ./cuda.run
|
||||
|
||||
Ubuntu 21.10
|
||||
Ubuntu 22.04
|
||||
^^^^^^^^^^^^
|
||||
End of Life: July 2022
|
||||
End of Life: April 2027
|
||||
|
||||
Install Requirements
|
||||
.. code-block:: bash
|
||||
@@ -193,16 +140,18 @@ Install Requirements
|
||||
sudo apt update && sudo apt install \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libboost-program-options-dev \
|
||||
libcap-dev \ # KMS
|
||||
libdrm-dev \ # KMS
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libmfx-dev \ # x86_64 only
|
||||
libnuma-dev \
|
||||
libopus-dev \
|
||||
libpulse-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \ # Wayland
|
||||
libx11-dev \ # X11
|
||||
@@ -212,91 +161,44 @@ Install Requirements
|
||||
libxfixes-dev \ # X11
|
||||
libxrandr-dev \ # X11
|
||||
libxtst-dev \ # X11
|
||||
nvidia-cuda-dev \ # Cuda, NvFBC
|
||||
nvidia-cuda-toolkit \ # Cuda, NvFBC
|
||||
nodejs \
|
||||
npm \
|
||||
nvidia-cuda-dev \ # CUDA, NvFBC
|
||||
nvidia-cuda-toolkit # CUDA, NvFBC
|
||||
|
||||
Ubuntu 22.04
|
||||
^^^^^^^^^^^^
|
||||
End of Life: April 2027
|
||||
CUDA
|
||||
----
|
||||
If the version of CUDA available from your distro is not adequate, manually install CUDA.
|
||||
|
||||
.. Todo:: Create Ubuntu 22.04 Dockerfile and complete this documentation.
|
||||
.. Tip:: The version of CUDA you use will determine compatibility with various GPU generations.
|
||||
See `CUDA compatibility <https://docs.nvidia.com/deploy/cuda-compatibility/index.html>`_ for more info.
|
||||
|
||||
Select the appropriate run file based on your desired CUDA version and architecture according to
|
||||
`CUDA Toolkit Archive <https://developer.nvidia.com/cuda-toolkit-archive>`_.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run \
|
||||
--progress=bar:force:noscroll -q --show-progress -O ./cuda.run
|
||||
chmod a+x ./cuda.run
|
||||
./cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm
|
||||
rm ./cuda.run
|
||||
|
||||
npm dependencies
|
||||
----------------
|
||||
Install npm dependencies.
|
||||
.. code-block:: bash
|
||||
|
||||
npm install
|
||||
|
||||
Build
|
||||
-----
|
||||
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
|
||||
|
||||
Debian based OSes
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 ..
|
||||
cmake ..
|
||||
make -j ${nproc}
|
||||
|
||||
Red Hat based Oses
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..
|
||||
|
||||
Finally
|
||||
.. code-block:: bash
|
||||
|
||||
make -j ${nproc}
|
||||
cpack -G DEB # optionally, create a deb package
|
||||
cpack -G RPM # optionally, create a rpm package
|
||||
|
||||
Dockerfile Builds
|
||||
-----------------
|
||||
You may wish to simply build sunshine from source, without bloating your OS with development files.
|
||||
There are scripts located in the ``./scripts`` directory that will create docker images that have the necessary
|
||||
packages. As a result, removing the development files after you're done is a single command away.
|
||||
These scripts use docker under the hood, as such, they can only be used to compile the Linux version
|
||||
|
||||
.. Todo:: Publish the Dockerfiles to Dockerhub and ghcr.
|
||||
|
||||
Requirements
|
||||
Install `Docker <https://docs.docker.com/engine/install/>`_
|
||||
|
||||
Instructions
|
||||
#. :ref:`Clone <building/build:clone>`. Sunshine.
|
||||
#. Select the desired Dockerfile from the ``./scripts`` directory.
|
||||
|
||||
Available Files:
|
||||
.. code-block:: text
|
||||
|
||||
Dockerfile-debian
|
||||
Dockerfile-fedora_33 # end of life
|
||||
Dockerfile-fedora_35
|
||||
Dockerfile-ubuntu_18_04
|
||||
Dockerfile-ubuntu_20_04
|
||||
Dockerfile-ubuntu_21_04 # end of life
|
||||
Dockerfile-ubuntu_21_10
|
||||
|
||||
#. Execute
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd scripts # move to the scripts directory
|
||||
./build-container.sh -f Dockerfile-<name> # create the container (replace the "<name>")
|
||||
./build-sunshine.sh -p -s .. # compile and build sunshine
|
||||
|
||||
#. Updating
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git pull # pull the latest changes from github
|
||||
./build-sunshine.sh -p -s .. # compile and build sunshine
|
||||
|
||||
#. Optionally, delete the container
|
||||
.. code-block:: bash
|
||||
|
||||
./build-container.sh -c delete
|
||||
|
||||
#. Install the resulting package
|
||||
|
||||
Debian
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt install -f sunshine-build/sunshine.deb
|
||||
|
||||
Red Hat
|
||||
.. code-block:: bash
|
||||
|
||||
sudo dnf install sunshine-build/sunshine.rpm
|
||||
cpack -G DEB # optionally, create a deb package
|
||||
cpack -G RPM # optionally, create a rpm package
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/building/macos.rst
|
||||
|
||||
macOS
|
||||
=====
|
||||
|
||||
@@ -14,30 +12,35 @@ MacPorts
|
||||
Install Requirements
|
||||
.. code-block:: bash
|
||||
|
||||
sudo port install cmake boost ffmpeg libopus
|
||||
sudo port install avahi boost180 cmake curl libopus npm9 pkgconfig
|
||||
|
||||
Homebrew
|
||||
""""""""
|
||||
Install Requirements
|
||||
.. code-block:: bash
|
||||
|
||||
brew install boost cmake ffmpeg opus
|
||||
brew install boost cmake node opus
|
||||
# if there are issues with an SSL header that is not found:
|
||||
cd /usr/local/include
|
||||
ln -s ../opt/openssl/include/openssl .
|
||||
|
||||
npm dependencies
|
||||
----------------
|
||||
Install npm dependencies.
|
||||
.. code-block:: bash
|
||||
|
||||
npm install
|
||||
|
||||
Build
|
||||
-----
|
||||
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
cmake ..
|
||||
make -j ${nproc}
|
||||
cmake ..
|
||||
make -j ${nproc}
|
||||
|
||||
cpack -G DragNDrop # optionally, create a macOS dmg package
|
||||
cpack -G DragNDrop # optionally, create a macOS dmg package
|
||||
|
||||
If cmake fails complaining to find Boost, try to set the path explicitly.
|
||||
|
||||
``cmake -DBOOST_ROOT=[boost path] ..``, e.g., ``cmake -DBOOST_ROOT=/opt/local/libexec/boost/1.76 ..``
|
||||
|
||||
``cmake -DBOOST_ROOT=[boost path] ..``, e.g., ``cmake -DBOOST_ROOT=/opt/local/libexec/boost/1.80 ..``
|
||||
|
||||
@@ -1,27 +1,41 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/building/windows.rst
|
||||
|
||||
Windows
|
||||
=======
|
||||
|
||||
Requirements
|
||||
------------
|
||||
First you need to install `MSYS2 <https://www.msys2.org>`_, then startup "MSYS2 MinGW 64-bit" and install the
|
||||
following packages using:
|
||||
First you need to install `MSYS2 <https://www.msys2.org>`_, then startup "MSYS2 MinGW 64-bit" and execute the following
|
||||
codes.
|
||||
|
||||
.. code-block:: bash
|
||||
Update all packages:
|
||||
.. code-block:: bash
|
||||
|
||||
pacman -S mingw-w64-x86_64-binutils mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git mingw-w64-x86_64-make cmake make gcc
|
||||
pacman -Suy
|
||||
|
||||
Install dependencies:
|
||||
.. code-block:: bash
|
||||
|
||||
pacman -S base-devel cmake diffutils gcc git make mingw-w64-x86_64-binutils \
|
||||
mingw-w64-x86_64-boost mingw-w64-x86_64-cmake mingw-w64-x86_64-curl \
|
||||
mingw-w64-x86_64-libmfx mingw-w64-x86_64-openssl mingw-w64-x86_64-opus \
|
||||
mingw-w64-x86_64-toolchain
|
||||
|
||||
npm dependencies
|
||||
----------------
|
||||
Install nodejs and npm. Downloads available `here <https://nodejs.org/en/download/>`_.
|
||||
|
||||
Install npm dependencies.
|
||||
.. code-block:: bash
|
||||
|
||||
npm install
|
||||
|
||||
Build
|
||||
-----
|
||||
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -G"Unix Makefiles" ..
|
||||
cmake -G"MinGW Makefiles" .. # alternatively
|
||||
cmake -G "MinGW Makefiles" ..
|
||||
mingw32-make -j$(nproc)
|
||||
|
||||
mingw32-make
|
||||
|
||||
cpack -G NSIS # optionally, create a windows installer
|
||||
cpack -G ZIP # optionally, create a windows standalone package
|
||||
cpack -G NSIS # optionally, create a windows installer
|
||||
cpack -G ZIP # optionally, create a windows standalone package
|
||||
|
||||
@@ -73,23 +73,11 @@ html_logo = os.path.join(root_dir, 'sunshine.png')
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme = 'furo'
|
||||
|
||||
html_theme_options = {
|
||||
# 'analytics_id': 'G-XXXXXXXXXX', # Provided by Google in your dashboard
|
||||
# 'analytics_anonymize_ip': False,
|
||||
'logo_only': False,
|
||||
'display_version': False,
|
||||
'prev_next_buttons_location': 'bottom',
|
||||
'style_external_links': True,
|
||||
'vcs_pageview_mode': 'blob',
|
||||
'style_nav_header_background': '#151515',
|
||||
# Toc options
|
||||
'collapse_navigation': True,
|
||||
'sticky_navigation': True,
|
||||
'navigation_depth': 4,
|
||||
'includehidden': True,
|
||||
'titles_only': False,
|
||||
"top_of_page_button": "edit",
|
||||
"source_edit_link": "https://github.com/lizardbyte/sunshine/tree/nightly/docs/source/{filename}",
|
||||
}
|
||||
|
||||
# extension config options
|
||||
|
||||
@@ -1,39 +1,5 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/contributing/contributing.rst
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
.. Tip:: If this is your first time contributing to an open source project, it is a good idea to read
|
||||
MDN's `Basic etiquette for open source projects`_ first. There are a few best practices to adopt that will help
|
||||
ensure that you and the other project contributors feel valued and safe, and stay productive.
|
||||
|
||||
#. Fork the repo on GitHub
|
||||
#. Create a new branch for the feature you are adding or the issue you are fixing
|
||||
|
||||
.. Tip:: Base the new branch off the `nightly` branch. It will make your life easier when you submit the PR!
|
||||
|
||||
#. Make changes, push commits, etc.
|
||||
#. Files should contain an empty line at the end.
|
||||
#. Document your code!
|
||||
#. Test your code!
|
||||
#. When ready create a PR to this repo on the `nightly` branch.
|
||||
|
||||
.. Hint:: If you accidentally make your PR against a different branch, a bot will comment letting you know it's on
|
||||
the wrong branch. Don't worry. You can edit the PR to change the target branch. There is no reason to close the
|
||||
PR!
|
||||
|
||||
.. Note:: Draft PRs are also welcome as you work through issues. The benefit of creating a draft PR is that an
|
||||
automated build can run in a github runner.
|
||||
|
||||
.. Attention:: Do not expect partially complete PRs to be merged. These topics will be considered before merging.
|
||||
|
||||
- Does the code follows the style guidelines of this project?
|
||||
|
||||
.. Tip:: Look at examples of existing code in the project!
|
||||
|
||||
- Is the code well commented?
|
||||
- Were documentation blocks updated for new or modified components?
|
||||
|
||||
.. Note:: Developers and maintainers will attempt to assist with challenging issues.
|
||||
|
||||
.. _Basic etiquette for open source projects: https://developer.mozilla.org/en-US/docs/MDN/Contribute/Open_source_etiquette
|
||||
Read our contribution guide in our organization level
|
||||
`docs <https://lizardbyte.readthedocs.io/en/latest/developers/contributing.html>`_.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/contributing/localization.rst
|
||||
|
||||
Localization
|
||||
============
|
||||
Sunshine is being localized into various languages. The default language is `en` (English) and is highlighted green.
|
||||
@@ -24,15 +22,15 @@ Only elements of the API are planned to be translated.
|
||||
|
||||
.. Attention:: The rest API has not yet been implemented.
|
||||
|
||||
Translations Basics
|
||||
**Translations Basics**
|
||||
- The brand names `LizardByte` and `Sunshine` should never be translated.
|
||||
- Other brand names should never be translated.
|
||||
Examples:
|
||||
|
||||
- AMD
|
||||
- Nvidia
|
||||
- AMD
|
||||
- Nvidia
|
||||
|
||||
CrowdIn Integration
|
||||
**CrowdIn Integration**
|
||||
How does it work?
|
||||
|
||||
When a change is made to sunshine source code, a workflow generates new translation templates
|
||||
@@ -47,15 +45,14 @@ Extraction
|
||||
There should be minimal cases where strings need to be extracted from source code; however it may be necessary in some
|
||||
situations. For example if a system tray icon is added it should be localized as it is user interfacing.
|
||||
|
||||
- Wrap the string to be extracted in a function as shown.
|
||||
- Wrap the string to be extracted in a function as shown.
|
||||
.. code-block:: cpp
|
||||
|
||||
.. code-block:: cpp
|
||||
#include <boost/locale.hpp>
|
||||
boost::locale::translate("Hello world!")
|
||||
|
||||
#include <boost/locale.hpp>
|
||||
boost::locale::translate("Hello world!")
|
||||
|
||||
.. Tip:: More examples can be found in the documentation for
|
||||
`boost locale <https://www.boost.org/doc/libs/1_70_0/libs/locale/doc/html/messages_formatting.html>`_.
|
||||
.. Tip:: More examples can be found in the documentation for
|
||||
`boost locale <https://www.boost.org/doc/libs/1_70_0/libs/locale/doc/html/messages_formatting.html>`_.
|
||||
|
||||
.. Warning:: This is for information only. Contributors should never include manually updated template files, or
|
||||
manually compiled language files in Pull Requests.
|
||||
@@ -65,20 +62,20 @@ used by CrowdIn to generate language specific template files. The file is genera
|
||||
`.github/workflows/localize.yml` workflow and is run on any push event into the `nightly` branch. Jobs are only run if
|
||||
any of the following paths are modified.
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
- 'src/**'
|
||||
- 'src/**'
|
||||
|
||||
When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is
|
||||
required for this, along with the python dependencies in the `./scripts/requirements.txt` file. Additionally,
|
||||
`xgettext <https://www.gnu.org/software/gettext/>`_ must be installed.
|
||||
|
||||
Extract, initialize, and update
|
||||
.. code-block:: bash
|
||||
**Extract, initialize, and update**
|
||||
.. code-block:: bash
|
||||
|
||||
python ./scripts/_locale.py --extract --init --update
|
||||
python ./scripts/_locale.py --extract --init --update
|
||||
|
||||
Compile
|
||||
.. code-block:: bash
|
||||
**Compile**
|
||||
.. code-block:: bash
|
||||
|
||||
python ./scripts/_locale.py --compile
|
||||
python ./scripts/_locale.py --compile
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
:github_url: https://github.com/RetroArcher/RetroArcher/tree/nightly/docs/source/contributing/testing.rst
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Clang Format
|
||||
------------
|
||||
Source code is tested against the `.clang-format` file for linting errors. The workflow file responsible for clang
|
||||
format testing is `.github/workflows/clang.yml`.
|
||||
format testing is `.github/workflows/cpp-clang-format-lint.yml`.
|
||||
|
||||
Test clang-format locally.
|
||||
.. Todo:: This documentation needs to be improved.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
clang-format ...
|
||||
find ./ -iname *.cpp -o -iname *.h -iname *.m -iname *.mm | xargs clang-format -i
|
||||
|
||||
Sphinx
|
||||
------
|
||||
Sunshine uses `Sphinx <https://www.sphinx-doc.org/en/master/>`_ for documentation building. Sphinx is included
|
||||
in the `./scripts/requirements.txt` file. Python is required to build sphinx docs. Installation and setup of python
|
||||
will not be covered here.
|
||||
Sunshine uses `Sphinx <https://www.sphinx-doc.org/en/master/>`_ for documentation building. Sphinx, along with other
|
||||
required documentation depencies are included in the `./docs/requirements.txt` file. Python is required to build
|
||||
sphinx docs. Installation and setup of python will not be covered here.
|
||||
|
||||
The config file for Sphinx is `docs/source/conf.py`. This is already included in the repo and should not be modified.
|
||||
|
||||
|
||||
20
docs/source/gamestream/gamestream.rst
Normal file
20
docs/source/gamestream/gamestream.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
GameStream
|
||||
==========
|
||||
Nvidia announced that their GameStream service for Nvidia Games clients will be discontinued in February 2023.
|
||||
Luckily, Sunshine performance is now on par with Nvidia GameStream. Many users have even reported that Sunshine
|
||||
outperforms GameStream, so rest assured that Sunshine will be equally performant moving forward.
|
||||
|
||||
Migration
|
||||
---------
|
||||
We have developed a simple migration tool to help you migrate your GameStream games and apps to Sunshine automatically.
|
||||
Please check out our `GSMS <https://github.com/LizardByte/GSMS>`_ project if you're interested in an automated
|
||||
migration option. At the time of writing this GSMS offers the ability to migrate your custom games and apps. The
|
||||
working directory, command, and image are all set in Sunshine's ``apps.json`` file. The box-art image is also copied
|
||||
to a specified directory.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
Sunshine does have some limitations, as compared to Nvidia GameStream.
|
||||
|
||||
- Automatic game/application list.
|
||||
- Changing game settings automatically, to optimize streaming.
|
||||
21
docs/source/legal/legal.rst
Normal file
21
docs/source/legal/legal.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
Legal
|
||||
=====
|
||||
.. Attention:: This documentation is for informational purposes only and is not intended as legal advice. If you have
|
||||
any legal questions or concerns about using Sunshine, we recommend consulting with a lawyer.
|
||||
|
||||
Sunshine is licensed under the GPL-3.0 license, which allows for free use and modification of the software.
|
||||
The full text of the license can be reviewed `here <https://github.com/LizardByte/Sunshine/blob/master/LICENSE>`_.
|
||||
|
||||
Commercial Use
|
||||
--------------
|
||||
Sunshine can be used in commercial applications without any limitations. This means that businesses and organizations
|
||||
can use Sunshine to create and sell products or services without needing to seek permission or pay a fee.
|
||||
|
||||
However, it is important to note that the GPL-3.0 license does not grant any rights to distribute or sell the encoders
|
||||
contained within Sunshine. If you plan to sell access to Sunshine as part of their distribution, you are responsible
|
||||
for obtaining the necessary licenses to do so. This may include obtaining a license from the
|
||||
Motion Picture Experts Group (MPEG-LA) and/or any other necessary licensing requirements.
|
||||
|
||||
In summary, while Sunshine is free to use, it is the user's responsibility to ensure compliance with all applicable
|
||||
licensing requirements when redistributing the software as part of a commercial offering. If you have any questions or
|
||||
concerns about using Sunshine in a commercial setting, we recommend consulting with a lawyer.
|
||||
@@ -9,6 +9,12 @@
|
||||
about/usage
|
||||
about/advanced_usage
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: GameStream
|
||||
|
||||
gamestream/gamestream
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Troubleshooting
|
||||
@@ -34,3 +40,9 @@
|
||||
contributing/contributing
|
||||
contributing/localization
|
||||
contributing/testing
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Legal
|
||||
|
||||
legal/legal
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/troubleshooting/general.rst
|
||||
|
||||
General
|
||||
=======
|
||||
If you forgot your credentials to the web UI, try this.
|
||||
|
||||
Forgotten Credentials
|
||||
---------------------
|
||||
If you forgot your credentials to the web UI, try this.
|
||||
.. code-block:: bash
|
||||
|
||||
sunshine -creds <new username> <new password>
|
||||
sunshine --creds <new username> <new password>
|
||||
|
||||
Web UI Access
|
||||
-------------
|
||||
Can't access the web UI?
|
||||
#. Check firewall rules.
|
||||
|
||||
#. Check firefall rules.
|
||||
Nvidia issues
|
||||
-------------
|
||||
NvFBC, NvENC, or general issues with Nvidia graphics card.
|
||||
- Consumer grade Nvidia cards are software limited to a specific number of encodes. See
|
||||
`Video Encode and Decode GPU Support Matrix <https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new>`_
|
||||
for more info.
|
||||
- You can usually bypass the restriction with a driver patch. See Keylase's
|
||||
`Linux <https://github.com/keylase/nvidia-patch>`_
|
||||
or `Windows <https://github.com/keylase/nvidia-patch/blob/master/win>`_ patches for more guidance.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/troubleshooting/linux.rst
|
||||
|
||||
Linux
|
||||
=====
|
||||
If screencasting fails with Wayland, you may need to run the following to force screencasting with X11.
|
||||
|
||||
KMS Streaming fails
|
||||
-------------------
|
||||
If screencasting fails with KMS, you may need to run the following to force unprivileged screencasting.
|
||||
.. code-block:: bash
|
||||
|
||||
sudo setcap -r $(readlink -f $(which sunshine))
|
||||
|
||||
@@ -1,29 +1,13 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/troubleshooting/macos.rst
|
||||
|
||||
macOS
|
||||
=====
|
||||
If you get this error:
|
||||
|
||||
``Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that
|
||||
org.freedesktop.dbus-session.plist is loaded!``
|
||||
Dynamic session lookup failed
|
||||
-----------------------------
|
||||
If you get this error:
|
||||
`Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that
|
||||
org.freedesktop.dbus-session.plist is loaded!`
|
||||
|
||||
Try this.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
launchctl load -w /Library/LaunchAgents/org.freedesktop.dbus-session.plist
|
||||
|
||||
Uninstall:
|
||||
|
||||
- pkg
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo chmod +x /opt/local/etc/sunshine/assets/uninstall_pkg.sh
|
||||
sudo /opt/local/etc/sunshine/assets/uninstall_pkg.sh
|
||||
|
||||
- Portfile
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo port uninstall Sunshine
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/troubleshooting/windows.rst
|
||||
|
||||
Windows
|
||||
=======
|
||||
No gamepad is detected.
|
||||
|
||||
#. Verify that you've installed `ViGEmBus <https://github.com/ViGEm/ViGEmBus/releases/latest>`_.
|
||||
No gamepad detected
|
||||
-------------------
|
||||
#. Verify that you've installed `ViGEmBus <https://github.com/ViGEm/ViGEmBus/releases/latest>`_.
|
||||
|
||||
7
package.json
Normal file
7
package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "6.2.1",
|
||||
"bootstrap": "5.2.3",
|
||||
"vue": "2.6.12"
|
||||
}
|
||||
}
|
||||
110
packaging/linux/AppImage/AppRun
Normal file
110
packaging/linux/AppImage/AppRun
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# custom AppRun for Sunshine AppImage
|
||||
|
||||
# path of the extracted AppRun
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"
|
||||
SUNSHINE_PATH=/usr/bin/sunshine
|
||||
SUNSHINE_BIN_HERE=$HERE/usr/bin/sunshine
|
||||
SUNSHINE_SHARE_HERE=$HERE/usr/share/sunshine
|
||||
|
||||
# Set APPDIR when running directly from the AppDir:
|
||||
if [ -z "$APPDIR" ]; then
|
||||
ARGV0="AppRun"
|
||||
fi
|
||||
|
||||
cd "$HERE" || exit 1
|
||||
|
||||
function help() {
|
||||
echo "
|
||||
------------------------------
|
||||
Sunshine AppImage package.
|
||||
------------------------------
|
||||
|
||||
sunshine.AppImage options
|
||||
------------------------
|
||||
|
||||
Usage: $ARGV0 --help, -h
|
||||
------ # This message
|
||||
|
||||
$ARGV0 --install, -i
|
||||
# Install input rules sunshine.service files. Restart required.
|
||||
|
||||
$ARGV0 --remove, -r
|
||||
# Remove input rules sunshine.service files.
|
||||
|
||||
$ARGV0 --appimage-help
|
||||
# Show available AppImage options
|
||||
|
||||
sunshine options
|
||||
----------------
|
||||
"
|
||||
# print sunshine binary help, replacing the sunshine command in usage statement
|
||||
"$SUNSHINE_BIN_HERE" --help | sed -e "s#$SUNSHINE_BIN_HERE#$ARGV0#g"
|
||||
}
|
||||
|
||||
function install() {
|
||||
# user input rules
|
||||
sudo usermod -a -G input $USER
|
||||
# shellcheck disable=SC2002
|
||||
cat "$SUNSHINE_SHARE_HERE/udev/rules.d/85-sunshine.rules" | sudo tee /etc/udev/85-sunshine.rules
|
||||
|
||||
# sunshine service
|
||||
mkdir -p ~/.config/systemd/user
|
||||
cp -r "$SUNSHINE_SHARE_HERE/systemd/user/" ~/.config/systemd/
|
||||
# patch service executable path
|
||||
sed -i -e "s#$SUNSHINE_PATH#$(readlink -f $ARGV0)#g" ~/.config/systemd/user/sunshine.service
|
||||
|
||||
# setcap
|
||||
sudo setcap cap_sys_admin+p "$(readlink -f "$SUNSHINE_BIN_HERE")"
|
||||
|
||||
while true
|
||||
do
|
||||
read -r -p "This installation requires a reboot. Do you want to reboot NOW? [y/n] " input
|
||||
|
||||
case $input in
|
||||
[yY][eE][sS]|[yY])
|
||||
echo "Yes"
|
||||
sudo reboot now
|
||||
;;
|
||||
[nN][oO]|[nN])
|
||||
echo "No"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function remove() {
|
||||
# remove input rules
|
||||
sudo rm -f /etc/udev/rules.d/85-sunshine.rules
|
||||
|
||||
# remove service
|
||||
sudo rm -f ~/.config/systemd/user/sunshine.service
|
||||
}
|
||||
|
||||
# process arguments
|
||||
if [ "x$1" == "xhelp" ] || [ "x$1" == "x--help" ] || [ "x$1" == "x-h" ] ; then
|
||||
help
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ "x$1" == "xinstall" ] || [ "x$1" == "x--install" ] || [ "x$1" == "x-i" ] ; then
|
||||
install
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ "x$1" == "xremove" ] || [ "x$1" == "x--remove" ] || [ "x$1" == "x-r" ] ; then
|
||||
remove
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# create config directory if it doesn't exist
|
||||
# https://github.com/LizardByte/Sunshine/issues/324
|
||||
mkdir -p ~/.config/sunshine
|
||||
|
||||
# run sunshine
|
||||
"$SUNSHINE_BIN_HERE" $@
|
||||
@@ -1,20 +1,21 @@
|
||||
# Edit on github: https://github.com/LizardByte/Sunshine/tree/nightly/packaging/linux/aur/PKGBUILD
|
||||
# Reference: https://wiki.archlinux.org/title/PKGBUILD
|
||||
|
||||
pkgname=@SUNSHINE_AUR_PKG@
|
||||
pkgname='sunshine'
|
||||
pkgver=@PROJECT_VERSION@@SUNSHINE_SUB_VERSION@
|
||||
pkgrel=1
|
||||
pkgdesc="@PROJECT_DESCRIPTION@"
|
||||
arch=('x86_64' 'i686')
|
||||
arch=('x86_64' 'aarch64')
|
||||
url=@PROJECT_HOMEPAGE_URL@
|
||||
license=('GPL3')
|
||||
|
||||
depends=('avahi' 'boost-libs' 'ffmpeg4.4' 'libevdev' 'libpulse' 'libx11' 'libxcb' 'libxfixes' 'libxrandr' 'libxtst' 'openssl' 'opus' 'udev')
|
||||
makedepends=('boost' 'cmake' 'git' 'make')
|
||||
optdepends=('cuda' 'libcap' 'libdrm')
|
||||
depends=('avahi' 'boost-libs' 'curl' 'libevdev' 'libmfx' 'libpulse' 'libva' 'libvdpau' 'libx11' 'libxcb' 'libxfixes' 'libxrandr' 'libxtst' 'numactl' 'openssl' 'opus' 'udev')
|
||||
makedepends=('boost' 'cmake' 'git' 'make' 'nodejs' 'npm')
|
||||
optdepends=('cuda: NvFBC capture support'
|
||||
'libcap'
|
||||
'libdrm')
|
||||
|
||||
provides=(@SUNSHINE_AUR_PROVIDES@)
|
||||
conflicts=(@SUNSHINE_AUR_CONFLICTS@)
|
||||
provides=('sunshine')
|
||||
|
||||
source=("$pkgname::git+@GITHUB_CLONE_URL@#commit=@GITHUB_COMMIT@")
|
||||
sha256sums=('SKIP')
|
||||
@@ -25,6 +26,10 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
pushd "$pkgname"
|
||||
npm install
|
||||
popd
|
||||
|
||||
export CFLAGS="${CFLAGS/-Werror=format-security/}"
|
||||
export CXXFLAGS="${CXXFLAGS/-Werror=format-security/}"
|
||||
|
||||
@@ -32,20 +37,9 @@ build() {
|
||||
-S "$pkgname" \
|
||||
-B build \
|
||||
-Wno-dev \
|
||||
-D CMAKE_INSTALL_PREFIX=/usr \
|
||||
-D SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
|
||||
-D CMAKE_INSTALL_PREFIX="/usr" \
|
||||
-D SUNSHINE_ASSETS_DIR="share/sunshine/assets" \
|
||||
-D SUNSHINE_CONFIG_DIR="share/sunshine/config" \
|
||||
-D LIBAVCODEC_INCLUDE_DIR=/usr/include/ffmpeg4.4 \
|
||||
-D LIBAVCODEC_LIBRARIES=/usr/lib/ffmpeg4.4/libavcodec.so \
|
||||
-D LIBAVDEVICE_INCLUDE_DIR=/usr/include/ffmpeg4.4 \
|
||||
-D LIBAVDEVICE_LIBRARIES=/usr/lib/ffmpeg4.4/libavdevice.so \
|
||||
-D LIBAVFORMAT_INCLUDE_DIR=/usr/include/ffmpeg4.4 \
|
||||
-D LIBAVFORMAT_LIBRARIES=/usr/lib/ffmpeg4.4/libavformat.so \
|
||||
-D LIBAVUTIL_INCLUDE_DIR=/usr/include/ffmpeg4.4 \
|
||||
-D LIBAVUTIL_LIBRARIES=/usr/lib/ffmpeg4.4/libavutil.so \
|
||||
-D LIBSWSCALE_INCLUDE_DIR=/usr/include/ffmpeg4.4 \
|
||||
-D LIBSWSCALE_LIBRARIES=/usr/lib/ffmpeg4.4/libswscale.so
|
||||
-D SUNSHINE_ASSETS_DIR="share/sunshine"
|
||||
|
||||
make -C build
|
||||
}
|
||||
|
||||
@@ -3,19 +3,21 @@ app-id: dev.lizardbyte.sunshine
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: "21.08"
|
||||
sdk: org.freedesktop.Sdk
|
||||
sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.node18
|
||||
command: sunshine
|
||||
separate-locales: false
|
||||
finish-args:
|
||||
- --device=all
|
||||
- --env=PULSE_PROP_media.category=Manager
|
||||
- --persist=.config/sunshine
|
||||
- --share=ipc
|
||||
- --share=network
|
||||
- --socket=pulseaudio
|
||||
- --socket=wayland
|
||||
- --socket=x11
|
||||
- --system-talk-name=org.freedesktop.Avahi
|
||||
- --talk-name=org.freedesktop.Flatpak
|
||||
- --device=all # access all devices
|
||||
- --env=PULSE_PROP_media.category=Manager # allow sunshine to manage audio sinks
|
||||
- --filesystem=home # need to save files in user's home directory
|
||||
- --share=ipc # required for X11 shared memory extension
|
||||
- --share=network # access network
|
||||
- --socket=pulseaudio # play sounds using pulseaudio
|
||||
- --socket=wayland # show windows using Wayland
|
||||
- --socket=x11 # show windows using X11
|
||||
- --system-talk-name=org.freedesktop.Avahi # talk to avahi on the system bus
|
||||
- --talk-name=org.freedesktop.Flatpak # talk to flatpak on the session bus
|
||||
|
||||
cleanup:
|
||||
- /include
|
||||
@@ -23,122 +25,34 @@ cleanup:
|
||||
- /lib/pkgconfig
|
||||
- /lib/*.la
|
||||
- /lib/*.a
|
||||
- /share
|
||||
- /share/man
|
||||
|
||||
modules:
|
||||
- name: cuda
|
||||
- name: boost
|
||||
disabled: false
|
||||
buildsystem: simple
|
||||
only-arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
cleanup:
|
||||
- '*'
|
||||
build-commands:
|
||||
- chmod u+x ./cuda.run
|
||||
- ./cuda.run --silent --toolkit --toolkitpath=$FLATPAK_DEST/cuda --no-opengl-libs --no-man-page --no-drm --tmpdir=$FLATPAK_BUILDER_BUILDDIR # yamllint disable-line rule:line-length
|
||||
- rm -r $FLATPAK_DEST/cuda/nsight-systems-2021.3.2
|
||||
- rm ./cuda.run
|
||||
sources:
|
||||
- type: file
|
||||
only-arches:
|
||||
- x86_64
|
||||
url: https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run
|
||||
sha256: bbd87ca0e913f837454a796367473513cddef555082e4d86ed9a38659cc81f0a
|
||||
dest-filename: cuda.run
|
||||
- type: file
|
||||
only-arches:
|
||||
- aarch64
|
||||
url: https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux_sbsa.run # yamllint disable-line rule:line-length
|
||||
sha256: f2c4a52e06329606c8dfb7c5ea3f4cb4c0b28f9d3fdffeeb734fcc98daf580d8
|
||||
dest-filename: cuda.run
|
||||
|
||||
- name: boost
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=system,thread,log
|
||||
- ./b2 install variant=release link=static,shared runtime-link=shared cxxflags="$CXXFLAGS" linkflags="$LDFLAGS" -j $FLATPAK_BUILDER_N_JOBS # yamllint disable-line rule:line-length
|
||||
- cd tools/build && bison -y -d -o src/engine/jamgram.cpp src/engine/jamgram.y
|
||||
- ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=system,thread,log,program_options || cat bootstrap.log
|
||||
- ./b2 install variant=release link=shared runtime-link=shared cxxflags="$CXXFLAGS" linkflags="$LDFLAGS"
|
||||
-j $FLATPAK_BUILDER_N_JOBS
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2
|
||||
sha256: 475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39
|
||||
|
||||
- name: ffmpeg
|
||||
config-opts:
|
||||
- --enable-gpl
|
||||
- --disable-static
|
||||
- --enable-shared
|
||||
- --disable-doc
|
||||
- --disable-programs
|
||||
- --disable-decoders
|
||||
- --enable-libfontconfig
|
||||
- --enable-libfreetype
|
||||
- --enable-libopus
|
||||
- --enable-libvorbis
|
||||
- --enable-libvpx
|
||||
- --enable-libx264
|
||||
- --enable-libx265
|
||||
- --enable-nvenc
|
||||
- --enable-encoder=h264_v4l2m2m
|
||||
- --enable-encoder=hevc_v4l2m2m
|
||||
# - --enable-nonfree
|
||||
# - --enable-cuda-nvcc
|
||||
# - --enable-libnpp
|
||||
# - --extra-cflags=-I${FLATPAK_DEST}/cuda/include
|
||||
# - --extra-ldflags=-L${FLATPAK_DEST}/cuda/lib64
|
||||
# - --nvccflags="-gencode arch=compute_52,code=sm_52 -O2"
|
||||
cleanup:
|
||||
- /share/ffmpeg/examples
|
||||
sources:
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/b/boost1.74/boost1.74_1.74.0.orig.tar.xz
|
||||
sha256: 2467be4af625b5ae4b3c93fc7af196a09eba39c11a7338cd9e8b356fa44d2f45
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/universe/f/ffmpeg/ffmpeg_4.4.2.orig.tar.xz
|
||||
sha256: af419a7f88adbc56c758ab19b4c708afbcae15ef09606b82b855291f6a6faa93
|
||||
modules:
|
||||
- name: vmaf
|
||||
buildsystem: meson
|
||||
subdir: libvmaf
|
||||
cleanup:
|
||||
- /bin
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/Netflix/vmaf/archive/refs/tags/v2.3.1.tar.gz
|
||||
sha256: 8d60b1ddab043ada25ff11ced821da6e0c37fd7730dd81c24f1fc12be7293ef2
|
||||
- name: x264
|
||||
config-opts:
|
||||
- --disable-cli
|
||||
- --enable-shared
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://code.videolan.org/videolan/x264/-/archive/stable/x264-stable.tar.bz2
|
||||
sha256: 8fedb184045722d8cc39353099373a5b7350171d0964d01fff8eced21b959b29
|
||||
- name: x265
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
subdir: source
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- -DENABLE_CLI=OFF
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://bitbucket.org/multicoreware/x265_git/downloads/x265_3.5.tar.gz
|
||||
sha256: e70a3335cacacbba0b3a20ec6fecd6783932288ebc8163ad74bcc9606477cae8
|
||||
- name: ffnvcodec
|
||||
no-autogen: true
|
||||
make-install-args:
|
||||
- PREFIX=${FLATPAK_DEST}
|
||||
cleanup:
|
||||
- '*'
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n11.1.5.1.tar.gz
|
||||
sha256: d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/b/boost1.74/boost1.74_1.74.0-17ubuntu1.debian.tar.xz
|
||||
sha256: 22e623d98c84eb3fec57e19ea371157a5bc8225ba4c5907f7e5155072317a31d
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
|
||||
- name: avahi
|
||||
disabled: false
|
||||
cleanup:
|
||||
- /bin
|
||||
- /lib/avahi
|
||||
- /share/applications/*.desktop
|
||||
- /share/avahi
|
||||
- /share
|
||||
config-opts:
|
||||
- --with-distro=none
|
||||
- --disable-gobject
|
||||
@@ -161,56 +75,169 @@ modules:
|
||||
- --disable-doxygen-html
|
||||
- --disable-manpages
|
||||
- --disable-xmltoman
|
||||
- --disable-libevent
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://avahi.org/download/avahi-0.8.tar.gz
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/a/avahi/avahi_0.8.orig.tar.gz
|
||||
sha256: 060309d7a333d38d951bc27598c677af1796934dbd98e1024e7ad8de798fedda
|
||||
modules:
|
||||
- name: libevent
|
||||
cleanup:
|
||||
- /bin
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz # yamllint disable-line rule:line-length
|
||||
sha256: 92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/a/avahi/avahi_0.8-6ubuntu1.debian.tar.xz
|
||||
sha256: ebf1dfe5e853b6bc6843e3bd784cb6af632041f305abd0e5415114f80c1dcea4
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
- autoreconf -ivf
|
||||
|
||||
- name: libevdev
|
||||
disabled: false
|
||||
buildsystem: meson
|
||||
config-opts:
|
||||
- -Ddocumentation=disabled
|
||||
- -Dtests=disabled
|
||||
cleanup:
|
||||
- /bin
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://www.freedesktop.org/software/libevdev/libevdev-1.12.1.tar.xz
|
||||
sha256: 1dbba41bc516d3ca7abc0da5b862efe3ea8a7018fa6e9b97ce9d39401b22426c
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/libe/libevdev/libevdev_1.13.0+dfsg.orig.tar.xz
|
||||
sha256: a882e13ef1dd6bd227318080cabf60fe5af3c06471259d3acfc9dbfb202351a7
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/libe/libevdev/libevdev_1.13.0+dfsg-1.debian.tar.xz
|
||||
sha256: d33c56acbbfff2dc540e45c57a38d92210b5e7fd0947ac47fbe48183468aad74
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
|
||||
- name: intel-mediasdk
|
||||
disabled: false
|
||||
buildsystem: cmake
|
||||
config-opts:
|
||||
- -DENABLE_OPENCL=ON
|
||||
- -DENABLE_X11_DRI3=ON
|
||||
- -DENABLE_WAYLAND=ON
|
||||
- -DENABLE_ITT=OFF
|
||||
- -DENABLE_TEXTLOG=OFF
|
||||
- -DENABLE_STAT=OFF
|
||||
- -DBUILD_ALL=OFF
|
||||
- -DBUILD_RUNTIME=ON
|
||||
- -DBUILD_SAMPLES=OFF
|
||||
- -DBUILD_TESTS=OFF
|
||||
- -DBUILD_TOOLS=OFF
|
||||
- -DUSE_SYSTEM_GTEST=OFF
|
||||
- -DMFX_ENABLE_KERNELS=ON
|
||||
only-arches:
|
||||
- x86_64
|
||||
sources:
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/universe/i/intel-mediasdk/intel-mediasdk_22.3.0.orig.tar.gz
|
||||
sha256: e1e74229f409e969b70c2b35b1955068de3d40db85ecc42bd6ff501468bc76d7
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/universe/i/intel-mediasdk/intel-mediasdk_22.3.0-1.debian.tar.xz
|
||||
sha256: 024d98d2f63443d2765a90cfe997d104e7b897694889f199ca8fb4d9ffdcf1dc
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
modules:
|
||||
- name: libcheck
|
||||
buildsystem: cmake
|
||||
cleanup:
|
||||
- /bin
|
||||
- name: libdrm
|
||||
disabled: false
|
||||
buildsystem: meson
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/libcheck/check/archive/refs/tags/0.15.2.tar.gz
|
||||
sha256: 998d355294bb94072f40584272cf4424571c396c631620ce463f6ea97aa67d2e
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/libd/libdrm/libdrm_2.4.110.orig.tar.xz
|
||||
sha256: eecee4c4b47ed6d6ce1a9be3d6d92102548ea35e442282216d47d05293cf9737
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/libd/libdrm/libdrm_2.4.110-1ubuntu1.debian.tar.xz
|
||||
sha256: 464b9553861f39beddfaee6b8924734b02a0febfae3968e4ca1360f2972bba8b
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
|
||||
- name: numactl
|
||||
buildsystem: autotools
|
||||
make-args:
|
||||
- install
|
||||
sources:
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/n/numactl/numactl_2.0.14.orig.tar.gz
|
||||
sha256: 1ee27abd07ff6ba140aaf9bc6379b37825e54496e01d6f7343330cf1a4487035
|
||||
- type: archive
|
||||
url: http://archive.ubuntu.com/ubuntu/pool/main/n/numactl/numactl_2.0.14-3ubuntu2.debian.tar.xz
|
||||
sha256: 49089e5be5367f6367f8b0389d1d523944432607783b53f0605705792e1015ee
|
||||
- type: shell
|
||||
commands:
|
||||
- for n in $(cat patches/series); do if [[ $n != "#"* ]]; then patch -Np1 -i "patches/$n" -d .; fi; done
|
||||
cleanup:
|
||||
- "/bin"
|
||||
|
||||
# Caching is configured until here, not including CUDA
|
||||
- name: cuda
|
||||
disabled: false
|
||||
buildsystem: simple
|
||||
only-arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
cleanup:
|
||||
- "*"
|
||||
build-commands:
|
||||
- chmod u+x ./cuda.run
|
||||
- ./cuda.run --silent --toolkit --toolkitpath=$FLATPAK_DEST/cuda --no-opengl-libs --no-man-page --no-drm
|
||||
--tmpdir=$FLATPAK_BUILDER_BUILDDIR
|
||||
- rm -r $FLATPAK_DEST/cuda/nsight-systems-*
|
||||
- rm ./cuda.run
|
||||
sources:
|
||||
- type: file
|
||||
only-arches:
|
||||
- x86_64
|
||||
url: https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run
|
||||
sha256: 9223c4af3aebe4a7bbed9abd9b163b03a1b34b855fbc2b4a0d1b706ac09a5a16
|
||||
dest-filename: cuda.run
|
||||
- type: file
|
||||
only-arches:
|
||||
- aarch64
|
||||
url: https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux_sbsa.run # yamllint disable-line rule:line-length
|
||||
sha256: e6e9a8d31163c9776b5e313fd7590877c5684e1ecddee741154f95704d4ed27c
|
||||
dest-filename: cuda.run
|
||||
|
||||
- name: sunshine
|
||||
disabled: false
|
||||
buildsystem: cmake
|
||||
no-make-install: false
|
||||
builddir: true
|
||||
build-options:
|
||||
append-path: /usr/lib/sdk/node18/bin
|
||||
build-args:
|
||||
- --share=network
|
||||
cxxflags: -I${C_INCLUDE_PATH}/libevdev-1.0
|
||||
env:
|
||||
npm_config_nodedir: /usr/lib/sdk/node18
|
||||
NPM_CONFIG_LOGLEVEL: info
|
||||
build-commands:
|
||||
# Install npm dependencies
|
||||
- cd ${FLATPAK_BUILDER_BUILDDIR} && npm install
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DCMAKE_INSTALL_PREFIX=/app
|
||||
- -DCMAKE_CUDA_COMPILER=/app/cuda/bin/nvcc
|
||||
- -DSUNSHINE_ASSETS_DIR=assets
|
||||
- -DSUNSHINE_CONFIG_DIR=config
|
||||
- -DSUNSHINE_ASSETS_DIR=share/sunshine
|
||||
- -DSUNSHINE_EXECUTABLE_PATH=/app/bin/sunshine
|
||||
- -DSUNSHINE_ENABLE_WAYLAND=ON
|
||||
- -DSUNSHINE_ENABLE_X11=ON
|
||||
- -DSUNSHINE_ENABLE_DRM=ON
|
||||
- -DSUNSHINE_ENABLE_CUDA=ON
|
||||
- -DSUNSHINE_CONFIGURE_FLATPAK=ON
|
||||
sources:
|
||||
- type: git
|
||||
url: '@GITHUB_CLONE_URL@'
|
||||
branch: '@GITHUB_BRANCH@'
|
||||
commit: '@GITHUB_COMMIT@'
|
||||
url: "@GITHUB_CLONE_URL@"
|
||||
branch: "@GITHUB_BRANCH@"
|
||||
commit: "@GITHUB_COMMIT@"
|
||||
post-install:
|
||||
# use `sed` to update apps.json with prefixes required for flatpak
|
||||
# -r (regex)
|
||||
# -z (handle new lines) https://linuxhint.com/sed-replace-newline-with-space
|
||||
# `/gm` global and multiline
|
||||
- sed -r -z -i -e
|
||||
's/("((do)|(undo)|(cmd)|(detached))"\s*:\s*\[?\n*\s*")(.*")/\1flatpak-spawn --host \7/gm'
|
||||
/app/share/sunshine/apps.json
|
||||
- sed -i
|
||||
's%/app/bin/sunshine%flatpak run dev.lizardbyte.sunshine\nExecStop=flatpak kill dev.lizardbyte.sunshine%g'
|
||||
/app/share/sunshine/systemd/user/sunshine.service
|
||||
- install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/scripts/* /app/bin
|
||||
|
||||
13
packaging/linux/flatpak/scripts/additional-install.sh
Normal file
13
packaging/linux/flatpak/scripts/additional-install.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
# User Service
|
||||
mkdir -p ~/.config/systemd/user
|
||||
cp /app/share/sunshine/systemd/user/sunshine.service $HOME/.config/systemd/user/sunshine.service
|
||||
echo Sunshine User Service has been installed.
|
||||
echo Use [systemctl --user enable sunshine] once to autostart Sunshine on login.
|
||||
|
||||
# Udev rule and input group
|
||||
UDEV=$(cat /app/share/sunshine/udev/rules.d/85-sunshine.rules)
|
||||
echo Configuring mouse permission.
|
||||
flatpak-spawn --host pkexec sh -c "usermod -a -G input $USER && echo '$UDEV' > /etc/udev/rules.d/85-sunshine.rules"
|
||||
echo Restart computer for mouse permission to take effect.
|
||||
11
packaging/linux/flatpak/scripts/remove-additional-install.sh
Normal file
11
packaging/linux/flatpak/scripts/remove-additional-install.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# User Service
|
||||
systemctl --user stop sunshine
|
||||
rm $HOME/.config/systemd/user/sunshine.service
|
||||
systemctl --user daemon-reload
|
||||
echo Sunshine User Service has been removed.
|
||||
|
||||
# Udev rule and input group
|
||||
flatpak-spawn --host pkexec sh -c "gpasswd -d $USER input && rm /etc/udev/rules.d/85-sunshine.rules"
|
||||
echo Mouse permission removed. Restart computer to take effect.
|
||||
@@ -32,14 +32,15 @@ post-fetch {
|
||||
}
|
||||
|
||||
depends_lib port:avahi \
|
||||
port:ffmpeg \
|
||||
port:libopus
|
||||
port:curl \
|
||||
port:libopus \
|
||||
port:npm9 \
|
||||
port:pkgconfig
|
||||
|
||||
boost.version 1.76
|
||||
boost.version 1.80
|
||||
|
||||
configure.args -DCMAKE_INSTALL_PREFIX=${prefix} \
|
||||
-DSUNSHINE_ASSETS_DIR=etc/sunshine/assets \
|
||||
-DSUNSHINE_CONFIG_DIR=etc/sunshine/config
|
||||
-DSUNSHINE_ASSETS_DIR=etc/sunshine/assets
|
||||
|
||||
startupitem.create yes
|
||||
startupitem.executable "${prefix}/bin/{$name}"
|
||||
@@ -54,30 +55,10 @@ platform darwin {
|
||||
}
|
||||
}
|
||||
|
||||
# destroot not required as cmake install directive handles moving files
|
||||
pre-build {
|
||||
system -W ${worksrcpath} "npm install"
|
||||
}
|
||||
|
||||
# # Rename files in `destroot`
|
||||
# post-destroot {
|
||||
# file rename ${destroot}${prefix}/etc/${name}/config/sunshine.conf ${destroot}${prefix}/etc/${name}/config/sunshine.conf.sample
|
||||
# file rename ${destroot}${prefix}/etc/${name}/config/apps.json ${destroot}${prefix}/etc/${name}/config/apps.json.sample
|
||||
# }
|
||||
|
||||
# # Don't overwrite existing preference files
|
||||
# post-activate {
|
||||
# if {![file exists ${prefix}/etc/${name}/config/sunshine.conf]} {
|
||||
# file copy ${destroot}${prefix}/etc/${name}/config/sunshine.conf.sample \
|
||||
# ${prefix}/etc/${name}/config/sunshine.conf
|
||||
# }
|
||||
# if {![file exists ${prefix}/etc/${name}/config/apps.json]} {
|
||||
# file copy ${destroot}${prefix}/etc/${name}/config/apps.json.sample \
|
||||
# ${prefix}/etc/${name}/config/apps.json
|
||||
# }
|
||||
# }
|
||||
|
||||
# disabled not overwriting config files... these are the default config files required by Sunshine
|
||||
# this did not work with pkg created by macports
|
||||
# we should always install the default files and user should start sunshine like "sunshine <path to user config file>"
|
||||
# if the file doesn't exist sunshine will copy the default config to that location
|
||||
notes-append "Run @PROJECT_NAME@ by executing 'sunshine <path to user config>', e.g. 'sunshine ~/sunshine.conf' "
|
||||
notes-append "The config file will be created if it doesn't exist."
|
||||
notes-append "It is recommended to set a location for the apps file in the config."
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
FROM debian:bullseye AS sunshine-debian
|
||||
|
||||
# Debian Bullseye end of life is TBD
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG TZ="Europe/London"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN echo deb http://deb.debian.org/debian/ bullseye main contrib non-free | tee /etc/apt/sources.list.d/non-free.list
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libcap-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxcb1-dev \
|
||||
libxfixes-dev \
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
nvidia-cuda-dev \
|
||||
nvidia-cuda-toolkit \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-deb"]
|
||||
@@ -1,32 +0,0 @@
|
||||
FROM fedora:33 AS sunshine-fedora_33
|
||||
|
||||
# Fedora 33 end of life is November 2021
|
||||
# This file remains for reference only
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN dnf -y update && \
|
||||
dnf -y group install "Development Tools" && \
|
||||
dnf -y install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm && \
|
||||
dnf -y install \
|
||||
boost-devel \
|
||||
boost-static.x86_64 \
|
||||
cmake \
|
||||
ffmpeg-devel \
|
||||
libevdev-devel \
|
||||
libxcb-devel \
|
||||
libX11-devel \
|
||||
libXfixes-devel \
|
||||
libXrandr-devel \
|
||||
libXtst-devel \
|
||||
openssl-devel \
|
||||
opus-devel \
|
||||
pulseaudio-libs-devel \
|
||||
libcap-devel \
|
||||
libdrm-devel \
|
||||
rpm-build \
|
||||
&& dnf clean all \
|
||||
&& rm -rf /var/cache/yum
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-rpm"]
|
||||
@@ -1,36 +0,0 @@
|
||||
FROM fedora:35 AS sunshine-fedora_35
|
||||
|
||||
# Fedora 35 end of life is TBD
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN dnf -y update && \
|
||||
dnf -y group install "Development Tools" && \
|
||||
dnf -y install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm && \
|
||||
dnf -y install \
|
||||
boost-devel \
|
||||
boost-static.x86_64 \
|
||||
cmake \
|
||||
ffmpeg-devel \
|
||||
gcc-c++ \
|
||||
libevdev-devel \
|
||||
libX11-devel \
|
||||
libxcb-devel \
|
||||
libXcursor-devel \
|
||||
libXfixes-devel \
|
||||
libXinerama-devel \
|
||||
libXi-devel \
|
||||
libXrandr-devel \
|
||||
libXtst-devel \
|
||||
mesa-libGL-devel \
|
||||
openssl-devel \
|
||||
opus-devel \
|
||||
pulseaudio-libs-devel \
|
||||
libcap-devel \
|
||||
libdrm-devel \
|
||||
rpm-build \
|
||||
&& dnf clean all \
|
||||
&& rm -rf /var/cache/yum
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-rpm"]
|
||||
@@ -1,63 +0,0 @@
|
||||
FROM ubuntu:18.04 AS sunshine-ubuntu_18_04
|
||||
|
||||
# Ubuntu 18.04 end of life is April 2028
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG TZ="Europe/London"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y \
|
||||
software-properties-common \
|
||||
&& add-apt-repository ppa:savoury1/graphics && \
|
||||
add-apt-repository ppa:savoury1/multimedia && \
|
||||
add-apt-repository ppa:savoury1/ffmpeg4 && \
|
||||
add-apt-repository ppa:savoury1/boost-defaults-1.71 && \
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test && \
|
||||
apt-get update -y && \
|
||||
apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
gcc-10 \
|
||||
git \
|
||||
g++-10 \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem1.71-dev \
|
||||
libboost-log1.71-dev \
|
||||
libboost-regex1.71-dev \
|
||||
libboost-thread1.71-dev \
|
||||
libcap-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxcb1-dev \
|
||||
libxfixes-dev \
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
wget \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Update gcc alias
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
||||
|
||||
# Install CuDA
|
||||
RUN wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run && chmod a+x /root/cuda.run
|
||||
RUN /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm /root/cuda.run
|
||||
|
||||
# Install cmake
|
||||
ADD https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh /cmake-3.22.2-linux-x86_64.sh
|
||||
RUN mkdir /opt/cmake
|
||||
RUN sh /cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license
|
||||
RUN ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
RUN cmake --version
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-deb"]
|
||||
@@ -1,46 +0,0 @@
|
||||
FROM ubuntu:20.04 AS sunshine-ubuntu_20_04
|
||||
|
||||
# Ubuntu 20.04 end of life is April 2030
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG TZ="Europe/London"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
g++-10 \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libcap-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxcb1-dev \
|
||||
libxfixes-dev \
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
wget \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Update gcc alias
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
||||
|
||||
# Install CuDA
|
||||
RUN wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run && chmod a+x /root/cuda.run
|
||||
RUN /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm /root/cuda.run
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-deb"]
|
||||
@@ -1,40 +0,0 @@
|
||||
FROM ubuntu:21.04 AS sunshine-ubuntu_21_04
|
||||
|
||||
# Ubuntu 21.04 end of life is January 2022
|
||||
# This file remains for reference only
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG TZ="Europe/London"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libavdevice-dev \
|
||||
libboost-thread-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libcap-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxcb1-dev \
|
||||
libxfixes-dev \
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
nvidia-cuda-dev \
|
||||
nvidia-cuda-toolkit \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-deb"]
|
||||
@@ -1,39 +0,0 @@
|
||||
FROM ubuntu:21.10 AS sunshine-ubuntu_21_10
|
||||
|
||||
# Ubuntu 21.10 end of life is July 2022
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG TZ="Europe/London"
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libavdevice-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-log-dev \
|
||||
libboost-thread-dev \
|
||||
libcap-dev \
|
||||
libdrm-dev \
|
||||
libevdev-dev \
|
||||
libpulse-dev \
|
||||
libopus-dev \
|
||||
libssl-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxcb1-dev \
|
||||
libxfixes-dev \
|
||||
libxrandr-dev \
|
||||
libxtst-dev \
|
||||
nvidia-cuda-dev \
|
||||
nvidia-cuda-toolkit \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Entrypoint
|
||||
COPY build-private.sh /root/build.sh
|
||||
ENTRYPOINT ["/root/build.sh", "-deb"]
|
||||
@@ -1,179 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo " -c: command --> default [build]"
|
||||
echo " | delete --> Delete the container, Dockerfile isn't mandatory"
|
||||
echo " | build --> Build the container, Dockerfile is mandatory"
|
||||
echo " | compile --> Builds the container, then compiles it. Dockerfile is mandatory"
|
||||
echo ""
|
||||
echo " -s: path: The path to the source for compilation"
|
||||
echo " -n: name: Docker container name --> default [sunshine]"
|
||||
echo " --> all: Build/Compile/Delete all available docker containers"
|
||||
echo " -f: Dockerfile: The name of the docker file"
|
||||
}
|
||||
|
||||
# Attempt to turn relative paths into absolute paths
|
||||
absolute_path() {
|
||||
RELATIVE_PATH=$1
|
||||
if which realpath >/dev/null 2>/dev/null
|
||||
then
|
||||
RELATIVE_PATH=$(realpath $RELATIVE_PATH)
|
||||
else
|
||||
echo "Warning: realpath is not installed on your system, ensure [$1] is absolute"
|
||||
fi
|
||||
|
||||
RETURN=$RELATIVE_PATH
|
||||
}
|
||||
|
||||
CONTAINER_NAME=sunshine
|
||||
COMMAND=BUILD
|
||||
|
||||
build_container() {
|
||||
CONTAINER_NAME=$1
|
||||
DOCKER_FILE=$2
|
||||
|
||||
if [ ! -f "$DOCKER_FILE" ]
|
||||
then
|
||||
echo "Error: $DOCKER_FILE doesn't exist"
|
||||
exit 7
|
||||
fi
|
||||
|
||||
echo "docker build . -t $CONTAINER_NAME -f $DOCKER_FILE"
|
||||
docker build . -t "$CONTAINER_NAME" -f "$DOCKER_FILE"
|
||||
}
|
||||
|
||||
delete() {
|
||||
CONTAINER_NAME_UPPER=$(echo "$CONTAINER_NAME" | tr '[:lower:]' '[:upper:]')
|
||||
if [ "$CONTAINER_NAME_UPPER" = "ALL" ]
|
||||
then
|
||||
shopt -s nullglob
|
||||
for file in $(find . -maxdepth 1 -iname "Dockerfile-*" -type f)
|
||||
do
|
||||
CURRENT_CONTAINER="sunshine-$(echo $file | cut -c 14-)"
|
||||
|
||||
if docker inspect "$CURRENT_CONTAINER" > /dev/null 2> /dev/null
|
||||
then
|
||||
echo "docker rmi $CURRENT_CONTAINER"
|
||||
docker rmi "$CURRENT_CONTAINER"
|
||||
fi
|
||||
done
|
||||
shopt -u nullglob #revert nullglob back to it's normal default state
|
||||
else
|
||||
if docker inspect "$CONTAINER_NAME" > /dev/null 2> /dev/null
|
||||
then
|
||||
echo "docker rmi $CONTAINER_NAME"
|
||||
docker rmi $CONTAINER_NAME
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
CONTAINER_NAME_UPPER=$(echo "$CONTAINER_NAME" | tr '[:lower:]' '[:upper:]')
|
||||
if [ "$CONTAINER_NAME_UPPER" = "ALL" ]
|
||||
then
|
||||
shopt -s nullglob
|
||||
for file in $(find . -maxdepth 1 -iname "Dockerfile-*" -type f)
|
||||
do
|
||||
CURRENT_CONTAINER="sunshine-$(echo $file | cut -c 14-)"
|
||||
build_container "$CURRENT_CONTAINER" "$file"
|
||||
done
|
||||
shopt -u nullglob #revert nullglob back to it's normal default state
|
||||
else
|
||||
if [[ -z "$DOCKER_FILE" ]]
|
||||
then
|
||||
echo "Error: if container name isn't equal to 'all', you need to specify the Dockerfile"
|
||||
exit 6
|
||||
fi
|
||||
|
||||
build_container "$CONTAINER_NAME" "$DOCKER_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
abort() {
|
||||
echo "$1"
|
||||
exit 10
|
||||
}
|
||||
|
||||
compile() {
|
||||
CONTAINER_NAME_UPPER=$(echo "$CONTAINER_NAME" | tr '[:lower:]' '[:upper:]')
|
||||
if [ "$CONTAINER_NAME_UPPER" = "ALL" ]
|
||||
then
|
||||
shopt -s nullglob
|
||||
|
||||
# If any docker container doesn't exist, we cannot compile all of them
|
||||
for file in $(find . -maxdepth 1 -iname "Dockerfile-*" -type f)
|
||||
do
|
||||
CURRENT_CONTAINER="sunshine-$(echo $file | cut -c 14-)"
|
||||
|
||||
# If container doesn't exist --> abort.
|
||||
docker inspect "$CURRENT_CONTAINER" > /dev/null 2> /dev/null || abort "Error: container image [$CURRENT_CONTAINER] doesn't exist"
|
||||
done
|
||||
|
||||
for file in $(find . -maxdepth 1 -iname "Dockerfile-*" -type f)
|
||||
do
|
||||
CURRENT_CONTAINER="sunshine-$(echo $file | cut -c 14-)"
|
||||
|
||||
echo "$PWD/build-sunshine.sh -p -n $CURRENT_CONTAINER $SUNSHINE_SOURCES"
|
||||
"$PWD/build-sunshine.sh" -p -n "$CURRENT_CONTAINER" $SUNSHINE_SOURCES
|
||||
done
|
||||
shopt -u nullglob #revert nullglob back to it's normal default state
|
||||
else
|
||||
# If container exists
|
||||
if docker inspect "$CONTAINER_NAME" > /dev/null 2> /dev/null
|
||||
then
|
||||
echo "$PWD/build-sunshine.sh -p -n $CONTAINER_NAME $SUNSHINE_SOURCES"
|
||||
"$PWD/build-sunshine.sh" -p -n "$CONTAINER_NAME" $SUNSHINE_SOURCES
|
||||
else
|
||||
echo "Error: container image [$CONTAINER_NAME] doesn't exist"
|
||||
exit 9
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
while getopts ":c:hn:f:s:" arg; do
|
||||
case ${arg} in
|
||||
s)
|
||||
SUNSHINE_SOURCES="-s $OPTARG"
|
||||
;;
|
||||
c)
|
||||
COMMAND=$(echo $OPTARG | tr '[:lower:]' '[:upper:]')
|
||||
;;
|
||||
n)
|
||||
echo "Container name: $OPTARG"
|
||||
CONTAINER_NAME="$OPTARG"
|
||||
;;
|
||||
f)
|
||||
echo "Using Dockerfile [$OPTARG]"
|
||||
DOCKER_FILE="$OPTARG"
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "$0 set to $(echo $COMMAND | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
if [ "$COMMAND" = "BUILD" ]
|
||||
then
|
||||
echo "Start building..."
|
||||
delete
|
||||
build
|
||||
echo "Done."
|
||||
elif [ "$COMMAND" = "COMPILE" ]
|
||||
then
|
||||
echo "Start compiling..."
|
||||
compile
|
||||
echo "Done."
|
||||
elif [ "$COMMAND" = "DELETE" ]
|
||||
then
|
||||
echo "Start deleting..."
|
||||
delete
|
||||
echo "Done."
|
||||
else
|
||||
echo "Unknown command [$(echo $COMMAND | tr '[:upper:]' '[:lower:]')]"
|
||||
exit 4
|
||||
fi
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
set -e
|
||||
|
||||
CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}"
|
||||
SUNSHINE_EXECUTABLE_PATH="${SUNSHINE_EXECUTABLE_PATH:-/usr/bin/sunshine}"
|
||||
SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR:-/etc/sunshine}"
|
||||
|
||||
|
||||
SUNSHINE_ROOT="${SUNSHINE_ROOT:-/root/sunshine}"
|
||||
SUNSHINE_TAG="${SUNSHINE_TAG:-master}"
|
||||
SUNSHINE_GIT_URL="${SUNSHINE_GIT_URL:-https://github.com/lizardbyte/sunshine.git}"
|
||||
|
||||
|
||||
SUNSHINE_ENABLE_WAYLAND=${SUNSHINE_ENABLE_WAYLAND:-ON}
|
||||
SUNSHINE_ENABLE_X11=${SUNSHINE_ENABLE_X11:-ON}
|
||||
SUNSHINE_ENABLE_DRM=${SUNSHINE_ENABLE_DRM:-ON}
|
||||
SUNSHINE_ENABLE_CUDA=${SUNSHINE_ENABLE_CUDA:-ON}
|
||||
|
||||
# For debugging, it would be usefull to have the sources on the host.
|
||||
if [[ ! -d "$SUNSHINE_ROOT" ]]
|
||||
then
|
||||
git clone --depth 1 --branch "$SUNSHINE_TAG" "$SUNSHINE_GIT_URL" --recurse-submodules "$SUNSHINE_ROOT"
|
||||
fi
|
||||
|
||||
if [[ ! -d /root/sunshine-build ]]
|
||||
then
|
||||
mkdir -p /root/sunshine-build
|
||||
fi
|
||||
cd /root/sunshine-build
|
||||
|
||||
cmake "-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" "-DSUNSHINE_EXECUTABLE_PATH=$SUNSHINE_EXECUTABLE_PATH" "-DSUNSHINE_ASSETS_DIR=$SUNSHINE_ASSETS_DIR" "-DSUNSHINE_ENABLE_WAYLAND=$SUNSHINE_ENABLE_WAYLAND" "-DSUNSHINE_ENABLE_X11=$SUNSHINE_ENABLE_X11" "-DSUNSHINE_ENABLE_DRM=$SUNSHINE_ENABLE_DRM" "-DSUNSHINE_ENABLE_CUDA=$SUNSHINE_ENABLE_CUDA" "$SUNSHINE_ROOT"
|
||||
|
||||
make -j ${nproc}
|
||||
|
||||
# Get preferred package format
|
||||
if [ "$1" == "-rpm" ]
|
||||
then
|
||||
echo "Packaging in .rpm format."
|
||||
./gen-rpm -d
|
||||
elif [ "$1" == "-deb" ]
|
||||
then
|
||||
echo "Packaging in .deb format."
|
||||
./gen-deb
|
||||
else
|
||||
echo "Preferred packaging not specified."
|
||||
echo "Use -deb or -rpm to specify preferred package format."
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,132 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0"
|
||||
echo " -d: Generate a debug build"
|
||||
echo " -p: Generate a linux package"
|
||||
echo " -e: Extension of package... i.e. 'deb', 'rpm' --> default [deb]"
|
||||
echo " -u: The input device is not a TTY"
|
||||
echo " -n name: Docker container name --> default [sunshine]"
|
||||
echo " -s path/to/sources/sunshine: Use local sources instead of a git repository"
|
||||
echo " -c path/to/cmake/binary/dir: Store cmake output on host OS"
|
||||
}
|
||||
|
||||
# Attempt to turn relative paths into absolute paths
|
||||
absolute_path() {
|
||||
RELATIVE_PATH=$1
|
||||
if which realpath >/dev/null 2>/dev/null
|
||||
then
|
||||
RELATIVE_PATH=$(realpath $RELATIVE_PATH)
|
||||
else
|
||||
echo "Warning: realpath is not installed on your system, ensure [$1] is absolute"
|
||||
fi
|
||||
|
||||
RETURN=$RELATIVE_PATH
|
||||
}
|
||||
|
||||
CMAKE_BUILD_TYPE="-e CMAKE_BUILD_TYPE=Release"
|
||||
SUNSHINE_PACKAGE_BUILD=OFF
|
||||
SUNSHINE_PACKAGE_EXTENSION=deb
|
||||
SUNSHINE_GIT_URL=https://github.com/lizardbyte/sunshine.git
|
||||
CONTAINER_NAME=sunshine
|
||||
|
||||
# Docker will fail if ctrl+c is passed through and the input is not a tty
|
||||
DOCKER_INTERACTIVE=-ti
|
||||
|
||||
while getopts ":dpuhc:e:s:n:" arg; do
|
||||
case ${arg} in
|
||||
u)
|
||||
echo "Input device is not a TTY"
|
||||
USERNAME="$USER"
|
||||
unset DOCKER_INTERACTIVE
|
||||
;;
|
||||
d)
|
||||
echo "Creating debug build"
|
||||
CMAKE_BUILD_TYPE="-e CMAKE_BUILD_TYPE=Debug"
|
||||
;;
|
||||
p)
|
||||
echo "Creating package build"
|
||||
SUNSHINE_PACKAGE_BUILD=ON
|
||||
SUNSHINE_ASSETS_DIR="-e SUNSHINE_ASSETS_DIR=/etc/sunshine"
|
||||
SUNSHINE_EXECUTABLE_PATH="-e SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine"
|
||||
;;
|
||||
e)
|
||||
echo "Defining package extension: $OPTARG"
|
||||
if [ "$OPTARG" == "deb" ]
|
||||
then
|
||||
SUNSHINE_PACKAGE_EXTENSION=$OPTARG
|
||||
echo "Package extension: deb"
|
||||
elif [ "$OPTARG" == "rpm" ]
|
||||
then
|
||||
SUNSHINE_PACKAGE_EXTENSION=$OPTARG
|
||||
echo "Package extension: rpm"
|
||||
else
|
||||
echo "Package extension not supported: $OPTARG"
|
||||
echo "Falling back to default package extension: $SUNSHINE_PACKAGE_EXTENSION"
|
||||
fi
|
||||
;;
|
||||
s)
|
||||
absolute_path "$OPTARG"
|
||||
OPTARG="$RETURN"
|
||||
echo "Using sources from $OPTARG"
|
||||
SUNSHINE_ROOT="-v $OPTARG:/root/sunshine"
|
||||
;;
|
||||
c)
|
||||
[ "$USERNAME" == "" ] && USERNAME=$(logname)
|
||||
|
||||
absolute_path "$OPTARG"
|
||||
OPTARG="$RETURN"
|
||||
|
||||
echo "Using $OPTARG as cmake binary dir"
|
||||
if [[ ! -d $OPTARG ]]
|
||||
then
|
||||
echo "cmake binary dir doesn't exist, a new one will be created."
|
||||
mkdir -p "$OPTARG"
|
||||
[ "$USERNAME" == "$USER"] || chown $USERNAME:$USERNAME "$OPTARG"
|
||||
fi
|
||||
|
||||
CMAKE_ROOT="-v $OPTARG:/root/sunshine-build"
|
||||
;;
|
||||
n)
|
||||
echo "Container name: $OPTARG"
|
||||
CONTAINER_NAME=$OPTARG
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$USERNAME" = "" ] && USERNAME=$(logname)
|
||||
|
||||
BUILD_DIR="$PWD/$CONTAINER_NAME-build"
|
||||
[ "$SUNSHINE_ASSETS_DIR" = "" ] && SUNSHINE_ASSETS_DIR="-e SUNSHINE_ASSETS_DIR=$BUILD_DIR/assets"
|
||||
[ "$SUNSHINE_EXECUTABLE_PATH" = "" ] && SUNSHINE_EXECUTABLE_PATH="-e SUNSHINE_EXECUTABLE_PATH=$BUILD_DIR/sunshine"
|
||||
|
||||
echo "docker run $DOCKER_INTERACTIVE --privileged $SUNSHINE_ROOT $CMAKE_ROOT $SUNSHINE_ASSETS_DIR $SUNSHINE_EXECUTABLE_PATH $CMAKE_BUILD_TYPE --name $CONTAINER_NAME $CONTAINER_NAME"
|
||||
docker run $DOCKER_INTERACTIVE --privileged $SUNSHINE_ROOT $CMAKE_ROOT $SUNSHINE_ASSETS_DIR $SUNSHINE_EXECUTABLE_PATH $CMAKE_BUILD_TYPE --name $CONTAINER_NAME $CONTAINER_NAME
|
||||
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -eq 0 ]
|
||||
then
|
||||
mkdir -p $BUILD_DIR
|
||||
case $SUNSHINE_PACKAGE_BUILD in
|
||||
ON)
|
||||
echo "Downloading package to: $BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION"
|
||||
docker cp $CONTAINER_NAME:/root/sunshine-build/package-$SUNSHINE_PACKAGE_EXTENSION/sunshine.$SUNSHINE_PACKAGE_EXTENSION "$BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION"
|
||||
;;
|
||||
*)
|
||||
echo "Downloading binary and assets to: $BUILD_DIR"
|
||||
docker cp $CONTAINER_NAME:/root/sunshine/assets "$BUILD_DIR"
|
||||
docker cp $CONTAINER_NAME:/root/sunshine-build/sunshine "$BUILD_DIR"
|
||||
;;
|
||||
esac
|
||||
echo "chown --recursive $USERNAME:$USERNAME $BUILD_DIR"
|
||||
chown --recursive $USERNAME:$USERNAME "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
echo "Removing docker container $CONTAINER_NAME"
|
||||
docker rm $CONTAINER_NAME
|
||||
@@ -1,5 +1 @@
|
||||
Babel==2.10.3
|
||||
m2r2==0.3.2
|
||||
Sphinx==5.1.1
|
||||
sphinx-copybutton==0.5.0
|
||||
sphinx-rtd-theme==1.0.0
|
||||
Babel==2.11.0
|
||||
|
||||
@@ -39,6 +39,15 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
|
||||
1,
|
||||
1,
|
||||
platf::speaker::map_stereo,
|
||||
96000,
|
||||
},
|
||||
{
|
||||
SAMPLE_RATE,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
platf::speaker::map_stereo,
|
||||
512000,
|
||||
},
|
||||
{
|
||||
SAMPLE_RATE,
|
||||
@@ -46,6 +55,7 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
|
||||
4,
|
||||
2,
|
||||
platf::speaker::map_surround51,
|
||||
256000,
|
||||
},
|
||||
{
|
||||
SAMPLE_RATE,
|
||||
@@ -53,6 +63,7 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
|
||||
6,
|
||||
0,
|
||||
platf::speaker::map_surround51,
|
||||
1536000,
|
||||
},
|
||||
{
|
||||
SAMPLE_RATE,
|
||||
@@ -60,6 +71,7 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
|
||||
5,
|
||||
3,
|
||||
platf::speaker::map_surround71,
|
||||
450000,
|
||||
},
|
||||
{
|
||||
SAMPLE_RATE,
|
||||
@@ -67,6 +79,7 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
|
||||
8,
|
||||
0,
|
||||
platf::speaker::map_surround71,
|
||||
2048000,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -74,9 +87,10 @@ auto control_shared = safe::make_shared<audio_ctx_t>(start_audio_control, stop_a
|
||||
|
||||
void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
|
||||
auto packets = mail::man->queue<packet_t>(mail::audio_packets);
|
||||
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
|
||||
|
||||
//FIXME: Pick correct opus_stream_config_t based on config.channels
|
||||
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
|
||||
// Encoding takes place on this thread
|
||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||
|
||||
opus_t opus { opus_multistream_encoder_create(
|
||||
stream->sampleRate,
|
||||
@@ -84,17 +98,15 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
|
||||
stream->streams,
|
||||
stream->coupledStreams,
|
||||
stream->mapping,
|
||||
OPUS_APPLICATION_AUDIO,
|
||||
OPUS_APPLICATION_RESTRICTED_LOWDELAY,
|
||||
nullptr) };
|
||||
|
||||
// For some reason, audio is crackling when the encoder is set to constant bitstream.
|
||||
// We simulate a constant bitstream with OPUS_SET_BITRATE(OPUS_BITRATE_MAX) -->
|
||||
// which tries to occupy as much space as possible in the packet
|
||||
opus_multistream_encoder_ctl(opus.get(), OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
|
||||
opus_multistream_encoder_ctl(opus.get(), OPUS_SET_BITRATE(stream->bitrate));
|
||||
opus_multistream_encoder_ctl(opus.get(), OPUS_SET_VBR(0));
|
||||
|
||||
auto frame_size = config.packetDuration * stream->sampleRate / 1000;
|
||||
while(auto sample = samples->pop()) {
|
||||
buffer_t packet { 1400 }; // 1KB
|
||||
buffer_t packet { 1400 };
|
||||
|
||||
int bytes = opus_multistream_encode(opus.get(), sample->data(), frame_size, std::begin(packet), packet.size());
|
||||
if(bytes < 0) {
|
||||
@@ -104,14 +116,6 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Even with OPUS_SET_BITRATE(OPUS_BITRATE_MAX), silent packets are smaller than the rest
|
||||
// Drop silent packets to ensure Moonlight won't complain
|
||||
// A packet size of 128 seems a reasonable enough threshold
|
||||
if(bytes < 128) {
|
||||
BOOST_LOG(verbose) << "Dropped silent packet"sv;
|
||||
continue;
|
||||
}
|
||||
|
||||
packet.fake_resize(bytes);
|
||||
packets->raise(channel_data, std::move(packet));
|
||||
}
|
||||
@@ -119,9 +123,7 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
|
||||
|
||||
void capture(safe::mail_t mail, config_t config, void *channel_data) {
|
||||
auto shutdown_event = mail->event<bool>(mail::shutdown);
|
||||
|
||||
//FIXME: Pick correct opus_stream_config_t based on config.channels
|
||||
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
|
||||
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
|
||||
|
||||
auto ref = control_shared.ref();
|
||||
if(!ref) {
|
||||
@@ -135,7 +137,7 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Order of priorty:
|
||||
// Order of priority:
|
||||
// 1. Config
|
||||
// 2. Virtual if available
|
||||
// 3. Host
|
||||
@@ -162,12 +164,21 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) {
|
||||
if(!ref->sink_flag->exchange(true, std::memory_order_acquire)) {
|
||||
ref->restore_sink = !config.flags[config_t::HOST_AUDIO];
|
||||
|
||||
// If the sink is empty (Host has no sink!), definately switch to the virtual.
|
||||
if(ref->sink.host.empty()) {
|
||||
if(control->set_sink(*sink)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If the client requests audio on the host, don't change the default sink
|
||||
if(!config.flags[config_t::HOST_AUDIO] && control->set_sink(*sink)) {
|
||||
else if(!config.flags[config_t::HOST_AUDIO] && control->set_sink(*sink)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Capture takes place on this thread
|
||||
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
||||
|
||||
auto samples = std::make_shared<sample_queue_t::element_type>(30);
|
||||
std::thread thread { encodeThread, samples, config, channel_data };
|
||||
|
||||
@@ -219,7 +230,7 @@ int map_stream(int channels, bool quality) {
|
||||
int shift = quality ? 1 : 0;
|
||||
switch(channels) {
|
||||
case 2:
|
||||
return STEREO;
|
||||
return STEREO + shift;
|
||||
case 6:
|
||||
return SURROUND51 + shift;
|
||||
case 8:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
namespace audio {
|
||||
enum stream_config_e : int {
|
||||
STEREO,
|
||||
HIGH_STEREO,
|
||||
SURROUND51,
|
||||
HIGH_SURROUND51,
|
||||
SURROUND71,
|
||||
@@ -19,6 +20,7 @@ struct opus_stream_config_t {
|
||||
int streams;
|
||||
int coupledStreams;
|
||||
const std::uint8_t *mapping;
|
||||
int bitrate;
|
||||
};
|
||||
|
||||
extern opus_stream_config_t stream_configs[MAX_STREAM_CONFIG];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extern "C" {
|
||||
#include <cbs/cbs_h264.h>
|
||||
#include <cbs/cbs_h265.h>
|
||||
#include <cbs/video_levels.h>
|
||||
#include <cbs/h264_levels.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
}
|
||||
@@ -124,9 +124,9 @@ util::buffer_t<std::uint8_t> make_sps_h264(const AVCodecContext *ctx) {
|
||||
sps.seq_parameter_set_id = 0;
|
||||
sps.chroma_format_idc = 1;
|
||||
|
||||
sps.log2_max_frame_num_minus4 = 3; //4;
|
||||
sps.log2_max_frame_num_minus4 = 3; // 4;
|
||||
sps.pic_order_cnt_type = 0;
|
||||
sps.log2_max_pic_order_cnt_lsb_minus4 = 0; //4;
|
||||
sps.log2_max_pic_order_cnt_lsb_minus4 = 0; // 4;
|
||||
|
||||
sps.max_num_ref_frames = dpb_frame;
|
||||
|
||||
@@ -297,4 +297,4 @@ bool validate_sps(const AVPacket *packet, int codec_id) {
|
||||
|
||||
return ((CodedBitstreamH265Context *)ctx->priv_data)->active_sps->vui_parameters_present_flag;
|
||||
}
|
||||
} // namespace cbs
|
||||
} // namespace cbs
|
||||
|
||||
@@ -31,4 +31,4 @@ h264_t make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet);
|
||||
bool validate_sps(const AVPacket *packet, int codec_id);
|
||||
} // namespace cbs
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
301
src/config.cpp
301
src/config.cpp
@@ -6,6 +6,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "main.h"
|
||||
@@ -24,50 +25,71 @@ using namespace std::literals;
|
||||
namespace config {
|
||||
|
||||
namespace nv {
|
||||
#ifdef __APPLE__
|
||||
// values accurate as of 27/12/2022, but aren't strictly necessary for MacOS build
|
||||
#define NV_ENC_TUNING_INFO_HIGH_QUALITY 1
|
||||
#define NV_ENC_TUNING_INFO_LOW_LATENCY 2
|
||||
#define NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY 3
|
||||
#define NV_ENC_TUNING_INFO_LOSSLESS 4
|
||||
#define NV_ENC_PARAMS_RC_CONSTQP 0x0
|
||||
#define NV_ENC_PARAMS_RC_VBR 0x1
|
||||
#define NV_ENC_PARAMS_RC_CBR 0x2
|
||||
#define NV_ENC_H264_ENTROPY_CODING_MODE_CABAC 1
|
||||
#define NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC 2
|
||||
#else
|
||||
#include <ffnvcodec/nvEncodeAPI.h>
|
||||
#endif
|
||||
|
||||
enum preset_e : int {
|
||||
_default = 0,
|
||||
slow,
|
||||
medium,
|
||||
fast,
|
||||
hp,
|
||||
hq,
|
||||
bd,
|
||||
ll_default,
|
||||
llhq,
|
||||
llhp,
|
||||
lossless_default, // lossless presets must be the last ones
|
||||
lossless_hp,
|
||||
p1 = 12, // PRESET_P1, // must be kept in sync with <libavcodec/nvenc.h>
|
||||
p2, // PRESET_P2,
|
||||
p3, // PRESET_P3,
|
||||
p4, // PRESET_P4,
|
||||
p5, // PRESET_P5,
|
||||
p6, // PRESET_P6,
|
||||
p7 // PRESET_P7
|
||||
};
|
||||
|
||||
enum tune_e : int {
|
||||
hq = NV_ENC_TUNING_INFO_HIGH_QUALITY,
|
||||
ll = NV_ENC_TUNING_INFO_LOW_LATENCY,
|
||||
ull = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY,
|
||||
lossless = NV_ENC_TUNING_INFO_LOSSLESS
|
||||
};
|
||||
|
||||
enum rc_e : int {
|
||||
constqp = 0x0, /**< Constant QP mode */
|
||||
vbr = 0x1, /**< Variable bitrate mode */
|
||||
cbr = 0x2, /**< Constant bitrate mode */
|
||||
cbr_ld_hq = 0x8, /**< low-delay CBR, high quality */
|
||||
cbr_hq = 0x10, /**< CBR, high quality (slower) */
|
||||
vbr_hq = 0x20 /**< VBR, high quality (slower) */
|
||||
constqp = NV_ENC_PARAMS_RC_CONSTQP, /**< Constant QP mode */
|
||||
vbr = NV_ENC_PARAMS_RC_VBR, /**< Variable bitrate mode */
|
||||
cbr = NV_ENC_PARAMS_RC_CBR /**< Constant bitrate mode */
|
||||
};
|
||||
|
||||
enum coder_e : int {
|
||||
_auto = 0,
|
||||
cabac,
|
||||
cavlc
|
||||
cabac = NV_ENC_H264_ENTROPY_CODING_MODE_CABAC,
|
||||
cavlc = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC,
|
||||
};
|
||||
|
||||
std::optional<preset_e> preset_from_view(const std::string_view &preset) {
|
||||
#define _CONVERT_(x) \
|
||||
if(preset == #x##sv) return x
|
||||
_CONVERT_(slow);
|
||||
_CONVERT_(medium);
|
||||
_CONVERT_(fast);
|
||||
_CONVERT_(hp);
|
||||
_CONVERT_(bd);
|
||||
_CONVERT_(ll_default);
|
||||
_CONVERT_(llhq);
|
||||
_CONVERT_(llhp);
|
||||
_CONVERT_(lossless_default);
|
||||
_CONVERT_(lossless_hp);
|
||||
if(preset == "default"sv) return _default;
|
||||
_CONVERT_(p1);
|
||||
_CONVERT_(p2);
|
||||
_CONVERT_(p3);
|
||||
_CONVERT_(p4);
|
||||
_CONVERT_(p5);
|
||||
_CONVERT_(p6);
|
||||
_CONVERT_(p7);
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<tune_e> tune_from_view(const std::string_view &tune) {
|
||||
#define _CONVERT_(x) \
|
||||
if(tune == #x##sv) return x
|
||||
_CONVERT_(hq);
|
||||
_CONVERT_(ll);
|
||||
_CONVERT_(ull);
|
||||
_CONVERT_(lossless);
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -78,9 +100,6 @@ std::optional<rc_e> rc_from_view(const std::string_view &rc) {
|
||||
_CONVERT_(constqp);
|
||||
_CONVERT_(vbr);
|
||||
_CONVERT_(cbr);
|
||||
_CONVERT_(cbr_hq);
|
||||
_CONVERT_(vbr_hq);
|
||||
_CONVERT_(cbr_ld_hq);
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -95,46 +114,98 @@ int coder_from_view(const std::string_view &coder) {
|
||||
} // namespace nv
|
||||
|
||||
namespace amd {
|
||||
enum quality_e : int {
|
||||
_default = 0,
|
||||
speed,
|
||||
balanced,
|
||||
#ifdef __APPLE__
|
||||
// values accurate as of 27/12/2022, but aren't strictly necessary for MacOS build
|
||||
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED 10
|
||||
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY 0
|
||||
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED 5
|
||||
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED 1
|
||||
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY 2
|
||||
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED 0
|
||||
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP 0
|
||||
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR 3
|
||||
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2
|
||||
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 1
|
||||
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP 0
|
||||
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR 1
|
||||
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2
|
||||
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 3
|
||||
#define AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING 0
|
||||
#define AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY 1
|
||||
#define AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY 2
|
||||
#define AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM 3
|
||||
#define AMF_VIDEO_ENCODER_USAGE_TRANSCONDING 0
|
||||
#define AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY 1
|
||||
#define AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY 2
|
||||
#define AMF_VIDEO_ENCODER_USAGE_WEBCAM 3
|
||||
#define AMF_VIDEO_ENCODER_UNDEFINED 0
|
||||
#define AMF_VIDEO_ENCODER_CABAC 1
|
||||
#define AMF_VIDEO_ENCODER_CALV 2
|
||||
#else
|
||||
#include <AMF/components/VideoEncoderHEVC.h>
|
||||
#include <AMF/components/VideoEncoderVCE.h>
|
||||
#endif
|
||||
|
||||
enum class quality_hevc_e : int {
|
||||
speed = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED,
|
||||
quality = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY,
|
||||
balanced = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED
|
||||
};
|
||||
|
||||
enum class quality_h264_e : int {
|
||||
speed = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED,
|
||||
quality = AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY,
|
||||
balanced = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED
|
||||
};
|
||||
|
||||
enum class rc_hevc_e : int {
|
||||
constqp, /**< Constant QP mode */
|
||||
vbr_latency, /**< Latency Constrained Variable Bitrate */
|
||||
vbr_peak, /**< Peak Contrained Variable Bitrate */
|
||||
cbr, /**< Constant bitrate mode */
|
||||
cqp = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP,
|
||||
vbr_latency = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
|
||||
vbr_peak = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
|
||||
cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR
|
||||
};
|
||||
|
||||
enum class rc_h264_e : int {
|
||||
constqp, /**< Constant QP mode */
|
||||
cbr, /**< Constant bitrate mode */
|
||||
vbr_peak, /**< Peak Contrained Variable Bitrate */
|
||||
vbr_latency, /**< Latency Constrained Variable Bitrate */
|
||||
cqp = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP,
|
||||
vbr_latency = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
|
||||
vbr_peak = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
|
||||
cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR
|
||||
};
|
||||
|
||||
enum class usage_hevc_e : int {
|
||||
transcoding = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING,
|
||||
webcam = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM,
|
||||
lowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY,
|
||||
ultralowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY
|
||||
};
|
||||
|
||||
enum class usage_h264_e : int {
|
||||
transcoding = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING,
|
||||
webcam = AMF_VIDEO_ENCODER_USAGE_WEBCAM,
|
||||
lowlatency = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY,
|
||||
ultralowlatency = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY
|
||||
};
|
||||
|
||||
enum coder_e : int {
|
||||
_auto = 0,
|
||||
cabac,
|
||||
cavlc
|
||||
_auto = AMF_VIDEO_ENCODER_UNDEFINED,
|
||||
cabac = AMF_VIDEO_ENCODER_CABAC,
|
||||
cavlc = AMF_VIDEO_ENCODER_CALV
|
||||
};
|
||||
|
||||
std::optional<quality_e> quality_from_view(const std::string_view &quality) {
|
||||
std::optional<int> quality_from_view(const std::string_view &quality_type, int codec) {
|
||||
#define _CONVERT_(x) \
|
||||
if(quality == #x##sv) return x
|
||||
if(quality_type == #x##sv) return codec == 0 ? (int)quality_hevc_e::x : (int)quality_h264_e::x
|
||||
_CONVERT_(quality);
|
||||
_CONVERT_(speed);
|
||||
_CONVERT_(balanced);
|
||||
if(quality == "default"sv) return _default;
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<int> rc_h264_from_view(const std::string_view &rc) {
|
||||
std::optional<int> rc_from_view(const std::string_view &rc, int codec) {
|
||||
#define _CONVERT_(x) \
|
||||
if(rc == #x##sv) return (int)rc_h264_e::x
|
||||
_CONVERT_(constqp);
|
||||
if(rc == #x##sv) return codec == 0 ? (int)rc_hevc_e::x : (int)rc_h264_e::x
|
||||
_CONVERT_(cqp);
|
||||
_CONVERT_(vbr_latency);
|
||||
_CONVERT_(vbr_peak);
|
||||
_CONVERT_(cbr);
|
||||
@@ -142,13 +213,13 @@ std::optional<int> rc_h264_from_view(const std::string_view &rc) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<int> rc_hevc_from_view(const std::string_view &rc) {
|
||||
std::optional<int> usage_from_view(const std::string_view &rc, int codec) {
|
||||
#define _CONVERT_(x) \
|
||||
if(rc == #x##sv) return (int)rc_hevc_e::x
|
||||
_CONVERT_(constqp);
|
||||
_CONVERT_(vbr_latency);
|
||||
_CONVERT_(vbr_peak);
|
||||
_CONVERT_(cbr);
|
||||
if(rc == #x##sv) return codec == 0 ? (int)usage_hevc_e::x : (int)usage_h264_e::x
|
||||
_CONVERT_(transcoding);
|
||||
_CONVERT_(webcam);
|
||||
_CONVERT_(lowlatency);
|
||||
_CONVERT_(ultralowlatency);
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -162,6 +233,46 @@ int coder_from_view(const std::string_view &coder) {
|
||||
}
|
||||
} // namespace amd
|
||||
|
||||
namespace qsv {
|
||||
enum preset_e : int {
|
||||
veryslow = 1,
|
||||
slower = 2,
|
||||
slow = 3,
|
||||
medium = 4,
|
||||
fast = 5,
|
||||
faster = 6,
|
||||
veryfast = 7
|
||||
};
|
||||
|
||||
enum cavlc_e : int {
|
||||
_auto = false,
|
||||
enabled = true,
|
||||
disabled = false
|
||||
};
|
||||
|
||||
std::optional<int> preset_from_view(const std::string_view &preset) {
|
||||
#define _CONVERT_(x) \
|
||||
if(preset == #x##sv) return x
|
||||
_CONVERT_(veryslow);
|
||||
_CONVERT_(slower);
|
||||
_CONVERT_(slow);
|
||||
_CONVERT_(medium);
|
||||
_CONVERT_(fast);
|
||||
_CONVERT_(faster);
|
||||
_CONVERT_(veryfast);
|
||||
#undef _CONVERT_
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<int> coder_from_view(const std::string_view &coder) {
|
||||
if(coder == "auto"sv) return _auto;
|
||||
if(coder == "cabac"sv || coder == "ac"sv) return disabled;
|
||||
if(coder == "cavlc"sv || coder == "vlc"sv) return enabled;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace qsv
|
||||
|
||||
namespace vt {
|
||||
|
||||
enum coder_e : int {
|
||||
@@ -210,21 +321,35 @@ video_t video {
|
||||
}, // software
|
||||
|
||||
{
|
||||
nv::llhq,
|
||||
std::nullopt,
|
||||
-1 }, // nv
|
||||
nv::p4, // preset
|
||||
nv::ull, // tune
|
||||
nv::cbr, // rc
|
||||
nv::_auto // coder
|
||||
}, // nv
|
||||
|
||||
{
|
||||
amd::balanced,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
-1 }, // amd
|
||||
qsv::medium, // preset
|
||||
qsv::_auto, // cavlc
|
||||
}, // qsv
|
||||
|
||||
{
|
||||
(int)amd::quality_h264_e::balanced, // quality (h264)
|
||||
(int)amd::quality_hevc_e::balanced, // quality (hevc)
|
||||
(int)amd::rc_h264_e::vbr_latency, // rate control (h264)
|
||||
(int)amd::rc_hevc_e::vbr_latency, // rate control (hevc)
|
||||
(int)amd::usage_h264_e::ultralowlatency, // usage (h264)
|
||||
(int)amd::usage_hevc_e::ultralowlatency, // usage (hevc)
|
||||
0, // preanalysis
|
||||
1, // vbaq
|
||||
(int)amd::coder_e::_auto, // coder
|
||||
}, // amd
|
||||
|
||||
{
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
-1 }, // vt
|
||||
-1,
|
||||
}, // vt
|
||||
|
||||
{}, // encoder
|
||||
{}, // adapter_name
|
||||
@@ -295,6 +420,7 @@ sunshine_t sunshine {
|
||||
platf::appdata().string() + "/sunshine.conf", // config file
|
||||
{}, // cmd args
|
||||
47989,
|
||||
platf::appdata().string() + "/sunshine.log", // log file
|
||||
};
|
||||
|
||||
bool endline(char ch) {
|
||||
@@ -702,7 +828,7 @@ int apply_flags(const char *line) {
|
||||
|
||||
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
if(!fs::exists(stream.file_apps.c_str())) {
|
||||
fs::copy_file(SUNSHINE_CONFIG_DIR "/apps.json", stream.file_apps);
|
||||
fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps);
|
||||
}
|
||||
|
||||
for(auto &[name, val] : vars) {
|
||||
@@ -715,19 +841,38 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
string_f(vars, "sw_preset", video.sw.preset);
|
||||
string_f(vars, "sw_tune", video.sw.tune);
|
||||
int_f(vars, "nv_preset", video.nv.preset, nv::preset_from_view);
|
||||
int_f(vars, "nv_tune", video.nv.tune, nv::tune_from_view);
|
||||
int_f(vars, "nv_rc", video.nv.rc, nv::rc_from_view);
|
||||
int_f(vars, "nv_coder", video.nv.coder, nv::coder_from_view);
|
||||
|
||||
int_f(vars, "amd_quality", video.amd.quality, amd::quality_from_view);
|
||||
int_f(vars, "qsv_preset", video.qsv.preset, qsv::preset_from_view);
|
||||
int_f(vars, "qsv_coder", video.qsv.cavlc, qsv::coder_from_view);
|
||||
|
||||
std::string quality;
|
||||
string_f(vars, "amd_quality", quality);
|
||||
if(!quality.empty()) {
|
||||
video.amd.quality_h264 = amd::quality_from_view(quality, 1);
|
||||
video.amd.quality_hevc = amd::quality_from_view(quality, 0);
|
||||
}
|
||||
|
||||
std::string rc;
|
||||
string_f(vars, "amd_rc", rc);
|
||||
int_f(vars, "amd_coder", video.amd.coder, amd::coder_from_view);
|
||||
if(!rc.empty()) {
|
||||
video.amd.rc_h264 = amd::rc_h264_from_view(rc);
|
||||
video.amd.rc_hevc = amd::rc_hevc_from_view(rc);
|
||||
video.amd.rc_h264 = amd::rc_from_view(rc, 1);
|
||||
video.amd.rc_hevc = amd::rc_from_view(rc, 0);
|
||||
}
|
||||
|
||||
std::string usage;
|
||||
string_f(vars, "amd_usage", usage);
|
||||
if(!usage.empty()) {
|
||||
video.amd.usage_h264 = amd::usage_from_view(rc, 1);
|
||||
video.amd.usage_hevc = amd::usage_from_view(rc, 0);
|
||||
}
|
||||
|
||||
bool_f(vars, "amd_preanalysis", (bool &)video.amd.preanalysis);
|
||||
bool_f(vars, "amd_vbaq", (bool &)video.amd.vbaq);
|
||||
|
||||
int_f(vars, "vt_coder", video.vt.coder, vt::coder_from_view);
|
||||
int_f(vars, "vt_software", video.vt.allow_sw, vt::allow_software_from_view);
|
||||
int_f(vars, "vt_software", video.vt.require_sw, vt::force_software_from_view);
|
||||
@@ -741,7 +886,7 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
path_f(vars, "pkey", nvhttp.pkey);
|
||||
path_f(vars, "cert", nvhttp.cert);
|
||||
string_f(vars, "sunshine_name", nvhttp.sunshine_name);
|
||||
|
||||
path_f(vars, "log_path", config::sunshine.log_file);
|
||||
path_f(vars, "file_state", nvhttp.file_state);
|
||||
|
||||
// Must be run after "file_state"
|
||||
@@ -910,8 +1055,14 @@ int parse(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// create appdata folder if it does not exist
|
||||
if(!boost::filesystem::exists(platf::appdata().string())) {
|
||||
boost::filesystem::create_directory(platf::appdata().string());
|
||||
}
|
||||
|
||||
// create config file if it does not exist
|
||||
if(!fs::exists(sunshine.config_file)) {
|
||||
fs::copy_file(SUNSHINE_CONFIG_DIR "/sunshine.conf", sunshine.config_file);
|
||||
std::ofstream { sunshine.config_file }; // create empty config file
|
||||
}
|
||||
|
||||
auto vars = parse_config(read_file(sunshine.config_file.c_str()));
|
||||
|
||||
14
src/config.h
14
src/config.h
@@ -23,14 +23,25 @@ struct video_t {
|
||||
|
||||
struct {
|
||||
std::optional<int> preset;
|
||||
std::optional<int> tune;
|
||||
std::optional<int> rc;
|
||||
int coder;
|
||||
} nv;
|
||||
|
||||
struct {
|
||||
std::optional<int> quality;
|
||||
std::optional<int> preset;
|
||||
std::optional<int> cavlc;
|
||||
} qsv;
|
||||
|
||||
struct {
|
||||
std::optional<int> quality_h264;
|
||||
std::optional<int> quality_hevc;
|
||||
std::optional<int> rc_h264;
|
||||
std::optional<int> rc_hevc;
|
||||
std::optional<int> usage_h264;
|
||||
std::optional<int> usage_hevc;
|
||||
std::optional<int> preanalysis;
|
||||
std::optional<int> vbaq;
|
||||
int coder;
|
||||
} amd;
|
||||
|
||||
@@ -120,6 +131,7 @@ struct sunshine_t {
|
||||
} cmd;
|
||||
|
||||
std::uint16_t port;
|
||||
std::string log_file;
|
||||
};
|
||||
|
||||
extern video_t video;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
//
|
||||
// Created by TheElixZammuto on 2021-05-09.
|
||||
// TODO: Authentication, better handling of routes common to nvhttp, cleanup
|
||||
|
||||
@@ -7,13 +6,18 @@
|
||||
#include "process.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <set>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <Simple-Web-Server/crypto.hpp>
|
||||
#include <Simple-Web-Server/server_https.hpp>
|
||||
#include <boost/asio/ssl/context_base.hpp>
|
||||
@@ -52,7 +56,7 @@ void print_req(const req_https_t &request) {
|
||||
BOOST_LOG(debug) << "DESTINATION :: "sv << request->path;
|
||||
|
||||
for(auto &[name, val] : request->header) {
|
||||
BOOST_LOG(debug) << name << " -- " << val;
|
||||
BOOST_LOG(debug) << name << " -- " << (name == "Authorization" ? "CREDENTIALS REDACTED" : val);
|
||||
}
|
||||
|
||||
BOOST_LOG(debug) << " [--] "sv;
|
||||
@@ -65,7 +69,7 @@ void print_req(const req_https_t &request) {
|
||||
}
|
||||
|
||||
void send_unauthorized(resp_https_t response, req_https_t request) {
|
||||
auto address = request->remote_endpoint_address();
|
||||
auto address = request->remote_endpoint().address().to_string();
|
||||
BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
|
||||
const SimpleWeb::CaseInsensitiveMultimap headers {
|
||||
{ "WWW-Authenticate", R"(Basic realm="Sunshine Gamestream Host", charset="UTF-8")" }
|
||||
@@ -74,7 +78,7 @@ void send_unauthorized(resp_https_t response, req_https_t request) {
|
||||
}
|
||||
|
||||
void send_redirect(resp_https_t response, req_https_t request, const char *path) {
|
||||
auto address = request->remote_endpoint_address();
|
||||
auto address = request->remote_endpoint().address().to_string();
|
||||
BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
|
||||
const SimpleWeb::CaseInsensitiveMultimap headers {
|
||||
{ "Location", path }
|
||||
@@ -83,7 +87,7 @@ void send_redirect(resp_https_t response, req_https_t request, const char *path)
|
||||
}
|
||||
|
||||
bool authenticate(resp_https_t response, req_https_t request) {
|
||||
auto address = request->remote_endpoint_address();
|
||||
auto address = request->remote_endpoint().address().to_string();
|
||||
auto ip_type = net::from_address(address);
|
||||
|
||||
if(ip_type > http::origin_web_ui_allowed) {
|
||||
@@ -92,7 +96,7 @@ bool authenticate(resp_https_t response, req_https_t request) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//If credentials are shown, redirect the user to a /welcome page
|
||||
// If credentials are shown, redirect the user to a /welcome page
|
||||
if(config::sunshine.username.empty()) {
|
||||
send_redirect(response, request, "/welcome");
|
||||
return false;
|
||||
@@ -140,6 +144,7 @@ void not_found(resp_https_t response, req_https_t request) {
|
||||
<< data.str();
|
||||
}
|
||||
|
||||
// todo - combine these functions into a single function that accepts the page, i.e "index", "pin", "apps"
|
||||
void getIndexPage(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
@@ -165,9 +170,12 @@ void getAppsPage(resp_https_t response, req_https_t request) {
|
||||
|
||||
print_req(request);
|
||||
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
headers.emplace("Access-Control-Allow-Origin", "https://images.igdb.com/");
|
||||
|
||||
std::string header = read_file(WEB_DIR "header.html");
|
||||
std::string content = read_file(WEB_DIR "apps.html");
|
||||
response->write(header + content);
|
||||
response->write(header + content, headers);
|
||||
}
|
||||
|
||||
void getClientsPage(resp_https_t response, req_https_t request) {
|
||||
@@ -222,6 +230,8 @@ void getTroubleshootingPage(resp_https_t response, req_https_t request) {
|
||||
}
|
||||
|
||||
void getFaviconImage(resp_https_t response, req_https_t request) {
|
||||
// todo - combine function with getSunshineLogoImage and possibly getNodeModules
|
||||
// todo - use mime_types map
|
||||
print_req(request);
|
||||
|
||||
std::ifstream in(WEB_DIR "images/favicon.ico", std::ios::binary);
|
||||
@@ -231,6 +241,8 @@ void getFaviconImage(resp_https_t response, req_https_t request) {
|
||||
}
|
||||
|
||||
void getSunshineLogoImage(resp_https_t response, req_https_t request) {
|
||||
// todo - combine function with getFaviconImage and possibly getNodeModules
|
||||
// todo - use mime_types map
|
||||
print_req(request);
|
||||
|
||||
std::ifstream in(WEB_DIR "images/logo-sunshine-45.png", std::ios::binary);
|
||||
@@ -239,50 +251,42 @@ void getSunshineLogoImage(resp_https_t response, req_https_t request) {
|
||||
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
|
||||
}
|
||||
|
||||
void getFontAwesomeCss(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
|
||||
std::string content = read_file(WEB_DIR "fonts/fontawesome-free-web/css/all.min.css");
|
||||
response->write(content);
|
||||
bool isChildPath(fs::path const &base, fs::path const &query) {
|
||||
auto relPath = fs::relative(base, query);
|
||||
return *(relPath.begin()) != fs::path("..");
|
||||
}
|
||||
|
||||
void getFontAwesomeBrands(resp_https_t response, req_https_t request) {
|
||||
void getNodeModules(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
fs::path webDirPath(WEB_DIR);
|
||||
fs::path nodeModulesPath(webDirPath / "node_modules");
|
||||
|
||||
std::ifstream in(WEB_DIR "fonts/fontawesome-free-web/webfonts/fa-brands-400.ttf", std::ios::binary);
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
headers.emplace("Content-Type", "font/ttf");
|
||||
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
|
||||
}
|
||||
// .relative_path is needed to shed any leading slash that might exist in the request path
|
||||
auto filePath = fs::weakly_canonical(webDirPath / fs::path(request->path).relative_path());
|
||||
|
||||
void getFontAwesomeSolid(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
|
||||
std::ifstream in(WEB_DIR "fonts/fontawesome-free-web/webfonts/fa-solid-900.ttf", std::ios::binary);
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
headers.emplace("Content-Type", "font/ttf");
|
||||
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
|
||||
}
|
||||
|
||||
void getBootstrapCss(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
|
||||
std::string content = read_file(WEB_DIR "third_party/bootstrap.min.css");
|
||||
response->write(content);
|
||||
}
|
||||
|
||||
void getBootstrapJs(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
|
||||
std::string content = read_file(WEB_DIR "third_party/bootstrap.bundle.min.js");
|
||||
response->write(content);
|
||||
}
|
||||
|
||||
void getVueJs(resp_https_t response, req_https_t request) {
|
||||
print_req(request);
|
||||
|
||||
std::string content = read_file(WEB_DIR "third_party/vue.js");
|
||||
response->write(content);
|
||||
// Don't do anything if file does not exist or is outside the node_modules directory
|
||||
if(!isChildPath(filePath, nodeModulesPath)) {
|
||||
BOOST_LOG(warning) << "Someone requested a path " << filePath << " that is outside the node_modules folder";
|
||||
response->write(SimpleWeb::StatusCode::client_error_bad_request, "Bad Request");
|
||||
}
|
||||
else if(!fs::exists(filePath)) {
|
||||
response->write(SimpleWeb::StatusCode::client_error_not_found);
|
||||
}
|
||||
else {
|
||||
auto relPath = fs::relative(filePath, webDirPath);
|
||||
// get the mime type from the file extension mime_types map
|
||||
// remove the leading period from the extension
|
||||
auto mimeType = mime_types.find(relPath.extension().string().substr(1));
|
||||
// check if the extension is in the map at the x position
|
||||
if(mimeType != mime_types.end()) {
|
||||
// if it is, set the content type to the mime type
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
headers.emplace("Content-Type", mimeType->second);
|
||||
std::ifstream in(filePath.string(), std::ios::binary);
|
||||
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
|
||||
}
|
||||
// do not return any file if the type is not in the map
|
||||
}
|
||||
}
|
||||
|
||||
void getApps(resp_https_t response, req_https_t request) {
|
||||
@@ -294,6 +298,17 @@ void getApps(resp_https_t response, req_https_t request) {
|
||||
response->write(content);
|
||||
}
|
||||
|
||||
void getLogs(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
print_req(request);
|
||||
|
||||
std::string content = read_file(config::sunshine.log_file.c_str());
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
headers.emplace("Content-Type", "text/plain");
|
||||
response->write(SimpleWeb::StatusCode::success_ok, content, headers);
|
||||
}
|
||||
|
||||
void saveApp(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
@@ -314,7 +329,7 @@ void saveApp(resp_https_t response, req_https_t request) {
|
||||
|
||||
BOOST_LOG(fatal) << config::stream.file_apps;
|
||||
try {
|
||||
//TODO: Input Validation
|
||||
// TODO: Input Validation
|
||||
pt::read_json(ss, inputTree);
|
||||
pt::read_json(config::stream.file_apps, fileTree);
|
||||
|
||||
@@ -335,7 +350,7 @@ void saveApp(resp_https_t response, req_https_t request) {
|
||||
apps_node.push_back(std::make_pair("", inputTree));
|
||||
}
|
||||
else {
|
||||
//Unfortuantely Boost PT does not allow to directly edit the array, copy should do the trick
|
||||
// Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick
|
||||
pt::ptree newApps;
|
||||
int i = 0;
|
||||
for(const auto &kv : apps_node) {
|
||||
@@ -388,7 +403,7 @@ void deleteApp(resp_https_t response, req_https_t request) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
//Unfortuantely Boost PT does not allow to directly edit the array, copy should do the trick
|
||||
// Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick
|
||||
pt::ptree newApps;
|
||||
int i = 0;
|
||||
for(const auto &kv : apps_node) {
|
||||
@@ -412,6 +427,67 @@ void deleteApp(resp_https_t response, req_https_t request) {
|
||||
proc::refresh(config::stream.file_apps);
|
||||
}
|
||||
|
||||
void uploadCover(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
std::stringstream ss;
|
||||
std::stringstream configStream;
|
||||
ss << request->content.rdbuf();
|
||||
pt::ptree outputTree;
|
||||
auto g = util::fail_guard([&]() {
|
||||
std::ostringstream data;
|
||||
|
||||
SimpleWeb::StatusCode code = SimpleWeb::StatusCode::success_ok;
|
||||
if(outputTree.get_child_optional("error").has_value()) {
|
||||
code = SimpleWeb::StatusCode::client_error_bad_request;
|
||||
}
|
||||
|
||||
pt::write_json(data, outputTree);
|
||||
response->write(code, data.str());
|
||||
});
|
||||
pt::ptree inputTree;
|
||||
try {
|
||||
pt::read_json(ss, inputTree);
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
BOOST_LOG(warning) << "UploadCover: "sv << e.what();
|
||||
outputTree.put("status", "false");
|
||||
outputTree.put("error", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
auto key = inputTree.get("key", "");
|
||||
if(key.empty()) {
|
||||
outputTree.put("error", "Cover key is required");
|
||||
return;
|
||||
}
|
||||
auto url = inputTree.get("url", "");
|
||||
|
||||
const std::string coverdir = platf::appdata().string() + "/covers/";
|
||||
if(!boost::filesystem::exists(coverdir)) {
|
||||
boost::filesystem::create_directory(coverdir);
|
||||
}
|
||||
|
||||
std::basic_string path = coverdir + http::url_escape(key) + ".png";
|
||||
if(!url.empty()) {
|
||||
if(http::url_get_host(url) != "images.igdb.com") {
|
||||
outputTree.put("error", "Only images.igdb.com is allowed");
|
||||
return;
|
||||
}
|
||||
if(!http::download_file(url, path)) {
|
||||
outputTree.put("error", "Failed to download cover");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto data = SimpleWeb::Crypto::Base64::decode(inputTree.get<std::string>("data"));
|
||||
|
||||
std::ofstream imgfile(path);
|
||||
imgfile.write(data.data(), (int)data.size());
|
||||
}
|
||||
outputTree.put("path", path);
|
||||
}
|
||||
|
||||
void getConfig(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
@@ -427,6 +503,7 @@ void getConfig(resp_https_t response, req_https_t request) {
|
||||
|
||||
outputTree.put("status", "true");
|
||||
outputTree.put("platform", SUNSHINE_PLATFORM);
|
||||
outputTree.put("restart_supported", platf::restart_supported());
|
||||
|
||||
auto vars = config::parse_config(read_file(config::sunshine.config_file.c_str()));
|
||||
|
||||
@@ -452,7 +529,7 @@ void saveConfig(resp_https_t response, req_https_t request) {
|
||||
});
|
||||
pt::ptree inputTree;
|
||||
try {
|
||||
//TODO: Input Validation
|
||||
// TODO: Input Validation
|
||||
pt::read_json(ss, inputTree);
|
||||
for(const auto &kv : inputTree) {
|
||||
std::string value = inputTree.get<std::string>(kv.first);
|
||||
@@ -470,6 +547,37 @@ void saveConfig(resp_https_t response, req_https_t request) {
|
||||
}
|
||||
}
|
||||
|
||||
void restart(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
print_req(request);
|
||||
|
||||
std::stringstream ss;
|
||||
std::stringstream configStream;
|
||||
ss << request->content.rdbuf();
|
||||
pt::ptree outputTree;
|
||||
auto g = util::fail_guard([&]() {
|
||||
std::ostringstream data;
|
||||
|
||||
pt::write_json(data, outputTree);
|
||||
response->write(data.str());
|
||||
});
|
||||
|
||||
if(!platf::restart_supported()) {
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", "Restart is not currently supported on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!platf::restart()) {
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", "Restart failed");
|
||||
return;
|
||||
}
|
||||
|
||||
outputTree.put("status", true);
|
||||
}
|
||||
|
||||
void savePassword(resp_https_t response, req_https_t request) {
|
||||
if(!config::sunshine.username.empty() && !authenticate(response, request)) return;
|
||||
|
||||
@@ -488,7 +596,7 @@ void savePassword(resp_https_t response, req_https_t request) {
|
||||
});
|
||||
|
||||
try {
|
||||
//TODO: Input Validation
|
||||
// TODO: Input Validation
|
||||
pt::read_json(ss, inputTree);
|
||||
auto username = inputTree.count("currentUsername") > 0 ? inputTree.get<std::string>("currentUsername") : "";
|
||||
auto newUsername = inputTree.get<std::string>("newUsername");
|
||||
@@ -544,7 +652,7 @@ void savePin(resp_https_t response, req_https_t request) {
|
||||
});
|
||||
|
||||
try {
|
||||
//TODO: Input Validation
|
||||
// TODO: Input Validation
|
||||
pt::read_json(ss, inputTree);
|
||||
std::string pin = inputTree.get<std::string>("pin");
|
||||
outputTree.put("status", nvhttp::pin(pin));
|
||||
@@ -595,53 +703,40 @@ void start() {
|
||||
|
||||
auto port_https = map_port(PORT_HTTPS);
|
||||
|
||||
auto ctx = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tls);
|
||||
ctx->use_certificate_chain_file(config::nvhttp.cert);
|
||||
ctx->use_private_key_file(config::nvhttp.pkey, boost::asio::ssl::context::pem);
|
||||
https_server_t server { ctx, 0 };
|
||||
server.default_resource = not_found;
|
||||
server.resource["^/$"]["GET"] = getIndexPage;
|
||||
server.resource["^/pin$"]["GET"] = getPinPage;
|
||||
server.resource["^/apps$"]["GET"] = getAppsPage;
|
||||
server.resource["^/clients$"]["GET"] = getClientsPage;
|
||||
server.resource["^/config$"]["GET"] = getConfigPage;
|
||||
server.resource["^/password$"]["GET"] = getPasswordPage;
|
||||
server.resource["^/welcome$"]["GET"] = getWelcomePage;
|
||||
server.resource["^/troubleshooting$"]["GET"] = getTroubleshootingPage;
|
||||
server.resource["^/api/pin"]["POST"] = savePin;
|
||||
server.resource["^/api/apps$"]["GET"] = getApps;
|
||||
server.resource["^/api/apps$"]["POST"] = saveApp;
|
||||
server.resource["^/api/config$"]["GET"] = getConfig;
|
||||
server.resource["^/api/config$"]["POST"] = saveConfig;
|
||||
server.resource["^/api/password$"]["POST"] = savePassword;
|
||||
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
||||
server.resource["^/api/clients/unpair$"]["POST"] = unpairAll;
|
||||
server.resource["^/api/apps/close"]["POST"] = closeApp;
|
||||
server.resource["^/images/favicon.ico$"]["GET"] = getFaviconImage;
|
||||
server.resource["^/images/logo-sunshine-45.png$"]["GET"] = getSunshineLogoImage;
|
||||
server.resource["^/third_party/bootstrap.min.css$"]["GET"] = getBootstrapCss;
|
||||
server.resource["^/third_party/bootstrap.bundle.min.js$"]["GET"] = getBootstrapJs;
|
||||
server.resource["^/fontawesome/css/all.min.css$"]["GET"] = getFontAwesomeCss;
|
||||
server.resource["^/fontawesome/webfonts/fa-brands-400.ttf$"]["GET"] = getFontAwesomeBrands;
|
||||
server.resource["^/fontawesome/webfonts/fa-solid-900.ttf$"]["GET"] = getFontAwesomeSolid;
|
||||
server.resource["^/third_party/vue.js$"]["GET"] = getVueJs;
|
||||
server.config.reuse_address = true;
|
||||
server.config.address = "0.0.0.0"s;
|
||||
server.config.port = port_https;
|
||||
https_server_t server { config::nvhttp.cert, config::nvhttp.pkey };
|
||||
server.default_resource["GET"] = not_found;
|
||||
server.resource["^/$"]["GET"] = getIndexPage;
|
||||
server.resource["^/pin$"]["GET"] = getPinPage;
|
||||
server.resource["^/apps$"]["GET"] = getAppsPage;
|
||||
server.resource["^/clients$"]["GET"] = getClientsPage;
|
||||
server.resource["^/config$"]["GET"] = getConfigPage;
|
||||
server.resource["^/password$"]["GET"] = getPasswordPage;
|
||||
server.resource["^/welcome$"]["GET"] = getWelcomePage;
|
||||
server.resource["^/troubleshooting$"]["GET"] = getTroubleshootingPage;
|
||||
server.resource["^/api/pin$"]["POST"] = savePin;
|
||||
server.resource["^/api/apps$"]["GET"] = getApps;
|
||||
server.resource["^/api/logs$"]["GET"] = getLogs;
|
||||
server.resource["^/api/apps$"]["POST"] = saveApp;
|
||||
server.resource["^/api/config$"]["GET"] = getConfig;
|
||||
server.resource["^/api/config$"]["POST"] = saveConfig;
|
||||
server.resource["^/api/restart$"]["POST"] = restart;
|
||||
server.resource["^/api/password$"]["POST"] = savePassword;
|
||||
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
||||
server.resource["^/api/clients/unpair$"]["POST"] = unpairAll;
|
||||
server.resource["^/api/apps/close$"]["POST"] = closeApp;
|
||||
server.resource["^/api/covers/upload$"]["POST"] = uploadCover;
|
||||
server.resource["^/images/favicon.ico$"]["GET"] = getFaviconImage;
|
||||
server.resource["^/images/logo-sunshine-45.png$"]["GET"] = getSunshineLogoImage;
|
||||
server.resource["^/node_modules\\/.+$"]["GET"] = getNodeModules;
|
||||
server.config.reuse_address = true;
|
||||
server.config.address = "0.0.0.0"s;
|
||||
server.config.port = port_https;
|
||||
|
||||
try {
|
||||
server.bind();
|
||||
BOOST_LOG(info) << "Configuration UI available at [https://localhost:"sv << port_https << "]";
|
||||
}
|
||||
catch(boost::system::system_error &err) {
|
||||
BOOST_LOG(fatal) << "Couldn't bind http server to ports ["sv << port_https << "]: "sv << err.what();
|
||||
|
||||
shutdown_event->raise(true);
|
||||
return;
|
||||
}
|
||||
auto accept_and_run = [&](auto *server) {
|
||||
try {
|
||||
server->accept_and_run();
|
||||
server->start([](unsigned short port) {
|
||||
BOOST_LOG(info) << "Configuration UI available at [https://localhost:"sv << port << "]";
|
||||
});
|
||||
}
|
||||
catch(boost::system::system_error &err) {
|
||||
// It's possible the exception gets thrown after calling server->stop() from a different thread
|
||||
@@ -649,7 +744,7 @@ void start() {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_LOG(fatal) << "Couldn't start Configuration HTTPS server to port ["sv << port_https << "]: "sv << err.what();
|
||||
BOOST_LOG(fatal) << "Couldn't start Configuration HTTPS server on port ["sv << port_https << "]: "sv << err.what();
|
||||
shutdown_event->raise(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 6/3/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_CONFIGHTTP_H
|
||||
#define SUNSHINE_CONFIGHTTP_H
|
||||
@@ -18,4 +16,23 @@ constexpr auto PORT_HTTPS = 1;
|
||||
void start();
|
||||
} // namespace confighttp
|
||||
|
||||
#endif //SUNSHINE_CONFIGHTTP_H
|
||||
// mime types map
|
||||
const std::map<std::string, std::string> mime_types = {
|
||||
{ "css", "text/css" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "htm", "text/html" },
|
||||
{ "html", "text/html" },
|
||||
{ "ico", "image/x-icon" },
|
||||
{ "jpeg", "image/jpeg" },
|
||||
{ "jpg", "image/jpeg" },
|
||||
{ "js", "application/javascript" },
|
||||
{ "json", "application/json" },
|
||||
{ "png", "image/png" },
|
||||
{ "svg", "image/svg+xml" },
|
||||
{ "ttf", "font/ttf" },
|
||||
{ "txt", "text/plain" },
|
||||
{ "woff2", "font/woff2" },
|
||||
{ "xml", "text/xml" },
|
||||
};
|
||||
|
||||
#endif // SUNSHINE_CONFIGHTTP_H
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
//
|
||||
// Created by loki on 5/31/19.
|
||||
//
|
||||
|
||||
#include "crypto.h"
|
||||
#include <openssl/pem.h>
|
||||
|
||||
namespace crypto {
|
||||
using big_num_t = util::safe_ptr<BIGNUM, BN_free>;
|
||||
//using rsa_t = util::safe_ptr<RSA, RSA_free>;
|
||||
using asn1_string_t = util::safe_ptr<ASN1_STRING, ASN1_STRING_free>;
|
||||
|
||||
cert_chain_t::cert_chain_t() : _certs {}, _cert_ctx { X509_STORE_CTX_new() } {}
|
||||
@@ -22,7 +18,7 @@ static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {
|
||||
int err_code = X509_STORE_CTX_get_error(ctx);
|
||||
|
||||
switch(err_code) {
|
||||
//FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi
|
||||
// FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
return 1;
|
||||
|
||||
@@ -274,7 +270,7 @@ int cbc_t::encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_
|
||||
|
||||
int len;
|
||||
|
||||
int size = plaintext.size(); //round_to_pkcs7_padded(plaintext.size());
|
||||
int size = plaintext.size(); // round_to_pkcs7_padded(plaintext.size());
|
||||
|
||||
// Encrypt into the caller's buffer
|
||||
if(EVP_EncryptUpdate(encrypt_ctx.get(), cipher, &size, (const std::uint8_t *)plaintext.data(), plaintext.size()) != 1) {
|
||||
@@ -317,12 +313,7 @@ aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &p
|
||||
|
||||
sha256_t hash(const std::string_view &plaintext) {
|
||||
sha256_t hsh;
|
||||
|
||||
SHA256_CTX sha256;
|
||||
SHA256_Init(&sha256);
|
||||
SHA256_Update(&sha256, plaintext.data(), plaintext.size());
|
||||
SHA256_Final(hsh.data(), &sha256);
|
||||
|
||||
EVP_Digest(plaintext.data(), plaintext.size(), hsh.data(), nullptr, EVP_sha256(), nullptr);
|
||||
return hsh;
|
||||
}
|
||||
|
||||
@@ -411,17 +402,20 @@ std::vector<uint8_t> sign(const pkey_t &pkey, const std::string_view &data, cons
|
||||
|
||||
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits) {
|
||||
x509_t x509 { X509_new() };
|
||||
pkey_t pkey { EVP_PKEY_new() };
|
||||
pkey_ctx_t ctx { EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr) };
|
||||
pkey_t pkey;
|
||||
|
||||
big_num_t big_num { BN_new() };
|
||||
BN_set_word(big_num.get(), RSA_F4);
|
||||
|
||||
auto rsa = RSA_new();
|
||||
RSA_generate_key_ex(rsa, key_bits, big_num.get(), nullptr);
|
||||
EVP_PKEY_assign_RSA(pkey.get(), rsa);
|
||||
EVP_PKEY_keygen_init(ctx.get());
|
||||
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), key_bits);
|
||||
EVP_PKEY_keygen(ctx.get(), &pkey);
|
||||
|
||||
X509_set_version(x509.get(), 2);
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), 0);
|
||||
|
||||
// Generate a real serial number to avoid SEC_ERROR_REUSED_ISSUER_AND_SERIAL with Firefox
|
||||
bignum_t serial { BN_new() };
|
||||
BN_rand(serial.get(), 159, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); // 159 bits to fit in 20 bytes in DER format
|
||||
BN_set_negative(serial.get(), 0); // Serial numbers must be positive
|
||||
BN_to_ASN1_INTEGER(serial.get(), X509_get_serialNumber(x509.get()));
|
||||
|
||||
constexpr auto year = 60 * 60 * 24 * 365;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
@@ -492,4 +486,4 @@ std::string rand_alphabet(std::size_t bytes, const std::string_view &alphabet) {
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
} // namespace crypto
|
||||
|
||||
16
src/crypto.h
16
src/crypto.h
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 6/1/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_CRYPTO_H
|
||||
#define SUNSHINE_CRYPTO_H
|
||||
@@ -32,6 +30,8 @@ using cipher_ctx_t = util::safe_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>;
|
||||
using md_ctx_t = util::safe_ptr<EVP_MD_CTX, md_ctx_destroy>;
|
||||
using bio_t = util::safe_ptr<BIO, BIO_free_all>;
|
||||
using pkey_t = util::safe_ptr<EVP_PKEY, EVP_PKEY_free>;
|
||||
using pkey_ctx_t = util::safe_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
|
||||
using bignum_t = util::safe_ptr<BIGNUM, BN_free>;
|
||||
|
||||
sha256_t hash(const std::string_view &plaintext);
|
||||
|
||||
@@ -84,8 +84,8 @@ public:
|
||||
|
||||
class ecb_t : public cipher_t {
|
||||
public:
|
||||
ecb_t() = default;
|
||||
ecb_t(ecb_t &&) noexcept = default;
|
||||
ecb_t() = default;
|
||||
ecb_t(ecb_t &&) noexcept = default;
|
||||
ecb_t &operator=(ecb_t &&) noexcept = default;
|
||||
|
||||
ecb_t(const aes_t &key, bool padding = true);
|
||||
@@ -96,8 +96,8 @@ public:
|
||||
|
||||
class gcm_t : public cipher_t {
|
||||
public:
|
||||
gcm_t() = default;
|
||||
gcm_t(gcm_t &&) noexcept = default;
|
||||
gcm_t() = default;
|
||||
gcm_t(gcm_t &&) noexcept = default;
|
||||
gcm_t &operator=(gcm_t &&) noexcept = default;
|
||||
|
||||
gcm_t(const crypto::aes_t &key, bool padding = true);
|
||||
@@ -115,8 +115,8 @@ public:
|
||||
|
||||
class cbc_t : public cipher_t {
|
||||
public:
|
||||
cbc_t() = default;
|
||||
cbc_t(cbc_t &&) noexcept = default;
|
||||
cbc_t() = default;
|
||||
cbc_t(cbc_t &&) noexcept = default;
|
||||
cbc_t &operator=(cbc_t &&) noexcept = default;
|
||||
|
||||
cbc_t(const crypto::aes_t &key, bool padding = true);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <Simple-Web-Server/server_http.hpp>
|
||||
#include <Simple-Web-Server/server_https.hpp>
|
||||
#include <boost/asio/ssl/context_base.hpp>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "crypto.h"
|
||||
@@ -44,7 +45,7 @@ int init() {
|
||||
|
||||
if(clean_slate) {
|
||||
unique_id = util::uuid_t::generate().string();
|
||||
auto dir = std::filesystem::temp_directory_path() / "Sushine"sv;
|
||||
auto dir = std::filesystem::temp_directory_path() / "Sunshine"sv;
|
||||
config::nvhttp.cert = (dir / ("cert-"s + unique_id)).string();
|
||||
config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string();
|
||||
}
|
||||
@@ -180,4 +181,55 @@ int create_creds(const std::string &pkey, const std::string &cert) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace http
|
||||
|
||||
bool download_file(const std::string &url, const std::string &file) {
|
||||
CURL *curl = curl_easy_init();
|
||||
if(!curl) {
|
||||
BOOST_LOG(error) << "Couldn't create CURL instance";
|
||||
return false;
|
||||
}
|
||||
FILE *fp = fopen(file.c_str(), "wb");
|
||||
if(!fp) {
|
||||
BOOST_LOG(error) << "Couldn't open ["sv << file << ']';
|
||||
curl_easy_cleanup(curl);
|
||||
return false;
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
#ifdef _WIN32
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
|
||||
#endif
|
||||
CURLcode result = curl_easy_perform(curl);
|
||||
if(result != CURLE_OK) {
|
||||
BOOST_LOG(error) << "Couldn't download ["sv << url << ", code:" << result << ']';
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(fp);
|
||||
return result == CURLE_OK;
|
||||
}
|
||||
|
||||
std::string url_escape(const std::string &url) {
|
||||
CURL *curl = curl_easy_init();
|
||||
char *string = curl_easy_escape(curl, url.c_str(), url.length());
|
||||
std::string result(string);
|
||||
curl_free(string);
|
||||
curl_easy_cleanup(curl);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string url_get_host(const std::string &url) {
|
||||
CURLU *curlu = curl_url();
|
||||
curl_url_set(curlu, CURLUPART_URL, url.c_str(), url.length());
|
||||
char *host;
|
||||
if(curl_url_get(curlu, CURLUPART_HOST, &host, 0) != CURLUE_OK) {
|
||||
curl_url_cleanup(curlu);
|
||||
return "";
|
||||
}
|
||||
std::string result(host);
|
||||
curl_free(host);
|
||||
curl_url_cleanup(curlu);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace http
|
||||
|
||||
@@ -12,8 +12,12 @@ int save_user_creds(
|
||||
bool run_our_mouth = false);
|
||||
|
||||
int reload_user_creds(const std::string &file);
|
||||
bool download_file(const std::string &url, const std::string &file);
|
||||
std::string url_escape(const std::string &url);
|
||||
std::string url_get_host(const std::string &url);
|
||||
|
||||
extern std::string unique_id;
|
||||
extern net::net_e origin_pin_allowed;
|
||||
extern net::net_e origin_web_ui_allowed;
|
||||
|
||||
} // namespace http
|
||||
} // namespace http
|
||||
|
||||
136
src/input.cpp
136
src/input.cpp
@@ -1,11 +1,10 @@
|
||||
//
|
||||
// Created by loki on 6/20/19.
|
||||
//
|
||||
|
||||
// define uint32_t for <moonlight-common-c/src/Input.h>
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
#include <moonlight-common-c/src/Input.h>
|
||||
#include <moonlight-common-c/src/Limelight.h>
|
||||
}
|
||||
|
||||
#include <bitset>
|
||||
@@ -89,7 +88,7 @@ struct gamepad_t {
|
||||
|
||||
// When emulating the HOME button, we may need to artificially release the back button.
|
||||
// Afterwards, the gamepad state on sunshine won't match the state on Moonlight.
|
||||
// To prevent Sunshine from sending erronious input data to the active application,
|
||||
// To prevent Sunshine from sending erroneous input data to the active application,
|
||||
// Sunshine forces the button to be in a specific state until the gamepad state matches that of
|
||||
// Moonlight once more.
|
||||
button_state_e back_button_state;
|
||||
@@ -177,7 +176,7 @@ void print(PNV_ABS_MOUSE_MOVE_PACKET packet) {
|
||||
void print(PNV_MOUSE_BUTTON_PACKET packet) {
|
||||
BOOST_LOG(debug)
|
||||
<< "--begin mouse button packet--"sv << std::endl
|
||||
<< "action ["sv << util::hex(packet->action).to_string_view() << ']' << std::endl
|
||||
<< "action ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl
|
||||
<< "button ["sv << util::hex(packet->button).to_string_view() << ']' << std::endl
|
||||
<< "--end mouse button packet--"sv;
|
||||
}
|
||||
@@ -189,15 +188,31 @@ void print(PNV_SCROLL_PACKET packet) {
|
||||
<< "--end mouse scroll packet--"sv;
|
||||
}
|
||||
|
||||
void print(PSS_HSCROLL_PACKET packet) {
|
||||
BOOST_LOG(debug)
|
||||
<< "--begin mouse hscroll packet--"sv << std::endl
|
||||
<< "scrollAmount ["sv << util::endian::big(packet->scrollAmount) << ']' << std::endl
|
||||
<< "--end mouse hscroll packet--"sv;
|
||||
}
|
||||
|
||||
void print(PNV_KEYBOARD_PACKET packet) {
|
||||
BOOST_LOG(debug)
|
||||
<< "--begin keyboard packet--"sv << std::endl
|
||||
<< "keyAction ["sv << util::hex(packet->keyAction).to_string_view() << ']' << std::endl
|
||||
<< "keyAction ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl
|
||||
<< "keyCode ["sv << util::hex(packet->keyCode).to_string_view() << ']' << std::endl
|
||||
<< "modifiers ["sv << util::hex(packet->modifiers).to_string_view() << ']' << std::endl
|
||||
<< "flags ["sv << util::hex(packet->flags).to_string_view() << ']' << std::endl
|
||||
<< "--end keyboard packet--"sv;
|
||||
}
|
||||
|
||||
void print(PNV_UNICODE_PACKET packet) {
|
||||
std::string text(packet->text, util::endian::big(packet->header.size) - sizeof(packet->header.magic));
|
||||
BOOST_LOG(debug)
|
||||
<< "--begin unicode packet--"sv << std::endl
|
||||
<< "text ["sv << text << ']' << std::endl
|
||||
<< "--end unicode packet--"sv;
|
||||
}
|
||||
|
||||
void print(PNV_MULTI_CONTROLLER_PACKET packet) {
|
||||
// Moonlight spams controller packet even when not necessary
|
||||
BOOST_LOG(verbose)
|
||||
@@ -214,33 +229,35 @@ void print(PNV_MULTI_CONTROLLER_PACKET packet) {
|
||||
<< "--end controller packet--"sv;
|
||||
}
|
||||
|
||||
constexpr int PACKET_TYPE_SCROLL_OR_KEYBOARD = PACKET_TYPE_SCROLL;
|
||||
void print(void *input) {
|
||||
int input_type = util::endian::big(*(int *)input);
|
||||
void print(void *payload) {
|
||||
auto header = (PNV_INPUT_HEADER)payload;
|
||||
|
||||
switch(input_type) {
|
||||
case PACKET_TYPE_REL_MOUSE_MOVE:
|
||||
print((PNV_REL_MOUSE_MOVE_PACKET)input);
|
||||
switch(util::endian::little(header->magic)) {
|
||||
case MOUSE_MOVE_REL_MAGIC_GEN5:
|
||||
print((PNV_REL_MOUSE_MOVE_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_ABS_MOUSE_MOVE:
|
||||
print((PNV_ABS_MOUSE_MOVE_PACKET)input);
|
||||
case MOUSE_MOVE_ABS_MAGIC:
|
||||
print((PNV_ABS_MOUSE_MOVE_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_MOUSE_BUTTON:
|
||||
print((PNV_MOUSE_BUTTON_PACKET)input);
|
||||
case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5:
|
||||
case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5:
|
||||
print((PNV_MOUSE_BUTTON_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_SCROLL_OR_KEYBOARD: {
|
||||
char *tmp_input = (char *)input + 4;
|
||||
if(tmp_input[0] == 0x0A) {
|
||||
print((PNV_SCROLL_PACKET)input);
|
||||
}
|
||||
else {
|
||||
print((PNV_KEYBOARD_PACKET)input);
|
||||
}
|
||||
|
||||
case SCROLL_MAGIC_GEN5:
|
||||
print((PNV_SCROLL_PACKET)payload);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_MULTI_CONTROLLER:
|
||||
print((PNV_MULTI_CONTROLLER_PACKET)input);
|
||||
case SS_HSCROLL_MAGIC:
|
||||
print((PSS_HSCROLL_PACKET)payload);
|
||||
break;
|
||||
case KEY_DOWN_EVENT_MAGIC:
|
||||
case KEY_UP_EVENT_MAGIC:
|
||||
print((PNV_KEYBOARD_PACKET)payload);
|
||||
break;
|
||||
case UTF8_TEXT_EVENT_MAGIC:
|
||||
print((PNV_UNICODE_PACKET)payload);
|
||||
break;
|
||||
case MULTI_CONTROLLER_MAGIC_GEN5:
|
||||
print((PNV_MULTI_CONTROLLER_PACKET)payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -296,14 +313,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET pack
|
||||
}
|
||||
|
||||
void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
|
||||
auto constexpr BUTTON_RELEASED = 0x09;
|
||||
|
||||
auto constexpr BUTTON_LEFT = 0x01;
|
||||
auto constexpr BUTTON_RIGHT = 0x03;
|
||||
|
||||
auto release = packet->action == BUTTON_RELEASED;
|
||||
|
||||
auto button = util::endian::big(packet->button);
|
||||
auto release = util::endian::little(packet->header.magic) == MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5;
|
||||
auto button = util::endian::big(packet->button);
|
||||
if(button > 0 && button < mouse_press.size()) {
|
||||
if(mouse_press[button] != release) {
|
||||
// button state is already what we want
|
||||
@@ -316,11 +327,11 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
|
||||
/*/
|
||||
* When Moonlight sends mouse input through absolute coordinates,
|
||||
* it's possible that BUTTON_RIGHT is pressed down immediately after releasing BUTTON_LEFT.
|
||||
* As a result, Sunshine will left click on hyperlinks in the browser before right clicking
|
||||
* As a result, Sunshine will left-click on hyperlinks in the browser before right-clicking
|
||||
*
|
||||
* This can be solved by delaying BUTTON_LEFT, however, any delay on input is undesirable during gaming
|
||||
* As a compromise, Sunshine will only put delays on BUTTON_LEFT when
|
||||
* absolute mouse coordinates have been send.
|
||||
* absolute mouse coordinates have been sent.
|
||||
*
|
||||
* Try to make sure BUTTON_RIGHT gets called before BUTTON_LEFT is released.
|
||||
*
|
||||
@@ -419,16 +430,14 @@ void repeat_key(short key_code) {
|
||||
}
|
||||
|
||||
void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
|
||||
auto constexpr BUTTON_RELEASED = 0x04;
|
||||
|
||||
auto release = packet->keyAction == BUTTON_RELEASED;
|
||||
auto release = util::endian::little(packet->header.magic) == KEY_UP_EVENT_MAGIC;
|
||||
auto keyCode = packet->keyCode & 0x00FF;
|
||||
|
||||
auto &pressed = key_press[keyCode];
|
||||
if(!pressed) {
|
||||
if(!release) {
|
||||
// A new key has been pressed down, we need to check for key combo's
|
||||
// If a keycombo has been pressed down, don't pass it through
|
||||
// If a key-combo has been pressed down, don't pass it through
|
||||
if(input->shortcutFlags == input_t::SHORTCUT && apply_shortcut(keyCode) > 0) {
|
||||
return;
|
||||
}
|
||||
@@ -461,6 +470,15 @@ void passthrough(PNV_SCROLL_PACKET packet) {
|
||||
platf::scroll(platf_input, util::endian::big(packet->scrollAmt1));
|
||||
}
|
||||
|
||||
void passthrough(PSS_HSCROLL_PACKET packet) {
|
||||
platf::hscroll(platf_input, util::endian::big(packet->scrollAmount));
|
||||
}
|
||||
|
||||
void passthrough(PNV_UNICODE_PACKET packet) {
|
||||
auto size = util::endian::big(packet->header.size) - sizeof(packet->header.magic);
|
||||
platf::unicode(platf_input, packet->text, size);
|
||||
}
|
||||
|
||||
int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state, const platf::rumble_queue_t &rumble_queue) {
|
||||
auto xorGamepadMask = old_state ^ new_state;
|
||||
if(!xorGamepadMask) {
|
||||
@@ -602,31 +620,33 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET pa
|
||||
|
||||
void passthrough_helper(std::shared_ptr<input_t> input, std::vector<std::uint8_t> &&input_data) {
|
||||
void *payload = input_data.data();
|
||||
auto header = (PNV_INPUT_HEADER)payload;
|
||||
|
||||
int input_type = util::endian::big(*(int *)payload);
|
||||
|
||||
switch(input_type) {
|
||||
case PACKET_TYPE_REL_MOUSE_MOVE:
|
||||
switch(util::endian::little(header->magic)) {
|
||||
case MOUSE_MOVE_REL_MAGIC_GEN5:
|
||||
passthrough(input, (PNV_REL_MOUSE_MOVE_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_ABS_MOUSE_MOVE:
|
||||
case MOUSE_MOVE_ABS_MAGIC:
|
||||
passthrough(input, (PNV_ABS_MOUSE_MOVE_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_MOUSE_BUTTON:
|
||||
case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5:
|
||||
case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5:
|
||||
passthrough(input, (PNV_MOUSE_BUTTON_PACKET)payload);
|
||||
break;
|
||||
case PACKET_TYPE_SCROLL_OR_KEYBOARD: {
|
||||
char *tmp_input = (char *)payload + 4;
|
||||
if(tmp_input[0] == 0x0A) {
|
||||
passthrough((PNV_SCROLL_PACKET)payload);
|
||||
}
|
||||
else {
|
||||
passthrough(input, (PNV_KEYBOARD_PACKET)payload);
|
||||
}
|
||||
|
||||
case SCROLL_MAGIC_GEN5:
|
||||
passthrough((PNV_SCROLL_PACKET)payload);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_MULTI_CONTROLLER:
|
||||
case SS_HSCROLL_MAGIC:
|
||||
passthrough((PSS_HSCROLL_PACKET)payload);
|
||||
break;
|
||||
case KEY_DOWN_EVENT_MAGIC:
|
||||
case KEY_UP_EVENT_MAGIC:
|
||||
passthrough(input, (PNV_KEYBOARD_PACKET)payload);
|
||||
break;
|
||||
case UTF8_TEXT_EVENT_MAGIC:
|
||||
passthrough((PNV_UNICODE_PACKET)payload);
|
||||
break;
|
||||
case MULTI_CONTROLLER_MAGIC_GEN5:
|
||||
passthrough(input, (PNV_MULTI_CONTROLLER_PACKET)payload);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 6/20/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_INPUT_H
|
||||
#define SUNSHINE_INPUT_H
|
||||
@@ -32,4 +30,4 @@ struct touch_port_t : public platf::touch_port_t {
|
||||
};
|
||||
} // namespace input
|
||||
|
||||
#endif //SUNSHINE_INPUT_H
|
||||
#endif // SUNSHINE_INPUT_H
|
||||
|
||||
72
src/main.cpp
72
src/main.cpp
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 5/30/19.
|
||||
//
|
||||
|
||||
#include "process.h"
|
||||
|
||||
@@ -103,6 +101,7 @@ int entry(const char *name, int argc, char *argv[]) {
|
||||
}
|
||||
} // namespace version
|
||||
|
||||
|
||||
void log_flush() {
|
||||
sink->flush();
|
||||
}
|
||||
@@ -138,23 +137,71 @@ std::map<std::string_view, std::function<int(const char *name, int argc, char **
|
||||
{ "version"sv, version::entry }
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
LRESULT CALLBACK SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch(uMsg) {
|
||||
case WM_ENDSESSION: {
|
||||
// Raise a SIGINT to trigger our cleanup logic and terminate ourselves
|
||||
std::cout << "Received WM_ENDSESSION"sv << std::endl;
|
||||
std::raise(SIGINT);
|
||||
|
||||
// The signal handling is asynchronous, so we will wait here to be terminated.
|
||||
// If for some reason we don't terminate in a few seconds, Windows will kill us.
|
||||
SuspendThread(GetCurrentThread());
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
util::TaskPool::task_id_t force_shutdown = nullptr;
|
||||
|
||||
bool shutdown_by_interrupt = false;
|
||||
#ifdef _WIN32
|
||||
// Wait as long as possible to terminate Sunshine.exe during logoff/shutdown
|
||||
SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);
|
||||
|
||||
auto exit_guard = util::fail_guard([&shutdown_by_interrupt, &force_shutdown]() {
|
||||
if(!shutdown_by_interrupt) {
|
||||
// We must create a hidden window to receive shutdown notifications since we load gdi32.dll
|
||||
std::thread window_thread([]() {
|
||||
WNDCLASSA wnd_class {};
|
||||
wnd_class.lpszClassName = "SunshineSessionMonitorClass";
|
||||
wnd_class.lpfnWndProc = SessionMonitorWindowProc;
|
||||
if(!RegisterClassA(&wnd_class)) {
|
||||
std::cout << "Failed to register session monitor window class"sv << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
task_pool.cancel(force_shutdown);
|
||||
auto wnd = CreateWindowExA(
|
||||
0,
|
||||
wnd_class.lpszClassName,
|
||||
"Sunshine Session Monitor Window",
|
||||
0,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
if(!wnd) {
|
||||
std::cout << "Failed to create session monitor window"sv << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Sunshine exited: Press enter to continue"sv << std::endl;
|
||||
ShowWindow(wnd, SW_HIDE);
|
||||
|
||||
std::string _;
|
||||
std::getline(std::cin, _);
|
||||
// Run the message loop for our window
|
||||
MSG msg {};
|
||||
while(GetMessage(&msg, nullptr, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
});
|
||||
window_thread.detach();
|
||||
#endif
|
||||
|
||||
mail::man = std::make_shared<safe::mail_raw_t>();
|
||||
|
||||
@@ -173,6 +220,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
boost::shared_ptr<std::ostream> stream { &std::cout, NoDelete {} };
|
||||
sink->locked_backend()->add_stream(stream);
|
||||
sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(config::sunshine.log_file));
|
||||
sink->set_filter(severity >= config::sunshine.min_log_level);
|
||||
|
||||
sink->set_formatter([message = "Message"s, severity = "Severity"s](const bl::record_view &view, bl::formatting_ostream &os) {
|
||||
@@ -236,7 +284,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Create signal handler after logging has been initialized
|
||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||
on_signal(SIGINT, [&shutdown_by_interrupt, &force_shutdown, shutdown_event]() {
|
||||
on_signal(SIGINT, [&force_shutdown, shutdown_event]() {
|
||||
BOOST_LOG(info) << "Interrupt handler called"sv;
|
||||
|
||||
auto task = []() {
|
||||
@@ -246,7 +294,6 @@ int main(int argc, char *argv[]) {
|
||||
};
|
||||
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
||||
|
||||
shutdown_by_interrupt = true;
|
||||
shutdown_event->raise(true);
|
||||
});
|
||||
|
||||
@@ -289,7 +336,7 @@ int main(int argc, char *argv[]) {
|
||||
upnp_unmap = upnp::start();
|
||||
});
|
||||
|
||||
//FIXME: Temporary workaround: Simple-Web_server needs to be updated or replaced
|
||||
// FIXME: Temporary workaround: Simple-Web_server needs to be updated or replaced
|
||||
if(shutdown_event->peek()) {
|
||||
return 0;
|
||||
}
|
||||
@@ -310,6 +357,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
std::string read_file(const char *path) {
|
||||
if(!std::filesystem::exists(path)) {
|
||||
BOOST_LOG(debug) << "Missing file: " << path;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
14
src/main.h
14
src/main.h
@@ -1,10 +1,9 @@
|
||||
//
|
||||
// Created by loki on 12/22/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_MAIN_H
|
||||
#define SUNSHINE_MAIN_H
|
||||
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
|
||||
#include "thread_pool.h"
|
||||
@@ -32,8 +31,10 @@ int write_file(const char *path, const std::string_view &contents);
|
||||
std::uint16_t map_port(int port);
|
||||
|
||||
namespace mail {
|
||||
#define MAIL(x) \
|
||||
constexpr auto x = std::string_view { #x }
|
||||
#define MAIL(x) \
|
||||
constexpr auto x = std::string_view { \
|
||||
#x \
|
||||
}
|
||||
|
||||
extern safe::mail_t man;
|
||||
|
||||
@@ -50,8 +51,7 @@ MAIL(switch_display);
|
||||
MAIL(touch_port);
|
||||
MAIL(idr);
|
||||
MAIL(rumble);
|
||||
MAIL(hdr);
|
||||
#undef MAIL
|
||||
} // namespace mail
|
||||
|
||||
|
||||
#endif //SUNSHINE_MAIN_H
|
||||
#endif // SUNSHINE_MAIN_H
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 12/27/19.
|
||||
//
|
||||
|
||||
#include "network.h"
|
||||
#include "utility.h"
|
||||
@@ -112,4 +110,4 @@ void free_host(ENetHost *host) {
|
||||
|
||||
enet_host_destroy(host);
|
||||
}
|
||||
} // namespace net
|
||||
} // namespace net
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 12/27/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_NETWORK_H
|
||||
#define SUNSHINE_NETWORK_H
|
||||
@@ -32,4 +30,4 @@ net_e from_address(const std::string_view &view);
|
||||
host_t host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port);
|
||||
} // namespace net
|
||||
|
||||
#endif //SUNSHINE_NETWORK_H
|
||||
#endif // SUNSHINE_NETWORK_H
|
||||
|
||||
160
src/nvhttp.cpp
160
src/nvhttp.cpp
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// Created by loki on 6/3/19.
|
||||
//
|
||||
|
||||
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
|
||||
|
||||
@@ -33,13 +31,76 @@
|
||||
using namespace std::literals;
|
||||
namespace nvhttp {
|
||||
|
||||
constexpr auto VERSION = "7.1.431.0";
|
||||
// The negative 4th version number tells Moonlight that this is Sunshine
|
||||
constexpr auto VERSION = "7.1.431.-1";
|
||||
constexpr auto GFE_VERSION = "3.23.0.74";
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
using https_server_t = SimpleWeb::Server<SimpleWeb::HTTPS>;
|
||||
class SunshineHttpsServer : public SimpleWeb::Server<SimpleWeb::HTTPS> {
|
||||
public:
|
||||
SunshineHttpsServer(const std::string &certification_file, const std::string &private_key_file)
|
||||
: SimpleWeb::Server<SimpleWeb::HTTPS>::Server(certification_file, private_key_file) {}
|
||||
|
||||
std::function<int(SSL *)> verify;
|
||||
std::function<void(std::shared_ptr<Response>, std::shared_ptr<Request>)> on_verify_failed;
|
||||
|
||||
protected:
|
||||
void after_bind() override {
|
||||
SimpleWeb::Server<SimpleWeb::HTTPS>::after_bind();
|
||||
|
||||
if(verify) {
|
||||
context.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert | boost::asio::ssl::verify_client_once);
|
||||
context.set_verify_callback([](int verified, boost::asio::ssl::verify_context &ctx) {
|
||||
// To respond with an error message, a connection must be established
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// This is Server<HTTPS>::accept() with SSL validation support added
|
||||
void accept() override {
|
||||
auto connection = create_connection(*io_service, context);
|
||||
|
||||
acceptor->async_accept(connection->socket->lowest_layer(), [this, connection](const SimpleWeb::error_code &ec) {
|
||||
auto lock = connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
|
||||
if(ec != SimpleWeb::error::operation_aborted)
|
||||
this->accept();
|
||||
|
||||
auto session = std::make_shared<Session>(config.max_request_streambuf_size, connection);
|
||||
|
||||
if(!ec) {
|
||||
boost::asio::ip::tcp::no_delay option(true);
|
||||
SimpleWeb::error_code ec;
|
||||
session->connection->socket->lowest_layer().set_option(option, ec);
|
||||
|
||||
session->connection->set_timeout(config.timeout_request);
|
||||
session->connection->socket->async_handshake(boost::asio::ssl::stream_base::server, [this, session](const SimpleWeb::error_code &ec) {
|
||||
session->connection->cancel_timeout();
|
||||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if(!ec) {
|
||||
if(verify && !verify(session->connection->socket->native_handle()))
|
||||
this->write(session, on_verify_failed);
|
||||
else
|
||||
this->read(session);
|
||||
}
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
}
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
using https_server_t = SunshineHttpsServer;
|
||||
using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>;
|
||||
|
||||
struct conf_intern_t {
|
||||
@@ -88,6 +149,14 @@ enum class op_e {
|
||||
REMOVE
|
||||
};
|
||||
|
||||
std::string get_arg(const args_t &args, const char *name) {
|
||||
auto it = args.find(name);
|
||||
if(it == std::end(args)) {
|
||||
throw std::out_of_range(name);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void save_state() {
|
||||
pt::ptree root;
|
||||
|
||||
@@ -190,8 +259,8 @@ stream::launch_session_t make_launch_session(bool host_audio, const args_t &args
|
||||
stream::launch_session_t launch_session;
|
||||
|
||||
launch_session.host_audio = host_audio;
|
||||
launch_session.gcm_key = util::from_hex<crypto::aes_t>(args.at("rikey"s), true);
|
||||
uint32_t prepend_iv = util::endian::big<uint32_t>(util::from_view(args.at("rikeyid"s)));
|
||||
launch_session.gcm_key = util::from_hex<crypto::aes_t>(get_arg(args, "rikey"), true);
|
||||
uint32_t prepend_iv = util::endian::big<uint32_t>(util::from_view(get_arg(args, "rikeyid")));
|
||||
auto prepend_iv_p = (uint8_t *)&prepend_iv;
|
||||
|
||||
auto next = std::copy(prepend_iv_p, prepend_iv_p + sizeof(prepend_iv), std::begin(launch_session.iv));
|
||||
@@ -219,7 +288,7 @@ void getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
}
|
||||
void serverchallengeresp(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
|
||||
auto encrypted_response = util::from_hex_vec(args.at("serverchallengeresp"s), true);
|
||||
auto encrypted_response = util::from_hex_vec(get_arg(args, "serverchallengeresp"), true);
|
||||
|
||||
std::vector<uint8_t> decrypted;
|
||||
crypto::cipher::ecb_t cipher(*sess.cipher_key, false);
|
||||
@@ -239,7 +308,7 @@ void serverchallengeresp(pair_session_t &sess, pt::ptree &tree, const args_t &ar
|
||||
}
|
||||
|
||||
void clientchallenge(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
|
||||
auto challenge = util::from_hex_vec(args.at("clientchallenge"s), true);
|
||||
auto challenge = util::from_hex_vec(get_arg(args, "clientchallenge"), true);
|
||||
|
||||
crypto::cipher::ecb_t cipher(*sess.cipher_key, false);
|
||||
|
||||
@@ -276,7 +345,7 @@ void clientchallenge(pair_session_t &sess, pt::ptree &tree, const args_t &args)
|
||||
void clientpairingsecret(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, pair_session_t &sess, pt::ptree &tree, const args_t &args) {
|
||||
auto &client = sess.client;
|
||||
|
||||
auto pairingsecret = util::from_hex_vec(args.at("clientpairingsecret"), true);
|
||||
auto pairingsecret = util::from_hex_vec(get_arg(args, "clientpairingsecret"), true);
|
||||
|
||||
std::string_view secret { pairingsecret.data(), 16 };
|
||||
std::string_view sign { pairingsecret.data() + secret.size(), crypto::digest_size };
|
||||
@@ -297,7 +366,7 @@ void clientpairingsecret(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cer
|
||||
|
||||
// if hash not correct, probably MITM
|
||||
if(std::memcmp(hash.data(), sess.clienthash.data(), hash.size())) {
|
||||
//TODO: log
|
||||
// TODO: log
|
||||
|
||||
map_id_sess.erase(client.uniqueID);
|
||||
tree.put("root.paired", 0);
|
||||
@@ -393,7 +462,7 @@ void pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_
|
||||
return;
|
||||
}
|
||||
|
||||
auto uniqID { std::move(args.at("uniqueid"s)) };
|
||||
auto uniqID { std::move(get_arg(args, "uniqueid")) };
|
||||
auto sess_it = map_id_sess.find(uniqID);
|
||||
|
||||
args_t::const_iterator it;
|
||||
@@ -402,12 +471,12 @@ void pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_
|
||||
pair_session_t sess;
|
||||
|
||||
sess.client.uniqueID = std::move(uniqID);
|
||||
sess.client.cert = util::from_hex_vec(args.at("clientcert"s), true);
|
||||
sess.client.cert = util::from_hex_vec(get_arg(args, "clientcert"), true);
|
||||
|
||||
BOOST_LOG(debug) << sess.client.cert;
|
||||
auto ptr = map_id_sess.emplace(sess.client.uniqueID, std::move(sess)).first;
|
||||
|
||||
ptr->second.async_insert_pin.salt = std::move(args.at("salt"s));
|
||||
ptr->second.async_insert_pin.salt = std::move(get_arg(args, "salt"));
|
||||
|
||||
if(config::sunshine.flags[config::flag::PIN_STDIN]) {
|
||||
std::string pin;
|
||||
@@ -479,7 +548,7 @@ void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response,
|
||||
|
||||
response->close_connection_after_response = true;
|
||||
|
||||
auto address = request->remote_endpoint_address();
|
||||
auto address = request->remote_endpoint().address().to_string();
|
||||
auto ip_type = net::from_address(address);
|
||||
if(ip_type > http::origin_pin_allowed) {
|
||||
BOOST_LOG(info) << "/pin: ["sv << address << "] -- denied"sv;
|
||||
@@ -515,6 +584,8 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
|
||||
}
|
||||
}
|
||||
|
||||
auto local_endpoint = request->local_endpoint();
|
||||
|
||||
pt::ptree tree;
|
||||
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
@@ -525,9 +596,9 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
|
||||
tree.put("root.uniqueid", http::unique_id);
|
||||
tree.put("root.HttpsPort", map_port(PORT_HTTPS));
|
||||
tree.put("root.ExternalPort", map_port(PORT_HTTP));
|
||||
tree.put("root.mac", platf::get_mac_address(request->local_endpoint_address()));
|
||||
tree.put("root.mac", platf::get_mac_address(local_endpoint.address().to_string()));
|
||||
tree.put("root.MaxLumaPixelsHEVC", config::video.hevc_mode > 1 ? "1869449984" : "0");
|
||||
tree.put("root.LocalIP", request->local_endpoint_address());
|
||||
tree.put("root.LocalIP", local_endpoint.address().to_string());
|
||||
|
||||
if(config::video.hevc_mode == 3) {
|
||||
tree.put("root.ServerCodecModeSupport", "3843");
|
||||
@@ -570,8 +641,8 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
|
||||
}
|
||||
auto current_appid = proc::proc.running();
|
||||
tree.put("root.PairStatus", pair_status);
|
||||
tree.put("root.currentgame", current_appid >= 0 ? current_appid + 1 : 0);
|
||||
tree.put("root.state", current_appid >= 0 ? "SUNSHINE_SERVER_BUSY" : "SUNSHINE_SERVER_FREE");
|
||||
tree.put("root.currentgame", current_appid);
|
||||
tree.put("root.state", current_appid > 0 ? "SUNSHINE_SERVER_BUSY" : "SUNSHINE_SERVER_FREE");
|
||||
|
||||
std::ostringstream data;
|
||||
|
||||
@@ -600,7 +671,7 @@ void applist(resp_https_t response, req_https_t request) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clientID = args.at("uniqueid"s);
|
||||
auto clientID = get_arg(args, "uniqueid");
|
||||
|
||||
auto client = map_id_client.find(clientID);
|
||||
if(client == std::end(map_id_client)) {
|
||||
@@ -613,13 +684,12 @@ void applist(resp_https_t response, req_https_t request) {
|
||||
|
||||
apps.put("<xmlattr>.status_code", 200);
|
||||
|
||||
int x = 0;
|
||||
for(auto &proc : proc::proc.get_apps()) {
|
||||
pt::ptree app;
|
||||
|
||||
app.put("IsHdrSupported"s, config::video.hevc_mode == 3 ? 1 : 0);
|
||||
app.put("AppTitle"s, proc.name);
|
||||
app.put("ID"s, ++x);
|
||||
app.put("ID", proc.id);
|
||||
|
||||
apps.push_back(std::make_pair("App", std::move(app)));
|
||||
}
|
||||
@@ -657,17 +727,17 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto appid = util::from_view(args.at("appid")) - 1;
|
||||
auto appid = util::from_view(get_arg(args, "appid"));
|
||||
|
||||
auto current_appid = proc::proc.running();
|
||||
if(current_appid != -1) {
|
||||
if(current_appid > 0) {
|
||||
tree.put("root.resume", 0);
|
||||
tree.put("root.<xmlattr>.status_code", 400);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(appid >= 0) {
|
||||
if(appid > 0) {
|
||||
auto err = proc::proc.execute(appid);
|
||||
if(err) {
|
||||
tree.put("root.<xmlattr>.status_code", err);
|
||||
@@ -677,11 +747,11 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
}
|
||||
}
|
||||
|
||||
host_audio = util::from_view(args.at("localAudioPlayMode"));
|
||||
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
|
||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.gamesession", 1);
|
||||
}
|
||||
|
||||
@@ -707,7 +777,7 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
}
|
||||
|
||||
auto current_appid = proc::proc.running();
|
||||
if(current_appid == -1) {
|
||||
if(current_appid == 0) {
|
||||
tree.put("root.resume", 0);
|
||||
tree.put("root.<xmlattr>.status_code", 503);
|
||||
|
||||
@@ -728,7 +798,7 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.resume", 1);
|
||||
}
|
||||
|
||||
@@ -756,7 +826,7 @@ void cancel(resp_https_t response, req_https_t request) {
|
||||
tree.put("root.cancel", 1);
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
|
||||
if(proc::proc.running() != -1) {
|
||||
if(proc::proc.running() > 0) {
|
||||
proc::proc.terminate();
|
||||
}
|
||||
}
|
||||
@@ -766,7 +836,7 @@ void appasset(resp_https_t response, req_https_t request) {
|
||||
print_req<SimpleWeb::HTTPS>(request);
|
||||
|
||||
auto args = request->parse_query_string();
|
||||
auto app_image = proc::proc.get_app_image(util::from_view(args.at("appid")));
|
||||
auto app_image = proc::proc.get_app_image(util::from_view(get_arg(args, "appid")));
|
||||
|
||||
std::ifstream in(app_image, std::ios::binary);
|
||||
SimpleWeb::CaseInsensitiveMultimap headers;
|
||||
@@ -790,10 +860,6 @@ void start() {
|
||||
conf_intern.pkey = read_file(config::nvhttp.pkey.c_str());
|
||||
conf_intern.servercert = read_file(config::nvhttp.cert.c_str());
|
||||
|
||||
auto ctx = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tls);
|
||||
ctx->use_certificate_chain_file(config::nvhttp.cert);
|
||||
ctx->use_private_key_file(config::nvhttp.pkey, boost::asio::ssl::context::pem);
|
||||
|
||||
crypto::cert_chain_t cert_chain;
|
||||
for(auto &[_, client] : map_id_client) {
|
||||
for(auto &cert : client.certs) {
|
||||
@@ -803,16 +869,11 @@ void start() {
|
||||
|
||||
auto add_cert = std::make_shared<safe::queue_t<crypto::x509_t>>(30);
|
||||
|
||||
ctx->set_verify_callback([](int verified, boost::asio::ssl::verify_context &ctx) {
|
||||
// To respond with an error message, a connection must be established
|
||||
return 1;
|
||||
});
|
||||
|
||||
// /resume doesn't get the parameter "localAudioPlayMode"
|
||||
// /launch will store it in host_audio
|
||||
bool host_audio {};
|
||||
|
||||
https_server_t https_server { ctx, boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert | boost::asio::ssl::verify_client_once };
|
||||
https_server_t https_server { config::nvhttp.cert, config::nvhttp.pkey };
|
||||
http_server_t http_server;
|
||||
|
||||
// Verify certificates after establishing connection
|
||||
@@ -872,7 +933,7 @@ void start() {
|
||||
tree.put("root.<xmlattr>.status_message"s, "The client is not authorized. Certificate verification failed."s);
|
||||
};
|
||||
|
||||
https_server.default_resource = not_found<SimpleWeb::HTTPS>;
|
||||
https_server.default_resource["GET"] = not_found<SimpleWeb::HTTPS>;
|
||||
https_server.resource["^/serverinfo$"]["GET"] = serverinfo<SimpleWeb::HTTPS>;
|
||||
https_server.resource["^/pair$"]["GET"] = [&add_cert](auto resp, auto req) { pair<SimpleWeb::HTTPS>(add_cert, resp, req); };
|
||||
https_server.resource["^/applist$"]["GET"] = applist;
|
||||
@@ -886,7 +947,7 @@ void start() {
|
||||
https_server.config.address = "0.0.0.0"s;
|
||||
https_server.config.port = port_https;
|
||||
|
||||
http_server.default_resource = not_found<SimpleWeb::HTTP>;
|
||||
http_server.default_resource["GET"] = not_found<SimpleWeb::HTTP>;
|
||||
http_server.resource["^/serverinfo$"]["GET"] = serverinfo<SimpleWeb::HTTP>;
|
||||
http_server.resource["^/pair$"]["GET"] = [&add_cert](auto resp, auto req) { pair<SimpleWeb::HTTP>(add_cert, resp, req); };
|
||||
http_server.resource["^/pin/([0-9]+)$"]["GET"] = pin<SimpleWeb::HTTP>;
|
||||
@@ -895,20 +956,9 @@ void start() {
|
||||
http_server.config.address = "0.0.0.0"s;
|
||||
http_server.config.port = port_http;
|
||||
|
||||
try {
|
||||
https_server.bind();
|
||||
http_server.bind();
|
||||
}
|
||||
catch(boost::system::system_error &err) {
|
||||
BOOST_LOG(fatal) << "Couldn't bind http server to ports ["sv << port_http << ", "sv << port_http << "]: "sv << err.what();
|
||||
|
||||
shutdown_event->raise(true);
|
||||
return;
|
||||
}
|
||||
|
||||
auto accept_and_run = [&](auto *http_server) {
|
||||
try {
|
||||
http_server->accept_and_run();
|
||||
http_server->start();
|
||||
}
|
||||
catch(boost::system::system_error &err) {
|
||||
// It's possible the exception gets thrown after calling http_server->stop() from a different thread
|
||||
@@ -916,7 +966,7 @@ void start() {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_LOG(fatal) << "Couldn't start http server to ports ["sv << port_https << ", "sv << port_https << "]: "sv << err.what();
|
||||
BOOST_LOG(fatal) << "Couldn't start http server on ports ["sv << port_https << ", "sv << port_https << "]: "sv << err.what();
|
||||
shutdown_event->raise(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user