mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-08-10 00:52:16 +00:00
Compare commits
55 Commits
v2025.628.
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f51137eafb | ||
|
|
03bb53d591 | ||
|
|
bb6e3bc8e1 | ||
|
|
b2d3ded6f4 | ||
|
|
9f101fb546 | ||
|
|
48c2c52498 | ||
|
|
d6787c4ed4 | ||
|
|
eff88de993 | ||
|
|
b3ee60d422 | ||
|
|
99cf9ac960 | ||
|
|
4bac84ee38 | ||
|
|
7252d9e897 | ||
|
|
8bfb65ee4b | ||
|
|
f2e4f55a84 | ||
|
|
84bb4cfaf1 | ||
|
|
bce4b1b4c5 | ||
|
|
a19312bbf1 | ||
|
|
274b998ec5 | ||
|
|
31f87bbc18 | ||
|
|
2b785b3cb9 | ||
|
|
6ab24491ed | ||
|
|
77edcd047f | ||
|
|
d4fe41556c | ||
|
|
cb54e5e90a | ||
|
|
5097afdea9 | ||
|
|
1d4f5c3798 | ||
|
|
1725da216b | ||
|
|
99a757627c | ||
|
|
047cc684cf | ||
|
|
dfeeebfacf | ||
|
|
fe26129697 | ||
|
|
4478fd2a14 | ||
|
|
35f0b30845 | ||
|
|
aa7b83bdfc | ||
|
|
165e5e9b81 | ||
|
|
3cfe4e2ec5 | ||
|
|
feac80656d | ||
|
|
417007685d | ||
|
|
01f281a4a3 | ||
|
|
d96251d18f | ||
|
|
914c423338 | ||
|
|
512aa1e2aa | ||
|
|
1bc491f949 | ||
|
|
d28e221bb7 | ||
|
|
c0823c7444 | ||
|
|
2a9bb98c6e | ||
|
|
7e95d536a9 | ||
|
|
2259141bd2 | ||
|
|
5ef3f2ff5c | ||
|
|
9f399eef5c | ||
|
|
6f78404c18 | ||
|
|
5a40190830 | ||
|
|
d3ef63bd9b | ||
|
|
c0e029117d | ||
|
|
5b1da1c1ab |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,6 +1,5 @@
|
||||
# ensure dockerfiles are checked out with LF line endings
|
||||
# ensure Linux specific files are checked out with LF line endings
|
||||
Dockerfile text eol=lf
|
||||
*.dockerfile text eol=lf
|
||||
|
||||
# ensure flatpak lint json files are checked out with LF line endings
|
||||
*flatpak-lint-*.json text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
||||
17
.github/matchers/copr-ci.json
vendored
Normal file
17
.github/matchers/copr-ci.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "copr-ci-gcc",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^/?(?:[^/]+/){5}([^:]+):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
17
.github/matchers/docker.json
vendored
Normal file
17
.github/matchers/docker.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "docker-gcc",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(?:#\\d+\\s+\\d+\\.\\d+\\s+)?/?(?:[^/]+/){2}([^:]+):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
17
.github/matchers/gcc-strip3.json
vendored
Normal file
17
.github/matchers/gcc-strip3.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "gcc-strip3",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^/?(?:[^/]+/){3}([^:]+):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
29
.github/matchers/gcc.json
vendored
Normal file
29
.github/matchers/gcc.json
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "gcc",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "doxygen",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^.*?([A-Za-z]:[\\\\/][^:]+|[\\\\/][^:]+):(\\d+): ([a-zA-Z]+): (.+)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"severity": 3,
|
||||
"message": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
1088
.github/workflows/CI.yml
vendored
1088
.github/workflows/CI.yml
vendored
File diff suppressed because it is too large
Load Diff
39
.github/workflows/_docker.yml
vendored
39
.github/workflows/_docker.yml
vendored
@@ -1,39 +0,0 @@
|
||||
---
|
||||
# This workflow is centrally managed in https://github.com/LizardByte/.github/
|
||||
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
|
||||
# the above-mentioned repo.
|
||||
|
||||
name: Docker
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
call-docker:
|
||||
name: Docker
|
||||
uses: LizardByte/.github/.github/workflows/__call-docker.yml@master
|
||||
if: ${{ github.repository != 'LizardByte/.github' }}
|
||||
secrets:
|
||||
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
GH_BOT_NAME: ${{ secrets.GH_BOT_NAME }}
|
||||
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
2
.github/workflows/_release-notifier.yml
vendored
2
.github/workflows/_release-notifier.yml
vendored
@@ -20,4 +20,6 @@ jobs:
|
||||
uses: LizardByte/.github/.github/workflows/__call-release-notifier.yml@master
|
||||
if: github.repository_owner == 'LizardByte'
|
||||
secrets:
|
||||
GH_EMAIL: ${{ secrets.GH_BOT_EMAIL }}
|
||||
GH_NAME: ${{ secrets.GH_BOT_NAME }}
|
||||
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
2
.github/workflows/_update-flathub-repo.yml
vendored
2
.github/workflows/_update-flathub-repo.yml
vendored
@@ -26,4 +26,6 @@ jobs:
|
||||
uses: LizardByte/.github/.github/workflows/__call-update-flathub-repo.yml@master
|
||||
if: github.repository_owner == 'LizardByte'
|
||||
secrets:
|
||||
GH_EMAIL: ${{ secrets.GH_BOT_EMAIL }}
|
||||
GH_NAME: ${{ secrets.GH_BOT_NAME }}
|
||||
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
2
.github/workflows/_update-pacman-repo.yml
vendored
2
.github/workflows/_update-pacman-repo.yml
vendored
@@ -26,4 +26,6 @@ jobs:
|
||||
uses: LizardByte/.github/.github/workflows/__call-update-pacman-repo.yml@master
|
||||
if: github.repository_owner == 'LizardByte'
|
||||
secrets:
|
||||
GH_EMAIL: ${{ secrets.GH_BOT_EMAIL }}
|
||||
GH_NAME: ${{ secrets.GH_BOT_NAME }}
|
||||
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
55
.github/workflows/ci-copr.yml
vendored
55
.github/workflows/ci-copr.yml
vendored
@@ -1,23 +1,28 @@
|
||||
---
|
||||
name: CI Copr
|
||||
name: CI-Copr
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
release:
|
||||
types:
|
||||
- prereleased
|
||||
- released
|
||||
workflow_call:
|
||||
secrets:
|
||||
COPR_BETA_WEBHOOK_TOKEN:
|
||||
required: false
|
||||
COPR_STABLE_WEBHOOK_TOKEN:
|
||||
required: false
|
||||
COPR_CLI_CONFIG:
|
||||
required: false
|
||||
GH_BOT_TOKEN:
|
||||
required: false
|
||||
VIRUSTOTAL_API_KEY:
|
||||
required: false
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
group: "_${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -33,3 +38,35 @@ jobs:
|
||||
COPR_BETA_WEBHOOK_TOKEN: ${{ secrets.COPR_BETA_WEBHOOK_TOKEN }}
|
||||
COPR_STABLE_WEBHOOK_TOKEN: ${{ secrets.COPR_STABLE_WEBHOOK_TOKEN }}
|
||||
COPR_CLI_CONFIG: ${{ secrets.COPR_CLI_CONFIG }}
|
||||
|
||||
release:
|
||||
name: Release
|
||||
if:
|
||||
github.event_name == 'release' &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
needs:
|
||||
- call-copr-ci
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
pattern: build-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Debug artifacts
|
||||
run: ls -l artifacts
|
||||
|
||||
- name: Update GitHub Release
|
||||
uses: LizardByte/actions/actions/release_create@v2025.715.25226
|
||||
with:
|
||||
allowUpdates: true
|
||||
body: ${{ github.event.release.body }}
|
||||
deleteOtherPreReleases: false
|
||||
generateReleaseNotes: false
|
||||
name: ${{ github.event.release.name }}
|
||||
prerelease: true
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
virustotal_api_key: ${{ secrets.VIRUSTOTAL_API_KEY }}
|
||||
|
||||
218
.github/workflows/ci-flatpak.yml
vendored
Normal file
218
.github/workflows/ci-flatpak.yml
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
---
|
||||
name: CI-Flatpak
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_commit:
|
||||
required: true
|
||||
type: string
|
||||
release_version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build_linux_flatpak:
|
||||
name: ${{ matrix.arch }}
|
||||
env:
|
||||
APP_ID: dev.lizardbyte.app.Sunshine
|
||||
NODE_VERSION: "20"
|
||||
PLATFORM_VERSION: "23.08"
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
runner: ubuntu-22.04
|
||||
- arch: aarch64
|
||||
runner: ubuntu-22.04-arm
|
||||
steps:
|
||||
- name: Maximize build space
|
||||
if: matrix.arch == 'x86_64'
|
||||
uses: easimon/maximize-build-space@v10
|
||||
with:
|
||||
root-reserve-mb: 10240
|
||||
remove-dotnet: 'true'
|
||||
remove-android: 'true'
|
||||
remove-haskell: 'true'
|
||||
remove-codeql: 'true'
|
||||
remove-docker-images: 'true'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup node
|
||||
id: node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm install --package-lock-only
|
||||
|
||||
- name: Debug package-lock.json
|
||||
run: cat package-lock.json
|
||||
|
||||
- name: Setup python
|
||||
id: python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Setup Dependencies Linux Flatpak
|
||||
run: |
|
||||
python -m pip install ./packaging/linux/flatpak/deps/flatpak-builder-tools/node
|
||||
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
cmake \
|
||||
flatpak
|
||||
|
||||
sudo su "$(whoami)" -c "flatpak --user remote-add --if-not-exists flathub \
|
||||
https://flathub.org/repo/flathub.flatpakrepo
|
||||
"
|
||||
|
||||
sudo su "$(whoami)" -c "flatpak --user install -y flathub \
|
||||
org.flatpak.Builder \
|
||||
org.freedesktop.Platform/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
org.freedesktop.Sdk/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
org.freedesktop.Sdk.Extension.node${NODE_VERSION}/${{ matrix.arch }}/${PLATFORM_VERSION} \
|
||||
"
|
||||
|
||||
flatpak run org.flatpak.Builder --version
|
||||
|
||||
- name: flatpak node generator
|
||||
# https://github.com/flatpak/flatpak-builder-tools/blob/master/node/README.md
|
||||
run: flatpak-node-generator npm package-lock.json
|
||||
|
||||
- name: Debug generated-sources.json
|
||||
run: cat generated-sources.json
|
||||
|
||||
- name: Cache Flatpak build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./build/.flatpak-builder
|
||||
key: flatpak-${{ matrix.arch }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
flatpak-${{ matrix.arch }}-
|
||||
|
||||
- name: Configure Flatpak Manifest
|
||||
env:
|
||||
BRANCH: ${{ github.head_ref }}
|
||||
run: |
|
||||
# variables for manifest
|
||||
branch="${{ env.BRANCH }}"
|
||||
build_version=${{ inputs.release_version }}
|
||||
commit=${{ inputs.release_commit }}
|
||||
|
||||
# check the branch variable
|
||||
if [ -z "$branch" ]
|
||||
then
|
||||
echo "This is a PUSH event"
|
||||
branch=${{ github.ref_name }}
|
||||
clone_url=${{ github.event.repository.clone_url }}
|
||||
else
|
||||
echo "This is a PR event"
|
||||
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
|
||||
fi
|
||||
echo "Branch: ${branch}"
|
||||
echo "Commit: ${commit}"
|
||||
echo "Clone URL: ${clone_url}"
|
||||
|
||||
export BRANCH=${branch}
|
||||
export BUILD_VERSION=${build_version}
|
||||
export CLONE_URL=${clone_url}
|
||||
export COMMIT=${commit}
|
||||
|
||||
mkdir -p build
|
||||
mkdir -p artifacts
|
||||
|
||||
cmake -DGITHUB_CLONE_URL=${clone_url} \
|
||||
-B build \
|
||||
-S . \
|
||||
-DSUNSHINE_CONFIGURE_FLATPAK_MAN=ON \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON
|
||||
|
||||
- name: Debug Manifest
|
||||
working-directory: build
|
||||
run: cat "${APP_ID}.yml"
|
||||
|
||||
- name: Build Linux Flatpak
|
||||
working-directory: build
|
||||
run: |
|
||||
echo "::add-matcher::.github/matchers/gcc-strip3.json"
|
||||
sudo su "$(whoami)" -c "flatpak run org.flatpak.Builder \
|
||||
--arch=${{ matrix.arch }} \
|
||||
--force-clean \
|
||||
--repo=repo \
|
||||
--sandbox \
|
||||
--stop-at=cuda build-sunshine ${APP_ID}.yml"
|
||||
cp -r .flatpak-builder copy-of-flatpak-builder
|
||||
sudo su "$(whoami)" -c "flatpak run org.flatpak.Builder \
|
||||
--arch=${{ matrix.arch }} \
|
||||
--force-clean \
|
||||
--repo=repo \
|
||||
--sandbox \
|
||||
build-sunshine ${APP_ID}.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 ${APP_ID}"
|
||||
sudo su "$(whoami)" -c "flatpak build-bundle \
|
||||
--runtime \
|
||||
--arch=${{ matrix.arch }} \
|
||||
./repo \
|
||||
../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak ${APP_ID}.Debug"
|
||||
echo "::remove-matcher owner=gcc-strip3::"
|
||||
|
||||
- name: Lint Flatpak
|
||||
working-directory: build
|
||||
run: |
|
||||
exceptions_file="${{ github.workspace }}/packaging/linux/flatpak/exceptions.json"
|
||||
|
||||
echo "Linting flatpak manifest"
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder \
|
||||
--exceptions \
|
||||
--user-exceptions "${exceptions_file}" \
|
||||
manifest \
|
||||
"${APP_ID}.yml"
|
||||
|
||||
echo "Linting flatpak repo"
|
||||
# TODO: add arg
|
||||
# --mirror-screenshots-url=https://dl.flathub.org/media \
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder \
|
||||
--exceptions \
|
||||
--user-exceptions "${exceptions_file}" \
|
||||
repo \
|
||||
repo
|
||||
|
||||
- name: Package Flathub repo archive
|
||||
# copy files required to generate the Flathub repo
|
||||
if: matrix.arch == 'x86_64'
|
||||
run: |
|
||||
mkdir -p flathub/modules
|
||||
cp "./build/generated-sources.json" "./flathub/"
|
||||
cp "./build/package-lock.json" "./flathub/"
|
||||
cp "./build/${APP_ID}.yml" "./flathub/"
|
||||
cp "./build/${APP_ID}.metainfo.xml" "./flathub/"
|
||||
cp "./packaging/linux/flatpak/README.md" "./flathub/"
|
||||
cp "./packaging/linux/flatpak/flathub.json" "./flathub/"
|
||||
cp -r "./packaging/linux/flatpak/modules/." "./flathub/modules/"
|
||||
# submodules will need to be handled in the workflow that creates the PR
|
||||
|
||||
# create the archive
|
||||
tar -czf ./artifacts/flathub.tar.gz -C ./flathub .
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-Linux-Flatpak-${{ matrix.arch }}
|
||||
path: artifacts/
|
||||
if-no-files-found: error
|
||||
236
.github/workflows/ci-homebrew.yml
vendored
Normal file
236
.github/workflows/ci-homebrew.yml
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
---
|
||||
name: CI-Homebrew
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
publish_release:
|
||||
required: true
|
||||
type: string
|
||||
release_commit:
|
||||
required: true
|
||||
type: string
|
||||
release_tag:
|
||||
required: true
|
||||
type: string
|
||||
release_version:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
GH_TOKEN:
|
||||
required: true
|
||||
GIT_EMAIL:
|
||||
required: true
|
||||
GIT_USERNAME:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build_homebrew:
|
||||
name: ${{ matrix.os_name }}-${{ matrix.os_version }}${{ matrix.release == true && ' (Release)' || '' }}
|
||||
runs-on: ${{ matrix.os_name }}-${{ matrix.os_version }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
|
||||
# while GitHub has larger macOS runners, they are not available for our repos :(
|
||||
- os_version: "13"
|
||||
os_name: "macos"
|
||||
- os_version: "14"
|
||||
os_name: "macos"
|
||||
- os_version: "15"
|
||||
os_name: "macos"
|
||||
- os_version: "latest"
|
||||
os_name: "ubuntu"
|
||||
- os_version: "latest" # this job will only configure the formula for release, no validation
|
||||
os_name: "ubuntu"
|
||||
release: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fix homebrew python
|
||||
if: matrix.os_name == 'macos' && matrix.os_version == '13'
|
||||
run: |
|
||||
rm '/usr/local/bin/2to3'
|
||||
rm '/usr/local/bin/2to3-3.12'
|
||||
rm '/usr/local/bin/idle3'
|
||||
rm '/usr/local/bin/idle3.12'
|
||||
rm '/usr/local/bin/idle3.13'
|
||||
rm '/usr/local/bin/pip3.12'
|
||||
rm '/usr/local/bin/pip3.13'
|
||||
rm '/usr/local/bin/pydoc3'
|
||||
rm '/usr/local/bin/pydoc3.12'
|
||||
rm '/usr/local/bin/pydoc3.13'
|
||||
rm '/usr/local/bin/python3'
|
||||
rm '/usr/local/bin/python3.12'
|
||||
rm '/usr/local/bin/python3.13'
|
||||
rm '/usr/local/bin/python3-config'
|
||||
rm '/usr/local/bin/python3.12-config'
|
||||
rm '/usr/local/bin/python3.13-config'
|
||||
brew install python3
|
||||
|
||||
- name: Configure formula
|
||||
env:
|
||||
HEAD_REF: ${{ github.head_ref }}
|
||||
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
||||
PR_DEFAULT_BRANCH: ${{ github.event.pull_request.head.repo.default_branch }}
|
||||
run: |
|
||||
# variables for formula
|
||||
branch="${{ env.HEAD_REF }}"
|
||||
build_version=${{ inputs.release_version }}
|
||||
commit=${{ inputs.release_commit }}
|
||||
|
||||
# check the branch variable
|
||||
if [ -z "$branch" ]
|
||||
then
|
||||
echo "This is a PUSH event"
|
||||
clone_url=${{ github.event.repository.clone_url }}
|
||||
branch="${{ github.ref_name }}"
|
||||
default_branch="${{ github.event.repository.default_branch }}"
|
||||
|
||||
if [ "${{ matrix.release }}" == "true" ]; then
|
||||
# we will publish the formula with the release tag
|
||||
tag="${{ inputs.release_tag }}"
|
||||
else
|
||||
tag="${{ github.ref_name }}"
|
||||
fi
|
||||
else
|
||||
echo "This is a PR event"
|
||||
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
|
||||
branch="${{ env.PR_HEAD_REF }}"
|
||||
default_branch="${{ env.PR_DEFAULT_BRANCH }}"
|
||||
tag="${{ env.PR_HEAD_REF }}"
|
||||
fi
|
||||
echo "Branch: ${branch}"
|
||||
echo "Clone URL: ${clone_url}"
|
||||
echo "Tag: ${tag}"
|
||||
|
||||
export BRANCH=${branch}
|
||||
export BUILD_VERSION=${build_version}
|
||||
export CLONE_URL=${clone_url}
|
||||
export COMMIT=${commit}
|
||||
export TAG=${tag}
|
||||
|
||||
mkdir -p build
|
||||
cmake \
|
||||
-B build \
|
||||
-S . \
|
||||
-DGITHUB_DEFAULT_BRANCH="${default_branch}" \
|
||||
-DSUNSHINE_CONFIGURE_HOMEBREW=ON \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON
|
||||
|
||||
# copy formula to artifacts
|
||||
mkdir -p homebrew
|
||||
cp -f ./build/sunshine.rb ./homebrew/sunshine.rb
|
||||
|
||||
# testing
|
||||
cat ./homebrew/sunshine.rb
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: matrix.release
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-Homebrew
|
||||
path: homebrew/
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Setup Xvfb
|
||||
if: matrix.release != true && runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
xvfb
|
||||
|
||||
export DISPLAY=:1
|
||||
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
|
||||
echo "DISPLAY=${DISPLAY}" >> "${GITHUB_ENV}"
|
||||
|
||||
- run: echo "::add-matcher::.github/matchers/gcc-strip3.json"
|
||||
- name: Validate Homebrew Formula
|
||||
id: test
|
||||
if: matrix.release != true
|
||||
uses: LizardByte/actions/actions/release_homebrew@v2025.715.25226
|
||||
with:
|
||||
formula_file: ${{ github.workspace }}/homebrew/sunshine.rb
|
||||
git_email: ${{ secrets.GIT_EMAIL }}
|
||||
git_username: ${{ secrets.GIT_USERNAME }}
|
||||
publish: false
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
validate: true
|
||||
- run: echo "::remove-matcher owner=gcc-strip3::"
|
||||
|
||||
- name: Setup python
|
||||
id: python
|
||||
if: false
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Generate gcov report
|
||||
id: test_report
|
||||
# any except canceled or skipped
|
||||
# TODO: fix coverage, no .gcno files are being created
|
||||
# TODO: .gcno files are supposed to be created next to .o files
|
||||
if: false
|
||||
# if: >-
|
||||
# always() &&
|
||||
# matrix.release != true &&
|
||||
# (steps.test.outcome == 'success' || steps.test.outcome == 'failure')
|
||||
run: |
|
||||
cp -rf ${{ steps.test.outputs.buildpath }}/build/ ./build/
|
||||
cd build
|
||||
ls -Ra
|
||||
|
||||
${{ steps.python.outputs.python-path }} -m pip install gcovr
|
||||
${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \
|
||||
--exclude-noncode-lines \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--verbose \
|
||||
--xml-pretty \
|
||||
-o coverage.xml
|
||||
|
||||
- name: Upload coverage artifact
|
||||
if: >-
|
||||
always() &&
|
||||
matrix.release != true &&
|
||||
(steps.test.outcome == 'success' || steps.test.outcome == 'failure') &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-Homebrew-${{ matrix.os_name }}-${{ matrix.os_version }}
|
||||
path: |
|
||||
build/coverage.xml
|
||||
${{ steps.test.outputs.testpath }}/test_results.xml
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Patch homebrew formula
|
||||
# create beta version of the formula
|
||||
# don't run this on macOS, as the sed command fails
|
||||
if: matrix.release
|
||||
run: |
|
||||
# variables
|
||||
formula_file="homebrew/sunshine-beta.rb"
|
||||
|
||||
# rename the file
|
||||
mv homebrew/sunshine.rb $formula_file
|
||||
|
||||
# update the formula
|
||||
sed -i 's/class Sunshine < Formula/class SunshineBeta < Formula/' $formula_file
|
||||
sed -i 's/# conflicts_with/conflicts_with/' $formula_file
|
||||
|
||||
# print new file
|
||||
echo "New formula:"
|
||||
cat $formula_file
|
||||
|
||||
- name: Upload Artifacts (Beta)
|
||||
if: matrix.release
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: beta-Homebrew
|
||||
path: homebrew/
|
||||
if-no-files-found: error
|
||||
218
.github/workflows/ci-linux.yml
vendored
Normal file
218
.github/workflows/ci-linux.yml
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
---
|
||||
name: CI-Linux
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_commit:
|
||||
required: true
|
||||
type: string
|
||||
release_version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
name: ${{ matrix.name }}
|
||||
env:
|
||||
APP_ID: dev.lizardbyte.app.Sunshine
|
||||
runs-on: ubuntu-${{ matrix.dist }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: AppImage
|
||||
EXTRA_ARGS: '--appimage-build'
|
||||
dist: 22.04
|
||||
steps:
|
||||
- name: Maximize build space
|
||||
uses: easimon/maximize-build-space@v10
|
||||
with:
|
||||
root-reserve-mb: 30720
|
||||
remove-dotnet: 'true'
|
||||
remove-android: 'true'
|
||||
remove-haskell: 'true'
|
||||
remove-codeql: 'true'
|
||||
remove-docker-images: 'true'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Dependencies Linux
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
# create the artifacts directory
|
||||
mkdir -p artifacts
|
||||
|
||||
# allow libfuse2 for appimage on 22.04+
|
||||
sudo add-apt-repository universe
|
||||
|
||||
sudo apt-get install -y \
|
||||
libdrm-dev \
|
||||
libfuse2 \
|
||||
libgl-dev \
|
||||
libwayland-dev \
|
||||
libx11-xcb-dev \
|
||||
libxcb-dri3-dev \
|
||||
libxfixes-dev
|
||||
|
||||
- name: Setup python
|
||||
id: python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Build latest libva
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
gh release download --archive=tar.gz --repo=intel/libva
|
||||
tar xzf libva-*.tar.gz && rm libva-*.tar.gz
|
||||
cd libva-*
|
||||
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu \
|
||||
--enable-drm \
|
||||
--enable-x11 \
|
||||
--enable-glx \
|
||||
--enable-wayland \
|
||||
--without-legacy
|
||||
make -j "$(nproc)"
|
||||
sudo make install
|
||||
cd .. && rm -rf libva-*
|
||||
|
||||
- name: Build Linux
|
||||
env:
|
||||
BRANCH: ${{ github.head_ref || github.ref_name }}
|
||||
BUILD_VERSION: ${{ inputs.release_version }}
|
||||
COMMIT: ${{ inputs.release_commit }}
|
||||
run: |
|
||||
chmod +x ./scripts/linux_build.sh
|
||||
echo "::add-matcher::.github/matchers/gcc.json"
|
||||
./scripts/linux_build.sh \
|
||||
--publisher-name='${{ github.repository_owner }}' \
|
||||
--publisher-website='https://app.lizardbyte.dev' \
|
||||
--publisher-issue-url='https://app.lizardbyte.dev/support' \
|
||||
--skip-cleanup \
|
||||
--skip-package \
|
||||
--ubuntu-test-repo ${{ matrix.EXTRA_ARGS }}
|
||||
echo "::remove-matcher owner=gcc::"
|
||||
|
||||
- name: Set AppImage Version
|
||||
if: matrix.name == 'AppImage'
|
||||
run: |
|
||||
version=${{ inputs.release_version }}
|
||||
echo "VERSION=${version}" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Package Linux - AppImage
|
||||
if: matrix.name == 'AppImage'
|
||||
working-directory: build
|
||||
run: |
|
||||
# install sunshine to the DESTDIR
|
||||
DESTDIR=AppDir ninja install
|
||||
|
||||
# custom AppRun file
|
||||
cp -f ../packaging/linux/AppImage/AppRun ./AppDir/
|
||||
chmod +x ./AppDir/AppRun
|
||||
|
||||
# variables
|
||||
DESKTOP_FILE="${DESKTOP_FILE:-${APP_ID}.desktop}"
|
||||
ICON_FILE="${ICON_FILE:-sunshine.png}"
|
||||
|
||||
# AppImage
|
||||
# https://docs.appimage.org/packaging-guide/index.html
|
||||
wget -q 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 -q 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 \
|
||||
--plugin gtk \
|
||||
--executable ./sunshine \
|
||||
--icon-file "../$ICON_FILE" \
|
||||
--desktop-file "./$DESKTOP_FILE" \
|
||||
--output appimage
|
||||
|
||||
# move
|
||||
mv Sunshine*.AppImage ../artifacts/sunshine.AppImage
|
||||
|
||||
# permissions
|
||||
chmod +x ../artifacts/sunshine.AppImage
|
||||
|
||||
- name: Delete CUDA
|
||||
# free up space on the runner
|
||||
run: |
|
||||
rm -rf ./build/cuda
|
||||
|
||||
- name: Verify AppImage
|
||||
if: matrix.name == 'AppImage'
|
||||
run: |
|
||||
wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage
|
||||
chmod +x appimagelint-x86_64.AppImage
|
||||
|
||||
./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage
|
||||
|
||||
- name: Install test deps
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
x11-xserver-utils \
|
||||
xvfb
|
||||
|
||||
# clean apt cache
|
||||
sudo apt-get clean
|
||||
sudo rm -rf /var/lib/apt/lists/*
|
||||
|
||||
- name: Run tests
|
||||
id: test
|
||||
working-directory: build/tests
|
||||
run: |
|
||||
export DISPLAY=:1
|
||||
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
sleep 5 # give Xvfb time to start
|
||||
|
||||
./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml
|
||||
|
||||
- name: Generate gcov report
|
||||
id: test_report
|
||||
# any except canceled or skipped
|
||||
if: >-
|
||||
always() &&
|
||||
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
|
||||
working-directory: build
|
||||
run: |
|
||||
${{ steps.python.outputs.python-path }} -m pip install gcovr
|
||||
${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \
|
||||
--exclude-noncode-lines \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--verbose \
|
||||
--xml-pretty \
|
||||
-o coverage.xml
|
||||
|
||||
- name: Upload coverage artifact
|
||||
if: >-
|
||||
always() &&
|
||||
(steps.test_report.outcome == 'success')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-Linux-${{ matrix.name }}
|
||||
path: |
|
||||
build/coverage.xml
|
||||
build/tests/test_results.xml
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-Linux-${{ matrix.name }}
|
||||
path: artifacts/
|
||||
if-no-files-found: error
|
||||
347
.github/workflows/ci-windows.yml
vendored
Normal file
347
.github/workflows/ci-windows.yml
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
---
|
||||
name: CI-Windows
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_commit:
|
||||
required: true
|
||||
type: string
|
||||
release_version:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Windows-AMD64
|
||||
os: windows-2022
|
||||
arch: x86_64
|
||||
msystem: ucrt64
|
||||
toolchain: ucrt-x86_64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare tests
|
||||
id: prepare-tests
|
||||
if: false # todo: DirectX11 is not available, so even software encoder fails
|
||||
shell: pwsh
|
||||
run: |
|
||||
# function to download and extract a zip file
|
||||
function DownloadAndExtract {
|
||||
param (
|
||||
[string]$Uri,
|
||||
[string]$OutFile
|
||||
)
|
||||
|
||||
$maxRetries = 5
|
||||
$retryCount = 0
|
||||
$success = $false
|
||||
|
||||
while (-not $success -and $retryCount -lt $maxRetries) {
|
||||
$retryCount++
|
||||
Write-Host "Downloading $Uri to $OutFile, attempt $retryCount of $maxRetries"
|
||||
try {
|
||||
Invoke-WebRequest -Uri $Uri -OutFile $OutFile
|
||||
$success = $true
|
||||
} catch {
|
||||
Write-Host "Attempt $retryCount of $maxRetries failed with error: $($_.Exception.Message). Retrying..."
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $success) {
|
||||
Write-Host "Failed to download the file after $maxRetries attempts."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# use .NET to get the base name of the file
|
||||
$baseName = (Get-Item $OutFile).BaseName
|
||||
|
||||
# Extract the zip file
|
||||
Expand-Archive -Path $OutFile -DestinationPath $baseName
|
||||
}
|
||||
|
||||
# virtual display driver
|
||||
DownloadAndExtract `
|
||||
-Uri "https://www.amyuni.com/downloads/usbmmidd_v2.zip" `
|
||||
-OutFile "usbmmidd_v2.zip"
|
||||
|
||||
# install
|
||||
Set-Location -Path usbmmidd_v2/usbmmidd_v2
|
||||
./deviceinstaller64 install usbmmidd.inf usbmmidd
|
||||
|
||||
# create the virtual display
|
||||
./deviceinstaller64 enableidd 1
|
||||
|
||||
# move up a directory
|
||||
Set-Location -Path ../..
|
||||
|
||||
# install devcon
|
||||
DownloadAndExtract `
|
||||
-Uri "https://github.com/Drawbackz/DevCon-Installer/releases/download/1.4-rc/Devcon.Installer.zip" `
|
||||
-OutFile "Devcon.Installer.zip"
|
||||
Set-Location -Path Devcon.Installer
|
||||
# hash needs to match OS version
|
||||
# https://github.com/Drawbackz/DevCon-Installer/blob/master/devcon_sources.json
|
||||
Start-Process -FilePath "./Devcon Installer.exe" -Wait -ArgumentList `
|
||||
'install', `
|
||||
'-hash', '54004C83EE34F6A55380528A8B29F4C400E61FBB947A19E0AB9E5A193D7D961E', `
|
||||
'-addpath', `
|
||||
'-update', `
|
||||
'-dir', 'C:\Windows\System32'
|
||||
|
||||
# disable Hyper-V Video
|
||||
# https://stackoverflow.com/a/59490940
|
||||
C:\Windows\System32\devcon.exe disable "VMBUS\{da0a7802-e377-4aac-8e77-0558eb1073f8}"
|
||||
|
||||
# move up a directory
|
||||
Set-Location -Path ..
|
||||
|
||||
# multi monitor tool
|
||||
DownloadAndExtract `
|
||||
-Uri "http://www.nirsoft.net/utils/multimonitortool-x64.zip" `
|
||||
-OutFile "multimonitortool.zip"
|
||||
|
||||
# enable the virtual display
|
||||
# http://www.nirsoft.net/utils/multi_monitor_tool.html
|
||||
Set-Location -Path multimonitortool
|
||||
|
||||
# Original Hyper-V is \\.\DISPLAY1, it will recreate itself as \\.\DISPLAY6 (or something higher than 2)
|
||||
# USB Mobile Monitor Virtual Display is \\.\DISPLAY2
|
||||
|
||||
# these don't seem to work if not using runAs
|
||||
# todo: do they work if not using runAs?
|
||||
Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /enable \\.\DISPLAY2'
|
||||
Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /SetPrimary \\.\DISPLAY2'
|
||||
|
||||
# wait a few seconds
|
||||
Start-Sleep -s 5
|
||||
|
||||
# list monitors
|
||||
./MultiMonitorTool.exe /stext monitor_list.txt
|
||||
|
||||
# wait a few seconds
|
||||
Start-Sleep -s 5
|
||||
|
||||
# print the monitor list
|
||||
Get-Content -Path monitor_list.txt
|
||||
|
||||
- name: Setup Dependencies Windows
|
||||
# if a dependency needs to be pinned, see https://github.com/LizardByte/build-deps/pull/186
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
update: true
|
||||
install: >-
|
||||
wget
|
||||
|
||||
- name: Update Windows dependencies
|
||||
env:
|
||||
MSYSTEM: ${{ matrix.msystem }}
|
||||
TOOLCHAIN: ${{ matrix.toolchain }}
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# variables
|
||||
declare -A pinned_deps
|
||||
|
||||
# dependencies
|
||||
dependencies=(
|
||||
"git"
|
||||
"mingw-w64-${TOOLCHAIN}-cmake"
|
||||
"mingw-w64-${TOOLCHAIN}-cppwinrt"
|
||||
"mingw-w64-${TOOLCHAIN}-curl-winssl"
|
||||
"mingw-w64-${TOOLCHAIN}-gcc"
|
||||
"mingw-w64-${TOOLCHAIN}-graphviz"
|
||||
"mingw-w64-${TOOLCHAIN}-MinHook"
|
||||
"mingw-w64-${TOOLCHAIN}-miniupnpc"
|
||||
"mingw-w64-${TOOLCHAIN}-nlohmann-json"
|
||||
"mingw-w64-${TOOLCHAIN}-nodejs"
|
||||
"mingw-w64-${TOOLCHAIN}-nsis"
|
||||
"mingw-w64-${TOOLCHAIN}-onevpl"
|
||||
"mingw-w64-${TOOLCHAIN}-openssl"
|
||||
"mingw-w64-${TOOLCHAIN}-opus"
|
||||
"mingw-w64-${TOOLCHAIN}-toolchain"
|
||||
)
|
||||
|
||||
# do not modify below this line
|
||||
|
||||
ignore_packages=()
|
||||
tarballs=""
|
||||
for pkg in "${!pinned_deps[@]}"; do
|
||||
ignore_packages+=("${pkg}")
|
||||
version="${pinned_deps[$pkg]}"
|
||||
tarball="${pkg}-${version}-any.pkg.tar.zst"
|
||||
|
||||
# download working version
|
||||
wget "https://repo.msys2.org/mingw/${MSYSTEM}/${tarball}"
|
||||
|
||||
tarballs="${tarballs} ${tarball}"
|
||||
done
|
||||
|
||||
# Create the ignore string for pacman
|
||||
ignore_list=$(IFS=,; echo "${ignore_packages[*]}")
|
||||
|
||||
# install pinned dependencies
|
||||
if [ -n "${tarballs}" ]; then
|
||||
pacman -U --noconfirm "${tarballs}"
|
||||
fi
|
||||
|
||||
# Only add --ignore if we have packages to ignore
|
||||
if [ -n "${ignore_list}" ]; then
|
||||
pacman -Syu --noconfirm --ignore="${ignore_list}" "${dependencies[@]}"
|
||||
else
|
||||
pacman -Syu --noconfirm "${dependencies[@]}"
|
||||
fi
|
||||
|
||||
- name: Install Doxygen
|
||||
# GCC compiled doxygen has issues when running graphviz
|
||||
env:
|
||||
DOXYGEN_VERSION: "1.11.0"
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Set version variables
|
||||
$doxy_ver = $env:DOXYGEN_VERSION
|
||||
$_doxy_ver = $doxy_ver.Replace(".", "_")
|
||||
|
||||
# Download the Doxygen installer
|
||||
Invoke-WebRequest -Uri `
|
||||
"https://github.com/doxygen/doxygen/releases/download/Release_${_doxy_ver}/doxygen-${doxy_ver}-setup.exe" `
|
||||
-OutFile "doxygen-setup.exe"
|
||||
|
||||
# Run the installer
|
||||
Start-Process `
|
||||
-FilePath .\doxygen-setup.exe `
|
||||
-ArgumentList `
|
||||
'/VERYSILENT' `
|
||||
-Wait `
|
||||
-NoNewWindow
|
||||
|
||||
# Clean up
|
||||
Remove-Item -Path doxygen-setup.exe
|
||||
|
||||
- name: Setup python
|
||||
id: setup-python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Python Path
|
||||
id: python-path
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# replace backslashes with double backslashes
|
||||
python_path=$(echo "${{ steps.setup-python.outputs.python-path }}" | sed 's/\\/\\\\/g')
|
||||
|
||||
# step output
|
||||
echo "python-path=${python_path}"
|
||||
echo "python-path=${python_path}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Build Windows
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
BRANCH: ${{ github.head_ref || github.ref_name }}
|
||||
BUILD_VERSION: ${{ inputs.release_version }}
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
COMMIT: ${{ inputs.release_commit }}
|
||||
run: |
|
||||
mkdir -p build
|
||||
cmake \
|
||||
-B build \
|
||||
-G Ninja \
|
||||
-S . \
|
||||
-DBUILD_WERROR=ON \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DSUNSHINE_ASSETS_DIR=assets \
|
||||
-DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \
|
||||
-DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \
|
||||
-DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
|
||||
echo "::add-matcher::.github/matchers/gcc.json"
|
||||
ninja -C build
|
||||
echo "::remove-matcher owner=gcc::"
|
||||
|
||||
- name: Package Windows
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
cd build
|
||||
|
||||
# package
|
||||
cpack -G NSIS
|
||||
cpack -G ZIP
|
||||
|
||||
# move
|
||||
mv ./cpack_artifacts/Sunshine.exe ../artifacts/Sunshine-${{ matrix.name }}-installer.exe
|
||||
mv ./cpack_artifacts/Sunshine.zip ../artifacts/Sunshine-${{ matrix.name }}-portable.zip
|
||||
|
||||
- name: Run tests
|
||||
id: test
|
||||
shell: msys2 {0}
|
||||
working-directory: build/tests
|
||||
run: |
|
||||
./test_sunshine.exe --gtest_color=yes --gtest_output=xml:test_results.xml
|
||||
|
||||
- name: Generate gcov report
|
||||
id: test_report
|
||||
# any except canceled or skipped
|
||||
if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure')
|
||||
shell: msys2 {0}
|
||||
working-directory: build
|
||||
run: |
|
||||
${{ steps.python-path.outputs.python-path }} -m pip install gcovr
|
||||
${{ steps.python-path.outputs.python-path }} -m gcovr . -r ../src \
|
||||
--exclude-noncode-lines \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--verbose \
|
||||
--xml-pretty \
|
||||
-o coverage.xml
|
||||
|
||||
- name: Upload coverage artifact
|
||||
if: >-
|
||||
always() &&
|
||||
(steps.test_report.outcome == 'success')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-${{ matrix.name }}
|
||||
path: |
|
||||
build/coverage.xml
|
||||
build/tests/test_results.xml
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Package Windows Debug Info
|
||||
shell: pwsh
|
||||
working-directory: build
|
||||
run: |
|
||||
# use .dbg file extension for binaries to avoid confusion with real packages
|
||||
Get-ChildItem -File -Recurse | `
|
||||
% { Rename-Item -Path $_.PSPath -NewName $_.Name.Replace(".exe",".dbg") }
|
||||
|
||||
# save the binaries with debug info
|
||||
7z -r `
|
||||
"-xr!CMakeFiles" `
|
||||
"-xr!cpack_artifacts" `
|
||||
a "../artifacts/Sunshine-${{ matrix.name }}-debuginfo.7z" "*.dbg"
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.name }}
|
||||
path: artifacts/
|
||||
if-no-files-found: error
|
||||
241
.github/workflows/ci.yml
vendored
Normal file
241
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
name: CI
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
github-env:
|
||||
name: GitHub Env Debug
|
||||
uses: LizardByte/.github/.github/workflows/__call-github-env.yml@master
|
||||
|
||||
release-setup:
|
||||
name: Release Setup
|
||||
outputs:
|
||||
publish_release: ${{ steps.release-setup.outputs.publish_release }}
|
||||
release_body: ${{ steps.release-setup.outputs.release_body }}
|
||||
release_commit: ${{ steps.release-setup.outputs.release_commit }}
|
||||
release_generate_release_notes: ${{ steps.release-setup.outputs.release_generate_release_notes }}
|
||||
release_tag: ${{ steps.release-setup.outputs.release_tag }}
|
||||
release_version: ${{ steps.release-setup.outputs.release_version }}
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Release Setup
|
||||
id: release-setup
|
||||
uses: LizardByte/actions/actions/release_setup@v2025.715.25226
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
build-docker:
|
||||
name: Docker
|
||||
needs: release-setup
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: LizardByte/.github/.github/workflows/__call-docker.yml@master
|
||||
with:
|
||||
maximize_build_space: true
|
||||
publish_release: ${{ needs.release-setup.outputs.publish_release }}
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_tag: ${{ needs.release-setup.outputs.release_tag }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
secrets:
|
||||
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
GH_BOT_NAME: ${{ secrets.GH_BOT_NAME }}
|
||||
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
build-homebrew:
|
||||
name: Homebrew
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-homebrew.yml
|
||||
with:
|
||||
publish_release: ${{ needs.release-setup.outputs.publish_release }}
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_tag: ${{ needs.release-setup.outputs.release_tag }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
secrets:
|
||||
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
GIT_EMAIL: ${{ secrets.GH_BOT_EMAIL }}
|
||||
GIT_USERNAME: ${{ secrets.GH_BOT_NAME }}
|
||||
|
||||
build-linux:
|
||||
name: Linux
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-linux.yml
|
||||
with:
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
|
||||
build-linux-copr:
|
||||
name: Linux Copr
|
||||
if: github.event_name != 'push' # releases are handled directly in ci-copr.yml
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-copr.yml
|
||||
secrets:
|
||||
COPR_BETA_WEBHOOK_TOKEN: ${{ secrets.COPR_BETA_WEBHOOK_TOKEN }}
|
||||
COPR_STABLE_WEBHOOK_TOKEN: ${{ secrets.COPR_STABLE_WEBHOOK_TOKEN }}
|
||||
COPR_CLI_CONFIG: ${{ secrets.COPR_CLI_CONFIG }}
|
||||
|
||||
build-linux-flatpak:
|
||||
name: Linux Flatpak
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-flatpak.yml
|
||||
with:
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
|
||||
build-windows:
|
||||
name: Windows
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-windows.yml
|
||||
with:
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
coverage:
|
||||
name: Coverage-${{ matrix.name }}
|
||||
if: >-
|
||||
always() &&
|
||||
!cancelled() &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
needs:
|
||||
- build-linux
|
||||
- build-linux-flatpak
|
||||
- build-homebrew
|
||||
- build-windows
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Linux-AppImage
|
||||
coverage: true
|
||||
- name: Homebrew-macos-13
|
||||
coverage: false
|
||||
- name: Homebrew-macos-14
|
||||
coverage: false
|
||||
- name: Homebrew-macos-15
|
||||
coverage: false
|
||||
- name: Homebrew-ubuntu-latest
|
||||
coverage: false
|
||||
- name: Windows-AMD64
|
||||
coverage: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download coverage artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: coverage-${{ matrix.name }}
|
||||
path: _coverage
|
||||
|
||||
- name: Upload test results
|
||||
uses: codecov/test-results-action@v1
|
||||
with:
|
||||
disable_search: true
|
||||
fail_ci_if_error: true
|
||||
files: ./_coverage/tests/test_results.xml
|
||||
flags: ${{ matrix.name }}
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v5
|
||||
if: matrix.coverage != false
|
||||
with:
|
||||
disable_search: true
|
||||
fail_ci_if_error: true
|
||||
files: ./_coverage/coverage.xml
|
||||
flags: ${{ matrix.name }}
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
|
||||
release:
|
||||
name: Release
|
||||
if:
|
||||
needs.release-setup.outputs.publish_release == 'true' &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
needs:
|
||||
- release-setup
|
||||
- build-docker
|
||||
- build-linux
|
||||
- build-linux-flatpak
|
||||
- build-homebrew
|
||||
- build-windows
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
pattern: build-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Debug artifacts
|
||||
run: ls -l artifacts
|
||||
|
||||
- name: Create/Update GitHub Release
|
||||
uses: LizardByte/actions/actions/release_create@v2025.715.25226
|
||||
with:
|
||||
allowUpdates: false
|
||||
body: ${{ needs.release-setup.outputs.release_body }}
|
||||
generateReleaseNotes: ${{ needs.release-setup.outputs.release_generate_release_notes }}
|
||||
name: ${{ needs.release-setup.outputs.release_tag }}
|
||||
prerelease: true
|
||||
tag: ${{ needs.release-setup.outputs.release_tag }}
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
virustotal_api_key: ${{ secrets.VIRUSTOTAL_API_KEY }}
|
||||
|
||||
release-homebrew-beta:
|
||||
name: Release Homebrew Beta
|
||||
if:
|
||||
needs.release-setup.outputs.publish_release == 'true' &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
needs:
|
||||
- release-setup
|
||||
- build-homebrew
|
||||
- release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download homebrew artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: beta-Homebrew
|
||||
path: homebrew
|
||||
|
||||
- name: Upload Homebrew Beta Formula
|
||||
uses: LizardByte/actions/actions/release_homebrew@v2025.715.25226
|
||||
with:
|
||||
formula_file: ${{ github.workspace }}/homebrew/sunshine-beta.rb
|
||||
git_email: ${{ secrets.GH_BOT_EMAIL }}
|
||||
git_username: ${{ secrets.GH_BOT_NAME }}
|
||||
publish: true
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
validate: false
|
||||
8
.github/workflows/localize.yml
vendored
8
.github/workflows/localize.yml
vendored
@@ -48,9 +48,9 @@ jobs:
|
||||
if [ -f "${{ env.file }}" ];
|
||||
then
|
||||
rm ${{ env.file }}
|
||||
echo "new_file=false" >> $GITHUB_ENV
|
||||
echo "new_file=false" >> "${GITHUB_ENV}"
|
||||
else
|
||||
echo "new_file=true" >> $GITHUB_ENV
|
||||
echo "new_file=true" >> "${GITHUB_ENV}"
|
||||
fi
|
||||
|
||||
# extract the new strings
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
# 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
|
||||
echo "git_diff=${OUTPUT}" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: git reset
|
||||
# only run if a single line changed (date/time) and file already existed
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
||||
run: echo "date=$(date +'%Y-%m-%d')" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Create/Update Pull Request
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<a href="https://flathub.org/apps/dev.lizardbyte.app.Sunshine"><img src="https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub" alt="Flathub Version"></a>
|
||||
<a href="https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine"><img src="https://img.shields.io/winget/v/LizardByte.Sunshine?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHuSURBVFhH7ZfNTtRQGIYZiMDwN/IrCAqIhMSNKxcmymVwG+5dcDVsWHgDrtxwCYQVl+BChzDEwSnPY+eQ0sxoOz1mQuBNnpyvTdvz9jun5/SrjfxnJUkyQbMEz2ELduF1l0YUA3QyTrMAa2AnPtyOXsELeAYNyKtV2EC3k3lYgTOwg09ghy/BTp7CKBRV844BOpmmMV2+ySb4BmInG7AKY7AHH+EYqqhZo9PPBG/BVDlOizAD/XQFmnoPXzxRQX8M/CCYS48L6RIc4ygGHK9WGg9HZSZMUNRPVwNJGg5Hg2Qgqh4N3FsDsb6EmgYm07iwwvUxstdxJTwgmILf4CfZ6bb5OHANX8GN5x20IVxnG8ge94pt2xpwU3GnCwayF4Q2G2vgFLzHndFzQdk4q77nNfCdwL28qNyMtmEf3A1/QV5FjDiPWo5jrwf8TWZChTlgJvL4F9QL50/A43qVidTvLcuoM2wDQ1+IkgefgUpLcYwMVBqCKNJA2b0gKNocOIITOIef8C/F/CdMbh/GklynsSawKLHS8d9/B1x2LUqsfFyy3TMsWj5A1cLkotDbYO4JjWWZlZEGv8EbOIR1CAVN2eG8W5oNKgxaeC6DmTJjZs7ixUxpznLPLT+v4sXpoMLcLI3mzFSonDXIEI/M3QCIO4YuimBJ/gAAAABJRU5ErkJggg==" alt="Winget Version"></a>
|
||||
<a href="https://gurubase.io/g/sunshine"><img src="https://img.shields.io/badge/Gurubase-Ask%20Guru-ef1a1b?style=for-the-badge&logo=data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIABgAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AOLqSO3mlilljido4QGkYDIQEgAn05IH41seFo7aS+uRKlrJci2Y2cd2QImlyOGyQPu7sA8ZxXapAlvpThbPRkv7nTQWhDoIZZRc/XaSAOmcZGOnFfP06XMr3P17F5iqE+Tl1uuvf9Lde55dRW74pit4r61EcdtFdG2U3kVqQY0lyeBgkD5duQOASawqykuV2O6jV9rTU0rXLNjf3Om3QubSXy5QCudoYEEYIIOQR7GnahqV3qk6zXk3mOqhFAUKqqOyqAAByeAKqUUXdrFezhz89lfv1+8KKKKRZ//Z" alt="Gurubase"></a>
|
||||
<a href="https://github.com/LizardByte/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster"><img src="https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/CI.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge" alt="GitHub Workflow Status (CI)"></a>
|
||||
<a href="https://github.com/LizardByte/Sunshine/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/ci.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge" alt="GitHub Workflow Status (CI)"></a>
|
||||
<a href="https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Amaster"><img src="https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=master&label=localize%20build&logo=github&style=for-the-badge" alt="GitHub Workflow Status (localize)"></a>
|
||||
<a href="https://docs.lizardbyte.dev/projects/sunshine"><img src="https://img.shields.io/readthedocs/sunshinestream.svg?label=Docs&style=for-the-badge&logo=readthedocs" alt="Read the Docs"></a>
|
||||
<a href="https://codecov.io/gh/LizardByte/Sunshine"><img src="https://img.shields.io/codecov/c/gh/LizardByte/Sunshine?token=SMGXQ5NVMJ&style=for-the-badge&logo=codecov&label=codecov" alt="Codecov"></a>
|
||||
|
||||
@@ -52,9 +52,6 @@ include_directories(BEFORE SYSTEM "${CMAKE_SOURCE_DIR}/third-party/nv-codec-head
|
||||
file(GLOB NVENC_SOURCES CONFIGURE_DEPENDS "src/nvenc/*.cpp" "src/nvenc/*.h")
|
||||
list(APPEND PLATFORM_TARGET_FILES ${NVENC_SOURCES})
|
||||
|
||||
configure_file("${CMAKE_SOURCE_DIR}/src/version.h.in" version.h @ONLY)
|
||||
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") # required for importing version.h
|
||||
|
||||
set(SUNSHINE_TARGET_FILES
|
||||
"${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/src/Input.h"
|
||||
"${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/src/Rtsp.h"
|
||||
|
||||
@@ -85,18 +85,27 @@ if(CUDA_FOUND)
|
||||
add_compile_definitions(SUNSHINE_BUILD_CUDA)
|
||||
endif()
|
||||
|
||||
# drm
|
||||
if(${SUNSHINE_ENABLE_DRM})
|
||||
# libdrm is required for both DRM (KMS) and Wayland
|
||||
if(${SUNSHINE_ENABLE_DRM} OR ${SUNSHINE_ENABLE_WAYLAND})
|
||||
find_package(LIBDRM REQUIRED)
|
||||
find_package(LIBCAP REQUIRED)
|
||||
else()
|
||||
set(LIBDRM_FOUND OFF)
|
||||
endif()
|
||||
if(LIBDRM_FOUND)
|
||||
include_directories(SYSTEM ${LIBDRM_INCLUDE_DIRS})
|
||||
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# drm
|
||||
if(${SUNSHINE_ENABLE_DRM})
|
||||
find_package(LIBCAP REQUIRED)
|
||||
else()
|
||||
set(LIBCAP_FOUND OFF)
|
||||
endif()
|
||||
if(LIBDRM_FOUND AND LIBCAP_FOUND)
|
||||
add_compile_definitions(SUNSHINE_BUILD_DRM)
|
||||
include_directories(SYSTEM ${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS})
|
||||
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES})
|
||||
include_directories(SYSTEM ${LIBCAP_INCLUDE_DIRS})
|
||||
list(APPEND PLATFORM_LIBRARIES ${LIBCAP_LIBRARIES})
|
||||
list(APPEND PLATFORM_TARGET_FILES
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/linux/kmsgrab.cpp")
|
||||
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
||||
|
||||
@@ -9,10 +9,6 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
# gcc complains about misleading indentation in some mingw includes
|
||||
list(APPEND SUNSHINE_COMPILE_OPTIONS -Wno-misleading-indentation)
|
||||
|
||||
# gcc15 complains about non-template type 'coroutine_handle' used as a template in Windows.Foundation.h
|
||||
# can remove after https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120495 is available in mingw-w64
|
||||
list(APPEND SUNSHINE_COMPILE_OPTIONS -Wno-template-body)
|
||||
|
||||
# see gcc bug 98723
|
||||
add_definitions(-DUSE_BOOST_REGEX)
|
||||
|
||||
@@ -42,10 +38,17 @@ if(NOT DEFINED SUNSHINE_ICON_PATH)
|
||||
set(SUNSHINE_ICON_PATH "${CMAKE_SOURCE_DIR}/sunshine.ico")
|
||||
endif()
|
||||
|
||||
configure_file("${CMAKE_SOURCE_DIR}/src/platform/windows/windows.rc.in" windows.rc @ONLY)
|
||||
# Create a separate object library for the RC file with minimal includes
|
||||
add_library(sunshine_rc_object OBJECT "${CMAKE_SOURCE_DIR}/src/platform/windows/windows.rc")
|
||||
|
||||
# Set minimal properties for RC compilation - only what's needed for the resource file
|
||||
# Otherwise compilation can fail due to "line too long" errors
|
||||
set_target_properties(sunshine_rc_object PROPERTIES
|
||||
COMPILE_DEFINITIONS "PROJECT_ICON_PATH=${SUNSHINE_ICON_PATH};PROJECT_NAME=${PROJECT_NAME};PROJECT_VENDOR=${SUNSHINE_PUBLISHER_NAME};PROJECT_VERSION=${PROJECT_VERSION};PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR};PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR};PROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}" # cmake-lint: disable=C0301
|
||||
INCLUDE_DIRECTORIES ""
|
||||
)
|
||||
|
||||
set(PLATFORM_TARGET_FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/windows.rc"
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/windows/publish.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/windows/misc.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/windows/misc.cpp"
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
# common cpack options
|
||||
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_VENDOR "LizardByte")
|
||||
string(REGEX REPLACE "^v" "" CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) # remove the v prefix if it exists
|
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpack_artifacts)
|
||||
set(CPACK_PACKAGE_CONTACT "https://app.lizardbyte.dev")
|
||||
set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION})
|
||||
|
||||
@@ -45,6 +45,7 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
||||
libcap2, \
|
||||
libcurl4, \
|
||||
libdrm2, \
|
||||
libgbm1, \
|
||||
libevdev2, \
|
||||
libnuma1, \
|
||||
libopus0, \
|
||||
@@ -65,6 +66,7 @@ set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||
libva >= 2.14.0, \
|
||||
libwayland-client >= 1.20.0, \
|
||||
libX11 >= 1.7.3.1, \
|
||||
mesa-libgbm >= 25.0.7, \
|
||||
miniupnpc >= 2.2.4, \
|
||||
numactl-libs >= 2.0.14, \
|
||||
openssl >= 3.0.2, \
|
||||
|
||||
@@ -4,6 +4,20 @@ install(TARGETS sunshine RUNTIME DESTINATION "." COMPONENT application)
|
||||
# Hardening: include zlib1.dll (loaded via LoadLibrary() in openssl's libcrypto.a)
|
||||
install(FILES "${ZLIB}" DESTINATION "." COMPONENT application)
|
||||
|
||||
# ViGEmBus installer
|
||||
set(VIGEMBUS_INSTALLER "${CMAKE_BINARY_DIR}/vigembus_installer.exe")
|
||||
file(DOWNLOAD
|
||||
"https://github.com/nefarius/ViGEmBus/releases/download/v1.21.442.0/ViGEmBus_1.21.442_x64_x86_arm64.exe"
|
||||
${VIGEMBUS_INSTALLER}
|
||||
SHOW_PROGRESS
|
||||
EXPECTED_HASH SHA256=155c50f1eec07bdc28d2f61a3e3c2c6c132fee7328412de224695f89143316bc
|
||||
TIMEOUT 60
|
||||
)
|
||||
install(FILES ${VIGEMBUS_INSTALLER}
|
||||
DESTINATION "scripts"
|
||||
RENAME "vigembus_installer.exe"
|
||||
COMPONENT gamepad)
|
||||
|
||||
# Adding tools
|
||||
install(TARGETS dxgi-info RUNTIME DESTINATION "tools" COMPONENT dxgi)
|
||||
install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio)
|
||||
|
||||
@@ -15,7 +15,8 @@ SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\update-path.bat\\\" add'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\migrate-config.bat\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\add-firewall-rule.bat\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-gamepad.bat\\\"'
|
||||
nsExec::ExecToLog \
|
||||
'powershell.exe -ExecutionPolicy Bypass -File \\\"$INSTDIR\\\\scripts\\\\install-gamepad.ps1\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-service.bat\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\autostart-service.bat\\\"'
|
||||
NoController:
|
||||
@@ -31,7 +32,9 @@ set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
'Do you want to remove Virtual Gamepad?' \
|
||||
/SD IDNO IDNO NoGamepad
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\uninstall-gamepad.bat\\\"'; skipped if no
|
||||
nsExec::ExecToLog \
|
||||
'powershell.exe -ExecutionPolicy Bypass -File \\\"$INSTDIR\\\\scripts\\\\uninstall-gamepad.ps1\\\"'; \
|
||||
skipped if no
|
||||
NoGamepad:
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
'Do you want to remove $INSTDIR (this includes the configuration, cover images, and settings)?' \
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
# Set build variables if env variables are defined
|
||||
# These are used in configured files such as manifests for different packages
|
||||
if(DEFINED ENV{BRANCH})
|
||||
set(GITHUB_BRANCH $ENV{BRANCH})
|
||||
endif()
|
||||
if(DEFINED ENV{BUILD_VERSION}) # cmake-lint: disable=W0106
|
||||
set(BUILD_VERSION $ENV{BUILD_VERSION})
|
||||
endif()
|
||||
if(DEFINED ENV{CLONE_URL})
|
||||
set(GITHUB_CLONE_URL $ENV{CLONE_URL})
|
||||
endif()
|
||||
if(DEFINED ENV{COMMIT})
|
||||
set(GITHUB_COMMIT $ENV{COMMIT})
|
||||
endif()
|
||||
if(DEFINED ENV{TAG})
|
||||
set(GITHUB_TAG $ENV{TAG})
|
||||
endif()
|
||||
|
||||
# Check if env vars are defined before attempting to access them, variables will be defined even if blank
|
||||
if((DEFINED ENV{BRANCH}) AND (DEFINED ENV{BUILD_VERSION}) AND (DEFINED ENV{COMMIT})) # cmake-lint: disable=W0106
|
||||
if(($ENV{BRANCH} STREQUAL "master") AND (NOT $ENV{BUILD_VERSION} STREQUAL ""))
|
||||
# If BRANCH is "master" and BUILD_VERSION is not empty, then we are building a master branch
|
||||
MESSAGE("Got from CI master branch and version $ENV{BUILD_VERSION}")
|
||||
if((DEFINED ENV{BRANCH}) AND (DEFINED ENV{BUILD_VERSION})) # cmake-lint: disable=W0106
|
||||
if((DEFINED ENV{BRANCH}) AND (NOT $ENV{BUILD_VERSION} STREQUAL ""))
|
||||
# If BRANCH is defined and BUILD_VERSION is not empty, then we are building from CI
|
||||
# If BRANCH is master we are building a push/release build
|
||||
MESSAGE("Got from CI '$ENV{BRANCH}' branch and version '$ENV{BUILD_VERSION}'")
|
||||
set(PROJECT_VERSION $ENV{BUILD_VERSION})
|
||||
string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) # remove the v prefix if it exists
|
||||
set(CMAKE_PROJECT_VERSION ${PROJECT_VERSION}) # cpack will use this to set the binary versions
|
||||
elseif((DEFINED ENV{BRANCH}) AND (DEFINED ENV{COMMIT}))
|
||||
# If BRANCH is set but not BUILD_VERSION we are building a PR, we gather only the commit hash
|
||||
MESSAGE("Got from CI $ENV{BRANCH} branch and commit $ENV{COMMIT}")
|
||||
set(PROJECT_VERSION ${PROJECT_VERSION}.$ENV{COMMIT})
|
||||
endif()
|
||||
else()
|
||||
# Generate Sunshine Version based of the git tag
|
||||
# https://github.com/nocnokneo/cmake-git-versioning-example/blob/master/LICENSE
|
||||
else()
|
||||
find_package(Git)
|
||||
if(GIT_EXECUTABLE)
|
||||
MESSAGE("${CMAKE_SOURCE_DIR}")
|
||||
@@ -60,18 +76,24 @@ set(PROJECT_YEAR "1990")
|
||||
set(PROJECT_MONTH "01")
|
||||
set(PROJECT_DAY "01")
|
||||
|
||||
# Extract year, month, and day
|
||||
if(PROJECT_VERSION MATCHES "^([0-9]{4})[.]([0-9]{3,4})")
|
||||
# Extract year, month, and day (do this AFTER version parsing)
|
||||
# Note: Cmake doesn't support "{}" regex syntax
|
||||
if(PROJECT_VERSION MATCHES "^([0-9][0-9][0-9][0-9])\\.([0-9][0-9][0-9][0-9]?)\\.([0-9]+)$")
|
||||
message("Extracting year and month/day from PROJECT_VERSION: ${PROJECT_VERSION}")
|
||||
# First capture group is the year
|
||||
set(PROJECT_YEAR "${CMAKE_MATCH_1}")
|
||||
|
||||
# Second capture group is month/day
|
||||
# Second capture group contains month and day
|
||||
set(MONTH_DAY "${CMAKE_MATCH_2}")
|
||||
|
||||
# Extract month (first 1-2 digits) and day (last 2 digits)
|
||||
string(LENGTH "${MONTH_DAY}" MONTH_DAY_LENGTH)
|
||||
if(MONTH_DAY_LENGTH EQUAL 3)
|
||||
# Format: MDD (e.g., 703 = month 7, day 03)
|
||||
string(SUBSTRING "${MONTH_DAY}" 0 1 PROJECT_MONTH)
|
||||
string(SUBSTRING "${MONTH_DAY}" 1 2 PROJECT_DAY)
|
||||
elseif(MONTH_DAY_LENGTH EQUAL 4)
|
||||
# Format: MMDD (e.g., 1203 = month 12, day 03)
|
||||
string(SUBSTRING "${MONTH_DAY}" 0 2 PROJECT_MONTH)
|
||||
string(SUBSTRING "${MONTH_DAY}" 2 2 PROJECT_DAY)
|
||||
endif()
|
||||
@@ -85,3 +107,35 @@ if(PROJECT_VERSION MATCHES "^([0-9]{4})[.]([0-9]{3,4})")
|
||||
set(PROJECT_DAY "0${PROJECT_DAY}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Parse PROJECT_VERSION to extract major, minor, and patch components
|
||||
if(PROJECT_VERSION MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
||||
set(PROJECT_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
set(CMAKE_PROJECT_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
|
||||
set(PROJECT_VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
set(CMAKE_PROJECT_VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
|
||||
set(PROJECT_VERSION_PATCH "${CMAKE_MATCH_3}")
|
||||
set(CMAKE_PROJECT_VERSION_PATCH "${CMAKE_MATCH_3}")
|
||||
endif()
|
||||
|
||||
message("PROJECT_NAME: ${PROJECT_NAME}")
|
||||
message("PROJECT_VERSION: ${PROJECT_VERSION}")
|
||||
message("PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}")
|
||||
message("PROJECT_VERSION_MINOR: ${PROJECT_VERSION_MINOR}")
|
||||
message("PROJECT_VERSION_PATCH: ${PROJECT_VERSION_PATCH}")
|
||||
message("CMAKE_PROJECT_VERSION: ${CMAKE_PROJECT_VERSION}")
|
||||
message("CMAKE_PROJECT_VERSION_MAJOR: ${CMAKE_PROJECT_VERSION_MAJOR}")
|
||||
message("CMAKE_PROJECT_VERSION_MINOR: ${CMAKE_PROJECT_VERSION_MINOR}")
|
||||
message("CMAKE_PROJECT_VERSION_PATCH: ${CMAKE_PROJECT_VERSION_PATCH}")
|
||||
message("PROJECT_YEAR: ${PROJECT_YEAR}")
|
||||
message("PROJECT_MONTH: ${PROJECT_MONTH}")
|
||||
message("PROJECT_DAY: ${PROJECT_DAY}")
|
||||
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_NAME="${PROJECT_NAME}")
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_VERSION="${PROJECT_VERSION}")
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_VERSION_MAJOR="${PROJECT_VERSION_MAJOR}")
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_VERSION_MINOR="${PROJECT_VERSION_MINOR}")
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_VERSION_PATCH="${PROJECT_VERSION_PATCH}")
|
||||
list(APPEND SUNSHINE_DEFINITIONS PROJECT_VERSION_COMMIT="${GITHUB_COMMIT}")
|
||||
|
||||
@@ -27,7 +27,7 @@ endif()
|
||||
|
||||
target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES} ${EXTRA_LIBS})
|
||||
target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS})
|
||||
set_target_properties(sunshine PROPERTIES CXX_STANDARD 20
|
||||
set_target_properties(sunshine PROPERTIES CXX_STANDARD 23
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
|
||||
@@ -3,5 +3,6 @@ set_target_properties(sunshine PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
|
||||
find_library(ZLIB ZLIB1)
|
||||
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
|
||||
$<TARGET_OBJECTS:sunshine_rc_object>
|
||||
Windowsapp.lib
|
||||
Wtsapi32.lib)
|
||||
|
||||
@@ -28,10 +28,10 @@ ARG CLONE_URL
|
||||
ENV BRANCH=${BRANCH}
|
||||
ENV BUILD_VERSION=${BUILD_VERSION}
|
||||
ENV COMMIT=${COMMIT}
|
||||
ENV CLONE_URL=${CLONE_URL}
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# hadolint ignore=SC2016
|
||||
RUN <<_SETUP
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -41,6 +41,7 @@ useradd -m builder
|
||||
echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
# patch the build flags
|
||||
# shellcheck disable=SC2016
|
||||
sed -i 's,#MAKEFLAGS="-j2",MAKEFLAGS="-j$(nproc)",g' /etc/makepkg.conf
|
||||
|
||||
# install dependencies
|
||||
@@ -68,19 +69,16 @@ WORKDIR /build/sunshine/build
|
||||
RUN <<_MAKE
|
||||
#!/bin/bash
|
||||
set -e
|
||||
if [[ "${BUILD_VERSION}" == '' ]]; then
|
||||
|
||||
sub_version=""
|
||||
if [[ "${BRANCH}" != "master" ]]; then
|
||||
sub_version=".r${COMMIT}"
|
||||
else
|
||||
sub_version=""
|
||||
fi
|
||||
|
||||
cmake \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON \
|
||||
-DSUNSHINE_CONFIGURE_PKGBUILD=ON \
|
||||
-DSUNSHINE_SUB_VERSION="${sub_version}" \
|
||||
-DGITHUB_CLONE_URL="${CLONE_URL}" \
|
||||
-DGITHUB_BRANCH=${BRANCH} \
|
||||
-DGITHUB_BUILD_VERSION=${BUILD_VERSION} \
|
||||
-DGITHUB_COMMIT="${COMMIT}" \
|
||||
-DSUNSHINE_CONFIGURE_ONLY=ON \
|
||||
/build/sunshine
|
||||
_MAKE
|
||||
|
||||
@@ -114,14 +112,13 @@ rm -f /build/sunshine/pkg/sunshine-debug*.pkg.tar.zst
|
||||
ls -a
|
||||
_PKGBUILD
|
||||
|
||||
FROM scratch AS artifacts
|
||||
|
||||
COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /sunshine.pkg.tar.zst
|
||||
COPY --link --from=sunshine-build /build/sunshine/sunshine.pkg.tar.gz /sunshine.pkg.tar.gz
|
||||
|
||||
FROM sunshine-base AS sunshine
|
||||
|
||||
COPY --link --from=artifacts /sunshine.pkg.tar.zst /
|
||||
COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /sunshine.pkg.tar.zst
|
||||
|
||||
# artifacts to be extracted in CI
|
||||
COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /artifacts/sunshine.pkg.tar.zst
|
||||
COPY --link --from=sunshine-build /build/sunshine/sunshine.pkg.tar.gz /artifacts/sunshine.pkg.tar.gz
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
|
||||
@@ -19,7 +19,6 @@ ENV DISPLAY=:0
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# install dependencies
|
||||
# hadolint ignore=SC1091
|
||||
RUN <<_DEPS
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -74,7 +73,6 @@ WORKDIR /build/cuda
|
||||
# versions: https://developer.nvidia.com/cuda-toolkit-archive
|
||||
ENV CUDA_VERSION="11.8.0"
|
||||
ENV CUDA_BUILD="520.61.05"
|
||||
# hadolint ignore=SC3010
|
||||
RUN <<_INSTALL_CUDA
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
@@ -42,7 +42,6 @@ _BUILD
|
||||
|
||||
# run tests
|
||||
WORKDIR /build/sunshine/build/tests
|
||||
# hadolint ignore=SC1091
|
||||
RUN <<_TEST
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -51,16 +50,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
./test_sunshine --gtest_color=yes
|
||||
_TEST
|
||||
|
||||
FROM scratch AS artifacts
|
||||
FROM sunshine-base AS sunshine
|
||||
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base AS sunshine
|
||||
# artifacts to be extracted in CI
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
|
||||
@@ -42,7 +42,6 @@ _BUILD
|
||||
|
||||
# run tests
|
||||
WORKDIR /build/sunshine/build/tests
|
||||
# hadolint ignore=SC1091
|
||||
RUN <<_TEST
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -51,16 +50,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
./test_sunshine --gtest_color=yes
|
||||
_TEST
|
||||
|
||||
FROM scratch AS artifacts
|
||||
FROM sunshine-base AS sunshine
|
||||
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base AS sunshine
|
||||
# artifacts to be extracted in CI
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
|
||||
@@ -42,7 +42,6 @@ _BUILD
|
||||
|
||||
# run tests
|
||||
WORKDIR /build/sunshine/build/tests
|
||||
# hadolint ignore=SC1091
|
||||
RUN <<_TEST
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -51,16 +50,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
./test_sunshine --gtest_color=yes
|
||||
_TEST
|
||||
|
||||
FROM scratch AS artifacts
|
||||
FROM sunshine-base AS sunshine
|
||||
|
||||
ARG BASE
|
||||
ARG TAG
|
||||
ARG TARGETARCH
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
FROM sunshine-base AS sunshine
|
||||
# artifacts to be extracted in CI
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
|
||||
|
||||
# copy deb from builder
|
||||
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
|
||||
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb
|
||||
|
||||
# install sunshine
|
||||
RUN <<_INSTALL_SUNSHINE
|
||||
|
||||
@@ -1270,7 +1270,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<td colspan="2">
|
||||
Remap the requested resolution and FPS to another display mode.<br>
|
||||
Depending on the [dd_resolution_option](#dd_resolution_option) and
|
||||
[dd_refresh_rate_option](#dd_refresh_rate_option) values, the following mapping
|
||||
[dd_refresh_rate_option](#dd_refresh_rate_option) values, the following mapping
|
||||
groups are available:
|
||||
<ul>
|
||||
<li>`mixed` - both options are set to `auto`.</li>
|
||||
@@ -1281,7 +1281,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
`refresh_rate_only` - only [dd_refresh_rate_option](#dd_refresh_rate_option) is set to `auto`.
|
||||
</li>
|
||||
</ul>
|
||||
For each of those groups, a list of fields can be configured to perform remapping:
|
||||
For each of those groups, a list of fields can be configured to perform remapping:
|
||||
<ul>
|
||||
<li>
|
||||
`requested_resolution` - resolution that needs to be matched in order to use this remapping entry.
|
||||
@@ -1291,10 +1291,10 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<li>`final_refresh_rate` - refresh rate value to be used if the entry was matched.</li>
|
||||
</ul>
|
||||
If `requested_*` field is left empty, it will match <b>everything</b>.<br>
|
||||
If `final_*` field is left empty, the original value will not be remapped and either a requested, manual
|
||||
or current value is used. However, at least one `final_*` must be set, otherwise the entry is considered
|
||||
If `final_*` field is left empty, the original value will not be remapped and either a requested, manual
|
||||
or current value is used. However, at least one `final_*` must be set, otherwise the entry is considered
|
||||
invalid.<br>
|
||||
@note{"Optimize game settings" must be enabled on client side for ANY entry with `resolution`
|
||||
@note{"Optimize game settings" must be enabled on client side for ANY entry with `resolution`
|
||||
field to be considered.}
|
||||
@note{First entry to be matched in the list is the one that will be used.}
|
||||
@tip{`requested_resolution` and `final_resolution` can be omitted for `refresh_rate_only` group.}
|
||||
@@ -1371,6 +1371,32 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### minimum_fps_target
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td colspan="2">
|
||||
Sunshine tries to save bandwidth when content on screen is static or a low framerate. Because many clients expect a constant stream of video frames, a certain amount of duplicate frames are sent when this happens. This setting controls the lowest effective framerate a stream can reach.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Default</td>
|
||||
<td colspan="2">@code{}
|
||||
0
|
||||
@endcode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="3">Choices</td>
|
||||
<td>0</td>
|
||||
<td>Use half the stream's FPS as the minimum target.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1-1000</td>
|
||||
<td>Specify your own value. The real minimum may differ from this value.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Network
|
||||
|
||||
### upnp
|
||||
|
||||
@@ -284,7 +284,7 @@ brew uninstall sunshine
|
||||
#### Installer (recommended)
|
||||
|
||||
1. Download and install
|
||||
[sunshine-windows-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-installer.exe)
|
||||
[Sunshine-Windows-AMD64-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-installer.exe)
|
||||
|
||||
@attention{You should carefully select or unselect the options you want to install. Do not blindly install or
|
||||
enable features.}
|
||||
@@ -298,7 +298,7 @@ overflow menu. Different versions of Windows may provide slightly different step
|
||||
recommended for most users. No support will be provided!}
|
||||
|
||||
1. Download and extract
|
||||
[sunshine-windows-portable.zip](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-portable.zip)
|
||||
[Sunshine-Windows-AMD64-portable.zip](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-portable.zip)
|
||||
2. Open command prompt as administrator
|
||||
3. Firewall rules
|
||||
|
||||
|
||||
@@ -84,9 +84,35 @@ client only 1 Gbit/s or Wi-Fi. Similarly, a 1 Gbps host may be too fast for a
|
||||
client having only a 100 Mbps interface.
|
||||
|
||||
As a workaround the transmission speed of the host NIC can be reduced: 1 Gbps
|
||||
instead of 2.5 or 100 Mbps instead of 1 Gbps. (A technically more advanced
|
||||
instead of 2.5 or 100 Mbps instead of 1 Gbps. A technically more advanced
|
||||
solution would be to configure traffic shaping rules at the OS-level, so that
|
||||
only Sunshine's traffic is slowed down.)
|
||||
only Sunshine's traffic is slowed down.
|
||||
|
||||
Such a solution on Linux could look like that:
|
||||
|
||||
```bash
|
||||
# 1) Remove existing qdisc (pfifo_fast)
|
||||
sudo tc qdisc del dev <NIC> root
|
||||
|
||||
# 2) Add HTB root qdisc with default class 1:1
|
||||
sudo tc qdisc add dev <NIC> root handle 1: htb default 1
|
||||
|
||||
# 3) Create class 1:1 for full 10 Gbit/s (all other traffic)
|
||||
sudo tc class add dev <NIC> parent 1: classid 1:1 htb \
|
||||
rate 10000mbit ceil 10000mbit burst 32k
|
||||
|
||||
# 4) Create class 1:10 for Sunshine game stream at 1 Gbit/s
|
||||
sudo tc class add dev <NIC> parent 1: classid 1:10 htb \
|
||||
rate 1000mbit ceil 1000mbit burst 32k
|
||||
|
||||
# 5) Filter UDP source port 47998 into class 1:10
|
||||
sudo tc filter add dev <NIC> protocol ip parent 1: prio 1 \
|
||||
u32 match ip protocol 17 0xff \
|
||||
match ip sport 47998 0xffff flowid 1:10
|
||||
```
|
||||
|
||||
In that way only the Sunshine traffic is limited by 1 Gbit. This is not persistent on reboots.
|
||||
If you use a different port for the game stream you need to adjust the last command.
|
||||
|
||||
Sunshine versions > 0.23.1 include improved networking code that should
|
||||
alleviate or even solve this issue (without reducing the NIC speed).
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@lizardbyte/shared-web": "2025.626.181239",
|
||||
"vue": "3.5.17",
|
||||
"vue-i18n": "11.1.7"
|
||||
"vue": "3.5.18",
|
||||
"vue-i18n": "11.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codecov/vite-plugin": "1.9.1",
|
||||
|
||||
@@ -67,7 +67,7 @@ prepare() {
|
||||
|
||||
build() {
|
||||
export BRANCH="@GITHUB_BRANCH@"
|
||||
export BUILD_VERSION="@GITHUB_BUILD_VERSION@"
|
||||
export BUILD_VERSION="@BUILD_VERSION@"
|
||||
export COMMIT="@GITHUB_COMMIT@"
|
||||
|
||||
export CC="gcc-${_gcc_version}"
|
||||
|
||||
@@ -97,9 +97,6 @@ tar -xzf %{SOURCE0} -C %{_builddir}/Sunshine
|
||||
# list directory
|
||||
ls -a %{_builddir}/Sunshine
|
||||
|
||||
# patches
|
||||
%autopatch -p1
|
||||
|
||||
%build
|
||||
# exit on error
|
||||
set -e
|
||||
|
||||
Submodule packaging/linux/flatpak/deps/flatpak-builder-tools updated: 903919f82f...7b66dbce31
Submodule packaging/linux/flatpak/deps/shared-modules updated: 8a98211689...b63062b3cd
@@ -32,15 +32,12 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://salsa.debian.org/utopia-team/avahi.git",
|
||||
"commit": "1412c015d348166d58ea9c192239b00769eae24e",
|
||||
"tag": "debian/0.8-13",
|
||||
"url": "https://github.com/avahi/avahi.git",
|
||||
"commit": "f060abee2807c943821d88839c013ce15db17b58",
|
||||
"tag": "v0.8",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^debian\\/(\\d.+)$",
|
||||
"versions": {
|
||||
"<": "0.9"
|
||||
}
|
||||
"tag-pattern": "^v([\\d.]+)$"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,22 +5,24 @@
|
||||
"-Ddocumentation=disabled",
|
||||
"-Dtests=disabled"
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://salsa.debian.org/debian/libevdev.git",
|
||||
"commit": "1aa7baa233d6df4cee6a66fbc61bb5ffc8b6e88d",
|
||||
"tag": "debian/1.13.0+dfsg-1",
|
||||
"url": "https://github.com/LizardByte-infrastructure/libevdev.git",
|
||||
"commit": "ac0056961c3332a260db063ab4fccc7747638a1d",
|
||||
"tag": "libevdev-1.13.4",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^debian\\/(\\d.\\d+\\.\\d+)",
|
||||
"versions": {
|
||||
"<": "1.13.1"
|
||||
}
|
||||
"type": "anitya",
|
||||
"project-id": 20540,
|
||||
"stable-only": true,
|
||||
"tag-template": "libevdev-$version"
|
||||
}
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin",
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/share"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,15 +11,12 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://salsa.debian.org/gnome-team/libnotify.git",
|
||||
"commit": "ccf2f62ef0a4b264dd4eff32cab70a3e213ceb1a",
|
||||
"tag": "debian/0.8.1-1",
|
||||
"url": "https://github.com/LizardByte-infrastructure/libnotify.git",
|
||||
"commit": "131aad01ff5f563b4863becbb6ed84dac6e75d5a",
|
||||
"tag": "0.8.6",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^debian\\/(\\d.+)$",
|
||||
"versions": {
|
||||
"<": "0.8.2"
|
||||
}
|
||||
"tag-pattern": "^([\\d.]+)$"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
{
|
||||
"name": "miniupnpc",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DUPNPC_BUILD_SAMPLE=OFF",
|
||||
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
|
||||
"-DUPNPC_BUILD_STATIC=OFF",
|
||||
"-DUPNPC_BUILD_SHARED=ON",
|
||||
"-DUPNPC_BUILD_TESTS=OFF"
|
||||
"-DUPNPC_BUILD_TESTS=OFF",
|
||||
"-DUPNPC_BUILD_SAMPLE=OFF"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://salsa.debian.org/miniupnp-team/miniupnpc.git",
|
||||
"commit": "c5fe3aa794e92a503cecec6a4071eb6d310b4e42",
|
||||
"tag": "debian/2.2.4-1",
|
||||
"url": "https://miniupnp.tuxfamily.org/files/miniupnpc-2.3.3.tar.gz",
|
||||
"sha256": "d52a0afa614ad6c088cc9ddff1ae7d29c8c595ac5fdd321170a05f41e634bd1a",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^debian\\/(\\d.+)$",
|
||||
"versions": {
|
||||
"<": "2.2.5"
|
||||
}
|
||||
}
|
||||
"type": "anitya",
|
||||
"project-id": 1986,
|
||||
"stable-only": true,
|
||||
"url-template": "https://miniupnp.tuxfamily.org/files/miniupnpc-$version.tar.gz"
|
||||
},
|
||||
"type": "archive"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/share/man",
|
||||
"/lib/pkgconfig",
|
||||
"/lib/libminiupnpc.so",
|
||||
"/lib/cmake",
|
||||
"/include",
|
||||
"/bin/external-ip.sh"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
{
|
||||
"name": "numactl",
|
||||
"buildsystem": "autotools",
|
||||
"cleanup": [
|
||||
"/bin"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://salsa.debian.org/debian/numactl.git",
|
||||
"commit": "640bb34497702f9aaeb8af1b491f32b91d03ec80",
|
||||
"tag": "debian/2.0.16-1",
|
||||
"url": "https://github.com/numactl/numactl.git",
|
||||
"tag": "v2.0.19",
|
||||
"commit": "3bc85e37d5a30da6790cb7e8bb488bb8f679170f",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^debian\\/(\\d.+)$",
|
||||
"versions": {
|
||||
"<": "2.0.17"
|
||||
}
|
||||
"tag-pattern": "^v([\\d.]+)$"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rm-configure": true,
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/lib/*.a",
|
||||
"/lib/*.la",
|
||||
"/lib/*.so",
|
||||
"/share/man"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
# User Service
|
||||
mkdir -p ~/.config/systemd/user
|
||||
cp /app/share/sunshine/systemd/user/sunshine.service $HOME/.config/systemd/user/sunshine.service
|
||||
echo Sunshine User Service has been installed.
|
||||
echo Use [systemctl --user enable sunshine] once to autostart Sunshine on login.
|
||||
cp "/app/share/sunshine/systemd/user/sunshine.service" "$HOME/.config/systemd/user/sunshine.service"
|
||||
echo "Sunshine User Service has been installed."
|
||||
echo "Use [systemctl --user enable sunshine] once to autostart Sunshine on login."
|
||||
|
||||
# Udev rule
|
||||
UDEV=$(cat /app/share/sunshine/udev/rules.d/60-sunshine.rules)
|
||||
echo Configuring mouse permission.
|
||||
echo "Configuring mouse permission."
|
||||
flatpak-spawn --host pkexec sh -c "echo '$UDEV' > /etc/udev/rules.d/60-sunshine.rules"
|
||||
echo Restart computer for mouse permission to take effect.
|
||||
echo "Restart computer for mouse permission to take effect."
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
# User Service
|
||||
systemctl --user stop sunshine
|
||||
rm $HOME/.config/systemd/user/sunshine.service
|
||||
rm "$HOME/.config/systemd/user/sunshine.service"
|
||||
systemctl --user daemon-reload
|
||||
echo Sunshine User Service has been removed.
|
||||
echo "Sunshine User Service has been removed."
|
||||
|
||||
# Udev rule
|
||||
flatpak-spawn --host pkexec sh -c "rm /etc/udev/rules.d/60-sunshine.rules"
|
||||
echo Input rules removed. Restart computer to take effect.
|
||||
echo "Input rules removed. Restart computer to take effect."
|
||||
|
||||
@@ -6,7 +6,7 @@ class @PROJECT_NAME@ < Formula
|
||||
homepage "@PROJECT_HOMEPAGE_URL@"
|
||||
url "@GITHUB_CLONE_URL@",
|
||||
tag: "@GITHUB_TAG@"
|
||||
version "@FORMULA_VERSION@"
|
||||
version "@BUILD_VERSION@"
|
||||
license all_of: ["GPL-3.0-only"]
|
||||
head "@GITHUB_CLONE_URL@", branch: "@GITHUB_DEFAULT_BRANCH@"
|
||||
|
||||
@@ -29,9 +29,8 @@ class @PROJECT_NAME@ < Formula
|
||||
depends_on "cmake" => :build
|
||||
depends_on "doxygen" => :build
|
||||
depends_on "graphviz" => :build
|
||||
depends_on "ninja" => :build
|
||||
depends_on "node" => :build
|
||||
depends_on "pkg-config" => :build
|
||||
depends_on "pkgconf" => :build
|
||||
depends_on "curl"
|
||||
depends_on "miniupnpc"
|
||||
depends_on "openssl"
|
||||
@@ -39,25 +38,8 @@ class @PROJECT_NAME@ < Formula
|
||||
depends_on "icu4c" => :recommended
|
||||
|
||||
on_linux do
|
||||
# the "build" dependencies are for libayatana-appindicator
|
||||
depends_on "at-spi2-core" => :build
|
||||
depends_on "cairo" => :build
|
||||
depends_on "fontconfig" => :build
|
||||
depends_on "freetype" => :build
|
||||
depends_on "fribidi" => :build
|
||||
depends_on "gettext" => :build
|
||||
depends_on "gobject-introspection" => :build
|
||||
depends_on "graphite2" => :build
|
||||
depends_on "gtk+3" => :build
|
||||
depends_on "harfbuzz" => :build
|
||||
depends_on "intltool" => :build
|
||||
depends_on "libepoxy" => :build
|
||||
depends_on "libxdamage" => :build
|
||||
depends_on "libxkbcommon" => :build
|
||||
depends_on "pango" => :build
|
||||
depends_on "perl" => :build
|
||||
depends_on "pixman" => :build
|
||||
depends_on "avahi"
|
||||
depends_on "libayatana-appindicator"
|
||||
depends_on "libcap"
|
||||
depends_on "libdrm"
|
||||
depends_on "libnotify"
|
||||
@@ -75,128 +57,6 @@ class @PROJECT_NAME@ < Formula
|
||||
depends_on "pulseaudio"
|
||||
depends_on "systemd"
|
||||
depends_on "wayland"
|
||||
|
||||
# resources that do not have brew packages
|
||||
resource "libayatana-appindicator" do
|
||||
url "https://github.com/AyatanaIndicators/libayatana-appindicator/archive/refs/tags/0.5.94.tar.gz"
|
||||
sha256 "884a6bc77994c0b58c961613ca4c4b974dc91aa0f804e70e92f38a542d0d0f90"
|
||||
end
|
||||
|
||||
resource "libdbusmenu" do
|
||||
url "https://launchpad.net/libdbusmenu/16.04/16.04.0/+download/libdbusmenu-16.04.0.tar.gz"
|
||||
sha256 "b9cc4a2acd74509435892823607d966d424bd9ad5d0b00938f27240a1bfa878a"
|
||||
|
||||
patch 'From 729546c51806a1b3ea6cb6efb7a115b1baa811f1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
|
||||
Date: Mon, 18 Nov 2019 19:58:53 +0100
|
||||
Subject: [PATCH 1/1] Fix HAVE_VALGRIND AM_CONDITIONAL
|
||||
|
||||
The AM_CONDITIONAL should also be run with --disable-tests, otherwise
|
||||
HAVE_VALGRIND is undefined.
|
||||
---
|
||||
configure | 4 ++--
|
||||
configure.ac | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 831a3bb..8913b9b 100644
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -14801,6 +14801,8 @@ else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
have_valgrind=yes
|
||||
+fi
|
||||
+
|
||||
fi
|
||||
if test "x$have_valgrind" = "xyes"; then
|
||||
HAVE_VALGRIND_TRUE=
|
||||
@@ -14811,8 +14813,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
-fi
|
||||
-
|
||||
|
||||
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ace54d1..cbd38a6 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -120,8 +120,8 @@ PKG_CHECK_MODULES(DBUSMENUTESTS, json-glib-1.0 >= $JSON_GLIB_REQUIRED_VERSION
|
||||
[have_tests=yes]
|
||||
)
|
||||
PKG_CHECK_MODULES(DBUSMENUTESTSVALGRIND, valgrind, have_valgrind=yes, have_valgrind=no)
|
||||
-AM_CONDITIONAL([HAVE_VALGRIND], [test "x$have_valgrind" = "xyes"])
|
||||
])
|
||||
+AM_CONDITIONAL([HAVE_VALGRIND], [test "x$have_valgrind" = "xyes"])
|
||||
|
||||
AC_SUBST(DBUSMENUTESTS_CFLAGS)
|
||||
AC_SUBST(DBUSMENUTESTS_LIBS)
|
||||
--
|
||||
2.46.2
|
||||
|
||||
|
||||
'
|
||||
end
|
||||
|
||||
resource "ayatana-ido" do
|
||||
url "https://github.com/AyatanaIndicators/ayatana-ido/archive/refs/tags/0.10.4.tar.gz"
|
||||
sha256 "bd59abd5f1314e411d0d55ce3643e91cef633271f58126be529de5fb71c5ab38"
|
||||
|
||||
patch 'From 8a09e6ad33c58c017c0c8fd756da036fc39428ea Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Koskovich <akoskovich@pm.me>
|
||||
Date: Sun, 29 Sep 2024 13:47:54 -0400
|
||||
Subject: [PATCH 1/1] Make introspection configurable
|
||||
|
||||
---
|
||||
CMakeLists.txt | 1 +
|
||||
src/CMakeLists.txt | 4 ++++
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 0e13fcd..f3e9ec0 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -12,6 +12,7 @@ endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
option(ENABLE_TESTS "Enable all tests and checks" OFF)
|
||||
option(ENABLE_COVERAGE "Enable coverage reports (includes enabling all tests and checks)" OFF)
|
||||
option(ENABLE_WERROR "Treat all build warnings as errors" OFF)
|
||||
+option(ENABLE_INTROSPECTION "Enable introspection" ON)
|
||||
|
||||
if(ENABLE_COVERAGE)
|
||||
set(ENABLE_TESTS ON)
|
||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index 5b3638d..aca9481 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -108,6 +108,8 @@ install(TARGETS "ayatana-ido3-0.4" LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIB
|
||||
|
||||
# AyatanaIdo3-0.4.gir
|
||||
|
||||
+if (ENABLE_INTROSPECTION)
|
||||
+
|
||||
find_package(GObjectIntrospection REQUIRED QUIET)
|
||||
|
||||
if (INTROSPECTION_FOUND)
|
||||
@@ -183,3 +185,5 @@ if (INTROSPECTION_FOUND)
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
+
|
||||
+endif ()
|
||||
--
|
||||
2.46.2
|
||||
|
||||
|
||||
'
|
||||
end
|
||||
|
||||
resource "libayatana-indicator" do
|
||||
url "https://github.com/AyatanaIndicators/libayatana-indicator/archive/refs/tags/0.9.4.tar.gz"
|
||||
sha256 "a18d3c682e29afd77db24366f8475b26bda22b0e16ff569a2ec71cd6eb4eac95"
|
||||
end
|
||||
end
|
||||
|
||||
def install
|
||||
@@ -206,7 +66,7 @@ index 5b3638d..aca9481 100644
|
||||
|
||||
args = %W[
|
||||
-DBUILD_WERROR=ON
|
||||
-DCMAKE_CXX_STANDARD=20
|
||||
-DCMAKE_CXX_STANDARD=23
|
||||
-DCMAKE_INSTALL_PREFIX=#{prefix}
|
||||
-DHOMEBREW_ALLOW_FETCHCONTENT=ON
|
||||
-DOPENSSL_ROOT_DIR=#{Formula["openssl"].opt_prefix}
|
||||
@@ -248,59 +108,6 @@ index 5b3638d..aca9481 100644
|
||||
args << "-DCUDA_FAIL_ON_MISSING=OFF" if OS.linux?
|
||||
args << "-DSUNSHINE_ENABLE_TRAY=OFF" if OS.mac?
|
||||
|
||||
# Handle system tray on Linux
|
||||
if OS.linux?
|
||||
# Build and install libayatana components
|
||||
|
||||
# Build libdbusmenu
|
||||
resource("libdbusmenu").stage do
|
||||
system "./configure",
|
||||
"--prefix=#{prefix}",
|
||||
"--with-gtk=3",
|
||||
"--disable-dumper",
|
||||
"--disable-static",
|
||||
"--disable-tests",
|
||||
"--disable-gtk-doc",
|
||||
"--enable-introspection=no",
|
||||
"--disable-vala"
|
||||
system "make", "install"
|
||||
end
|
||||
|
||||
# Build ayatana-ido
|
||||
resource("ayatana-ido").stage do
|
||||
system "cmake", "-S", ".", "-B", "build", "-G", "Ninja",
|
||||
"-DCMAKE_INSTALL_PREFIX=#{prefix}",
|
||||
"-DENABLE_INTROSPECTION=OFF",
|
||||
*std_cmake_args
|
||||
system "ninja", "-C", "build"
|
||||
system "ninja", "-C", "build", "install"
|
||||
end
|
||||
|
||||
# Build libayatana-indicator
|
||||
resource("libayatana-indicator").stage do
|
||||
ENV.append_path "PKG_CONFIG_PATH", "#{lib}/pkgconfig"
|
||||
ENV.append "LDFLAGS", "-L#{lib}"
|
||||
|
||||
system "cmake", "-S", ".", "-B", "build", "-G", "Ninja",
|
||||
"-DCMAKE_INSTALL_PREFIX=#{prefix}",
|
||||
*std_cmake_args
|
||||
system "ninja", "-C", "build"
|
||||
system "ninja", "-C", "build", "install"
|
||||
end
|
||||
|
||||
# Build libayatana-appindicator
|
||||
resource("libayatana-appindicator").stage do
|
||||
system "cmake", "-S", ".", "-B", "build", "-G", "Ninja",
|
||||
"-DCMAKE_INSTALL_PREFIX=#{prefix}",
|
||||
"-DENABLE_BINDINGS_MONO=OFF",
|
||||
"-DENABLE_BINDINGS_VALA=OFF",
|
||||
"-DENABLE_GTKDOC=OFF",
|
||||
*std_cmake_args
|
||||
system "ninja", "-C", "build"
|
||||
system "ninja", "-C", "build", "install"
|
||||
end
|
||||
end
|
||||
|
||||
system "cmake", "-S", ".", "-B", "build", "-G", "Unix Makefiles",
|
||||
*std_cmake_args,
|
||||
*args
|
||||
|
||||
@@ -1,61 +1,63 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -x "$(command -v ./go-png2ico)" ]; then
|
||||
echo "./go-png2ico not found"
|
||||
echo "download the executable from https://github.com/J-Siu/go-png2ico"
|
||||
echo "and drop it in this folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v ./oxipng)" ]; then
|
||||
echo "./oxipng executable not found"
|
||||
echo "download the executable from https://github.com/shssoichiro/oxipng"
|
||||
echo "and drop it in this folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v inkscape)" ]; then
|
||||
echo "inkscape executable not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
icon_base_sizes=(16 64)
|
||||
icon_sizes_keys=() # associative array to prevent duplicates
|
||||
icon_sizes_keys[256]=1
|
||||
|
||||
for icon_base_size in ${icon_base_sizes[@]}; do
|
||||
# increment in 25% till 400%
|
||||
icon_size_increment=$((icon_base_size / 4))
|
||||
for ((i = 0; i <= 12; i++)); do
|
||||
icon_sizes_keys[$((icon_base_size + i * icon_size_increment))]=1
|
||||
done
|
||||
done
|
||||
|
||||
# convert to normal array
|
||||
icon_sizes=${!icon_sizes_keys[@]}
|
||||
|
||||
echo "using icon sizes:"
|
||||
echo ${icon_sizes[@]}
|
||||
|
||||
src_vectors=("../../src_assets/common/assets/web/public/images/sunshine-locked.svg"
|
||||
"../../src_assets/common/assets/web/public/images/sunshine-pausing.svg"
|
||||
"../../src_assets/common/assets/web/public/images/sunshine-playing.svg"
|
||||
"../../sunshine.svg")
|
||||
|
||||
echo "using sources vectors:"
|
||||
echo ${src_vectors[@]}
|
||||
|
||||
for src_vector in ${src_vectors[@]}; do
|
||||
file_name=`basename "$src_vector" .svg`
|
||||
png_files=()
|
||||
for icon_size in ${icon_sizes[@]}; do
|
||||
png_file="${file_name}${icon_size}.png"
|
||||
echo "converting ${png_file}"
|
||||
inkscape -w $icon_size -h $icon_size "$src_vector" --export-filename "${png_file}" &&
|
||||
./oxipng -o max --strip safe --alpha "${png_file}" &&
|
||||
png_files+=("${png_file}")
|
||||
done
|
||||
|
||||
echo "packing ${file_name}.ico"
|
||||
./go-png2ico "${png_files[@]}" "${file_name}.ico"
|
||||
done
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -x "$(command -v ./go-png2ico)" ]; then
|
||||
echo "./go-png2ico not found"
|
||||
echo "download the executable from https://github.com/J-Siu/go-png2ico"
|
||||
echo "and drop it in this folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v ./oxipng)" ]; then
|
||||
echo "./oxipng executable not found"
|
||||
echo "download the executable from https://github.com/shssoichiro/oxipng"
|
||||
echo "and drop it in this folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v inkscape)" ]; then
|
||||
echo "inkscape executable not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
icon_base_sizes=(16 64)
|
||||
icon_sizes_keys=() # associative array to prevent duplicates
|
||||
icon_sizes_keys[256]=1
|
||||
|
||||
for icon_base_size in "${icon_base_sizes[@]}"; do
|
||||
# increment in 25% till 400%
|
||||
icon_size_increment=$((icon_base_size / 4))
|
||||
for ((i = 0; i <= 12; i++)); do
|
||||
icon_sizes_keys[icon_base_size + i * icon_size_increment]=1
|
||||
done
|
||||
done
|
||||
|
||||
# convert to normal array
|
||||
icon_sizes=("${!icon_sizes_keys[@]}")
|
||||
|
||||
echo "using icon sizes:"
|
||||
# shellcheck disable=SC2068 # intentionally word split
|
||||
echo ${icon_sizes[@]}
|
||||
|
||||
src_vectors=("../../src_assets/common/assets/web/public/images/sunshine-locked.svg"
|
||||
"../../src_assets/common/assets/web/public/images/sunshine-pausing.svg"
|
||||
"../../src_assets/common/assets/web/public/images/sunshine-playing.svg"
|
||||
"../../sunshine.svg")
|
||||
|
||||
echo "using sources vectors:"
|
||||
# shellcheck disable=SC2068 # intentionally word split
|
||||
echo ${src_vectors[@]}
|
||||
|
||||
for src_vector in "${src_vectors[@]}"; do
|
||||
file_name=$(basename "${src_vector}" .svg)
|
||||
png_files=()
|
||||
for icon_size in "${icon_sizes[@]}"; do
|
||||
png_file="${file_name}${icon_size}.png"
|
||||
echo "converting ${png_file}"
|
||||
inkscape -w "${icon_size}" -h "${icon_size}" "${src_vector}" --export-filename "${png_file}" &&
|
||||
./oxipng -o max --strip safe --alpha "${png_file}" &&
|
||||
png_files+=("${png_file}")
|
||||
done
|
||||
|
||||
echo "packing ${file_name}.ico"
|
||||
./go-png2ico "${png_files[@]}" "${file_name}.ico"
|
||||
done
|
||||
|
||||
@@ -96,9 +96,11 @@ function add_arch_deps() {
|
||||
'base-devel'
|
||||
'cmake'
|
||||
'curl'
|
||||
'doxygen'
|
||||
"gcc${gcc_version}"
|
||||
"gcc${gcc_version}-libs"
|
||||
'git'
|
||||
'graphviz'
|
||||
'libayatana-appindicator'
|
||||
'libcap'
|
||||
'libdrm'
|
||||
@@ -400,7 +402,7 @@ function run_install() {
|
||||
for file in "${gcc_alternative_files[@]}"; do
|
||||
file_path="/etc/alternatives/$file"
|
||||
if [ -e "$file_path" ]; then
|
||||
mv "$file_path" "$file_path.bak"
|
||||
${sudo_cmd} mv "$file_path" "$file_path.bak"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -439,12 +441,14 @@ function run_install() {
|
||||
echo "Compiling doxygen"
|
||||
doxygen_url="https://github.com/doxygen/doxygen/releases/download/Release_${_doxygen_min}/doxygen-${doxygen_min}.src.tar.gz"
|
||||
echo "doxygen url: ${doxygen_url}"
|
||||
wget "$doxygen_url" --progress=bar:force:noscroll -q --show-progress -O "${build_dir}/doxygen.tar.gz"
|
||||
tar -xzf "${build_dir}/doxygen.tar.gz"
|
||||
cd "doxygen-${doxygen_min}"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -G="Ninja" -B="build" -S="."
|
||||
ninja -C "build" -j"${num_processors}"
|
||||
ninja -C "build" install
|
||||
pushd "${build_dir}"
|
||||
wget "$doxygen_url" --progress=bar:force:noscroll -q --show-progress -O "doxygen.tar.gz"
|
||||
tar -xzf "doxygen.tar.gz"
|
||||
cd "doxygen-${doxygen_min}"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -G="Ninja" -B="build" -S="."
|
||||
ninja -C "build" -j"${num_processors}"
|
||||
${sudo_cmd} ninja -C "build" install
|
||||
popd
|
||||
else
|
||||
echo "Doxygen version not in range, skipping docs"
|
||||
cmake_args+=("-DBUILD_DOCS=OFF")
|
||||
@@ -456,6 +460,8 @@ function run_install() {
|
||||
nvm_url="https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh"
|
||||
echo "nvm url: ${nvm_url}"
|
||||
wget -qO- ${nvm_url} | bash
|
||||
|
||||
# shellcheck source=/dev/null # we don't care that shellcheck cannot find nvm.sh
|
||||
source "$HOME/.nvm/nvm.sh"
|
||||
nvm install node
|
||||
nvm use node
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
// For NVENC legacy constants
|
||||
#include <ffnvcodec/nvEncodeAPI.h>
|
||||
#endif
|
||||
@@ -504,7 +504,8 @@ namespace config {
|
||||
{} // wa
|
||||
}, // display_device
|
||||
|
||||
0 // max_bitrate
|
||||
0, // max_bitrate
|
||||
0 // minimum_fps_target (0 = framerate)
|
||||
};
|
||||
|
||||
audio_t audio {
|
||||
@@ -1038,9 +1039,12 @@ namespace config {
|
||||
}
|
||||
|
||||
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
#ifndef __ANDROID__
|
||||
// TODO: Android can possibly support this
|
||||
if (!fs::exists(stream.file_apps.c_str())) {
|
||||
fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto &[name, val] : vars) {
|
||||
BOOST_LOG(info) << "config: '"sv << name << "' = "sv << val;
|
||||
@@ -1066,7 +1070,7 @@ namespace config {
|
||||
bool_f(vars, "nvenc_opengl_vulkan_on_dxgi", video.nv_opengl_vulkan_on_dxgi);
|
||||
bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode);
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
video.nv_legacy.preset = video.nv.quality_preset + 11;
|
||||
video.nv_legacy.multipass = video.nv.two_pass == nvenc::nvenc_two_pass::quarter_resolution ? NV_ENC_TWO_PASS_QUARTER_RESOLUTION :
|
||||
video.nv.two_pass == nvenc::nvenc_two_pass::full_resolution ? NV_ENC_TWO_PASS_FULL_RESOLUTION :
|
||||
@@ -1143,6 +1147,7 @@ namespace config {
|
||||
}
|
||||
|
||||
int_f(vars, "max_bitrate", video.max_bitrate);
|
||||
double_between_f(vars, "minimum_fps_target", video.minimum_fps_target, {0.0, 1000.0});
|
||||
|
||||
path_f(vars, "pkey", nvhttp.pkey);
|
||||
path_f(vars, "cert", nvhttp.cert);
|
||||
|
||||
@@ -141,6 +141,7 @@ namespace config {
|
||||
} dd;
|
||||
|
||||
int max_bitrate; // Maximum bitrate, sets ceiling in kbps for bitrate requested from client
|
||||
double minimum_fps_target; ///< Lowest framerate that will be used when streaming. Range 0-1000, 0 = half of client's requested framerate.
|
||||
};
|
||||
|
||||
struct audio_t {
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "process.h"
|
||||
#include "utility.h"
|
||||
#include "uuid.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
@@ -693,9 +692,8 @@ namespace confighttp {
|
||||
* @api_examples{/api/apps/9999| DELETE| null}
|
||||
*/
|
||||
void deleteApp(resp_https_t response, req_https_t request) {
|
||||
if (!check_content_type(response, request, "application/json")) {
|
||||
return;
|
||||
}
|
||||
// Skip check_content_type() for this endpoint since the request body is not used.
|
||||
|
||||
if (!authenticate(response, request)) {
|
||||
return;
|
||||
}
|
||||
@@ -843,7 +841,7 @@ namespace confighttp {
|
||||
nlohmann::json output_tree;
|
||||
output_tree["status"] = true;
|
||||
output_tree["platform"] = SUNSHINE_PLATFORM;
|
||||
output_tree["version"] = PROJECT_VER;
|
||||
output_tree["version"] = PROJECT_VERSION;
|
||||
|
||||
auto vars = config::parse_config(file_handler::read_file(config::sunshine.config_file.c_str()));
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "logging.h"
|
||||
#include "network.h"
|
||||
#include "platform/common.h"
|
||||
#include "version.h"
|
||||
|
||||
extern "C" {
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -15,11 +15,17 @@
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <display_device/logging.h>
|
||||
|
||||
// local includes
|
||||
#include "logging.h"
|
||||
|
||||
// conditional includes
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#else
|
||||
#include <display_device/logging.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/log.h>
|
||||
}
|
||||
@@ -97,6 +103,48 @@ namespace logging {
|
||||
os << "["sv << std::put_time(<, "%Y-%m-%d %H:%M:%S.") << boost::format("%03u") % ms.count() << "]: "sv
|
||||
<< log_type << view.attribute_values()[message].extract<std::string>();
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
namespace sinks = boost::log::sinks;
|
||||
namespace expr = boost::log::expressions;
|
||||
|
||||
void android_log(const std::string &message, int severity) {
|
||||
android_LogPriority android_priority;
|
||||
switch (severity) {
|
||||
case 0:
|
||||
android_priority = ANDROID_LOG_VERBOSE;
|
||||
break;
|
||||
case 1:
|
||||
android_priority = ANDROID_LOG_DEBUG;
|
||||
break;
|
||||
case 2:
|
||||
android_priority = ANDROID_LOG_INFO;
|
||||
break;
|
||||
case 3:
|
||||
android_priority = ANDROID_LOG_WARN;
|
||||
break;
|
||||
case 4:
|
||||
android_priority = ANDROID_LOG_ERROR;
|
||||
break;
|
||||
case 5:
|
||||
android_priority = ANDROID_LOG_FATAL;
|
||||
break;
|
||||
default:
|
||||
android_priority = ANDROID_LOG_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
__android_log_print(android_priority, "Sunshine", "%s", message.c_str());
|
||||
}
|
||||
|
||||
// custom sink backend for android
|
||||
struct android_sink_backend: public sinks::basic_sink_backend<sinks::concurrent_feeding> {
|
||||
void consume(const bl::record_view &rec) {
|
||||
int log_sev = rec[severity].get();
|
||||
const std::string log_msg = rec[expr::smessage].get();
|
||||
// log to android
|
||||
android_log(log_msg, log_sev);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
[[nodiscard]] std::unique_ptr<deinit_t> init(int min_log_level, const std::string &log_file) {
|
||||
if (sink) {
|
||||
@@ -104,8 +152,10 @@ namespace logging {
|
||||
deinit();
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
setup_av_logging(min_log_level);
|
||||
setup_libdisplaydevice_logging(min_log_level);
|
||||
#endif
|
||||
|
||||
sink = boost::make_shared<text_sink>();
|
||||
|
||||
@@ -113,6 +163,7 @@ namespace logging {
|
||||
boost::shared_ptr<std::ostream> stream {&std::cout, boost::null_deleter()};
|
||||
sink->locked_backend()->add_stream(stream);
|
||||
#endif
|
||||
|
||||
sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(log_file));
|
||||
sink->set_filter(severity >= min_log_level);
|
||||
sink->set_formatter(&formatter);
|
||||
@@ -122,9 +173,15 @@ namespace logging {
|
||||
sink->locked_backend()->auto_flush(true);
|
||||
|
||||
bl::core::get()->add_sink(sink);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
auto android_sink = boost::make_shared<sinks::synchronous_sink<android_sink_backend>>();
|
||||
bl::core::get()->add_sink(android_sink);
|
||||
#endif
|
||||
return std::make_unique<deinit_t>();
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
void setup_av_logging(int min_log_level) {
|
||||
if (min_log_level >= 1) {
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
@@ -182,6 +239,7 @@ namespace logging {
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
void log_flush() {
|
||||
if (sink) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "process.h"
|
||||
#include "system_tray.h"
|
||||
#include "upnp.h"
|
||||
#include "version.h"
|
||||
#include "video.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -123,7 +122,7 @@ int main(int argc, char *argv[]) {
|
||||
// logging can begin at this point
|
||||
// if anything is logged prior to this point, it will appear in stdout, but not in the log viewer in the UI
|
||||
// the version should be printed to the log before anything else
|
||||
BOOST_LOG(info) << PROJECT_NAME << " version: " << PROJECT_VER;
|
||||
BOOST_LOG(info) << PROJECT_NAME << " version: " << PROJECT_VERSION << " commit: " << PROJECT_VERSION_COMMIT;
|
||||
|
||||
// Log publisher metadata
|
||||
log_publisher_data();
|
||||
@@ -341,6 +340,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
std::thread httpThread {nvhttp::start};
|
||||
std::thread configThread {confighttp::start};
|
||||
std::thread rtspThread {rtsp_stream::start};
|
||||
|
||||
#ifdef _WIN32
|
||||
// If we're using the default port and GameStream is enabled, warn the user
|
||||
@@ -350,10 +350,12 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
rtsp_stream::rtpThread();
|
||||
// Wait for shutdown
|
||||
shutdown_event->view();
|
||||
|
||||
httpThread.join();
|
||||
configThread.join();
|
||||
rtspThread.join();
|
||||
|
||||
task_pool.stop();
|
||||
task_pool.join();
|
||||
|
||||
@@ -424,7 +424,7 @@ namespace platf {
|
||||
// UDP GSO on Linux currently only supports sending 64K or 64 segments at a time
|
||||
size_t seg_index = 0;
|
||||
const size_t seg_max = 65536 / 1500;
|
||||
struct iovec iovs[(send_info.headers ? std::min(seg_max, send_info.block_count) : 1) * max_iovs_per_msg] = {};
|
||||
struct iovec iovs[(send_info.headers ? std::min(seg_max, send_info.block_count) : 1) * max_iovs_per_msg];
|
||||
auto msg_size = send_info.header_size + send_info.payload_size;
|
||||
while (seg_index < send_info.block_count) {
|
||||
int iovlen = 0;
|
||||
@@ -507,10 +507,11 @@ namespace platf {
|
||||
|
||||
{
|
||||
// If GSO is not supported, use sendmmsg() instead.
|
||||
struct mmsghdr msgs[send_info.block_count] = {};
|
||||
struct iovec iovs[send_info.block_count * (send_info.headers ? 2 : 1)] = {};
|
||||
struct mmsghdr msgs[send_info.block_count];
|
||||
struct iovec iovs[send_info.block_count * (send_info.headers ? 2 : 1)];
|
||||
int iov_idx = 0;
|
||||
for (size_t i = 0; i < send_info.block_count; i++) {
|
||||
msgs[i].msg_len = 0;
|
||||
msgs[i].msg_hdr.msg_iov = &iovs[iov_idx];
|
||||
msgs[i].msg_hdr.msg_iovlen = send_info.headers ? 2 : 1;
|
||||
|
||||
@@ -528,6 +529,7 @@ namespace platf {
|
||||
msgs[i].msg_hdr.msg_namelen = msg.msg_namelen;
|
||||
msgs[i].msg_hdr.msg_control = cmbuf.buf;
|
||||
msgs[i].msg_hdr.msg_controllen = cmbuflen;
|
||||
msgs[i].msg_hdr.msg_flags = 0;
|
||||
}
|
||||
|
||||
// Call sendmmsg() until all messages are sent
|
||||
@@ -620,7 +622,7 @@ namespace platf {
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||
}
|
||||
|
||||
struct iovec iovs[2] = {};
|
||||
struct iovec iovs[2];
|
||||
int iovlen = 0;
|
||||
if (send_info.header) {
|
||||
iovs[iovlen].iov_base = (void *) send_info.header;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define INITGUID
|
||||
|
||||
// platform includes
|
||||
#include <audioclient.h>
|
||||
#include <Audioclient.h>
|
||||
#include <avrt.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <newdev.h>
|
||||
@@ -172,19 +172,19 @@ namespace {
|
||||
std::to_string(waveformat.Format.nSamplesPerSec) + " ";
|
||||
|
||||
switch (waveformat.dwChannelMask) {
|
||||
case (waveformat_mask_stereo):
|
||||
case waveformat_mask_stereo:
|
||||
result += "2.0";
|
||||
break;
|
||||
|
||||
case (waveformat_mask_surround51_with_backspeakers):
|
||||
case waveformat_mask_surround51_with_backspeakers:
|
||||
result += "5.1";
|
||||
break;
|
||||
|
||||
case (waveformat_mask_surround51_with_sidespeakers):
|
||||
case waveformat_mask_surround51_with_sidespeakers:
|
||||
result += "5.1 (sidespeakers)";
|
||||
break;
|
||||
|
||||
case (waveformat_mask_surround71):
|
||||
case waveformat_mask_surround71:
|
||||
result += "7.1";
|
||||
break;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <Unknwn.h>
|
||||
#include <winrt/Windows.Graphics.Capture.h>
|
||||
#include <winrt/windows.graphics.capture.h>
|
||||
|
||||
// local includes
|
||||
#include "src/platform/common.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// platform includes
|
||||
#include <d3dcompiler.h>
|
||||
#include <directxmath.h>
|
||||
#include <DirectXMath.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// Gross hack to work around MINGW-packages#22160
|
||||
#define ____FIReference_1_boolean_INTERFACE_DEFINED__
|
||||
|
||||
#include <windows.graphics.capture.interop.h>
|
||||
#include <Windows.Graphics.Capture.Interop.h>
|
||||
#include <winrt/windows.foundation.h>
|
||||
#include <winrt/windows.foundation.metadata.h>
|
||||
#include <winrt/windows.graphics.directx.direct3d11.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define WINVER 0x0A00
|
||||
|
||||
// platform includes
|
||||
#include <windows.h>
|
||||
#include <Windows.h>
|
||||
|
||||
// standard includes
|
||||
#include <cmath>
|
||||
@@ -1598,8 +1598,8 @@ namespace platf {
|
||||
uint16_t y = touch.y * 943;
|
||||
uint8_t touchData[] = {
|
||||
(uint8_t) (x & 0xFF), // Low 8 bits of X
|
||||
(uint8_t) (((x >> 8) & 0x0F) | ((y & 0x0F) << 4)), // High 4 bits of X and low 4 bits of Y
|
||||
(uint8_t) (((y >> 4) & 0xFF)) // High 8 bits of Y
|
||||
(uint8_t) ((x >> 8 & 0x0F) | (y & 0x0F) << 4), // High 4 bits of X and low 4 bits of Y
|
||||
(uint8_t) (y >> 4 & 0xFF) // High 8 bits of Y
|
||||
};
|
||||
|
||||
report.sCurrentTouch.bPacketCounter++;
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
#include <iphlpapi.h>
|
||||
#include <iterator>
|
||||
#include <timeapi.h>
|
||||
#include <userenv.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winuser.h>
|
||||
#include <UserEnv.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <WinUser.h>
|
||||
#include <wlanapi.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wtsapi32.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <WtsApi32.h>
|
||||
#include <sddl.h>
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <string_view>
|
||||
|
||||
// platform includes
|
||||
#include <windows.h>
|
||||
#include <Windows.h>
|
||||
#include <winnt.h>
|
||||
|
||||
namespace platf {
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
// platform includes
|
||||
// disable clang-format header reordering
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <aclapi.h>
|
||||
#include <Windows.h>
|
||||
#include <AclAPI.h>
|
||||
// clang-format on
|
||||
|
||||
// local includes
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* @brief Definitions for Windows mDNS service registration.
|
||||
*/
|
||||
// platform includes
|
||||
// winsock2.h must be included before windows.h
|
||||
// WinSock2.h must be included before Windows.h
|
||||
// clang-format off
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
// clang-format on
|
||||
#include <windns.h>
|
||||
#include <WinDNS.h>
|
||||
#include <winerror.h>
|
||||
|
||||
// local includes
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/**
|
||||
* @file src/platform/windows/windows.rc.in
|
||||
* @brief Windows resource file template.
|
||||
* @note The final `windows.rc` is generated from this file during the CMake build.
|
||||
* @todo Use CMake definitions directly, instead of configuring this file.
|
||||
* @file src/platform/windows/windows.rc
|
||||
* @brief Windows resource file.
|
||||
*/
|
||||
#include "winver.h"
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0
|
||||
PRODUCTVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0
|
||||
FILEVERSION PROJECT_VERSION_MAJOR,PROJECT_VERSION_MINOR,PROJECT_VERSION_PATCH,0
|
||||
PRODUCTVERSION PROJECT_VERSION_MAJOR,PROJECT_VERSION_MINOR,PROJECT_VERSION_PATCH,0
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
@@ -16,13 +18,13 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "LizardByte\0"
|
||||
VALUE "FileDescription", "Sunshine\0"
|
||||
VALUE "FileVersion", "@PROJECT_VERSION@\0"
|
||||
VALUE "InternalName", "Sunshine\0"
|
||||
VALUE "LegalCopyright", "https://raw.githubusercontent.com/LizardByte/Sunshine/master/LICENSE\0"
|
||||
VALUE "ProductName", "Sunshine\0"
|
||||
VALUE "ProductVersion", "@PROJECT_VERSION@\0"
|
||||
VALUE "CompanyName", TOSTRING(PROJECT_VENDOR)
|
||||
VALUE "FileDescription", TOSTRING(PROJECT_NAME)
|
||||
VALUE "FileVersion", TOSTRING(PROJECT_VERSION)
|
||||
VALUE "InternalName", TOSTRING(PROJECT_NAME)
|
||||
VALUE "ProductName", TOSTRING(PROJECT_NAME)
|
||||
VALUE "ProductVersion", TOSTRING(PROJECT_VERSION)
|
||||
VALUE "LegalCopyright", "https://raw.githubusercontent.com/LizardByte/Sunshine/master/LICENSE"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -39,4 +41,4 @@ BEGIN
|
||||
|
||||
END
|
||||
END
|
||||
SuperDuperAmazing ICON DISCARDABLE "@SUNSHINE_ICON_PATH@"
|
||||
SuperDuperAmazing ICON DISCARDABLE PROJECT_ICON_PATH
|
||||
@@ -158,7 +158,7 @@ namespace proc {
|
||||
_env["SUNSHINE_CLIENT_GCMAP"] = std::to_string(launch_session->gcmap);
|
||||
_env["SUNSHINE_CLIENT_HOST_AUDIO"] = launch_session->host_audio ? "true" : "false";
|
||||
_env["SUNSHINE_CLIENT_ENABLE_SOPS"] = launch_session->enable_sops ? "true" : "false";
|
||||
int channelCount = launch_session->surround_info & (65535);
|
||||
int channelCount = launch_session->surround_info & 65535;
|
||||
switch (channelCount) {
|
||||
case 2:
|
||||
_env["SUNSHINE_CLIENT_AUDIO_CONFIGURATION"] = "2.0";
|
||||
|
||||
88
src/rtsp.cpp
88
src/rtsp.cpp
@@ -432,11 +432,6 @@ namespace rtsp_stream {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T, class X>
|
||||
void iterate(std::chrono::duration<T, X> timeout) {
|
||||
io_context.run_one_for(timeout);
|
||||
}
|
||||
|
||||
void handle_msg(tcp::socket &sock, launch_session_t &session, msg_t &&req) {
|
||||
auto func = _map_cmd_cb.find(req->message.request.command);
|
||||
if (func != std::end(_map_cmd_cb)) {
|
||||
@@ -494,15 +489,24 @@ namespace rtsp_stream {
|
||||
* @param launch_session Streaming session information.
|
||||
*/
|
||||
void session_raise(std::shared_ptr<launch_session_t> launch_session) {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
// If a launch event is still pending, don't overwrite it.
|
||||
if (raised_timeout > now && launch_event.peek()) {
|
||||
if (launch_event.view(0s)) {
|
||||
return;
|
||||
}
|
||||
raised_timeout = now + config::stream.ping_timeout;
|
||||
|
||||
// Raise the new launch session to prepare for the RTSP handshake
|
||||
launch_event.raise(std::move(launch_session));
|
||||
|
||||
// Arm the timer to expire this launch session if the client times out
|
||||
raised_timer.expires_after(config::stream.ping_timeout);
|
||||
raised_timer.async_wait([this](const boost::system::error_code &ec) {
|
||||
if (!ec) {
|
||||
auto discarded = launch_event.pop(0s);
|
||||
if (discarded) {
|
||||
BOOST_LOG(debug) << "Event timeout: "sv << discarded->unique_id;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -517,6 +521,7 @@ namespace rtsp_stream {
|
||||
if (launch_session->id != launch_session_id) {
|
||||
BOOST_LOG(error) << "Attempted to clear unexpected session: "sv << launch_session_id << " vs "sv << launch_session->id;
|
||||
} else {
|
||||
raised_timer.cancel();
|
||||
launch_event.pop();
|
||||
}
|
||||
}
|
||||
@@ -541,14 +546,6 @@ namespace rtsp_stream {
|
||||
* @examples_end
|
||||
*/
|
||||
void clear(bool all = true) {
|
||||
// if a launch event timed out --> Remove it.
|
||||
if (raised_timeout < std::chrono::steady_clock::now()) {
|
||||
auto discarded = launch_event.pop(0s);
|
||||
if (discarded) {
|
||||
BOOST_LOG(debug) << "Event timeout: "sv << discarded->unique_id;
|
||||
}
|
||||
}
|
||||
|
||||
auto lg = _session_slots.lock();
|
||||
|
||||
for (auto i = _session_slots->begin(); i != _session_slots->end();) {
|
||||
@@ -583,15 +580,36 @@ namespace rtsp_stream {
|
||||
BOOST_LOG(info) << "New streaming session started [active sessions: "sv << _session_slots->size() << ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Runs an iteration of the RTSP server loop
|
||||
*/
|
||||
void iterate() {
|
||||
// If we have a session, we will return to the server loop every
|
||||
// 500ms to allow session cleanup to happen.
|
||||
if (session_count() > 0) {
|
||||
io_context.run_one_for(500ms);
|
||||
} else {
|
||||
io_context.run_one();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the RTSP server.
|
||||
*/
|
||||
void stop() {
|
||||
acceptor.close();
|
||||
io_context.stop();
|
||||
clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string_view, cmd_func_t> _map_cmd_cb;
|
||||
|
||||
sync_util::sync_t<std::set<std::shared_ptr<stream::session_t>>> _session_slots;
|
||||
|
||||
std::chrono::steady_clock::time_point raised_timeout;
|
||||
|
||||
boost::asio::io_context io_context;
|
||||
tcp::acceptor acceptor {io_context};
|
||||
boost::asio::steady_timer raised_timer {io_context};
|
||||
|
||||
std::shared_ptr<socket_t> next_socket;
|
||||
};
|
||||
@@ -1088,9 +1106,8 @@ namespace rtsp_stream {
|
||||
respond(sock, session, &option, 200, "OK", req->sequenceNumber, {});
|
||||
}
|
||||
|
||||
void rtpThread() {
|
||||
void start() {
|
||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
|
||||
|
||||
server.map("OPTIONS"sv, &cmd_option);
|
||||
server.map("DESCRIBE"sv, &cmd_describe);
|
||||
@@ -1106,18 +1123,29 @@ namespace rtsp_stream {
|
||||
return;
|
||||
}
|
||||
|
||||
while (!shutdown_event->peek()) {
|
||||
server.iterate(std::min(500ms, config::stream.ping_timeout));
|
||||
std::thread rtsp_thread {[&shutdown_event] {
|
||||
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
|
||||
|
||||
if (broadcast_shutdown_event->peek()) {
|
||||
server.clear();
|
||||
} else {
|
||||
// cleanup all stopped sessions
|
||||
server.clear(false);
|
||||
while (!shutdown_event->peek()) {
|
||||
server.iterate();
|
||||
|
||||
if (broadcast_shutdown_event->peek()) {
|
||||
server.clear();
|
||||
} else {
|
||||
// cleanup all stopped sessions
|
||||
server.clear(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server.clear();
|
||||
server.clear();
|
||||
}};
|
||||
|
||||
// Wait for shutdown
|
||||
shutdown_event->view();
|
||||
|
||||
// Stop the server and join the server thread
|
||||
server.stop();
|
||||
rtsp_thread.join();
|
||||
}
|
||||
|
||||
void print_msg(PRTSP_MESSAGE msg) {
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace rtsp_stream {
|
||||
*/
|
||||
void terminate_sessions();
|
||||
|
||||
void rtpThread();
|
||||
|
||||
/**
|
||||
* @brief Runs the RTSP server loop.
|
||||
*/
|
||||
void start();
|
||||
} // namespace rtsp_stream
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "platform/common.h"
|
||||
#include "process.h"
|
||||
#include "src/entry_handler.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @file src/version.h.in
|
||||
* @brief Version definitions for Sunshine.
|
||||
* @note The final `version.h` is generated from this file during the CMake build.
|
||||
* @todo Use CMake definitions directly, instead of configuring this file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define PROJECT_NAME "@PROJECT_NAME@"
|
||||
#define PROJECT_VER "@PROJECT_VERSION@"
|
||||
#define PROJECT_VER_MAJOR "@PROJECT_VERSION_MAJOR@"
|
||||
#define PROJECT_VER_MINOR "@PROJECT_VERSION_MINOR@"
|
||||
#define PROJECT_VER_PATCH "@PROJECT_VERSION_PATCH@"
|
||||
@@ -765,6 +765,18 @@ namespace video {
|
||||
{"usage"s, &config::video.amd.amd_usage_hevc},
|
||||
{"vbaq"s, &config::video.amd.amd_vbaq},
|
||||
{"enforce_hrd"s, &config::video.amd.amd_enforce_hrd},
|
||||
{"level"s, [](const config_t &cfg) {
|
||||
auto size = cfg.width * cfg.height;
|
||||
// For 4K and below, try to use level 5.1 or 5.2 if possible
|
||||
if (size <= 8912896) {
|
||||
if (size * cfg.framerate <= 534773760) {
|
||||
return "5.1"s;
|
||||
} else if (size * cfg.framerate <= 1069547520) {
|
||||
return "5.2"s;
|
||||
}
|
||||
}
|
||||
return "auto"s;
|
||||
}},
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -1639,7 +1651,7 @@ namespace video {
|
||||
ctx->thread_count = ctx->slices;
|
||||
|
||||
AVDictionary *options {nullptr};
|
||||
auto handle_option = [&options](const encoder_t::option_t &option) {
|
||||
auto handle_option = [&options, &config](const encoder_t::option_t &option) {
|
||||
std::visit(
|
||||
util::overloaded {
|
||||
[&](int v) {
|
||||
@@ -1653,7 +1665,7 @@ namespace video {
|
||||
av_dict_set_int(&options, option.name.c_str(), **v, 0);
|
||||
}
|
||||
},
|
||||
[&](std::function<int()> v) {
|
||||
[&](const std::function<int()> &v) {
|
||||
av_dict_set_int(&options, option.name.c_str(), v(), 0);
|
||||
},
|
||||
[&](const std::string &v) {
|
||||
@@ -1663,6 +1675,9 @@ namespace video {
|
||||
if (!v->empty()) {
|
||||
av_dict_set(&options, option.name.c_str(), v->c_str(), 0);
|
||||
}
|
||||
},
|
||||
[&](const std::function<const std::string(const config_t &cfg)> &v) {
|
||||
av_dict_set(&options, option.name.c_str(), v(config).c_str(), 0);
|
||||
}
|
||||
},
|
||||
option.value
|
||||
@@ -1875,9 +1890,10 @@ namespace video {
|
||||
}
|
||||
});
|
||||
|
||||
// set minimum frame time based on client-requested target framerate
|
||||
std::chrono::duration<double, std::milli> minimum_frame_time {1000.0 / config.framerate};
|
||||
BOOST_LOG(info) << "Minimum frame time set to "sv << minimum_frame_time.count() << "ms, based on client-requested target framerate "sv << config.framerate << "."sv;
|
||||
// set max frame time based on client-requested target framerate.
|
||||
double minimum_fps_target = (config::video.minimum_fps_target > 0.0) ? config::video.minimum_fps_target : config.framerate;
|
||||
std::chrono::duration<double, std::milli> max_frametime {1000.0 / minimum_fps_target};
|
||||
BOOST_LOG(info) << "Minimum FPS target set to ~"sv << (minimum_fps_target / 2) << "fps ("sv << max_frametime.count() * 2 << "ms)"sv;
|
||||
|
||||
auto shutdown_event = mail->event<bool>(mail::shutdown);
|
||||
auto packets = mail::man->queue<packet_t>(mail::video_packets);
|
||||
@@ -1928,7 +1944,7 @@ namespace video {
|
||||
|
||||
// Encode at a minimum FPS to avoid image quality issues with static content
|
||||
if (!requested_idr_frame || images->peek()) {
|
||||
if (auto img = images->pop(minimum_frame_time)) {
|
||||
if (auto img = images->pop(max_frametime)) {
|
||||
frame_timestamp = img->frame_timestamp;
|
||||
if (session->convert(*img)) {
|
||||
BOOST_LOG(error) << "Could not convert image"sv;
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace video {
|
||||
option_t(const option_t &) = default;
|
||||
|
||||
std::string name;
|
||||
std::variant<int, int *, std::optional<int> *, std::function<int()>, std::string, std::string *> value;
|
||||
std::variant<int, int *, std::optional<int> *, std::function<int()>, std::string, std::string *, std::function<const std::string(const config_t &)>> value;
|
||||
|
||||
option_t(std::string &&name, decltype(value) &&value):
|
||||
name {std::move(name)},
|
||||
|
||||
@@ -179,6 +179,7 @@
|
||||
"dd_mode_remapping": {"mixed": [], "resolution_only": [], "refresh_rate_only": []},
|
||||
"dd_wa_hdr_toggle_delay": 0,
|
||||
"max_bitrate": 0,
|
||||
"minimum_fps_target": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PlatformLayout from '../../../PlatformLayout.vue'
|
||||
import Checkbox from "../../../Checkbox.vue";
|
||||
|
||||
const props = defineProps({
|
||||
platform: String,
|
||||
|
||||
@@ -17,6 +17,13 @@ const config = ref(props.config)
|
||||
<input type="number" class="form-control" id="max_bitrate" placeholder="0" v-model="config.max_bitrate" />
|
||||
<div class="form-text">{{ $t("config.max_bitrate_desc") }}</div>
|
||||
</div>
|
||||
|
||||
<!--minimum_fps_target-->
|
||||
<div class="mb-3">
|
||||
<label for="minimum_fps_target" class="form-label">{{ $t("config.minimum_fps_target") }}</label>
|
||||
<input type="number" min="0" max="1000" class="form-control" id="minimum_fps_target" placeholder="0" v-model="config.minimum_fps_target" />
|
||||
<div class="form-text">{{ $t("config.minimum_fps_target_desc") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -137,129 +137,129 @@
|
||||
"av1_mode_3": "Sunshine bude inzerovat podporu hlavních 8bitových a 10bitových profilů AV1 (HDR)",
|
||||
"av1_mode_desc": "Umožňuje klientovi požádat o AV1 hlavní 8-bitové nebo 10-bitové video streamy. AV1 je intenzivnější na CPU kódování, takže díky tomu může dojít ke snížení výkonu při používání kódování softwaru.",
|
||||
"back_button_timeout": "Časový limit emulace tlačítka Domů/Návod",
|
||||
"back_button_timeout_desc": "Pokud je tlačítko Zpět/Výběr podrženo pro zadaný počet milisekund, je emulováno stisknutí tlačítka Domů/Průvodce. Je-li nastaveno na hodnotu < 0 (výchozí), podržením tlačítka Zpět/Výběr nebude tlačítko Domů/Průvodce emulováno.",
|
||||
"back_button_timeout_desc": "Pokud je tlačítko Zpět/Vybrat podrženo po zadaný počet milisekund, je emulováno stisknutí tlačítka Domů/Průvodce. Pokud je nastavena hodnota < 0 (výchozí), podržením tlačítka Zpět/Vybrat se tlačítko Domů/Průvodce neemuluje.",
|
||||
"capture": "Vynutit specifickou metodu snímání",
|
||||
"capture_desc": "V automatickém režimu bude Sunshine používat ten první, který funguje. NvFBC vyžaduje upravené nvidia ovladače.",
|
||||
"cert": "Osvědčení",
|
||||
"cert_desc": "Certifikát používaný pro párování webových UI a Moonlight klientů. Pro nejlepší kompatibilitu by měl mít veřejný klíč RSA-2048.",
|
||||
"capture_desc": "V automatickém režimu Sunshine použije první, který funguje. NvFBC vyžaduje opravené ovladače nvidia.",
|
||||
"cert": "Certifikát",
|
||||
"cert_desc": "Certifikát použitý pro párování webového uživatelského rozhraní a klienta Moonlight. Kvůli nejlepší kompatibilitě by měl mít veřejný klíč RSA-2048.",
|
||||
"channels": "Maximální počet připojených klientů",
|
||||
"channels_desc_1": "Sluneční svár může umožnit sdílení jediné streamovací relace s více klienty současně.",
|
||||
"channels_desc_1": "Sunshine může umožnit sdílení jedné relace streamování s více klienty současně.",
|
||||
"channels_desc_2": "Některé hardwarové enkodéry mohou mít omezení, která snižují výkon s více streamy.",
|
||||
"coder_cabac": "cabac -- kontextové binární aritmetické kódování – vyšší kvalita",
|
||||
"coder_cavlc": "cavlc -- kontextové adaptivní kódování variabilní délky - rychlejší dekódování",
|
||||
"configuration": "Konfigurace",
|
||||
"controller": "Enable Gamepad Input",
|
||||
"controller_desc": "Umožňuje hostům ovládat hostitelský systém pomocí gamepad / controller",
|
||||
"controller": "Povolení vstupu z gamepadu",
|
||||
"controller_desc": "Umožňuje hostům ovládat hostitelský systém pomocí gamepadu/ovladače",
|
||||
"credentials_file": "Soubor pověření",
|
||||
"credentials_file_desc": "Uložit uživatelské jméno/heslo odděleně od souboru se stavem Sunshine.",
|
||||
"credentials_file_desc": "Uživatelské jméno/heslo ukládejte odděleně od souboru stavu Sunshine.",
|
||||
"dd_config_ensure_active": "Automaticky aktivovat displej",
|
||||
"dd_config_ensure_only_display": "Deaktivovat další displeje a aktivovat pouze zadaný displej",
|
||||
"dd_config_ensure_primary": "Automaticky aktivovat displej a učinit jej primárním displejem",
|
||||
"dd_config_label": "Konfigurace zařízení",
|
||||
"dd_config_revert_delay": "Zpoždění nastavení zpětného chodu",
|
||||
"dd_config_revert_delay_desc": "Další zpoždění v milisekundách čeká na obnovení konfigurace při zavření aplikace nebo ukončení poslední relace. Hlavním účelem je zajistit hladký přechod při rychlém přepínání mezi aplikacemi.",
|
||||
"dd_config_revert_on_disconnect": "Konfigurace se vrátí po odpojení",
|
||||
"dd_config_revert_on_disconnect_desc": "Vrátit konfiguraci po odpojení všech klientů namísto zavření aplikace nebo posledního ukončení relace.",
|
||||
"dd_config_revert_delay": "Zpoždění vrácení konfigurace",
|
||||
"dd_config_revert_delay_desc": "Dodatečná prodleva v milisekundách, která má být vyčkána před vrácením konfigurace, pokud byla aplikace zavřena nebo poslední relace ukončena. Hlavním účelem je zajistit plynulejší přechod při rychlém přepínání mezi aplikacemi.",
|
||||
"dd_config_revert_on_disconnect": "Vrácení konfigurace při odpojení",
|
||||
"dd_config_revert_on_disconnect_desc": "Vrácení konfigurace při odpojení všech klientů místo ukončení aplikace nebo poslední relace.",
|
||||
"dd_config_verify_only": "Ověřte, zda je displej povolen",
|
||||
"dd_hdr_option": "HDR",
|
||||
"dd_hdr_option_auto": "Zapnout/vypnout HDR režim podle požadavku klienta (výchozí)",
|
||||
"dd_hdr_option_disabled": "Neměnit nastavení HDR",
|
||||
"dd_mode_remapping": "Režim zobrazení přemapování",
|
||||
"dd_mode_remapping": "Přemapování režimu zobrazení",
|
||||
"dd_mode_remapping_add": "Přidat položku pro nové mapování",
|
||||
"dd_mode_remapping_desc_1": "Určete položky pro nové mapování pro změnu požadovaného rozlišení a/nebo obnovení frekvence na jiné hodnoty.",
|
||||
"dd_mode_remapping_desc_2": "Seznam se iteruje shora dolů a použije se první shoda.",
|
||||
"dd_mode_remapping_desc_3": "Pole \"Požadováno\" mohou být ponechána prázdná, aby odpovídala libovolné požadované hodnotě.",
|
||||
"dd_mode_remapping_desc_4_final_values_mixed": "Alespoň jedno pole \"Final\" musí být zadáno. Nespecifikované rozlišení nebo obnovovací frekvence se nezmění.",
|
||||
"dd_mode_remapping_desc_4_final_values_mixed": "Musí být zadáno alespoň jedno pole \"Final\". Nezadané rozlišení nebo obnovovací frekvence se nezmění.",
|
||||
"dd_mode_remapping_desc_4_final_values_non_mixed": "Pole \"Final\" musí být zadáno a nesmí být prázdné.",
|
||||
"dd_mode_remapping_desc_5_sops_mixed_only": "Možnost \"Optimalizovat nastavení hry\" musí být povolena v klientovi Měsíční světlo, jinak budou přeskočeny záznamy s libovolnými vybranými rozlišeními polí.",
|
||||
"dd_mode_remapping_desc_5_sops_resolution_only": "Možnost \"Optimalizovat nastavení hry\" musí být povolena v klientovi Měsíční světlo, jinak je mapování přeskočeno.",
|
||||
"dd_mode_remapping_desc_5_sops_mixed_only": "V klientovi Moonlight musí být povolena možnost \"Optimalizovat nastavení hry\", jinak budou položky se zadanými poli rozlišení přeskočeny.",
|
||||
"dd_mode_remapping_desc_5_sops_resolution_only": "V klientovi Moonlight musí být povolena možnost \"Optimalizovat nastavení hry\", jinak se mapování přeskočí.",
|
||||
"dd_mode_remapping_final_refresh_rate": "Konečná obnovovací frekvence",
|
||||
"dd_mode_remapping_final_resolution": "Konečné řešení",
|
||||
"dd_mode_remapping_requested_fps": "Požadovaná FPS",
|
||||
"dd_mode_remapping_final_resolution": "Konečné rozlišení",
|
||||
"dd_mode_remapping_requested_fps": "Požadované FPS",
|
||||
"dd_mode_remapping_requested_resolution": "Požadované rozlišení",
|
||||
"dd_options_header": "Rozšířené možnosti displeje",
|
||||
"dd_refresh_rate_option": "Obnovovací frekvence",
|
||||
"dd_refresh_rate_option_auto": "Použít FPS hodnotu poskytnutou klientem (výchozí)",
|
||||
"dd_refresh_rate_option_auto": "Použít hodnotu FPS zadanou klientem (výchozí)",
|
||||
"dd_refresh_rate_option_disabled": "Neměnit obnovovací frekvenci",
|
||||
"dd_refresh_rate_option_manual": "Použít ručně zadanou obnovovací frekvenci",
|
||||
"dd_refresh_rate_option_manual_desc": "Zadejte obnovovací frekvenci pro použití",
|
||||
"dd_refresh_rate_option_manual_desc": "Zadejte obnovovací frekvenci, která se má použít",
|
||||
"dd_resolution_option": "Rozlišení",
|
||||
"dd_resolution_option_auto": "Použít rozlišení poskytované klientem (výchozí)",
|
||||
"dd_resolution_option_disabled": "Neměnit rozlišení",
|
||||
"dd_resolution_option_manual": "Použít ručně zadané rozlišení",
|
||||
"dd_resolution_option_manual_desc": "Zadejte rozlišení, které má být použito",
|
||||
"dd_resolution_option_ogs_desc": "Možnost \"Optimalizovat nastavení hry\" musí být povolena na klientovi Moonlight aby to fungovalo.",
|
||||
"dd_wa_hdr_toggle_delay_desc_1": "Při použití virtuálního displeje (VDD) pro vysílání může nesprávně zobrazit barvu HDR. Sluneční svár se může pokusit tento problém zmírnit tím, že vypne HDR a poté znovu vypne.",
|
||||
"dd_wa_hdr_toggle_delay_desc_2": "Pokud je hodnota nastavena na 0, je práce zakázána (výchozí). Pokud je hodnota mezi 0 a 3000 milisekundami, sunshine vypne HDR, počkejte na stanovený čas a pak znovu zapněte HDR. Doporučená doba zpoždění je ve většině případů přibližně 500 milisekund.",
|
||||
"dd_wa_hdr_toggle_delay_desc_3": "NEPOUŽÍVEJTE toto fungování, pokud nemáte problémy s HDR protože přímo ovlivňuje počáteční čas!",
|
||||
"dd_wa_hdr_toggle_delay": "Práce na vysokém kontrastu pro HDR",
|
||||
"ds4_back_as_touchpad_click": "Mapa zpátky/Vyberte pro klepnutí na Touchpad",
|
||||
"ds4_back_as_touchpad_click_desc": "Při vynucení emulace DS4 mapa zpět/Vyberte na Touchpad kliknutí",
|
||||
"dd_resolution_option_ogs_desc": "Aby tato funkce fungovala, musí být v klientovi Moonlight povolena možnost \"Optimalizovat nastavení hry\".",
|
||||
"dd_wa_hdr_toggle_delay_desc_1": "Při použití virtuálního zobrazovacího zařízení (VDD) pro streamování může dojít k nesprávnému zobrazení barev HDR. Sunshine se může pokusit tento problém zmírnit vypnutím a opětovným zapnutím HDR.",
|
||||
"dd_wa_hdr_toggle_delay_desc_2": "Pokud je hodnota nastavena na 0, je obcházení zakázáno (výchozí nastavení). Pokud je hodnota v rozmezí 0 až 3000 milisekund, Sunshine vypne HDR, počká zadanou dobu a poté HDR opět zapne. Doporučená doba zpoždění je ve většině případů přibližně 500 milisekund.",
|
||||
"dd_wa_hdr_toggle_delay_desc_3": "NEPOUŽÍVEJTE toto řešení, pokud skutečně nemáte problémy s HDR, protože přímo ovlivňuje čas spuštění streamu!",
|
||||
"dd_wa_hdr_toggle_delay": "Řešení pro HDR s vysokým kontrastem",
|
||||
"ds4_back_as_touchpad_click": "Namapovat Zpět/Vybrat na klepnutí touchpadu",
|
||||
"ds4_back_as_touchpad_click_desc": "Při vynucení emulace DS4 namapujte funkci Zpět/Vybrat na klepnutí touchpadu",
|
||||
"encoder": "Vynutit specifický enkodér",
|
||||
"encoder_desc": "Vynutit konkrétní enkodér, jinak Sunshine vybere nejlepší dostupnou možnost. Poznámka: Pokud zadáte hardwarový enkodér v systému Windows, musí odpovídat GPU, kde je displej připojen.",
|
||||
"encoder_software": "Programové vybavení",
|
||||
"encoder_desc": "Vynutit konkrétní kodér, jinak Sunshine vybere nejlepší dostupnou možnost. Poznámka: Pokud v systému Windows zadáte hardwarový kodér, musí odpovídat grafickému procesoru, ke kterému je displej připojen.",
|
||||
"encoder_software": "Software",
|
||||
"external_ip": "Externí IP",
|
||||
"external_ip_desc": "Pokud není zadána žádná externí IP adresa, Sluneční server automaticky rozpozná externí IP adresu",
|
||||
"external_ip_desc": "Pokud není zadána žádná externí IP adresa, Sunshine automaticky zjistí externí IP adresu",
|
||||
"fec_percentage": "Procento FEC",
|
||||
"fec_percentage_desc": "Procento chyb při opravě paketů na datových paketech v každém video snímku. Vyšší hodnoty mohou opravit větší ztrátu síťových paketů, ale za cenu zvýšení využití šířky pásma.",
|
||||
"ffmpeg_auto": "auto -- nechat rozhodnutí ffmpeg (výchozí)",
|
||||
"fec_percentage_desc": "Procento paketů pro opravu chyb v každém datovém paketu v každém videosnímku. Vyšší hodnoty mohou korigovat větší ztráty síťových paketů, ale za cenu zvýšení využití šířky pásma.",
|
||||
"ffmpeg_auto": "auto -- nechat ffmpeg rozhodnout (výchozí)",
|
||||
"file_apps": "Soubor aplikací",
|
||||
"file_apps_desc": "Soubor, kde jsou uloženy aktuální aplikace Sunshine.",
|
||||
"file_state": "Státní soubor",
|
||||
"file_state_desc": "Soubor, ve kterém je uložen aktuální stav sunshine",
|
||||
"gamepad": "Emulovaný typ hry",
|
||||
"file_apps_desc": "Soubor, ve kterém jsou uloženy aktuální aplikace Sunshine.",
|
||||
"file_state": "Stavový soubor",
|
||||
"file_state_desc": "Soubor, ve kterém je uložen aktuální stav Sunshine",
|
||||
"gamepad": "Typ emulovaného gamepadu",
|
||||
"gamepad_auto": "Možnosti automatického výběru",
|
||||
"gamepad_desc": "Vyberte typ gamepadu, který chcete emulovat na hostiteli",
|
||||
"gamepad_desc": "Výběr typu gamepadu pro emulaci v hostitelském počítači",
|
||||
"gamepad_ds4": "DS4 (PS4)",
|
||||
"gamepad_ds4_manual": "Možnosti výběru DS4",
|
||||
"gamepad_ds5": "DS5 (PS5)",
|
||||
"gamepad_switch": "Nintendo Pro (Switch)",
|
||||
"gamepad_manual": "Možnosti manuálního DS4",
|
||||
"gamepad_manual": "Možnosti manuálního ovládání DS4",
|
||||
"gamepad_x360": "X360 (Xbox 360)",
|
||||
"gamepad_xone": "Xone (Xbox Jedna)",
|
||||
"gamepad_xone": "XOne (Xbox One)",
|
||||
"global_prep_cmd": "Příprava příkazů",
|
||||
"global_prep_cmd_desc": "Konfigurace seznamu příkazů, které mají být provedeny před spuštěním jakékoli aplikace nebo po ní. Pokud některý z určených příkazů neuspěje, proces spuštění aplikace bude přerušen.",
|
||||
"global_prep_cmd_desc": "Konfigurace seznamu příkazů, které se mají spustit před nebo po spuštění libovolné aplikace. Pokud některý ze zadaných přípravných příkazů selže, proces spuštění aplikace se přeruší.",
|
||||
"hevc_mode": "Podpora HEVC",
|
||||
"hevc_mode_0": "Sunshine bude propagovat podporu pro HEVC na základě možností enkodéru (doporučeno)",
|
||||
"hevc_mode_1": "Sluneční síť nebude propagovat podporu HEVC",
|
||||
"hevc_mode_2": "Sluneční svaz bude propagovat podporu hlavního profilu HEVC",
|
||||
"hevc_mode_3": "Sluneční svaz bude propagovat podporu profilů HEVC Main a Main10 (HDR)",
|
||||
"hevc_mode_desc": "Umožňuje klientovi vyžádat si HEVC Main nebo HEVC Main10 video streamy. HEVC je intenzivnější na CPU kódování, takže povolení může snížit výkon při používání kódování softwaru.",
|
||||
"hevc_mode_1": "Sunshine nebude inzerovat podporu HEVC",
|
||||
"hevc_mode_2": "Sunshine bude inzerovat podporu hlavního profilu HEVC",
|
||||
"hevc_mode_3": "Sunshine bude inzerovat podporu profilů HEVC Main a Main10 (HDR)",
|
||||
"hevc_mode_desc": "Umožňuje klientovi vyžádat videostreamy HEVC Main nebo HEVC Main10. Kódování HEVC je náročnější na procesor, takže zapnutí této funkce může snížit výkon při použití softwarového kódování.",
|
||||
"high_resolution_scrolling": "Podpora rolování s vysokým rozlišením",
|
||||
"high_resolution_scrolling_desc": "Pokud je povoleno, sunshine projde událostmi posunu s vysokým rozlišením od klientů Moonight. To může být užitečné pro vypnutí starších aplikací, které se posouvají příliš rychle při posunu s vysokým rozlišením.",
|
||||
"install_steam_audio_drivers": "Nainstalujte Steam Audio Drivers",
|
||||
"install_steam_audio_drivers_desc": "Pokud je Steam nainstalován, tak se automaticky nainstaluje ovladač Steam Streaming Speakers pro podporu 5.1/7.1 prostorového zvuku a ztlumení zvuku.",
|
||||
"key_repeat_delay": "Zpoždění opakování klíče",
|
||||
"key_repeat_delay_desc": "Ovládejte, jak rychle se budou klíče opakovat. Počáteční zpoždění v milisekundách před opakováním klíčů.",
|
||||
"key_repeat_frequency": "Frekvence opakování klíče",
|
||||
"key_repeat_frequency_desc": "Jak často se klíče opakují každou vteřinu. Tato konfigurovatelná volba podporuje desetinná místa.",
|
||||
"key_rightalt_to_key_win": "Mapovat pravý Alt klíč k klíči Windows",
|
||||
"key_rightalt_to_key_win_desc": "Může být možné, že z Moonlight nemůžete přímo odeslat klíč pro Windows. V těchto případech může být užitečné udělat sunshine si myslet, že klíč pravý Alt je klíč pro Windows",
|
||||
"keyboard": "Povolit vstup klávesnice",
|
||||
"high_resolution_scrolling_desc": "Je-li tato funkce povolena, bude Sunshine předávat události posouvání ve vysokém rozlišení od klientů Moonlight. To může být užitečné zakázat u starších aplikací, které se při událostech posouvání ve vysokém rozlišení posouvají příliš rychle.",
|
||||
"install_steam_audio_drivers": "Instalace ovladačů zvuku služby Steam",
|
||||
"install_steam_audio_drivers_desc": "Pokud je nainstalována služba Steam, automaticky se nainstaluje ovladač Steam Streaming Speakers pro podporu prostorového zvuku 5.1/7.1 a ztlumení zvuku hostitele.",
|
||||
"key_repeat_delay": "Zpoždění opakování kláves",
|
||||
"key_repeat_delay_desc": "Ovládání rychlosti opakování kláves. Počáteční prodleva v milisekundách před opakováním kláves.",
|
||||
"key_repeat_frequency": "Frekvence opakování kláves",
|
||||
"key_repeat_frequency_desc": "Jak často se klávesy opakují každou sekundu. Tato nastavitelná možnost podporuje desetinná čísla.",
|
||||
"key_rightalt_to_key_win": "Mapování pravé klávesy Alt na klávesu Windows",
|
||||
"key_rightalt_to_key_win_desc": "Je možné, že klávesa Windows nelze odeslat přímo z aplikace Moonlight. V takových případech může být užitečné přimět Sunshine, aby si myslel, že pravý Alt je klávesa Windows",
|
||||
"keyboard": "Povolit vstupu z klávesnice",
|
||||
"keyboard_desc": "Umožňuje hostům ovládat hostitelský systém pomocí klávesnice",
|
||||
"lan_encryption_mode": "Režim šifrování LAN",
|
||||
"lan_encryption_mode_1": "Povoleno pro podporované klienty",
|
||||
"lan_encryption_mode_2": "Vyžadováno pro všechny klienty",
|
||||
"lan_encryption_mode_desc": "Určuje, kdy bude šifrování použito při streamování přes místní síť. Šifrování může snížit výkon streamování, zejména u méně výkonných hostitelů a klientů.",
|
||||
"locale": "Místní prostředí",
|
||||
"locale_desc": "Lokální prostředí používané pro uživatelské rozhraní Sunshine.",
|
||||
"locale_desc": "Místní jazyk používaný pro uživatelské rozhraní Sunshine.",
|
||||
"log_level": "Úroveň logu",
|
||||
"log_level_0": "Verbose",
|
||||
"log_level_1": "Debug",
|
||||
"log_level_2": "Info",
|
||||
"log_level_3": "Varování",
|
||||
"log_level_4": "Chyba",
|
||||
"log_level_5": "Fatal",
|
||||
"log_level_5": "Fatální",
|
||||
"log_level_6": "Nic",
|
||||
"log_level_desc": "Minimální úroveň logu vytištěná pro standardizaci",
|
||||
"log_level_desc": "Minimální úroveň logu vypisovaná do standardního výstupu",
|
||||
"log_path": "Cesta k logu",
|
||||
"log_path_desc": "Soubor s aktuálními protokoly sunshine jsou uloženy.",
|
||||
"log_path_desc": "Soubor, ve kterém jsou uloženy aktuální logy Sunshine.",
|
||||
"max_bitrate": "Maximální bitrate",
|
||||
"max_bitrate_desc": "Maximální bitrate (v Kbps) zakódovaný sunshine streamem. Je-li nastaveno na 0, bude vždy používat bitrate požadovaný Moonlight.",
|
||||
"min_threads": "Minimální počet CPU vláken",
|
||||
"min_threads_desc": "Zvýšení hodnoty mírně snižuje efektivitu kódování, ale tento kompromis obvykle stojí za to získat více jader CPU pro kódování. Ideální hodnota je nejnižší hodnota, která může spolehlivě kódovat v požadovaném nastavení streamu do vašeho hardwaru.",
|
||||
"max_bitrate_desc": "Maximální bitrate (v Kb/s), kterým bude Sunshine kódovat datový tok. Pokud je nastaven na 0, bude vždy použit bitrate požadovaný aplikací Moonlight.",
|
||||
"min_threads": "Minimální počet vláken CPU",
|
||||
"min_threads_desc": "Zvýšení této hodnoty mírně snižuje efektivitu kódování, ale tento kompromis se obvykle vyplatí, protože získáte více jader procesoru pro kódování. Ideální hodnota je nejnižší hodnota, která dokáže spolehlivě enkódovat při požadovaném nastavení streamování na vašem hardwaru.",
|
||||
"misc": "Různé možnosti",
|
||||
"motion_as_ds4": "Emulovat DS4 gamepad pokud jsou přítomny snímače pohybu",
|
||||
"motion_as_ds4": "Emulovat gamepad DS4, pokud klientský gamepad hlásí přítomnost pohybových senzorů",
|
||||
"motion_as_ds4_desc": "Je-li zakázáno, nebudou při výběru typu gamepadu brány v úvahu snímače pohybu.",
|
||||
"mouse": "Povolit vstup myši",
|
||||
"mouse_desc": "Umožňuje hostům ovládat systém pomocí myši",
|
||||
@@ -313,52 +313,52 @@
|
||||
"port_udp": "UDP",
|
||||
"port_warning": "Vystavení webového uživatelského rozhraní na internet je bezpečnostní riziko! Pokračujte na vlastní nebezpečí!",
|
||||
"port_web_ui": "Web UI",
|
||||
"qp": "Parametr kvantizace",
|
||||
"qp_desc": "Některá zařízení nemusí podporovat Constant Bit Rate. Pro tato zařízení se místo toho používá QP. Vyšší hodnota znamená větší kompresi, ale menší kvalitu.",
|
||||
"qp": "Kvantizační parametr",
|
||||
"qp_desc": "Některá zařízení nemusí podporovat konstantní přenosovou rychlost. U těchto zařízení se místo toho používá QP. Vyšší hodnota znamená větší kompresi, ale nižší kvalitu.",
|
||||
"qsv_coder": "Kodér QuickSync (H264)",
|
||||
"qsv_preset": "QuickSync Preset",
|
||||
"qsv_preset_fast": "rychlá (nízká kvalita)",
|
||||
"qsv_preset": "Předvolba QuickSync",
|
||||
"qsv_preset_fast": "rychle (nízká kvalita)",
|
||||
"qsv_preset_faster": "rychlejší (nižší kvalita)",
|
||||
"qsv_preset_medium": "střední (výchozí)",
|
||||
"qsv_preset_slow": "pomalý (dobrá kvalita)",
|
||||
"qsv_preset_slower": "pomalejší (lepší kvalita)",
|
||||
"qsv_preset_slowest": "nejpomalejší (nejlepší kvalita)",
|
||||
"qsv_preset_veryfast": "nejrychlejší (nejnižší jakost)",
|
||||
"qsv_preset_veryfast": "nejrychlejší (nejnižší kvalita)",
|
||||
"qsv_slow_hevc": "Povolit pomalé kódování HEVC",
|
||||
"qsv_slow_hevc_desc": "To může povolit HEVC kódování na starších Intel GPU, za cenu vyšší spotřeby GPU a horšího výkonu.",
|
||||
"restart_note": "Sluneční brýle se restartuje a aplikuje změny.",
|
||||
"stream_audio": "Stream zvuk",
|
||||
"stream_audio_desc": "Zakázání zvuku může být užitečné pro streamování bezhlavých displejů jako druhý monitor.",
|
||||
"sunshine_name": "Sluneční jméno",
|
||||
"sunshine_name_desc": "Jméno zobrazené podle měsíčního světla. Není-li zadáno, použije se hostname počítače",
|
||||
"sw_preset": "SW přednastavení",
|
||||
"sw_preset_desc": "Optimalizujte kompromis mezi rychlostí kódování (kódované snímky za sekundu) a efektivitou komprese (kvalita na bit v bitovém toku). Výchozí nastavení je superrychlé.",
|
||||
"qsv_slow_hevc_desc": "To může umožnit kódování HEVC na starších grafických procesorech Intel za cenu vyššího využití grafického procesoru a nižšího výkonu.",
|
||||
"restart_note": "Sunshine se restartuje a aplikuje změny.",
|
||||
"stream_audio": "Streamování zvuku",
|
||||
"stream_audio_desc": "Zda se má zvuk streamovat, nebo ne. Vypnutí této funkce může být užitečné pro streamování bezhlavých displejů jako druhých monitorů.",
|
||||
"sunshine_name": "Jméno Sunshine",
|
||||
"sunshine_name_desc": "Název zobrazený u Moonlight. Pokud není zadán, použije se název hostitele počítače",
|
||||
"sw_preset": "Předvolby SW",
|
||||
"sw_preset_desc": "Optimalizace kompromisu mezi rychlostí kódování (zakódované snímky za sekundu) a účinností komprese (kvalita na bit v datovém toku). Výchozí hodnota je superrychlá.",
|
||||
"sw_preset_fast": "rychlá",
|
||||
"sw_preset_faster": "rychleji",
|
||||
"sw_preset_medium": "střední",
|
||||
"sw_preset_slow": "pomalu",
|
||||
"sw_preset_slower": "pomalejší",
|
||||
"sw_preset_superfast": "superfast (výchozí)",
|
||||
"sw_preset_ultrafast": "ultrafast",
|
||||
"sw_preset_veryfast": "veryfast",
|
||||
"sw_preset_veryslow": "veryslow",
|
||||
"sw_tune": "SW melodie",
|
||||
"sw_tune_animation": "animace -- dobré pro karikatury; používá vyšší deblokovací a více referenčních rámců",
|
||||
"sw_tune_desc": "Vyladění možností, které jsou aplikovány po předvolbě. Výchozí nastavení je nula.",
|
||||
"sw_preset_superfast": "superrychlá (výchozí)",
|
||||
"sw_preset_ultrafast": "ultrarychlá",
|
||||
"sw_preset_veryfast": "velmirychlá",
|
||||
"sw_preset_veryslow": "velmipomalá",
|
||||
"sw_tune": "SW ladění",
|
||||
"sw_tune_animation": "animace -- vhodné pro kreslené filmy; používá vyšší deblokaci a více referenčních snímků",
|
||||
"sw_tune_desc": "Možnosti ladění, které se použijí po předvolbě. Výchozí hodnota je nulová latence.",
|
||||
"sw_tune_fastdecode": "fastdecode -- umožňuje rychlejší dekódování vypnutím určitých filtrů",
|
||||
"sw_tune_film": "film -- používá pro vysoce kvalitní filmový obsah; snižuje odblokování",
|
||||
"sw_tune_grain": "zrno – zachovává strukturu zrn ve starém, zrním materiálu",
|
||||
"sw_tune_stillimage": "stillimage -- dobré pro slideshow-like obsah",
|
||||
"sw_tune_zerolatency": "nulová latence -- dobrá pro rychlé kódování a nízká latence streamování (výchozí)",
|
||||
"touchpad_as_ds4": "Emulovat DS4 gamepad pokud klient nahlásí přítomnost touchpadu",
|
||||
"touchpad_as_ds4_desc": "Je-li zakázáno, během výběru typu gamepadu nebude brána v úvahu přítomnost touchpadu.",
|
||||
"sw_tune_film": "film -- použití pro vysoce kvalitní filmový obsah; snižuje deblokaci",
|
||||
"sw_tune_grain": "zrno - zachovává strukturu zrna ve starém zrnitém filmovém materiálu",
|
||||
"sw_tune_stillimage": "stillimage -- dobré pro prezentační obsah",
|
||||
"sw_tune_zerolatency": "zerolatency -- vhodné pro rychlé kódování a streamování s nízkou latencí (výchozí)",
|
||||
"touchpad_as_ds4": "Emulovat gamepad DS4, pokud klientský gamepad hlásí přítomnost touchpadu",
|
||||
"touchpad_as_ds4_desc": "Pokud je vypnuto, nebude při výběru typu gamepadu zohledněna přítomnost touchpadu.",
|
||||
"upnp": "UPnP",
|
||||
"upnp_desc": "Automaticky konfigurovat přesměrování portů pro streamování přes Internet",
|
||||
"vaapi_strict_rc_buffer": "Striktně prosazovat limity bitrate pro H.264/HEVC na AMD GPU.",
|
||||
"vaapi_strict_rc_buffer_desc": "Povolením této volby se během změn scény vyhnete shození snímků přes síť, ale kvalita videa může být během pohybu snížena.",
|
||||
"virtual_sink": "Virtuální šinek",
|
||||
"virtual_sink_desc": "Ručně zadejte virtuální audio zařízení, které má být použito. Pokud je zařízení odstaveno, je vybráno automaticky. Důrazně doporučujeme ponechat toto pole prázdné pro automatický výběr zařízení!",
|
||||
"virtual_sink_placeholder": "Reproduktory pro streamování přes Steam",
|
||||
"upnp_desc": "Automatická konfigurace přesměrování portů pro streamování přes Internet",
|
||||
"vaapi_strict_rc_buffer": "Přísné vynucení limitů datového toku snímků pro H.264/HEVC na grafických procesorech AMD",
|
||||
"vaapi_strict_rc_buffer_desc": "Povolením této možnosti lze zabránit vypadávání snímků po síti při změnách scény, ale kvalita videa může být při pohybu snížena.",
|
||||
"virtual_sink": "Virtuální zvuk",
|
||||
"virtual_sink_desc": "Ručně zadejte virtuální zvukové zařízení, které chcete použít. Pokud není nastaveno, je zařízení vybráno automaticky. Důrazně doporučujeme ponechat toto pole prázdné, chcete-li použít automatický výběr zařízení!",
|
||||
"virtual_sink_placeholder": "Streamovací reproduktory služby Steam",
|
||||
"vt_coder": "VideoToolbox Coder",
|
||||
"vt_realtime": "Video Toolbox v reálném čase enkódování",
|
||||
"vt_software": "Softwarové kódování video nástrojů",
|
||||
@@ -422,34 +422,34 @@
|
||||
"troubleshooting": {
|
||||
"dd_reset": "Obnovit nastavení trvalého zobrazení zařízení",
|
||||
"dd_reset_desc": "Pokud se sluneční svaz zasekne o obnovení změněného nastavení zobrazovacího zařízení, můžete obnovit nastavení a pokračovat v obnově stavu displeje ručně.",
|
||||
"dd_reset_error": "Chyba při obnovování trvalosti!",
|
||||
"dd_reset_success": "Úspěch resetování trvalosti!",
|
||||
"dd_reset_error": "Chyba při obnovení perzistence!",
|
||||
"dd_reset_success": "Úspěch resetování perzistence!",
|
||||
"force_close": "Vynutit zavření",
|
||||
"force_close_desc": "Pokud si Měsíc stěžuje na právě spuštěnou aplikaci, vynucené zavření aplikace by mělo problém vyřešit.",
|
||||
"force_close_desc": "Pokud si aplikace Moonlight stěžuje na aktuálně spuštěnou aplikaci, mělo by její násilné zavření problém vyřešit.",
|
||||
"force_close_error": "Chyba při zavírání aplikace",
|
||||
"force_close_success": "Aplikace úspěšně uzavřena!",
|
||||
"logs": "Logy",
|
||||
"logs_desc": "Podívejte se na logy nahrané sunshine",
|
||||
"logs_find": "Najít...",
|
||||
"logs_desc": "Podívejte se na logy nahrané Sunshine",
|
||||
"logs_find": "Hledat...",
|
||||
"restart_sunshine": "Restartovat Sunshine",
|
||||
"restart_sunshine_desc": "Pokud sluneční svit nefunguje správně, můžete jej zkusit restartovat. To ukončí všechny spuštěné relace.",
|
||||
"restart_sunshine_desc": "Pokud Sunshine nefunguje správně, můžete jej zkusit restartovat. Tím se ukončí všechny spuštěné relace.",
|
||||
"restart_sunshine_success": "Sunshine se restartuje",
|
||||
"troubleshooting": "Řešení problémů",
|
||||
"unpair_all": "Zrušit spárování vše",
|
||||
"unpair_all_error": "Chyba při nepárování",
|
||||
"unpair_all_success": "Všechna zařízení nejsou spárována.",
|
||||
"unpair_desc": "Odstranit spárovaná zařízení. Jednotlivě nespárovaná zařízení s aktivní relací zůstanou připojena, ale nemohou spustit nebo obnovit relaci.",
|
||||
"unpair_all": "Zrušit párování všech",
|
||||
"unpair_all_error": "Chyba při odpárování",
|
||||
"unpair_all_success": "Všechna zařízení jsou nespárovaná.",
|
||||
"unpair_desc": "Odeberte spárovaná zařízení. Jednotlivá nespárovaná zařízení s aktivní relací zůstanou připojena, ale nemohou zahájit nebo obnovit relaci.",
|
||||
"unpair_single_no_devices": "Neexistují žádná spárovaná zařízení.",
|
||||
"unpair_single_success": "Zařízení však mohou být stále v aktivní relaci. Použijte tlačítko 'Vynutit zavření' pro ukončení všech otevřených relací.",
|
||||
"unpair_single_success": "Zařízení však mohou být stále v aktivní relaci. Pomocí výše uvedeného tlačítka \"Vynutit ukončení\" ukončete všechny otevřené relace.",
|
||||
"unpair_single_unknown": "Neznámý klient",
|
||||
"unpair_title": "Zrušit párování"
|
||||
},
|
||||
"welcome": {
|
||||
"confirm_password": "Potvrdit heslo",
|
||||
"create_creds": "Před spuštěním potřebujeme, abyste vytvořili nové uživatelské jméno a heslo pro přístup k webovému uživatelskému rozhraní.",
|
||||
"create_creds_alert": "Níže uvedené přihlašovací údaje jsou potřebné pro přístup k webovému rozhraní Sunshine. Uchovávejte je v bezpečí, protože je už nikdy nebudete vidět!",
|
||||
"create_creds": "Před zahájením je třeba vytvořit nové uživatelské jméno a heslo pro přístup k webovému uživatelskému rozhraní.",
|
||||
"create_creds_alert": "Pro přístup k webovému uživatelskému rozhraní Sunshine je třeba zadat níže uvedené přihlašovací údaje. Uchovávejte je v bezpečí, protože už je nikdy neuvidíte!",
|
||||
"greeting": "Vítejte v Sunshine!",
|
||||
"login": "Přihlásit se",
|
||||
"welcome_success": "Tato stránka se brzy obnoví, váš prohlížeč vás požádá o nové přihlašovací údaje."
|
||||
"welcome_success": "Tato stránka se brzy znovu načte a prohlížeč vás požádá o nové přihlašovací údaje"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +256,8 @@
|
||||
"log_path_desc": "The file where the current logs of Sunshine are stored.",
|
||||
"max_bitrate": "Maximum Bitrate",
|
||||
"max_bitrate_desc": "The maximum bitrate (in Kbps) that Sunshine will encode the stream at. If set to 0, it will always use the bitrate requested by Moonlight.",
|
||||
"minimum_fps_target": "Minimum FPS Target",
|
||||
"minimum_fps_target_desc": "The lowest effective FPS a stream can reach. A value of 0 is treated as roughly half of the stream's FPS. A setting of 20 is recommended if you stream 24 or 30fps content.",
|
||||
"min_threads": "Minimum CPU Thread Count",
|
||||
"min_threads_desc": "Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually worth it to gain the use of more CPU cores for encoding. The ideal value is the lowest value that can reliably encode at your desired streaming settings on your hardware.",
|
||||
"misc": "Miscellaneous options",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"elevated": "Come Admin",
|
||||
"enabled": "Abilitato",
|
||||
"enabled_def": "Abilitato (predefinito)",
|
||||
"enabled_def_cbox": "Predefinito: controllato",
|
||||
"enabled_def_cbox": "Predefinito: selezionato",
|
||||
"error": "Errore!",
|
||||
"note": "Nota:",
|
||||
"password": "Password",
|
||||
@@ -65,7 +65,7 @@
|
||||
"env_vars_desc": "Tutti i comandi ottengono queste variabili d'ambiente per impostazione predefinita:",
|
||||
"env_xrandr_example": "Esempio - Xrandr per l'automazione della risoluzione:",
|
||||
"exit_timeout": "Timeout Uscita",
|
||||
"exit_timeout_desc": "Numero di secondi in cui attendere che tutti i processi delle app si chiudano correttamente quando richiesto. Se disattivato, il valore predefinito è di attendere fino a 5 secondi. Se impostato a zero o a un valore negativo, l'app verrà immediatamente terminata.",
|
||||
"exit_timeout_desc": "Numero di secondi in cui attendere che tutti i processi delle app si chiudano correttamente quando richiesto. Se disattivato, il valore predefinito è di 5 secondi. Se viene impostato a 0 o a un valore negativo, l'app verrà immediatamente terminata.",
|
||||
"find_cover": "Trova Copertina",
|
||||
"global_prep_desc": "Abilita/Disabilita l'esecuzione dei Comandi di Preparazione Globali per questa applicazione.",
|
||||
"global_prep_name": "Comandi di Preparazione Globali",
|
||||
@@ -159,15 +159,15 @@
|
||||
"dd_config_revert_delay": "Ritardo ripristino configurazione",
|
||||
"dd_config_revert_delay_desc": "Ulteriori ritardi in millisecondi per attendere prima di ripristinare la configurazione quando l'app è stata chiusa o l'ultima sessione è terminata. Lo scopo principale è quello di fornire una transizione più fluida quando si passa rapidamente tra le applicazioni.",
|
||||
"dd_config_revert_on_disconnect": "Ripristina configurazione alla disconnessione",
|
||||
"dd_config_revert_on_disconnect_desc": "Ripristina la configurazione al momento della disconnessione di tutti i client invece della chiusura dell'app o dell'ultima terminazione della sessione.",
|
||||
"dd_config_verify_only": "Verifica che il display sia abilitato (predefinito)",
|
||||
"dd_config_revert_on_disconnect_desc": "Ripristina la configurazione al momento della disconnessione di tutti i client invece della chiusura dell'app o l'interruzione dell'ultima sessione.",
|
||||
"dd_config_verify_only": "Verifica che il display sia abilitato",
|
||||
"dd_hdr_option": "HDR",
|
||||
"dd_hdr_option_auto": "Attiva/disattiva la modalità HDR come richiesto dal client (predefinito)",
|
||||
"dd_hdr_option_auto": "Attiva/disattiva la modalità HDR in base alle impostazioni del client (predefinito)",
|
||||
"dd_hdr_option_disabled": "Non modificare le impostazioni HDR",
|
||||
"dd_mode_remapping": "Modalità di visualizzazione remapping",
|
||||
"dd_mode_remapping_add": "Aggiungi voce di remapping",
|
||||
"dd_mode_remapping_desc_1": "Specificare le voci di remapping per modificare la risoluzione richiesta e/o la frequenza di aggiornamento ad altri valori.",
|
||||
"dd_mode_remapping_desc_2": "L'elenco è iterato dall'alto verso il basso e viene usata la prima partita.",
|
||||
"dd_mode_remapping_desc_1": "Specificare le voci di rimappatura per modificare la risoluzione richiesta e/o la frequenza di aggiornamento ad altri valori.",
|
||||
"dd_mode_remapping_desc_2": "L'elenco viene iterato dall'alto verso il basso e viene utilizzata la prima corrispondenza.",
|
||||
"dd_mode_remapping_desc_3": "I campi \"Richiesti\" possono essere lasciati vuoti per corrispondere a qualsiasi valore richiesto.",
|
||||
"dd_mode_remapping_desc_4_final_values_mixed": "Almeno un campo \"Finale\" deve essere specificato. La risoluzione o la frequenza di aggiornamento non specificata non saranno modificate.",
|
||||
"dd_mode_remapping_desc_4_final_values_non_mixed": "Il campo \"Finale\" deve essere specificato e non può essere vuoto.",
|
||||
@@ -175,7 +175,7 @@
|
||||
"dd_mode_remapping_desc_5_sops_resolution_only": "L'opzione \"Ottimizza le impostazioni di gioco\" deve essere abilitata nel client Moonlight, altrimenti la mappatura viene saltata.",
|
||||
"dd_mode_remapping_final_refresh_rate": "Frequenza di aggiornamento finale",
|
||||
"dd_mode_remapping_final_resolution": "Risoluzione finale",
|
||||
"dd_mode_remapping_requested_fps": "FPS Richiesto",
|
||||
"dd_mode_remapping_requested_fps": "FPS richiesti",
|
||||
"dd_mode_remapping_requested_resolution": "Risoluzione richiesta",
|
||||
"dd_options_header": "Opzioni avanzate del dispositivo di visualizzazione",
|
||||
"dd_refresh_rate_option": "Velocità di aggiornamento",
|
||||
@@ -189,9 +189,9 @@
|
||||
"dd_resolution_option_manual": "Usa la risoluzione inserita manualmente",
|
||||
"dd_resolution_option_manual_desc": "Inserisci la risoluzione da usare",
|
||||
"dd_resolution_option_ogs_desc": "L'opzione \"Ottimizza le impostazioni di gioco\" deve essere abilitata sul client Moonlight perché questo funzioni.",
|
||||
"dd_wa_hdr_toggle_delay_desc_1": "Quando si utilizza il dispositivo di visualizzazione virtuale (VDD) per lo streaming, potrebbe visualizzare erroneamente il colore HDR. Sunshine può cercare di mitigare questo problema, spegnendo HDR e poi di nuovo.",
|
||||
"dd_wa_hdr_toggle_delay_desc_2": "Se il valore è impostato a 0, il workaround è disabilitato (predefinito). Se il valore è compreso tra 0 e 3000 millisecondi, Sunshine disattiverà HDR, attendere la quantità di tempo specificata e poi accendere di nuovo l'HDR. Il tempo di ritardo raccomandato è di circa 500 millisecondi nella maggior parte dei casi.",
|
||||
"dd_wa_hdr_toggle_delay_desc_3": "NON utilizzare questo workaround a meno che non si hanno effettivamente problemi con HDR in quanto influisce direttamente sul tempo di inizio del flusso!",
|
||||
"dd_wa_hdr_toggle_delay_desc_1": "Quando si utilizza il dispositivo di visualizzazione virtuale (VDD) per lo streaming, potrebbe visualizzare erroneamente il colore HDR. Sunshine può cercare di mitigare questo problema, attivando e disattivando l'HDR.",
|
||||
"dd_wa_hdr_toggle_delay_desc_2": "Se il valore è impostato a 0, il workaround è disabilitato (predefinito). Se il valore è compreso tra 0 e 3000 millisecondi, Sunshine disattiverà HDR, attenderà la quantità di tempo specificata e poi attiverà di nuovo l'HDR. Il tempo di ritardo raccomandato è di circa 500 millisecondi nella maggior parte dei casi.",
|
||||
"dd_wa_hdr_toggle_delay_desc_3": "NON utilizzare questo workaround a meno che non si abbiano effettivamente problemi con HDR in quanto influisce direttamente sul tempo di inizio del flusso!",
|
||||
"dd_wa_hdr_toggle_delay": "Workaround ad alto contrasto per HDR",
|
||||
"ds4_back_as_touchpad_click": "Mappa Indietro/Select come Clic Touchpad",
|
||||
"ds4_back_as_touchpad_click_desc": "Quando si forza l'emulazione DS4, mappa Indietro/Select come Clic Touchpad",
|
||||
@@ -211,7 +211,7 @@
|
||||
"gamepad_auto": "Opzioni di selezione automatica",
|
||||
"gamepad_desc": "Scegli quale tipo di gamepad emulare sull'host",
|
||||
"gamepad_ds4": "DS4 (PS4)",
|
||||
"gamepad_ds4_manual": "Opzioni di selezione DS4",
|
||||
"gamepad_ds4_manual": "Opzioni del DS4",
|
||||
"gamepad_ds5": "DS5 (PS5)",
|
||||
"gamepad_switch": "Nintendo Pro (Switch)",
|
||||
"gamepad_manual": "Opzioni manuali DS4",
|
||||
@@ -294,9 +294,9 @@
|
||||
"origin_web_ui_allowed_pc": "Solo localhost può accedere all'interfaccia Web",
|
||||
"origin_web_ui_allowed_wan": "Chiunque può accedere all'interfaccia Web",
|
||||
"output_name_desc_unix": "Durante l'avvio di Sunshine, dovresti vedere l'elenco dei display rilevati. Nota: devi usare il valore id all'interno della parentesi. Quello in basso è un esempio, la lista effettiva può essere trovata in \"Risoluzione dei Problemi\".",
|
||||
"output_name_desc_windows": "Specifica manualmente un display da usare per la cattura. Se lasciato vuoto, viene catturato il display primario. Nota: Se hai specificato una GPU sopra, questo display deve essere collegato a quella GPU. I valori appropriati possono essere trovati usando il seguente comando:",
|
||||
"output_name_desc_windows": "Specifica manualmente un display id da usare per la cattura. Se lasciato vuoto, viene catturato il display primario. Nota: Se hai specificato una GPU sopra, questo display deve essere collegato a quella GPU. Durante l'avvio di Sunshine dovresti vedere la lista dei display individuati. Esempio sotto; l'output può essere trovato nella pagina di Troubleshooting.",
|
||||
"output_name_unix": "Numero di Display",
|
||||
"output_name_windows": "Nome Output",
|
||||
"output_name_windows": "Id display",
|
||||
"ping_timeout": "Timeout Ping",
|
||||
"ping_timeout_desc": "Per quanti millisecondi attendere dati da Moonlight prima di chiudere lo streaming",
|
||||
"pkey": "Chiave Privata",
|
||||
@@ -327,7 +327,7 @@
|
||||
"qsv_slow_hevc": "Permetti la codifica lenta in HEVC",
|
||||
"qsv_slow_hevc_desc": "Questo può abilitare la codifica HEVC su vecchie GPU Intel, al costo di un maggiore utilizzo della GPU e prestazioni peggiori.",
|
||||
"restart_note": "Sunshine sta riavviando per applicare le modifiche.",
|
||||
"stream_audio": "Audio Di Stream",
|
||||
"stream_audio": "Stream Audio",
|
||||
"stream_audio_desc": "Indica se trasmettere o meno audio. Disabilitarlo può essere utile per lo streaming di display senza intestazione come secondo monitor.",
|
||||
"sunshine_name": "Nome Sunshine",
|
||||
"sunshine_name_desc": "Il nome visualizzato da Moonlight. Se non specificato, viene utilizzato il nome host del PC",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"cancel": "Скасувати",
|
||||
"disabled": "Вимкнено",
|
||||
"disabled_def": "Вимкнено (за замовчуванням)",
|
||||
"disabled_def_cbox": "За замовчуванням: відмічено",
|
||||
"disabled_def_cbox": "За замовчуванням: вимкнено",
|
||||
"dismiss": "Відхилити",
|
||||
"do_cmd": "Виконати команду",
|
||||
"elevated": "Потребуються",
|
||||
|
||||
@@ -27,7 +27,8 @@ for dir in ${DIRECTORIES}; do
|
||||
|
||||
# remove the directory if it is empty
|
||||
if [[ $empty_dir != "" ]]; then # prevent the loop from running and failing if no directories found
|
||||
for i in "${empty_dir}"; do # don't split words as we already know this will be a single directory
|
||||
# shellcheck disable=SC2066 # don't split words as we already know this will be a single directory
|
||||
for i in "${empty_dir}"; do
|
||||
echo "Removing empty directory: ${i}"
|
||||
rmdir "${i}"
|
||||
done
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
rem Check if a compatible version of ViGEmBus is already installed (1.17 or later)
|
||||
rem
|
||||
rem Note: We use exit code 2 to indicate success because either 0 or 1 may be returned
|
||||
rem based on the PowerShell version if an exception occurs.
|
||||
powershell -c Exit $(if ((Get-Item "$env:SystemRoot\System32\drivers\ViGEmBus.sys").VersionInfo.FileVersion -ge [System.Version]"1.17") { 2 } Else { 1 })
|
||||
if %ERRORLEVEL% EQU 2 (
|
||||
goto skip
|
||||
)
|
||||
goto continue
|
||||
|
||||
:skip
|
||||
echo "The installed version is 1.17 or later, no update needed. Exiting."
|
||||
exit /b 0
|
||||
|
||||
:continue
|
||||
rem Get temp directory
|
||||
set temp_dir=%temp%/Sunshine
|
||||
|
||||
rem Create temp directory if it doesn't exist
|
||||
if not exist "%temp_dir%" mkdir "%temp_dir%"
|
||||
|
||||
rem Get system proxy setting
|
||||
set proxy=
|
||||
for /f "tokens=3" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ^| find /i "ProxyEnable"') do (
|
||||
set ProxyEnable=%%a
|
||||
|
||||
if !ProxyEnable! equ 0x1 (
|
||||
for /f "tokens=3" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ^| find /i "ProxyServer"') do (
|
||||
set proxy=%%a
|
||||
echo Using system proxy !proxy! to download Virtual Gamepad
|
||||
set proxy=-x !proxy!
|
||||
)
|
||||
) else (
|
||||
rem Proxy is not enabled.
|
||||
)
|
||||
)
|
||||
|
||||
rem get browser_download_url from asset 0 of https://api.github.com/repos/nefarius/vigembus/releases/latest
|
||||
set latest_release_url=https://api.github.com/repos/nefarius/vigembus/releases/latest
|
||||
|
||||
rem Use curl to get the api response, and find the browser_download_url
|
||||
for /F "tokens=* USEBACKQ" %%F in (`curl -s !proxy! -L %latest_release_url% ^| findstr browser_download_url`) do (
|
||||
set browser_download_url=%%F
|
||||
)
|
||||
|
||||
rem Strip quotes
|
||||
set browser_download_url=%browser_download_url:"=%
|
||||
|
||||
rem Remove the browser_download_url key
|
||||
set browser_download_url=%browser_download_url:browser_download_url: =%
|
||||
|
||||
echo %browser_download_url%
|
||||
|
||||
rem Download the exe
|
||||
curl -s -L !proxy! -o "%temp_dir%\virtual_gamepad.exe" %browser_download_url%
|
||||
|
||||
rem Install Virtual Gamepad
|
||||
%temp_dir%\virtual_gamepad.exe /passive /promptrestart
|
||||
|
||||
rem Delete temp directory
|
||||
rmdir /S /Q "%temp_dir%"
|
||||
20
src_assets/windows/misc/gamepad/install-gamepad.ps1
Normal file
20
src_assets/windows/misc/gamepad/install-gamepad.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
# Check if a compatible version of ViGEmBus is already installed (1.17 or later)
|
||||
try {
|
||||
$vigemBusPath = "$env:SystemRoot\System32\drivers\ViGEmBus.sys"
|
||||
$fileVersion = (Get-Item $vigemBusPath).VersionInfo.FileVersion
|
||||
|
||||
if ($fileVersion -ge [System.Version]"1.17") {
|
||||
Write-Information "The installed version is 1.17 or later, no update needed. Exiting."
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Information "ViGEmBus driver not found or inaccessible, proceeding with installation."
|
||||
}
|
||||
|
||||
# Install Virtual Gamepad
|
||||
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$installerPath = Join-Path $scriptPath "vigembus_installer.exe"
|
||||
Start-Process `
|
||||
-FilePath $installerPath `
|
||||
-ArgumentList "/passive", "/promptrestart"
|
||||
@@ -1,4 +0,0 @@
|
||||
@echo off
|
||||
|
||||
rem Use wmic to get the uninstall Virtual Gamepad
|
||||
wmic product where name="ViGEm Bus Driver" call uninstall
|
||||
8
src_assets/windows/misc/gamepad/uninstall-gamepad.ps1
Normal file
8
src_assets/windows/misc/gamepad/uninstall-gamepad.ps1
Normal file
@@ -0,0 +1,8 @@
|
||||
# Use Get-CimInstance to find and uninstall Virtual Gamepad
|
||||
$product = Get-CimInstance -ClassName Win32_Product -Filter "Name='ViGEm Bus Driver'"
|
||||
if ($product) {
|
||||
Invoke-CimMethod -InputObject $product -MethodName Uninstall
|
||||
Write-Information "ViGEm Bus Driver uninstalled successfully"
|
||||
} else {
|
||||
Write-Warning "ViGEm Bus Driver not found"
|
||||
}
|
||||
@@ -56,7 +56,7 @@ foreach(dep ${SUNSHINE_TARGET_DEPENDENCIES})
|
||||
add_dependencies(${PROJECT_NAME} ${dep}) # compile these before sunshine
|
||||
endforeach()
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 20)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 23)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
${SUNSHINE_EXTERNAL_LIBRARIES}
|
||||
gtest
|
||||
|
||||
2
third-party/build-deps
vendored
2
third-party/build-deps
vendored
Submodule third-party/build-deps updated: cf5dffaf4c...94369e6377
2
third-party/inputtino
vendored
2
third-party/inputtino
vendored
Submodule third-party/inputtino updated: 3a7a658782...83cf70ef33
2
third-party/moonlight-common-c
vendored
2
third-party/moonlight-common-c
vendored
Submodule third-party/moonlight-common-c updated: 58902e342f...5f2280183c
2
third-party/tray
vendored
2
third-party/tray
vendored
Submodule third-party/tray updated: f6d0684c2b...db96aeab04
2
third-party/wlr-protocols
vendored
2
third-party/wlr-protocols
vendored
Submodule third-party/wlr-protocols updated: 2ec67ebd26...a5028afbe4
@@ -5,7 +5,7 @@ project(sunshine_tools)
|
||||
include_directories("${CMAKE_SOURCE_DIR}")
|
||||
|
||||
add_executable(dxgi-info dxgi.cpp)
|
||||
set_target_properties(dxgi-info PROPERTIES CXX_STANDARD 20)
|
||||
set_target_properties(dxgi-info PROPERTIES CXX_STANDARD 23)
|
||||
target_link_libraries(dxgi-info
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
dxgi
|
||||
@@ -13,7 +13,7 @@ target_link_libraries(dxgi-info
|
||||
target_compile_options(dxgi-info PRIVATE ${SUNSHINE_COMPILE_OPTIONS})
|
||||
|
||||
add_executable(audio-info audio.cpp)
|
||||
set_target_properties(audio-info PROPERTIES CXX_STANDARD 20)
|
||||
set_target_properties(audio-info PROPERTIES CXX_STANDARD 23)
|
||||
target_link_libraries(audio-info
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
@@ -22,7 +22,7 @@ target_link_libraries(audio-info
|
||||
target_compile_options(audio-info PRIVATE ${SUNSHINE_COMPILE_OPTIONS})
|
||||
|
||||
add_executable(sunshinesvc sunshinesvc.cpp)
|
||||
set_target_properties(sunshinesvc PROPERTIES CXX_STANDARD 20)
|
||||
set_target_properties(sunshinesvc PROPERTIES CXX_STANDARD 23)
|
||||
target_link_libraries(sunshinesvc
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
wtsapi32
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define INITGUID
|
||||
|
||||
// platform includes
|
||||
#include <audioclient.h>
|
||||
#include <Audioclient.h>
|
||||
#include <codecvt>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
#include <wtsapi32.h>
|
||||
#include <WtsApi32.h>
|
||||
|
||||
// PROC_THREAD_ATTRIBUTE_JOB_LIST is currently missing from MinGW headers
|
||||
#ifndef PROC_THREAD_ATTRIBUTE_JOB_LIST
|
||||
|
||||
Reference in New Issue
Block a user