diff --git a/.codeql-prebuild-cpp-Windows.sh b/.codeql-prebuild-cpp-Windows.sh index 0ada468e..b0c7b4cc 100644 --- a/.codeql-prebuild-cpp-Windows.sh +++ b/.codeql-prebuild-cpp-Windows.sh @@ -2,44 +2,35 @@ set -e # update pacman -pacman --noconfirm -Suy - -# install wget -pacman --noconfirm -S \ - wget - -# download working curl -wget https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst +pacman --noconfirm -Syu # install dependencies -pacman -U --noconfirm mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst -pacman -Syu --noconfirm --ignore=mingw-w64-ucrt-x86_64-curl \ - base-devel \ - diffutils \ - gcc \ - git \ - make \ - mingw-w64-ucrt-x86_64-boost \ - mingw-w64-ucrt-x86_64-cmake \ - mingw-w64-ucrt-x86_64-cppwinrt \ - mingw-w64-ucrt-x86_64-graphviz \ - mingw-w64-ucrt-x86_64-miniupnpc \ - mingw-w64-ucrt-x86_64-nlohmann-json \ - mingw-w64-ucrt-x86_64-nodejs \ - mingw-w64-ucrt-x86_64-nsis \ - mingw-w64-ucrt-x86_64-onevpl \ - mingw-w64-ucrt-x86_64-openssl \ - mingw-w64-ucrt-x86_64-opus \ - mingw-w64-ucrt-x86_64-rust \ - mingw-w64-ucrt-x86_64-toolchain +dependencies=( + "git" + "mingw-w64-ucrt-x86_64-boost" + "mingw-w64-ucrt-x86_64-cmake" + "mingw-w64-ucrt-x86_64-cppwinrt" + "mingw-w64-ucrt-x86_64-curl-winssl" + "mingw-w64-ucrt-x86_64-miniupnpc" + "mingw-w64-ucrt-x86_64-nlohmann-json" + "mingw-w64-ucrt-x86_64-nodejs" + "mingw-w64-ucrt-x86_64-nsis" + "mingw-w64-ucrt-x86_64-onevpl" + "mingw-w64-ucrt-x86_64-openssl" + "mingw-w64-ucrt-x86_64-opus" + "mingw-w64-ucrt-x86_64-toolchain" +) +pacman -S --noconfirm "${dependencies[@]}" # build mkdir -p build -cd build || exit 1 cmake \ + -B build \ + -G Ninja \ + -S . \ -DBUILD_DOCS=OFF \ - -G "MinGW Makefiles" .. -mingw32-make -j"$(nproc)" + -DBUILD_WERROR=ON +ninja -C build # skip autobuild echo "skip_autobuild=true" >> "$GITHUB_OUTPUT" diff --git a/.codeql-prebuild-cpp-macOS.sh b/.codeql-prebuild-cpp-macOS.sh index 0a505136..7fbc090a 100644 --- a/.codeql-prebuild-cpp-macOS.sh +++ b/.codeql-prebuild-cpp-macOS.sh @@ -2,22 +2,28 @@ set -e # install dependencies -brew install \ - boost \ - cmake \ - miniupnpc \ - node \ - opus \ - pkg-config +dependencies=( + "boost" + "cmake" + "miniupnpc" + "ninja" + "node" + "openssl@3" + "opus" + "pkg-config" +) +brew install "${dependencies[@]}" # build mkdir -p build -cd build || exit 1 cmake \ + -B build \ + -G Ninja \ + -S . \ -DBOOST_USE_STATIC=OFF \ -DBUILD_DOCS=OFF \ - -G "Unix Makefiles" .. -make -j"$(sysctl -n hw.logicalcpu)" + -DBUILD_WERROR=ON +ninja -C build # skip autobuild echo "skip_autobuild=true" >> "$GITHUB_OUTPUT" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..e9faf5e9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,13 @@ +--- +# 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. + +blank_issues_enabled: false +contact_links: + - name: Support Center + url: https://app.lizardbyte.dev/support + about: Official LizardByte support + - name: Discussions + url: https://github.com/orgs/LizardByte/discussions + about: Community discussions, questions, and feature requests diff --git a/.github/workflows/update-flathub-repo.yml b/.github/workflows/update-flathub-repo.yml new file mode 100644 index 00000000..15580f23 --- /dev/null +++ b/.github/workflows/update-flathub-repo.yml @@ -0,0 +1,187 @@ +--- +# This action is a candidate to centrally manage in https://github.com//.github/ +# If more Flathub applications are developed, consider moving this action to the organization's .github repository, +# using the `flathub-pkg` repository label to identify repositories that should trigger this workflow. + +# Update Flathub on release events. + +name: Update flathub repo + +on: + release: + types: [released] + +concurrency: + group: "${{ github.workflow }}-${{ github.event.release.tag_name }}" + cancel-in-progress: true + +jobs: + update-flathub-repo: + env: + FLATHUB_PKG: dev.lizardbyte.app.${{ github.event.repository.name }} + if: >- + github.repository_owner == 'LizardByte' + runs-on: ubuntu-latest + steps: + - name: Check if flathub repo + env: + TOPIC: flathub-pkg + id: check-label + uses: actions/github-script@v7 + with: + script: | + const topic = process.env.TOPIC; + console.log(`Checking if repo has topic: ${topic}`); + + const repoTopics = await github.rest.repos.getAllTopics({ + owner: context.repo.owner, + repo: context.repo.repo + }); + console.log(`Repo topics: ${repoTopics.data.names}`); + + const hasTopic = repoTopics.data.names.includes(topic); + console.log(`Has topic: ${hasTopic}`); + + core.setOutput('hasTopic', hasTopic); + + - name: Check if latest GitHub release + id: check-release + if: >- + steps.check-label.outputs.hasTopic == 'true' + uses: actions/github-script@v7 + with: + script: | + const latestRelease = await github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo + }); + + core.setOutput('isLatestRelease', latestRelease.data.tag_name === context.payload.release.tag_name); + + - name: Checkout + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: actions/checkout@v4 + + - name: Checkout flathub-repo + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: actions/checkout@v4 + with: + repository: "flathub/${{ env.FLATHUB_PKG }}" + path: "flathub/${{ env.FLATHUB_PKG }}" + + - name: Clean up legacy files + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + working-directory: flathub/${{ env.FLATHUB_PKG }} + run: | + rm -rf ./* + + - name: Copy github files + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + working-directory: flathub/${{ env.FLATHUB_PKG }} + run: | + mkdir -p .github/ISSUE_TEMPLATE + + # sponsors + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/FUNDING.yml \ + -o .github/FUNDING.yml + # pull request template + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/pull_request_template.md \ + -o .github/pull_request_template.md + # issue config + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/ISSUE_TEMPLATE/config.yml \ + -o .github/ISSUE_TEMPLATE/config.yml + + - name: Download release asset + id: download + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: robinraju/release-downloader@v1.11 + with: + repository: "${{ github.repository }}" + tag: "${{ github.event.release.tag_name }}" + fileName: "flathub.tar.gz" + tarBall: false + zipBall: false + out-file-path: "flathub/${{ env.FLATHUB_PKG }}" + extract: true + + - name: Delete arhive + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + rm -f flathub/${{ env.FLATHUB_PKG }}/flathub.tar.gz + + - name: Update metainfo.xml + id: update_metainfo + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + xml_file="flathub/${{ env.FLATHUB_PKG }}/${{ env.FLATHUB_PKG }}.metainfo.xml" + + # Extract release information + version="${{ github.event.release.tag_name }}" && version="${version#v}" + date="${{ github.event.release.published_at }}" && date="${date%%T*}" + changelog="${{ github.event.release.body }}" && changelog="${changelog//&/&}" && \ + changelog="${changelog///>}" + + # Store the old release information into a temp file to be used for precise replacement + tmpfile=$(mktemp) + + # Match the existing block, replace it with the new data + awk -v version="$version" -v date="$date" -v changelog="$changelog" ' + BEGIN { replaced = 0 } + // { + if (!replaced) { + print "" + print "

