diff --git a/.clang-format b/.clang-format index 6944ec3e..9f868d75 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,4 @@ +--- # This file is centrally managed in https://github.com//.github/ # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in # the above-mentioned repo. @@ -6,7 +7,7 @@ BasedOnStyle: LLVM AccessModifierOffset: -2 AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: true +AlignConsecutiveAssignments: Consecutive AlignOperands: Align AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false @@ -14,7 +15,7 @@ AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: Always AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Always +AllowShortIfStatementsOnASingleLine: WithoutElse AllowShortLambdasOnASingleLine: All AllowShortLoopsOnASingleLine: true AlwaysBreakAfterReturnType: None @@ -62,7 +63,7 @@ SpaceBeforeParens: Never SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 -SpacesInAngles: false +SpacesInAngles: Never SpacesInCStyleCastParentheses: false SpacesInContainerLiterals: false SpacesInParentheses: false diff --git a/.flake8 b/.flake8 index 2ea73951..2d028b2d 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,7 @@ [flake8] filename = - *.py + *.py, + *.pys max-line-length = 120 extend-exclude = venv/ diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ba507895..3371de06 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,15 +5,9 @@ blank_issues_enabled: false contact_links: - - name: Discord support - url: https://docs.lizardbyte.dev/about/support.html#discord - about: Ask questions in Discord - - name: Reddit support - url: https://www.reddit.com/r/LizardByte - about: Get community support on Reddit - - name: Facebook support - url: https://www.facebook.com/groups/lizardbyte - about: Get community support on Facebook + - name: Support Center + url: https://app.lizardbyte.dev/support + about: Official LizardByte support - name: Feature request - url: https://feedback.lizardbyte.dev + url: https://app.lizardbyte.dev/feedback about: Share your suggestions or ideas to help us improve diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e3b47ad7..b67ea638 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,14 @@ version: 2 updates: + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" + time: "00:00" + target-branch: "nightly" + open-pull-requests-limit: 10 + - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/label-actions.yml b/.github/label-actions.yml index 6d0a74a2..29496018 100644 --- a/.github/label-actions.yml +++ b/.github/label-actions.yml @@ -25,8 +25,8 @@ invalid:duplicate: invalid:support: comment: > :wave: @{issue-author}, we use the issue tracker exclusively for bug reports. - However, this issue appears to be a support request. Please use - [Discord](https://docs.lizardbyte.dev/about/support.html#discord) for support issues. Thanks. + However, this issue appears to be a support request. Please use our + [Support Center](https://app.lizardbyte.dev/support) for support issues. Thanks. close: true lock: true lock-reason: 'off-topic' diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c9e6b0df..2d367286 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -73,7 +73,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Dependencies Linux AUR run: | @@ -106,7 +106,6 @@ jobs: 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 @@ -158,7 +157,7 @@ jobs: - name: Publish AUR package if: ${{ env.aur_publish == 'true' }} - uses: KSXGitHub/github-actions-deploy-aur@v2.4.1 + uses: KSXGitHub/github-actions-deploy-aur@v2.5.0 with: pkgname: ${{ env.aur_pkg }} pkgbuild: ./artifacts/PKGBUILD @@ -172,8 +171,15 @@ jobs: build_linux_flatpak: name: Linux Flatpak - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: check_changelog + strategy: + fail-fast: false # false to test all, true to fail entire job if any fail + matrix: + arch: ['x86_64', 'aarch64'] + exclude: + # exclude `aarch64` on anything except a release triggering event + - arch: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) && '' || 'aarch64' }} steps: - name: Checkout @@ -184,11 +190,22 @@ jobs: sudo apt-get update -y sudo apt-get install -y \ cmake \ + qemu-user-static \ flatpak - sudo su $(whoami) -c 'flatpak remote-add --user --if-not-exists flathub \ + sudo su $(whoami) -c 'flatpak --user remote-add --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' + sudo su $(whoami) -c 'flatpak --user install -y flathub \ + org.flatpak.Builder \ + org.freedesktop.Platform/${{ matrix.arch }}/21.08 \ + org.freedesktop.Sdk/${{ matrix.arch }}/21.08' + + - name: Cache Flatpak build + uses: actions/cache@v3 + with: + path: ./build/.flatpak-builder + key: flatpak-${{ matrix.arch }}-${{ github.sha }} + restore-keys: | + flatpak-${{ matrix.arch }}- - name: Configure Flatpak Manifest run: | @@ -218,21 +235,29 @@ jobs: cmake -DGITHUB_CLONE_URL=${clone_url} \ -DGITHUB_BRANCH=${branch} \ -DGITHUB_COMMIT=${commit} \ - -DSUNSHINE_CONFIGURE_FLATPAK=ON \ + -DSUNSHINE_CONFIGURE_FLATPAK_MAN=ON \ -DSUNSHINE_CONFIGURE_ONLY=ON \ .. - name: Build Linux Flatpak working-directory: build run: | - sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --repo=repo --force-clean build-sunshine \ - dev.lizardbyte.sunshine.yml' - sudo su $(whoami) -c 'flatpak build-bundle ./repo ../artifacts/sunshine.flatpak dev.lizardbyte.sunshine' + sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ + --stop-at=cuda build-sunshine dev.lizardbyte.sunshine.yml' + cp -r .flatpak-builder copy-of-flatpak-builder + sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ + build-sunshine dev.lizardbyte.sunshine.yml' + rm -rf .flatpak-builder + mv copy-of-flatpak-builder .flatpak-builder + sudo su $(whoami) -c 'flatpak build-bundle --arch=${{ matrix.arch }} ./repo \ + ../artifacts/sunshine_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine' + sudo su $(whoami) -c 'flatpak build-bundle --runtime --arch=${{ matrix.arch }} ./repo \ + ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine.Debug' - name: Upload Artifacts uses: actions/upload-artifact@v3 with: - name: sunshine-linux-flatpak + name: sunshine-linux-flatpak-${{ matrix.arch }} path: artifacts/ - name: Create Release @@ -253,14 +278,8 @@ jobs: 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: @@ -280,7 +299,6 @@ jobs: build-essential \ cmake \ gcc-10 \ - git \ g++-10 \ libavdevice-dev \ libboost-filesystem-dev \ @@ -343,9 +361,8 @@ jobs: cd build cmake -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=${{ matrix.CMAKE_INSTALL_PREFIX }} \ - -DSUNSHINE_ASSETS_DIR=${{ matrix.SUNSHINE_ASSETS_DIR }} \ - -DSUNSHINE_CONFIG_DIR=${{ matrix.SUNSHINE_CONFIG_DIR }} \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DSUNSHINE_ASSETS_DIR=share/sunshine \ -DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ -DSUNSHINE_ENABLE_WAYLAND=ON \ -DSUNSHINE_ENABLE_X11=ON \ @@ -380,12 +397,9 @@ jobs: # install sunshine to the DESTDIR make install DESTDIR=AppDir - # portable home and config - # todo - this is ugly... we should use a custom AppRun script to take care of this - mv ./AppDir${{ matrix.CMAKE_INSTALL_PREFIX }}/sunshine.AppImage.* ../artifacts/ - mkdir -p ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }} - cp ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/apps.json \ - ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }}/ + # custom AppRun file + cp -f ../packaging/linux/AppImage/AppRun ./AppDir/ + chmod +x ./AppDir/AppRun # variables DESKTOP_FILE="${DESKTOP_FILE:-sunshine.desktop}" @@ -396,12 +410,6 @@ jobs: wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage chmod +x linuxdeploy-x86_64.AppImage - # # https://github.com/linuxdeploy/linuxdeploy-plugin-gtk - # sudo apt-get install libgtk-3-dev librsvg2-dev -y - # wget https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh - # chmod +x linuxdeploy-plugin-gtk.sh - # export DEPLOY_GTK_VERSION=3 - ./linuxdeploy-x86_64.AppImage \ --appdir ./AppDir \ --executable ./sunshine \ @@ -411,8 +419,6 @@ jobs: --library /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 \ --library /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 \ --output appimage - # # add this argument back if using gtk plugin - # --plugin gtk \ # move mv Sunshine*.AppImage ../artifacts/sunshine.AppImage @@ -430,14 +436,6 @@ jobs: ./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage - - name: Archive AppImage - if: ${{ matrix.type == 'appimage' }} - working-directory: artifacts - run: | - chmod +x ./sunshine.AppImage - - zip --recurse-paths --move --test ./sunshine-appimage.zip ./* - - name: Upload Artifacts uses: actions/upload-artifact@v3 with: @@ -479,7 +477,7 @@ jobs: cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DSUNSHINE_ASSETS_DIR=local/sunshine/assets \ - -DSUNSHINE_CONFIG_DIR=local/sunshine/config \ + -DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ .. make -j ${nproc} @@ -619,7 +617,7 @@ jobs: echo "$subport" subportlist="$subportlist $subport" done - echo "::set-output name=subportlist::${subportlist}" + echo "subportlist=${subportlist}" >> $GITHUB_OUTPUT - name: Run port lint for all subports run: | @@ -770,7 +768,6 @@ jobs: cd build cmake -DCMAKE_BUILD_TYPE=Release \ -DSUNSHINE_ASSETS_DIR=assets \ - -DSUNSHINE_CONFIG_DIR=config \ -G "MinGW Makefiles" \ .. mingw32-make -j2 diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 7ff83e0a..0ac82a7a 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Autoapproving - uses: hmarr/auto-approve-action@v2 + uses: hmarr/auto-approve-action@v3 with: github-token: "${{ secrets.GITHUB_TOKEN }}" @@ -44,7 +44,7 @@ jobs: steps: - name: Automerging - uses: pascalgn/automerge-action@v0.15.3 + uses: pascalgn/automerge-action@v0.15.5 env: BASE_BRANCHES: nightly GITHUB_TOKEN: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/cpp-clang-format-lint.yml b/.github/workflows/cpp-clang-format-lint.yml index 4717f70a..cc42ea10 100644 --- a/.github/workflows/cpp-clang-format-lint.yml +++ b/.github/workflows/cpp-clang-format-lint.yml @@ -28,7 +28,7 @@ jobs: FOUND=false fi - echo "::set-output name=src::${FOUND}" + echo "src=${FOUND}" >> $GITHUB_OUTPUT outputs: src: ${{ steps.check.outputs.src }} diff --git a/.github/workflows/issues-stale.yml b/.github/workflows/issues-stale.yml index 225b07de..7baf4b9a 100644 --- a/.github/workflows/issues-stale.yml +++ b/.github/workflows/issues-stale.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Stale - uses: actions/stale@v5 + uses: actions/stale@v6 with: close-issue-message: > - This issue was closed because it has been stalled for 5 days with no activity. + This issue was closed because it has been stalled for 10 days with no activity. close-pr-message: > This PR was closed because it has been stalled for 10 days with no activity. days-before-stale: 90 @@ -28,15 +28,16 @@ jobs: exempt-pr-labels: 'dependencies,l10n' stale-issue-label: 'stale' stale-issue-message: > - This issue is stale because it has been open for 30 days with no activity. - Comment or remove the stale label, otherwise this will be closed in 5 days. + This issue is stale because it has been open for 90 days with no activity. + Comment or remove the stale label, otherwise this will be closed in 10 days. stale-pr-label: 'stale' stale-pr-message: > This PR is stale because it has been open for 90 days with no activity. Comment or remove the stale label, otherwise this will be closed in 10 days. + repo-token: ${{ secrets.GH_BOT_TOKEN }} - name: Invalid Template - uses: actions/stale@v5 + uses: actions/stale@v6 with: close-issue-message: > This issue was closed because the the template was not completed after 5 days. @@ -52,3 +53,4 @@ jobs: stale-pr-label: 'invalid:template-incomplete' stale-pr-message: > Invalid PR template. + repo-token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index f89975f9..6ba44446 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -19,4 +19,4 @@ jobs: - name: Label Actions uses: dessant/label-actions@v2 with: - github-token: ${{ github.token }} + github-token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/localize.yml b/.github/workflows/localize.yml index 79674aa4..2c57c114 100644 --- a/.github/workflows/localize.yml +++ b/.github/workflows/localize.yml @@ -62,17 +62,20 @@ jobs: # print the git diff git diff locale/sunshine.po - # set the variable with minimal output - OUTPUT=$(git diff --numstat locale/sunshine.po) + # set the variable with minimal output, replacing `\t` with ` ` + OUTPUT=$(git diff --numstat locale/sunshine.po | sed -e "s#\t# #g") echo "git_diff=${OUTPUT}" >> $GITHUB_ENV - name: git reset # only run if a single line changed (date/time) and file already existed - # \t in next line is a tab character - if: ${{ env.git_diff == '1\t1\tlocale/sunshine.po' && env.new_file == 'false' }} + if: ${{ env.git_diff == '1 1 locale/sunshine.po' && env.new_file == 'false' }} run: | git reset --hard + - name: Get current date + id: date + run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: Create/Update Pull Request uses: peter-evans/create-pull-request@v4 with: @@ -86,7 +89,7 @@ jobs: title: New Babel Updates body: | Update report - - Updated with *today's* date + - Updated ${{ steps.date.outputs.date }} - Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request diff --git a/.github/workflows/release-notifier-moonlight.yml b/.github/workflows/release-notifier-moonlight.yml new file mode 100644 index 00000000..9ac896f3 --- /dev/null +++ b/.github/workflows/release-notifier-moonlight.yml @@ -0,0 +1,22 @@ +--- +name: Release Notifications (Moonlight) + +on: + release: + types: [published] + +jobs: + discord: + runs-on: ubuntu-latest + steps: + - name: discord + uses: sarisia/actions-status-discord@v1 # https://github.com/sarisia/actions-status-discord + with: + webhook: ${{ secrets.DISCORD_RELEASE_WEBHOOK_MOONLIGHT }} + nodetail: true + nofail: false + username: ${{ secrets.DISCORD_USERNAME }} + avatar_url: ${{ secrets.ORG_LOGO_URL }} + title: ${{ github.event.repository.name }} ${{ github.ref_name }} Released + description: ${{ github.event.release.body }} + color: 0xFF4500 diff --git a/.github/workflows/yaml-lint.yml b/.github/workflows/yaml-lint.yml index 83de6c23..5623c2dc 100644 --- a/.github/workflows/yaml-lint.yml +++ b/.github/workflows/yaml-lint.yml @@ -15,7 +15,25 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 + + - name: Find additional files + id: find-files + run: | + # space separated list of files + FILES=.clang-format + + # empty placeholder + FOUND="" + + for FILE in ${FILES}; do + if [ -f "$FILE" ] + then + FOUND="$FOUND $FILE" + fi + done + + echo "found=${FOUND}" >> $GITHUB_OUTPUT - name: yaml lint id: yaml-lint @@ -30,17 +48,14 @@ jobs: line-length: max: 120 truthy: - allowed-values: ['true', 'false', 'on'] # GitHub uses "on" for workflow event triggers + # GitHub uses "on" for workflow event triggers + # .clang-format file has options of "Yes" "No" that will be caught by this, so changed to "warning" + allowed-values: ['true', 'false', 'on'] check-keys: true - level: error + level: warning + file_or_dir: . ${{ steps.find-files.outputs.found }} - name: Log - run: | - echo ${{ steps.yaml-lint.outputs.logfile }} - - - name: Upload logs - uses: actions/upload-artifact@v2 if: failure() - with: - name: yamllint-logfile - path: ${{ steps.yaml-lint.outputs.logfile }} + run: | + cat "${{ steps.yaml-lint.outputs.logfile }}" >> $GITHUB_STEP_SUMMARY diff --git a/CMakeLists.txt b/CMakeLists.txt index d3e36294..cfbbfa7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,10 @@ set(PROJECT_LONG_DESCRIPTION "Sunshine is a self hosted, low latency, cloud gami 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_APPIMAGE "Configuration specific 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_FLATPAK_MAN "Configure manifest file required for Flatpak build." OFF) +option(SUNSHINE_CONFIGURE_FLATPAK "Configuration specific for Flatpak." OFF) option(SUNSHINE_CONFIGURE_PORTFILE "Configure macOS Portfile." OFF) option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF) @@ -19,7 +20,7 @@ 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}) +elseif(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) 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) @@ -93,7 +94,7 @@ if(WIN32) endif() add_compile_definitions(SUNSHINE_PLATFORM="windows") - add_subdirectory(tools) #This is temporary, only tools for Windows are needed, for now + add_subdirectory(tools) # This is temporary, only tools for Windows are needed, for now include_directories(third-party/ViGEmClient/include) @@ -421,19 +422,23 @@ else() list(APPEND SUNSHINE_COMPILE_OPTIONS -O3) endif() +# setup assets directory if(NOT SUNSHINE_ASSETS_DIR) - set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets") + set(SUNSHINE_ASSETS_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}) +if(UNIX) set(SUNSHINE_ASSETS_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_ASSETS_DIR}") - set(SUNSHINE_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_CONFIG_DIR}") endif() +# use relative assets path for AppImage... maybe for all unix +if(${SUNSHINE_CONFIGURE_APPIMAGE}) + string(REPLACE "${CMAKE_INSTALL_PREFIX}" ".${CMAKE_INSTALL_PREFIX}" SUNSHINE_ASSETS_DIR_DEF ${SUNSHINE_ASSETS_DIR}) +else() + set(SUNSHINE_ASSETS_DIR_DEF "${SUNSHINE_ASSETS_DIR}") +endif() +list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR_DEF}") + + list(APPEND CBS_EXTERNAL_LIBRARIES cbs) @@ -452,8 +457,6 @@ if(NOT WIN32) list(APPEND SUNSHINE_EXTERNAL_LIBRARIES Boost::log) endif() -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}) @@ -501,70 +504,101 @@ if(WIN32) # see options at: https://cmake.org/cmake/help/latest/cpack_gen/nsis.h install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio) install(TARGETS sunshinesvc RUNTIME DESTINATION "tools" COMPONENT sunshinesvc) + # scripts + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/firewall/" DESTINATION "scripts" COMPONENT firewall) + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/service/" DESTINATION "scripts" COMPONENT service) + + # Sunshine assets 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 + 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 + # Extra install commands # Sets permissions on the installed folder so that we can write in it + # Install service SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS - "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} - ExecWait 'icacls \\\"$INSTDIR\\\" /grant:r Users:\\\(OI\\\)\\\(CI\\\)\\\(F\\\)' - ") + "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} + ExecWait 'icacls \\\"$INSTDIR\\\" /grant:r Users:\\\(OI\\\)\\\(CI\\\)\\\(F\\\)' + ExecWait '\\\"$INSTDIR\\\\scripts\\\\add-firewall-rule.bat\\\"' + ExecWait '\\\"$INSTDIR\\\\scripts\\\\install-service.bat\\\"' + ") + + # Extra uninstall commands + # Uninstall service + set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS + "${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} + ExecWait '\\\"$INSTDIR\\\\scripts\\\\delete-firewall-rule.bat\\\"' + ExecWait '\\\"$INSTDIR\\\\scripts\\\\uninstall-service.bat\\\"' + MessageBox MB_YESNO|MB_ICONQUESTION 'Do you want to completely remove the directory $INSTDIR and all of its contents?' IDNO NoDelete + RMDir /r \\\"$INSTDIR\\\" ; skipped if no + NoDelete: + ") # 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'") + 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_EXTRA + "${CPACK_NSIS_CREATE_ICONS_EXTRA} + CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' '\$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe' + ") + set(CPACK_NSIS_DELETE_ICONS_EXTRA + "${CPACK_NSIS_DELETE_ICONS_EXTRA} + Delete '\$SMPROGRAMS\\\\$MUI_TEMP\\\\${CMAKE_PROJECT_NAME}.lnk' + ") # 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 + # set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") # TODO: doesn't work on my machine when Sunshine is already installed + + set(CPACK_NSIS_HELP_LINK "https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/installation.html") + set(CPACK_NSIS_URL_INFO_ABOUT "${CMAKE_PROJECT_HOMEPAGE_URL}") + set(CPACK_NSIS_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}/support") # 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_DESCRIPTION "${CMAKE_PROJECT_NAME} main application.") + set(CPACK_COMPONENT_APPLICATION_GROUP "core") set(CPACK_COMPONENT_APPLICATION_REQUIRED true) set(CPACK_COMPONENT_APPLICATION_DEPENDS assets) # assets - set(CPACK_COMPONENT_ASSETS_DISPLAY_NAME "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_GROUP "core") 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") + set(CPACK_COMPONENT_AUDIO_DISPLAY_NAME "audio-info") + set(CPACK_COMPONENT_AUDIO_DESCRIPTION "CLI tool providing 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") + set(CPACK_COMPONENT_DXGI_DISPLAY_NAME "dxgi-info") + set(CPACK_COMPONENT_DXGI_DESCRIPTION "CLI tool providing 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") + # service + set(CPACK_COMPONENT_SUNSHINESVC_DISPLAY_NAME "sunshinesvc") + set(CPACK_COMPONENT_SUNSHINESVC_DESCRIPTION "CLI tool providing ability to enable/disable the Sunshine service.") + set(CPACK_COMPONENT_SUNSHINESVC_GROUP "tools") + + # service scripts + set(CPACK_COMPONENT_SERVICE_DISPLAY_NAME "service-scripts") + set(CPACK_COMPONENT_SERVICE_DESCRIPTION "Scripts to enable/disable the service.") + set(CPACK_COMPONENT_SERVICE_GROUP "scripts") + set(CPACK_COMPONENT_SERVICE_DEPENDS sunshinesvc) + + # firewall scripts + set(CPACK_COMPONENT_FIREWALL_DISPLAY_NAME "firewall-scripts") + set(CPACK_COMPONENT_FIREWALL_DESCRIPTION "Scripts to enable or disable firewall rules.") + set(CPACK_COMPONENT_FIREWALL_GROUP "scripts") endif() if(APPLE) # TODO: bundle doesn't produce a valid .app use cpack -G DragNDrop @@ -573,15 +607,12 @@ if(APPLE) 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 +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 @@ -590,39 +621,35 @@ elseif(UNIX) # Installation destination dir set(CPACK_SET_DESTDIR true) if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "/usr/local/sunshine") + set(CMAKE_INSTALL_PREFIX "/usr/share/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}") + if(${SUNSHINE_CONFIGURE_APPIMAGE} OR ${SUNSHINE_CONFIGURE_FLATPAK}) + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" DESTINATION "${SUNSHINE_ASSETS_DIR}/udev/rules.d") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user") + else() + 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") + endif() - 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") + # Post install + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst") 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 + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) # This should automatically figure out dependencies, doesn't work with the current config endif() endif() diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index 0d65175e..b8613850 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -21,10 +21,8 @@ location by modifying the configuration file. Value Description ========= =========== Docker /config/ - Linux-aur /usr/share/sunshine/config/ - Linux-deb /usr/local/sunshine/config/ - Linux-rpm /usr/local/sunshine/config/ - macOS /usr/local/sunshine/config/ + Linux ~/.config/sunshine/ + macOS ~/.config/sunshine/ Windows ./config/ ========= =========== @@ -445,7 +443,28 @@ port ^^^^ Description - Set the family of ports used by Sunshine. + Set the family of ports used by Sunshine. Changing this value will offset other ports per the table below. + +.. table:: + :widths: auto + + ================ ============ =========================== + Port Description Default Port Difference from config port + ================ ============ =========================== + HTTPS 47984 TCP -5 + HTTP 47989 TCP 0 + Web 47990 TCP +1 + RTSP 48010 TCP +21 + Video 47998 UDP +9 + Control 47999 UDP +10 + Audio 48000 UDP +11 + tbd 48002 UDP +13 + ================ ============ =========================== + +.. Attention:: Custom ports are only allowed on select Moonlight clients. + +.. Todo:: Determine the function of port 48002 UDP. See + `here `_. Default ``47989`` diff --git a/docs/source/about/installation.rst b/docs/source/about/installation.rst index f1687b3d..eecdc04f 100644 --- a/docs/source/about/installation.rst +++ b/docs/source/about/installation.rst @@ -4,9 +4,12 @@ Installation ============ The recommended method for running Sunshine is to use the `binaries`_ bundled with the `latest release`_. +.. Attention:: Additional setup is required after installation. See + :ref:`Setup `. + Binaries -------- -Binaries of Sunshine are created for each release. They are available for Linux, and Windows. +Binaries of Sunshine are created for each release. They are available for Linux, macOS, and Windows. Binaries can be found in the `latest release`_. .. Tip:: Some third party packages also exist. See @@ -19,7 +22,13 @@ Docker Linux ----- -Follow the instructions for your preferred package type below. +First, follow the instructions for your preferred package type below. + +Then start sunshine with the following command, unless a start command is listed in the specified package. + +.. code-block:: bash + + sunshine AppImage ^^^^^^^^ @@ -41,6 +50,23 @@ According to AppImageLint the AppImage can run on the following distros. - [✖] CentOS 7 #. Download ``sunshine-appimage.zip`` and extract the contents to your home directory. +#. Open terminal and run the following code. + + .. code-block:: bash + + ./sunshine.AppImage --install + +Start: + + .. code-block:: bash + + ./sunshine.AppImage --install && ./sunshine.AppImage + +Uninstall: + + .. code-block:: bash + + ./sunshine.AppImage --remove AUR Package ^^^^^^^^^^^ @@ -48,10 +74,16 @@ AUR Package .. code-block:: bash - git clone https://aur.archlinux.org/sunshine-git.git - cd sunshine-git + git clone https://aur.archlinux.org/sunshine.git + cd sunshine makepkg -fi +Uninstall: + + .. code-block:: bash + + pacman -R sunshine + Debian Package ^^^^^^^^^^^^^^ .. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:deb?logo=github&style=for-the-badge @@ -65,13 +97,17 @@ Debian Package .. Tip:: You can double click the deb file to see details about the package and begin installation. +Uninstall: + + .. code-block:: bash + + sudo apt remove sunshine + Flatpak Package ^^^^^^^^^^^^^^^ .. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:flatpak?logo=github&style=for-the-badge :alt: GitHub issues by-label -.. Todo:: This package needs to have CUDA added. - #. Install `Flatpak `_ as required. #. Download ``sunshine.flatpak`` and run the following code. @@ -85,6 +121,18 @@ Flatpak Package flatpak install --user sunshine.flatpak +Start: + + .. code-block:: bash + + flatpak run dev.lizardbyte.sunshine + +Uninstall: + + .. code-block:: bash + + flatpak uninstall --delete-data sunshine.flatpak + RPM Package ^^^^^^^^^^^ .. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/pkg:rpm?logo=github&style=for-the-badge @@ -105,41 +153,62 @@ RPM Package .. Tip:: You can double click the rpm file to see details about the package and begin installation. +Uninstall: + + .. code-block:: bash + + sudo dnf remove sunshine + macOS ----- .. image:: https://img.shields.io/github/issues/lizardbyte/sunshine/os:macos?logo=github&style=for-the-badge :alt: GitHub issues by-label pkg - .. Warning:: The `pkg` does not include runtime dependencies and should be considered experimental. +^^^ +.. Warning:: The `pkg` does not include runtime dependencies and should be considered experimental. - #. Download the ``sunshine.pkg`` file and install it as normal. +#. Download the ``sunshine.pkg`` file and install it as normal. + +Uninstall: + + .. code-block:: bash + + cd /etc/sunshine/assets + uninstall_pkg.sh Portfile - #. Install `MacPorts `_ - #. Update the Macports sources. +^^^^^^^^ +#. Install `MacPorts `_ +#. Update the Macports sources. - .. code-block:: bash + .. code-block:: bash - sudo nano /opt/local/etc/macports/sources.conf + sudo nano /opt/local/etc/macports/sources.conf - Add this line, replacing your username, below the line that starts with ``rsync``. + Add this line, replacing your username, below the line that starts with ``rsync``. - file://Users//ports + ``file:///Users//ports`` - ``Ctrl+x``, then ``Y`` to exit and save changes. + ``Ctrl+x``, then ``Y`` to exit and save changes. - #. Download the ``Portfile`` to ``~/Downloads`` and run the following code. +#. Download the ``Portfile`` to ``~/Downloads`` and run the following code. - .. code-block:: bash + .. code-block:: bash - mkdir -p ~/ports/multimedia/sunshine - mv ~/Downlaods/Portfile ~/ports/multimedia/sunshine - cd ~/ports - portindex - sudo port install sunshine + mkdir -p ~/ports/multimedia/sunshine + mv ~/Downloads/Portfile ~/ports/multimedia/sunshine/ + cd ~/ports + portindex + sudo port install sunshine - #. The first time you start Sunshine, you will be asked to grant access to screen recording and your microphone. +#. The first time you start Sunshine, you will be asked to grant access to screen recording and your microphone. + +Uninstall: + + .. code-block:: bash + + sudo port uninstall sunshine Windows ------- @@ -149,11 +218,18 @@ Windows .. 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`` +Installer +^^^^^^^^^ +#. Download and install ``sunshine-windows.exe`` -Standalone option: - #. Download and extract ``sunshine-windows.zip`` +To uninstall, find Sunshine in the list `here `_ and select "Uninstall" from the overflow +menu. Different versions of Windows may provide slightly different steps for uninstall. + +Standalone +^^^^^^^^^^ +#. Download and extract ``sunshine-windows.zip`` + +To uninstall, delete the extracted directory which contains the ``sunshine.exe`` file. .. _latest release: https://github.com/LizardByte/Sunshine/releases/latest .. _Dockerhub.io: https://hub.docker.com/repository/docker/lizardbyte/sunshine diff --git a/docs/source/about/usage.rst b/docs/source/about/usage.rst index 009585ed..f1012192 100644 --- a/docs/source/about/usage.rst +++ b/docs/source/about/usage.rst @@ -39,9 +39,9 @@ Usage Network ------- -Sunshine will be available on port 47990 by default. +The Sunshine user interface will be available on port 47990 by default. -.. Danger:: Do not expose port 47990, or the web ui, to the internet! +.. Warning:: Exposing ports to the internet can be dangerous. Do this at your own risk. Arguments --------- @@ -56,7 +56,8 @@ Setup Linux ^^^^^ -The deb and rpm packages handle these steps automatically. The AppImage does not, third party packages may not as well. +The deb, rpm, and AppImage packages handle these steps automatically. The flatpak does not, third party packages +also may not. Sunshine needs access to `uinput` to create mouse and gamepad events. @@ -105,7 +106,7 @@ Sunshine needs access to `uinput` to create mouse and gamepad events. aur /usr/bin/sunshine ✔ deb /usr/bin/sunshine ✔ rpm /usr/bin/sunshine ✔ - AppImage ~/sunshine.AppImage ✖ + AppImage ~/sunshine.AppImage ✔ Flatpak flatpak run dev.lizardbyte.sunshine ✖ ======== ============================================== =============== @@ -169,9 +170,11 @@ All shortcuts start with CTRL + ALT + SHIFT, just like Moonlight Application List ---------------- +- Applications should be configured via the web UI. +- A basic understanding of working directories and commands is recommended. - You can use Environment variables in place of values - ``$(HOME)`` will be replaced by the value of ``$HOME`` -- ``$$`` will be replaced by ``$``, e.g. ``$$(HOME)`` will be replaced by ``$(HOME)`` +- ``$$`` will be replaced by ``$``, e.g. ``$$(HOME)`` will be become ``$(HOME)`` - ``env`` - Adds or overwrites Environment variables for the commands/applications run by Sunshine - ``"Variable name":"Variable value"`` - ``apps`` - The list of applications @@ -219,3 +222,4 @@ Considerations - 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. +- For the Linux flatpak you must prepend commands with ``flatpak-spawn --host``. diff --git a/docs/source/troubleshooting/linux.rst b/docs/source/troubleshooting/linux.rst index 5bac8c08..a1c8b4da 100644 --- a/docs/source/troubleshooting/linux.rst +++ b/docs/source/troubleshooting/linux.rst @@ -2,7 +2,7 @@ Linux ===== -If screencasting fails with Wayland, you may need to run the following to force screencasting with X11. +If screencasting fails with KMS, you may need to run the following to force unprivileged screencasting. .. code-block:: bash diff --git a/packaging/linux/AppImage/AppRun b/packaging/linux/AppImage/AppRun new file mode 100644 index 00000000..e9f9f3f7 --- /dev/null +++ b/packaging/linux/AppImage/AppRun @@ -0,0 +1,110 @@ +#!/bin/bash + +# custom AppRun for Sunshine AppImage + +# path of the extracted AppRun +HERE="$(dirname "$(readlink -f "${0}")")" +SUNSHINE_PATH=/usr/bin/sunshine +SUNSHINE_BIN_HERE=$HERE/usr/bin/sunshine +SUNSHINE_SHARE_HERE=$HERE/usr/share/sunshine + +# Set APPDIR when running directly from the AppDir: +if [ -z "$APPDIR" ]; then + ARGV0="AppRun" +fi + +cd "$HERE" || exit 1 + +function help() { +echo " + ------------------------------ + Sunshine AppImage package. + ------------------------------ + + sunshine.AppImage options + ------------------------ + + Usage: $ARGV0 --help, -h + ------ # This message + + $ARGV0 --install, -i + # Install input rules sunshine.service files. Restart required. + + $ARGV0 --remove, -r + # Remove input rules sunshine.service files. + + $ARGV0 --appimage-help + # Show available AppImage options + + sunshine options + ---------------- +" +# print sunshine binary help, replacing the sunshine command in usage statement +"$SUNSHINE_BIN_HERE" --help | sed -e "s#$SUNSHINE_BIN_HERE#$ARGV0#g" +} + +function install() { + # user input rules + sudo usermod -a -G input $USER + # shellcheck disable=SC2002 + cat "$SUNSHINE_SHARE_HERE/udev/rules.d/85-sunshine.rules" | sudo tee /etc/udev/85-sunshine.rules + + # sunshine service + mkdir -p ~/.config/systemd/user + cp -r "$SUNSHINE_SHARE_HERE/systemd/user/" ~/.config/systemd/ + # patch service executable path + sed -i -e "s#$SUNSHINE_PATH#$(readlink -f $ARGV0)#g" ~/.config/systemd/user/sunshine.service + + # setcap + sudo setcap cap_sys_admin+p "$(readlink -f "$SUNSHINE_BIN_HERE")" + + while true + do + read -r -p "This installation requires a reboot. Do you want to reboot NOW? [y/n] " input + + case $input in + [yY][eE][sS]|[yY]) + echo "Yes" + sudo reboot now + ;; + [nN][oO]|[nN]) + echo "No" + break + ;; + *) + echo "Invalid input..." + ;; + esac + done +} + +function remove() { + # remove input rules + sudo rm -f /etc/udev/rules.d/85-sunshine.rules + + # remove service + sudo rm -f ~/.config/systemd/user/sunshine.service +} + +# process arguments +if [ "x$1" == "xhelp" ] || [ "x$1" == "x--help" ] || [ "x$1" == "x-h" ] ; then + help + exit $? +fi + +if [ "x$1" == "xinstall" ] || [ "x$1" == "x--install" ] || [ "x$1" == "x-i" ] ; then + install + exit $? +fi + +if [ "x$1" == "xremove" ] || [ "x$1" == "x--remove" ] || [ "x$1" == "x-r" ] ; then + remove + exit $? +fi + +# create config directory if it doesn't exist +# https://github.com/LizardByte/Sunshine/issues/324 +mkdir -p ~/.config/sunshine + +# run sunshine +"$SUNSHINE_BIN_HERE" $@ diff --git a/packaging/linux/aur/PKGBUILD b/packaging/linux/aur/PKGBUILD index ede1af25..1ef6d54b 100644 --- a/packaging/linux/aur/PKGBUILD +++ b/packaging/linux/aur/PKGBUILD @@ -32,10 +32,9 @@ build() { -S "$pkgname" \ -B build \ -Wno-dev \ + -D CMAKE_INSTALL_PREFIX=/usr \ -D SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ - -D CMAKE_INSTALL_PREFIX="/usr" \ - -D SUNSHINE_ASSETS_DIR="share/sunshine/assets" \ - -D SUNSHINE_CONFIG_DIR="share/sunshine/config" \ + -D SUNSHINE_ASSETS_DIR="share/sunshine" \ -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 \ diff --git a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml index 04d3df5a..d9e64a13 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml @@ -6,16 +6,16 @@ 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 + - --device=all # access all devices + - --env=PULSE_PROP_media.category=Manager # allow sunshine to manage audio sinks + - --filesystem=home # need to save files in user's home directory + - --share=ipc # required for X11 shared memory extension + - --share=network # access network + - --socket=pulseaudio # play sounds using pulseaudio + - --socket=wayland # show windows using Wayland + - --socket=x11 # show windows using X11 + - --system-talk-name=org.freedesktop.Avahi # talk to avahi on the system bus + - --talk-name=org.freedesktop.Flatpak # talk to flatpak on the session bus cleanup: - /include @@ -23,47 +23,24 @@ cleanup: - /lib/pkgconfig - /lib/*.la - /lib/*.a - - /share + - /share/man modules: - - name: cuda + - name: boost disabled: false buildsystem: simple - only-arches: - - x86_64 - - aarch64 - cleanup: - - '*' build-commands: - - chmod u+x ./cuda.run - - ./cuda.run --silent --toolkit --toolkitpath=$FLATPAK_DEST/cuda --no-opengl-libs --no-man-page --no-drm --tmpdir=$FLATPAK_BUILDER_BUILDDIR # yamllint disable-line rule:line-length - - rm -r $FLATPAK_DEST/cuda/nsight-systems-2021.3.2 - - rm ./cuda.run - sources: - - type: file - only-arches: - - x86_64 - url: https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run - sha256: bbd87ca0e913f837454a796367473513cddef555082e4d86ed9a38659cc81f0a - dest-filename: cuda.run - - type: file - only-arches: - - aarch64 - url: https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux_sbsa.run # yamllint disable-line rule:line-length - sha256: f2c4a52e06329606c8dfb7c5ea3f4cb4c0b28f9d3fdffeeb734fcc98daf580d8 - dest-filename: cuda.run - - - name: boost - buildsystem: simple - build-commands: - - ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=system,thread,log - - ./b2 install variant=release link=static,shared runtime-link=shared cxxflags="$CXXFLAGS" linkflags="$LDFLAGS" -j $FLATPAK_BUILDER_N_JOBS # yamllint disable-line rule:line-length + - cd tools/build && bison -y -d -o src/engine/jamgram.cpp src/engine/jamgram.y + - ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=system,thread,log || cat bootstrap.log + - ./b2 install variant=release link=static,shared runtime-link=shared cxxflags="$CXXFLAGS" linkflags="$LDFLAGS" + -j $FLATPAK_BUILDER_N_JOBS sources: - type: archive - url: https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 - sha256: 475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 + url: http://archive.ubuntu.com/ubuntu/pool/main/b/boost1.74/boost1.74_1.74.0.orig.tar.xz + sha256: 2467be4af625b5ae4b3c93fc7af196a09eba39c11a7338cd9e8b356fa44d2f45 - name: ffmpeg + disabled: false config-opts: - --enable-gpl - --disable-static @@ -71,47 +48,38 @@ modules: - --disable-doc - --disable-programs - --disable-decoders - - --enable-libfontconfig - - --enable-libfreetype - - --enable-libopus - - --enable-libvorbis - - --enable-libvpx + - --disable-vdpau + - --disable-audiotoolbox + - --disable-videotoolbox + - --disable-vulkan + - --disable-sdl2 + - --disable-filters + - --disable-avfilter + - --disable-postproc + - --disable-autodetect + - --enable-nvenc + - --enable-ffnvcodec + - --enable-vaapi - --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 + - /share sources: - type: archive - url: http://archive.ubuntu.com/ubuntu/pool/universe/f/ffmpeg/ffmpeg_4.4.2.orig.tar.xz - sha256: af419a7f88adbc56c758ab19b4c708afbcae15ef09606b82b855291f6a6faa93 + url: http://archive.ubuntu.com/ubuntu/pool/universe/f/ffmpeg/ffmpeg_5.1.1.orig.tar.xz + sha256: 95bf3ff8c496511e71e958fb249e663c8c9c3de583c5bebc0f5a9745abbc0435 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 + url: http://archive.ubuntu.com/ubuntu/pool/universe/x/x264/x264_0.164.3095+gitbaee400.orig.tar.gz + sha256: 8b237e94b08c196a1da22f2f25875f10be4cff3648df4eeff21e00da8f683fc2 + - name: x265 + disabled: false buildsystem: cmake-ninja builddir: true subdir: source @@ -120,9 +88,10 @@ modules: - -DENABLE_CLI=OFF sources: - type: archive - url: https://bitbucket.org/multicoreware/x265_git/downloads/x265_3.5.tar.gz + url: http://archive.ubuntu.com/ubuntu/pool/universe/x/x265/x265_3.5.orig.tar.gz sha256: e70a3335cacacbba0b3a20ec6fecd6783932288ebc8163ad74bcc9606477cae8 - - name: ffnvcodec + + - name: nv-codec-headers no-autogen: true make-install-args: - PREFIX=${FLATPAK_DEST} @@ -130,15 +99,15 @@ modules: - '*' sources: - type: archive - url: https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n11.1.5.1.tar.gz + url: http://archive.ubuntu.com/ubuntu/pool/universe/n/nv-codec-headers/nv-codec-headers_11.1.5.1.orig.tar.gz sha256: d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c - name: avahi + disabled: false cleanup: - /bin - /lib/avahi - - /share/applications/*.desktop - - /share/avahi + - /share config-opts: - --with-distro=none - --disable-gobject @@ -161,38 +130,55 @@ modules: - --disable-doxygen-html - --disable-manpages - --disable-xmltoman + - --disable-libevent sources: - type: archive - url: https://avahi.org/download/avahi-0.8.tar.gz + url: http://archive.ubuntu.com/ubuntu/pool/main/a/avahi/avahi_0.8.orig.tar.gz sha256: 060309d7a333d38d951bc27598c677af1796934dbd98e1024e7ad8de798fedda - modules: - - name: libevent - cleanup: - - /bin - sources: - - type: archive - url: https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz # yamllint disable-line rule:line-length - sha256: 92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb - name: libevdev + disabled: false buildsystem: meson + config-opts: + - -Ddocumentation=disabled + - -Dtests=disabled cleanup: - /bin sources: - type: archive - url: https://www.freedesktop.org/software/libevdev/libevdev-1.12.1.tar.xz - sha256: 1dbba41bc516d3ca7abc0da5b862efe3ea8a7018fa6e9b97ce9d39401b22426c - 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 + url: http://archive.ubuntu.com/ubuntu/pool/main/libe/libevdev/libevdev_1.13.0+dfsg.orig.tar.xz + sha256: a882e13ef1dd6bd227318080cabf60fe5af3c06471259d3acfc9dbfb202351a7 + + - name: cuda + disabled: false + buildsystem: simple + only-arches: + - x86_64 + - aarch64 + cleanup: + - '*' + build-commands: + - chmod u+x ./cuda.run + - ./cuda.run --silent --toolkit --toolkitpath=$FLATPAK_DEST/cuda --no-opengl-libs --no-man-page --no-drm + --tmpdir=$FLATPAK_BUILDER_BUILDDIR + - rm -r $FLATPAK_DEST/cuda/nsight-systems-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: sunshine + disabled: false buildsystem: cmake no-make-install: false builddir: true @@ -202,13 +188,13 @@ modules: - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=/app - -DCMAKE_CUDA_COMPILER=/app/cuda/bin/nvcc - - -DSUNSHINE_ASSETS_DIR=assets - - -DSUNSHINE_CONFIG_DIR=config + - -DSUNSHINE_ASSETS_DIR=share/sunshine - -DSUNSHINE_EXECUTABLE_PATH=/app/bin/sunshine - -DSUNSHINE_ENABLE_WAYLAND=ON - -DSUNSHINE_ENABLE_X11=ON - -DSUNSHINE_ENABLE_DRM=ON - -DSUNSHINE_ENABLE_CUDA=ON + - -DSUNSHINE_CONFIGURE_FLATPAK=ON sources: - type: git url: '@GITHUB_CLONE_URL@' diff --git a/packaging/macos/Portfile b/packaging/macos/Portfile index 8707cedc..d440fad3 100644 --- a/packaging/macos/Portfile +++ b/packaging/macos/Portfile @@ -35,11 +35,10 @@ depends_lib port:avahi \ port:ffmpeg \ port:libopus -boost.version 1.76 +boost.version 1.80 configure.args -DCMAKE_INSTALL_PREFIX=${prefix} \ - -DSUNSHINE_ASSETS_DIR=etc/sunshine/assets \ - -DSUNSHINE_CONFIG_DIR=etc/sunshine/config + -DSUNSHINE_ASSETS_DIR=etc/sunshine/assets startupitem.create yes startupitem.executable "${prefix}/bin/{$name}" @@ -54,30 +53,6 @@ platform darwin { } } -# 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 " -# if the file doesn't exist sunshine will copy the default config to that location notes-append "Run @PROJECT_NAME@ by executing 'sunshine ', 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." diff --git a/scripts/requirements.txt b/scripts/requirements.txt index a572e249..84c26fe1 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,5 +1,5 @@ Babel==2.10.3 m2r2==0.3.2 -Sphinx==5.1.1 +Sphinx==5.3.0 sphinx-copybutton==0.5.0 sphinx-rtd-theme==1.0.0 diff --git a/src/audio.cpp b/src/audio.cpp index 2894d128..c5b6a976 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -75,7 +75,7 @@ auto control_shared = safe::make_shared(start_audio_control, stop_a void encodeThread(sample_queue_t samples, config_t config, void *channel_data) { auto packets = mail::man->queue(mail::audio_packets); - //FIXME: Pick correct opus_stream_config_t based on config.channels + // FIXME: Pick correct opus_stream_config_t based on config.channels auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])]; opus_t opus { opus_multistream_encoder_create( @@ -120,7 +120,7 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) { void capture(safe::mail_t mail, config_t config, void *channel_data) { auto shutdown_event = mail->event(mail::shutdown); - //FIXME: Pick correct opus_stream_config_t based on config.channels + // FIXME: Pick correct opus_stream_config_t based on config.channels auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])]; auto ref = control_shared.ref(); @@ -135,7 +135,7 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) { return; } - // Order of priorty: + // Order of priority: // 1. Config // 2. Virtual if available // 3. Host @@ -162,8 +162,14 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) { if(!ref->sink_flag->exchange(true, std::memory_order_acquire)) { ref->restore_sink = !config.flags[config_t::HOST_AUDIO]; + // If the sink is empty (Host has no sink!), definately switch to the virtual. + if(ref->sink.host.empty()) { + if(control->set_sink(*sink)) { + return; + } + } // If the client requests audio on the host, don't change the default sink - if(!config.flags[config_t::HOST_AUDIO] && control->set_sink(*sink)) { + else if(!config.flags[config_t::HOST_AUDIO] && control->set_sink(*sink)) { return; } } diff --git a/src/cbs.cpp b/src/cbs.cpp index e4e24571..d50bd195 100644 --- a/src/cbs.cpp +++ b/src/cbs.cpp @@ -124,9 +124,9 @@ util::buffer_t make_sps_h264(const AVCodecContext *ctx) { sps.seq_parameter_set_id = 0; sps.chroma_format_idc = 1; - sps.log2_max_frame_num_minus4 = 3; //4; + sps.log2_max_frame_num_minus4 = 3; // 4; sps.pic_order_cnt_type = 0; - sps.log2_max_pic_order_cnt_lsb_minus4 = 0; //4; + sps.log2_max_pic_order_cnt_lsb_minus4 = 0; // 4; sps.max_num_ref_frames = dpb_frame; @@ -297,4 +297,4 @@ bool validate_sps(const AVPacket *packet, int codec_id) { return ((CodedBitstreamH265Context *)ctx->priv_data)->active_sps->vui_parameters_present_flag; } -} // namespace cbs \ No newline at end of file +} // namespace cbs diff --git a/src/cbs.h b/src/cbs.h index dc772dd9..cd989b4a 100644 --- a/src/cbs.h +++ b/src/cbs.h @@ -31,4 +31,4 @@ h264_t make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet); bool validate_sps(const AVPacket *packet, int codec_id); } // namespace cbs -#endif \ No newline at end of file +#endif diff --git a/src/config.cpp b/src/config.cpp index fd887605..b7f483ac 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "config.h" #include "main.h" @@ -104,14 +105,14 @@ enum quality_e : int { enum class rc_hevc_e : int { constqp, /**< Constant QP mode */ vbr_latency, /**< Latency Constrained Variable Bitrate */ - vbr_peak, /**< Peak Contrained Variable Bitrate */ + vbr_peak, /**< Peak Constrained 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_peak, /**< Peak Constrained Variable Bitrate */ vbr_latency, /**< Latency Constrained Variable Bitrate */ }; @@ -702,7 +703,7 @@ int apply_flags(const char *line) { void apply_config(std::unordered_map &&vars) { if(!fs::exists(stream.file_apps.c_str())) { - fs::copy_file(SUNSHINE_CONFIG_DIR "/apps.json", stream.file_apps); + fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps); } for(auto &[name, val] : vars) { @@ -910,8 +911,14 @@ int parse(int argc, char *argv[]) { } } + // create appdata folder if it does not exist + if(!boost::filesystem::exists(platf::appdata().string())) { + boost::filesystem::create_directory(platf::appdata().string()); + } + + // create config file if it does not exist if(!fs::exists(sunshine.config_file)) { - fs::copy_file(SUNSHINE_CONFIG_DIR "/sunshine.conf", sunshine.config_file); + std::ofstream { sunshine.config_file }; // create empty config file } auto vars = parse_config(read_file(sunshine.config_file.c_str())); diff --git a/src/confighttp.cpp b/src/confighttp.cpp index c21089de..f5f2ce09 100644 --- a/src/confighttp.cpp +++ b/src/confighttp.cpp @@ -1,4 +1,3 @@ -// // Created by TheElixZammuto on 2021-05-09. // TODO: Authentication, better handling of routes common to nvhttp, cleanup @@ -92,7 +91,7 @@ bool authenticate(resp_https_t response, req_https_t request) { return false; } - //If credentials are shown, redirect the user to a /welcome page + // If credentials are shown, redirect the user to a /welcome page if(config::sunshine.username.empty()) { send_redirect(response, request, "/welcome"); return false; @@ -314,7 +313,7 @@ void saveApp(resp_https_t response, req_https_t request) { BOOST_LOG(fatal) << config::stream.file_apps; try { - //TODO: Input Validation + // TODO: Input Validation pt::read_json(ss, inputTree); pt::read_json(config::stream.file_apps, fileTree); @@ -335,7 +334,7 @@ void saveApp(resp_https_t response, req_https_t request) { apps_node.push_back(std::make_pair("", inputTree)); } else { - //Unfortuantely Boost PT does not allow to directly edit the array, copy should do the trick + // Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick pt::ptree newApps; int i = 0; for(const auto &kv : apps_node) { @@ -388,7 +387,7 @@ void deleteApp(resp_https_t response, req_https_t request) { return; } else { - //Unfortuantely Boost PT does not allow to directly edit the array, copy should do the trick + // Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick pt::ptree newApps; int i = 0; for(const auto &kv : apps_node) { @@ -452,7 +451,7 @@ void saveConfig(resp_https_t response, req_https_t request) { }); pt::ptree inputTree; try { - //TODO: Input Validation + // TODO: Input Validation pt::read_json(ss, inputTree); for(const auto &kv : inputTree) { std::string value = inputTree.get(kv.first); @@ -488,7 +487,7 @@ void savePassword(resp_https_t response, req_https_t request) { }); try { - //TODO: Input Validation + // TODO: Input Validation pt::read_json(ss, inputTree); auto username = inputTree.count("currentUsername") > 0 ? inputTree.get("currentUsername") : ""; auto newUsername = inputTree.get("newUsername"); @@ -544,7 +543,7 @@ void savePin(resp_https_t response, req_https_t request) { }); try { - //TODO: Input Validation + // TODO: Input Validation pt::read_json(ss, inputTree); std::string pin = inputTree.get("pin"); outputTree.put("status", nvhttp::pin(pin)); diff --git a/src/confighttp.h b/src/confighttp.h index 1e0c4a76..cae32aef 100644 --- a/src/confighttp.h +++ b/src/confighttp.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/3/19. -// #ifndef SUNSHINE_CONFIGHTTP_H #define SUNSHINE_CONFIGHTTP_H @@ -18,4 +16,4 @@ constexpr auto PORT_HTTPS = 1; void start(); } // namespace confighttp -#endif //SUNSHINE_CONFIGHTTP_H +#endif // SUNSHINE_CONFIGHTTP_H diff --git a/src/crypto.cpp b/src/crypto.cpp index 006cf7fb..45b65abc 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -1,13 +1,11 @@ -// // Created by loki on 5/31/19. -// #include "crypto.h" #include namespace crypto { using big_num_t = util::safe_ptr; -//using rsa_t = util::safe_ptr; +// using rsa_t = util::safe_ptr; using asn1_string_t = util::safe_ptr; cert_chain_t::cert_chain_t() : _certs {}, _cert_ctx { X509_STORE_CTX_new() } {} @@ -22,7 +20,7 @@ static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) { int err_code = X509_STORE_CTX_get_error(ctx); switch(err_code) { - //FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi + // FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: return 1; @@ -274,7 +272,7 @@ int cbc_t::encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_ int len; - int size = plaintext.size(); //round_to_pkcs7_padded(plaintext.size()); + int size = plaintext.size(); // round_to_pkcs7_padded(plaintext.size()); // Encrypt into the caller's buffer if(EVP_EncryptUpdate(encrypt_ctx.get(), cipher, &size, (const std::uint8_t *)plaintext.data(), plaintext.size()) != 1) { @@ -492,4 +490,4 @@ std::string rand_alphabet(std::size_t bytes, const std::string_view &alphabet) { return value; } -} // namespace crypto \ No newline at end of file +} // namespace crypto diff --git a/src/crypto.h b/src/crypto.h index 7f648311..46259d1a 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/1/19. -// #ifndef SUNSHINE_CRYPTO_H #define SUNSHINE_CRYPTO_H diff --git a/src/httpcommon.cpp b/src/httpcommon.cpp index 91074144..5f1955a6 100644 --- a/src/httpcommon.cpp +++ b/src/httpcommon.cpp @@ -44,7 +44,7 @@ int init() { if(clean_slate) { unique_id = util::uuid_t::generate().string(); - auto dir = std::filesystem::temp_directory_path() / "Sushine"sv; + auto dir = std::filesystem::temp_directory_path() / "Sunshine"sv; config::nvhttp.cert = (dir / ("cert-"s + unique_id)).string(); config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string(); } @@ -180,4 +180,4 @@ int create_creds(const std::string &pkey, const std::string &cert) { return 0; } -} // namespace http \ No newline at end of file +} // namespace http diff --git a/src/httpcommon.h b/src/httpcommon.h index 37d8451f..e1a1509a 100644 --- a/src/httpcommon.h +++ b/src/httpcommon.h @@ -16,4 +16,4 @@ extern std::string unique_id; extern net::net_e origin_pin_allowed; extern net::net_e origin_web_ui_allowed; -} // namespace http \ No newline at end of file +} // namespace http diff --git a/src/input.cpp b/src/input.cpp index 050a8687..c40cdef5 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 6/20/19. -// // define uint32_t for #include @@ -89,7 +87,7 @@ struct gamepad_t { // When emulating the HOME button, we may need to artificially release the back button. // Afterwards, the gamepad state on sunshine won't match the state on Moonlight. - // To prevent Sunshine from sending erronious input data to the active application, + // To prevent Sunshine from sending erroneous input data to the active application, // Sunshine forces the button to be in a specific state until the gamepad state matches that of // Moonlight once more. button_state_e back_button_state; @@ -316,11 +314,11 @@ void passthrough(std::shared_ptr &input, PNV_MOUSE_BUTTON_PACKET packet /*/ * When Moonlight sends mouse input through absolute coordinates, * it's possible that BUTTON_RIGHT is pressed down immediately after releasing BUTTON_LEFT. - * As a result, Sunshine will left click on hyperlinks in the browser before right clicking + * As a result, Sunshine will left-click on hyperlinks in the browser before right-clicking * * This can be solved by delaying BUTTON_LEFT, however, any delay on input is undesirable during gaming * As a compromise, Sunshine will only put delays on BUTTON_LEFT when - * absolute mouse coordinates have been send. + * absolute mouse coordinates have been sent. * * Try to make sure BUTTON_RIGHT gets called before BUTTON_LEFT is released. * @@ -428,7 +426,7 @@ void passthrough(std::shared_ptr &input, PNV_KEYBOARD_PACKET packet) { if(!pressed) { if(!release) { // A new key has been pressed down, we need to check for key combo's - // If a keycombo has been pressed down, don't pass it through + // If a key-combo has been pressed down, don't pass it through if(input->shortcutFlags == input_t::SHORTCUT && apply_shortcut(keyCode) > 0) { return; } diff --git a/src/input.h b/src/input.h index c9c0590e..ce291623 100644 --- a/src/input.h +++ b/src/input.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/20/19. -// #ifndef SUNSHINE_INPUT_H #define SUNSHINE_INPUT_H @@ -32,4 +30,4 @@ struct touch_port_t : public platf::touch_port_t { }; } // namespace input -#endif //SUNSHINE_INPUT_H +#endif // SUNSHINE_INPUT_H diff --git a/src/main.cpp b/src/main.cpp index 0f5581d6..58271f83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 5/30/19. -// #include "process.h" @@ -289,7 +287,7 @@ int main(int argc, char *argv[]) { upnp_unmap = upnp::start(); }); - //FIXME: Temporary workaround: Simple-Web_server needs to be updated or replaced + // FIXME: Temporary workaround: Simple-Web_server needs to be updated or replaced if(shutdown_event->peek()) { return 0; } diff --git a/src/main.h b/src/main.h index aa9558b3..89c4dbdc 100644 --- a/src/main.h +++ b/src/main.h @@ -1,6 +1,4 @@ -// // Created by loki on 12/22/19. -// #ifndef SUNSHINE_MAIN_H #define SUNSHINE_MAIN_H @@ -54,4 +52,4 @@ MAIL(rumble); } // namespace mail -#endif //SUNSHINE_MAIN_H +#endif // SUNSHINE_MAIN_H diff --git a/src/network.cpp b/src/network.cpp index ccf9e32f..90254899 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 12/27/19. -// #include "network.h" #include "utility.h" @@ -112,4 +110,4 @@ void free_host(ENetHost *host) { enet_host_destroy(host); } -} // namespace net \ No newline at end of file +} // namespace net diff --git a/src/network.h b/src/network.h index 88f18a40..bd371841 100644 --- a/src/network.h +++ b/src/network.h @@ -1,6 +1,4 @@ -// // Created by loki on 12/27/19. -// #ifndef SUNSHINE_NETWORK_H #define SUNSHINE_NETWORK_H @@ -32,4 +30,4 @@ net_e from_address(const std::string_view &view); host_t host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port); } // namespace net -#endif //SUNSHINE_NETWORK_H +#endif // SUNSHINE_NETWORK_H diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 67f8878c..47067d26 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 6/3/19. -// #define BOOST_BIND_GLOBAL_PLACEHOLDERS @@ -297,7 +295,7 @@ void clientpairingsecret(std::shared_ptr> &add_cer // if hash not correct, probably MITM if(std::memcmp(hash.data(), sess.clienthash.data(), hash.size())) { - //TODO: log + // TODO: log map_id_sess.erase(client.uniqueID); tree.put("root.paired", 0); diff --git a/src/nvhttp.h b/src/nvhttp.h index af077a56..ae96c6db 100644 --- a/src/nvhttp.h +++ b/src/nvhttp.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/3/19. -// #ifndef SUNSHINE_NVHTTP_H #define SUNSHINE_NVHTTP_H @@ -17,4 +15,4 @@ bool pin(std::string pin); void erase_all_clients(); } // namespace nvhttp -#endif //SUNSHINE_NVHTTP_H +#endif // SUNSHINE_NVHTTP_H diff --git a/src/platform/linux/audio.cpp b/src/platform/linux/audio.cpp index d3ac03f9..531e348a 100644 --- a/src/platform/linux/audio.cpp +++ b/src/platform/linux/audio.cpp @@ -343,12 +343,7 @@ public: } auto sink_name = get_default_sink_name(); - if(sink_name.empty()) { - BOOST_LOG(warning) << "Couldn't find an active sink"sv; - } - else { - sink.host = sink_name; - } + sink.host = sink_name; if(index.stereo == PA_INVALID_INDEX) { index.stereo = load_null(stereo, speaker::map_stereo, sizeof(speaker::map_stereo)); @@ -380,6 +375,10 @@ public: } } + if(sink_name.empty()) { + BOOST_LOG(warning) << "Couldn't find an active default sink. Continuing with virtual audio only."sv; + } + if(nullcount == 3) { sink.null = std::make_optional(sink_t::null_t { stereo, surround51, surround71 }); } @@ -388,8 +387,8 @@ public: } std::string get_default_sink_name() { - std::string sink_name = "@DEFAULT_SINK@"s; - auto alarm = safe::make_alarm(); + std::string sink_name; + auto alarm = safe::make_alarm(); cb_simple_t server_f = [&](ctx_t::pointer ctx, const pa_server_info *server_info) { if(!server_info) { @@ -397,7 +396,9 @@ public: alarm->ring(-1); } - sink_name = server_info->default_sink_name; + if(server_info->default_sink_name) { + sink_name = server_info->default_sink_name; + } alarm->ring(0); }; @@ -408,8 +409,12 @@ public: } std::string get_monitor_name(const std::string &sink_name) { - std::string monitor_name = "@DEFAULT_MONITOR@"s; - auto alarm = safe::make_alarm(); + std::string monitor_name; + auto alarm = safe::make_alarm(); + + if(sink_name.empty()) { + return monitor_name; + } cb_t sink_f = [&](ctx_t::pointer ctx, const pa_sink_info *sink_info, int eol) { if(!sink_info) { diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index 3b9257be..04763026 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -167,7 +167,7 @@ static std::uint32_t from_view(const std::string_view &string) { _CONVERT("eDP"sv, eDP); _CONVERT("DSI"sv, DSI); - BOOST_LOG(error) << "Unknown Monitor connector type ["sv << string << "]: Please report this to the Github issue tracker"sv; + BOOST_LOG(error) << "Unknown Monitor connector type ["sv << string << "]: Please report this to the GitHub issue tracker"sv; return DRM_MODE_CONNECTOR_Unknown; } diff --git a/src/process.cpp b/src/process.cpp index 7fd900c5..2b6c1507 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 12/14/19. -// #define BOOST_BIND_GLOBAL_PLACEHOLDERS @@ -47,7 +45,7 @@ int exe(const std::string &cmd, bp::environment &env, file_t &file, std::error_c int proc_t::execute(int app_id) { if(!running() && _app_id != -1) { - // previous process exited on it's own, reset _process_handle + // previous process exited on its own, reset _process_handle _process_handle = bp::group(); _app_id = -1; @@ -73,7 +71,7 @@ int proc_t::execute(int app_id) { } std::error_code ec; - //Executed when returning from function + // Executed when returning from function auto fg = util::fail_guard([&]() { terminate(); }); @@ -193,9 +191,10 @@ std::vector &proc_t::get_apps() { return _apps; } -/// Gets application image from application list. -/// Returns default image if image configuration is not set. -/// returns http content-type header compatible image type +// Gets application image from application list. +// Returns image from assets directory if found there. +// Returns default image if image configuration is not set. +// Returns http content-type header compatible image type. std::string proc_t::get_app_image(int app_id) { auto app_index = app_id - 1; if(app_index < 0 || app_index >= _apps.size()) { @@ -203,20 +202,41 @@ std::string proc_t::get_app_image(int app_id) { return SUNSHINE_ASSETS_DIR "/box.png"; } + auto default_image = SUNSHINE_ASSETS_DIR "/box.png"; auto app_image_path = _apps[app_index].image_path; if(app_image_path.empty()) { - return SUNSHINE_ASSETS_DIR "/box.png"; + // image is empty, return default box image + return default_image; } + // get the image extension and convert it to lowercase auto image_extension = std::filesystem::path(app_image_path).extension().string(); boost::to_lower(image_extension); - std::error_code code; - if(!std::filesystem::exists(app_image_path, code) || image_extension != ".png") { - return SUNSHINE_ASSETS_DIR "/box.png"; + // return the default box image if extension is not "png" + if(image_extension != ".png") { + return default_image; } - // return only "content-type" http header compatible image type. + // check if image is in assets directory + auto full_image_path = std::filesystem::path(SUNSHINE_ASSETS_DIR) / app_image_path; + if(std::filesystem::exists(full_image_path)) { + return full_image_path.string(); + } + else if(app_image_path == "./assets/steam.png") { + // handle old default steam image definition + return SUNSHINE_ASSETS_DIR "/steam.png"; + } + + // check if specified image exists + std::error_code code; + if(!std::filesystem::exists(app_image_path, code)) { + // return default box image if image does not exist + return default_image; + } + + // image is a png, and not in assets directory + // return only "content-type" http header compatible image type return app_image_path; } diff --git a/src/process.h b/src/process.h index 2b3fdad8..eab324a7 100644 --- a/src/process.h +++ b/src/process.h @@ -1,6 +1,4 @@ -// // Created by loki on 12/14/19. -// #ifndef SUNSHINE_PROCESS_H #define SUNSHINE_PROCESS_H @@ -105,4 +103,4 @@ std::optional parse(const std::string &file_name); extern proc_t proc; } // namespace proc -#endif //SUNSHINE_PROCESS_H +#endif // SUNSHINE_PROCESS_H diff --git a/src/rtsp.cpp b/src/rtsp.cpp index 983aff96..a2ffa143 100644 --- a/src/rtsp.cpp +++ b/src/rtsp.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 2/2/20. -// #define BOOST_BIND_GLOBAL_PLACEHOLDERS @@ -123,7 +121,7 @@ public: socket->read_payload(); }); - auto content_lenght = 0; + auto content_length = 0; for(auto option = req->options; option != nullptr; option = option->next) { if("Content-length"sv == option->option) { BOOST_LOG(debug) << "Found Content-Length: "sv << option->content << " bytes"sv; @@ -133,14 +131,14 @@ public: std::string_view content { option->content }; auto begin = std::find_if(std::begin(content), std::end(content), [](auto ch) { return (bool)std::isdigit(ch); }); - content_lenght = util::from_chars(begin, std::end(content)); + content_length = util::from_chars(begin, std::end(content)); break; } } - if(end - socket->crlf >= content_lenght) { - if(end - socket->crlf > content_lenght) { - BOOST_LOG(warning) << "(end - socket->crlf) > content_lenght -- "sv << (std::size_t)(end - socket->crlf) << " > "sv << content_lenght; + if(end - socket->crlf >= content_length) { + if(end - socket->crlf > content_length) { + BOOST_LOG(warning) << "(end - socket->crlf) > content_length -- "sv << (std::size_t)(end - socket->crlf) << " > "sv << content_length; } fg.disable(); @@ -271,7 +269,7 @@ public: if(ec) { BOOST_LOG(error) << "Couldn't accept incoming connections: "sv << ec.message(); - //Stop server + // Stop server clear(); return; } @@ -380,7 +378,7 @@ void launch_session_raise(launch_session_t launch_session) { } int session_count() { - // Ensure session_count is up to date + // Ensure session_count is up-to-date server.clear(false); return server.session_count(); diff --git a/src/rtsp.h b/src/rtsp.h index f038a5cf..f295e615 100644 --- a/src/rtsp.h +++ b/src/rtsp.h @@ -1,6 +1,4 @@ -// // Created by loki on 2/2/20. -// #ifndef SUNSHINE_RTSP_H #define SUNSHINE_RTSP_H @@ -27,4 +25,4 @@ void rtpThread(); } // namespace stream -#endif //SUNSHINE_RTSP_H +#endif // SUNSHINE_RTSP_H diff --git a/src/stream.cpp b/src/stream.cpp index 27fbe85a..7a357c12 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 6/5/19. -// #include "process.h" @@ -240,11 +238,10 @@ struct broadcast_ctx_t { udp::socket video_sock { io }; udp::socket audio_sock { io }; - // This is purely for adminitrative purposes. - // - // It's possible two instances of Moonlight are behind a NAT. - // From Sunshine's point of view, the ip addresses are identical - // We need some way to know what ports are already used for different streams + // This is purely for administrative purposes. + // It's possible two instances of Moonlight are behind a NAT. + // From Sunshine's point of view, the ip addresses are identical + // We need some way to know what ports are already used for different streams util::sync_t>> audio_video_connections; control_server_t control_server; @@ -767,7 +764,7 @@ void controlBroadcastThread(control_server_t *server) { } // Let all remaining connections know the server is shutting down - // reason: gracefull termination + // reason: graceful termination std::uint32_t reason = 0x80030023; control_terminate_t plaintext; @@ -932,7 +929,7 @@ void videoBroadcastThread(udp::socket &sock) { // With a fecpercentage of 255, if payload_new is broken up into more than a 100 data_shards // it will generate greater than DATA_SHARDS_MAX shards. - // Therefore, we start breaking the data up into three seperate fec blocks. + // Therefore, we start breaking the data up into three separate fec blocks. auto multi_fec_threshold = 90 * blocksize; // We can go up to 4 fec blocks, but 3 is plenty @@ -1331,7 +1328,7 @@ void join(session_t &session) { session.audioThread.join(); BOOST_LOG(debug) << "Waiting for control to end..."sv; session.controlEnd.view(); - //Reset input on session stop to avoid stuck repeated keys + // Reset input on session stop to avoid stuck repeated keys BOOST_LOG(debug) << "Resetting Input..."sv; input::reset(session.input); diff --git a/src/stream.h b/src/stream.h index b1e17b0f..8e054aa9 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/5/19. -// #ifndef SUNSHINE_STREAM_H #define SUNSHINE_STREAM_H @@ -45,4 +43,4 @@ state_e state(session_t &session); } // namespace session } // namespace stream -#endif //SUNSHINE_STREAM_H +#endif // SUNSHINE_STREAM_H diff --git a/src/sync.h b/src/sync.h index 8d67de2a..019adc9e 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,6 +1,4 @@ -// // Created by loki on 16-4-19. -// #ifndef SUNSHINE_SYNC_H #define SUNSHINE_SYNC_H @@ -92,4 +90,4 @@ private: } // namespace util -#endif //T_MAN_SYNC_H +#endif // SUNSHINE_SYNC_H diff --git a/src/task_pool.h b/src/task_pool.h index fc07e8ab..8352289c 100644 --- a/src/task_pool.h +++ b/src/task_pool.h @@ -17,7 +17,7 @@ namespace util { class _ImplBase { public: - //_unique_base_type _this_ptr; + // _unique_base_type _this_ptr; inline virtual ~_ImplBase() = default; diff --git a/src/thread_pool.h b/src/thread_pool.h index 8048e6d0..b26c8e34 100644 --- a/src/thread_pool.h +++ b/src/thread_pool.h @@ -7,7 +7,7 @@ namespace util { /* * Allow threads to execute unhindered - * while keeping full controll over the threads. + * while keeping full control over the threads. */ class ThreadPool : public TaskPool { public: diff --git a/src/thread_safe.h b/src/thread_safe.h index d1541ee9..b14b3234 100644 --- a/src/thread_safe.h +++ b/src/thread_safe.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/10/19. -// #ifndef SUNSHINE_THREAD_SAFE_H #define SUNSHINE_THREAD_SAFE_H @@ -37,7 +35,7 @@ public: _cv.notify_all(); } - // pop and view shoud not be used interchangebly + // pop and view shoud not be used interchangeably status_t pop() { std::unique_lock ul { _lock }; @@ -58,7 +56,7 @@ public: return val; } - // pop and view shoud not be used interchangebly + // pop and view shoud not be used interchangeably template status_t pop(std::chrono::duration delay) { std::unique_lock ul { _lock }; @@ -78,7 +76,7 @@ public: return val; } - // pop and view shoud not be used interchangebly + // pop and view shoud not be used interchangeably const status_t &view() { std::unique_lock ul { _lock }; @@ -508,4 +506,4 @@ inline void cleanup(mail_raw_t *mail) { } } // namespace safe -#endif //SUNSHINE_THREAD_SAFE_H +#endif // SUNSHINE_THREAD_SAFE_H diff --git a/src/upnp.cpp b/src/upnp.cpp index a8fc6f4b..a5a99e86 100644 --- a/src/upnp.cpp +++ b/src/upnp.cpp @@ -181,4 +181,4 @@ std::unique_ptr start() { return std::make_unique(std::move(urls), data, std::move(mappings)); } -} // namespace upnp \ No newline at end of file +} // namespace upnp diff --git a/src/upnp.h b/src/upnp.h index 478d69b1..2ab57df6 100644 --- a/src/upnp.h +++ b/src/upnp.h @@ -7,4 +7,4 @@ namespace upnp { [[nodiscard]] std::unique_ptr start(); } -#endif \ No newline at end of file +#endif diff --git a/src/uuid.h b/src/uuid.h index 6d8abe80..c3a026c0 100644 --- a/src/uuid.h +++ b/src/uuid.h @@ -1,6 +1,4 @@ -// // Created by loki on 8-2-19. -// #ifndef T_MAN_UUID_H #define T_MAN_UUID_H @@ -76,4 +74,4 @@ union uuid_t { } }; } // namespace util -#endif //T_MAN_UUID_H +#endif // T_MAN_UUID_H diff --git a/src/video.cpp b/src/video.cpp index f49cac95..bec77c81 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -1,6 +1,4 @@ -// // Created by loki on 6/6/19. -// #include #include @@ -225,7 +223,7 @@ public: ~swdevice_t() override {} - // Store ownsership when frame is hw_frame + // Store ownership when frame is hw_frame frame_t hw_frame; frame_t sw_frame; @@ -239,7 +237,7 @@ public: enum flag_e { DEFAULT = 0x00, PARALLEL_ENCODING = 0x01, - H264_ONLY = 0x02, // When HEVC is to heavy + H264_ONLY = 0x02, // When HEVC is too heavy LIMITED_GOP_SIZE = 0x04, // Some encoders don't like it when you have an infinite GOP_SIZE. *cough* VAAPI *cough* SINGLE_SLICE_ONLY = 0x08, // Never use multiple slices <-- Older intel iGPU's ruin it for everyone else :P }; @@ -1622,12 +1620,7 @@ retry: } int init() { - BOOST_LOG(info) << "//////////////////////////////////////////////////////////////////"sv; - BOOST_LOG(info) << "// //"sv; - BOOST_LOG(info) << "// Testing for available encoders, this may generate errors. //"sv; - BOOST_LOG(info) << "// You can safely ignore those errors. //"sv; - BOOST_LOG(info) << "// //"sv; - BOOST_LOG(info) << "//////////////////////////////////////////////////////////////////"sv; + BOOST_LOG(info) << "// Testing for available encoders, this may generate errors. You can safely ignore those errors. //"sv; KITTY_WHILE_LOOP(auto pos = std::begin(encoders), pos != std::end(encoders), { if( @@ -1643,11 +1636,7 @@ int init() { }) BOOST_LOG(info); - BOOST_LOG(info) << "//////////////////////////////////////////////////////////////"sv; - BOOST_LOG(info) << "// //"sv; - BOOST_LOG(info) << "// Ignore any errors mentioned above, they are not relevant //"sv; - BOOST_LOG(info) << "// //"sv; - BOOST_LOG(info) << "//////////////////////////////////////////////////////////////"sv; + BOOST_LOG(info) << "// Ignore any errors mentioned above, they are not relevant. //"sv; BOOST_LOG(info); if(encoders.empty()) { diff --git a/src/video.h b/src/video.h index 05df4463..6b8d6e57 100644 --- a/src/video.h +++ b/src/video.h @@ -1,6 +1,4 @@ -// // Created by loki on 6/9/19. -// #ifndef SUNSHINE_VIDEO_H #define SUNSHINE_VIDEO_H @@ -84,4 +82,4 @@ void capture( int init(); } // namespace video -#endif //SUNSHINE_VIDEO_H +#endif // SUNSHINE_VIDEO_H diff --git a/src_assets/common/config/sunshine.conf b/src_assets/common/config/sunshine.conf deleted file mode 100644 index 58dd670b..00000000 --- a/src_assets/common/config/sunshine.conf +++ /dev/null @@ -1 +0,0 @@ -# See our documentation at https://docs.lizardbyte.dev/projects/sunshine diff --git a/src_assets/linux/config/apps.json b/src_assets/linux/assets/apps.json similarity index 90% rename from src_assets/linux/config/apps.json rename to src_assets/linux/assets/apps.json index 552dabe2..4a848bd8 100644 --- a/src_assets/linux/config/apps.json +++ b/src_assets/linux/assets/apps.json @@ -14,7 +14,7 @@ "output":"steam.txt", "detached":["setsid steam steam://open/bigpicture"], - "image-path":"./assets/steam.png" + "image-path":"steam.png" } ] } diff --git a/src_assets/linux/misc/conffiles b/src_assets/linux/misc/conffiles deleted file mode 100644 index 4a35822b..00000000 --- a/src_assets/linux/misc/conffiles +++ /dev/null @@ -1,2 +0,0 @@ -/usr/local/sunshine/config/sunshine.conf -/usr/local/sunshine/config/apps.json diff --git a/src_assets/linux/misc/postinst b/src_assets/linux/misc/postinst index a42d3ca5..da617605 100644 --- a/src_assets/linux/misc/postinst +++ b/src_assets/linux/misc/postinst @@ -12,27 +12,6 @@ else echo "Warning: /etc/group not found" fi -if [ -f /usr/local/sunshine/config/sunshine.conf.old ]; then - echo "Restoring old sunshine.conf" - mv /usr/local/sunshine/config/sunshine.conf.old /usr/local/sunshine/config/sunshine.conf -fi - -if [ -f /usr/local/sunshine/config/apps.json.old ]; then - echo "Restoring old apps.json" - mv /usr/local/sunshine/config/apps.json.old /usr/local/sunshine/config/apps.json -fi - -# Update permissions on config files for Web Manager -if [ -f /usr/local/sunshine/config/apps.json ]; then - echo "chmod 666 /etc/sunshine/apps.json" - chmod 666 /usr/local/sunshine/config/apps.json -fi - -if [ -f /usr/local/sunshine/config/sunshine.conf ]; then - echo "chmod 666 /etc/sunshine/sunshine.conf" - chmod 666 /usr/local/sunshine/config/sunshine.conf -fi - # Ensure Sunshine can grab images from KMS path_to_setcap=$(which setcap) if [ -x "$path_to_setcap" ] ; then diff --git a/src_assets/linux/misc/preinst b/src_assets/linux/misc/preinst deleted file mode 100644 index 0522b5d6..00000000 --- a/src_assets/linux/misc/preinst +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -#Store backup for old config files to prevent it from being overwritten -if [ -f /usr/local/sunshine/config/sunshine.conf ]; then - cp /usr/local/sunshine/config/sunshine.conf /usr/local/sunshine/config/sunshine.conf.old -fi - -if [ -f /usr/local/sunshine/config/apps.json ]; then - cp /usr/local/sunshine/config/apps.json /usr/local/sunshine/config/apps.json.old -fi diff --git a/src_assets/macos/config/apps.json b/src_assets/macos/assets/apps.json similarity index 100% rename from src_assets/macos/config/apps.json rename to src_assets/macos/assets/apps.json diff --git a/src_assets/macos/misc/uninstall_pkg.sh b/src_assets/macos/misc/uninstall_pkg.sh index 7e136109..869f33d2 100644 --- a/src_assets/macos/misc/uninstall_pkg.sh +++ b/src_assets/macos/misc/uninstall_pkg.sh @@ -6,41 +6,10 @@ package_name=org.macports.Sunshine echo "Removing files now..." FILES=$(pkgutil --files $package_name --only-files) -remove_config=True -remove_apps=True - for file in ${FILES}; do file="/$file" - remove_current=True - if [[ $file == *sunshine.conf ]]; then - if [[ $remove_config == True ]]; then - while true; do - read -p -r "Do you wish to remove 'sunshine.conf'?" yn - case $yn in - [Yy]* ) echo "removing: $file"; rm -f "$file"; break;; - [Nn]* ) remove_config=False; remove_current=False; break;; - * ) echo "Please answer yes or no.";; - esac - done - fi - fi - if [[ $file == *apps.json ]]; then - if [[ $remove_apps == True ]]; then - while true; do - read -p -r "Do you wish to remove 'apps.conf'?" yn - case $yn in - [Yy]* ) echo "removing: $file"; rm -f "$file"; break;; - [Nn]* ) remove_apps=False; remove_current=False; break;; - * ) echo "Please answer yes or no.";; - esac - done - fi - fi - - if [[ $remove_current == True ]]; then - echo "removing: $file" - rm -f "$file" - fi + echo "removing: $file" + rm -f "$file" done echo "Removing directories now..." diff --git a/src_assets/windows/config/apps.json b/src_assets/windows/assets/apps.json similarity index 83% rename from src_assets/windows/config/apps.json rename to src_assets/windows/assets/apps.json index 419f2be4..379dd2fb 100644 --- a/src_assets/windows/config/apps.json +++ b/src_assets/windows/assets/apps.json @@ -8,7 +8,7 @@ "output":"steam.txt", "detached":["steam steam://open/bigpicture"], - "image-path":"./assets/steam.png" + "image-path":"steam.png" } ] } diff --git a/src_assets/windows/misc/firewall/add-firewall-rule.bat b/src_assets/windows/misc/firewall/add-firewall-rule.bat index 8c3e7b9e..81d5dd92 100644 --- a/src_assets/windows/misc/firewall/add-firewall-rule.bat +++ b/src_assets/windows/misc/firewall/add-firewall-rule.bat @@ -1,7 +1,10 @@ @echo off +rem Get sunshine root directory +for %%I in ("%~dp0\..") do set "ROOT_DIR=%%~fI" + set RULE_NAME=Sunshine -set PROGRAM_BIN="%~dp0sunshine.exe" +set PROGRAM_BIN="%ROOT_DIR%\sunshine.exe" rem Add the rule netsh advfirewall firewall add rule name=%RULE_NAME% dir=in action=allow protocol=tcp program=%PROGRAM_BIN% enable=yes diff --git a/tools/install-service.bat b/src_assets/windows/misc/service/install-service.bat similarity index 80% rename from tools/install-service.bat rename to src_assets/windows/misc/service/install-service.bat index 5e6fbc22..af27fec1 100644 --- a/tools/install-service.bat +++ b/src_assets/windows/misc/service/install-service.bat @@ -1,7 +1,10 @@ @echo off +rem Get sunshine root directory +for %%I in ("%~dp0\..") do set "ROOT_DIR=%%~fI" + set SERVICE_NAME=sunshinesvc -set SERVICE_BIN="%~dp0\tools\sunshinesvc.exe" +set SERVICE_BIN="%ROOT_DIR%\tools\sunshinesvc.exe" set SERVICE_START_TYPE=auto rem Check if sunshinesvc already exists diff --git a/tools/uninstall-service.bat b/src_assets/windows/misc/service/uninstall-service.bat similarity index 100% rename from tools/uninstall-service.bat rename to src_assets/windows/misc/service/uninstall-service.bat