Compare commits

...

647 Commits

Author SHA1 Message Date
ReenigneArcher
6000b85b1a Merge pull request #283 from LizardByte/nightly
v0.14.1
2022-08-09 19:42:10 -04:00
ReenigneArcher
d661568536 Merge pull request #317 from LizardByte/prepare-v0.14.1
prepare v0.14.1
2022-08-09 18:44:36 -04:00
ReenigneArcher
c4e3687c01 Merge branch 'nightly' into prepare-v0.14.1 2022-08-09 17:22:14 -04:00
ReenigneArcher
a6b8371178 v0.14.1 2022-08-09 17:20:46 -04:00
ReenigneArcher
f546ee8551 Merge pull request #316 from LizardByte/prepare-v0.14.1
Prepare v0.14.1
2022-08-09 08:23:20 -04:00
ReenigneArcher
db28239939 v0.14.1 2022-08-08 22:40:13 -04:00
ReenigneArcher
9f87401173 fix source directory 2022-08-08 22:40:01 -04:00
ReenigneArcher
4100f790ee Merge pull request #304 from LizardByte/bot/manual-update-global-workflow-nightly-cnnsp
ci: update global workflows
2022-08-08 20:35:16 -04:00
ReenigneArcher
a4acaf15b0 move sunshine to src
- this will allow for common cpp workflow files within org
2022-08-07 23:37:57 -04:00
ReenigneArcher
0de52efdb1 move TPCircularBuffer submodule 2022-08-07 23:13:19 -04:00
ReenigneArcher
1d242aed7c fix yaml-lint errors 2022-08-07 21:19:05 -04:00
LizardByte-bot
4d3c9b0be8 ci: update global workflows 2022-08-07 23:33:19 +00:00
ReenigneArcher
8164c09ea0 Merge pull request #215 from sitiom/winget-releaser
Add winget releaser action
2022-08-07 19:32:13 -04:00
ReenigneArcher
b464902f25 Merge branch 'nightly' into winget-releaser 2022-08-07 18:35:09 -04:00
ReenigneArcher
844f041a58 Merge pull request #302 from LizardByte/update/html
Update/html
2022-08-07 18:16:39 -04:00
ReenigneArcher
de628e843e Merge branch 'nightly' into update/html 2022-08-07 17:29:03 -04:00
ReenigneArcher
de6779ed83 Merge pull request #303 from LizardByte/fix/archlinux-package-action
fixed archlinux-package-action
2022-08-07 17:28:45 -04:00
ReenigneArcher
2afa3a4390 Change docs nav header background color 2022-08-07 17:01:25 -04:00
ReenigneArcher
094ab4eb1a fixed archlinux-package-action 2022-08-07 16:46:02 -04:00
ReenigneArcher
c184f16e28 fix support link and...
- remove AUR `sunshine-git` badge
2022-08-07 16:39:59 -04:00
ReenigneArcher
15aca474eb fix button formatting 2022-08-07 16:34:39 -04:00
ReenigneArcher
d963bd1daa add discord widgetbot crate 2022-08-07 16:34:15 -04:00
istori1
d38392aea0 sunshine.conf and apps.json on user's home config dir (#269) 2022-08-05 20:47:21 -04:00
sitiom
b7ef109d95 Update Winget badge link (#284)
Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2022-08-03 15:56:35 -04:00
dependabot[bot]
dc8bda0e1b Bump KSXGitHub/github-actions-deploy-aur from 2.3.0 to 2.4.1 (#292)
Bumps [KSXGitHub/github-actions-deploy-aur](https://github.com/KSXGitHub/github-actions-deploy-aur) from 2.3.0 to 2.4.1.
- [Release notes](https://github.com/KSXGitHub/github-actions-deploy-aur/releases)
- [Commits](https://github.com/KSXGitHub/github-actions-deploy-aur/compare/v2.3.0...v2.4.1)

---
updated-dependencies:
- dependency-name: KSXGitHub/github-actions-deploy-aur
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2022-08-03 15:13:31 -04:00
Ryan Caezar Itang
7cc5e1345c Add Winget Releaser workflow 2022-08-03 23:31:29 +08:00
Robert
49147694de Fix minor typo (#287)
Correct 'verfied' to 'verified'

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2022-08-02 09:20:34 -04:00
istori1
58a71bf3e7 Add permission for Flatpak. (#291)
* Add permission for Flatpak.

Adding --talk-name=org.freedesktop.Flatpak as this is needed to launch applications on the host. Example flatpak-spawn --host sleep 1m.

* Alphabetical order
2022-07-31 20:52:39 -04:00
LizardByte-bot
5ac84fd03f ci: update global workflows (#286) 2022-07-30 21:48:13 -04:00
LizardByte-bot
1439c8d951 ci: update release notifier (#282) 2022-07-30 15:14:28 -04:00
LizardByte-bot
ce9934ca52 ci: update issue templates (#281) 2022-07-30 13:44:57 -04:00
LizardByte-bot
7451c1bd17 ci: update global cpp (#280) 2022-07-29 23:18:06 -04:00
LizardByte-bot
7340f7660b ci: update dependabot (#278) 2022-07-29 22:29:35 -04:00
LizardByte-bot
a9af8472df ci: update global workflows (#279) 2022-07-29 21:45:02 -04:00
LizardByte-bot
b5fa9bb1be ci: update global python (#277)
Co-authored-by: LizardByte-bot <108553330+RetroArcher-bot@users.noreply.github.com>
2022-07-29 19:28:15 -04:00
dependabot[bot]
f850b037bc Bump sphinx from 5.0.2 to 5.1.1 in /scripts (#268)
Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 5.0.2 to 5.1.1.
- [Release notes](https://github.com/sphinx-doc/sphinx/releases)
- [Changelog](https://github.com/sphinx-doc/sphinx/blob/5.x/CHANGES)
- [Commits](https://github.com/sphinx-doc/sphinx/compare/v5.0.2...v5.1.1)

---
updated-dependencies:
- dependency-name: sphinx
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-29 10:47:41 -04:00
ReenigneArcher
da3c39e9e3 change org to LizardByte (#263)
- updates issue template
- updates docker readme
2022-07-29 09:45:26 -04:00
ReenigneArcher
7d4df19cdc fix aur build (#273)
* fix aur build

* Update both aur repos
2022-07-29 08:56:07 -04:00
istori1
d19c883067 Add CUDA to Flatpak (#218) 2022-07-05 19:27:14 -04:00
ReenigneArcher
42eda48ce4 Merge pull request #232 from SunshineStream/fix-CI-for-outside-pull-requests
Fix flatpak CI for outside pull requests
2022-06-29 20:32:25 -04:00
ReenigneArcher
fd0dc9ab8e Fix flatpak CI for outside pull requests 2022-06-29 20:02:15 -04:00
ReenigneArcher
1415c8b200 Merge pull request #204 from SunshineStream/macports-improvements
Macports improvements
2022-06-29 19:44:46 -04:00
ReenigneArcher
8ba3c073e7 Remove macOS requirements table 2022-06-29 19:08:14 -04:00
ReenigneArcher
92f1313993 Merge branch 'nightly' into macports-improvements 2022-06-29 19:06:33 -04:00
ReenigneArcher
2b3c514aad Merge pull request #214 from SunshineStream/add-aur-publish
Integrate AUR package `sunshine-git`
2022-06-29 18:57:16 -04:00
ReenigneArcher
819501c4e7 Use v2.3.0 of KSXGitHub/github-actions-deploy-aur action 2022-06-28 20:39:58 -04:00
ReenigneArcher
3b2226c4ea Add paths for aur package 2022-06-28 20:39:33 -04:00
ReenigneArcher
00405892cb Don't rename default config files 2022-06-28 19:26:34 -04:00
ReenigneArcher
3cd3d261e9 Update macOS documentation 2022-06-28 19:16:24 -04:00
ReenigneArcher
4f07672cfa CI cleanup 2022-06-28 19:00:13 -04:00
ReenigneArcher
25e21ee807 Fix removing directories for macos uninstall_pkg 2022-06-25 19:10:47 -04:00
ReenigneArcher
270d4ddffe Fix paths for AUR and...
- Rename udev rules file
- Refactor CI to properly collect clone url for PRs (AUR only)
2022-06-23 23:55:48 -04:00
ReenigneArcher
46dede3381 Disable matrix for Macports
- Currently cannot build Sunshine on macOS < 10.8 due to missing video toolbox framework
2022-06-23 22:58:27 -04:00
ReenigneArcher
7019756fa1 Fix macos uninstall pkg script 2022-06-23 20:42:18 -04:00
ReenigneArcher
a1d8cc2296 Update installation.rst 2022-06-22 21:43:18 -04:00
ReenigneArcher
c61b31e8a6 Create uninstall_pkg.sh 2022-06-22 21:42:10 -04:00
ReenigneArcher
802e5c79fa Add config option SUNSHINE_MACOS_PACKAGE
- Refactor UNIX/APPLE packaging
2022-06-22 19:52:48 -04:00
ReenigneArcher
6b64149591 Update Portfile
- Add `compiler.cxx_standard`
- Don't overwrite config files
- Fix `maintainers`
- Correct cmake configure arguments
- Remove `destroot`
- Use `git` instead of `github.setup`
- Set revision to 0
- Add long description
2022-06-21 22:35:03 -04:00
ReenigneArcher
8fc8884dbc Update PKGBUILD
- Add `avahi` as dependency
- Order dependencies in alphabetical order
- Use fast compilation for `make` command
2022-06-20 20:35:19 -04:00
ReenigneArcher
2b76111e51 Remove AUR from issue template config 2022-06-20 19:44:20 -04:00
ReenigneArcher
54221ae938 Use cached responses for AUR badges 2022-06-20 19:19:47 -04:00
ReenigneArcher
f07171315f Configure PKGBUILD according to github event
- Release to AUR on push into `master`
- Update AUR installation instructions
- Use common linux directories for `PKGBUILD`
2022-06-19 23:35:02 -04:00
ReenigneArcher
f4074341a5 Add AUR PKGBUILD 2022-06-19 14:42:19 -04:00
ReenigneArcher
9c4763af75 Configure Portfile in Macports job 2022-06-18 14:19:34 -04:00
ReenigneArcher
6dc10a4d60 Merge branch 'nightly' into macports-improvements 2022-06-18 12:48:35 -04:00
ReenigneArcher
4b332d6fa0 Merge branch 'macports-improvements' of https://github.com/SunshineStream/Sunshine into macports-improvements 2022-06-18 12:13:05 -04:00
ReenigneArcher
12a361a3d9 Merge pull request #195 from SunshineStream/add-flatpak
Initial flatpak packaging
2022-06-18 11:59:00 -04:00
ReenigneArcher
840013ec78 Update documentation for Flatpak 2022-06-18 11:10:07 -04:00
sitiom
e45452b9bc Add Winget in Third Party Packages (#207)
* Add Winget in Third Party Packages
* Add etiquette tip in Contributing section

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2022-06-18 09:42:05 -04:00
ReenigneArcher
8509260194 Fix branch for PUSH events
- This partially fixes #194
2022-06-17 19:18:56 -04:00
ReenigneArcher
2a13697fef Replace hardcoded paths for unix and...
- Add cache for flatpak job

Co-Authored-By: istori1 <107304850+istori1@users.noreply.github.com>
2022-06-17 17:58:07 -04:00
ReenigneArcher
bd51a7d5fa Refactor assets and config directories 2022-06-17 15:30:56 -04:00
ReenigneArcher
1cf0360520 Initial flatpak packaging
- adds `com.github.sunshinestream.sunshine.yml`
- moves and renames `sunshine.desktop`
- moves and renames `Portfile`
- adds cmake options for configuration only

Co-Authored-By: istori1 <107304850+istori1@users.noreply.github.com>
2022-06-17 14:29:34 -04:00
ReenigneArcher
4a0d632c6e Lint and built Portfile 2022-06-17 11:14:34 -04:00
ReenigneArcher
d336de68a2 Merge pull request #202 from SunshineStream/dependabot/pip/scripts/nightly/babel-2.10.3
Bump babel from 2.9.1 to 2.10.3 in /scripts
2022-06-17 10:19:15 -04:00
dependabot[bot]
1175a3184e Bump babel from 2.9.1 to 2.10.3 in /scripts
Bumps [babel](https://github.com/python-babel/babel) from 2.9.1 to 2.10.3.
- [Release notes](https://github.com/python-babel/babel/releases)
- [Changelog](https://github.com/python-babel/babel/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-babel/babel/compare/v2.9.1...v2.10.3)

---
updated-dependencies:
- dependency-name: babel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 14:03:34 +00:00
ReenigneArcher
dde56c2bb7 Merge pull request #209 from SunshineStream/dependabot/pip/scripts/nightly/sphinx-5.0.2
Bump sphinx from 4.5.0 to 5.0.2 in /scripts
2022-06-17 10:02:54 -04:00
dependabot[bot]
7da652e299 Bump sphinx from 4.5.0 to 5.0.2 in /scripts
Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 4.5.0 to 5.0.2.
- [Release notes](https://github.com/sphinx-doc/sphinx/releases)
- [Changelog](https://github.com/sphinx-doc/sphinx/blob/5.x/CHANGES)
- [Commits](https://github.com/sphinx-doc/sphinx/compare/v4.5.0...v5.0.2)

---
updated-dependencies:
- dependency-name: sphinx
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 13:25:50 +00:00
ReenigneArcher
3663e35ecf Lint and built Portfile 2022-06-16 17:40:26 -04:00
ReenigneArcher
e78ec5c2ce Add notes 2022-06-16 16:18:59 -04:00
ReenigneArcher
70ae7a2fa9 Merge pull request #190 from SunshineStream/nightly
v0.14.0
2022-06-15 18:29:04 -04:00
ReenigneArcher
651d75fce7 Update version 2022-06-15 18:17:12 -04:00
ReenigneArcher
c3dfcc1f11 Merge pull request #189 from SunshineStream/update-changelog-v0.14.0
Update CHANGELOG.md for v0.14.0
2022-06-15 18:07:50 -04:00
ReenigneArcher
a02d314dde Update CHANGELOG.md for v0.14.0 2022-06-15 17:50:11 -04:00
ReenigneArcher
b5fd69a9ed Merge pull request #164 from psyke83/DwmFlush
platform/windows: add DwmFlush() call to improve Windows capture
2022-06-15 17:49:45 -04:00
Conn O'Griofa
2d969c2ccc platform/windows: change dwmflush default, add autodetection
On each re/init, query the active monitor refresh rate via
DwmGetCompositionTimingInfo. If the client requested framerate exceeds
the host monitor refresh, automatically disable DwmFlush.

This avoids the problem by which DwmFlush would constrain the client
FPS if the host monitor runs at a lower refresh rate, thus allowing
the feature to be enabled by default.

If there are other issues caused by DwmFlush for certain systems,
it can still be disabled via configuration.
2022-06-15 22:23:09 +01:00
Conn O'Griofa
211b25848f platform/windows: add optional DwmFlush() call to improve Windows capture
Invoke DwmFlush() before acquiring the next frame to alleviate visual stutter
during mouse movement at the cost of constraining the capture rate to the host's
monitor refresh.

Disabled by default; enable via "dwmflush" boolean configuration parameter.
2022-06-15 22:23:09 +01:00
Conn O'Griofa
d051b58190 webui: correct AMD AMF Coder name & pre-fill default setting 2022-06-15 22:23:09 +01:00
Conn O'Griofa
ab0a6b5fa6 webui: remove erroneous v-bind properties
These were causing unusual behaviour (select dialogs displaying a blank label
when a value should be selected, and values randomly setting themselves to
undefined when switching tabs).
2022-06-15 22:23:09 +01:00
Conn O'Griofa
0c827690ec config: move VideoToolbox variables into correct video_t struct location 2022-06-15 22:23:09 +01:00
ReenigneArcher
f5d7cf7692 Merge pull request #144 from SunshineStream/add-cpack
Add cpack
2022-06-15 17:12:19 -04:00
ReenigneArcher
dd73f45175 Deactivate mac port job 2022-06-15 16:05:23 -04:00
ReenigneArcher
e86207606a Use openssl for deb package instead of libssl1.1/3 2022-06-15 15:53:04 -04:00
ReenigneArcher
ca21e6a8ac Update documentation 2022-06-15 15:52:38 -04:00
ReenigneArcher
9990b9b04b Separate job for Macports build 2022-06-15 15:02:57 -04:00
ReenigneArcher
341bc98730 Merge branch 'add-cpack' of https://github.com/SunshineStream/Sunshine into add-cpack 2022-06-13 20:26:16 -04:00
ReenigneArcher
1a1cf20152 Update MacOS build 2022-06-13 15:56:46 -04:00
ReenigneArcher
7a5890469c Update MacOS build 2022-06-12 22:31:59 -04:00
ReenigneArcher
65c4f01998 Update documentation
- Add copy button to code blocks
- Fix some badges
- Improve Linux installation instructions
2022-06-09 19:50:20 -04:00
ReenigneArcher
676b5559ec Merge pull request #179 from SunshineStream/dependabot/github_actions/nightly/actions/setup-python-4
Bump actions/setup-python from 3 to 4
2022-06-09 11:30:46 -04:00
dependabot[bot]
e9b46201fd Bump actions/setup-python from 3 to 4
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 3 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-09 12:42:27 +00:00
ReenigneArcher
9b4fc8a270 Fix udev rules
- Adds to permission to create "Sunshine Mouse"
2022-06-08 23:00:18 -04:00
ReenigneArcher
7cb0286414 Fix paths for linux cpack build 2022-06-08 21:27:41 -04:00
ReenigneArcher
3b41888c66 Update CI.yml 2022-06-08 21:03:14 -04:00
ReenigneArcher
4a65d2cafc Fix libssl3 dependency for Ubuntu 22.04 2022-06-08 21:02:28 -04:00
ReenigneArcher
34f1e89366 Update linux installation instructions 2022-06-08 21:01:34 -04:00
ReenigneArcher
91cf3bcdcc Use portable config directory for AppImage 2022-06-08 21:01:08 -04:00
ReenigneArcher
e7ec6050d9 Use portable config directory for AppImage 2022-06-07 23:32:08 -04:00
ReenigneArcher
0f3eaf0f84 Add pip for dependabot 2022-06-07 18:32:09 -04:00
ReenigneArcher
c75efd3999 Merge pull request #170 from SunshineStream/dependabot/github_actions/nightly/DoozyX/clang-format-lint-action-0.14
Bump DoozyX/clang-format-lint-action from 0.13 to 0.14
2022-06-03 12:02:58 -04:00
dependabot[bot]
f2934c620b Bump DoozyX/clang-format-lint-action from 0.13 to 0.14
Bumps [DoozyX/clang-format-lint-action](https://github.com/DoozyX/clang-format-lint-action) from 0.13 to 0.14.
- [Release notes](https://github.com/DoozyX/clang-format-lint-action/releases)
- [Commits](https://github.com/DoozyX/clang-format-lint-action/compare/v0.13...v0.14)

---
updated-dependencies:
- dependency-name: DoozyX/clang-format-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-03 12:35:18 +00:00
ReenigneArcher
4f6b001483 Update paths and dependencies
- Updates paths for Linux and MacOS builds
- Strategy matrix build for Linux (CPACK/AppImage)
- Fix dependencies for rpm package
2022-05-15 16:26:00 -04:00
ReenigneArcher
de3c37969f Merge pull request #157 from KarlVogel/f35-libcap
f35: add libcap-devel to enable KMS code
2022-05-14 08:21:28 -04:00
Karl Vogel
c719ddfc31 fedora: add libcap/libdrm-devel to enable KMS code 2022-05-14 12:16:14 +02:00
ReenigneArcher
a5e56cf47d Merge branch 'nightly' into add-cpack 2022-05-12 21:05:23 -04:00
ReenigneArcher
84fd2c5766 Merge pull request #158 from cazzoo/nightly
Add missing dependencies to AppImage
2022-05-12 15:21:57 -04:00
ReenigneArcher
68ba1db24a Refactor assets and config directory 2022-05-11 23:10:46 -04:00
ReenigneArcher
ca00949851 Refactor build_linux job 2022-05-11 19:23:05 -04:00
ReenigneArcher
88925c705f Add gtk plugin for linuxdeploy / AppImage 2022-05-10 20:39:14 -04:00
ReenigneArcher
c2752262e5 Add missing AppImage libraries 2022-05-10 18:54:50 -04:00
Caz zoo
496e51d93a Fixes #8 and relates #146 Adding required missing dependencies for Arch base distro 2022-05-10 23:46:03 +02:00
ReenigneArcher
6c04065ba7 Set DEFAULT_SUNSHINE_DIR for CI builds
- Add libssl3.0 as CPACK_DEBIAN_PACKAGE_DEPENDS
2022-05-08 21:39:10 -04:00
ReenigneArcher
fff419a7ff Fix AppImage source filename 2022-05-06 15:19:11 -04:00
ReenigneArcher
a3e3da3136 Fix cmake project parameters 2022-05-06 14:39:26 -04:00
ReenigneArcher
49bfd2ba1f Rename apps.json files throughout project
- Remove `appveyor.yml`
- Add project description to CMakeLists.txt
- Add project homepage url to CMakeLists.txt
2022-05-06 14:24:39 -04:00
ReenigneArcher
93aebf461a Set assets dir for Windows 2022-05-06 13:21:47 -04:00
ReenigneArcher
c409022df5 Combine AppImage and Linux build 2022-05-06 12:55:43 -04:00
ReenigneArcher
c4441db606 Remove CPACK_COMPONENT_APPLICATION_DEPENDS 2022-05-06 10:16:59 -04:00
ReenigneArcher
0d0496adf3 Remove CPACK_NSIS_MUI_HEADERIMAGE 2022-05-06 10:04:29 -04:00
ReenigneArcher
ca6f02c953 Modify windows installer 2022-05-05 23:58:08 -04:00
ReenigneArcher
8b86abfceb Reorganize assets 2022-05-05 23:09:35 -04:00
ReenigneArcher
5135c16bda Update Portfile and...
- Upload Portfile as artifact during builds and releases
- Update assets for cpack packages
2022-05-05 21:19:19 -04:00
ReenigneArcher
e6d6d47be1 Create MacOS archive 2022-05-05 20:05:07 -04:00
ReenigneArcher
639af4f08a Add MacOS build 2022-05-03 20:40:01 -04:00
ReenigneArcher
12bf5cffc5 Use CMAKE_PROJECT_NAME 2022-04-30 19:06:19 -04:00
ReenigneArcher
6741997e59 Update documentation for cpack 2022-04-30 18:22:17 -04:00
ReenigneArcher
369a941c48 Fix artifacts folder for AppImage 2022-04-30 17:51:14 -04:00
ReenigneArcher
2a69385aed Revert workflow logic 2022-04-30 15:13:36 -04:00
ABeltramo
31f7faa6a5 win: installation directory fix 2022-04-30 10:25:40 +01:00
ABeltramo
dc4393a583 CI: windows build packaging to ZIP, split artifacts upload for different packages 2022-04-30 10:25:40 +01:00
ABeltramo
5eb3e7c75f CI: use cpack for windows 7Z, split back deb/rpm and appimage, moved release action at the end 2022-04-30 10:25:38 +01:00
ABeltramo
6858f9c8d4 fix: testing CI 2022-04-30 10:25:00 +01:00
ABeltramo
af342c8cc9 fix: CI, better jobs dependencies 2022-04-30 10:25:00 +01:00
ABeltramo
4e4a5c8df8 feat: testing out a better CI workflow 2022-04-30 10:25:00 +01:00
ABeltramo
cc2d982ceb feat: testing out CI building for new packages 2022-04-30 10:25:00 +01:00
ABeltramo
e2bef750b4 feat: created NSIS windows installer, fixed Linux packaging paths 2022-04-30 10:25:00 +01:00
ABeltramo
ffdcf0fea8 feat: basic OSX .app generation
added default brew link libraries path
2022-04-30 10:24:59 +01:00
ABeltramo
2ea414d1d4 testing RPM package dependencies 2022-04-30 10:24:59 +01:00
ABeltramo
c4977b5393 WIP: Moving to cpack in order to unify installers across all platforms 2022-04-30 10:24:57 +01:00
ReenigneArcher
13c2dce3f1 Merge pull request #143 from SunshineStream/update-localization-workflow
Do not fail workflow if `sunshine.po` doesn't exist
2022-04-29 21:20:16 -04:00
ReenigneArcher
b0a02a5985 Do not fail workflow if sunshine.po doesn't exist
- Add proper keywords for boost::locale
- Minor documentation updates about localization
2022-04-29 19:48:07 -04:00
ReenigneArcher
b0df4eabd1 Merge pull request #130 from Logical-sh/pipewire-compatibility
Improved Pulse/Pipewire Compatibility for Linux.
2022-04-29 15:59:04 -04:00
ReenigneArcher
ceb7f5f41a Merge pull request #142 from SunshineStream/update-help-argument
Update help argument
2022-04-29 13:06:28 -04:00
ReenigneArcher
aa46b8e293 Revert removing name argument from print_help function
- The existing method is better because it uses the binary name instead of the project name `Sunshine`.
2022-04-29 12:52:09 -04:00
Michael Rogers
63a83cdf7a Fix formatting 2022-04-29 11:22:35 -05:00
Michael Rogers
bd033f9e15 Fixed formatting. 2022-04-29 11:20:45 -05:00
Michael Rogers
62ca9c31a0 Updated the linux for better pulse behavior. 2022-04-29 11:20:38 -05:00
Michael Rogers
e8ef708034 Fix virtual sink overriding config sink. 2022-04-29 11:19:00 -05:00
ReenigneArcher
ec450be8b5 Merge pull request #125 from Logical-sh/AVPacket-Fix
AVPacket Fix
2022-04-29 10:45:42 -04:00
ReenigneArcher
d4df041210 Merge pull request #141 from thatsysadmin/nightly
Add dependencies for Fedora RPM package
2022-04-29 08:51:00 -04:00
ReenigneArcher
ced0029abc Remove unused argument 2022-04-29 00:01:32 -04:00
ReenigneArcher
a9cf0ebf18 Remove unused name variable
- Add documentation blocks
2022-04-28 23:24:17 -04:00
ReenigneArcher
3d6611fd50 Update help argument 2022-04-28 22:51:02 -04:00
h
74736c6b76 Merge branch 'nightly' of https://github.com/thatsysadmin/Sunshine into nightly 2022-04-28 17:38:23 -07:00
h
0e0b2ce366 Add RPMFusion/FFMPEG dependancy. 2022-04-28 17:38:20 -07:00
ReenigneArcher
3b49deac25 Merge pull request #140 from SunshineStream/general-cleanup
Workflow updates
2022-04-28 18:41:21 -04:00
ReenigneArcher
734400dc77 Remove white background from png logo 2022-04-28 18:20:53 -04:00
ReenigneArcher
ef9abf2f15 Get version number from CMakeLists 2022-04-28 18:15:56 -04:00
ReenigneArcher
b286c06144 Fix localize git diff and git reset steps 2022-04-23 20:50:42 -04:00
ReenigneArcher
521335c387 Add ffmpeg dependency 2022-04-23 16:20:06 -04:00
ReenigneArcher
780339d91b Add boost dependencies 2022-04-23 13:18:29 -04:00
ReenigneArcher
b332633b07 Add submodules 2022-04-23 13:09:18 -04:00
ReenigneArcher
4cd1014bac Use apt_packages to install cmake 2022-04-23 13:01:57 -04:00
ReenigneArcher
7a1e5f43d9 Workflow updates
- Do not re-run PR tests on edited PRs
- Close added/fixed issues on published release
- Issues stale after 60 days instead of 30, close after 10 days instead of 5
- Use Vankka/pr-target-branch-action for checking that PR is made to proper branch
- Add version number to sphinx config, must use cmake to configure the file
- Add jobs to readthedocs.yaml configuration
2022-04-23 12:35:39 -04:00
ReenigneArcher
c4054c75a7 Merge pull request #134 from SunshineStream/add-sphinx-docs
Add sphinx docs
2022-04-21 08:30:48 -04:00
ReenigneArcher
f36d81954b Update rpm install commands 2022-04-19 20:38:06 -04:00
ReenigneArcher
eacae3954e Fix typos 2022-04-18 16:21:05 -04:00
ReenigneArcher
56cf3e4ede Update admonitions 2022-04-18 16:05:17 -04:00
ReenigneArcher
293ee266af Add docker file build instructions and...
- Remove readme.md files
2022-04-18 15:26:53 -04:00
ReenigneArcher
536df759ae Initial version of sphinx documentation and...
- remove ubuntu 21.04 from CI (end of life)
- adjust matrix strategy for clang.yml
- Use lessons learned from RetroArcher on localize.yml, crowdin.yml, and locale.py
- Add end of life comments to Dockerfiles
- Adjust dependency order in Dockerfiles
2022-04-18 14:53:28 -04:00
ReenigneArcher
4bdf8375cc Merge pull request #129 from SunshineStream/dependabot/github_actions/nightly/actions/upload-artifact-3
Bump actions/upload-artifact from 2 to 3
2022-04-12 23:32:51 -04:00
h
a6921fffad Add initial support for RPM packaging (#121)
- Add gen-rpm
- Package rpm in CI testing and releases
- Remove fedora 33 from testing (end of life)
- Update arguments for `build_private.sh` and `build_sunshine.sh`

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2022-04-12 23:29:08 -04:00
Michael Rogers
1ad0c93ad8 Changed the video packet to contain AVPacket instead of extending it. 2022-04-12 16:13:05 -05:00
ReenigneArcher
97f333c970 Merge pull request #118 from HomerSp/fix-network-drop-crash
Properly catch exceptions in stream broadcast handlers
2022-04-11 18:29:56 -04:00
dependabot[bot]
b854807d40 Bump actions/upload-artifact from 2 to 3
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 14:37:04 +00:00
Mathias Tillman
a9b9d1bd09 Properly catch exceptions in stream broadcast handlers to prevent unhandled exception crash/termination. 2022-04-07 08:20:47 +02:00
ReenigneArcher
0044ec1d52 Merge pull request #104 from SunshineStream/general-cleanup
General cleanup
2022-03-16 18:58:10 -04:00
ReenigneArcher
9c976a23de Rename artifacts 2022-03-16 18:34:43 -04:00
ReenigneArcher
9930880ee6 Update README.md 2022-03-15 22:30:23 -04:00
ReenigneArcher
82e1b61a31 Delete gamepad.png 2022-03-15 22:30:10 -04:00
ReenigneArcher
5bb197ccfc Update sunshine.ico 2022-03-15 22:30:01 -04:00
ReenigneArcher
20c0426ace Update pull_request_template.md 2022-03-15 22:11:44 -04:00
ReenigneArcher
0a9cc511ed Update config.yml 2022-03-15 22:06:24 -04:00
ReenigneArcher
2a7af03f9a Rename packages 2022-03-15 22:02:16 -04:00
ReenigneArcher
7910ac78a5 Merge pull request #103 from SunshineStream/add-ubuntu-18.04
Add ubuntu 18.04 packaging
2022-03-15 19:54:11 -04:00
ReenigneArcher
67762aa445 Fix matrix.extension 2022-03-15 19:39:21 -04:00
ReenigneArcher
7f22774e08 Fix syntax error 2022-03-15 19:29:12 -04:00
ReenigneArcher
cbafe09396 Add ubuntu 18.04 build and
- Prepare for rpm packaging
2022-03-15 19:23:08 -04:00
ReenigneArcher
615f7e5875 Use correct version of boost and cmake 2022-03-15 19:18:23 -04:00
ReenigneArcher
3f309832f7 Add comments 2022-03-15 19:17:22 -04:00
ReenigneArcher
719f4cef59 Add pipefail and comments 2022-03-15 19:17:06 -04:00
ReenigneArcher
da582198db Merge pull request #97 from SunshineStream/dependabot/github_actions/nightly/actions-js/push-1.3
Bump actions-js/push from 1.2 to 1.3
2022-03-14 10:27:46 -04:00
dependabot[bot]
04a2ecaff4 Bump actions-js/push from 1.2 to 1.3
Bumps [actions-js/push](https://github.com/actions-js/push) from 1.2 to 1.3.
- [Release notes](https://github.com/actions-js/push/releases)
- [Commits](https://github.com/actions-js/push/compare/v1.2...v1.3)

---
updated-dependencies:
- dependency-name: actions-js/push
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 12:38:51 +00:00
ReenigneArcher
3b8b4653e9 Merge pull request #94 from SunshineStream/i10n
Initial support for localization
2022-03-13 16:54:25 -04:00
ReenigneArcher
ea27955b16 Merge pull request #88 from HomerSp/fix-hwdevice-destroyed-before-ctx
Fix hwdevice being destroyed before context causing sigsegv on AMD
2022-03-13 16:50:30 -04:00
ReenigneArcher
e223ba53f9 Merge pull request #87 from HomerSp/fix-rumble-hang
Fix rumble events causing game to freeze
2022-03-13 16:48:43 -04:00
ReenigneArcher
907d0bfcd5 Fix .po file extension 2022-03-13 16:39:33 -04:00
ReenigneArcher
a014391ae7 Update for Crowdin Integration
- Rename extracted template file to `sunshine.po`
- Add `crowdin.yml`
- Remove `--init` and `--update` from `localize.yml`
  - Crowdin will initialize new languages and update existing ones
2022-03-13 16:29:51 -04:00
ReenigneArcher
84584c950b Update comment 2022-03-11 14:07:10 -05:00
ReenigneArcher
f1d82a7d09 Update trigger conditions
- Only run when changes are made on files inside 'sunshine' directory
  - Prevents workflow from running again when this workflow pushes changes back into 'locale' directory
  - Should be cleaner than using 'paths-ignore'
2022-03-11 14:00:23 -05:00
ReenigneArcher
01155ef4a3 Update trigger events
- Don't run if commits are all in 'locale' directory
  - Allows pushing changes back into nightly from this workflow without triggering and endless loop
- Don't run job unless event is 'pull_request.merged'
2022-03-11 13:48:24 -05:00
ReenigneArcher
88cf616a48 Move _locale.py and requirements 2022-03-11 13:46:18 -05:00
ReenigneArcher
b3cdadca86 Create localize.yml 2022-03-11 00:26:53 -05:00
ReenigneArcher
3bd9f6b710 Ignore translation templates and compilations 2022-03-11 00:22:29 -05:00
ReenigneArcher
e28cc5e645 Create _locale.py 2022-03-11 00:21:12 -05:00
ReenigneArcher
045970bcc5 Create requirements.txt 2022-03-11 00:20:25 -05:00
Mathias Tillman
6fca2c593c Use session_t destructor to ensure the context and hwdevice are always destroyed in the correct order. 2022-03-10 09:09:24 +01:00
Mathias Tillman
e61bbe87b4 Read revents from the temporary pollfds instead of copying them over to the old vector.
Decrement index for polls when erasing to make sure none of the events are skipped.
2022-03-09 22:23:38 +01:00
Mathias Tillman
80ebc9982e Fix another lint warning. 2022-03-09 17:27:42 +01:00
Mathias Tillman
9a2689692a Fix lint warning about code style. 2022-03-09 16:40:39 +01:00
Mathias Tillman
a31c6c4cd0 Fix hwdevice being destroyed before context, causing a sigsegv because the context relies on the hwdevice still being active. 2022-03-09 16:20:51 +01:00
Mathias Tillman
1f79f4ed12 Fix rumble events causing hang because the received input events were not read properly. 2022-03-09 00:30:10 +01:00
ReenigneArcher
6da0483951 Merge pull request #82 from sitiom/nightly
Add TPCircularBuffer submodule
2022-03-03 11:10:25 -05:00
ReenigneArcher
3abb199697 Merge pull request #83 from SunshineStream/dependabot/github_actions/nightly/actions/stale-5
Bump actions/stale from 4.1.0 to 5
2022-03-03 09:05:00 -05:00
dependabot[bot]
4c7afc05c7 Bump actions/stale from 4.1.0 to 5
Bumps [actions/stale](https://github.com/actions/stale) from 4.1.0 to 5.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v4.1.0...v5)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 21:55:46 +00:00
ReenigneArcher
222e53781d Merge pull request #84 from SunshineStream/dependabot/github_actions/nightly/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-03-02 16:41:50 -05:00
dependabot[bot]
8d4bd87ad2 Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 12:36:17 +00:00
Ryan Caezar Itang
861331be1c Add TPCircularBuffer submodule 2022-03-02 11:19:05 +08:00
ReenigneArcher
2fa2afed56 Merge pull request #74 from SunshineStream/dependabot/github_actions/nightly/actions/stale-4.1.0
Bump actions/stale from 3 to 4.1.0
2022-02-27 23:26:29 -05:00
ReenigneArcher
5e910b5fab Update issues-stale.yml
- Remove skip-stale-issue-message
- Remove skip-stale-pr-message
2022-02-27 13:18:36 -05:00
dependabot[bot]
1520cb7bf9 Bump actions/stale from 3 to 4.1.0
Bumps [actions/stale](https://github.com/actions/stale) from 3 to 4.1.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v3...v4.1.0)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-27 18:11:56 +00:00
ReenigneArcher
4b658cd86b Merge pull request #73 from SunshineStream/nightly
v0.13.0
2022-02-27 13:11:37 -05:00
ReenigneArcher
f6311ceb3f Merge pull request #72 from SunshineStream/prepare-v0.13.0
Prepare v0.13.0
2022-02-27 12:54:55 -05:00
ReenigneArcher
9b2321a722 Merge pull request #71 from SunshineStream/improve-version-automation
Get version from CMakeLists
2022-02-27 12:54:20 -05:00
ReenigneArcher
1e91356155 Fix desktop file directory 2022-02-27 12:40:31 -05:00
ReenigneArcher
fb7a3a0758 Bump version to v0.13.0 2022-02-27 12:21:48 -05:00
ReenigneArcher
c2d4ffdaed Use master branch for create_release action
- Will always use latest version
2022-02-27 12:21:23 -05:00
ReenigneArcher
c5e6b84e3d Get version from CMakeLists 2022-02-27 12:17:30 -05:00
ReenigneArcher
68f35f6ab1 Merge pull request #66 from abusse/staging
Initial support for MacOS
2022-02-27 11:44:09 -05:00
Anselm Busse
2b450839a1 Initial support for MacOS
This commit introduces initial support for MacOS as third major host platform.
It relies on the VideoToolbox framework for audio and video processing, which
enables hardware accelerated processing of the stream on most platforms.
Audio capturing requires third party tools as MacOS does not offer the
recording of the audio output like the other platforms do. The commit enables
most features offered by Sunshine for MacOS with the big exception of gamepad
support. The patch sets was tested by a few volunteers, which allowed to remove
some of the early bugs. However, several bugs especially regarding corner
cases have probably not surfaced yet.

Besides instructions how to build from source, the commit also adds a Portfile
that allows a more easy installation. After available on the release branch,
a pull request for the Portfile in the MacPorts project is planned.

Signed-off-by: Anselm Busse <anselm.busse@outlook.com>
2022-02-26 10:18:00 +01:00
Anselm Busse
df3e7c5ca1 Prepare for ObjectiveC/ObjectiveC++ code
This commit modifies the clang-format configuration and workflow to support ObjectiveC and ObjectiveC++ code.

Signed-off-by: Anselm Busse <anselm.busse@outlook.com>
2022-02-24 21:10:25 +01:00
ReenigneArcher
a4fa42fa96 Merge pull request #55 from SunshineStream/add-clang-linter
Add clang linter
2022-02-17 18:13:59 -05:00
ReenigneArcher
d6183430ef clang lint 2022-02-16 18:23:56 -05:00
ReenigneArcher
f54a32feac Update clang.yml 2022-02-16 18:13:16 -05:00
ReenigneArcher
37edcb1b55 Update clang.yml
- Fix syntax error
2022-02-16 18:10:54 -05:00
ReenigneArcher
320b691086 Update clang.yml
- Use job strategy matrix
  - inplace True allows artifacts to be uploaded; however workflow succeeds even if there are errors
  - inplace False fails workflow if there are errors
2022-02-16 18:09:23 -05:00
ReenigneArcher
5163ec93b4 Update clang.yml 2022-02-16 18:02:05 -05:00
ReenigneArcher
2be7790415 Update clang.yml
- Add upload artifacts
2022-02-16 17:58:06 -05:00
ReenigneArcher
27d2735454 Create clang.yml 2022-02-16 17:51:05 -05:00
ReenigneArcher
361e5f7ea7 Create dependabot.yml 2022-02-16 17:50:52 -05:00
ReenigneArcher
4a483078ad Merge pull request #30 from SunshineStream/nightly
v0.12.0
2022-02-14 14:09:15 -05:00
ReenigneArcher
4dff0c8384 Merge branch 'nightly' of https://github.com/SunshineStream/Sunshine into nightly 2022-02-13 13:04:41 -05:00
ReenigneArcher
543254691b v0.12.0 2022-02-13 13:04:17 -05:00
ReenigneArcher
96205dc48d Merge pull request #51 from SunshineStream/improve-version-verification
Improve version verification
2022-02-13 13:02:39 -05:00
ReenigneArcher
ec5ea7cffb Update CI.yml
- Version from .desktop file needs to be 1.0 (this is not the sunshine version)
- Setting VERSION environment variable will set AppImage version, otherwise short commit hash will be used
2022-02-13 12:45:13 -05:00
ReenigneArcher
8bb7a63479 Fix job needs
- Build jobs didn't run if `check_versions` doesn't run (need to ENSURE PR check into master is successful before merging!)
2022-02-13 12:17:04 -05:00
ReenigneArcher
95302485a0 Improve version verification 2022-02-13 12:07:10 -05:00
ReenigneArcher
7a1347c1f5 Merge branch 'v0.12.0-changelog' into nightly 2022-02-13 09:31:46 -05:00
ReenigneArcher
a78ad20142 Merge branch 'nightly' into v0.12.0-changelog 2022-02-13 09:30:33 -05:00
ReenigneArcher
9dd6576b26 Update CHANGELOG.md
- Update v0.12.0 release date
2022-02-13 09:25:41 -05:00
ReenigneArcher
cf8a843b03 Merge pull request #43 from SunshineStream/update-web-ui
Update web ui
2022-02-13 09:21:45 -05:00
ReenigneArcher
8b423315d0 Use local fontawesome assets 2022-02-10 18:34:35 -05:00
ReenigneArcher
7417430659 Update .gitignore 2022-02-10 18:32:50 -05:00
ReenigneArcher
a494bfa1e9 Merge pull request #49 from SunshineStream/fix-sample-config
Fix sample config
2022-02-10 07:08:10 -05:00
ReenigneArcher
e239751f50 Update sunshine.conf
- Rename `amd_preset` to `amd_quality`
- Document `key_rightalt_to_key_win`
2022-02-09 19:44:45 -05:00
ReenigneArcher
91465ed257 Update config.html
- Fix some typos
- Reformat some tags
2022-02-09 19:44:05 -05:00
ReenigneArcher
830fa6567b Fix ico file
- All sizes available on separate layers
2022-02-08 23:09:10 -05:00
ReenigneArcher
f347089312 Fix font-awesome stylesheet 2022-02-08 23:08:36 -05:00
ReenigneArcher
a577f76d71 Fix favicon and logo 2022-02-08 21:35:48 -05:00
ReenigneArcher
89f05711e0 Use cdn for fontawesome 2022-02-08 21:35:00 -05:00
ReenigneArcher
b19803564c Update issues.yml
- Label discussions
2022-02-06 17:42:38 -05:00
ReenigneArcher
a9988cb346 Update issues-stale.yml
- Change time of scheduled trigger
2022-02-06 17:42:20 -05:00
ReenigneArcher
b288993b86 Rename workflow 2022-02-06 17:32:55 -05:00
ReenigneArcher
37e608a889 Update CHANGELOG.md 2022-02-06 17:23:57 -05:00
ReenigneArcher
067214a9f9 Merge pull request #36 from cfajardo/add-application-image
Add application image
2022-02-06 16:44:43 -05:00
Christophe Fajardo
b5896c8f26 remove NOTICE from CMakeLists.txt 2022-02-06 21:28:03 +01:00
ReenigneArcher
9f4ad530ca Update web ui
- Add fontawesome
- Add favicon
- Add logo
- Add support and legal links to index.html
- Improve layout of index.html
- Improve layout of navbar
2022-02-05 18:18:00 -05:00
ReenigneArcher
c6d489da11 Merge pull request #42 from okkiv/master
fix git url in build scripts
2022-02-04 09:28:52 -05:00
okkiv
c3d498e30c fetch correct sources 2022-02-04 11:54:20 +01:00
okkiv
bd8ba66023 fetch correct sources 2022-02-04 11:53:49 +01:00
Christophe Fajardo
cf859b7c13 NOTICE file added with Steam trademarks notice 2022-02-03 22:15:13 +01:00
Christophe Fajardo
3b2c70422a remove double quotes from path 2022-02-03 22:02:36 +01:00
Christophe Fajardo
a9ebdf6785 fixed apps_linux typo 2022-02-03 09:58:57 +01:00
Christophe Fajardo
8164b514e1 apps page image path documentation update 2022-02-02 23:04:25 +01:00
Christophe Fajardo
398bf9819e steam.png added 2022-02-02 23:02:49 +01:00
Christophe Fajardo
59959d6397 extension bugfix and default app_windows.json image-path fixed 2022-02-01 23:14:05 +01:00
ReenigneArcher
cbbd813c5a Merge pull request #38 from ReenigneArcher/add-version-argument
Add version argument
2022-01-25 16:51:06 -05:00
Christophe Fajardo
f4344ade53 tolower on extension 2022-01-25 21:13:54 +01:00
Christophe Fajardo
8e1b718d7f reviews changes 2022-01-24 21:33:26 +01:00
ReenigneArcher
ed62a1f93d Add "v" to --version argument output 2022-01-23 18:38:15 -05:00
ReenigneArcher
592cb002bd Add version test
- Add version test on push or PR targets to master branch (AppImage only)
2022-01-23 18:20:37 -05:00
ReenigneArcher
ebc581e165 Merge pull request #34 from TheElixZammuto/web-ui-fixes
UI Web Fixes
2022-01-23 13:35:02 -05:00
ReenigneArcher
c7a3f7f46e Add version argument 2022-01-23 13:05:35 -05:00
Elia Zammuto
41df9c658b Update welcome.html 2022-01-23 17:31:59 +01:00
Elia Zammuto
4bada2d9f6 Update pin.html 2022-01-23 17:31:32 +01:00
Christophe Fajardo
83da80f631 Fix HTTP content type for appassets 2022-01-23 16:27:31 +01:00
Christophe Fajardo
2bcb713b82 formating 2022-01-23 11:33:02 +01:00
ReenigneArcher
e5239583b5 Merge pull request #28 from alvaromunoz/patch-1
Update index.html
2022-01-20 23:02:32 -05:00
ReenigneArcher
4126a1a98e Update CHANGELOG.md
- Update based on #33
- Fix year for 2021 releases
2022-01-20 22:56:53 -05:00
Christophe Fajardo
abf2a5ea4e minor refactoring and Content-Type header 2022-01-20 18:10:30 +01:00
Christophe Fajardo
a9bbadf8ad WebUI image path configuration added 2022-01-20 16:15:44 +01:00
Christophe Fajardo
38dcdcba2f fully working backend image posters 2022-01-20 15:55:06 +01:00
Christophe Fajardo
4a50fcafd8 send image as a binary stream 2022-01-20 14:31:16 +01:00
Christophe Fajardo
67f35dfc5f Merge branch 'nightly' into add-application-image 2022-01-20 09:17:39 +01:00
ReenigneArcher
de9136c61e Merge pull request #33 from cfajardo/psyke83-bufsize-fix
video: use a better vbv-bufsize & correct software bitrate calculation
2022-01-19 20:23:33 -05:00
Elia Zammuto
dd7736e806 UI Web Fixes 2022-01-19 21:27:17 +01:00
ReenigneArcher
720f44c03b Merge pull request #32 from SunshineStream/update-issue-template
Update bug-report.yml
2022-01-18 21:58:10 -05:00
Christophe Fajardo
3981ca0840 applist image attribute 2022-01-18 22:06:20 +01:00
Alvaro
9f707f9015 Update index.html 2022-01-18 11:08:23 -03:00
Conn O'Griofa
1b6bf8fa34 video: use a better vbv-bufsize & correct software bitrate calculation
* Increase vbv-bufsize to 1/10 of requested bitrate. The previous value
  was too low, which was resulting in poor encoding quality and failure to
  stabilize at the requested bitrate. Setting to 1/10 of bitrate is a
  good compromise, as it avoids quality loss but also prevents bandwidth
  spikes far above the bitrate/vbv-maxrate.
* With vbv-bufsize set to a more appropriate value, testing shows that
  the average bitrate vs client-requested bandwidth overshoots by ~20%.
  Adjust for this scenario in the software encoding case only.
2022-01-18 09:42:25 +01:00
ReenigneArcher
41e6344995 Update bug-report.yml
- Use form instead of template
2022-01-16 14:05:18 -05:00
ReenigneArcher
5993deadb2 Merge pull request #31 from SunshineStream/fix-changelog-parser-issue
Update create_package.yml
2022-01-15 19:32:35 -05:00
ReenigneArcher
7306a3468d Update create_package.yml
-Use master branch for verify_changelog action
2022-01-15 19:19:15 -05:00
ReenigneArcher
1513880f63 Merge pull request #29 from SunshineStream/fix-changelog-parser-issue
Fix changelog_parser action
2022-01-15 19:10:25 -05:00
ReenigneArcher
41044ab97f Update CHANGELOG.md
- changelog parser action fails if "v" is in prefix
2022-01-15 00:48:30 -05:00
Alvaro
1b392e3921 Update index.html
Update repo address
2022-01-13 23:38:32 -03:00
ReenigneArcher
870b6e2675 Merge pull request #27 from SunshineStream/nightly
v0.11.1
2022-01-13 16:17:32 -05:00
ReenigneArcher
ac7fcfe056 Merge pull request #26 from ReenigneArcher/update-changelog
Update changelog
2022-01-12 19:08:40 -05:00
ReenigneArcher
55ac123d03 Update history 2022-01-12 19:01:00 -05:00
ReenigneArcher
c748980f58 Merge branch 'SunshineStream:nightly' into nightly 2022-01-12 18:29:50 -05:00
ReenigneArcher
d1a41ad8fe Merge pull request #6 from ReenigneArcher/add-build-checks
Automated PR tests and releases
2022-01-12 17:19:12 -05:00
ReenigneArcher
db6e2a57ad Merge pull request #9 from ReenigneArcher/add-build-checks
Update create_package.yml
2022-01-11 19:10:36 -05:00
ReenigneArcher
f2c53a52c2 Update create_package.yml
-Verify changelog requires checkout
2022-01-11 18:55:58 -05:00
ReenigneArcher
adfb3619c3 Merge pull request #8 from ReenigneArcher/add-build-checks
Test
2022-01-11 18:52:43 -05:00
ReenigneArcher
8781fbcc20 Update create_package.yml
- github.base_ref is needed for pull request check
2022-01-11 18:35:05 -05:00
ReenigneArcher
2c0873332c Merge pull request #6 from ReenigneArcher/add-build-checks
Update create_package.yml
2022-01-11 18:20:41 -05:00
ReenigneArcher
a2c45f8de0 Update create_package.yml
-Fix typo in Windows build
2022-01-11 18:03:30 -05:00
ReenigneArcher
cefcaed358 Update create_package.yml 2022-01-11 17:40:58 -05:00
ReenigneArcher
6ba4b56f32 Merge pull request #4 from ReenigneArcher/test_release
Update CHANGELOG.md
2022-01-11 10:53:26 -05:00
ReenigneArcher
bfda8558ea Update CHANGELOG.md 2022-01-11 10:39:20 -05:00
ReenigneArcher
cc5c1a9b90 Merge pull request #3 from ReenigneArcher/add-build-checks
Add build checks
2022-01-11 10:32:21 -05:00
ReenigneArcher
c5d782dac5 Remove Ubuntu 18.04 from strategy 2022-01-11 10:18:52 -05:00
ReenigneArcher
60d63fcd21 Update create_package.yml
-Remove push event for add-build-checks
2022-01-11 10:01:43 -05:00
ReenigneArcher
8f99d6cf01 Delete create_release.yml 2022-01-11 10:01:20 -05:00
ReenigneArcher
4c6a0cdc37 Package based on strategy matrix 2022-01-11 09:46:18 -05:00
ReenigneArcher
0cad1bf6a5 Revert changes 2022-01-11 09:45:45 -05:00
ReenigneArcher
95a478e55e Revert changes 2022-01-11 09:45:23 -05:00
ReenigneArcher
41a30b5826 Skip packaging/release for Fedora build 2022-01-11 01:13:57 -05:00
ReenigneArcher
b1030b6601 Move gen-deb to Dockerfiles 2022-01-11 01:13:29 -05:00
ReenigneArcher
5dfd5d8027 set -e
Github not respecting -e in shebang
2022-01-11 00:46:47 -05:00
ReenigneArcher
51b7dc5b5c Update create_package.yml 2022-01-11 00:14:49 -05:00
ReenigneArcher
7bfbdd5bc0 Update create_package.yml 2022-01-11 00:12:54 -05:00
ReenigneArcher
aa3137c0a9 Update create_package.yml
-Replace create_release.yml with common create_release action
2022-01-11 00:04:13 -05:00
ReenigneArcher
c2027a5481 Remove token
The documentation states "The called workflow is automatically granted access to `github.token` and `secrets.GITHUB_TOKEN`."
2022-01-10 21:46:12 -05:00
ReenigneArcher
909e36b80d Update create_package.yml
-Use with instead of secrets on caller workflow
2022-01-10 21:20:36 -05:00
ReenigneArcher
4fa2624495 Update create_package.yml
-Initialize workflow
2022-01-10 21:17:20 -05:00
ReenigneArcher
a97c88c45b Update create_package.yml
-Fix typo in uses path
2022-01-10 21:15:34 -05:00
ReenigneArcher
c579f638fc Create CHANGELOG.md 2022-01-10 21:12:04 -05:00
ReenigneArcher
65fdf8f6d1 Create create_release.yml 2022-01-10 21:11:58 -05:00
ReenigneArcher
f6fd1f7e84 Update and rename create_package.yml
-Create release on push to master (fails if changelog version matches latest release)
-Move windows package to artifacts folder
-Use re-usable workflow create_release.yml
2022-01-10 21:11:44 -05:00
ReenigneArcher
732f5bf21d Merge pull request #2 from TheElixZammuto/build-patch-windows
Build Checks - Fixed Windows Build
2021-12-27 10:19:47 -05:00
Elia Zammuto
6d2d3eca18 Manually Imported Upstream PR #296
https://github.com/loki-47-6F-64/sunshine/pull/296 by psyke83 should fix the header issue by compiling
2021-12-26 23:32:34 +01:00
Elia Zammuto
997738816d Update pull-requests_build-check.yml 2021-12-24 12:19:28 +01:00
Elia Zammuto
41906b6fab Use msys2 for Windows Build 2021-12-24 11:27:40 +01:00
ReenigneArcher
c910de12ff Update Dockerfile-ubuntu_18_04 2021-12-21 19:34:42 -05:00
ReenigneArcher
2baed357f2 Update Dockerfile-ubuntu_18_04 2021-12-21 19:10:27 -05:00
ReenigneArcher
ee513939aa Update Dockerfile-ubuntu_18_04 2021-12-21 18:51:55 -05:00
ReenigneArcher
b843ab7b97 Update Dockerfile-ubuntu_18_04 2021-12-21 18:33:59 -05:00
ReenigneArcher
8c37fa8d8b Update Dockerfile-ubuntu_18_04 2021-12-21 18:19:38 -05:00
ReenigneArcher
a46a14c6ac Update Dockerfile-ubuntu_18_04
-Test building glibc 2.31
2021-12-21 18:08:52 -05:00
ReenigneArcher
2fec2bfc51 Update pull-requests_build-check.yml
-Change version for MarkusJx/install-boost
2021-12-21 17:37:40 -05:00
ReenigneArcher
ea1e6f20a8 Update Dockerfile-ubuntu_20_04 2021-12-21 00:07:51 -05:00
ReenigneArcher
aeb72cba02 Update Dockerfile-ubuntu_18_04 2021-12-21 00:07:24 -05:00
ReenigneArcher
279fb8803e Update Dockerfile-ubuntu_18_04 2021-12-20 23:54:46 -05:00
ReenigneArcher
59394e23f4 Update Dockerfile-ubuntu_18_04 2021-12-20 23:43:23 -05:00
ReenigneArcher
8f78b599ae Use update-alternatives for gcc-10 and g++-10 2021-12-20 23:23:26 -05:00
ReenigneArcher
cc4ec1b526 Update Dockerfile-ubuntu_18_04 2021-12-20 23:00:25 -05:00
ReenigneArcher
18a977fdf1 Update pull-requests_build-check.yml 2021-12-20 21:38:32 -05:00
ReenigneArcher
bc945df0a7 Update pull-requests_build-check.yml 2021-12-20 21:31:22 -05:00
ReenigneArcher
32867d1bbf Update pull-requests_build-check.yml
-Try Windows build with Unix Makefiles
2021-12-20 21:15:24 -05:00
ReenigneArcher
c844290c81 Update pull-requests_build-check.yml 2021-12-20 18:26:38 -05:00
ReenigneArcher
4a1f5194cc Update pull-requests_build-check.yml
-Remove libc++
-Try setting compiler to c++17
2021-12-20 18:15:16 -05:00
ReenigneArcher
0db8e634a8 Update pull-requests_build-check.yml
-Fix name of libc++ for windows build
2021-12-20 17:54:13 -05:00
ReenigneArcher
8309ee965a Update pull-requests_build-check.yml
-Add mingw-w64-libc++
2021-12-20 17:38:42 -05:00
ReenigneArcher
0fa4a89223 Merge pull request #2 from SunshineStream/nightly
Add TEMPLATES and WORKFLOWS
2021-12-20 17:22:50 -05:00
ReenigneArcher
9350afbe6a Test boost compiled with mingw 2021-12-20 15:52:01 -05:00
ReenigneArcher
7ce9d27a67 Update Dockerfile-ubuntu_18_04
-Add ffmpeg
2021-12-19 19:20:20 -05:00
ReenigneArcher
83a4440cad Update Dockerfile-ubuntu_18_04
-Add libboost-regex-dev
2021-12-19 18:53:16 -05:00
ReenigneArcher
85cd54fdfe Update Dockerfile-ubuntu_18_04
-Move wget
2021-12-19 18:37:52 -05:00
ReenigneArcher
c3eabebd91 Update Dockerfile-ubuntu_18_04
-Try different cmake repo
2021-12-19 18:35:02 -05:00
ReenigneArcher
26aff26eb0 Update Dockerfile-fedora_35
-Add gcc-c++ package
2021-12-19 18:03:50 -05:00
ReenigneArcher
07b974d638 Update Dockerfile-fedora_33 2021-12-19 17:47:35 -05:00
ReenigneArcher
75cdac5dbf Update Dockerfile-ubuntu_18_04
-Remove cmake build
-Test pipefail
2021-12-19 17:19:01 -05:00
ReenigneArcher
7c6fecf13d Fix cmake 2021-12-19 16:46:47 -05:00
ReenigneArcher
7c96ee1e00 Fix cmake
-Add repo for updated cmake
2021-12-19 16:22:17 -05:00
ReenigneArcher
975c4e6b26 Install rpmfusion as separate command 2021-12-19 16:03:08 -05:00
ReenigneArcher
c4838424db Remove --no-install-recommends option 2021-12-19 16:02:13 -05:00
ReenigneArcher
e07279707a Update dockerfiles
-Fix spacing
2021-12-19 15:40:12 -05:00
ReenigneArcher
1e0db7df4e Rename deb to Linux 2021-12-19 15:39:39 -05:00
ReenigneArcher
b41cbc8ab4 Fix fedora version 2021-12-19 15:24:02 -05:00
ReenigneArcher
906870d36f Back to single line install command
-Testing, dockerfiles fail when packages split into multiple lines
2021-12-19 15:23:11 -05:00
ReenigneArcher
95baeed75e Re-order RUN command 2021-12-19 15:05:23 -05:00
ReenigneArcher
a622c1591e Rename job deb to Linux 2021-12-19 15:04:54 -05:00
ReenigneArcher
030269b596 Cleanup dockerfiles 2021-12-19 14:55:53 -05:00
ReenigneArcher
5ff5d46ba5 Cleanup dockerfiles 2021-12-19 14:41:04 -05:00
ReenigneArcher
d1ab44912b Fix dockerfile 2021-12-19 13:23:06 -05:00
ReenigneArcher
23c6e455fe Update Dockerfile-ubuntu_18_04
-Fix gcc-10
2021-12-19 11:10:40 -05:00
ReenigneArcher
7b5ac1c869 Update Dockerfile-fedora_35 2021-12-19 11:06:09 -05:00
ReenigneArcher
143ca274f5 Update Dockerfile-fedora_33 2021-12-19 11:06:06 -05:00
ReenigneArcher
7d51a4bfbf change linux names to lowercase 2021-12-19 10:45:29 -05:00
ReenigneArcher
23e64f23a8 Add additional distros 2021-12-19 10:40:11 -05:00
ReenigneArcher
a5e2df11eb Update pull-requests_build-check.yml 2021-12-19 00:42:34 -05:00
ReenigneArcher
4406f7428b Update pull-requests_build-check.yml 2021-12-19 00:11:15 -05:00
ReenigneArcher
17770fe130 Update pull-requests_build-check.yml 2021-12-19 00:04:20 -05:00
ReenigneArcher
ff47a13bc3 Update pull-requests_build-check.yml 2021-12-18 23:44:02 -05:00
ReenigneArcher
ed38b7e86c Update pull-requests_build-check.yml
-Testing
2021-12-18 23:35:41 -05:00
ReenigneArcher
3f2ee64293 Update pull-requests_build-check.yml
-Testing
2021-12-18 22:39:07 -05:00
ReenigneArcher
2512e7f445 Update pull-requests_build-check.yml
-Testing
2021-12-18 22:22:27 -05:00
ReenigneArcher
9fbfca5699 Update pull-requests_build-check.yml
-Try boost 1.72.0
2021-12-18 21:19:23 -05:00
ReenigneArcher
1039160d3a Update pull-requests_build-check.yml
-Try boost v1.73.0 built on windows server 2019
2021-12-18 20:57:11 -05:00
ReenigneArcher
214478760b Update pull-requests_build-check.yml
-Try older version of boost, new version failing with cmake 3.22
2021-12-18 19:37:32 -05:00
ReenigneArcher
c49cbd3c3c Update pull-requests_build-check.yml 2021-12-18 19:15:05 -05:00
ReenigneArcher
de8cff072d Update pull-requests_build-check.yml
-Add environment variable BOOST_ROOT
2021-12-18 18:41:58 -05:00
ReenigneArcher
2b0e1fb9dc Update pull-requests_build-check.yml
-Fix boost install directory
2021-12-18 18:21:12 -05:00
ReenigneArcher
f6d9061441 Update pull-requests_build-check.yml
-Install boost
-Remove boost debug during cmake
2021-12-18 18:16:27 -05:00
ReenigneArcher
71b5495569 Update pull-requests_build-check.yml
-Boost debug on
2021-12-18 17:59:30 -05:00
ReenigneArcher
0fa68397b7 Update pull-requests_build-check.yml
-Fix path issue for pacman command
2021-12-18 17:39:49 -05:00
ReenigneArcher
2561886189 Update pull-requests_build-check.yml
-Add Windows build
2021-12-18 17:36:39 -05:00
ReenigneArcher
b73ddc232b Update pull-requests_build-check.yml
-Fix permission denied error when moving deb package
2021-12-18 17:01:54 -05:00
ReenigneArcher
65b9b653d0 Update pull-requests_build-check.yml
-Fix command that moves deb package
-Separate setup, build, and package steps
2021-12-18 16:51:49 -05:00
ReenigneArcher
ca8917dd1b Update pull-requests_build-check.yml
-build with -u for non interactive
2021-12-18 16:31:45 -05:00
ReenigneArcher
bbdf9618ea Update pull-requests_build-check.yml 2021-12-18 11:41:06 -05:00
ReenigneArcher
23f9474e9e Update pull-requests_build-check.yml 2021-12-18 11:34:49 -05:00
ReenigneArcher
69642d2db3 Update pull-requests_build-check.yml 2021-12-18 11:03:56 -05:00
ReenigneArcher
47a7c5e27b Fix typo in docker build readme 2021-12-17 22:25:22 -05:00
ReenigneArcher
502bf8ebf8 Update pull-requests_build-check.yml
-Add deb job with matrix strategy
2021-12-17 22:00:37 -05:00
ReenigneArcher
ecba80372d Merge pull request #1 from ReenigneArcher/add-build-checks
Add build checks (just AppImage for now)
2021-12-17 22:00:02 -05:00
ReenigneArcher
f272b865cd Update pull-requests_build-check.yml
-recursive submodules
-only run on PR for master or nightly branch
2021-12-17 17:36:11 -05:00
ReenigneArcher
89cfbc6bd3 Update pull-requests_build-check.yml
-Checkout recursively with submodules
2021-12-17 14:15:23 -05:00
ReenigneArcher
e2d3fef9db Update pull-requests_build-check.yml
-Attempt to fix build step at line 56
-Various tweaks to quoting and directory names
2021-12-17 13:30:19 -05:00
ReenigneArcher
c5b8deff41 Update pull-requests_build-check.yml
-Fix syntax error
2021-12-17 10:59:55 -05:00
ReenigneArcher
8478ccca5d Create pull-requests_build-check.yml 2021-12-17 10:55:23 -05:00
ReenigneArcher
a268cb552d Create sunshine.desktop 2021-12-17 10:55:20 -05:00
ReenigneArcher
1b0978f252 Create sunshine.png 2021-12-17 10:55:18 -05:00
ReenigneArcher
8730980ab8 Update config.yml
-Fix path for discussions url
2021-12-16 12:14:26 -05:00
ReenigneArcher
caf70d703e Update bug-report.md
-Add lines for gpu information and capture method
2021-12-16 11:13:19 -05:00
ReenigneArcher
95ced89d5e Add .github 2021-12-16 10:39:14 -05:00
loki-47-6F-64
e4c9c292e5 Fix package generation when building with the scripts 2021-10-05 13:53:58 +02:00
loki-47-6F-64
fe7a7f4d77 Fix build scripts when used on Ubuntu 21.04 2021-10-04 20:53:40 +02:00
loki
cb0b32f90a Add icon to windows executable 2021-10-03 21:12:06 +02:00
loki-47-6F-64
9e93bb2dd8 Merge branch 'master' into crct 2021-10-03 19:21:02 +02:00
loki-47-6F-64
0e6c41f823 Merge pull request #240 from luk1337/master
Explicitely link to Boost::log on non-win32 platforms
2021-10-03 19:19:32 +02:00
loki-47-6F-64
725212b8a4 Create scripts that handle building from source automatically 2021-10-03 18:46:34 +02:00
LuK1337
a275ee6b65 Explicitely link to Boost::log on non-win32 platforms
This fixes linker errors related to boost log library.
2021-10-03 00:18:05 +02:00
loki-47-6F-64
997095ce39 Resolve merge conflicts 2021-10-01 11:30:12 +02:00
loki-47-6F-64
8b9cd51134 Merge branch 'master' of github.com:loki-47-6F-64/sunshine 2021-09-27 19:12:51 +02:00
loki-47-6F-64
e7cbfb3ee9 Fix dependencies for debian bullseye 2021-09-27 19:54:32 +02:00
loki-47-6F-64
1f7bdb1b2a Fix segfault when multiple controllers connected 2021-09-27 19:35:06 +02:00
loki-47-6F-64
9f14b2278d Fix rate control for hevc with amdvce 2021-09-27 19:12:42 +02:00
loki-47-6F-64
4177b02064 Allow cuda kernel to run in parallell 2021-09-27 17:58:35 +02:00
loki-47-6F-64
847d7b6980 Fix minor error in README 2021-09-26 23:45:44 +02:00
diadatp
ef1114512f test 3 2021-09-27 01:29:52 +05:30
diadatp
38c36c00c9 test 2 2021-09-27 00:54:53 +05:30
diadatp
846820f4ec test 1 2021-09-27 00:24:24 +05:30
diadatp
c39e90b9b0 Trying again with full cuda install. 2021-09-26 22:36:22 +05:30
diadatp
096d7587c3 Forgot sudo in appveyor config file. 2021-09-26 19:06:29 +05:30
diadatp
27f5bb60e5 Testing AppVeyor CUDA install. 2021-09-26 18:55:28 +05:30
diadatp
70ed5ce829 Merge branch 'master' into cmake_cuda 2021-09-26 17:48:51 +05:30
diadatp
e58dc8e446 Fix CUDA build via CMakeLists flags. 2021-09-26 16:01:59 +05:30
loki-47-6F-64
60e3538adc Attempt to fix ubuntu 20.04 build, again 2021-09-26 11:39:36 +02:00
loki-47-6F-64
e2fb02323c Attempt to fix ubuntu 20.04 build 2021-09-26 10:57:43 +02:00
loki-47-6F-64
57c7945847 Fix typo in README 2021-09-26 00:18:49 +02:00
loki-47-6F-64
68c723e135 Resolve merge conflicts 2021-09-26 00:16:14 +02:00
loki-47-6F-64
0241414dfb Merge branch 'cuda' of github.com:loki-47-6F-64/sunshine into cuda 2021-09-25 22:31:48 +02:00
loki-47-6F-64
c5a356f3e7 Fix compilation on ubuntu 20.04 2021-09-25 22:31:39 +02:00
loki-47-6F-64
deecd19af2 Update appveyor.yml 2021-09-25 21:50:47 +02:00
loki-47-6F-64
f4cb13aa0e Merge pull request #229 from hadicharara/master
Added warning for low version of ffmpeg
2021-09-25 21:16:26 +02:00
Hadi Charara
4385014049 Added warning for low version of ffmpeg 2021-09-25 15:09:03 -04:00
loki-47-6F-64
fcb84132f4 Sharper images when not scaling the image 2021-09-25 19:18:43 +02:00
loki-47-6F-64
50bd3094b4 More accurate capture rate for NvFBC 2021-09-25 17:46:26 +02:00
loki-47-6F-64
d7cb71f877 Update README 2021-09-25 15:35:44 +02:00
loki-47-6F-64
e287404992 Handle acquiring display names based on encoder 2021-09-25 14:44:38 +02:00
loki-47-6F-64
d332f11101 Update instructions in the config file 2021-09-25 13:12:13 +02:00
loki-47-6F-64
f78a9e2ccf Fix downscaling image when using cuda 2021-09-25 12:44:45 +02:00
loki-47-6F-64
bd7294e672 Fix cuda kernel launch when encoding in 4K 2021-09-22 19:12:20 +02:00
loki-47-6F-64
b3304a059d Target older cuda architecture for compatibility 2021-09-22 14:49:49 +02:00
loki-47-6F-64
d0529fb234 Make dependency on cuda development files optional 2021-09-22 14:17:08 +02:00
loki-47-6F-64
bb912786bd Added NvFBC on Linux 2021-09-22 11:36:59 +02:00
loki-47-6F-64
8f47190ffc Test for availability of crct info before using it 2021-09-20 18:37:51 +02:00
loki-47-6F-64
196f1f7471 Make changes in brightness of the color more visible 2021-09-20 00:21:54 +02:00
loki-47-6F-64
e3cc25f23f Use linear interpolation with the cuda kernel 2021-09-20 00:03:33 +02:00
loki-47-6F-64
a963b31c1d Ensure the background color is black 2021-09-19 23:00:42 +02:00
loki-47-6F-64
4d1689d6e9 Each cuda::sws_t has it's own color matrix 2021-09-19 21:27:31 +02:00
loki-47-6F-64
fed329568c Use an actual cuda kernel to convert RGB to NV12 2021-09-19 20:40:34 +02:00
loki-47-6F-64
e3f642ac25 Reduce cpu usage with x11grab 2021-09-15 12:10:12 +02:00
loki-47-6F-64
c94d922282 Fix windows build 2021-09-14 19:16:29 +02:00
loki-47-6F-64
7563a0fa1f Merge branch 'master' into cuda 2021-09-14 15:09:21 +02:00
loki-47-6F-64
f5db0e438b The background is black instead of green 2021-09-14 15:07:34 +02:00
loki-47-6F-64
9982ae4675 Convert images on the GPU on Linux for NVidia cards 2021-09-14 11:58:21 +02:00
loki
69eba9c493 Merge branch 'master' of github.com:loki-47-6F-64/sunshine 2021-09-13 20:55:16 +02:00
loki-47-6F-64
2c67d73f08 Merge pull request #214 from exetico/patch-1
Adding note about `sink` in pipewire
2021-09-13 20:54:35 +02:00
loki
7f4b9cf36c Change where keycode is mapped 2021-09-13 20:34:45 +02:00
loki
9c0ea17ada Update Linux specific code for fix in previous commit 2021-09-13 20:33:17 +02:00
loki
91a6e55f74 Fix segfault when connecting multiple controllers at the same ttime 2021-09-13 20:24:04 +02:00
Tobias Nordahl Kristensen
fea650fbe4 Typo ipewire 2021-09-13 17:17:32 +02:00
Tobias Nordahl Kristensen
35e0497f86 Adding note about sink in pipewire
Also, splitting it up to two points, so it's a bit easier to read.
2021-09-11 16:07:52 +02:00
loki-47-6F-64
fbc3735f44 Merge pull request #210 from WisdomCode/master
Apply key rewrite also when keeping key pressed
2021-09-09 21:23:22 +02:00
WisdomCode
9be80c103e Shortcut Flags need to be adjusted as well 2021-09-09 21:15:35 +02:00
WisdomCode
640f2b1c55 Syntax 2021-09-09 15:05:04 +02:00
WisdomCode
d8df57130a Apply key rewrite also when keeping key pressed 2021-09-09 14:57:04 +02:00
loki-47-6F-64
3ba0533773 Merge pull request #207 from WisdomCode/master
Add non US Backslash for international keyboards on Linux
2021-09-08 21:59:44 +02:00
Christian Rupp
b1224032a1 Add non US Backslash for international keyboards on Linux 2021-09-08 17:18:27 +02:00
loki-47-6F-64
1a7ed53559 Merge pull request #205 from sethicis/patch-1
Update README.md
2021-09-07 09:10:37 +02:00
Kyle Blagg
9e9487617a Update README.md
Added a troubleshooting note for an issue encountered on Manjaro Linux due to Avahi.
2021-09-06 20:49:20 -04:00
Loki
d68b8138a5 Detect x11/wayland at runtime 2021-09-06 20:40:41 +02:00
Loki
10ca72f934 Refactor egl::surface_descriptor_t, removed obj_count and plane_indices 2021-09-06 19:46:42 +02:00
loki-47-6F-64
9dbf0df67d Merge pull request #202 from angelnu/patch-1
libcap-dev is associated to libcap2
2021-09-05 11:18:31 +02:00
Loki
b072af3082 Fix bad file descriptor when using wlgrab 2021-09-05 11:16:59 +02:00
Angel Nunez Mencias
35c8b74bb4 libcap-dev is associated to libcap2
at least since Ubuntu 18.04
2021-09-05 01:30:55 +02:00
Loki
7fbe9ba34f Added warning if only one of libcap or libdrm has been found 2021-09-04 20:15:08 +02:00
Loki
81c6ca5915 Merge branch 'master' into setcap-p 2021-09-04 18:30:29 +02:00
loki
d73a4a38e5 Fix multi-monitor setup with KMSgrab 2021-09-04 18:16:36 +02:00
David Rosca
6309f478a2 kmsgrab: Only gain effective CAP_SYS_ADMIN when needed 2021-09-04 16:28:59 +02:00
loki-47-6F-64
4ca2c0e740 Merge branch 'cpu-usage' 2021-09-04 12:09:27 +02:00
loki-47-6F-64
ea9ada8d20 Trade slightly higher rumble latency for lower cpu usage 2021-09-04 12:09:12 +02:00
loki-47-6F-64
302b61090b Merge pull request #200 from nowrep/pabuf
pulse: Set pa_buffer_attr.maxlength when creating stream
2021-09-03 15:45:56 +02:00
David Rosca
75d224cd67 pulse: Set pa_buffer_attr.maxlength when creating stream 2021-09-03 14:53:53 +02:00
David Rosca
2ff9a129c0 Reduce CPU usage 2021-09-03 14:03:59 +02:00
loki-47-6F-64
a1a4ce1af8 Merge pull request #196 from nowrep/wlsoftware
wlgrab: Fix ram (software encoding) snapshot
2021-09-03 11:23:52 +02:00
David Rosca
44ac873100 wlgrab: Fix ram (software encoding) snapshot 2021-09-03 11:02:38 +02:00
loki-47-6F-64
3d179a869a Push the right change this time xD 2021-09-03 10:20:29 +02:00
loki-47-6F-64
530f2de79e Revert "Test for capability of modifiers when importing framebuffer to openGL"
This reverts commit 276aa23a61.
2021-09-03 10:16:46 +02:00
loki-47-6F-64
512e581d56 Revert "Revert "Linux: DRM modifier 0 is valid""
This reverts commit e5c2ad2069.
2021-09-03 10:16:10 +02:00
loki-47-6F-64
e5c2ad2069 Revert "Linux: DRM modifier 0 is valid"
This reverts commit e33a7ff53b.
2021-09-03 10:12:16 +02:00
loki-47-6F-64
6af961199e Remove redundent code 2021-09-03 10:01:51 +02:00
loki-47-6F-64
276aa23a61 Test for capability of modifiers when importing framebuffer to openGL 2021-09-02 20:38:45 +02:00
David Rosca
e33a7ff53b Linux: DRM modifier 0 is valid
DRM_FORMAT_MOD_LINEAR = 0
2021-09-02 12:34:27 +02:00
David Rosca
d9d50d8943 kmsgrab: Fix multi-plane import 2021-09-02 12:34:19 +02:00
loki-47-6F-64
7c753e2289 Merge branch 'master' into wlroots-drm 2021-09-01 21:50:24 +02:00
loki-47-6F-64
ff81a286bb Merge pull request #185 from TheElixZammuto/web-ui-troubleshooting
Web UI - Troubleshooting Page
2021-09-01 21:48:34 +02:00
Loki
c7c3ac7c9c Merged with master 2021-09-01 14:22:41 +02:00
Loki
74f673e23c Fix build for SUNSHINE_ENABLE_WAYLAND=OFF 2021-08-31 21:19:02 +02:00
Loki
7c51fbfd18 Correlate KMS output to wayland xdg-output 2021-08-31 20:46:50 +02:00
Elia Zammuto
7839ff8057 Minor tweaks to troubleshooting page 2021-08-30 20:46:14 +02:00
loki-47-6F-64
8b91e168e5 Merge pull request #179 from nowrep/kmsgrab-multiplane
kmsgrab: Support multi-plane formats
2021-08-29 21:07:04 +02:00
David Rosca
08f056bb3f kmsgrab: Support multi-plane formats 2021-08-29 20:26:11 +02:00
Elia Zammuto
808af7fce1 Fix Alignment 2021-08-29 18:48:43 +02:00
Elia Zammuto
090d353f3d Added Visual Feedback on action 2021-08-29 18:42:09 +02:00
Elia Zammuto
c4b371ccc9 Merge branch 'master' into web-ui-troubleshooting 2021-08-29 18:25:03 +02:00
Loki
06a1119512 Fix segfault for wlroots based capturing 2021-08-29 09:34:00 +02:00
Loki
b80c4253f0 Make KMSgrab smooth on Wayland 2021-08-28 22:22:02 +02:00
Loki
3f306de5e1 Prevent OpenGL error when switching cursor image 2021-08-28 20:30:07 +02:00
Loki
39f9506446 Fix blank video for vaapi 2021-08-28 17:48:28 +02:00
Loki
00de30d336 Omit single copy of frame with VAAPI if possible 2021-08-26 23:59:32 +02:00
Loki
b59df48dde Keep image on vram if at all possible with wlroots based compositors 2021-08-26 22:06:59 +02:00
loki-47-6F-64
3840b3c561 Merge pull request #169 from gamozolabs/master
Make Sunshine usable fully offline
2021-08-26 08:35:53 +02:00
loki-47-6F-64
b5424ec671 Merge pull request #171 from felipejfc/starting_dir
feat: add support to specifying start_dir to processes
2021-08-26 08:35:23 +02:00
Loki
ec184fb2ab Screencast wlroots based compositors 2021-08-25 16:09:42 +02:00
Felipe Cavalcanti
4a750c7b16 fix: rename starting dir with working dir 2021-08-24 21:13:33 -03:00
Felipe Cavalcanti
f38bbf90bb feat: add support to specifying start_dir to processes 2021-08-24 15:32:18 -03:00
Loki
05dcff4f87 Ask Wayland what monitor outputs are available 2021-08-23 18:22:59 +02:00
Brandon Falk
b458118e34 Pulled in remote assets locally such that Sunshine can be used fully offline 2021-08-22 05:26:39 -07:00
loki
7a920da06d Removed unnecessary references to drmModeFB2 2021-08-21 20:35:36 +02:00
loki
ec84f43b80 Bump up version number of debian package 2021-08-21 20:28:14 +02:00
loki
03d572fe10 Fix generated debian package 2021-08-20 22:21:13 +02:00
loki
c41df22c88 Fix build errors when disabling KMS 2021-08-20 22:00:26 +02:00
loki
3b3b9e2bd9 Fix reinitializing KMS framebuffer 2021-08-20 21:01:33 +02:00
loki
ebf9dbe931 Merge branch 'kmsgrab' 2021-08-19 22:19:46 +02:00
loki
0b3b78891b Update debian package 2021-08-19 22:16:02 +02:00
loki
12af30b75b Update README 2021-08-19 22:09:09 +02:00
loki-47-6F-64
a9775a0686 Merge pull request #164 from Jorys-Paulin/feature/welcome
Tweaks to the welcome page
2021-08-19 21:42:20 +02:00
loki
ca9809ca7e Fix stream based on KMS freezing when switching resolutions 2021-08-19 21:40:14 +02:00
Jorys Paulin
97e14de63e Update welcome page layout 2021-08-19 12:54:40 +02:00
loki
0f4cdc2d21 Fix hanging when switching monitors 2021-08-18 21:13:55 +02:00
loki
869b6ed89d Fix VAAPI with intel iGPU's 2021-08-18 20:19:15 +02:00
loki
1876de0a68 Fix cursor disappearing on Windows 2021-08-18 11:05:14 +02:00
Jorys Paulin
019d064d8e Disable submit button when loading 2021-08-18 10:46:57 +02:00
Jorys Paulin
d6b45eb825 Added autocompletion on welcome page 2021-08-18 10:39:24 +02:00
Jorys Paulin
556a6aaf33 Fixed labels on welcome page 2021-08-18 10:33:24 +02:00
loki
fc7ec9e538 Better validation of vaapi capability 2021-08-17 21:15:38 +02:00
Elia Zammuto
1f239214a1 Troubleshooting page 2021-08-17 20:22:47 +02:00
loki-47-6F-64
9e224987f7 Merge pull request #162 from TheElixZammuto/web-ui-prettier
Fixed Formatting of HTML pages, added Prettier Support
2021-08-17 19:15:54 +02:00
Elia Zammuto
81317ce672 Fixed Formatting of HTML pages, added Prettier Support 2021-08-17 19:12:15 +02:00
loki
fce23c482c Fix incorrect cursor location 2021-08-15 22:25:34 +02:00
loki
1d2e042240 Use standard function for create egl images 2021-08-15 22:19:08 +02:00
loki
d852bb82a3 Only use graphics card connected to monitor if it's capable of h264 encoding 2021-08-15 22:15:24 +02:00
loki
fdb7754043 Attempt to render cursor when X11 is available 2021-08-15 20:38:30 +02:00
loki-47-6F-64
62c3faaacb Merge branch 'master' of https://github.com/loki-47-6F-64/sunshine 2021-08-15 00:36:40 +02:00
loki-47-6F-64
b58279beea Omit one copy for display_vrm on Windows 2021-08-15 00:36:31 +02:00
loki
898d62bad9 Filter out cursors from drm planes 2021-08-13 16:09:05 +02:00
loki
446c8ace82 Merge branch 'master' into kmsgrab 2021-08-12 22:08:06 +02:00
loki
e007ee9976 Handle monitors in different GPU's 2021-08-12 22:07:00 +02:00
loki
6721155155 Omit copy to RAM when possible with VAAPI 2021-08-12 21:11:40 +02:00
loki-47-6F-64
b80619fb0f Merge pull request #154 from guanzhangrtk/master
Update README about MSYS2 requirement on Windows
2021-08-10 15:38:53 +02:00
GuanZhang
e75e26467f Merge branch 'loki-47-6F-64:master' into master 2021-08-09 15:54:26 +09:00
GuanZhang
2187f0b198 Merge pull request #1 from guanzhangrtk/guanzhangrtk-msys2-readme
MSYS2 is needed to build under Windows
2021-08-09 15:53:47 +09:00
GuanZhang
3382a5d03c MSYS2 is needed to build under Windows 2021-08-09 15:52:49 +09:00
loki-47-6F-64
fff9145680 Merge pull request #152 from guanzhangrtk/master
Add missing requirements for clean MSYS2 environment
2021-08-09 08:32:23 +02:00
GuanZhang
13e57bb183 Merge branch 'loki-47-6F-64:master' into master 2021-08-09 11:42:02 +09:00
GuanZhang
948500ae41 Added missing sv as requested by loki-47-6F-64 2021-08-09 11:38:12 +09:00
loki-47-6F-64
17bcdd7902 Merge pull request #153 from TheElixZammuto/password-validation
Welcome: Password Validation
2021-08-08 17:43:39 +02:00
Elia Zammuto
03837a9308 Password Validation 2021-08-08 16:47:38 +02:00
Loki
b8bfc13cf9 Prevent segfault on empty string_view 2021-08-08 13:59:43 +02:00
loki
24403cdd25 Fix segfault when switching monitors with kmsgrab 2021-08-08 13:42:25 +02:00
loki
13d0106feb Don't shutdown stream if audio capture fails 2021-08-08 13:41:09 +02:00
GuanZhang
dce64fc487 Add more detailed log message when config::nvhttp.file_state doesn't exist upon first run 2021-08-08 18:20:43 +09:00
GuanZhang
0629fe7846 Add missing requirements for clean MSYS2 environment 2021-08-08 18:04:48 +09:00
loki
315ec47523 Display single monitor only with kmsgrab 2021-08-07 21:31:25 +02:00
loki
9ed2141fc8 Fix X11 screengrabbing with vaapi 2021-08-07 14:39:18 +02:00
loki
5b40c5008f Merge branch 'master' of github.com:loki-47-6F-64/sunshine 2021-08-07 12:12:27 +02:00
loki
62db9ae01a fix reading config option for log level 2021-08-07 12:12:18 +02:00
loki-47-6F-64
8c2cd2f60d Load mDNS at runtime on Windows 2021-08-07 00:05:38 +02:00
loki
0812f6f3c3 Merge branch 'master' into kmsgrab 2021-08-06 15:56:10 +02:00
loki
065e9e718a Choose between x11grab and kmsgrab at runtime 2021-08-06 15:55:38 +02:00
loki-47-6F-64
27f1dc318b Merge pull request #137 from cgutman/win32_service
Add Win32 service to run Sunshine as LocalSystem
2021-08-06 09:26:39 +02:00
Loki
ac5f439839 Skeleton of grabbing image with kms 2021-08-05 21:24:52 +02:00
Cameron Gutman
b4255e22aa Write Sunshine log output to disk and hide the window 2021-08-03 19:27:23 -05:00
Cameron Gutman
d15c1af152 Add uninstall-service.bat 2021-08-03 18:41:23 -05:00
Cameron Gutman
0140989f3a Add Win32 service to run Sunshine as LocalSystem on login 2021-08-03 18:41:23 -05:00
Loki
793e329fa5 Merge with master 2021-08-03 20:35:57 +02:00
Loki
6702802829 Load X11 libraries at runtime 2021-08-03 20:31:27 +02:00
loki
dae9a67fe2 update README 2021-08-03 15:28:32 +02:00
loki
b8e11b1272 Merge branch 'master' of github.com:loki-47-6F-64/sunshine 2021-08-03 15:24:15 +02:00
loki
f08b6abc96 Make keybindings configurable 2021-08-03 15:24:04 +02:00
loki-47-6F-64
965812bc19 Merge pull request #146 from TheElixZammuto/web-ui-welcome
Show a Welcome Page if credentials are created the first time
2021-08-03 13:07:08 +02:00
Elia Zammuto
7f643345ce welcome now puts credentials instead of generating 2021-07-30 16:06:59 +02:00
Elia Zammuto
28fecbc50c Show a Welcome Page if credentials are created the first time Sunshine is started 2021-07-29 18:55:34 +02:00
loki
6c11e9f27d Switch monitors on Windows 2021-07-29 17:27:22 +02:00
loki
2af179630a Switch monitors based on keyboard shortcuts 2021-07-29 16:48:03 +02:00
loki
c243e82047 Add shortcut for hiding and showing the cursor 2021-07-28 22:03:17 +02:00
loki
3de77b1849 Fix error 104 in Moonlight when starting Steam Bigpicture 2021-07-27 23:05:49 +02:00
loki
37d09b0bdb Merge branch 'capture_callback' 2021-07-27 18:57:11 +02:00
loki
9a5d23ebde Fix setting default SUNSHINE_DEFAULT_DIR 2021-07-27 18:55:41 +02:00
loki-47-6F-64
da3ed5ff79 Merge pull request #142 from JacekJagosz/master
Make Sunshine on Linux stateless
2021-07-27 16:01:15 +02:00
Jacek Jagosz
2e8b462fe5 Not create unnecessary variables and make fs use strings directly instead of converting them 2021-07-27 15:58:01 +02:00
loki
87b2b708f8 Update Linux build for callback code 2021-07-26 20:56:32 +02:00
loki
7ddf8bbe94 Capturing images by callback, rather than pulling 2021-07-26 18:09:07 +02:00
loki
a87782b025 Fix stuttering on Windows 2021-07-26 14:37:57 +02:00
Jacek Jagosz
c39f2b0c1f If config files don't exist in user specified directory copy files from default, not override user choice 2021-07-25 20:39:45 +02:00
Jacek Jagosz
a07ad3e479 If CONFIG and DEFAULT directories haven't been configured, make them point to ASSETS 2021-07-25 14:09:47 +02:00
Jacek Jagosz
c58f95b79e Try making sunshine on Linux stateless 2021-07-25 14:02:58 +02:00
loki
d9f7952710 Fix weird bug where Sunshine couldn't accept user input from terminal on Linux 2021-07-25 13:16:17 +02:00
Loki
ab70a056fc Add CQP for older intel iGPU's 2021-07-24 19:33:23 +01:00
loki
844ba53f54 Remove dependency on X11 for keyboard input 2021-07-24 14:51:33 +02:00
loki
63b920cd7b Merge branch 'master' into rumble 2021-07-23 20:07:03 +02:00
loki
2a5fd78789 Fix crackling audio on Linux 2021-07-23 18:43:35 +02:00
loki
bc52fe9b82 Improve fps for software encoding on Windows 2021-07-23 17:36:32 +02:00
loki
667c113d5b Merge branch 'master' into rumble 2021-07-22 21:14:53 +02:00
loki
38915859ba Don't overwrite config files with debian package 2021-07-22 21:14:36 +02:00
loki
70d0be4b9a Add rumble effect on Linux 2021-07-22 18:19:25 +02:00
loki
dad446ea41 Print request for rumble on the terminal for Linux 2021-07-21 20:24:23 +02:00
loki
d283900e43 add config options for select gamepad to emulate 2021-07-18 15:46:46 +02:00
loki
4b043e31fe Support ds4 controller on Windows 2021-07-18 15:32:26 +02:00
loki
f65882e42a Merge branch 'master' into rumble 2021-07-18 11:06:08 +02:00
loki
1fda8f6219 Support Rumble on Windows 2021-07-18 11:05:34 +02:00
loki-47-6F-64
620c629bb4 Merge pull request #135 from cgutman/partial_chain
Fix X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE error with some embedded clients
2021-07-18 10:46:33 +02:00
Cameron Gutman
a1f63da057 Fix client auth error with some embedded clients 2021-07-17 19:34:08 -05:00
249 changed files with 48023 additions and 7666 deletions

View File

@@ -1,3 +1,7 @@
# 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.
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -2
@@ -23,6 +27,7 @@ BraceWrapping:
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterUnion: false
BeforeCatch: true
BeforeElse: true

6
.flake8 Normal file
View File

@@ -0,0 +1,6 @@
[flake8]
filename =
*.py
max-line-length = 120
extend-exclude =
venv/

102
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
---
name: Bug Report
description: Create a bug report to help us improve.
body:
- type: markdown
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.
- type: textarea
id: description
attributes:
label: Describe the Bug
description: A clear and concise description of the bug.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context about the bug here.
- type: dropdown
id: os
attributes:
label: Host Operating System
description: What version operating system are you running the software on?
options:
- Linux
- macOS
- Windows
- other
- type: input
id: os-version
attributes:
label: Operating System Version
description: Provide the version of the operating system. Additionally a build number would be helpful.
validations:
required: true
- type: input
id: os-architecture
attributes:
label: Architecture
placeholder: e.g. 32 bit, 64 bit, arm
validations:
required: true
- type: input
id: version
attributes:
label: Sunshine Version
placeholder: eg. 0.14.0
validations:
required: true
- type: input
id: graphics_type
attributes:
label: GPU Type
description: The type of the installed graphics card.
placeholder: e.g. Intel, AMD, Nvidia
validations:
required: true
- type: input
id: graphics_model
attributes:
label: GPU Model
description: The model of the installed graphics card.
placeholder: e.g. GeForce RTX 2080 SUPER
validations:
required: true
- type: input
id: graphics_driver
attributes:
label: GPU Driver/Mesa Version
description: The driver/mesa version of the installed graphics card.
placeholder: e.g. 497.29
validations:
required: true
- type: input
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
validations:
required: false
- type: textarea
id: logs
attributes:
label: Relevant log output
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.

19
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
---
# 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.
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: Feature request
url: https://feedback.lizardbyte.dev
about: Share your suggestions or ideas to help us improve

30
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
---
# 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.
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
target-branch: "nightly"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
target-branch: "nightly"
open-pull-requests-limit: 10
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
target-branch: "nightly"
open-pull-requests-limit: 10

49
.github/label-actions.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
---
# 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.
# Configuration for Label Actions - https://github.com/dessant/label-actions
added:
comment: >
This feature has been added and will be available in the next release.
fixed:
comment: >
This issue has been fixed and will be available in the next release.
invalid:duplicate:
comment: >
:wave: @{issue-author}, this appears to be a duplicate of a pre-existing issue.
close: true
lock: true
unlabel: 'status:awaiting-triage'
-invalid:duplicate:
reopen: true
unlock: true
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.
close: true
lock: true
lock-reason: 'off-topic'
unlabel: 'status:awaiting-triage'
-invalid:support:
reopen: true
unlock: true
invalid:template-incomplete:
issues:
comment: >
:wave: @{issue-author}, please edit your issue to complete the template with
all the required info. Your issue will be automatically closed in 5 days if
the template is not completed. Thanks.
prs:
comment: >
:wave: @{issue-author}, please edit your PR to complete the template with
all the required info. Your PR will be automatically closed in 5 days if
the template is not completed. Thanks.

24
.github/pr_release_template.md vendored Normal file
View File

@@ -0,0 +1,24 @@
## Description
<!--- Please include a summary of the changes. --->
This PR was created automatically.
### Screenshot
<!--- Include screenshots if the changes are UI-related. --->
### Issues Fixed or Closed
<!--- Close issue example: `- Closes #1` --->
<!--- Fix bug issue example: `- Fixes #2` --->
<!--- Resolve issue example: `- Resolves #3` --->
## Type of Change
- [ ] 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)
- [ ] Documentation update (changes to documentation)
- [ ] Repository update (changes to repository files)
## Changelog Summary
<!--- Summarize all the changes in a bulleted list. --->

22
.github/pull_request_template.md vendored Normal file
View File

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

805
.github/workflows/CI.yml vendored Normal file
View File

@@ -0,0 +1,805 @@
---
name: CI
on:
pull_request:
branches: [master, nightly]
types: [opened, synchronize, reopened]
push:
branches: [master]
workflow_dispatch:
jobs:
github_env:
name: GitHub Env Debug
runs-on: ubuntu-latest
steps:
- name: Dump github context
run: echo "$GITHUB_CONTEXT"
shell: bash
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
check_changelog:
name: Check Changelog
runs-on: ubuntu-latest
steps:
- name: Checkout
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 }}
check_versions:
name: Check Versions
runs-on: ubuntu-latest
needs: check_changelog
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
# base_ref for pull request check, ref for push
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Check CMakeLists.txt Version
run: |
version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt | \
grep -o -E '[0-9]+\.[0-9]+\.[0-9]+')
echo "cmakelists_version=${version}" >> $GITHUB_ENV
- name: Compare CMakeList.txt Version
if: ${{ env.cmakelists_version != needs.check_changelog.outputs.next_version_bare }}
run: |
echo CMakeLists version: "$cmakelists_version"
echo Changelog version: "${{ needs.check_changelog.outputs.next_version_bare }}"
echo Within 'CMakeLists.txt' change "project(Sunshine [VERSION $cmakelists_version]" to \
"project(Sunshine [VERSION ${{ needs.check_changelog.outputs.next_version_bare }}]"
exit 1
build_linux_aur:
name: Linux AUR
runs-on: ubuntu-latest
needs: check_changelog
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Dependencies Linux AUR
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
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}"
fi
echo "Commit: ${commit}"
echo "Clone URL: ${clone_url}"
echo "aur_pkg=${aur_pkg}" >> $GITHUB_ENV
mkdir -p artifacts
mkdir -p build
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 ..
mv ./build/PKGBUILD ./artifacts/
- 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
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: sunshine-linux-aur
path: artifacts/
- 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
build_linux_flatpak:
name: Linux Flatpak
runs-on: ubuntu-latest
needs: check_changelog
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Dependencies Linux Flatpak
run: |
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'
- name: Configure Flatpak Manifest
run: |
# variables for manifest
branch=${GITHUB_HEAD_REF}
# check the branch variable
if [ -z "$branch" ]
then
echo "This is a PUSH event"
branch=${{ github.ref_name }}
commit=${{ github.sha }}
clone_url=${{ github.event.repository.clone_url }}
else
echo "This is a PR event"
commit=${{ github.event.pull_request.head.sha }}
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
fi
echo "Branch: ${branch}"
echo "Commit: ${commit}"
echo "Clone URL: ${clone_url}"
mkdir -p build
mkdir -p artifacts
cd build
cmake -DGITHUB_CLONE_URL=${clone_url} \
-DGITHUB_BRANCH=${branch} \
-DGITHUB_COMMIT=${commit} \
-DSUNSHINE_CONFIGURE_FLATPAK=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'
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: sunshine-linux-flatpak
path: artifacts/
- 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 }}
build_linux:
name: Linux
runs-on: ubuntu-20.04
needs: check_changelog
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'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- 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
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 \
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
# # 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
sudo update-alternatives --install \
/usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10
# 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 \
--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
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 }} \
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
-DSUNSHINE_ENABLE_WAYLAND=ON \
-DSUNSHINE_ENABLE_X11=ON \
-DSUNSHINE_ENABLE_DRM=ON \
-DSUNSHINE_ENABLE_CUDA=ON \
${{ matrix.EXTRA_ARGS }} \
..
make -j ${nproc}
- name: Package Linux - CPACK
if: ${{ matrix.type == 'cpack' }}
working-directory: build
run: |
# package
cpack -G DEB
cpack -G RPM
# move
mv ./cpack_artifacts/Sunshine.deb ../artifacts/sunshine.deb
mv ./cpack_artifacts/Sunshine.rpm ../artifacts/sunshine.rpm
- 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
run: |
version=${{ needs.check_changelog.outputs.next_version_bare }}
echo "VERSION=${version}" >> $GITHUB_ENV
- name: Package Linux - AppImage
if: ${{ matrix.type == 'appimage' }}
working-directory: build
run: |
# 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 }}/
# variables
DESKTOP_FILE="${DESKTOP_FILE:-sunshine.desktop}"
ICON_FILE="${ICON_FILE:-sunshine.png}"
# AppImage
# https://docs.appimage.org/packaging-guide/index.html
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 \
--icon-file "../$ICON_FILE" \
--desktop-file "./$DESKTOP_FILE" \
--library /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 \
--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
# permissions
chmod +x ../artifacts/sunshine.AppImage
- name: Verify AppImage
if: ${{ matrix.type == 'appimage' }}
run: |
wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage
chmod +x appimagelint-x86_64.AppImage
# rm -rf ~/.cache/appimagelint/
./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 }}
path: artifacts/
- 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 }}
build_mac:
name: MacOS
runs-on: macos-11
needs: check_changelog
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Dependencies MacOS
run: |
# install dependencies using homebrew
brew install boost cmake ffmpeg opus
# fix openssl header not found
ln -sf /usr/local/opt/openssl/include/openssl /usr/local/include/openssl
- name: Build MacOS
run: |
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 \
..
make -j ${nproc}
- name: Package MacOS
run: |
mkdir -p artifacts
cd build
# package
cpack -G DragNDrop
mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine-macos-experimental-dragndrop.dmg
cpack -G Bundle
mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine-macos-experimental-bundle.dmg
cpack -G ZIP
mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-macos-experimental-archive.zip
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: sunshine-macos
path: artifacts/
# this step can be removed after packages are fixed
- name: Delete experimental packages
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
working-directory: artifacts
run: |
rm -f ./sunshine-macos-experimental-dragndrop.dmg
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 }}
build_mac_port:
name: Macports
needs: check_changelog
runs-on: macos-11
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout ports
uses: actions/checkout@v3
with:
repository: macports/macports-ports
fetch-depth: 64
path: ports
- name: Checkout mpbb
uses: actions/checkout@v3
with:
repository: macports/mpbb
path: mpbb
- name: Setup Dependencies Macports
run: |
# install dependencies using homebrew
brew install cmake
- name: Configure Portfile
run: |
# variables for Portfile
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 }}
else
echo "This is a PR event"
commit=${{ github.event.pull_request.head.sha }}
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
fi
echo "Commit: ${commit}"
echo "Clone URL: ${clone_url}"
mkdir build
cd build
cmake -DGITHUB_COMMIT=${commit} \
-DGITHUB_CLONE_URL=${clone_url} \
-DSUNSHINE_CONFIGURE_PORTFILE=ON \
-DSUNSHINE_CONFIGURE_ONLY=ON \
..
cd ..
# copy Portfile to artifacts
mkdir -p artifacts
cp -f ./build/Portfile ./artifacts/
# copy Portfile to ports
mkdir -p ./ports/multimedia/Sunshine
cp -f ./build/Portfile ./ports/multimedia/Sunshine/Portfile
# testing
cat ./artifacts/Portfile
- name: Bootstrap MacPorts
run: |
. ports/.github/workflows/bootstrap.sh
# Add getopt, mpbb and the MacPorts paths to $PATH for the subsequent steps.
echo "/opt/mports/bin" >> $GITHUB_PATH
echo "${PWD}/mpbb" >> $GITHUB_PATH
echo "/opt/local/bin" >> $GITHUB_PATH
echo "/opt/local/sbin" >> $GITHUB_PATH
- name: Determine list of subports
id: subportlist
run: |
set -eu
port=Sunshine
subportlist=""
echo "Listing subports for Sunshine"
new_subports=$(mpbb \
--work-dir /tmp/mpbb \
list-subports \
--archive-site= \
--archive-site-private= \
--include-deps=no \
"$port" \
| tr '\n' ' ')
for subport in $new_subports; do
echo "$subport"
subportlist="$subportlist $subport"
done
echo "::set-output name=subportlist::${subportlist}"
- name: Run port lint for all subports
run: |
set -eu
fail=0
for subport in $subportlist; do
echo "::group::${subport}"
path=$(port file "$subport")
messagetype="warning"
if ! messages=$(port -q lint "$subport" 2>&1); then
messagetype="error"
fail=1
fi
if [ -n "$messages" ]; then
echo "$messages"
# See https://github.com/actions/toolkit/issues/193#issuecomment-605394935
encoded_messages="port lint ${subport}:%0A"
encoded_messages+="$(echo "${messages}" | sed -E 's/$/%0A/g' | tr -d '\n')"
echo "::${messagetype} file=${path#${PWD}/ports/},line=1,col=1::${encoded_messages}"
fi
echo "::endgroup::"
done
exit "$fail"
env:
subportlist: ${{ steps.subportlist.outputs.subportlist }}
- name: Build subports
run: |
set -eu
fail=0
for subport in $subportlist; do
workdir="/tmp/mpbb/$subport"
mkdir -p "$workdir/logs"
touch "$workdir/logs/dependencies-progress.txt"
echo "::group::Cleaning up between ports"
sudo mpbb --work-dir "$workdir" cleanup
echo "::endgroup::"
echo "::group::Installing dependencies for ${subport}"
sudo mpbb \
--work-dir "$workdir" \
install-dependencies \
"$subport" >"$workdir/logs/install-dependencies.log" 2>&1 &
deps_pid=$!
tail -f "$workdir/logs/dependencies-progress.txt" 2>/dev/null &
tail_pid=$!
set +e
wait "$deps_pid"
deps_exit=$?
set -e
kill "$tail_pid" || true
if [ "$deps_exit" -ne 0 ]; then
echo "::endgroup::"
echo "::error::Failed to install dependencies for ${subport}"
fail=1
continue
fi
echo "::endgroup::"
echo "::group::Installing ${subport}"
set +e
sudo mpbb \
--work-dir "$workdir" \
install-port \
--source \
"$subport"
install_exit=$?
set -e
if [ "$install_exit" -ne 0 ]; then
echo "::endgroup::"
echo "::error::Failed to install ${subport}"
fail=1
continue
fi
echo "::endgroup::"
done
exit "$fail"
env:
subportlist: ${{ steps.subportlist.outputs.subportlist }}
- name: Package
run: |
# create packages
sudo port pkg sunshine
sudo port dmg sunshine
work=$(port work sunshine)
echo "Sunshine port work directory: ${work}"
# move components out of port work directory
sudo mv ${work}/Sunshine*component.pkg /tmp/
# copy artifacts
sudo mv ${work}/Sunshine*.pkg ./artifacts/sunshine.pkg
sudo mv ${work}/Sunshine*.dmg ./artifacts/sunshine.dmg
# move components back
# sudo mv /tmp/Sunshine*component.pkg ${work}/
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
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
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 }}
build_win:
name: Windows
runs-on: windows-2019
needs: check_changelog
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Dependencies Windows
uses: msys2/setup-msys2@v2
with:
update: true
install: >-
base-devel
diffutils
git
make
mingw-w64-x86_64-binutils
mingw-w64-x86_64-boost
mingw-w64-x86_64-cmake
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
yasm
- name: Build Windows
shell: msys2 {0}
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-DSUNSHINE_ASSETS_DIR=assets \
-DSUNSHINE_CONFIG_DIR=config \
-G "MinGW Makefiles" \
..
mingw32-make -j2
- name: Package Windows
shell: msys2 {0}
run: |
mkdir -p artifacts
cd build
# package
cpack -G NSIS
cpack -G ZIP
# move
mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows.exe
mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows.zip
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
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
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 }}

31
.github/workflows/auto-create-pr.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
---
# 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: Auto create PR
on:
push:
branches:
- 'nightly'
jobs:
create_pr:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Create Pull Request
uses: repo-sync/pull-request@v2
with:
source_branch: "" # should be "nightly" as it's the triggering branch
destination_branch: "master"
pr_title: "Pulling ${{ github.ref_name }} into master"
pr_template: ".github/pr_release_template.md"
pr_assignee: "${{ secrets.GH_BOT_NAME }}"
pr_draft: true
pr_allow_empty: false
github_token: ${{ secrets.GH_BOT_TOKEN }}

59
.github/workflows/automerge.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
---
# 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: Automerge PR
on:
pull_request:
types:
- opened
- synchronize
jobs:
autoapprove:
if: >
contains(fromJson('["LizardByte-bot"]'), github.event.pull_request.user.login) &&
contains(fromJson('["LizardByte-bot"]'), github.actor)
runs-on: ubuntu-latest
steps:
- name: Autoapproving
uses: hmarr/auto-approve-action@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Label autoapproved
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: ['autoapproved', 'autoupdate']
})
automerge:
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
env:
BASE_BRANCHES: nightly
GITHUB_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
GITHUB_LOGIN: ${{ secrets.GH_BOT_NAME }}
MERGE_LABELS: ""
MERGE_METHOD: "squash"
MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})"
MERGE_DELETE_BRANCH: true
MERGE_ERROR_FAIL: true
MERGE_FILTER_AUTHOR: ${{ secrets.GH_BOT_NAME }}
MERGE_RETRIES: "240" # 1 hour
MERGE_RETRY_SLEEP: "15000" # 15 seconds

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

@@ -0,0 +1,32 @@
---
# 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 designed to work with:
# - automerge workflows
# It uses GitHub 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.
name: autoupdate
on:
push:
branches:
- 'nightly'
jobs:
autoupdate-for-bot:
name: Autoupdate autoapproved PR created in the upstream
if: startsWith(github.repository, 'LizardByte/')
runs-on: ubuntu-latest
steps:
- name: Update
uses: docker://chinthakagodawita/autoupdate-action:v1
env:
GITHUB_TOKEN: '${{ secrets.GH_BOT_TOKEN }}'
PR_FILTER: "labelled"
PR_LABELS: "autoupdate"
PR_READY_STATE: "ready_for_review"
MERGE_CONFLICT_ACTION: "ignore"

View File

@@ -0,0 +1,60 @@
---
# 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/

54
.github/workflows/issues-stale.yml vendored Normal file
View File

@@ -0,0 +1,54 @@
---
# 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: Stale Issues / PRs
on:
schedule:
- cron: '00 00 * * *'
jobs:
stale:
name: Check Stale Issues / PRs
runs-on: ubuntu-latest
steps:
- name: Stale
uses: actions/stale@v5
with:
close-issue-message: >
This issue was closed because it has been stalled for 5 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
days-before-close: 10
exempt-all-assignees: true
exempt-issue-labels: 'added,fixed'
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.
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.
- name: Invalid Template
uses: actions/stale@v5
with:
close-issue-message: >
This issue was closed because the the template was not completed after 5 days.
close-pr-message: >
This PR was closed because the the template was not completed after 5 days.
days-before-stale: 0
days-before-close: 5
exempt-pr-labels: 'dependencies,l10n'
only-labels: 'invalid:template-incomplete'
stale-issue-label: 'invalid:template-incomplete'
stale-issue-message: >
Invalid issues template.
stale-pr-label: 'invalid:template-incomplete'
stale-pr-message: >
Invalid PR template.

22
.github/workflows/issues.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
---
# 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: Issues
on:
issues:
types: [labeled, unlabeled]
discussion:
types: [labeled, unlabeled]
jobs:
label:
name: Label Actions
runs-on: ubuntu-latest
steps:
- name: Label Actions
uses: dessant/label-actions@v2
with:
github-token: ${{ github.token }}

95
.github/workflows/localize.yml vendored Normal file
View File

@@ -0,0 +1,95 @@
---
name: localize
on:
push:
branches: [nightly]
paths: # prevents workflow from running unless these files change
- '.github/workflows/localize.yml'
- 'src/**'
- 'locale/sunshine.po'
workflow_dispatch:
env:
file: ./locale/sunshine.po
jobs:
localize:
name: Update Localization
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Python 3.9
uses: actions/setup-python@v4 # https://github.com/actions/setup-python
with:
python-version: '3.9'
- name: Set up Python 3.9 Dependencies
run: |
cd ./scripts
python -m pip install --upgrade pip setuptools
python -m pip install -r requirements.txt
- name: Set up xgettext
run: |
sudo apt-get update -y && \
sudo apt-get --reinstall install -y \
gettext
- name: Update Strings
run: |
# first, try to remove existing file as xgettext does not remove unused translations
if [ -f "${{ env.file }}" ];
then
rm ${{ env.file }}
echo "new_file=false" >> $GITHUB_ENV
else
echo "new_file=true" >> $GITHUB_ENV
fi
# extract the new strings
python ./scripts/_locale.py --extract
- name: git diff
if: ${{ env.new_file == 'false' }}
run: |
# disable the pager
git config --global pager.diff false
# print the git diff
git diff locale/sunshine.po
# set the variable with minimal output
OUTPUT=$(git diff --numstat locale/sunshine.po)
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' }}
run: |
git reset --hard
- name: Create/Update Pull Request
uses: peter-evans/create-pull-request@v4
with:
add-paths: |
locale/*.po
token: ${{ secrets.GH_BOT_TOKEN }} # must trigger PR tests
commit-message: New localization template
branch: localize/update
delete-branch: true
base: nightly
title: New Babel Updates
body: |
Update report
- Updated with *today's* date
- Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
labels: |
babel
l10n

27
.github/workflows/pull-requests.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
---
# 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: Pull Requests
on:
pull_request_target:
types: [opened, synchronize, edited, reopened]
jobs:
check-pull-request:
name: Check Pull Request
runs-on: ubuntu-latest
steps:
- uses: Vankka/pr-target-branch-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
target: master
exclude: nightly # Don't prevent going from nightly -> master
change-to: nightly
comment: |
Your PR was set to `master`, PRs should be sent to `nightly`.
The base branch of this PR has been automatically changed to `nightly`.
Please check that there are no merge conflicts

31
.github/workflows/python-flake8.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
---
# 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: flake8
on:
pull_request:
branches: [master, nightly]
types: [opened, synchronize, reopened]
jobs:
flake8:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4 # https://github.com/actions/setup-python
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools flake8
- name: Test with flake8
run: |
python -m flake8 --verbose

81
.github/workflows/release-notifier.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
---
# 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: Release Notifications
on:
release:
types: [published]
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onevent_nametypes
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 }}
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
facebook_group:
runs-on: ubuntu-latest
steps:
- name: facebook-post-action
uses: ReenigneArcher/facebook-post-action@v1 # https://github.com/ReenigneArcher/facebook-post-action
with:
page_id: ${{ secrets.FACEBOOK_GROUP_ID }}
access_token: ${{ secrets.FACEBOOK_ACCESS_TOKEN }}
message: |
${{ github.event.repository.name }} ${{ github.ref_name }} Released
${{ github.event.release.body }}
url: ${{ github.event.release.html_url }}
facebook_page:
runs-on: ubuntu-latest
steps:
- name: facebook-post-action
uses: ReenigneArcher/facebook-post-action@v1 # https://github.com/ReenigneArcher/facebook-post-action
with:
page_id: ${{ secrets.FACEBOOK_PAGE_ID }}
access_token: ${{ secrets.FACEBOOK_ACCESS_TOKEN }}
message: |
${{ github.event.repository.name }} ${{ github.ref_name }} Released
${{ github.event.release.body }}
url: ${{ github.event.release.html_url }}
reddit:
runs-on: ubuntu-latest
steps:
- name: reddit
uses: bluwy/release-for-reddit-action@v1 # https://github.com/bluwy/release-for-reddit-action
with:
username: ${{ secrets.REDDIT_USERNAME }}
password: ${{ secrets.REDDIT_PASSWORD }}
app-id: ${{ secrets.REDDIT_CLIENT_ID }}
app-secret: ${{ secrets.REDDIT_CLIENT_SECRET }}
subreddit: ${{ secrets.REDDIT_SUBREDDIT }}
title: ${{ github.event.repository.name }} ${{ github.ref_name }} Released
url: ${{ github.event.release.html_url }}
flair-id: ${{ secrets.REDDIT_FLAIR_ID }} # https://www.reddit.com/r/<subreddit>>/api/link_flair.json
comment: ${{ github.event.release.body }}
twitter:
runs-on: ubuntu-latest
steps:
- name: twitter
uses: ethomson/send-tweet-action@v1 # https://github.com/ethomson/send-tweet-action
with:
consumer-key: ${{ secrets.TWITTER_API_KEY }}
consumer-secret: ${{ secrets.TWITTER_API_SECRET }}
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
status: ${{ github.event.release.html_url }}

17
.github/workflows/winget.yml vendored Normal file
View File

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

46
.github/workflows/yaml-lint.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
---
# 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: yaml lint
on:
pull_request:
branches: [master, nightly]
types: [opened, synchronize, reopened]
jobs:
yaml-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: yaml lint
id: yaml-lint
uses: ibiqlik/action-yamllint@v3
with:
# https://yamllint.readthedocs.io/en/stable/configuration.html#default-configuration
config_data: |
extends: default
rules:
comments:
level: error
line-length:
max: 120
truthy:
allowed-values: ['true', 'false', 'on'] # GitHub uses "on" for workflow event triggers
check-keys: true
level: error
- 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 }}

16
.gitignore vendored
View File

@@ -7,4 +7,18 @@ cmake-build*
*.kdev4
.cache
.idea
.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/
# Translations
*.mo
*.pot

6
.gitmodules vendored
View File

@@ -10,3 +10,9 @@
[submodule "third-party/miniupnp"]
path = third-party/miniupnp
url = https://github.com/miniupnp/miniupnp
[submodule "third-party/nv-codec-headers"]
path = third-party/nv-codec-headers
url = https://github.com/FFmpeg/nv-codec-headers
[submodule "third-party/TPCircularBuffer"]
path = third-party/TPCircularBuffer
url = https://github.com/michaeltyson/TPCircularBuffer

1
.prettierrc.json Normal file
View File

@@ -0,0 +1 @@
{}

45
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,45 @@
---
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python
build:
os: ubuntu-20.04
tools:
python: "3.9"
## 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
## run cmake
# jobs:
# pre_build:
# - cmake .
## Include the submodules, required for cmake
# submodules:
# include: all
# recursive: true
# Build documentation in the docs/ directory with Sphinx
sphinx:
builder: html
configuration: docs/source/conf.py
fail_on_warning: true
# Using Sphinx, build docs in additional formats
formats: all
python:
install:
- requirements: ./scripts/requirements.txt
system_packages: true

152
CHANGELOG.md Normal file
View File

@@ -0,0 +1,152 @@
# Changelog
## [0.14.1] - 2022-08-09
### Added
- (Linux) Flatpak package added
- (Linux) AUR package automated updates
- (Windows) Winget package automated updates
### Changed
- (General) Moved repo to @LizardByte GitHub org
- (WebUI) Fixed button spacing on home page
- (WebUI) Added Discord WidgetBot Crate
### Fixed
- (Linux/Mac) Default config and app files now copied to user home directory
- (Windows) Default config and app files now copied to working directory
## [0.14.0] - 2022-06-15
### Added
- (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
- (Windows) Add DwmFlush() call to improve capture
- (Windows) Add Windows installer
### Fixed
- (AMD) Fixed hwdevice being destroyed before context
- (Linux) Added missing dependencies to AppImage
- (Linux) Fixed rumble events causing game to freeze
- (Linux) Improved Pulse/Pipewire compatibility
- (Linux) Moved to single deb package
- (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)
## [0.12.0] - 2022-02-13
### Added
- New command line argument `--version`
- Custom png poster support
### Changed
- Correct software bitrate calculation
- Increase vbv-bufsize to 1/10 of requested bitrate
- Improvements to Web UI
## [0.11.1] - 2021-10-04
### Changed
- (Linux) Fix search path for config file and assets
## [0.11.0] - 2021-10-04
### Added
- (Linux) Added support for wlroots based compositors on Wayland.
- (Windows) Added an icon for the executable
### Changed
- Fixed a bug causing segfault when connecting multiple controllers.
- (Linux) Improved NVENC, it now offloads converting images from RGB to NV12
- (Linux) Fixed a bug causes stuttering
## [0.10.1] - 2021-08-21
### Changed
- (Linux) Re-enabled KMS
## [0.10.0] - 2021-08-20
### Added
- Added support for Rumble with gamepads.
- Added support for keyboard shortcuts <--- See the README for details.
- (Windows) A very basic script has been added in Sunshine-Windows\tools <-- This will start Sunshine at boot with the highest privileges which is needed to display the login prompt.
### Changed
- Some cosmetic changes to the WebUI.
- The first time the WebUI is opened, it will request the creation of a username/password pair from the user.
- Fixed audio crackling introduced in version 0.8.0
- (Linux) VAAPI hardware encoding now works on Intel i7-6700 at least. <-- For the best experience, using ffmpeg version 4.3 or higher is recommended.
- (Windows) Installing from debian package shouldn't overwrite your configuration files anymore. <-- It's recommended that you back up `/etc/sunshine/` before testing this.
## [0.9.0] - 2021-07-11
### Added
- Added audio encryption
- (Linux) Added basic NVENC support on Linux
- (Windows) The Windows version can now capture the lock screen and the UAC prompt as long as it's run through `PsExec.exe` https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
### Changed
- Sunshine will now accept expired or not-yet-valid certificates, as long as they are signed properly.
- Fixed compatibility with iOS version of Moonlight
- Drastically reduced chance of being forced to skip error correction due to video frame size
- (Linux) sunshine.service will be installed automatically.
## [0.8.0] - 2021-06-30
### Added
- Added mDNS support: Moonlight will automatically find Sunshine.
- Added UPnP support. It's off by default.
## [0.7.7] - 2021-06-24
### Added
- (Linux) Added installation package for Debian
### Changed
- Fixed incorrect scaling for absolute mouse coordinates when using multiple monitors.
- Fixed incorrect colors when scaling for software encoder
## [0.7.1] - 2021-06-18
### Changed
- (Linux) Fixed an issue where it was impossible to start sunshine on ubuntu 20.04
## [0.7.0] - 2021-06-16
### Added
- Added a Web Manager. Accessible through: https://localhost:47990 or https://<ip of your pc>:47990
- (Linux) Added hardware encoding support for AMD on Linux
### Changed
- (Linux) Moved certificates and saved pairings generated during runtime to .config/sunshine on Linux
## [0.6.0] - 2021-05-26
### Added
- Added support for surround audio
### Changed
- Maintain aspect ratio when scaling video
- Fix issue where Sunshine is forced to drop frames when they are too large
## [0.5.0] - 2021-05-13
### Added
- Added support for absolute mouse coordinates
- (Linux) Added support for streaming specific monitor on Linux
- (Windows) Added support for AMF on Windows
## [0.4.0] - 2020-05-03
### Changed
- prep-cmd is now optional in apps.json
- Fixed bug causing video artifacts
- Fixed bug preventing Moonlight from closing app on exit
- Fixed bug causing preventing keyboard keys from repeating on latest version of Moonlight
- Fixed bug causing segfault when another session of sunshine was already running
- Fixed bug causing crash when monitor has resolution 1366x768
## [0.3.1] - 2020-04-24
### Changed
- Fix a memory leak.
## [0.3.0] - 2020-04-23
### Changed
- Hardware acceleration on NVidia GPU's for Video encoding on Windows
## [0.2.0] - 2020-03-21
### Changed
- Multicasting is now supported: You can set the maximum simultaneous connections with the configurable option: channels
- Configuration variables can be overwritten on the command line: "name=value" --> it can be useful to set min_log_level=debug without modifying the configuration file
- Switches to make testing the pairing mechanism more convenient has been added, see "sunshine --help" for details
## [0.1.1] - 2020-01-30
### Added
- (Linux) Added deb package and service for Linux
## [0.1.0] - 2020-01-27
### Added
- The first official release for Sunshine!

View File

@@ -1,9 +1,62 @@
cmake_minimum_required(VERSION 3.0)
project(Sunshine)
project(Sunshine VERSION 0.14.1
DESCRIPTION "Sunshine is a Gamestream host for Moonlight."
HOMEPAGE_URL "https://app.lizardbyte.dev"
)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set(PROJECT_LONG_DESCRIPTION "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.")
option(SUNSHINE_CONFIGURE_APPIMAGE "Configure files required for AppImage." OFF)
option(SUNSHINE_CONFIGURE_AUR "Configure files required for AUR." OFF)
option(SUNSHINE_CONFIGURE_FLATPAK "Configure files required for Flatpak." OFF)
option(SUNSHINE_CONFIGURE_PORTFILE "Configure macOS Portfile." OFF)
option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF)
if(${SUNSHINE_CONFIGURE_APPIMAGE})
configure_file(packaging/linux/sunshine.desktop sunshine.desktop @ONLY)
elseif(${SUNSHINE_CONFIGURE_AUR})
configure_file(packaging/linux/aur/PKGBUILD PKGBUILD @ONLY)
elseif(${SUNSHINE_CONFIGURE_FLATPAK})
configure_file(packaging/linux/flatpak/dev.lizardbyte.sunshine.yml dev.lizardbyte.sunshine.yml @ONLY)
elseif(${SUNSHINE_CONFIGURE_PORTFILE})
configure_file(packaging/macos/Portfile Portfile @ONLY)
endif()
# return if configure only is set
if(${SUNSHINE_CONFIGURE_ONLY})
return()
endif()
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(SUNSHINE_SOURCE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src_assets")
if(WIN32)
# Ugly hack to compile with #include <qos2.h>
add_compile_definitions(
QOS_FLOWID=UINT32
PQOS_FLOWID=UINT32*
QOS_NON_ADAPTIVE_FLOW=2)
endif()
if(APPLE)
macro(ADD_FRAMEWORK fwname appname)
find_library(FRAMEWORK_${fwname}
NAMES ${fwname}
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found")
else()
TARGET_LINK_LIBRARIES(${appname} "${FRAMEWORK_${fwname}}/${fwname}")
MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
endif()
endmacro(ADD_FRAMEWORK)
endif()
add_subdirectory(third-party/moonlight-common-c/enet)
add_subdirectory(third-party/Simple-Web-Server)
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "no shared libraries")
@@ -13,21 +66,18 @@ set(UPNPC_NO_INSTALL ON CACHE BOOL "Don't install any libraries build for miniup
add_subdirectory(third-party/miniupnp/miniupnpc)
include_directories(third-party/miniupnp)
if(WIN32)
# Ugly hack to compile with #include <qos2.h>
add_compile_definitions(
QOS_FLOWID=UINT32
PQOS_FLOWID=UINT32*
QOS_NON_ADAPTIVE_FLOW=2)
endif()
add_subdirectory(third-party/moonlight-common-c/enet)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)
if(NOT APPLE)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(Boost COMPONENTS log filesystem REQUIRED)
list(APPEND SUNSHINE_COMPILE_OPTIONS -fPIC -Wall -Wno-missing-braces -Wno-maybe-uninitialized -Wno-sign-compare)
list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-missing-braces -Wno-maybe-uninitialized -Wno-sign-compare)
if(WIN32)
enable_language(RC)
set(CMAKE_RC_COMPILER windres)
file(
DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip"
TIMEOUT 60
@@ -37,7 +87,7 @@ if(WIN32)
INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip"
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
if(NOT DEFINED SUNSHINE_PREPARED_BINARIES)
set(SUNSHINE_PREPARED_BINARIES "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled/windows")
endif()
@@ -45,20 +95,23 @@ if(WIN32)
add_compile_definitions(SUNSHINE_PLATFORM="windows")
add_subdirectory(tools) #This is temporary, only tools for Windows are needed, for now
list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_windows.json")
include_directories(third-party/ViGEmClient/include)
if(NOT DEFINED SUNSHINE_ICON_PATH)
set(SUNSHINE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sunshine.ico")
endif()
configure_file(src/platform/windows/windows.rs.in windows.rc @ONLY)
set(PLATFORM_TARGET_FILES
sunshine/platform/windows/publish.cpp
sunshine/platform/windows/misc.h
sunshine/platform/windows/misc.cpp
sunshine/platform/windows/input.cpp
sunshine/platform/windows/display.h
sunshine/platform/windows/display_base.cpp
sunshine/platform/windows/display_vram.cpp
sunshine/platform/windows/display_ram.cpp
sunshine/platform/windows/audio.cpp
"${CMAKE_CURRENT_BINARY_DIR}/windows.rc"
src/platform/windows/publish.cpp
src/platform/windows/misc.h
src/platform/windows/misc.cpp
src/platform/windows/input.cpp
src/platform/windows/display.h
src/platform/windows/display_base.cpp
src/platform/windows/display_vram.cpp
src/platform/windows/display_ram.cpp
src/platform/windows/audio.cpp
third-party/ViGEmClient/src/ViGEmClient.cpp
third-party/ViGEmClient/include/ViGEm/Client.h
third-party/ViGEmClient/include/ViGEm/Common.h
@@ -89,72 +142,212 @@ if(WIN32)
libstdc++.a
libwinpthread.a
libssp.a
Qwave
winmm
ksuser
wsock32
ws2_32
iphlpapi
d3d11 dxgi D3DCompiler
setupapi
dnsapi
dwmapi
)
set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650")
set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_FLAGS "-Wno-unknown-pragmas -Wno-misleading-indentation -Wno-class-memaccess")
else()
add_compile_definitions(SUNSHINE_PLATFORM="linux")
list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_linux.json")
elseif(APPLE)
add_compile_definitions(SUNSHINE_PLATFORM="macos")
option(SUNSHINE_MACOS_PACKAGE "Should only be used when creating a MACOS package/dmg." OFF)
link_directories(/opt/local/lib)
link_directories(/usr/local/lib)
ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
find_package(X11 REQUIRED)
find_package(FFmpeg REQUIRED)
FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices )
FIND_LIBRARY(AV_FOUNDATION_LIBRARY AVFoundation )
FIND_LIBRARY(CORE_MEDIA_LIBRARY CoreMedia )
FIND_LIBRARY(CORE_VIDEO_LIBRARY CoreVideo )
FIND_LIBRARY(FOUNDATION_LIBRARY Foundation )
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
${APP_SERVICES_LIBRARY}
${AV_FOUNDATION_LIBRARY}
${CORE_MEDIA_LIBRARY}
${CORE_VIDEO_LIBRARY}
${FOUNDATION_LIBRARY})
set(PLATFORM_INCLUDE_DIRS
${Boost_INCLUDE_DIR})
set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist)
set(PLATFORM_TARGET_FILES
sunshine/platform/linux/publish.cpp
sunshine/platform/linux/vaapi.h
sunshine/platform/linux/vaapi.cpp
sunshine/platform/linux/misc.h
sunshine/platform/linux/misc.cpp
sunshine/platform/linux/display.cpp
sunshine/platform/linux/audio.cpp
sunshine/platform/linux/input.cpp
src/platform/macos/av_audio.h
src/platform/macos/av_audio.m
src/platform/macos/av_img_t.h
src/platform/macos/av_video.h
src/platform/macos/av_video.m
src/platform/macos/display.mm
src/platform/macos/input.cpp
src/platform/macos/microphone.mm
src/platform/macos/misc.cpp
src/platform/macos/misc.h
src/platform/macos/nv12_zero_device.cpp
src/platform/macos/nv12_zero_device.h
src/platform/macos/publish.cpp
third-party/TPCircularBuffer/TPCircularBuffer.c
third-party/TPCircularBuffer/TPCircularBuffer.h
${APPLE_PLIST_FILE})
else()
add_compile_definitions(SUNSHINE_PLATFORM="linux")
option(SUNSHINE_ENABLE_DRM "Enable KMS grab if available" ON)
option(SUNSHINE_ENABLE_X11 "Enable X11 grab if available" ON)
option(SUNSHINE_ENABLE_WAYLAND "Enable building wayland specific code" ON)
option(SUNSHINE_ENABLE_CUDA "Enable cuda specific code" ON)
if(${SUNSHINE_ENABLE_X11})
find_package(X11)
else()
set(X11_FOUND OFF)
endif()
set(CUDA_FOUND OFF)
if(${SUNSHINE_ENABLE_CUDA})
include(CheckLanguage)
check_language(CUDA)
if(CMAKE_CUDA_COMPILER)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 35)
endif()
set(CUDA_FOUND ON)
enable_language(CUDA)
endif()
endif()
if(${SUNSHINE_ENABLE_DRM})
find_package(LIBDRM)
find_package(LIBCAP)
else()
set(LIBDRM_FOUND OFF)
set(LIBCAP_FOUND OFF)
endif()
if(${SUNSHINE_ENABLE_WAYLAND})
find_package(Wayland)
else()
set(WAYLAND_FOUND OFF)
endif()
find_package(FFMPEG REQUIRED)
if(X11_FOUND)
add_compile_definitions(SUNSHINE_BUILD_X11)
include_directories(${X11_INCLUDE_DIR})
list(APPEND PLATFORM_TARGET_FILES src/platform/linux/x11grab.cpp)
endif()
if(CUDA_FOUND)
include_directories(third-party/nvfbc)
list(APPEND PLATFORM_TARGET_FILES
src/platform/linux/cuda.cu
src/platform/linux/cuda.cpp
third-party/nvfbc/NvFBC.h)
add_compile_definitions(SUNSHINE_BUILD_CUDA)
endif()
if(LIBDRM_FOUND AND LIBCAP_FOUND)
add_compile_definitions(SUNSHINE_BUILD_DRM)
include_directories(${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS})
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES})
list(APPEND PLATFORM_TARGET_FILES src/platform/linux/kmsgrab.cpp)
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
elseif(LIBDRM_FOUND)
message(WARNING "Found libdrm, yet there is no libcap")
elseif(LIBDRM_FOUND)
message(WARNING "Found libcap, yet there is no libdrm")
endif()
if(WAYLAND_FOUND)
add_compile_definitions(SUNSHINE_BUILD_WAYLAND)
macro(genWayland FILENAME)
make_directory(${CMAKE_BINARY_DIR}/generated-src)
message("wayland-scanner private-code ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${FILENAME}.xml ${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.c")
message("wayland-scanner client-header ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${FILENAME}.xml ${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.h")
execute_process(
COMMAND wayland-scanner private-code ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${FILENAME}.xml ${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.c
COMMAND wayland-scanner client-header ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${FILENAME}.xml ${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.h
RESULT_VARIABLE EXIT_INT
)
if(NOT ${EXIT_INT} EQUAL 0)
message(FATAL_ERROR "wayland-scanner failed")
endif()
list(APPEND PLATFORM_TARGET_FILES
${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.c
${CMAKE_BINARY_DIR}/generated-src/${FILENAME}.h
)
endmacro()
genWayland(xdg-output-unstable-v1)
genWayland(wlr-export-dmabuf-unstable-v1)
include_directories(
${WAYLAND_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}/generated-src
)
list(APPEND PLATFORM_LIBRARIES ${WAYLAND_LIBRARIES})
list(APPEND PLATFORM_TARGET_FILES
src/platform/linux/wlgrab.cpp
src/platform/linux/wayland.cpp)
endif()
if(NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND}) AND NOT ${WAYLAND_FOUND} AND NOT ${})
message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)")
endif()
list(APPEND PLATFORM_TARGET_FILES
src/platform/linux/publish.cpp
src/platform/linux/vaapi.h
src/platform/linux/vaapi.cpp
src/platform/linux/cuda.h
src/platform/linux/graphics.h
src/platform/linux/graphics.cpp
src/platform/linux/misc.h
src/platform/linux/misc.cpp
src/platform/linux/audio.cpp
src/platform/linux/input.cpp
src/platform/linux/x11grab.h
src/platform/linux/wayland.h
third-party/glad/src/egl.c
third-party/glad/src/gl.c
third-party/glad/include/EGL/eglplatform.h
third-party/glad/include/KHR/khrplatform.h
third-party/glad/include/glad/gl.h
third-party/glad/include/glad/egl.h)
set(PLATFORM_LIBRARIES
Xfixes
Xtst
xcb
xcb-shm
xcb-xfixes
Xrandr
${X11_LIBRARIES}
list(APPEND PLATFORM_LIBRARIES
dl
evdev
pulse
pulse-simple
)
set(PLATFORM_INCLUDE_DIRS
${X11_INCLUDE_DIR}
include_directories(
/usr/include/libevdev-1.0
third-party/nv-codec-headers/include
third-party/glad/include)
if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH)
set(SUNSHINE_EXECUTABLE_PATH "sunshine")
endif()
configure_file(gen-deb.in gen-deb @ONLY)
configure_file(sunshine.service.in sunshine.service @ONLY)
endif()
add_subdirectory(third-party/cbs)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS log filesystem REQUIRED)
configure_file(version.h.in version.h @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(SUNSHINE_TARGET_FILES
third-party/moonlight-common-c/reedsolomon/rs.c
@@ -163,47 +356,47 @@ set(SUNSHINE_TARGET_FILES
third-party/moonlight-common-c/src/Rtsp.h
third-party/moonlight-common-c/src/RtspParser.c
third-party/moonlight-common-c/src/Video.h
sunshine/upnp.cpp
sunshine/upnp.h
sunshine/cbs.cpp
sunshine/utility.h
sunshine/uuid.h
sunshine/config.h
sunshine/config.cpp
sunshine/main.cpp
sunshine/main.h
sunshine/crypto.cpp
sunshine/crypto.h
sunshine/nvhttp.cpp
sunshine/nvhttp.h
sunshine/httpcommon.cpp
sunshine/httpcommon.h
sunshine/confighttp.cpp
sunshine/confighttp.h
sunshine/rtsp.cpp
sunshine/rtsp.h
sunshine/stream.cpp
sunshine/stream.h
sunshine/video.cpp
sunshine/video.h
sunshine/input.cpp
sunshine/input.h
sunshine/audio.cpp
sunshine/audio.h
sunshine/platform/common.h
sunshine/process.cpp
sunshine/process.h
sunshine/network.cpp
sunshine/network.h
sunshine/move_by_copy.h
sunshine/task_pool.h
sunshine/thread_pool.h
sunshine/thread_safe.h
sunshine/sync.h
sunshine/round_robin.h
src/upnp.cpp
src/upnp.h
src/cbs.cpp
src/utility.h
src/uuid.h
src/config.h
src/config.cpp
src/main.cpp
src/main.h
src/crypto.cpp
src/crypto.h
src/nvhttp.cpp
src/nvhttp.h
src/httpcommon.cpp
src/httpcommon.h
src/confighttp.cpp
src/confighttp.h
src/rtsp.cpp
src/rtsp.h
src/stream.cpp
src/stream.h
src/video.cpp
src/video.h
src/input.cpp
src/input.h
src/audio.cpp
src/audio.h
src/platform/common.h
src/process.cpp
src/process.h
src/network.cpp
src/network.h
src/move_by_copy.h
src/task_pool.h
src/thread_pool.h
src/thread_safe.h
src/sync.h
src/round_robin.h
${PLATFORM_TARGET_FILES})
set_source_files_properties(sunshine/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic)
set_source_files_properties(src/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@@ -215,11 +408,13 @@ include_directories(
${PLATFORM_INCLUDE_DIRS}
)
add_subdirectory(third-party/cbs)
string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE)
if("${BUILD_TYPE}" STREQUAL "XDEBUG")
list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -pedantic -ggdb3)
list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -ggdb3)
if(WIN32)
set_source_files_properties(sunshine/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2)
set_source_files_properties(src/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2)
endif()
else()
add_definitions(-DNDEBUG)
@@ -227,7 +422,16 @@ else()
endif()
if(NOT SUNSHINE_ASSETS_DIR)
set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets")
set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets")
endif()
if(NOT SUNSHINE_CONFIG_DIR)
set(SUNSHINE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/config")
endif()
if(UNIX AND CMAKE_INSTALL_PREFIX AND NOT ${SUNSHINE_CONFIGURE_APPIMAGE})
set(SUNSHINE_ASSETS_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_ASSETS_DIR}")
set(SUNSHINE_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_CONFIG_DIR}")
endif()
list(APPEND CBS_EXTERNAL_LIBRARIES
@@ -237,7 +441,6 @@ list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
libminiupnpc-static
${CBS_EXTERNAL_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
stdc++fs
enet
opus
${FFMPEG_LIBRARIES}
@@ -245,10 +448,182 @@ list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
${OPENSSL_LIBRARIES}
${PLATFORM_LIBRARIES})
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR}")
add_executable(sunshine ${SUNSHINE_TARGET_FILES})
target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES})
target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS})
set_target_properties(sunshine PROPERTIES CXX_STANDARD 17)
if(NOT WIN32)
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES Boost::log)
endif()
target_compile_options(sunshine PRIVATE ${SUNSHINE_COMPILE_OPTIONS})
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR}")
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_CONFIG_DIR="${SUNSHINE_CONFIG_DIR}")
add_executable(sunshine ${SUNSHINE_TARGET_FILES})
target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES} ${EXTRA_LIBS})
target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS})
set_target_properties(sunshine PROPERTIES CXX_STANDARD 17
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
if(NOT DEFINED CMAKE_CUDA_STANDARD)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()
if(APPLE)
target_link_options(sunshine PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${APPLE_PLIST_FILE})
endif()
foreach(flag IN LISTS SUNSHINE_COMPILE_OPTIONS)
list(APPEND SUNSHINE_COMPILE_OPTIONS_CUDA "$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
target_compile_options(sunshine PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${SUNSHINE_COMPILE_OPTIONS}>;$<$<COMPILE_LANGUAGE:CUDA>:${SUNSHINE_COMPILE_OPTIONS_CUDA};-std=c++17>)
# CPACK / Packaging
# Common options
set(CPACK_PACKAGE_NAME "Sunshine")
set(CPACK_PACKAGE_VENDOR "LizardByte")
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpack_artifacts)
set(CPACK_PACKAGE_CONTACT "https://app.lizardbyte.dev")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "https://github.com/LizardByte")
set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION})
set(CPACK_PACKAGE_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE)
set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/sunshine.png)
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}")
set(CPACK_STRIP_FILES YES)
# Platform specific options
if(WIN32) # see options at: https://cmake.org/cmake/help/latest/cpack_gen/nsis.html
install(TARGETS sunshine RUNTIME DESTINATION "." COMPONENT application)
# Adding tools
install(TARGETS dxgi-info RUNTIME DESTINATION "tools" COMPONENT dxgi)
install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio)
install(TARGETS sunshinesvc RUNTIME DESTINATION "tools" COMPONENT sunshinesvc)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}" COMPONENT assets)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}" COMPONENT assets)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}" COMPONENT config)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}" COMPONENT config)
# set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\sunshine.ico")
set(CPACK_NSIS_INSTALLED_ICON_NAME "${PROJECT__DIR}\\\\${PROJECT_EXE}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") # The name of the directory that will be created in C:/Program files/
string(APPEND CPACK_NSIS_DEFINES "\n RequestExecutionLevel admin") # TODO: Not sure if this is needed but it took me a while to figure out where to put this option so I'm leaving it here
# Sets permissions on the installed folder so that we can write in it
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}
ExecWait 'icacls \\\"$INSTDIR\\\" /grant:r Users:\\\(OI\\\)\\\(CI\\\)\\\(F\\\)'
")
# Adding an option for the start menu and PATH
set(CPACK_NSIS_MODIFY_PATH "OFF") # TODO: it asks to add it to the PATH but is not working https://gitlab.kitware.com/cmake/cmake/-/issues/15635
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${CMAKE_PROJECT_NAME}.exe")
set(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe") # This will be shown on the installed apps Windows settings
set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' '\$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe'")
# Checking for previous installed versions
# set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") # TODO: doesn't work on my machine when Sunshine is already installed
# Setting components groups and dependencies
# sunshine binary
set(CPACK_COMPONENT_APPLICATION_DISPLAY_NAME "${CMAKE_PROJECT_NAME}")
set(CPACK_COMPONENT_APPLICATION_DESCRIPTION "The main application.")
set(CPACK_COMPONENT_APPLICATION_GROUP "${CMAKE_PROJECT_NAME}")
set(CPACK_COMPONENT_APPLICATION_REQUIRED true)
set(CPACK_COMPONENT_APPLICATION_DEPENDS assets)
# assets
set(CPACK_COMPONENT_ASSETS_DISPLAY_NAME "Assets")
set(CPACK_COMPONENT_ASSETS_DESCRIPTION "Shaders, default box art, and web ui.")
set(CPACK_COMPONENT_ASSETS_GROUP "${CMAKE_PROJECT_NAME}")
set(CPACK_COMPONENT_ASSETS_REQUIRED true)
# config
set(CPACK_COMPONENT_CONFIG_DISPLAY_NAME "Config")
set(CPACK_COMPONENT_CONFIG_DESCRIPTION "Default config and apps.json files.")
set(CPACK_COMPONENT_CONFIG_GROUP "${CMAKE_PROJECT_NAME}")
set(CPACK_COMPONENT_CONFIG_REQUIRED true)
# audio tool
set(CPACK_COMPONENT_AUDIO_DISPLAY_NAME "audio-info.exe")
set(CPACK_COMPONENT_AUDIO_DESCRIPTION "CLI tool that allows you to get information about sound devices.")
set(CPACK_COMPONENT_AUDIO_GROUP "Tools")
# display tool
set(CPACK_COMPONENT_DXGI_DISPLAY_NAME "dxgi-info.exe")
set(CPACK_COMPONENT_DXGI_DESCRIPTION "CLI tool that allows you to get information about graphics cards and displays.")
set(CPACK_COMPONENT_DXGI_GROUP "Tools")
# service tool
set(CPACK_COMPONENT_SUNSHINESVC_DISPLAY_NAME "sunshinesvc.exe")
set(CPACK_COMPONENT_SUNSHINESVC_DESCRIPTION "CLI tool that allows you to enable/disable the Sunshine service.")
set(CPACK_COMPONENT_SUNSHINESVC_GROUP "Tools")
endif()
if(APPLE)
# TODO: bundle doesn't produce a valid .app use cpack -G DragNDrop
set(CPACK_BUNDLE_NAME "${CMAKE_PROJECT_NAME}")
set(CPACK_BUNDLE_PLIST "${APPLE_PLIST_FILE}")
set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/sunshine.icns")
# set(CPACK_BUNDLE_STARTUP_COMMAND "${INSTALL_RUNTIME_DIR}/sunshine")
endif()
if(APPLE AND SUNSHINE_MACOS_PACKAGE) # TODO
set(prefix "${CMAKE_PROJECT_NAME}.app/Contents")
set(INSTALL_RUNTIME_DIR "${prefix}/MacOS")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}")
install(TARGETS sunshine
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime)
elseif(UNIX)
# Installation destination dir
set(CPACK_SET_DESTDIR true)
if(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local/sunshine")
endif()
install(TARGETS sunshine RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}")
if(APPLE)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/misc/uninstall_pkg.sh" DESTINATION "${SUNSHINE_ASSETS_DIR}")
else()
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}")
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" DESTINATION "${CMAKE_INSTALL_LIBDIR}/udev/rules.d")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" DESTINATION "${CMAKE_INSTALL_LIBDIR}/systemd/user")
# Pre and post install
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/preinst"
"${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst"
"${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/conffiles")
set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/preinst")
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
# Dependencies
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0 | libboost-thread1.74.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0 | libboost-filesystem1.74.0, libboost-log1.67.0 | libboost-log1.71.0 | libboost-log1.74.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2, libdrm2, libcap2")
set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.1, libavdevice >= 4.3, boost-thread >= 1.67.0, boost-filesystem >= 1.67.0, boost-log >= 1.67.0, pulseaudio-libs >= 10.0, libopusenc >= 0.2.1, libxcb >= 1.13, libXtst >= 1.2.3, libevdev >= 1.5.6, libdrm >= 2.4.97, libcap >= 2.22")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) # This should automatically figure out dependencies, doesn't work with the current config
endif()
endif()
include(CPack)

101
DOCKER_README.md Normal file
View File

@@ -0,0 +1,101 @@
# Docker
## Using docker run
Create and run the container (substitute your `<values>`):
```bash
docker run -d \
--name=sunshine \
--restart=unless-stopped
-v <path to data>:/config \
-e PUID=<uid> \
-e PGID=<gid> \
-e TZ=<timezone> \
-p 47984-47990:47984-47990/tcp \
-p 48010:48010 \
-p 47998-48000:47998-48000/udp \
lizardbyte/sunshine
```
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
Create a `docker-compose.yml` file with the following contents (substitute your `<values>`):
```yaml
version: '3'
services:
sunshine:
image: lizardbyte/sunshine
container_name: sunshine
restart: unless-stopped
volumes:
- <path to data>:/config
environment:
- PUID=<uid>
- PGID=<gid>
- TZ=<timezone>
ports:
- 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
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
container.
**Example:** `-p external:internal` - This shows the port mapping from internal to external of the container.
Therefore `-p 47990:47990` would expose port `47990` from inside the container to be accessible from the host's IP on
port `47990` (e.g. `http://<host_ip>:47990`). The internal port must be `47990`, but the external port may be changed
(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 |
### 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.
In this instance `PUID=1001` and `PGID=1001`. To find yours use id user as below:
```bash
$ id dockeruser
uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup)
```

3
NOTICE Normal file
View File

@@ -0,0 +1,3 @@
©2018 Valve Corporation. Steam and the Steam logo are trademarks and/or
registered trademarks of Valve Corporation in the U.S. and/or other countries. All
rights reserved.

199
README.md
View File

@@ -1,199 +0,0 @@
# Introduction
Sunshine is a Gamestream host for Moonlight
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/cgrtw2g3fq9b0b70/branch/master?svg=true)](https://ci.appveyor.com/project/loki-47-6F-64/sunshine/branch/master)
[![Downloads](https://img.shields.io/github/downloads/Loki-47-6F-64/sunshine/total)](https://github.com/Loki-47-6F-64/sunshine/releases)
- [Building](README.md#building)
- [Credits](README.md#credits)
# Building
- [Linux](README.md#linux)
- [Windows](README.md#windows-10)
## Linux
### Requirements:
Ubuntu 20.04:
Install the following
```
sudo apt install cmake libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev
```
### Compilation:
- `git clone https://github.com/loki-47-6F-64/sunshine.git --recurse-submodules`
- `cd sunshine && mkdir build && cd build`
- `cmake ..`
- `make -j ${nproc}`
### Setup:
sunshine needs access to uinput to create mouse and gamepad events:
- Add user to group 'input':
`usermod -a -G input $USER`
- Create udev rules:
- Run the following command:
`nano /etc/udev/rules.d/85-sunshine-input.rules`
- Input the following contents:
`KERNEL=="uinput", GROUP="input", MODE="0660"`
- Save the file and exit
1. `CTRL+X` to start exit
2. `Y` to save modifications
- `assets/sunshine.conf` is an example configuration file. Modify it as you see fit, then use it by running:
`sunshine path/to/sunshine.conf`
- Configure autostart service
`path/to/build/dir/sunshine.service` is used to start sunshine in the background. To use it, do the following:
1. Copy it to the users systemd, `cp sunshine.service ~/.config/systemd/user/`
2. Starting
- Onetime:
`systemctl --user start sunshine`
- Always on boot:
`systemctl --user enable sunshine`
- `assets/apps.json` is an [example](README.md#application-list) of a list of applications that are started just before running a stream
### Trouleshooting:
- If you get "Could not create Sunshine Gamepad: Permission Denied", ensure you are part of the group "input":
- `groups $USER`
- If Sunshine sends audio from the microphone instead of the speaker, try the following steps:
1. `$ pacmd list-sources | grep "name:"` or `$ pactl info | grep Source` if running pipewire.
2. Copy the name to the configuration option "audio_sink"
3. restart sunshine
## Windows 10
### Requirements:
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
### Compilation:
- `git clone https://github.com/loki-47-6F-64/sunshine.git --recursive`
- `cd sunshine && mkdir build && cd build`
- `cmake -G"Unix Makefiles" ..`
- `mingw32-make`
### Setup:
- **OPTIONAL** Gamepad support: Download and run 'ViGEmBus_Setup_1.16.116.exe' from [https://github.com/ViGEm/ViGEmBus/releases]
# Common
## Usage:
- run "sunshine path/to/sunshine.conf"
- If running for the first time, make sure to note the username and password Sunshine showed to you, since you **cannot get back later**!
- In Moonlight: Add PC manually
- When Moonlight request you insert the correct pin on sunshine:
- Type in the URL bar of your browser: `https://xxx.xxx.xxx.xxx:47990` where `xxx.xxx.xxx.xxx` is the IP address of your computer
- Ignore any warning given by your browser about "insecure website"
- Type in the username and password shown the first time you run Sunshine
- Go to "PIN" in the Header
- Type in your PIN and press Enter, you should get a Success Message
- Click on one of the Applications listed
- Have fun :)
## Note:
- The Windows key is not passed through by Moonlight, therefore Sunshine maps Right-Alt key to the Windows key
- If you set Video Bitrate to 0.5Mb/s:
- Sunshine will use CRF or QP to controll the quality of the stream. (See example configuration file for more details)
- This is less CPU intensive and it has lower average bandwith requirements compared to manually setting bitrate to acceptable quality
- However, it has higher peak bitrates, forcing Sunshine to drop entire frames when streaming 1080P due to their size.
- When this happens, the video portion of the stream appears to be frozen.
- This is rare enough that using this for the desktop environment is tolerable (in my opinion), however for gaming not so much.
## Credits:
- [Simple-Web-Server](https://gitlab.com/eidheim/Simple-Web-Server)
- [Moonlight](https://github.com/moonlight-stream)
- [Looking-Glass](https://github.com/gnif/LookingGlass) (For showing me how to properly capture frames on Windows, saving me a lot of time :)
- [Eretik](http://eretik.omegahg.com/) (For creating PolicyConfig.h, allowing me to change the default audio device on Windows programmatically)
## Application List:
**Note:** You can change the Application List in the "Apps" section of the User Interface `https://xxx.xxx.xxx.xxx:47990/`
- You can use Environment variables in place of values
- $(HOME) will be replaced by the value of $HOME
- $$ will be replaced by $ --> $$(HOME) will be replaced by $(HOME)
- env: Adds or overwrites Environment variables for the commands/applications run by Sunshine.
- "Variable name":"Variable value"
- apps: The list of applications
- Example:
```json
{
"name":"An App",
"cmd":"command to open app",
"prep-cmd":[
{
"do":"some-command",
"undo":"undo-that-command"
}
],
"detached":[
"some-command",
"another-command"
]
}
```
- name: Self explanatory
- output <optional>: The file where the output of the command is stored
- If it is not specified, the output is ignored
- 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 it fails, all 'undo' commands of the previously succeeded 'do' commands are run
- undo <optional>: 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
- cmd <optional>: The main application
- If not specified, a processs is started that sleeps indefinitely
1. When an application is started, if there is an application already running, it will be terminated.
2. When the application has been shutdown, the stream shuts down as well.
3. 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.
Linux
```json
{
"env":{
"DISPLAY":":0",
"DRI_PRIME":"1",
"XAUTHORITY":"$(HOME)/.Xauthority",
"PATH":"$(PATH):$(HOME)/.local/bin"
},
"apps":[
{
"name":"Low Res Desktop",
"prep-cmd":[
{ "do":"xrandr --output HDMI-1 --mode 1920x1080", "undo":"xrandr --output HDMI-1 --mode 1920x1200" }
]
},
{
"name":"Steam BigPicture",
"output":"steam.txt",
"cmd":"steam -bigpicture",
"prep-cmd":[]
}
]
}
```
Windows
```json
{
"env":{
"PATH":"$(PATH);C:\\Program Files (x86)\\Steam"
},
"apps":[
{
"name":"Steam BigPicture",
"output":"steam.txt",
"prep-cmd":[
{"do":"steam \"steam://open/bigpicture\""}
]
}
]
}
```

67
README.rst Normal file
View File

@@ -0,0 +1,67 @@
: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/>`_.
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.
These are the advantages of Sunshine over GeForce Experience.
- FOSS (Free and Open Source Software)
- Multi-platform
- Linux
- macOS
- Windows
- Pair over web ui
- Supports AMD, Intel, and Nvidia GPUs for encoding
- Supports software encoding
- Supports streaming to multiple clients
- Web UI for configuration
Integrations
------------
.. image:: https://img.shields.io/github/workflow/status/lizardbyte/sunshine/CI/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
:alt: GitHub Workflow Status (localize)
:target: https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Anightly
.. image:: https://img.shields.io/readthedocs/sunshinestream?label=Docs&style=for-the-badge&logo=readthedocs
:alt: Read the Docs
:target: http://sunshinestream.readthedocs.io/
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=localized&style=for-the-badge&query=%24.progress..data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json&logo=crowdin
:alt: CrowdIn
: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>`_.
Downloads
---------
.. image:: https://img.shields.io/github/downloads/lizardbyte/sunshine/total?style=for-the-badge&logo=github
: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
:alt: Docker
:target: https://hub.docker.com/r/lizardbyte/sunshine

View File

@@ -1,38 +0,0 @@
image:
- Ubuntu2004
- Visual Studio 2019
environment:
matrix:
- BUILD_TYPE: Debug
- BUILD_TYPE: Release
install:
- sh: sudo apt update --ignore-missing
- sh: sudo apt install -y build-essential fakeroot gcc-10 g++-10 cmake libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev
- cmd: C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -S 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 yasm nasm diffutils make"
before_build:
- git submodule update --init --recursive
- mkdir build
- cd build
build_script:
- cmd: set OLDPATH=%PATH%
- cmd: set PATH=C:\msys64\mingw64\bin
- sh: cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSUNSHINE_EXECUTABLE_PATH=sunshine -DSUNSHINE_ASSETS_DIR=/etc/sunshine ..
- cmd: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSUNSHINE_ASSETS_DIR=assets -G "MinGW Makefiles" ..
- sh: make -j$(nproc)
- cmd: mingw32-make -j2
- cmd: set PATH=%OLDPATH%
after_build:
- sh: ./gen-deb
- cmd: Del ..\assets\apps_linux.json
- cmd: 7z a Sunshine-Windows.zip ..\assets
- cmd: 7z a Sunshine-Windows.zip sunshine.exe
- cmd: 7z a Sunshine-Windows.zip tools\dxgi-info.exe
- cmd: 7z a Sunshine-Windows.zip tools\audio-info.exe
- cmd: appveyor PushArtifact Sunshine-Windows.zip
- sh: appveyor PushArtifact package-deb/sunshine.deb
- sh: appveyor PushArtifact sunshine.service

View File

@@ -1,271 +0,0 @@
# If no external IP address is given, Sunshine will attempt to automatically detect external ip-address
# external_ip = 123.456.789.12
# Set the familly of ports used by Sunshine
# port = 47989
# The private key must be 2048 bits
# pkey = /dir/pkey.pem
# The certificate must be signed with a 2048 bit key
# cert = /dir/cert.pem
# The name displayed by Moonlight
# If not specified, the PC's hostname is used
# sunshine_name = Sunshine
# The minimum log level printed to standard out
#
# none -> no logs are printed to standard out
#
# verbose = [0]
# debug = [1]
# info = [2]
# warning = [3]
# error = [4]
# fatal = [5]
# none = [6]
#
# min_log_level = info
# The origin of the remote endpoint address that is not denied for HTTP method /pin
# Could be any of the following values:
# pc|lan|wan
# pc: Only localhost may access /pin
# lan: Only those in LAN may access /pin
# wan: Anyone may access /pin
#
# origin_pin_allowed = pc
# The origin of the remote endpoint address that is not denied for HTTPS Web UI
# Could be any of the following values:
# pc|lan|wan
# pc: Only localhost may access the Web Manager
# lan: Only those in LAN may access the Web Manager
# wan: Anyone may access the Web Manager
#
# origin_web_ui_allowed = lan
# If UPnP is enabled, Sunshine will attempt to open ports for streaming over the internet
# To enable it, uncomment the following line:
# upnp = on
# The file where current state of Sunshine is stored
# file_state = sunshine_state.json
# The file where user credentials for the UI are stored
# By default, credentials are stored in `file_state`
# credentials_file = sunshine_state.json
# The display modes advertised by Sunshine
#
# Some versions of Moonlight, such as Moonlight-nx (Switch),
# rely on this list to ensure that the requested resolutions and fps
# are supported.
#
# fps = [10, 30, 60, 90, 120]
# resolutions = [
# 352x240,
# 480x360,
# 858x480,
# 1280x720,
# 1920x1080,
# 2560x1080,
# 3440x1440,
# 1920x1200,
# 3860x2160,
# 3840x1600,
# ]
# How long to wait in milliseconds for data from moonlight before shutting down the stream
# ping_timeout = 10000
# The file where configuration for the different applications that Sunshine can run during a stream
# file_apps = apps.json
# Percentage of error correcting packets per data packet in each video frame
# Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage
# The default value of 20 is what GeForce Experience uses
#
# The value must be greater than 0 and lower than or equal to 255
# fec_percentage = 20
# When multicasting, it could be usefull to have different configurations for each connected Client.
# For example:
# Clients connected through WAN and LAN have different bitrate contstraints.
# Decoders may require different settings for color
#
# Unlike simply broadcasting to multiple Client, this will generate distinct video streams.
# Note, CPU usage increases for each distinct video stream generated
# channels = 1
# The back/select button on the controller
# On the Shield, the home and powerbutton are not passed to Moonlight
# If, after the timeout, the back button is still pressed down, Home/Guide button press is emulated.
# If back_button_timeout < 0, then the Home/Guide button will not be emulated
# back_button_timeout = 2000
# !! Windows only !!
# Control how fast keys will repeat themselves
# The initial delay in milliseconds before repeating keys
# key_repeat_delay = 500
#
# How often keys repeat every second
# This configurable option supports decimals
# key_repeat_frequency = 24.9
# The name of the audio sink used for Audio Loopback
# If you do not specify this variable, pulseaudio will select the default monitor device.
#
# You can find the name of the audio sink using the following command:
# !! Linux only !!
# pacmd list-sinks | grep "name:" if running vanilla pulseaudio
# pactl info | grep Source` if running pipewire
# audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
#
# !! Windows only !!
# tools\audio-info.exe
# audio_sink = {0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B}
#
# The virtual sink, is the audio device that's virtual (Like Steam Streaming Speakers), it allows Sunshine
# to stream audio, while muting the speakers.
# virtual_sink = {0.0.0.00000000}.{8edba70c-1125-467c-b89c-15da389bc1d4}
# !! Windows only !!
# You can select the video card you want to stream:
# The appropriate values can be found using the following command:
# tools\dxgi-info.exe
# adapter_name = Radeon RX 580 Series
# output_name = \\.\DISPLAY1
# !! Linux only !!
# Set the display number to stream.
# You can find them by the following command:
# xrandr --listmonitors
# Example output: "0: +HDMI-1 1920/518x1200/324+0+0 HDMI-1"
# ^ <-- You need this.
# output_name = 0
###############################################
# FFmpeg software encoding parameters
# Honestly, I have no idea what the optimal values would be.
# Play around with this :)
# Constant Rate Factor. Between 1 and 52. It allows QP to go up during motion and down with still image, resulting in constant perceived quality
# Higher value means more compression, but less quality
# If crf == 0, then use QP directly instead
# crf = 0
# Quantitization Parameter
# Higher value means more compression, but less quality
# If crf != 0, then this parameter is ignored
# qp = 28
# Minimum number of threads used by ffmpeg to encode the video.
# Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually
# worth it to gain the use of more CPU cores for encoding. The ideal value is the lowest
# value that can reliably encode at your desired streaming settings on your hardware.
# min_threads = 1
# Allows the client to request HEVC Main or HEVC Main10 video streams.
# HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software encoding.
# If set to 0 (default), Sunshine will specify support for HEVC based on encoder
# If set to 1, Sunshine will not advertise support for HEVC
# If set to 2, Sunshine will advertise support for HEVC Main profile
# If set to 3, Sunshine will advertise support for HEVC Main and Main10 (HDR) profiles
# hevc_mode = 2
# Force a specific encoder, otherwise Sunshine will use the first encoder that is available
# supported encoders:
# nvenc
# amdvce # NOTE: alpha stage. The cursor is not yet displayed
# software
#
# encoder = nvenc
##################################### Software #####################################
# See x264 --fullhelp for the different presets
# sw_preset = superfast
# sw_tune = zerolatency
#
##################################### NVENC #####################################
###### presets ###########
# default
# hp -- high performance
# hq -- high quality
# slow -- hq 2 passes
# medium -- hq 1 pass
# fast -- hp 1 pass
# bd
# ll -- low latency
# llhq
# llhp
# lossless
# losslesshp
##########################
# nv_preset = llhq
#
####### rate control #####
# auto -- let ffmpeg decide rate control
# constqp -- constant QP mode
# vbr -- variable bitrate
# cbr -- constant bitrate
# cbr_hq -- cbr high quality
# cbr_ld_hq -- cbr low delay high quality
# vbr_hq -- vbr high quality
##########################
# nv_rc = auto
###### h264 entropy ######
# auto -- let ffmpeg nvenc decide the entropy encoding
# cabac
# cavlc
##########################
# nv_coder = auto
##################################### AMD #####################################
###### presets ###########
# default
# speed
# balanced
##########################
# amd_preset = balanced
#
####### rate control #####
# auto -- let ffmpeg decide rate control
# constqp -- constant QP mode
# vbr_latency -- Latency Constrained Variable Bitrate
# vbr_peak -- Peak Contrained Variable Bitrate
# cbr -- constant bitrate
##########################
# amd_rc = auto
###### h264 entropy ######
# auto -- let ffmpeg nvenc decide the entropy encoding
# cabac
# cavlc
##########################
# amd_coder = auto
#################################### VAAPI ###################################
####### adapter ##########
# Unlike with `amdvce` and `nvenc`, it doesn't matter if video encoding is done
# on a different GPU.
# Run the following commands:
# 1. ls /dev/dri/renderD*
# to find all devices capable of VAAPI
# 2. vainfo --display drm --device /dev/dri/renderD129 | grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version"
# Lists the name and capabilities of the device.
# To be supported by Sunshine, it needs to have at the very minimum:
# VAProfileH264High : VAEntrypointEncSlice
# adapter_name = /dev/dri/renderD128
##############################################
# Some configurable parameters, are merely toggles for specific features
# The first occurrence turns it on, the second occurence turns it off, the third occurence turns it on again, etc, etc
# Here, you change the default state of any flag
#
# To set the initial state of flags -0 and -1 to on, set the following flags:
# flags = 012
#
# See: sunshine --help for all options under the header: flags

View File

@@ -1,162 +0,0 @@
<div id="app" class="container">
<div class="my-4">
<h1>Applications</h1>
<div>Applications are refreshed only when Client is restarted</div>
</div>
<div class="card p-4">
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(app,i) in apps" :key="i">
<td>{{app.name}}</td>
<td><button class="btn btn-primary" @click="editApp(i)">Edit</button>
<button class="btn btn-danger" @click="showDeleteForm(i)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="edit-form card mt-2" v-if="showEditForm">
<div class="p-4">
<!--name-->
<div class="mb-3">
<label for="appName" class="form-label">Application Name</label>
<input type="text" class="form-control" id="appName" aria-describedby="appNameHelp" v-model="editForm.name">
<div id="appNameHelp" class="form-text">Application Name, as shown on Moonlight</div>
</div>
<!--output-->
<div class="mb-3">
<label for="appOutput" class="form-label">Output</label>
<input type="text" class="form-control monospace" id="appOutput" aria-describedby="appOutputHelp"
v-model="editForm.output">
<div id="appOutputHelp" class="form-text">The file where the output of the command is stored, if it is not
specified, the output is ignored</div>
</div>
<!--prep-cmd-->
<div class="mb-3 d-flex flex-column">
<label for="appName" class="form-label">Command Preparations</label>
<div class="form-text">A list of commands to be run before/after the application. <br> If any of the
prep-commands fail, starting the application is aborted</div>
<table v-if="editForm['prep-cmd'].length > 0">
<thead>
<th class="precmd-head">Do</th>
<th class="precmd-head">Undo</th>
<th style="width: 48px;"></th>
</thead>
<tbody>
<tr v-for="(c,i) in editForm['prep-cmd']">
<td><input type="text" class="form-control monospace" v-model="c.do"></td>
<td><input type="text" class="form-control monospace" v-model="c.undo"></td>
<td><button class="btn btn-danger" @click="editForm['prep-cmd'].splice(i,1)">&times;</button></td>
</tr>
</tbody>
</table>
<button class="mt-2 btn btn-success" style="margin: 0 auto;" @click="addPrepCmd">&plus; Add</button>
</div>
<!--detatched-->
<div class="mb-3">
<label for="appName" class="form-label">Detached Commands</label>
<div v-for="(c,i) in editForm.detached" class="d-flex justify-content-between my-2">
<pre>{{c}}</pre>
<button class="btn btn-danger mx-2" @click="editForm.detached.splice(i,1)">&times;</button>
</div>
<div class="d-flex justify-content-between">
<input type="text" class="form-control monospace" v-model="detachedCmd">
<button class="btn btn-success mx-2" @click="editForm.detached.push(detachedCmd);detachedCmd = '';">+</button>
</div>
<div class="form-text">A list of commands to be run and forgotten about</div>
</div>
<!--command-->
<div class="mb-3">
<label for="appCmd" class="form-label">Command</label>
<input type="text" class="form-control monospace" id="appCmd" aria-describedby="appCmdHelp"
v-model="editForm.cmd">
<div id="appCmdHelp" class="form-text">The main application, if it is not specified, a processs is started that
sleeps indefinitely</div>
</div>
<!--buttons-->
<div class="d-flex">
<button @click="showEditForm = false" class="btn btn-secondary m-2">Cancel</button>
<button class="btn btn-primary m-2" @click="save">Save</button>
</div>
</div>
</div>
<div class="mt-2" v-else>
<button class="btn btn-primary" @click="newApp">+ Add New</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
apps: [],
showEditForm: false,
editForm: null,
detachedCmd: '',
}
},
created() {
fetch("/api/apps").then(r => r.json()).then((r) => {
console.log(r);
this.apps = r.apps;
})
},
methods: {
newApp() {
this.editForm = {
name: '',
output: '',
cmd: [],
index: -1,
"prep-cmd": [],
"detached": []
};
this.editForm.index = -1;
this.showEditForm = true;
},
editApp(id) {
this.editForm = JSON.parse(JSON.stringify(this.apps[id]));
this.$set(this.editForm, "index", id);
if (this.editForm["prep-cmd"] === undefined) this.$set(this.editForm, "prep-cmd", []);
if (this.editForm["detached"] === undefined) this.$set(this.editForm, "detached", []);
this.showEditForm = true;
},
showDeleteForm(id) {
let resp = confirm("Are you sure to delete " + this.apps[id].name + "?");
if (resp) {
fetch("/api/apps/" + id, { method: "DELETE" }).then((r) => {
if (r.status == 200) document.location.reload();
});
}
},
addPrepCmd() {
this.editForm['prep-cmd'].push({
do: '',
undo: '',
});
},
save() {
fetch("/api/apps", { method: "POST", body: JSON.stringify(this.editForm) }).then((r) => {
if (r.status == 200) document.location.reload();
});
}
}
})
</script>
<style>
.precmd-head {
width: 200px;
}
.monospace {
font-family: monospace;
}
</style>

View File

@@ -1,592 +0,0 @@
<div id="app" class="container">
<h1 class="my-4">Configuration</h1>
<div class="form" v-if="config">
<!--Header-->
<ul class="nav nav-tabs">
<li class="nav-item" v-for="tab in tabs" :key="tab.id">
<a class="nav-link" :class="{'active': tab.id === currentTab}" href="#"
@click="currentTab = tab.id">{{tab.name}}</a>
</li>
</ul>
<!--General Tab-->
<div v-if="currentTab === 'general'" class="config-page">
<!--Sunshine Name-->
<div class="mb-3">
<label for="sunshine_name" class="form-label">Sunshine Name</label>
<input type="text" class="form-control" id="sunshine_name" placeholder="Sunshine"
v-model="config.sunshine_name">
<div class="form-text">The name displayed by Moonlight. If not specified, the PC's hostname is used
</div>
</div>
<!--Log Level-->
<div class="mb-3">
<label for="min_log_level" class="form-label">Log Level</label>
<select id="min_log_level" class="form-select" v-model="config.min_log_level">
<option :value="0">Verbose</option>
<option :value="1">Debug</option>
<option :value="2">Info</option>
<option :value="3">Warning</option>
<option :value="4">Error</option>
<option :value="5">Fatal</option>
<option :value="6">None</option>
</select>
<div class="form-text">The minimum log level printed to standard out</div>
</div>
<!--Origin Web UI Allowed-->
<div class="mb-3">
<label for="origin_web_ui_allowed" class="form-label">Origin Web UI Allowed</label>
<select id="origin_web_ui_allowed" class="form-select" v-model="config.origin_web_ui_allowed">
<option value="pc">Only localhost may access Web UI</option>
<option value="lan">Only those in LAN may access Web UI</option>
<option value="wan">Anyone may access Web UI</option>
</select>
<div class="form-text">The origin of the remote endpoint address that is not denied access to Web UI
</div>
</div>
<!--UPnP-->
<div class="mb-3">
<label for="upnp" class="form-label">UPnP</label>
<select id="upnp" class="form-select" v-model="config.upnp">
<option value="disabled">Disabled</option>
<option value="enabled">Enabled</option>
</select>
<div class="form-text">Automatically configure port forwarding</div>
</div>
<!--Ping Timeout-->
<div class="mb-3">
<label for="ping_timeout" class="form-label">Ping Timeout</label>
<input type="text" class="form-control" id="ping_timeout" placeholder="10000"
v-model="config.ping_timeout">
<div class="form-text">How long to wait in milliseconds for data from moonlight before shutting down the
stream</div>
</div>
<!--Advertised FPS and Resolutions-->
<div class="mb-3">
<label for="ping_timeout" class="form-label">Advertised Resolutions and FPS</label>
<div class="resolutions-container">
<label>Resolutions</label>
<div class="resolutions d-flex flex-wrap">
<div class="p-2 ms-item m-2 d-flex justify-content-between" v-for="(r,i) in resolutions"
:key="r">
<span class="px-2">{{r}}</span>
<span style="cursor: pointer;" @click="resolutions.splice(i,1)">&times;</span>
</div>
<form @submit.prevent="resolutions.push(resIn);resIn = '';" class="d-flex align-items-center">
<input type="text" v-model="resIn" required pattern="[0-9]+x[0-9]+"
style="border-top-right-radius: 0;border-bottom-right-radius: 0;" class="form-control">
<button style="border-top-left-radius: 0;border-bottom-left-radius: 0;"
class="btn btn-success">+</button>
</form>
</div>
</div>
<div class="fps-container">
<label>FPS</label>
<div class="fps d-flex flex-wrap">
<div class="p-2 ms-item m-2 d-flex justify-content-between" v-for="(f,i) in fps" :key="f">
<span class="px-2">{{f}}</span>
<span style="cursor: pointer;" @click="fps.splice(i,1)">&times;</span>
</div>
<form @submit.prevent="fps.push(fpsIn);fpsIn = '';" class="d-flex align-items-center">
<input type="text" v-model="fpsIn" required pattern="[0-9]+"
style="width: 6ch;border-top-right-radius: 0;border-bottom-right-radius: 0;"
class="form-control">
<button style="border-top-left-radius: 0;border-bottom-left-radius: 0;"
class="btn btn-success">+</button>
</form>
</div>
</div>
<div class="form-text">
The display modes advertised by Sunshine<br>
Some versions of Moonlight, such as Moonlight-nx (Switch),
rely on this list to ensure that the requested resolutions and fps
are supported.
</div>
</div>
</div>
<!--Files Tab-->
<div v-if="currentTab === 'files'" class="config-page">
<!--Private Key-->
<div class="mb-3">
<label for="pkey" class="form-label">Private Key</label>
<input type="text" class="form-control" id="pkey" placeholder="/dir/pkey.pem" v-model="config.pkey">
<div class="form-text">The private key must be 2048 bits</div>
</div>
<!--Cert-->
<div class="mb-3">
<label for="cert" class="form-label">Cert</label>
<input type="text" class="form-control" id="cert" placeholder="/dir/cert.pem" v-model="config.cert">
<div class="form-text">The certificate must be signed with a 2048 bit key</div>
</div>
<!--State File-->
<div class="mb-3">
<label for="file_state" class="form-label">State File</label>
<input type="text" class="form-control" id="file_state" placeholder="sunshine_state.json"
v-model="config.file_state">
<div class="form-text">The file where current state of Sunshine is stored</div>
</div>
<!--Apps File-->
<div class="mb-3">
<label for="file_apps" class="form-label">Apps File</label>
<input type="text" class="form-control" id="file_apps" placeholder="apps.json"
v-model="config.file_apps">
<div class="form-text">The file where current apps of Sunshine are stored</div>
</div>
</div>
<div v-if="currentTab === 'input'" class="config-page">
<!--Back Button Timeout-->
<div class="mb-3">
<label for="back_button_timeout" class="form-label">Back Button Timeout</label>
<input type="text" class="form-control" id="back_button_timeout" placeholder="2000"
v-model="config.back_button_timeout">
<div class="form-text">
The back/select button on the controller.<br>
On the Shield, the home and powerbutton are not passed to Moonlight.<br>
If, after the timeout, the back button is still pressed down, Home/Guide button press is
emulated.<br>
If back_button_timeout &lt; 0, then the Home/Guide button will not be emulated<br>
</div>
</div>
<!-- Key Repeat Delay-->
<div class="mb-3" v-if="platform === 'windows'">
<label for="key_repeat_delay" class="form-label">Key Repeat Delay</label>
<input type="text" class="form-control" id="key_repeat_delay" placeholder="500"
v-model="config.key_repeat_delay">
<div class="form-text">
Control how fast keys will repeat themselves<br>
The initial delay in milliseconds before repeating keys
</div>
</div>
<!-- Key Repeat Frequency-->
<div class="mb-3" v-if="platform === 'windows'">
<label for="key_repeat_frequency" class="form-label">Key Repeat Frequency</label>
<input type="text" class="form-control" id="key_repeat_frequency" placeholder="24.9"
v-model="config.key_repeat_frequency">
<div class="form-text">
How often keys repeat every second<br>
This configurable option supports decimals
</div>
</div>
</div>
<!--Files Tab-->
<div v-if="currentTab === 'av'" class="config-page">
<!--Audio Sink-->
<div class="mb-3" v-if="platform === 'windows'">
<label for="audio_sink" class="form-label">Audio Sink</label>
<input type="text" class="form-control" id="audio_sink"
placeholder="{0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B}" v-model="config.audio_sink">
<div class="form-text">
The name of the audio sink used for Audio Loopback<br>
You can find the name of the audio sink using the following command:<br>
<pre>tools\audio-info.exe</pre>
</div>
</div>
<div class="mb-3" v-if="platform === 'linux'">
<label for="audio_sink" class="form-label">Audio Sink</label>
<input type="text" class="form-control" id="audio_sink"
placeholder="alsa_output.pci-0000_09_00.3.analog-stereo" v-model="config.audio_sink">
<div class="form-text">
The name of the audio sink used for Audio Loopback<br>
If you do not specify this variable, pulseaudio will select the default monitor device.<br>
<br>
You can find the name of the audio sink using either command:<br>
<pre>pacmd list-sinks | grep "name:"</pre>
<pre>pactl info | grep Source</pre><br>
</div>
</div>
<!--Virtual Sink-->
<div class="mb-3" v-if="platform === 'windows'">
<label for="virtual_sink" class="form-label">Virtual Sink</label>
<input type="text" class="form-control" id="virtual_sink"
placeholder="{0.0.0.00000000}.{8edba70c-1125-467c-b89c-15da389bc1d4}" v-model="config.virtual_sink">
<div class="form-text">
The virtual sink, is the audio device that's virtual (Like Steam Streaming Speakers), it allows
Sunshine
to stream audio, while muting the speakers.
</div>
</div>
<!--Adapter Name -->
<div class="mb-3" v-if="platform === 'windows'">
<label for="adapter_name" class="form-label">Adapter Name</label>
<input type="text" class="form-control" id="adapter_name" placeholder="Radeon RX 580 Series"
v-model="config.adapter_name">
<div class="form-text" v-if="platform === 'windows'">
You can select the video card you want to stream:<br>
The appropriate values can be found using the following command:<br>
<pre>tools\dxgi-info.exe</pre>
</div>
</div>
<!--Output Name -->
<div class="mb-3" class="config-page" v-if="platform === 'windows'">
<label for="output_name" class="form-label">Output Name</label>
<input type="text" class="form-control" id="output_name" placeholder="\\.\DISPLAY1"
v-model="config.output_name">
<div class="form-text">
You can select the video card you want to stream:<br>
The appropriate values can be found using the following command:<br>
tools\dxgi-info.exe<br><br>
</div>
</div>
<div class="mb-3" class="config-page" v-if="platform === 'linux'">
<label for="output_name" class="form-label">Monitor number</label>
<input type="text" class="form-control" id="output_name" placeholder="0" v-model="config.output_name">
<div class="form-text">
xrandr --listmonitors<br>
Example output:
<pre> 0: +HDMI-1 1920/518x1200/324+0+0 HDMI-1</pre>
</div>
</div>
</div>
<div v-if="currentTab === 'advanced'" class="config-page">
<!--Port familly-->
<div class="mb-3">
<label for="port" class="form-label">Port</label>
<input type="number" min="0" max="65529" class="form-control" id="port" placeholder="47989"
v-model="config.port">
<div class="form-text">
Set the familly of ports used by Sunshine
</div>
</div>
<!--Constant Rate Factor-->
<div class="mb-3">
<label for="crf" class="form-label">Constant Rate Factor</label>
<input type="number" min="0" max="52" class="form-control" id="crf" placeholder="0"
v-model="config.crf">
<div class="form-text">
Constant Rate Factor. Between 1 and 52. It allows QP to go up during motion and down with still
image,
resulting in constant perceived quality<br>
Higher value means more compression, but less quality<br>
If crf == 0, then use QP directly instead
</div>
</div>
<!-- Quantization Parameter -->
<div class="mb-3">
<label for="qp" class="form-label">Quantitization Parameter</label>
<input type="number" class="form-control" id="qp" placeholder="28" v-model="config.qp">
<div class="form-text">
Quantitization Parameter<br>
Higher value means more compression, but less quality<br>
If crf != 0, then this parameter is ignored
</div>
</div>
<!-- Min Threads -->
<div class="mb-3">
<label for="min_threads" class="form-label">Minimum number of threads used by ffmpeg to encode the
video.</label>
<input type="number" min="1" class="form-control" id="min_threads" placeholder="1"
v-model="config.min_threads">
<div class="form-text">
Minimum number of threads used by ffmpeg to encode the video.<br>
Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually<br>
worth it to gain the use of more CPU cores for encoding. The ideal value is the lowest<br>
value that can reliably encode at your desired streaming settings on your hardware.
</div>
</div>
<!--HEVC Suppport -->
<div class="mb-3">
<label for="hevc_mode" class="form-label">HEVC Support</label>
<select id="hevc_mode" class="form-select" v-model="config.hevc_mode">
<option value="0">Sunshine will specify support for HEVC based on encoder</option>
<option value="1">Sunshine will not advertise support for HEVC</option>
<option value="2">Sunshine will advertise support for HEVC Main profile</option>
<option value="3">Sunshine will advertise support for HEVC Main and Main10 (HDR) profiles
</option>
</select>
<div class="form-text">
Allows the client to request HEVC Main or HEVC Main10 video streams.<br>
HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using
software
encoding.
</div>
</div>
<!--Encoder -->
<div class="mb-3">
<label for="encoder" class="form-label">Force a Specific Encoder</label>
<select id="encoder" class="form-select" v-model="config.encoder">
<option :value="''">Autodetect</option>
<option value="nvenc">nVidia NVENC</option>
<option value="amdvce">AMD AMF/VCE</option>
<option value="vaapi">VA-API</option>
<option value="software">Software</option>
</select>
<div class="form-text">
Force a specific encoder, otherwise Sunshine will use the first encoder that is available
</div>
</div>
<!--FEC Percentage-->
<div class="mb-3">
<label for="fec_percentage" class="form-label">FEC Percentage</label>
<input type="text" class="form-control" id="fec_percentage" placeholder="20"
v-model="config.fec_percentage">
<div class="form-text">
Percentage of error correcting packets per data packet in each video frame.<br>
Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage.<br>
The default value of 20 is what GeForce Experience uses.
</div>
</div>
<!--Channels-->
<div class="mb-3">
<label for="channels" class="form-label">Channels</label>
<input type="text" class="form-control" id="channels" placeholder="1" v-model="config.channels">
<div class="form-text">
When multicasting, it could be useful to have different configurations for each connected
Client.
For example:
<ul>
<li>Clients connected through WAN and LAN have different bitrate contstraints.</li>
<li>Decoders may require different settings for color</li>
</ul>
Unlike simply broadcasting to multiple Client, this will generate distinct video streams.<br>
Note, CPU usage increases for each distinct video stream generated
</div>
</div>
<!--Credentials File-->
<div class="mb-3">
<label for="credentials_file" class="form-label">Web Manager Credentials File</label>
<input type="text" class="form-control" id="credentials_file" placeholder="sunshine_state.json"
v-model="config.credentials_file">
<div class="form-text">
Store Username/Password seperately from Sunshine's state file.
</div>
</div>
<!--Origin PIN Allowed-->
<div class="mb-3">
<label for="origin_pin_allowed" class="form-label">Origin PIN Allowed</label>
<select id="origin_pin_allowed" class="form-select" v-model="config.origin_pin_allowed">
<option value="pc">Only localhost may access /pin</option>
<option value="lan">Only those in LAN may access /pin</option>
<option value="wan">Anyone may access /pin</option>
</select>
<div class="form-text">The origin of the remote endpoint address that is not denied for HTTP method /pin
</div>
</div>
<!--External IP-->
<div class="mb-3">
<label for="external_ip" class="form-label">External IP</label>
<input type="text" class="form-control" id="external_ip" placeholder="123.456.789.12"
v-model="config.external_ip">
<div class="form-text">If no external IP address is given, Sunshine will automatically detect external
IP</div>
</div>
</div>
<!--Software Settings-->
<div v-if="currentTab === 'sw'" class="config-page">
<div class="mb-3">
<label for="sw_preset" class="form-label">SW Presets</label>
<input class="form-control" id="sw_preset" placeholder="superfast" v-model="config.sw_preset">
</div>
<div class="mb-3">
<label for="sw_tune" class="form-label">SW Tune</label>
<input class="form-control" id="sw_tune" placeholder="zerolatency" v-model="config.sw_tune">
</div>
</div>
<!--Nvidia Encoder Settings-->
<div v-if="currentTab === 'nv'" class="config-page">
<!--NVENC SETTINGS-->
<div class="mb-3">
<label for="nv_preset" class="form-label">NVEnc Preset</label>
<select id="nv_preset" class="form-select" v-model="config.nv_preset">
<option value="default">Default</option>
<option value="hp">High Performance</option>
<option value="hq">High Quality</option>
<option value="slow">Slow - hq 2 passes</option>
<option value="medium">medium -- hq 1 pass</option>
<option value="fast">fast -- hp 1 pass</option>
<option value="bd">bd</option>
<option value="ll">ll -- low latency</option>
<option value="llhq">llhq</option>
<option value="llhp">llhp</option>
<option value="lossless">lossless</option>
<option value="losslesshp">losslesshp</option>
</select>
</div>
<div class="mb-3">
<label for="nv_rc" class="form-label">NVEnc Rate Control</label>
<select id="nv_rc" class="form-select" v-model="config.nv_rc">
<option value="auto">auto -- let ffmpeg decide rate control</option>
<option value="constqp">constqp -- constant QP mode</option>
<option value="vbr">vbr -- variable bitrate</option>
<option value="cbr">cbr -- constant bitrate</option>
<option value="cbr_hq">cbr_hq -- cbr high quality</option>
<option value="cbr_ld_hq">cbr_ld_hq -- cbr low delay high quality</option>
<option value="vbr_hq">vbr_hq -- vbr high quality</option>
</select>
</div>
<div class="mb-3">
<label for="nv_coder" class="form-label">NVEnc Coder</label>
<select id="nv_coder" class="form-select" v-model="config.nv_coder">
<option value="auto">auto</option>
<option value="cabac">cabac</option>
<option value="cavlc">cavlc</option>
</select>
</div>
</div>
<!--AMD Encoder Settings-->
<div v-if="currentTab === 'amd'" class="config-page">
<!--Presets-->
<div class="mb-3">
<label for="amd_quality" class="form-label">AMD AMF Quality</label>
<select id="amd_quality" class="form-select" v-model="config.amd_quality">
<option value="default">Default</option>
<option value="speed">Speed</option>
<option value="balanced">Balanced</option>
</select>
</div>
<div class="mb-3">
<label for="amd_rc" class="form-label">AMD AMF Rate Control</label>
<select id="amd_rc" class="form-select" v-model="config.amd_rc">
<option value="auto">auto -- let ffmpeg decide rate control</option>
<option value="constqp">constqp -- constant QP mode</option>
<option value="vbr_latency">vbr_latency -- Latency Constrained Variable Bitrate</option>
<option value="vbr_peak">vbr_peak -- Peak Contrained Variable Bitrate</option>
<option value="cbr">cbr -- constant bitrate</option>
</select>
</div>
<div class="mb-3">
<label for="amd_coder" class="form-label">AMD AMF Rate Control</label>
<select id="amd_coder" class="form-select" v-model="config.amd_coder">
<option value="auto">auto</option>
<option value="cabac">cabac</option>
<option value="cavlc">cavlc</option>
</select>
</div>
</div>
<div v-if="currentTab === 'va-api'" class="config-page">
<input class="form-control" id="adapter_name" placeholder="/dev/dri/renderD128"
v-model="config.adapter_name">
</div>
</div>
<div class="alert alert-success my-4" v-if="success"><b>Success!</b> Restart Sunshine to apply changes</div>
<div class="mb-3 buttons">
<button class="btn btn-primary" @click="save">Save</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
platform: '',
success: false,
config: null,
fps: [],
resolutions: [],
currentTab: 'general',
resIn: '',
fpsIn: '',
tabs: [{
id: 'general',
name: "General"
},
{
id: 'files',
name: "Files"
},
{
id: 'input',
name: "Input"
},
{
id: 'av',
name: "Audio/Video"
},
{
id: 'advanced',
name: "Advanced"
},
{
id: "sw",
name: "Software Encoder"
},
{
id: "nv",
name: "NVENC Encoder"
},
{
id: "amd",
name: "AMF Encoder"
},
{
id: "va-api",
name: "VA-API encoder"
}
]
}
},
created() {
fetch("/api/config").then(r => r.json()).then((r) => {
this.config = r;
this.platform = this.config.platform;
var app = document.getElementById("app");
if (this.platform == "windows") {
this.tabs = this.tabs.filter(el => {
return el.id !== "va-api";
});
}
if (this.platform == "linux") {
this.tabs = this.tabs.filter(el => {
return el.id !== "amd";
});
}
delete this.config.status;
delete this.config.platform;
//Populate default values if not present in config
this.config.upnp = this.config.upnp || 'disabled';
this.config.min_log_level = this.config.min_log_level || 2;
this.config.origin_pin_allowed = this.config.origin_pin_allowed || "pc";
this.config.origin_web_ui_allowed = this.config.origin_web_manager_allowed || "lan";
this.config.hevc_mode = this.config.hevc_mode || 0;
this.config.encoder = this.config.encoder || '';
this.config.nv_preset = this.config.nv_preset || 'default';
this.config.nv_rc = this.config.nv_rc || 'auto';
this.config.nv_coder = this.config.nv_coder || 'auto';
this.config.amd_quality = this.config.amd_quality || 'default';
this.config.amd_rc = this.config.amd_rc || 'auto';
this.config.fps = this.config.fps || '[10, 30, 60, 90, 120]';
this.config.resolutions = this.config.resolutions || '[352x240,480x360,858x480,1280x720,1920x1080,2560x1080,3440x1440,1920x1200,3860x2160,3840x1600]';
this.fps = JSON.parse(this.config.fps);
//Resolutions should be fixed because are not valid JSON
let res = this.config.resolutions.substring(1, this.config.resolutions.length - 1);
let resolutions = [];
res.split(",").forEach(r => resolutions.push(r.trim()));
this.resolutions = resolutions;
})
},
methods: {
save() {
this.success = false;
let nl = this.config === 'windows' ? "\r\n" : "\n";
this.config.resolutions = "[" + nl + " " + this.resolutions.join("," + nl + " ") + nl + "]";
this.config.fps = JSON.stringify(this.fps);
fetch("/api/config", {
method: "POST",
body: JSON.stringify(this.config)
}).then((r) => {
if (r.status == 200) this.success = true;
});
}
}
})
</script>
<style>
.config-page {
padding: 1em;
border: 1px solid #dee2e6;
border-top: none;
}
.buttons {
padding: 1em 0;
}
.ms-item {
background-color: #CCC;
font-size: 12px;
font-weight: bold;
}
</style>

View File

@@ -1,45 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sunshine</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #ffc400;">
<div class="container-fluid">
<span class="navbar-brand">Sunshine</span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/pin">PIN</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/apps">Applications</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config">Configuration</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/password">Change Password</a>
</li>
</ul>
</div>
</nav>

View File

@@ -1,9 +0,0 @@
<div id="content" class="container">
<div class="row">
<div class="col-md-6 py-4" style="margin: 0 auto;">
<h1>Hello, Sunshine!</h1>
<p>Sunshine is a Gamestream host for Moonlight</p>
<a href="https://github.com/loki-47-6F-64/sunshine">Official GitHub Repository</a>
</div>
</div>
</div>

View File

@@ -1,97 +0,0 @@
<div id="app" class="container">
<h1 class="my-4">Password Change</h1>
<form @submit.prevent="save">
<div class="card d-flex p-4 flex-row">
<div class="col-md-6 px-4">
<h4>Current Credentials</h4>
<div class="mb-3">
<label for="currentUsername" class="form-label">Username</label>
<input required type="text" class="form-control" id="currentUsername" v-model="passwordData.currentUsername">
<div class="form-text">&nbsp;</div>
</div>
<div class="mb-3">
<label for="currentPassword" class="form-label">Password</label>
<input autocomplete="current-password" type="password" class="form-control" id="currentPassword" v-model="passwordData.currentPassword">
</div>
</div>
<div class="col-md-6 px-4">
<h4>New Credentials</h4>
<div class="mb-3">
<label for="newUsername" class="form-label">New Username</label>
<input type="text" class="form-control" id="newUsername" v-model="passwordData.newUsername">
<div class="form-text">If not specified, the username will not change
</div>
</div>
<div class="mb-3">
<label for="newPassword" class="form-label">Password</label>
<input autocomplete="new-password" required type="password" class="form-control" id="newPassword" v-model="passwordData.newPassword">
</div>
<div class="mb-3">
<label for="confirmNewPassword" class="form-label">Confirm Password</label>
<input autocomplete="new-password" required type="password" class="form-control" id="confirmNewPassword" v-model="passwordData.confirmNewPassword">
</div>
</div>
</div>
<div class="alert alert-danger" v-if="error"><b>Error: </b>{{error}}</div>
<div class="alert alert-success" v-if="success"><b>Success! </b>This page will reload soon, your browser will ask you for the new credentials</div>
<div class="mb-3 buttons">
<button class="btn btn-primary">Save</button>
</div>
</form>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
error: null,
success: false,
passwordData: {
currentUsername: '',
currentPassword: '',
newUsername: '',
newPassword: '',
confirmNewPassword: ''
}
}
},
methods: {
save() {
this.error = null;
fetch("/api/password", {
method: "POST",
body: JSON.stringify(this.passwordData)
}).then((r) => {
if (r.status == 200){
r.json().then((rj) => {
if(rj.status.toString() === "true"){
this.success = true;
setTimeout(()=>{
document.location.reload();
},5000);
} else {
this.error = rj.error;
}
})
}
else {
this.error = "Internal Server Error"
}
});
}
}
})
</script>
<style>
.config-page {
padding: 1em;
border: 1px solid #dee2e6;
border-top: none;
}
.buttons {
padding: 1em 0;
}
</style>

View File

@@ -1,31 +0,0 @@
<div id="content" class="container">
<h1 class="my-4">PIN Pairing</h1>
<form action="" class="form d-flex flex-column align-items-center" id="form">
<div class="card flex-column d-flex p-4 mb-4">
<input type="number" placeholder="PIN" id="pin-input" class="form-control my-4">
<button class="btn btn-primary">Send</button>
</div>
<div class="alert alert-warning">
<b>Warning!</b> Make sure you have access to the client you are pairing with.<br>
This software can give total control to your computer, so be careful!
</div>
<div id="status"></div>
</form>
</div>
<script>
document.querySelector("#form").addEventListener("submit", (e) => {
e.preventDefault();
let pin = document.querySelector("#pin-input").value;
document.querySelector("#status").innerHTML = "";
let b = JSON.stringify({pin: pin});
fetch("/api/pin",{method: "POST",body: b}).then((response) => response.json()).then((response)=>{
if(response.status){
document.querySelector("#status").innerHTML = `<div class="alert alert-success" role="alert">Success! Please check Moonlight to continue</div>`;
} else {
document.querySelector("#status").innerHTML = `<div class="alert alert-danger" role="alert">PIN does not match, please check if it's typed correctly</div>`;
}
})
})
</script>

21
cmake/FindLIBCAP.cmake Normal file
View File

@@ -0,0 +1,21 @@
# - Try to find Libcap
# Once done this will define
#
# LIBCAP_FOUND - system has Libcap
# LIBCAP_INCLUDE_DIRS - the Libcap include directory
# LIBCAP_LIBRARIES - the libraries needed to use Libcap
# LIBCAP_DEFINITIONS - Compiler switches required for using Libcap
# 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(PC_LIBCAP libcap)
set(LIBCAP_DEFINITIONS ${PC_LIBCAP_CFLAGS})
find_path(LIBCAP_INCLUDE_DIRS sys/capability.h PATHS ${PC_LIBCAP_INCLUDEDIR} ${PC_LIBCAP_INCLUDE_DIRS})
find_library(LIBCAP_LIBRARIES NAMES libcap.so PATHS ${PC_LIBCAP_LIBDIR} ${PC_LIBCAP_LIBRARY_DIRS})
mark_as_advanced(LIBCAP_INCLUDE_DIRS LIBCAP_LIBRARIES)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBCAP REQUIRED_VARS LIBCAP_LIBRARIES LIBCAP_INCLUDE_DIRS)

21
cmake/FindLIBDRM.cmake Normal file
View File

@@ -0,0 +1,21 @@
# - Try to find Libdrm
# Once done this will define
#
# LIBDRM_FOUND - system has Libdrm
# LIBDRM_INCLUDE_DIRS - the Libdrm include directory
# LIBDRM_LIBRARIES - the libraries needed to use Libdrm
# LIBDRM_DEFINITIONS - Compiler switches required for using Libdrm
# 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(PC_LIBDRM libdrm)
set(LIBDRM_DEFINITIONS ${PC_LIBDRM_CFLAGS})
find_path(LIBDRM_INCLUDE_DIRS drm.h PATHS ${PC_LIBDRM_INCLUDEDIR} ${PC_LIBDRM_INCLUDE_DIRS} PATH_SUFFIXES libdrm)
find_library(LIBDRM_LIBRARIES NAMES libdrm.so PATHS ${PC_LIBDRM_LIBDIR} ${PC_LIBDRM_LIBRARY_DIRS})
mark_as_advanced(LIBDRM_INCLUDE_DIRS LIBDRM_LIBRARIES)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBDRM REQUIRED_VARS LIBDRM_LIBRARIES LIBDRM_INCLUDE_DIRS)

78
cmake/FindWayland.cmake Normal file
View File

@@ -0,0 +1,78 @@
# Try to find Wayland on a Unix system
#
# This will define:
#
# WAYLAND_FOUND - True if Wayland is found
# WAYLAND_LIBRARIES - Link these to use Wayland
# WAYLAND_INCLUDE_DIRS - Include directory for Wayland
# WAYLAND_DEFINITIONS - Compiler flags for using Wayland
#
# In addition the following more fine grained variables will be defined:
#
# Wayland_Client_FOUND WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES
# Wayland_Server_FOUND WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES
# Wayland_EGL_FOUND WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES
# Wayland_Cursor_FOUND WAYLAND_CURSOR_INCLUDE_DIRS WAYLAND_CURSOR_LIBRARIES
#
# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
# 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
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)
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_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_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_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)
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)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Wayland REQUIRED_VARS WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS HANDLE_COMPONENTS)
ENDIF ()

22
crowdin.yml Normal file
View File

@@ -0,0 +1,22 @@
---
"base_path": "."
"base_url": "https://api.crowdin.com" # optional (for Crowdin Enterprise only)
"preserve_hierarchy": false # flatten tree on crowdin
"pull_request_labels": [
"crowdin",
"l10n"
]
"files": [
{
"source": "/locale/*.po",
"translation": "/locale/%two_letters_code%/LC_MESSAGES/%original_file_name%",
"languages_mapping": {
"two_letters_code": {
# map non-two letter codes here, left side is crowdin designation, right side is babel designation
"en-GB": "en_GB",
"en-US": "en_US"
}
}
}
]

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

35
docs/make.bat Normal file
View File

@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,160 @@
: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`_.
Binaries
--------
Binaries of Sunshine are created for each release. They are available for Linux, and Windows.
Binaries can be found in the `latest release`_.
.. Tip:: Some third party packages also exist. See
:ref:`Third Party Packages <about/third_party_packages:third party packages>`.
Docker
------
.. Todo:: Docker images of Sunshine are planned to be included in the future.
They will be available on `Dockerhub.io`_ and `ghcr.io`_.
Linux
-----
Follow the instructions for your preferred package type below.
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 AppImage can run on the following distros.
- [✖] 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
^^^^^^^^^^^
#. Open terminal and run the following code.
.. code-block:: bash
git clone https://aur.archlinux.org/sunshine-git.git
cd sunshine-git
makepkg -fi
Debian Package
^^^^^^^^^^^^^^
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:deb?logo=github&style=for-the-badge
:alt: GitHub issues by-label
#. Download ``sunshine.deb`` and run the following code.
.. code-block:: bash
sudo apt install -f ./sunshine.deb
.. Tip:: You can double click the deb file to see details about the package and begin installation.
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.
System level (recommended)
.. code-block:: bash
flatpak install --system sunshine.flatpak
User level
.. code-block:: bash
flatpak install --user sunshine.flatpak
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
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
#. Download ``sunshine.rpm`` and run the following code.
.. code-block:: bash
sudo dnf install ./sunshine.rpm
.. Tip:: You can double click the rpm file to see details about the package and begin installation.
macOS
-----
.. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/os:macos?logo=github&style=for-the-badge
:alt: GitHub issues by-label
pkg
.. Warning:: The `pkg` does not include runtime dependencies and should be considered experimental.
#. Download the ``sunshine.pkg`` file and install it as normal.
Portfile
#. Install `MacPorts <https://www.macports.org>`_
#. Update the Macports sources.
.. code-block:: bash
sudo nano /opt/local/etc/macports/sources.conf
Add this line, replacing your username, below the line that starts with ``rsync``.
file://Users/<username>/ports
``Ctrl+x``, then ``Y`` to exit and save changes.
#. Download the ``Portfile`` to ``~/Downloads`` and run the following code.
.. code-block:: bash
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.
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
Installed option:
#. Download and install ``sunshine-windows.exe``
Standalone option:
#. Download and extract ``sunshine-windows.zip``
.. _latest release: https://github.com/LizardByte/Sunshine/releases/latest
.. _Dockerhub.io: https://hub.docker.com/repository/docker/lizardbyte/sunshine
.. _ghcr.io: https://github.com/orgs/LizardByte/packages?repo_name=sunshine

View File

@@ -0,0 +1 @@
.. include:: ../../../README.rst

View File

@@ -0,0 +1,47 @@
: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.
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
Scoop
-----
.. image:: https://img.shields.io/scoop/v/sunshine?bucket=extras&style=for-the-badge
:alt: Scoop Version (extras bucket)
:target: https://scoop.sh/#/apps?s=0&d=1&o=true&q=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
:alt: Winget Version
:target: https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine
Legacy GitHub Repo
------------------
.. Attention:: This repo is not maintained. Thank you to Loki for bringing this amazing project to life!
.. image:: https://img.shields.io/static/v1?label=repo&message=loki-47-6F-64/sunshine&color=blue&style=for-the-badge&logo=github
:alt: GitHub Maintainer
:target: https://github.com/loki-47-6F-64/sunshine/releases
.. image:: https://img.shields.io/github/last-commit/loki-47-6F-64/sunshine?style=for-the-badge&logo=github
:alt: GitHub last commit
.. 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

221
docs/source/about/usage.rst Normal file
View File

@@ -0,0 +1,221 @@
: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``.
.. 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.
.. Tip:: If using the Linux AppImage, replace ``sunshine`` with ``./sunshine.AppImage``
#. 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".
.. 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!
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
#. In Moonlight, you may need to add the PC manually.
#. When Moonlight request you insert the correct pin on sunshine:
- Login to the web ui
- Go to "PIN" in the Navbar
- Type in your PIN and press Enter, you should get a Success Message
- In Moonlight, select one of the Applications listed
Network
-------
Sunshine will be available on port 47990 by default.
.. Danger:: Do not expose port 47990, or the web ui, to the internet!
Arguments
---------
To get a list of available arguments run the following:
.. code-block:: bash
sunshine --help
Setup
-----
Linux
^^^^^
The deb and rpm packages handle these steps automatically. The AppImage does not, third party packages may not as well.
Sunshine needs access to `uinput` to create mouse and gamepad events.
#. Add user to group `input`, if this is the first time installing.
.. code-block:: bash
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.
#. Optionally, configure autostart service
- filename: ``~/.config/systemd/user/sunshine.service``
- contents:
.. code-block::
[Unit]
Description=Sunshine Gamestream Server for Moonlight
[Service]
ExecStart=<see table>
[Install]
WantedBy=graphical-session.target
.. table::
:widths: auto
======== ============================================== ===============
package ExecStart Auto Configured
======== ============================================== ===============
aur /usr/bin/sunshine ✔
deb /usr/bin/sunshine ✔
rpm /usr/bin/sunshine ✔
AppImage ~/sunshine.AppImage ✖
Flatpak flatpak run dev.lizardbyte.sunshine ✖
======== ============================================== ===============
Start once
.. code-block:: bash
systemctl --user start sunshine
Start on boot
.. code-block:: bash
systemctl --user enable sunshine
#. Additional Setup for KMS
.. 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
.. code-block:: bash
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
Disable
.. code-block:: bash
sudo setcap -r $(readlink -f $(which sunshine))
#. Reboot
.. code-block:: bash
sudo reboot now
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`.
.. 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
.. code-block:: bash
sudo port load Sunshine
Windows
^^^^^^^
For gamepad support, install `ViGEmBus <https://github.com/ViGEm/ViGEmBus/releases/latest>`_
Shortcuts
---------
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
Application List
----------------
- 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)``
- ``env`` - Adds or overwrites Environment variables for the commands/applications run by Sunshine
- ``"Variable name":"Variable value"``
- ``apps`` - The list of applications
- 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"
]
}
- ``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 it fails, all ``undo`` commands of the previously succeeded ``do`` commands are run
- ``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
- ``cmd`` - The main application
- If not specified, a process is started that sleeps indefinitely
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.
- 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.

View File

@@ -0,0 +1,35 @@
: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
supported. That means the binaries must be built on the target operating system and architecture.
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
cd sunshine && mkdir build && cd build
Compile
^^^^^^^
See the section specific to your OS.
- :ref:`Linux <building/linux:linux>`
- :ref:`macOS <building/macos:macos>`
- :ref:`Windows <building/windows:windows>`
Remote Build
------------
It may be beneficial to build remotely in some cases. This will enable easier building on different operating systems.
#. Fork the project
#. Activate workflows
#. Trigger the `CI` workflow manually
#. Download the artifacts/binaries from the workflow run summary

View File

@@ -0,0 +1,302 @@
: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
^^^^^^^^^^^^^^^
End of Life: TBD
Install Requirements
.. code-block:: bash
sudo apt update && sudo apt install \
build-essential \
cmake \
git \
libavdevice-dev \
libboost-filesystem-dev \
libboost-log-dev \
libboost-thread-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
nvidia-cuda-dev \ # Cuda, NvFBC
nvidia-cuda-toolkit \ # Cuda, NvFBC
Fedora 35
^^^^^^^^^
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 install \
boost-devel \
boost-static.x86_64 \
cmake \
ffmpeg-devel \
gcc-c++ \
libevdev-devel \
libX11-devel \ # X11
libxcb-devel \ # X11
libXcursor-devel \ # X11
libXfixes-devel \ # X11
libXinerama-devel \ # X11
libXi-devel \ # X11
libXrandr-devel \ # X11
libXtst-devel \ # X11
mesa-libGL-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
Ubuntu 20.04
^^^^^^^^^^^^
End of Life: April 2030
Install Requirements
.. code-block:: bash
sudo apt update && sudo apt install \
build-essential \
cmake \
git \
g++-10 \
libavdevice-dev \
libboost-filesystem-dev \
libboost-log-dev \
libboost-thread-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
Ubuntu 21.10
^^^^^^^^^^^^
End of Life: July 2022
Install Requirements
.. code-block:: bash
sudo apt update && sudo apt install \
build-essential \
cmake \
git \
libavdevice-dev \
libboost-filesystem-dev \
libboost-log-dev \
libboost-thread-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
nvidia-cuda-dev \ # Cuda, NvFBC
nvidia-cuda-toolkit \ # Cuda, NvFBC
Ubuntu 22.04
^^^^^^^^^^^^
End of Life: April 2027
.. Todo:: Create Ubuntu 22.04 Dockerfile and complete this documentation.
Build
-----
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
Debian based OSes
.. code-block:: bash
cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 ..
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

View File

@@ -0,0 +1,43 @@
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/building/macos.rst
macOS
=====
Requirements
------------
macOS Big Sur and Xcode 12.5+
Use either `MacPorts <https://www.macports.org>`_ or `Homebrew <https://brew.sh>`_
MacPorts
""""""""
Install Requirements
.. code-block:: bash
sudo port install cmake boost ffmpeg libopus
Homebrew
""""""""
Install Requirements
.. code-block:: bash
brew install boost cmake ffmpeg opus
# if there are issues with an SSL header that is not found:
cd /usr/local/include
ln -s ../opt/openssl/include/openssl .
Build
-----
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
.. code-block:: bash
cmake ..
make -j ${nproc}
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 ..``

View File

@@ -0,0 +1,27 @@
: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:
.. 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
Build
-----
.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing.
.. code-block:: bash
cmake -G"Unix Makefiles" ..
cmake -G"MinGW Makefiles" .. # alternatively
mingw32-make
cpack -G NSIS # optionally, create a windows installer
cpack -G ZIP # optionally, create a windows standalone package

97
docs/source/conf.py Normal file
View File

@@ -0,0 +1,97 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# standard imports
from datetime import datetime
import os
import re
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
script_dir = os.path.dirname(os.path.abspath(__file__)) # the directory of this file
source_dir = os.path.dirname(script_dir) # the source folder directory
root_dir = os.path.dirname(source_dir) # the root folder directory
# -- Project information -----------------------------------------------------
project = 'Sunshine'
copyright = f'{datetime.now ().year}, {project}'
author = 'ReenigneArcher'
# The full version, including alpha/beta/rc tags
with open(os.path.join(root_dir, 'CMakeLists.txt'), 'r') as f:
version = re.search(r"project\(Sunshine VERSION ((\d+)\.(\d+)\.(\d+))", str(f.read())).group(1)
"""
To use cmake method for obtaining version instead of regex,
1. Within CMakeLists.txt add the following line without backticks:
``configure_file(docs/source/conf.py.in "${CMAKE_CURRENT_SOURCE_DIR}/docs/source/conf.py" @ONLY)``
2. Rename this file to ``conf.py.in``
3. Uncomment the next line
"""
# version = '@PROJECT_VERSION@' # use this for cmake configure_file method
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'm2r2', # enable markdown files
'sphinx.ext.autosectionlabel',
'sphinx.ext.todo', # enable to-do sections
'sphinx.ext.viewcode', # add links to view source code
'sphinx_copybutton', # add a copy button to code blocks
]
# Add any paths that contain templates here, relative to this directory.
# templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['toc.rst']
# Extensions to include.
source_suffix = ['.rst', '.md']
# -- Options for HTML output -------------------------------------------------
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
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_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,
}
# extension config options
autosectionlabel_prefix_document = True # Make sure the target is unique
todo_include_todos = True

View File

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

View File

@@ -0,0 +1,84 @@
: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.
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=de&style=for-the-badge&query=%24.progress.0.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=green&label=en&style=for-the-badge&query=%24.progress.1.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=en-GB&style=for-the-badge&query=%24.progress.2.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=en-US&style=for-the-badge&query=%24.progress.3.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=es-ES&style=for-the-badge&query=%24.progress.4.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=fr&style=for-the-badge&query=%24.progress.5.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=it&style=for-the-badge&query=%24.progress.6.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=ru&style=for-the-badge&query=%24.progress.7.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json
Graph
.. image:: https://badges.awesome-crowdin.com/translation-15178612-503956.png
CrowdIn
-------
The translations occur on
`CrowdIn <https://crowdin.com/project/sunshinestream>`_. Feel free to contribute to localization there.
Only elements of the API are planned to be translated.
.. Attention:: The rest API has not yet been implemented.
Translations Basics
- The brand names `LizardByte` and `Sunshine` should never be translated.
- Other brand names should never be translated.
Examples:
- AMD
- Nvidia
CrowdIn Integration
How does it work?
When a change is made to sunshine source code, a workflow generates new translation templates
that get pushed to CrowdIn automatically.
When translations are updated on CrowdIn, a push gets made to the `l10n_nightly` branch and a PR is made against the
`nightly` branch. Once PR is merged, all updated translations are part of the project and will be included in the
next release.
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.
.. code-block:: cpp
#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>`_.
.. Warning:: This is for information only. Contributors should never include manually updated template files, or
manually compiled language files in Pull Requests.
Strings are automatically extracted from the code to the `locale/sunshine.po` template file. The generated file is
used by CrowdIn to generate language specific template files. The file is generated using the
`.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
- '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
python ./scripts/_locale.py --extract --init --update
Compile
.. code-block:: bash
python ./scripts/_locale.py --compile

View File

@@ -0,0 +1,42 @@
: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`.
Test clang-format locally.
.. Todo:: This documentation needs to be improved.
.. code-block:: bash
clang-format ...
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.
The config file for Sphinx is `docs/source/conf.py`. This is already included in the repo and should not be modified.
Test with Sphinx
.. code-block:: bash
cd docs
make html
Alternatively
.. code-block:: bash
cd docs
sphinx-build -b html source build
Unit Testing
------------
.. Todo:: Sunshine does not currently have any unit tests. If you would like to help us improve please get in contact
with us, or make a PR with suggested changes.

5
docs/source/index.rst Normal file
View File

@@ -0,0 +1,5 @@
:github_url: https://github.com/LizardByte/Sunshine/tree/nightly/docs/source/index.rst
Table of Contents
=================
.. include:: toc.rst

36
docs/source/toc.rst Normal file
View File

@@ -0,0 +1,36 @@
.. toctree::
:maxdepth: 2
:caption: About
about/overview
about/installation
about/docker
about/third_party_packages
about/usage
about/advanced_usage
.. toctree::
:maxdepth: 2
:caption: Troubleshooting
troubleshooting/general
troubleshooting/linux
troubleshooting/macos
troubleshooting/windows
.. toctree::
:maxdepth: 2
:caption: Build
building/build
building/linux
building/macos
building/windows
.. toctree::
:maxdepth: 2
:caption: Contributing
contributing/contributing
contributing/localization
contributing/testing

View File

@@ -0,0 +1,13 @@
: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.
.. code-block:: bash
sunshine -creds <new username> <new password>
Can't access the web UI?
#. Check firefall rules.

View File

@@ -0,0 +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.
.. code-block:: bash
sudo setcap -r $(readlink -f $(which sunshine))

View File

@@ -0,0 +1,29 @@
: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!``
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

View File

@@ -0,0 +1,7 @@
: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>`_.

View File

@@ -1,94 +0,0 @@
#!/bin/sh
if [ ! "@SUNSHINE_UNDEFINED_VARIABLE@" = "" ]; then
echo "Please run gen-deb generated by cmake inside the build directory"
exit 1
fi
if [ -d package-deb ]; then
echo "package-deb already exists: It will be replaced"
rm -rf package-deb
fi
export DEBIAN=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/DEBIAN
export RULES=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/etc/udev/rules.d
export BIN=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/usr/bin
export SERVICE=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/usr/lib/systemd/user
export ASSETS=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/etc/sunshine
mkdir -p $DEBIAN
mkdir -p $RULES
mkdir -p $BIN
mkdir -p $ASSETS/shaders
mkdir -p $SERVICE
if [ ! -f sunshine ]; then
echo "Error: Can't find sunshine"
exit 1
fi
cat << 'EOF' > $DEBIAN/conffiles
/etc/sunshine/sunshine.conf
/etc/sunshine/apps_linux.json
EOF
cat << 'EOF' > $DEBIAN/control
Package: sunshine
Architecture: amd64
Maintainer: @loki
Priority: optional
Version: 0.8.1
Depends: libssl1.1, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0, libboost-log1.67.0 | libboost-log1.71.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2
Description: Gamestream host for Moonlight
EOF
cat << 'EOF' > $DEBIAN/postinst
#!/bin/sh
export GROUP_INPUT=input
if [ -f /etc/group ]; then
if ! grep -q $GROUP_INPUT /etc/group; then
echo "Creating group $GROUP_INPUT"
groupadd $GROUP_INPUT
fi
else
echo "Warning: /etc/group not found"
fi
# Update permissions on config files for Web Manager
if [ -f /etc/sunshine/apps_linux.json ]; then
echo "chmod 666 /etc/sunshine/apps_linux.json"
chmod 666 /etc/sunshine/apps_linux.json
fi
if [ -f /etc/sunshine/sunshine.conf ]; then
echo "chmod 666 /etc/sunshine/sunshine.conf"
chmod 666 /etc/sunshine/sunshine.conf
fi
EOF
cat << 'EOF' > $RULES/85-sunshine-rules.rules
KERNEL=="uinput", GROUP="input", MODE="0660"
EOF
cp sunshine $BIN/sunshine
cp @CMAKE_CURRENT_SOURCE_DIR@/assets/apps_linux.json $ASSETS/apps_linux.json
cp @CMAKE_CURRENT_SOURCE_DIR@/assets/sunshine.conf $ASSETS/sunshine.conf
cp @CMAKE_CURRENT_BINARY_DIR@/sunshine.service $SERVICE/sunshine.service
cp -r @CMAKE_CURRENT_SOURCE_DIR@/assets/web $ASSETS/web
cp -r @CMAKE_CURRENT_SOURCE_DIR@/assets/shaders/opengl $ASSETS/shaders/opengl
chmod 755 $DEBIAN/postinst
chmod 755 $BIN/sunshine
chmod 644 $RULES/85-sunshine-rules.rules
chmod 666 $ASSETS/apps_linux.json
chmod 666 $ASSETS/sunshine.conf
cd package-deb
if fakeroot dpkg-deb --build sunshine; then
echo "generated debian package: @CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine.deb"
fi
cd ..

View File

@@ -0,0 +1,55 @@
# 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@
pkgver=@PROJECT_VERSION@@SUNSHINE_SUB_VERSION@
pkgrel=1
pkgdesc="@PROJECT_DESCRIPTION@"
arch=('x86_64' 'i686')
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')
provides=(@SUNSHINE_AUR_PROVIDES@)
conflicts=(@SUNSHINE_AUR_CONFLICTS@)
source=("$pkgname::git+@GITHUB_CLONE_URL@#commit=@GITHUB_COMMIT@")
sha256sums=('SKIP')
prepare() {
cd "$pkgname"
git submodule update --recursive --init
}
build() {
export CFLAGS="${CFLAGS/-Werror=format-security/}"
export CXXFLAGS="${CXXFLAGS/-Werror=format-security/}"
cmake \
-S "$pkgname" \
-B build \
-Wno-dev \
-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
make -C build
}
package() {
make -C build install DESTDIR="$pkgdir"
}

View File

@@ -0,0 +1,216 @@
---
app-id: dev.lizardbyte.sunshine
runtime: org.freedesktop.Platform
runtime-version: "21.08"
sdk: org.freedesktop.Sdk
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
cleanup:
- /include
- /lib/cmake
- /lib/pkgconfig
- /lib/*.la
- /lib/*.a
- /share
modules:
- 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 # 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
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:
- 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
- name: avahi
cleanup:
- /bin
- /lib/avahi
- /share/applications/*.desktop
- /share/avahi
config-opts:
- --with-distro=none
- --disable-gobject
- --disable-introspection
- --disable-qt3
- --disable-qt4
- --disable-qt5
- --disable-gtk
- --disable-core-docs
- --disable-manpages
- --disable-libdaemon
- --disable-python
- --disable-pygobject
- --disable-mono
- --disable-monodoc
- --disable-autoipd
- --disable-doxygen-doc
- --disable-doxygen-dot
- --disable-doxygen-xml
- --disable-doxygen-html
- --disable-manpages
- --disable-xmltoman
sources:
- type: archive
url: https://avahi.org/download/avahi-0.8.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
- name: libevdev
buildsystem: meson
cleanup:
- /bin
sources:
- type: archive
url: https://www.freedesktop.org/software/libevdev/libevdev-1.12.1.tar.xz
sha256: 1dbba41bc516d3ca7abc0da5b862efe3ea8a7018fa6e9b97ce9d39401b22426c
modules:
- name: libcheck
buildsystem: cmake
cleanup:
- /bin
sources:
- type: archive
url: https://github.com/libcheck/check/archive/refs/tags/0.15.2.tar.gz
sha256: 998d355294bb94072f40584272cf4424571c396c631620ce463f6ea97aa67d2e
- name: sunshine
buildsystem: cmake
no-make-install: false
builddir: true
build-options:
cxxflags: -I${C_INCLUDE_PATH}/libevdev-1.0
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_EXECUTABLE_PATH=/app/bin/sunshine
- -DSUNSHINE_ENABLE_WAYLAND=ON
- -DSUNSHINE_ENABLE_X11=ON
- -DSUNSHINE_ENABLE_DRM=ON
- -DSUNSHINE_ENABLE_CUDA=ON
sources:
- type: git
url: '@GITHUB_CLONE_URL@'
branch: '@GITHUB_BRANCH@'
commit: '@GITHUB_COMMIT@'

View File

@@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=@PROJECT_NAME@
Exec=sunshine
Version=1.0
Comment=@PROJECT_DESCRIPTION@
Icon=sunshine
Categories=Utility;
Terminal=true
X-AppImage-Name=sunshine
X-AppImage-Version=@PROJECT_VERSION@
X-AppImage-Arch=x86_64

84
packaging/macos/Portfile Normal file
View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# initial PR into macports: https://github.com/macports/macports-ports/pull/15143
PortSystem 1.0
PortGroup cmake 1.1
PortGroup github 1.0
PortGroup boost 1.0
name @PROJECT_NAME@
version @PROJECT_VERSION@
revision 0
categories multimedia emulators games
platforms darwin
license GPL-3
maintainers @LizardByte
description @PROJECT_DESCRIPTION@
# long_description will not be split into multiple lines as it's configured by CMakeLists
long_description @PROJECT_LONG_DESCRIPTION@
homepage @PROJECT_HOMEPAGE_URL@
master_sites https://github.com/lizardbyte/sunshine/releases
compiler.cxx_standard 2017
fetch.type git
git.url @GITHUB_CLONE_URL@
git.branch @GITHUB_COMMIT@
post-fetch {
system -W ${worksrcpath} "${git.cmd} submodule update --init --recursive"
}
depends_lib port:avahi \
port:ffmpeg \
port:libopus
boost.version 1.76
configure.args -DCMAKE_INSTALL_PREFIX=${prefix} \
-DSUNSHINE_ASSETS_DIR=etc/sunshine/assets \
-DSUNSHINE_CONFIG_DIR=etc/sunshine/config
startupitem.create yes
startupitem.executable "${prefix}/bin/{$name}"
startupitem.location LaunchDaemons
startupitem.name ${name}
startupitem.netchange yes
platform darwin {
if { ${os.major} < 20 } {
# See: https://github.com/LizardByte/Sunshine/discussions/117#discussioncomment-2513494
notes-append "Port is limited to software encoding, when used with macOS releases prior to Big Sur."
}
}
# destroot not required as cmake install directive handles moving files
# # 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."
notes-append "See our documentation at 'https://docs.lizardbyte.dev/projects/sunshine/en/v@PROJECT_VERSION@/' for further info."

40
scripts/Dockerfile-debian Normal file
View File

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

View File

@@ -0,0 +1,32 @@
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"]

View File

@@ -0,0 +1,36 @@
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"]

View File

@@ -0,0 +1,63 @@
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"]

View File

@@ -0,0 +1,46 @@
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"]

View File

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

View File

@@ -0,0 +1,39 @@
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"]

170
scripts/_locale.py Normal file
View File

@@ -0,0 +1,170 @@
"""
..
_locale.py
Functions related to building, initializing, updating, and compiling localization translations.
Borrowed from RetroArcher.
"""
# standard imports
import argparse
import datetime
import os
import subprocess
project_name = 'Sunshine'
project_owner = 'LizardByte'
script_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = os.path.dirname(script_dir)
locale_dir = os.path.join(root_dir, 'locale')
project_dir = os.path.join(root_dir, 'src')
year = datetime.datetime.now().year
# retroarcher target locales
target_locales = [
'de', # Deutsch
'en', # English
'en_GB', # English (United Kingdom)
'en_US', # English (United States)
'es', # español
'fr', # français
'it', # italiano
'ru', # русский
]
def x_extract():
"""Executes `xgettext extraction` in subprocess."""
pot_filepath = os.path.join(locale_dir, f'{project_name.lower()}.po')
commands = [
'xgettext',
'--keyword=translate:1,1t',
'--keyword=translate:1c,2,2t',
'--keyword=translate:1,2,3t',
'--keyword=translate:1c,2,3,4t',
'--keyword=gettext:1',
'--keyword=pgettext:1c,2',
'--keyword=ngettext:1,2',
'--keyword=npgettext:1c,2,3',
f'--default-domain={project_name.lower()}',
f'--output={pot_filepath}',
'--language=C++',
'--boost',
'--from-code=utf-8',
'-F',
f'--msgid-bugs-address=github.com/{project_owner.lower()}/{project_name.lower()}',
f'--copyright-holder={project_owner}',
f'--package-name={project_name}',
'--package-version=v0'
]
extensions = ['cpp', 'h', 'm', 'mm']
# find input files
for root, dirs, files in os.walk(project_dir, topdown=True):
for name in files:
filename = os.path.join(root, name)
extension = filename.rsplit('.', 1)[-1]
if extension in extensions: # append input files
commands.append(filename)
print(commands)
subprocess.check_output(args=commands, cwd=root_dir)
try:
# fix header
body = ""
with open(file=pot_filepath, mode='r') as file:
for line in file.readlines():
if line != '"Language: \\n"\n': # do not include this line
if line == '# SOME DESCRIPTIVE TITLE.\n':
body += f'# Translations template for {project_name}.\n'
elif line.startswith('#') and 'YEAR' in line:
body += line.replace('YEAR', str(year))
elif line.startswith('#') and 'PACKAGE' in line:
body += line.replace('PACKAGE', project_name)
else:
body += line
# rewrite pot file with updated header
with open(file=pot_filepath, mode='w+') as file:
file.write(body)
except FileNotFoundError:
pass
def babel_init(locale_code: str):
"""Executes `pybabel init` in subprocess.
:param locale_code: str - locale code
"""
commands = [
'pybabel',
'init',
'-i', os.path.join(locale_dir, f'{project_name.lower()}.po'),
'-d', locale_dir,
'-D', project_name.lower(),
'-l', locale_code
]
print(commands)
subprocess.check_output(args=commands, cwd=root_dir)
def babel_update():
"""Executes `pybabel update` in subprocess."""
commands = [
'pybabel',
'update',
'-i', os.path.join(locale_dir, f'{project_name.lower()}.po'),
'-d', locale_dir,
'-D', project_name.lower(),
'--update-header-comment'
]
print(commands)
subprocess.check_output(args=commands, cwd=root_dir)
def babel_compile():
"""Executes `pybabel compile` in subprocess."""
commands = [
'pybabel',
'compile',
'-d', locale_dir,
'-D', project_name.lower()
]
print(commands)
subprocess.check_output(args=commands, cwd=root_dir)
if __name__ == '__main__':
# Set up and gather command line arguments
parser = argparse.ArgumentParser(
description='Script helps update locale translations. Translations must be done manually.')
parser.add_argument('--extract', action='store_true', help='Extract messages from c++ files.')
parser.add_argument('--init', action='store_true', help='Initialize any new locales specified in target locales.')
parser.add_argument('--update', action='store_true', help='Update existing locales.')
parser.add_argument('--compile', action='store_true', help='Compile translated locales.')
args = parser.parse_args()
if args.extract:
x_extract()
if args.init:
for locale_id in target_locales:
if not os.path.isdir(os.path.join(locale_dir, locale_id)):
babel_init(locale_code=locale_id)
if args.update:
babel_update()
if args.compile:
babel_compile()

179
scripts/build-container.sh Executable file
View File

@@ -0,0 +1,179 @@
#!/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

48
scripts/build-private.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/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

132
scripts/build-sunshine.sh Executable file
View File

@@ -0,0 +1,132 @@
#!/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

5
scripts/requirements.txt Normal file
View File

@@ -0,0 +1,5 @@
Babel==2.10.3
m2r2==0.3.2
Sphinx==5.1.1
sphinx-copybutton==0.5.0
sphinx-rtd-theme==1.0.0

View File

@@ -87,11 +87,14 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
OPUS_APPLICATION_AUDIO,
nullptr) };
opus_multistream_encoder_ctl(opus.get(), OPUS_SET_VBR(0));
// 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));
auto frame_size = config.packetDuration * stream->sampleRate / 1000;
while(auto sample = samples->pop()) {
buffer_t packet { 1024 }; // 1KB
buffer_t packet { 1400 }; // 1KB
int bytes = opus_multistream_encode(opus.get(), sample->data(), frame_size, std::begin(packet), packet.size());
if(bytes < 0) {
@@ -101,6 +104,14 @@ 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,14 +130,20 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) {
auto &control = ref->control;
if(!control) {
BOOST_LOG(error) << "Couldn't create audio control"sv;
shutdown_event->view();
return;
}
std::string *sink =
config::audio.sink.empty() ? &ref->sink.host : &config::audio.sink;
if(ref->sink.null) {
// Order of priorty:
// 1. Config
// 2. Virtual if available
// 3. Host
std::string *sink = &ref->sink.host;
if(!config::audio.sink.empty()) {
sink = &config::audio.sink;
}
else if(ref->sink.null) {
auto &null = *ref->sink.null;
switch(stream->channelCount) {
case 2:
@@ -212,21 +229,29 @@ int map_stream(int channels, bool quality) {
}
int start_audio_control(audio_ctx_t &ctx) {
auto fg = util::fail_guard([]() {
BOOST_LOG(warning) << "There will be no audio"sv;
});
ctx.sink_flag = std::make_unique<std::atomic_bool>(false);
if(!(ctx.control = platf::audio_control())) {
return -1;
}
auto sink = ctx.control->sink_info();
if(!sink) {
return -1;
}
// The default sink has not been replaced yet.
ctx.restore_sink = false;
if(!(ctx.control = platf::audio_control())) {
return 0;
}
auto sink = ctx.control->sink_info();
if(!sink) {
// Let the calling code know it failed
ctx.control.reset();
return 0;
}
ctx.sink = std::move(*sink);
fg.disable();
return 0;
}

View File

@@ -20,7 +20,7 @@ using namespace std::literals;
#define PRIVATE_KEY_FILE CA_DIR "/cakey.pem"
#define CERTIFICATE_FILE CA_DIR "/cacert.pem"
#define APPS_JSON_PATH SUNSHINE_ASSETS_DIR "/" APPS_JSON
#define APPS_JSON_PATH platf::appdata().string() + "/apps.json"
namespace config {
namespace nv {
@@ -99,16 +99,22 @@ enum quality_e : int {
_default = 0,
speed,
balanced,
//quality2,
};
enum rc_e : int {
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 */
};
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 */
};
enum coder_e : int {
_auto = 0,
cabac,
@@ -120,15 +126,25 @@ std::optional<quality_e> quality_from_view(const std::string_view &quality) {
if(quality == #x##sv) return x
_CONVERT_(speed);
_CONVERT_(balanced);
//_CONVERT_(quality2);
if(quality == "default"sv) return _default;
#undef _CONVERT_
return std::nullopt;
}
std::optional<rc_e> rc_from_view(const std::string_view &rc) {
std::optional<int> rc_h264_from_view(const std::string_view &rc) {
#define _CONVERT_(x) \
if(rc == #x##sv) return x
if(rc == #x##sv) return (int)rc_h264_e::x
_CONVERT_(constqp);
_CONVERT_(vbr_latency);
_CONVERT_(vbr_peak);
_CONVERT_(cbr);
#undef _CONVERT_
return std::nullopt;
}
std::optional<int> rc_hevc_from_view(const std::string_view &rc) {
#define _CONVERT_(x) \
if(rc == #x##sv) return (int)rc_hevc_e::x
_CONVERT_(constqp);
_CONVERT_(vbr_latency);
_CONVERT_(vbr_peak);
@@ -146,8 +162,43 @@ int coder_from_view(const std::string_view &coder) {
}
} // namespace amd
namespace vt {
enum coder_e : int {
_auto = 0,
cabac,
cavlc
};
int coder_from_view(const std::string_view &coder) {
if(coder == "auto"sv) return _auto;
if(coder == "cabac"sv || coder == "ac"sv) return cabac;
if(coder == "cavlc"sv || coder == "vlc"sv) return cavlc;
return -1;
}
int allow_software_from_view(const std::string_view &software) {
if(software == "allowed"sv || software == "forced") return 1;
return 0;
}
int force_software_from_view(const std::string_view &software) {
if(software == "forced") return 1;
return 0;
}
int rt_from_view(const std::string_view &rt) {
if(rt == "disabled" || rt == "off" || rt == "0") return 0;
return 1;
}
} // namespace vt
video_t video {
0, // crf
28, // qp
0, // hevc_mode
@@ -166,11 +217,19 @@ video_t video {
{
amd::balanced,
std::nullopt,
std::nullopt,
-1 }, // amd
{}, // encoder
{}, // adapter_name
{}, // output_name
{
0,
0,
1,
-1 }, // vt
{}, // encoder
{}, // adapter_name
{}, // output_name
true // dwmflush
};
audio_t audio {};
@@ -211,20 +270,30 @@ nvhttp_t nvhttp {
};
input_t input {
2s, // back_button_timeout
500ms, // key_repeat_delay
std::chrono::duration<double> { 1 / 24.9 } // key_repeat_period
{
{ 0x10, 0xA0 },
{ 0x11, 0xA2 },
{ 0x12, 0xA4 },
},
2s, // back_button_timeout
500ms, // key_repeat_delay
std::chrono::duration<double> { 1 / 24.9 }, // key_repeat_period
{
platf::supported_gamepads().front().data(),
platf::supported_gamepads().front().size(),
}, // Default gamepad
};
sunshine_t sunshine {
2, // min_log_level
0, // flags
{}, // User file
{}, // Username
{}, // Password
{}, // Password Salt
SUNSHINE_ASSETS_DIR "/sunshine.conf", // config file
{}, // cmd args
2, // min_log_level
0, // flags
{}, // User file
{}, // Username
{}, // Password
{}, // Password Salt
platf::appdata().string() + "/sunshine.conf", // config file
{}, // cmd args
47989,
};
@@ -395,8 +464,20 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
return;
}
auto &val = it->second;
input = util::from_chars(&val[0], &val[0] + val.size());
std::string_view val = it->second;
// If value is something like: "756" instead of 756
if(val.size() >= 2 && val[0] == '"') {
val = val.substr(1, val.size() - 2);
}
// If that integer is in hexadecimal
if(val.size() >= 2 && val.substr(0, 2) == "0x"sv) {
input = util::from_hex<int>(val.substr(2));
}
else {
input = util::from_view(val);
}
vars.erase(it);
}
@@ -408,8 +489,20 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
return;
}
auto &val = it->second;
input = util::from_chars(&val[0], &val[0] + val.size());
std::string_view val = it->second;
// If value is something like: "756" instead of 756
if(val.size() >= 2 && val[0] == '"') {
val = val.substr(1, val.size() - 2);
}
// If that integer is in hexadecimal
if(val.size() >= 2 && val.substr(0, 2) == "0x"sv) {
input = util::from_hex<int>(val.substr(2));
}
else {
input = util::from_view(val);
}
vars.erase(it);
}
@@ -541,7 +634,42 @@ void list_int_f(std::unordered_map<std::string, std::string> &vars, const std::s
list_string_f(vars, name, list);
for(auto &el : list) {
input.emplace_back(util::from_view(el));
std::string_view val = el;
// If value is something like: "756" instead of 756
if(val.size() >= 2 && val[0] == '"') {
val = val.substr(1, val.size() - 2);
}
int tmp;
// If the integer is a hexadecimal
if(val.size() >= 2 && val.substr(0, 2) == "0x"sv) {
tmp = util::from_hex<int>(val.substr(2));
}
else {
tmp = util::from_view(val);
}
input.emplace_back(tmp);
}
}
void map_int_int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::unordered_map<int, int> &input) {
std::vector<int> list;
list_int_f(vars, name, list);
// The list needs to be a multiple of 2
if(list.size() % 2) {
std::cout << "Warning: expected "sv << name << " to have a multiple of two elements --> not "sv << list.size() << std::endl;
return;
}
int x = 0;
while(x < list.size()) {
auto key = list[x++];
auto val = list[x++];
input.emplace(key, val);
}
}
@@ -573,11 +701,14 @@ 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);
}
for(auto &[name, val] : vars) {
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
}
int_f(vars, "crf", video.crf);
int_f(vars, "qp", video.qp);
int_f(vars, "min_threads", video.min_threads);
int_between_f(vars, "hevc_mode", video.hevc_mode, { 0, 3 });
@@ -588,12 +719,24 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
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, "amd_rc", video.amd.rc, amd::rc_from_view);
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);
}
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);
int_f(vars, "vt_realtime", video.vt.realtime, vt::rt_from_view);
string_f(vars, "encoder", video.encoder);
string_f(vars, "adapter_name", video.adapter_name);
string_f(vars, "output_name", video.output_name);
bool_f(vars, "dwmflush", video.dwmflush);
path_f(vars, "pkey", nvhttp.pkey);
path_f(vars, "cert", nvhttp.cert);
@@ -626,6 +769,17 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
path_f(vars, "file_apps", stream.file_apps);
int_between_f(vars, "fec_percentage", stream.fec_percentage, { 1, 255 });
map_int_int_f(vars, "keybindings"s, input.keybindings);
// This config option will only be used by the UI
// When editing in the config file itself, use "keybindings"
bool map_rightalt_to_win = false;
bool_f(vars, "key_rightalt_to_key_win", map_rightalt_to_win);
if(map_rightalt_to_win) {
input.keybindings.emplace(0xA5, 0x5B);
}
to = std::numeric_limits<int>::min();
int_f(vars, "back_button_timeout", to);
@@ -646,6 +800,8 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
input.key_repeat_delay = std::chrono::milliseconds { to };
}
string_restricted_f(vars, "gamepad"s, input.gamepad, platf::supported_gamepads());
int port = sunshine.port;
int_f(vars, "port"s, port);
sunshine.port = (std::uint16_t)port;
@@ -658,7 +814,7 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
}
std::string log_level_string;
string_restricted_f(vars, "min_log_level", log_level_string, { "verbose"sv, "debug"sv, "info"sv, "warning"sv, "error"sv, "fatal"sv, "none"sv });
string_f(vars, "min_log_level", log_level_string);
if(!log_level_string.empty()) {
if(log_level_string == "verbose"sv) {
@@ -754,6 +910,10 @@ int parse(int argc, char *argv[]) {
}
}
if(!fs::exists(sunshine.config_file)) {
fs::copy_file(SUNSHINE_CONFIG_DIR "/sunshine.conf", sunshine.config_file);
}
auto vars = parse_config(read_file(sunshine.config_file.c_str()));
for(auto &[name, value] : cmd_vars) {

View File

@@ -11,8 +11,7 @@
namespace config {
struct video_t {
// ffmpeg params
int crf; // higher == more compression and less quality
int qp; // higher == more compression and less quality, ignored if crf != 0
int qp; // higher == more compression and less quality
int hevc_mode;
@@ -30,13 +29,22 @@ struct video_t {
struct {
std::optional<int> quality;
std::optional<int> rc;
std::optional<int> rc_h264;
std::optional<int> rc_hevc;
int coder;
} amd;
struct {
int allow_sw;
int require_sw;
int realtime;
int coder;
} vt;
std::string encoder;
std::string adapter_name;
std::string output_name;
bool dwmflush;
};
struct audio_t {
@@ -74,9 +82,13 @@ struct nvhttp_t {
};
struct input_t {
std::unordered_map<int, int> keybindings;
std::chrono::milliseconds back_button_timeout;
std::chrono::milliseconds key_repeat_delay;
std::chrono::duration<double> key_repeat_period;
std::string gamepad;
};
namespace flag {

View File

@@ -73,6 +73,15 @@ void send_unauthorized(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::client_error_unauthorized, headers);
}
void send_redirect(resp_https_t response, req_https_t request, const char *path) {
auto address = request->remote_endpoint_address();
BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
const SimpleWeb::CaseInsensitiveMultimap headers {
{ "Location", path }
};
response->write(SimpleWeb::StatusCode::redirection_temporary_redirect, headers);
}
bool authenticate(resp_https_t response, req_https_t request) {
auto address = request->remote_endpoint_address();
auto ip_type = net::from_address(address);
@@ -83,6 +92,12 @@ bool authenticate(resp_https_t response, req_https_t request) {
return false;
}
//If credentials are shown, redirect the user to a /welcome page
if(config::sunshine.username.empty()) {
send_redirect(response, request, "/welcome");
return false;
}
auto fg = util::fail_guard([&]() {
send_unauthorized(response, request);
});
@@ -185,6 +200,91 @@ void getPasswordPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getWelcomePage(resp_https_t response, req_https_t request) {
print_req(request);
if(!config::sunshine.username.empty()) {
send_redirect(response, request, "/");
return;
}
std::string header = read_file(WEB_DIR "header-no-nav.html");
std::string content = read_file(WEB_DIR "welcome.html");
response->write(header + content);
}
void getTroubleshootingPage(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
print_req(request);
std::string header = read_file(WEB_DIR "header.html");
std::string content = read_file(WEB_DIR "troubleshooting.html");
response->write(header + content);
}
void getFaviconImage(resp_https_t response, req_https_t request) {
print_req(request);
std::ifstream in(WEB_DIR "images/favicon.ico", std::ios::binary);
SimpleWeb::CaseInsensitiveMultimap headers;
headers.emplace("Content-Type", "image/x-icon");
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
}
void getSunshineLogoImage(resp_https_t response, req_https_t request) {
print_req(request);
std::ifstream in(WEB_DIR "images/logo-sunshine-45.png", std::ios::binary);
SimpleWeb::CaseInsensitiveMultimap headers;
headers.emplace("Content-Type", "image/png");
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);
}
void getFontAwesomeBrands(resp_https_t response, req_https_t request) {
print_req(request);
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);
}
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);
}
void getApps(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
@@ -371,7 +471,7 @@ void saveConfig(resp_https_t response, req_https_t request) {
}
void savePassword(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
if(!config::sunshine.username.empty() && !authenticate(response, request)) return;
print_req(request);
@@ -390,27 +490,33 @@ void savePassword(resp_https_t response, req_https_t request) {
try {
//TODO: Input Validation
pt::read_json(ss, inputTree);
auto username = inputTree.get<std::string>("currentUsername");
auto username = inputTree.count("currentUsername") > 0 ? inputTree.get<std::string>("currentUsername") : "";
auto newUsername = inputTree.get<std::string>("newUsername");
auto password = inputTree.get<std::string>("currentPassword");
auto newPassword = inputTree.get<std::string>("newPassword");
auto confirmPassword = inputTree.get<std::string>("confirmNewPassword");
auto password = inputTree.count("currentPassword") > 0 ? inputTree.get<std::string>("currentPassword") : "";
auto newPassword = inputTree.count("newPassword") > 0 ? inputTree.get<std::string>("newPassword") : "";
auto confirmPassword = inputTree.count("confirmNewPassword") > 0 ? inputTree.get<std::string>("confirmNewPassword") : "";
if(newUsername.length() == 0) newUsername = username;
auto hash = util::hex(crypto::hash(password + config::sunshine.salt)).to_string();
if(username == config::sunshine.username && hash == config::sunshine.password) {
if(newPassword != confirmPassword) {
outputTree.put("status", false);
outputTree.put("error", "Password Mismatch");
}
http::save_user_creds(config::sunshine.credentials_file, newUsername, newPassword);
http::reload_user_creds(config::sunshine.credentials_file);
outputTree.put("status", true);
if(newUsername.length() == 0) {
outputTree.put("status", false);
outputTree.put("error", "Invalid Username");
}
else {
outputTree.put("status", false);
outputTree.put("error", "Invalid Current Credentials");
auto hash = util::hex(crypto::hash(password + config::sunshine.salt)).to_string();
if(config::sunshine.username.empty() || (username == config::sunshine.username && hash == config::sunshine.password)) {
if(newPassword.empty() || newPassword != confirmPassword) {
outputTree.put("status", false);
outputTree.put("error", "Password Mismatch");
}
else {
http::save_user_creds(config::sunshine.credentials_file, newUsername, newPassword);
http::reload_user_creds(config::sunshine.credentials_file);
outputTree.put("status", true);
}
}
else {
outputTree.put("status", false);
outputTree.put("error", "Invalid Current Credentials");
}
}
}
catch(std::exception &e) {
@@ -451,6 +557,39 @@ void savePin(resp_https_t response, req_https_t request) {
}
}
void unpairAll(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
print_req(request);
pt::ptree outputTree;
auto g = util::fail_guard([&]() {
std::ostringstream data;
pt::write_json(data, outputTree);
response->write(data.str());
});
nvhttp::erase_all_clients();
outputTree.put("status", true);
}
void closeApp(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
print_req(request);
pt::ptree outputTree;
auto g = util::fail_guard([&]() {
std::ostringstream data;
pt::write_json(data, outputTree);
response->write(data.str());
});
proc::proc.terminate();
outputTree.put("status", true);
}
void start() {
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
@@ -460,23 +599,35 @@ void start() {
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["^/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.config.reuse_address = true;
server.config.address = "0.0.0.0"s;
server.config.port = port_https;
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;
try {
server.bind();
@@ -512,4 +663,4 @@ void start() {
tcp.join();
}
} // namespace confighttp
} // namespace confighttp

View File

@@ -52,9 +52,13 @@ const char *cert_chain_t::verify(x509_t::element_type *cert) {
X509_STORE_CTX_cleanup(_cert_ctx.get());
});
X509_STORE_CTX_init(_cert_ctx.get(), x509_store.get(), nullptr, nullptr);
X509_STORE_CTX_init(_cert_ctx.get(), x509_store.get(), cert, nullptr);
X509_STORE_CTX_set_verify_cb(_cert_ctx.get(), openssl_verify_cb);
X509_STORE_CTX_set_cert(_cert_ctx.get(), cert);
// We don't care to validate the entire chain for the purposes of client auth.
// Some versions of clients forked from Moonlight Embedded produce client certs
// that OpenSSL doesn't detect as self-signed due to some X509v3 extensions.
X509_STORE_CTX_set_flags(_cert_ctx.get(), X509_V_FLAG_PARTIAL_CHAIN);
auto err = X509_verify_cert(_cert_ctx.get());

View File

@@ -54,15 +54,12 @@ int init() {
return -1;
}
}
if(!user_creds_exist(config::sunshine.credentials_file)) {
if(save_user_creds(config::sunshine.credentials_file, "sunshine"s, crypto::rand_alphabet(16), true)) {
return -1;
}
if(user_creds_exist(config::sunshine.credentials_file)) {
if(reload_user_creds(config::sunshine.credentials_file)) return -1;
}
if(reload_user_creds(config::sunshine.credentials_file)) {
return -1;
else {
BOOST_LOG(info) << "Open the Web UI to set your new username and password and getting started";
}
return 0;
}
@@ -92,12 +89,6 @@ int save_user_creds(const std::string &file, const std::string &username, const
}
BOOST_LOG(info) << "New credentials have been created"sv;
if(run_our_mouth) {
BOOST_LOG(info) << "Username: "sv << username;
BOOST_LOG(info) << "Password: "sv << password;
}
return 0;
}

View File

@@ -9,6 +9,7 @@ extern "C" {
}
#include <bitset>
#include <unordered_map>
#include "config.h"
#include "input.h"
@@ -17,12 +18,23 @@ extern "C" {
#include "thread_pool.h"
#include "utility.h"
using namespace std::literals;
namespace input {
constexpr auto MAX_GAMEPADS = std::min((std::size_t)platf::MAX_GAMEPADS, sizeof(std::int16_t) * 8);
#define DISABLE_LEFT_BUTTON_DELAY ((util::ThreadPool::task_id_t)0x01)
#define ENABLE_LEFT_BUTTON_DELAY nullptr
constexpr auto VKEY_SHIFT = 0x10;
constexpr auto VKEY_LSHIFT = 0xA0;
constexpr auto VKEY_RSHIFT = 0xA1;
constexpr auto VKEY_CONTROL = 0x11;
constexpr auto VKEY_LCONTROL = 0xA2;
constexpr auto VKEY_RCONTROL = 0xA3;
constexpr auto VKEY_MENU = 0x12;
constexpr auto VKEY_LMENU = 0xA4;
constexpr auto VKEY_RMENU = 0xA5;
enum class button_state_e {
NONE,
DOWN,
@@ -46,7 +58,7 @@ void free_id(std::bitset<N> &gamepad_mask, int id) {
gamepad_mask[id] = false;
}
static util::TaskPool::task_id_t task_id {};
static util::TaskPool::task_id_t key_press_repeat_id {};
static std::unordered_map<short, bool> key_press {};
static std::array<std::uint8_t, 5> mouse_press {};
@@ -84,24 +96,65 @@ struct gamepad_t {
};
struct input_t {
input_t(safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event)
: active_gamepad_state {},
enum shortkey_e {
CTRL = 0x1,
ALT = 0x2,
SHIFT = 0x4,
SHORTCUT = CTRL | ALT | SHIFT
};
input_t(
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event,
platf::rumble_queue_t rumble_queue)
: shortcutFlags {},
active_gamepad_state {},
gamepads(MAX_GAMEPADS),
touch_port_event { std::move(touch_port_event) },
rumble_queue { std::move(rumble_queue) },
mouse_left_button_timeout {},
touch_port { 0, 0, 0, 0, 0, 0, 1.0f } {}
// Keep track of alt+ctrl+shift key combo
int shortcutFlags;
std::uint16_t active_gamepad_state;
std::vector<gamepad_t> gamepads;
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event;
platf::rumble_queue_t rumble_queue;
util::ThreadPool::task_id_t mouse_left_button_timeout;
input::touch_port_t touch_port;
};
using namespace std::literals;
/**
* Apply shortcut based on VKEY
* On success
* return > 0
* On nothing
* return 0
*/
inline int apply_shortcut(short keyCode) {
constexpr auto VK_F1 = 0x70;
constexpr auto VK_F13 = 0x7C;
BOOST_LOG(debug) << "Apply Shortcut: 0x"sv << util::hex((std::uint8_t)keyCode).to_string_view();
if(keyCode >= VK_F1 && keyCode <= VK_F13) {
mail::man->event<int>(mail::switch_display)->raise(keyCode - VK_F1);
return 1;
}
switch(keyCode) {
case 0x4E /* VKEY_N */:
display_cursor = !display_cursor;
return 1;
}
return 0;
}
void print(PNV_REL_MOUSE_MOVE_PACKET packet) {
BOOST_LOG(debug)
@@ -146,7 +199,8 @@ void print(PNV_KEYBOARD_PACKET packet) {
}
void print(PNV_MULTI_CONTROLLER_PACKET packet) {
BOOST_LOG(debug)
// Moonlight spams controller packet even when not necessary
BOOST_LOG(verbose)
<< "--begin controller packet--"sv << std::endl
<< "controllerNumber ["sv << packet->controllerNumber << ']' << std::endl
<< "activeGamepadMask ["sv << util::hex(packet->activeGamepadMask).to_string_view() << ']' << std::endl
@@ -192,15 +246,11 @@ void print(void *input) {
}
void passthrough(std::shared_ptr<input_t> &input, PNV_REL_MOUSE_MOVE_PACKET packet) {
display_cursor = true;
input->mouse_left_button_timeout = DISABLE_LEFT_BUTTON_DELAY;
platf::move_mouse(platf_input, util::endian::big(packet->deltaX), util::endian::big(packet->deltaY));
}
void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET packet) {
display_cursor = true;
if(input->mouse_left_button_timeout == DISABLE_LEFT_BUTTON_DELAY) {
input->mouse_left_button_timeout = ENABLE_LEFT_BUTTON_DELAY;
}
@@ -251,8 +301,6 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
auto constexpr BUTTON_LEFT = 0x01;
auto constexpr BUTTON_RIGHT = 0x03;
display_cursor = true;
auto release = packet->action == BUTTON_RELEASED;
auto button = util::endian::big(packet->button);
@@ -311,46 +359,86 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
platf::button_mouse(platf_input, button, release);
}
void repeat_key(short key_code) {
// If key no longer pressed, stop repeating
if(!key_press[key_code]) {
task_id = nullptr;
return;
}
platf::keyboard(platf_input, key_code & 0x00FF, false);
task_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code).task_id;
}
short map_keycode(short keycode) {
keycode &= 0x00FF;
switch(keycode) {
case 0x10:
return 0xA0;
case 0x11:
return 0xA2;
case 0x12:
return 0xA4;
auto it = config::input.keybindings.find(keycode);
if(it != std::end(config::input.keybindings)) {
return it->second;
}
return keycode;
}
/**
* Update flags for keyboard shortcut combo's
*/
inline void update_shortcutFlags(int *flags, short keyCode, bool release) {
switch(keyCode) {
case VKEY_SHIFT:
case VKEY_LSHIFT:
case VKEY_RSHIFT:
if(release) {
*flags &= ~input_t::SHIFT;
}
else {
*flags |= input_t::SHIFT;
}
break;
case VKEY_CONTROL:
case VKEY_LCONTROL:
case VKEY_RCONTROL:
if(release) {
*flags &= ~input_t::CTRL;
}
else {
*flags |= input_t::CTRL;
}
break;
case VKEY_MENU:
case VKEY_LMENU:
case VKEY_RMENU:
if(release) {
*flags &= ~input_t::ALT;
}
else {
*flags |= input_t::ALT;
}
break;
}
}
void repeat_key(short key_code) {
// If key no longer pressed, stop repeating
if(!key_press[key_code]) {
key_press_repeat_id = nullptr;
return;
}
platf::keyboard(platf_input, map_keycode(key_code), false);
key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code).task_id;
}
void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
auto constexpr BUTTON_RELEASED = 0x04;
auto release = packet->keyAction == BUTTON_RELEASED;
auto keyCode = packet->keyCode & 0x00FF;
auto &pressed = key_press[packet->keyCode];
auto &pressed = key_press[keyCode];
if(!pressed) {
if(!release) {
if(task_id) {
task_pool.cancel(task_id);
// 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(input->shortcutFlags == input_t::SHORTCUT && apply_shortcut(keyCode) > 0) {
return;
}
if(key_press_repeat_id) {
task_pool.cancel(key_press_repeat_id);
}
if(config::input.key_repeat_delay.count() > 0) {
task_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_delay, packet->keyCode).task_id;
key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_delay, keyCode).task_id;
}
}
else {
@@ -365,16 +453,15 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
pressed = !release;
platf::keyboard(platf_input, map_keycode(packet->keyCode), release);
update_shortcutFlags(&input->shortcutFlags, map_keycode(keyCode), release);
platf::keyboard(platf_input, map_keycode(keyCode), release);
}
void passthrough(PNV_SCROLL_PACKET packet) {
display_cursor = true;
platf::scroll(platf_input, util::endian::big(packet->scrollAmt1));
}
int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state) {
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) {
return 0;
@@ -400,7 +487,7 @@ int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std
return -1;
}
if(platf::alloc_gamepad(platf_input, id)) {
if(platf::alloc_gamepad(platf_input, id, rumble_queue)) {
free_id(gamepadMask, id);
// allocating a gamepad failed: solution: ignore gamepads
// The implementations of platf::alloc_gamepad already has logging
@@ -416,7 +503,7 @@ int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std
}
void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET packet) {
if(updateGamepads(input->gamepads, input->active_gamepad_state, packet->activeGamepadMask)) {
if(updateGamepads(input->gamepads, input->active_gamepad_state, packet->activeGamepadMask, input->rumble_queue)) {
return;
}
@@ -442,8 +529,6 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET pa
return;
}
display_cursor = false;
std::uint16_t bf = packet->buttonFlags;
platf::gamepad_state_t gamepad_state {
bf,
@@ -552,7 +637,7 @@ void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&in
}
void reset(std::shared_ptr<input_t> &input) {
task_pool.cancel(task_id);
task_pool.cancel(key_press_repeat_id);
task_pool.cancel(input->mouse_left_button_timeout);
// Ensure input is synchronous, by using the task_pool
@@ -571,12 +656,23 @@ void reset(std::shared_ptr<input_t> &input) {
});
}
void init() {
class deinit_t : public platf::deinit_t {
public:
~deinit_t() override {
platf_input.reset();
}
};
[[nodiscard]] std::unique_ptr<platf::deinit_t> init() {
platf_input = platf::input();
return std::make_unique<deinit_t>();
}
std::shared_ptr<input_t> alloc(safe::mail_t mail) {
auto input = std::make_shared<input_t>(mail->event<input::touch_port_t>(mail::touch_port));
auto input = std::make_shared<input_t>(
mail->event<input::touch_port_t>(mail::touch_port),
mail->queue<platf::rumble_t>(mail::rumble));
// Workaround to ensure new frames will be captured when a client connects
task_pool.pushDelayed([]() {

View File

@@ -5,11 +5,12 @@
#ifndef SUNSHINE_INPUT_H
#define SUNSHINE_INPUT_H
#include <functional>
#include "platform/common.h"
#include "thread_safe.h"
namespace input {
struct input_t;
void print(void *input);
@@ -17,7 +18,7 @@ void reset(std::shared_ptr<input_t> &input);
void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data);
void init();
[[nodiscard]] std::unique_ptr<platf::deinit_t> init();
std::shared_ptr<input_t> alloc(safe::mail_t mail);

View File

@@ -24,6 +24,7 @@
#include "rtsp.h"
#include "thread_pool.h"
#include "upnp.h"
#include "version.h"
#include "video.h"
#include "platform/common.h"
@@ -45,7 +46,7 @@ bl::sources::severity_logger<int> warning(3); // Strange events
bl::sources::severity_logger<int> error(4); // Recoverable errors
bl::sources::severity_logger<int> fatal(5); // Unrecoverable errors
bool display_cursor;
bool display_cursor = true;
using text_sink = bl::sinks::asynchronous_sink<bl::sinks::text_ostream_backend>;
boost::shared_ptr<text_sink> sink;
@@ -56,23 +57,34 @@ struct NoDelete {
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
/** Print the help to stdout.
This function prints output to stdout.
*/
void print_help(const char *name) {
std::cout
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
<< std::endl
<< " Note: The configuration will be created if it doesn't exist."sv << std::endl
<< std::endl
<< " --help | print help"sv << std::endl
<< " --creds username password | set user credentials for the Web manager" << std::endl
<< " --creds username password | set user credentials for the Web manager"sv << std::endl
<< " --version | print the version of sunshine"sv << std::endl
<< std::endl
<< " flags"sv << std::endl
<< " -0 | Read PIN from stdin"sv << std::endl
<< " -1 | Do not load previously saved state and do retain any state after shutdown"sv << std::endl
<< " | Effectively starting as if for the first time without overwriting any pairings with your devices"sv << std::endl
<< " -2 | Force replacement of headers in video stream" << std::endl
<< " -p | Enable/Disable UPnP" << std::endl
<< " -2 | Force replacement of headers in video stream"sv << std::endl
<< " -p | Enable/Disable UPnP"sv << std::endl
<< std::endl;
}
/** Call the print_help function.
Calls the print_help function and then exits.
*/
namespace help {
int entry(const char *name, int argc, char *argv[]) {
print_help(name);
@@ -80,6 +92,17 @@ int entry(const char *name, int argc, char *argv[]) {
}
} // namespace help
/** Print the version details to stdout.
This function prints the version details to stdout and then exits.
*/
namespace version {
int entry(const char *name, int argc, char *argv[]) {
std::cout << PROJECT_NAME << " version: v" << PROJECT_VER << std::endl;
return 0;
}
} // namespace version
void log_flush() {
sink->flush();
}
@@ -111,10 +134,28 @@ int entry(const char *name, int argc, char *argv[]) {
std::map<std::string_view, std::function<int(const char *name, int argc, char **argv)>> cmd_to_func {
{ "creds"sv, gen_creds::entry },
{ "help"sv, help::entry }
{ "help"sv, help::entry },
{ "version"sv, version::entry }
};
int main(int argc, char *argv[]) {
util::TaskPool::task_id_t force_shutdown = nullptr;
bool shutdown_by_interrupt = false;
auto exit_guard = util::fail_guard([&shutdown_by_interrupt, &force_shutdown]() {
if(!shutdown_by_interrupt) {
return;
}
task_pool.cancel(force_shutdown);
std::cout << "Sunshine exited: Press enter to continue"sv << std::endl;
std::string _;
std::getline(std::cin, _);
});
mail::man = std::make_shared<safe::mail_raw_t>();
if(config::parse(argc, argv)) {
@@ -168,6 +209,10 @@ int main(int argc, char *argv[]) {
os << _date << log_type << view.attribute_values()[message].extract<std::string>();
});
// Flush after each log record to ensure log file contents on disk isn't stale.
// This is particularly important when running from a Windows service.
sink->locked_backend()->auto_flush(true);
bl::core::get()->add_sink(sink);
auto fg = util::fail_guard(log_flush);
@@ -189,9 +234,6 @@ int main(int argc, char *argv[]) {
task_pool.start(1);
bool shutdown_by_interrupt = false;
util::TaskPool::task_id_t force_shutdown = nullptr;
// 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]() {
@@ -221,19 +263,6 @@ int main(int argc, char *argv[]) {
shutdown_event->raise(true);
});
auto exit_guard = util::fail_guard([&shutdown_by_interrupt, &force_shutdown]() {
if(!shutdown_by_interrupt) {
return;
}
task_pool.cancel(force_shutdown);
std::cout << "Sunshine exited: Press enter to continue"sv << std::endl;
std::string _;
std::getline(std::cin, _);
});
proc::refresh(config::stream.file_apps);
auto deinit_guard = platf::init();
@@ -242,7 +271,7 @@ int main(int argc, char *argv[]) {
}
reed_solomon_init();
input::init();
auto input_deinit_guard = input::init();
if(video::init()) {
return 2;
}
@@ -311,4 +340,4 @@ int write_file(const char *path, const std::string_view &contents) {
std::uint16_t map_port(int port) {
return (std::uint16_t)((int)config::sunshine.port + port);
}
}

View File

@@ -44,9 +44,12 @@ MAIL(broadcast_shutdown);
MAIL(video_packets);
MAIL(audio_packets);
MAIL(switch_display);
// Local mail
MAIL(touch_port);
MAIL(idr);
MAIL(rumble);
#undef MAIL
} // namespace mail

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