" changelog "

" + print "
" + replaced = 1 + } + } + !// && !/<\/release>/ { print $0 } + ' "$xml_file" > "$tmpfile" + + # Move the updated file back to the original location + mv "$tmpfile" "$xml_file" + + - name: Update submodule + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + # Get the current commit of the submodule in the main repository + git submodule update --init packaging/linux/flatpak/deps/shared-modules + cd ${{ github.workspace }}/packaging/linux/flatpak/deps/shared-modules + main_commit=$(git rev-parse HEAD) + + # update submodules + cd ${{ github.workspace }}/flathub/${{ env.FLATHUB_PKG }} + git submodule update --init shared-modules + cd shared-modules + git checkout $main_commit + + - name: Create/Update Pull Request + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' && + fromJson(steps.download.outputs.downloaded_files)[0] + uses: peter-evans/create-pull-request@v7 + with: + path: "flathub/${{ env.FLATHUB_PKG }}" + token: ${{ secrets.GH_BOT_TOKEN }} + commit-message: Update ${{ env.FLATHUB_PKG }} to ${{ github.event.release.tag_name }} + branch: bot/bump-${{ env.FLATHUB_PKG }}-${{ github.event.release.tag_name }} + delete-branch: true + title: "chore: Update ${{ env.FLATHUB_PKG }} to ${{ github.event.release.tag_name }}" + body: ${{ github.event.release.body }} diff --git a/.gitmodules b/.gitmodules index d373dbce..23e46b73 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ +[submodule "packaging/linux/flatpak/deps/flatpak-builder-tools"] + path = packaging/linux/flatpak/deps/flatpak-builder-tools + url = https://github.com/flatpak/flatpak-builder-tools.git + branch = master [submodule "packaging/linux/flatpak/deps/shared-modules"] path = packaging/linux/flatpak/deps/shared-modules url = https://github.com/flathub/shared-modules diff --git a/CMakeLists.txt b/CMakeLists.txt index 81dbc6c6..25c7109e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) # `CMAKE_CUDA_ARCHITECTURES` requires 3.18 -# set_source_files_properties requires 3.18 +# `set_source_files_properties` requires 3.18 +# `cmake_path(CONVERT ... TO_NATIVE_PATH_LIST ...)` requires 3.20 # todo - set this conditionally project(Apollo VERSION 0.0.0 diff --git a/cmake/compile_definitions/linux.cmake b/cmake/compile_definitions/linux.cmake index d90f5dc6..94465abe 100644 --- a/cmake/compile_definitions/linux.cmake +++ b/cmake/compile_definitions/linux.cmake @@ -227,6 +227,14 @@ else() endif() endif() +# AppImage and Flatpak +if (${SUNSHINE_BUILD_APPIMAGE}) + list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_BUILD_APPIMAGE=1) +endif () +if (${SUNSHINE_BUILD_FLATPAK}) + list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_BUILD_FLATPAK=1) +endif () + list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/src/platform/linux/publish.cpp" "${CMAKE_SOURCE_DIR}/src/platform/linux/graphics.h" diff --git a/cmake/dependencies/Boost_Sunshine.cmake b/cmake/dependencies/Boost_Sunshine.cmake index 6615a389..72ab5443 100644 --- a/cmake/dependencies/Boost_Sunshine.cmake +++ b/cmake/dependencies/Boost_Sunshine.cmake @@ -3,7 +3,7 @@ # include_guard(GLOBAL) -set(BOOST_VERSION 1.85) +set(BOOST_VERSION 1.86) set(BOOST_COMPONENTS filesystem locale @@ -15,7 +15,7 @@ if(BOOST_USE_STATIC) set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103 endif() -find_package(Boost ${BOOST_VERSION} COMPONENTS ${BOOST_COMPONENTS}) +find_package(Boost CONFIG ${BOOST_VERSION} COMPONENTS ${BOOST_COMPONENTS}) if(NOT Boost_FOUND) message(STATUS "Boost v${BOOST_VERSION}.x package not found in the system. Falling back to FetchContent.") include(FetchContent) @@ -39,9 +39,9 @@ if(NOT Boost_FOUND) set(BOOST_INCLUDE_LIBRARIES ${BOOST_COMPONENTS}) set(BOOST_URL - "https://github.com/boostorg/boost/releases/download/boost-1.85.0/boost-1.85.0-cmake.tar.xz") + "https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-cmake.tar.xz") set(BOOST_HASH - "MD5=BADEA970931766604D4D5F8F4090B176") + "MD5=D02759931CEDC02ADED80402906C5EB6") if(CMAKE_VERSION VERSION_LESS "3.24.0") FetchContent_Declare( diff --git a/cmake/packaging/windows.cmake b/cmake/packaging/windows.cmake index 01c2c1d8..f80f9cbd 100644 --- a/cmake/packaging/windows.cmake +++ b/cmake/packaging/windows.cmake @@ -50,8 +50,9 @@ file(COPY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" DESTINATION "${CMAKE_BINARY_DIR}/assets" PATTERN "shaders" EXCLUDE) # use junction for shaders directory -file(TO_NATIVE_PATH "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/shaders" shaders_in_build_src_native) -file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/assets/shaders" shaders_in_build_dest_native) +cmake_path(CONVERT "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/shaders" + TO_NATIVE_PATH_LIST shaders_in_build_src_native) +cmake_path(CONVERT "${CMAKE_BINARY_DIR}/assets/shaders" TO_NATIVE_PATH_LIST shaders_in_build_dest_native) execute_process(COMMAND cmd.exe /c mklink /J "${shaders_in_build_dest_native}" "${shaders_in_build_src_native}") # set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp diff --git a/cmake/prep/options.cmake b/cmake/prep/options.cmake index 151a22a7..03d65857 100644 --- a/cmake/prep/options.cmake +++ b/cmake/prep/options.cmake @@ -9,6 +9,7 @@ set(SUNSHINE_PUBLISHER_ISSUE_URL "https://github.com/ClassicOldSong/Apollo/issue option(BUILD_DOCS "Build documentation" ON) option(BUILD_TESTS "Build tests" ON) +option(NPM_OFFLINE "Use offline npm packages. You must ensure packages are in your npm cache." OFF) option(TESTS_ENABLE_PYTHON_TESTS "Enable Python tests" ON) # DirectX11 is not available in GitHub runners, so even software encoding fails diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index 3e5c5d9c..df1bbb36 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -40,8 +40,12 @@ elseif(UNIX) # configure the flatpak manifest if(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.yml ${PROJECT_FQDN}.yml @ONLY) + configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml + ${PROJECT_FQDN}.metainfo.xml @ONLY) file(COPY packaging/linux/flatpak/deps/ DESTINATION ${CMAKE_BINARY_DIR}) file(COPY packaging/linux/flatpak/modules DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY generated-sources.json DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY package-lock.json DESTINATION ${CMAKE_BINARY_DIR}) endif() endif() diff --git a/cmake/targets/common.cmake b/cmake/targets/common.cmake index b086bdd7..e928b2c5 100644 --- a/cmake/targets/common.cmake +++ b/cmake/targets/common.cmake @@ -53,10 +53,17 @@ endif() #WebUI build find_program(NPM npm REQUIRED) + +if (NPM_OFFLINE) + set(NPM_INSTALL_FLAGS "--offline") +else() + set(NPM_INSTALL_FLAGS "") +endif() + add_custom_target(web-ui ALL WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" COMMENT "Installing NPM Dependencies and Building the Web UI" - COMMAND "$<$:cmd;/C>" "${NPM}" install + COMMAND "$<$:cmd;/C>" "${NPM}" install ${NPM_INSTALL_FLAGS} COMMAND "${CMAKE_COMMAND}" -E env "SUNSHINE_BUILD_HOMEBREW=${NPM_BUILD_HOMEBREW}" "SUNSHINE_SOURCE_ASSETS_DIR=${NPM_SOURCE_ASSETS_DIR}" "SUNSHINE_ASSETS_DIR=${NPM_ASSETS_DIR}" "$<$:cmd;/C>" "${NPM}" run build # cmake-lint: disable=C0301 COMMAND_EXPAND_LISTS VERBATIM) diff --git a/docs/building.md b/docs/building.md index 6d0e7c47..851b21b1 100644 --- a/docs/building.md +++ b/docs/building.md @@ -34,12 +34,13 @@ dependencies=( "graphviz" # Optional, for docs "icu4c" # Optional, if boost is not installed "miniupnpc" + "ninja" "node" "openssl@3" "opus" "pkg-config" ) -brew install ${dependencies[@]} +brew install "${dependencies[@]}" ``` If there are issues with an SSL header that is not found: @@ -63,10 +64,11 @@ dependencies=( "graphviz" # Optional, for docs "libopus" "miniupnpc" + "ninja" "npm9" "pkgconfig" ) -sudo port install ${dependencies[@]} +sudo port install "${dependencies[@]}" ``` #### Windows @@ -86,7 +88,7 @@ dependencies=( "mingw-w64-ucrt-x86_64-boost" # Optional "mingw-w64-ucrt-x86_64-cmake" "mingw-w64-ucrt-x86_64-cppwinrt" - "mingw-w64-ucrt-x86_64-curl" + "mingw-w64-ucrt-x86_64-curl-winssl" "mingw-w64-ucrt-x86_64-graphviz" # Optional, for docs "mingw-w64-ucrt-x86_64-miniupnpc" "mingw-w64-ucrt-x86_64-nlohmann-json" @@ -97,7 +99,7 @@ dependencies=( "mingw-w64-ucrt-x86_64-opus" "mingw-w64-ucrt-x86_64-toolchain" ) -pacman -S ${dependencies[@]} +pacman -S "${dependencies[@]}" ``` ### Clone diff --git a/docs/getting_started.md b/docs/getting_started.md index d121813e..534aa5f2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -53,22 +53,24 @@ CUDA is used for NVFBC capture. sunshine-ubuntu-24.04-{arch}.deb - 12.0.0 - 525.60.13 + 12.0.0 + 525.60.13 50;52;60;61;62;70;72;75;80;86;87;89;90 - sunshine_{arch}.flatpak - - sunshine-debian-bookworm-{arch}.deb - 12.4.0 + 12.4.0 sunshine-fedora-39-{arch}.rpm - 12.5.1 + 12.5.1 sunshine.pkg.tar.zst + + 12.6.2 + 560.35.03 + sunshine_{arch}.flatpak + n/a n/a @@ -188,21 +190,30 @@ sudo dnf remove sunshine #### Flatpak @caution{Use distro-specific packages instead of the Flatpak if they are available.} -@important{The instructions provided here are for the version supplied in the [latest release][latest-release], -which does not necessarily match the version in the Flathub repository!} - Using this package requires that you have [Flatpak](https://flatpak.org/setup) installed. -##### Download +##### Download (local option) 1. Download `sunshine_{arch}.flatpak` and run the following command. @note{Replace `{arch}` with your system architecture.} -##### Install (system level) +##### Install (system level) +**Flathub** +```bash +flatpak install --system flathub dev.lizardbyte.app.Sunshine +``` + +**Local** ```bash flatpak install --system ./sunshine_{arch}.flatpak ``` ##### Install (user level) +**Flathub** +```bash +flatpak install --user flathub dev.lizardbyte.app.Sunshine +``` + +**Local** ```bash flatpak install --user ./sunshine_{arch}.flatpak ``` diff --git a/docs/third_party_packages.md b/docs/third_party_packages.md index 1793b4ce..14867299 100644 --- a/docs/third_party_packages.md +++ b/docs/third_party_packages.md @@ -5,9 +5,6 @@ ## Chocolatey [![Chocolatey](https://img.shields.io/badge/dynamic/xml.svg?color=orange&label=chocolatey&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27chocolatey%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=chocolatey)](https://community.chocolatey.org/packages/sunshine) -## Flathub -[![Flathub](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=Flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) - ## nixpkgs [![nixpkgs](https://img.shields.io/badge/dynamic/xml.svg?color=orange&label=nixpkgs&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27nix_unstable%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=nixos)](https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/servers/sunshine/default.nix) diff --git a/package.json b/package.json index a379c67e..d93d9629 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { + "name": "sunshine", + "version": "0.0.0", "scripts": { "build": "vite build --debug", "build-clean": "vite build --debug --emptyOutDir", - "dev": "vite build --watch" + "dev": "vite build --watch", + "serve": "serve ./tests/fixtures/http --no-port-switching" }, "dependencies": { "@lizardbyte/shared-web": "2024.901.195233", @@ -11,6 +14,7 @@ }, "devDependencies": { "@vitejs/plugin-vue": "4.6.2", + "serve": "14.2.3", "vite": "4.5.2", "vite-plugin-ejs": "1.6.4" } diff --git a/packaging/linux/flatpak/README.md b/packaging/linux/flatpak/README.md new file mode 100644 index 00000000..9b358b79 --- /dev/null +++ b/packaging/linux/flatpak/README.md @@ -0,0 +1,13 @@ +# Overview + +[![Flathub installs](https://img.shields.io/flathub/downloads/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) +[![Flathub Version](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) + +LizardByte has the full documentation hosted on [Read the Docs](https://sunshinestream.readthedocs.io). + +## About + +Sunshine is a self-hosted game stream host for Moonlight. + +This repo is synced from the upstream [Sunshine](https://github.com/LizardByte/Sunshine) repo. +Please report issues and contribute to the upstream repo. diff --git a/packaging/linux/flatpak/deps/flatpak-builder-tools b/packaging/linux/flatpak/deps/flatpak-builder-tools new file mode 160000 index 00000000..9a48b5e3 --- /dev/null +++ b/packaging/linux/flatpak/deps/flatpak-builder-tools @@ -0,0 +1 @@ +Subproject commit 9a48b5e30a53715f1e71a5b804ff99fa46c430a3 diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml index 8cbbd5a5..7b4f1f18 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml @@ -28,26 +28,15 @@ @PROJECT_LONG_DESCRIPTION@

-

NOTE: Allow Sunshine Virtual Input (Required)

-

sudo chown $USER /dev/uinput && echo 'KERNEL=="uinput", SUBSYSTEM=="misc", - OPTIONS+="static_node=uinput", TAG+="uaccess"' | sudo tee - /etc/udev/rules.d/60-sunshine-input.rules

-

NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, - but it is safe.

+

NOTE: Sunshine requires additional installation steps.

+

flatpak run --command=additional-install.sh @PROJECT_FQDN@

+

NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, but it is safe.

NOTE: KMS Grab (Optional)

-

sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') - flatpak run @PROJECT_FQDN@

+

sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@

- - - - - - - - + LizardByte diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml index 156b40c5..3313ed25 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml @@ -1,11 +1,10 @@ --- app-id: "@PROJECT_FQDN@" runtime: org.freedesktop.Platform -runtime-version: "22.08" +runtime-version: "23.08" # requires CUDA >= 12.2 sdk: org.freedesktop.Sdk sdk-extensions: - - org.freedesktop.Sdk.Extension.node18 - - org.freedesktop.Sdk.Extension.vala + - org.freedesktop.Sdk.Extension.node20 command: sunshine separate-locales: false finish-args: @@ -29,10 +28,6 @@ cleanup: - /lib/*.a - /share/man -build-options: - append-path: /usr/lib/sdk/vala/bin - prepend-ld-library-path: /usr/lib/sdk/vala/lib - modules: # Test dependencies - "modules/xvfb/xvfb.json" @@ -40,6 +35,7 @@ modules: # Runtime dependencies - shared-modules/libappindicator/libappindicator-gtk3-12.10.json - "modules/avahi.json" + - "modules/boost.json" - "modules/libevdev.json" - "modules/libnotify.json" - "modules/miniupnpc.json" @@ -49,23 +45,21 @@ modules: - "modules/cuda.json" - name: sunshine - disabled: false - buildsystem: cmake-ninja - no-make-install: false builddir: true build-options: - append-path: /usr/lib/sdk/node18/bin - build-args: - - --share=network - test-args: - - --share=network + append-path: /usr/lib/sdk/node20/bin env: BUILD_VERSION: "@BUILD_VERSION@" BRANCH: "@GITHUB_BRANCH@" COMMIT: "@GITHUB_COMMIT@" - npm_config_nodedir: /usr/lib/sdk/node18 + XDG_CACHE_HOME: /run/build/sunshine/flatpak-node/cache + npm_config_cache: /run/build/sunshine/flatpak-node/npm-cache + npm_config_nodedir: /usr/lib/sdk/node20 + npm_config_offline: 'true' NPM_CONFIG_LOGLEVEL: info + buildsystem: cmake-ninja config-opts: + - -DBOOST_USE_STATIC=OFF - -DBUILD_DOCS=OFF - -DBUILD_WERROR=ON - -DCMAKE_BUILD_TYPE=Release @@ -78,16 +72,20 @@ modules: - -DSUNSHINE_ENABLE_DRM=ON - -DSUNSHINE_ENABLE_CUDA=ON - -DSUNSHINE_PUBLISHER_NAME='LizardByte' - -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' - -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' - sources: - - type: git - url: "@GITHUB_CLONE_URL@" - commit: "@GITHUB_COMMIT@" + - -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' + - -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' + no-make-install: false post-install: - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/scripts/* /app/bin - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/apps.json /app/share/sunshine/apps.json run-tests: true test-rule: "" # empty to disable test-commands: - - xvfb-run tests/test_sunshine --gtest_color=yes + - npm run serve & xvfb-run tests/test_sunshine --gtest_color=yes + sources: + - generated-sources.json + - type: git + url: "@GITHUB_CLONE_URL@" + commit: "@GITHUB_COMMIT@" + - type: file + path: package-lock.json diff --git a/packaging/linux/flatpak/flathub.json b/packaging/linux/flatpak/flathub.json new file mode 100644 index 00000000..2de28147 --- /dev/null +++ b/packaging/linux/flatpak/flathub.json @@ -0,0 +1,3 @@ +{ + "disable-external-data-checker": true +} diff --git a/packaging/linux/flatpak/modules/boost.json b/packaging/linux/flatpak/modules/boost.json new file mode 100644 index 00000000..da111f64 --- /dev/null +++ b/packaging/linux/flatpak/modules/boost.json @@ -0,0 +1,16 @@ +{ + "name": "boost", + "buildsystem": "simple", + "build-commands": [ + "cd tools/build && bison -y -d -o src/engine/jamgram.cpp src/engine/jamgram.y", + "./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=filesystem,locale,log,program_options,system", + "./b2 install variant=release link=shared runtime-link=shared cxxflags=\"$CXXFLAGS\"" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-cmake.tar.xz", + "sha256": "2c5ec5edcdff47ff55e27ed9560b0a0b94b07bd07ed9928b476150e16b0efc57" + } + ] +} diff --git a/packaging/linux/flatpak/modules/cuda.json b/packaging/linux/flatpak/modules/cuda.json index 53a38c0c..3e10f2fb 100644 --- a/packaging/linux/flatpak/modules/cuda.json +++ b/packaging/linux/flatpak/modules/cuda.json @@ -19,8 +19,8 @@ "only-arches": [ "x86_64" ], - "url": "https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda_12.0.0_525.60.13_linux.run", - "sha256": "905e9b9516900839fb76064719db752439f38b8cb730b49335d8bd53ddfad392", + "url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux.run", + "sha256": "3729a89cb58f7ca6a46719cff110d6292aec7577585a8d71340f0dbac54fb237", "dest-filename": "cuda.run" }, { @@ -28,8 +28,8 @@ "only-arches": [ "aarch64" ], - "url": "https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda_12.0.0_525.60.13_linux_sbsa.run", - "sha256": "cd13e9c65d4c8f895a968706f46064d536be09f9706bce081cc864b7e4fa4544", + "url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux_sbsa.run", + "sha256": "2249408848b705c18b9eadfb5161b52e4e36fcc5753647329cce93db141e5466", "dest-filename": "cuda.run" } ] diff --git a/scripts/linux_build.sh b/scripts/linux_build.sh index f0cd3d7f..fc423a2d 100644 --- a/scripts/linux_build.sh +++ b/scripts/linux_build.sh @@ -304,7 +304,7 @@ function run_install() { add_ubuntu_deps elif [ "$distro" == "fedora" ]; then add_fedora_deps - dnf group install "Development Tools" -y + ${sudo_cmd} dnf group install "Development Tools" -y fi # Install the dependencies diff --git a/src/httpcommon.cpp b/src/httpcommon.cpp index a67943f3..cce566b4 100644 --- a/src/httpcommon.cpp +++ b/src/httpcommon.cpp @@ -197,7 +197,12 @@ namespace http { bool download_file(const std::string &url, const std::string &file) { CURL *curl = curl_easy_init(); - if (!curl) { + if (curl) { + // sonar complains about weak ssl and tls versions + // ideally, the setopts should go after the early returns; however sonar cannot detect the fix + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + } + else { BOOST_LOG(error) << "Couldn't create CURL instance"; return false; } @@ -215,16 +220,16 @@ namespace http { curl_easy_cleanup(curl); return false; } + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); -#ifdef _WIN32 - curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); -#endif + CURLcode result = curl_easy_perform(curl); if (result != CURLE_OK) { BOOST_LOG(error) << "Couldn't download ["sv << url << ", code:" << result << ']'; } + curl_easy_cleanup(curl); fclose(fp); return result == CURLE_OK; diff --git a/src/platform/common.h b/src/platform/common.h index a306b5e7..8fc7abc9 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -47,13 +47,13 @@ namespace boost { namespace filesystem { class path; } - namespace process { + namespace process::inline v1 { class child; class group; template class basic_environment; typedef basic_environment environment; - } // namespace process + } // namespace process::inline v1 } // namespace boost #endif namespace video { @@ -600,8 +600,8 @@ namespace platf { bool needs_encoder_reenumeration(); - boost::process::child - run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group); + boost::process::v1::child + run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const boost::process::v1::environment &env, FILE *file, std::error_code &ec, boost::process::v1::group *group); enum class thread_priority_e : int { low, ///< Low priority diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index c93b5aff..84b8c307 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -15,7 +15,7 @@ // lib includes #include #include -#include +#include #include #include #include @@ -352,7 +352,7 @@ get_local_ip_for_gateway() { auto working_dir = boost::filesystem::path(std::getenv("HOME")); std::string cmd = R"(xdg-open ")" + url + R"(")"; - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); std::error_code ec; auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr); if (ec) { diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 83c668eb..6be72233 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -362,6 +362,9 @@ const KeyCodeMap kKeyCodesMap[] = { CGEventSetDoubleValueField(event, kCGMouseEventDeltaY, deltaY); CGEventPost(kCGHIDEventTap, event); + // For why this is here, see: + // https://stackoverflow.com/questions/15194409/simulated-mouseevent-not-working-properly-osx + CGWarpMouseCursorPosition(location); } inline CGEventType diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index 499b6bd6..65edf076 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -23,7 +23,7 @@ #include "src/platform/common.h" #include -#include +#include using namespace std::literals; namespace fs = std::filesystem; @@ -203,7 +203,7 @@ namespace platf { boost::filesystem::path working_dir; std::string cmd = R"(open ")" + url + R"(")"; - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); std::error_code ec; auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr); if (ec) { diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index bafb8bb1..c6167886 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -7,9 +7,9 @@ #include #include -#include +#include -// We have to include boost/process.hpp before display.h due to WinSock.h, +// We have to include boost/process/v1.hpp before display.h due to WinSock.h, // but that prevents the definition of NTSTATUS so we must define it ourself. typedef long NTSTATUS; diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 1638bd62..6df7fe94 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include // prevent clang format from "optimizing" the header include order @@ -1121,7 +1121,7 @@ namespace platf { */ void open_url(const std::string &url) { - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); auto working_dir = boost::filesystem::path(); std::error_code ec; diff --git a/src/process.cpp b/src/process.cpp index 72188842..5bf41894 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -80,7 +80,7 @@ namespace proc { } void - terminate_process_group(boost::process::child &proc, boost::process::group &group, std::chrono::seconds exit_timeout) { + terminate_process_group(boost::process::v1::child &proc, boost::process::v1::group &group, std::chrono::seconds exit_timeout) { if (group.valid() && platf::process_group_running((std::uintptr_t) group.native_handle())) { if (exit_timeout.count() > 0) { // Request processes in the group to exit gracefully @@ -121,7 +121,7 @@ namespace proc { } boost::filesystem::path - find_working_directory(const std::string &cmd, boost::process::environment &env) { + find_working_directory(const std::string &cmd, boost::process::v1::environment &env) { // Parse the raw command string into parts to get the actual command portion #ifdef _WIN32 auto parts = boost::program_options::split_winmain(cmd); @@ -143,7 +143,7 @@ namespace proc { // If the cmd path is not an absolute path, resolve it using our PATH variable boost::filesystem::path cmd_path(parts.at(0)); if (!cmd_path.is_absolute()) { - cmd_path = boost::process::search_path(parts.at(0)); + cmd_path = boost::process::v1::search_path(parts.at(0)); if (cmd_path.empty()) { BOOST_LOG(error) << "Unable to find executable ["sv << parts.at(0) << "]. Is it in your PATH?"sv; return boost::filesystem::path(); @@ -500,8 +500,8 @@ namespace proc { std::error_code ec; placebo = false; terminate_process_group(_process, _process_group, _app.exit_timeout); - _process = boost::process::child(); - _process_group = boost::process::group(); + _process = boost::process::v1::child(); + _process_group = boost::process::v1::group(); for (; _app_prep_it != _app_prep_begin; --_app_prep_it) { auto &cmd = *(_app_prep_it - 1); @@ -631,7 +631,7 @@ namespace proc { } std::string - parse_env_val(boost::process::native_environment &env, const std::string_view &val_raw) { + parse_env_val(boost::process::v1::native_environment &env, const std::string_view &val_raw) { auto pos = std::begin(val_raw); auto dollar = std::find(pos, std::end(val_raw), '$'); diff --git a/src/process.h b/src/process.h index ba01384b..633ed1a1 100644 --- a/src/process.h +++ b/src/process.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include "config.h" @@ -88,7 +88,7 @@ namespace proc { proc_t( - boost::process::environment &&env, + boost::process::v1::environment &&env, std::vector &&apps): _app_id(0), _env(std::move(env)), @@ -120,7 +120,8 @@ namespace proc { private: int _app_id; - boost::process::environment _env; + + boost::process::v1::environment _env; std::shared_ptr _launch_session; @@ -131,8 +132,8 @@ namespace proc { // If no command associated with _app_id, yet it's still running bool placebo {}; - boost::process::child _process; - boost::process::group _process_group; + boost::process::v1::child _process; + boost::process::v1::group _process_group; file_t _pipe; std::vector::const_iterator _app_prep_it; @@ -172,7 +173,7 @@ namespace proc { * @param exit_timeout The timeout to wait for the process group to gracefully exit. */ void - terminate_process_group(boost::process::child &proc, boost::process::group &group, std::chrono::seconds exit_timeout); + terminate_process_group(boost::process::v1::child &proc, boost::process::v1::group &group, std::chrono::seconds exit_timeout); extern proc_t proc; } // namespace proc diff --git a/src/system_tray.cpp b/src/system_tray.cpp index fdb9c074..dd8550cd 100644 --- a/src/system_tray.cpp +++ b/src/system_tray.cpp @@ -36,7 +36,7 @@ // lib includes #include "tray/src/tray.h" #include - #include + #include // local includes #include "config.h" diff --git a/tests/fixtures/http/hello-redirect.txt b/tests/fixtures/http/hello-redirect.txt new file mode 100644 index 00000000..64a358d9 --- /dev/null +++ b/tests/fixtures/http/hello-redirect.txt @@ -0,0 +1 @@ +hello-redirect.txt diff --git a/tests/fixtures/http/hello.txt b/tests/fixtures/http/hello.txt new file mode 100644 index 00000000..f0ad0dec --- /dev/null +++ b/tests/fixtures/http/hello.txt @@ -0,0 +1 @@ +hello.txt diff --git a/tests/unit/test_httpcommon.cpp b/tests/unit/test_httpcommon.cpp index bb0bb562..3b2b37e3 100644 --- a/tests/unit/test_httpcommon.cpp +++ b/tests/unit/test_httpcommon.cpp @@ -45,9 +45,18 @@ TEST_P(DownloadFileTest, Run) { ASSERT_TRUE(http::download_file(url, path)); } +#ifdef SUNSHINE_BUILD_FLATPAK +// requires running `npm run serve` prior to running the tests +constexpr const char *URL_1 = "http://0.0.0.0:3000/hello.txt"; +constexpr const char *URL_2 = "http://0.0.0.0:3000/hello-redirect.txt"; +#else +constexpr const char *URL_1 = "https://httpbin.org/base64/aGVsbG8h"; +constexpr const char *URL_2 = "https://httpbin.org/redirect-to?url=/base64/aGVsbG8h"; +#endif + INSTANTIATE_TEST_SUITE_P( DownloadFileTests, DownloadFileTest, testing::Values( - std::make_tuple("https://httpbin.org/base64/aGVsbG8h", "hello.txt"), - std::make_tuple("https://httpbin.org/redirect-to?url=/base64/aGVsbG8h", "hello-redirect.txt"))); + std::make_tuple(URL_1, "hello.txt"), + std::make_tuple(URL_2, "hello-redirect.txt"))); diff --git a/toolchain-mingw64.cmake b/toolchain-mingw64.cmake deleted file mode 100644 index a090f58f..00000000 --- a/toolchain-mingw64.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# the name of the target operating system -SET(CMAKE_SYSTEM_NAME Windows) - -# which compilers to use for C and C++ -SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) -SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) -SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) - -# here is the target environment located -SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) -#SET(CMAKE_SYSROOT ${CMAKE_FIND_ROOT_PATH}) -#SET(CMAKE_EXE_LINKER_FLAGS "-static ${CMAKE_EXE_LINKER_FLAGS}") - -# adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search -# programs in the host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)