Compare commits

..

30 Commits

Author SHA1 Message Date
LizardByte-bot
1ffb4893ca New translations sunshine.json (Vietnamese) 2025-08-01 10:31:29 -04:00
LizardByte-bot
de86b6059b New translations sunshine.json (Vietnamese) 2025-08-01 09:00:00 -04:00
LizardByte-bot
a0704c4b17 New translations sunshine.json (Bulgarian) 2025-07-30 02:56:20 -04:00
LizardByte-bot
3b5809273b New translations sunshine.json (Hungarian) 2025-07-30 00:12:55 -04:00
LizardByte-bot
5ad37cb77a New translations sunshine.json (English, United Kingdom) 2025-07-30 00:12:54 -04:00
LizardByte-bot
7ba6f18b44 New translations sunshine.json (English, United States) 2025-07-30 00:12:52 -04:00
LizardByte-bot
05b35dac55 New translations sunshine.json (Portuguese, Brazilian) 2025-07-30 00:12:51 -04:00
LizardByte-bot
41013eac45 New translations sunshine.json (Vietnamese) 2025-07-30 00:12:50 -04:00
LizardByte-bot
be52b5c65a New translations sunshine.json (Chinese Traditional) 2025-07-30 00:12:49 -04:00
LizardByte-bot
7d89e227de New translations sunshine.json (Chinese Simplified) 2025-07-30 00:12:48 -04:00
LizardByte-bot
acf2219997 New translations sunshine.json (Ukrainian) 2025-07-30 00:12:47 -04:00
LizardByte-bot
c2cfc13dfd New translations sunshine.json (Turkish) 2025-07-30 00:12:46 -04:00
LizardByte-bot
e3b5ea24ab New translations sunshine.json (Swedish) 2025-07-30 00:12:45 -04:00
LizardByte-bot
532446b0e8 New translations sunshine.json (Russian) 2025-07-30 00:12:44 -04:00
LizardByte-bot
5b18aa7e11 New translations sunshine.json (Portuguese) 2025-07-30 00:12:43 -04:00
LizardByte-bot
e8acea05de New translations sunshine.json (Polish) 2025-07-30 00:12:42 -04:00
LizardByte-bot
6d8c49c3f2 New translations sunshine.json (Korean) 2025-07-30 00:12:41 -04:00
LizardByte-bot
118efdae64 New translations sunshine.json (Japanese) 2025-07-30 00:12:39 -04:00
LizardByte-bot
c4c1aeb479 New translations sunshine.json (Italian) 2025-07-30 00:12:38 -04:00
LizardByte-bot
5988b70b9f New translations sunshine.json (German) 2025-07-30 00:12:37 -04:00
LizardByte-bot
af404a6757 New translations sunshine.json (Bulgarian) 2025-07-30 00:12:36 -04:00
LizardByte-bot
50cd2545b3 New translations sunshine.json (Spanish) 2025-07-30 00:12:35 -04:00
LizardByte-bot
65ded6376c New translations sunshine.json (French) 2025-07-30 00:12:34 -04:00
LizardByte-bot
c4bc4a03cb New translations sunshine.json (Czech) 2025-07-30 00:12:33 -04:00
LizardByte-bot
418bf8de98 New translations sunshine.json (Vietnamese) 2025-07-29 02:29:13 -04:00
LizardByte-bot
614ef5932a New translations sunshine.json (Vietnamese) 2025-07-29 01:02:34 -04:00
LizardByte-bot
f486076b55 New translations sunshine.json (Hungarian) 2025-07-28 01:54:07 -04:00
LizardByte-bot
a9a40fdbaf New translations sunshine.json (Hungarian) 2025-07-27 22:02:20 -04:00
LizardByte-bot
d8c248408d New translations sunshine.json (Vietnamese) 2025-07-27 12:36:49 -04:00
LizardByte-bot
4e784a11d6 New translations sunshine.json (Vietnamese) 2025-07-27 10:25:17 -04:00
99 changed files with 1357 additions and 643 deletions

5
.gitattributes vendored
View File

@@ -1,5 +1,6 @@
# ensure Linux specific files are checked out with LF line endings
# ensure dockerfiles 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

View File

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

View File

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

View File

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

View File

@@ -1,29 +0,0 @@
{
"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
}
]
}
]
}

View File

@@ -20,6 +20,4 @@ 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 }}

View File

@@ -26,6 +26,4 @@ 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 }}

View File

@@ -26,6 +26,4 @@ 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 }}

View File

@@ -16,10 +16,6 @@ on:
required: false
COPR_CLI_CONFIG:
required: false
GH_BOT_TOKEN:
required: false
VIRUSTOTAL_API_KEY:
required: false
concurrency:
group: "_${{ github.workflow }}-${{ github.ref }}"
@@ -49,7 +45,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: build-*

View File

@@ -73,16 +73,15 @@ jobs:
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 remote-add --if-not-exists flathub \
https://flathub.org/repo/flathub.flatpakrepo"
sudo su "$(whoami)" -c "flatpak --user install -y flathub \
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
@@ -102,11 +101,9 @@ jobs:
flatpak-${{ matrix.arch }}-
- name: Configure Flatpak Manifest
env:
BRANCH: ${{ github.head_ref }}
run: |
# variables for manifest
branch="${{ env.BRANCH }}"
branch="${{ github.head_ref }}"
build_version=${{ inputs.release_version }}
commit=${{ inputs.release_commit }}
@@ -140,20 +137,19 @@ jobs:
- name: Debug Manifest
working-directory: build
run: cat "${APP_ID}.yml"
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 \
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 \
sudo su $(whoami) -c "flatpak run org.flatpak.Builder \
--arch=${{ matrix.arch }} \
--force-clean \
--repo=repo \
@@ -161,16 +157,15 @@ jobs:
build-sunshine ${APP_ID}.yml"
rm -rf .flatpak-builder
mv copy-of-flatpak-builder .flatpak-builder
sudo su "$(whoami)" -c "flatpak build-bundle \
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 \
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
@@ -182,7 +177,7 @@ jobs:
--exceptions \
--user-exceptions "${exceptions_file}" \
manifest \
"${APP_ID}.yml"
${APP_ID}.yml
echo "Linting flatpak repo"
# TODO: add arg
@@ -198,13 +193,13 @@ jobs:
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/"
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

View File

@@ -36,6 +36,8 @@ jobs:
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"
@@ -71,13 +73,9 @@ jobs:
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 }}"
branch="${{ github.head_ref }}"
build_version=${{ inputs.release_version }}
commit=${{ inputs.release_commit }}
@@ -98,9 +96,9 @@ jobs:
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 }}"
branch="${{ github.event.pull_request.head.ref }}"
default_branch="${{ github.event.pull_request.head.repo.default_branch }}"
tag="${{ github.event.pull_request.head.ref }}"
fi
echo "Branch: ${branch}"
echo "Clone URL: ${clone_url}"
@@ -145,9 +143,8 @@ jobs:
export DISPLAY=:1
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
echo "DISPLAY=${DISPLAY}" >> "${GITHUB_ENV}"
echo "DISPLAY=${DISPLAY}" >> $GITHUB_ENV
- run: echo "::add-matcher::.github/matchers/gcc-strip3.json"
- name: Validate Homebrew Formula
id: test
if: matrix.release != true
@@ -159,7 +156,6 @@ jobs:
publish: false
token: ${{ secrets.GH_TOKEN }}
validate: true
- run: echo "::remove-matcher owner=gcc-strip3::"
- name: Setup python
id: python

View File

@@ -79,8 +79,8 @@ jobs:
--enable-x11 \
--enable-glx \
--enable-wayland \
--without-legacy
make -j "$(nproc)"
--without-legacy # emgd, nvctrl, fglrx
make -j $(nproc)
sudo make install
cd .. && rm -rf libva-*
@@ -91,7 +91,6 @@ jobs:
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' \
@@ -99,13 +98,12 @@ jobs:
--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}"
echo "VERSION=${version}" >> $GITHUB_ENV
- name: Package Linux - AppImage
if: matrix.name == 'AppImage'

View File

@@ -199,12 +199,12 @@ jobs:
ignore_list=$(IFS=,; echo "${ignore_packages[*]}")
# install pinned dependencies
if [ -n "${tarballs}" ]; then
pacman -U --noconfirm "${tarballs}"
if [ -n "$tarballs" ]; then
pacman -U --noconfirm ${tarballs}
fi
# Only add --ignore if we have packages to ignore
if [ -n "${ignore_list}" ]; then
if [ -n "$ignore_list" ]; then
pacman -Syu --noconfirm --ignore="${ignore_list}" "${dependencies[@]}"
else
pacman -Syu --noconfirm "${dependencies[@]}"
@@ -251,7 +251,7 @@ jobs:
# step output
echo "python-path=${python_path}"
echo "python-path=${python_path}" >> "${GITHUB_OUTPUT}"
echo "python-path=${python_path}" >> $GITHUB_OUTPUT
- name: Build Windows
shell: msys2 {0}
@@ -272,9 +272,7 @@ jobs:
-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}

View File

@@ -56,7 +56,6 @@ jobs:
uses: LizardByte/.github/.github/workflows/__call-docker.yml@master
with:
maximize_build_space: true
maximize_build_space_root_reserve_size: 32768
publish_release: ${{ needs.release-setup.outputs.publish_release }}
release_commit: ${{ needs.release-setup.outputs.release_commit }}
release_tag: ${{ needs.release-setup.outputs.release_tag }}
@@ -137,6 +136,8 @@ jobs:
include:
- name: Linux-AppImage
coverage: true
- name: Homebrew-macos-13
coverage: false
- name: Homebrew-macos-14
coverage: false
- name: Homebrew-macos-15
@@ -150,7 +151,7 @@ jobs:
uses: actions/checkout@v4
- name: Download coverage artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: coverage-${{ matrix.name }}
path: _coverage
@@ -191,7 +192,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: build-*
@@ -224,7 +225,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download homebrew artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: beta-Homebrew
path: homebrew

View File

@@ -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

View File

@@ -72,13 +72,13 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
<td>Windows: 10+ (Windows Server does not support virtual gamepads)</td>
</tr>
<tr>
<td>macOS: 14+</td>
<td>macOS: 13+</td>
</tr>
<tr>
<td>Linux/Debian: 13+ (trixie)</td>
<td>Linux/Debian: 12+ (bookworm)</td>
</tr>
<tr>
<td>Linux/Fedora: 41+</td>
<td>Linux/Fedora: 40+</td>
</tr>
<tr>
<td>Linux/Ubuntu: 22.04+ (jammy)</td>

View File

@@ -45,7 +45,6 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
libcap2, \
libcurl4, \
libdrm2, \
libgbm1, \
libevdev2, \
libnuma1, \
libopus0, \
@@ -66,7 +65,6 @@ 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, \

View File

@@ -1,18 +1,18 @@
# Set build variables if env variables are defined
# These are used in configured files such as manifests for different packages
if(DEFINED ENV{BRANCH})
if(DEFINED ENV{BRANCH}) # cmake-lint: disable=W0106
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})
if(DEFINED ENV{CLONE_URL}) # cmake-lint: disable=W0106
set(GITHUB_CLONE_URL $ENV{CLONE_URL})
endif()
if(DEFINED ENV{COMMIT})
if(DEFINED ENV{COMMIT}) # cmake-lint: disable=W0106
set(GITHUB_COMMIT $ENV{COMMIT})
endif()
if(DEFINED ENV{TAG})
if(DEFINED ENV{TAG}) # cmake-lint: disable=W0106
set(GITHUB_TAG $ENV{TAG})
endif()

View File

@@ -32,6 +32,7 @@ ENV CLONE_URL=${CLONE_URL}
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=SC2016
RUN <<_SETUP
#!/bin/bash
set -e
@@ -41,7 +42,6 @@ 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

View File

@@ -3,8 +3,8 @@
# platforms: linux/amd64
# platforms_pr: linux/amd64
# no-cache-filters: toolchain-base,toolchain
ARG BASE=debian
ARG TAG=trixie-slim
ARG BASE=ubuntu
ARG TAG=22.04
FROM ${BASE}:${TAG} AS toolchain-base
ENV DEBIAN_FRONTEND=noninteractive
@@ -19,17 +19,18 @@ ENV DISPLAY=:0
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# install dependencies
# hadolint ignore=SC1091
RUN <<_DEPS
#!/bin/bash
set -e
apt-get update -y
apt-get install -y --no-install-recommends \
build-essential \
cmake=3.31.* \
cmake=3.22.* \
ca-certificates \
doxygen \
gcc=4:14.2.* \
g++=4:14.2.* \
gcc=4:11.2.* \
g++=4:11.2.* \
gdb \
git \
graphviz \
@@ -59,13 +60,21 @@ apt-get install -y --no-install-recommends \
xvfb
apt-get clean
rm -rf /var/lib/apt/lists/*
# Install Node
wget --max-redirect=0 -qO- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source "$HOME/.nvm/nvm.sh"
nvm install node
nvm use node
nvm alias default node
_DEPS
# install cuda
WORKDIR /build/cuda
# versions: https://developer.nvidia.com/cuda-toolkit-archive
ENV CUDA_VERSION="12.9.1"
ENV CUDA_BUILD="575.57.08"
ENV CUDA_VERSION="11.8.0"
ENV CUDA_BUILD="520.61.05"
# hadolint ignore=SC3010
RUN <<_INSTALL_CUDA
#!/bin/bash
set -e
@@ -76,31 +85,18 @@ if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
fi
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
echo "cuda url: ${url}"
tmpfile="/tmp/cuda.run"
wget "$url" --progress=bar:force:noscroll --show-progress -O "$tmpfile"
chmod a+x "${tmpfile}"
"${tmpfile}" --silent --toolkit --toolkitpath=/usr/local --no-opengl-libs --no-man-page --no-drm
rm -f "${tmpfile}"
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
chmod a+x ./cuda.run
./cuda.run --silent --toolkit --toolkitpath=/usr/local --no-opengl-libs --no-man-page --no-drm
rm ./cuda.run
_INSTALL_CUDA
WORKDIR /
# install node
RUN <<_INSTALL_NODE
#!/bin/bash
set -e
wget --max-redirect=0 -qO- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source "$HOME/.nvm/nvm.sh"
nvm install node
nvm use node
nvm alias default node
_INSTALL_NODE
WORKDIR /toolchain
# Create a shell script that starts Xvfb and then runs a shell
# Write a shell script that starts Xvfb and then runs a shell
RUN <<_ENTRYPOINT
#!/bin/bash
set -e
cat <<EOF > entrypoint.sh
cat <<EOF > /entrypoint.sh
#!/bin/bash
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
if [ "\$#" -eq 0 ]; then
@@ -111,11 +107,11 @@ fi
EOF
# Make the script executable
chmod +x entrypoint.sh
chmod +x /entrypoint.sh
# Note about CLion
echo "ATTENTION: CLion will override the entrypoint, you can disable this in the toolchain settings"
_ENTRYPOINT
# Use the shell script as the entrypoint
ENTRYPOINT ["/toolchain/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -4,7 +4,7 @@
# platforms_pr: linux/amd64
# no-cache-filters: sunshine-base,artifacts,sunshine
ARG BASE=debian
ARG TAG=trixie
ARG TAG=bookworm
FROM ${BASE}:${TAG} AS sunshine-base
ENV DEBIAN_FRONTEND=noninteractive
@@ -32,7 +32,6 @@ RUN <<_BUILD
set -e
chmod +x ./scripts/linux_build.sh
./scripts/linux_build.sh \
--cuda-patches \
--publisher-name='LizardByte' \
--publisher-website='https://app.lizardbyte.dev' \
--publisher-issue-url='https://app.lizardbyte.dev/support' \
@@ -43,6 +42,7 @@ _BUILD
# run tests
WORKDIR /build/sunshine/build/tests
# hadolint ignore=SC1091
RUN <<_TEST
#!/bin/bash
set -e

View File

@@ -35,14 +35,14 @@ chmod +x ./scripts/linux_build.sh
--publisher-name='LizardByte' \
--publisher-website='https://app.lizardbyte.dev' \
--publisher-issue-url='https://app.lizardbyte.dev/support' \
--sudo-off \
--ubuntu-test-repo
--sudo-off
apt-get clean
rm -rf /var/lib/apt/lists/*
_BUILD
# run tests
WORKDIR /build/sunshine/build/tests
# hadolint ignore=SC1091
RUN <<_TEST
#!/bin/bash
set -e

View File

@@ -42,6 +42,7 @@ _BUILD
# run tests
WORKDIR /build/sunshine/build/tests
# hadolint ignore=SC1091
RUN <<_TEST
#!/bin/bash
set -e

View File

@@ -3,15 +3,6 @@ Sunshine binaries are built using [CMake](https://cmake.org) and requires `cmake
## Building Locally
### Compiler
It is recommended to use one of the following compilers:
| Compiler | Version |
|:------------|:--------|
| GCC | 13+ |
| Clang | 17+ |
| Apple Clang | 15+ |
### Dependencies
#### Linux
@@ -25,7 +16,7 @@ Sunshine requires CUDA Toolkit for NVFBC capture. There are two caveats to CUDA:
1. The version installed depends on the version of GCC.
2. The version of CUDA you use will determine compatibility with various GPU generations.
At the time of writing, the recommended version to use is CUDA ~12.9.
At the time of writing, the recommended version to use is CUDA ~11.8.
See [CUDA compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/index.html) for more info.
@tip{To install older versions, select the appropriate run file based on your desired CUDA version and architecture

View File

@@ -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,32 +1371,6 @@ 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

View File

@@ -31,7 +31,7 @@ See [Docker](../DOCKER_README.md) for more information.
CUDA is used for NVFBC capture.
@tip{See [CUDA GPUS](https://developer.nvidia.com/cuda-gpus) to cross-reference Compute Capability to your GPU.
The table below applies to packages provided by LizardByte. If you use an official LizardByte package, then you do not
The table below applies to packages provided by LizardByte. If you use an official LizardByte package then you do not
need to install CUDA.}
<table>
@@ -43,9 +43,9 @@ need to install CUDA.}
<th>Package</th>
</tr>
<tr>
<td rowspan="8">12.9.1</td>
<td rowspan="8">575.57.08</td>
<td rowspan="8">50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td rowspan="3">11.8.0</td>
<td rowspan="3">450.80.02</td>
<td rowspan="3">35;50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td>sunshine.AppImage</td>
</tr>
<tr>
@@ -55,18 +55,27 @@ need to install CUDA.}
<td>sunshine-ubuntu-24.04-{arch}.deb</td>
</tr>
<tr>
<td>sunshine-debian-trixie-{arch}.deb</td>
<td rowspan="1">12.0.0</td>
<td rowspan="1">525.60.13</td>
<td rowspan="5">50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td>sunshine-debian-bookworm-{arch}.deb</td>
</tr>
<tr>
<td rowspan="2">12.6.2</td>
<td rowspan="2">560.35.03</td>
<td>sunshine_{arch}.flatpak</td>
</tr>
<tr>
<td>Sunshine (copr - Fedora 41)</td>
</tr>
<tr>
<td rowspan="1">12.8.1</td>
<td rowspan="1">570.124.06</td>
<td>Sunshine (copr - Fedora 42)</td>
</tr>
<tr>
<td rowspan="1">12.9.1</td>
<td rowspan="1">575.57.08</td>
<td>sunshine.pkg.tar.zst</td>
</tr>
</table>
@@ -80,15 +89,13 @@ According to AppImageLint the supported distro matrix of the AppImage is below.
- ✔ Debian bookworm
- ✔ Debian trixie
- ✔ Debian sid
- ✔ Ubuntu plucky
- ✔ Ubuntu noble
- ✔ Ubuntu jammy
- ✖ Ubuntu focal
- ✖ Ubuntu bionic
- ✖ Ubuntu xenial
- ✖ Ubuntu trusty
-Rocky Linux 8
- ✖ Rocky Linux 9
-CentOS 7
##### Install
1. Download [sunshine.AppImage](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine.AppImage)

View File

@@ -84,35 +84,9 @@ 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.
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.
only Sunshine's traffic is slowed down.)
Sunshine versions > 0.23.1 include improved networking code that should
alleviate or even solve this issue (without reducing the NIC speed).

View File

@@ -56,18 +56,18 @@ BuildRequires: which
BuildRequires: xorg-x11-server-Xvfb
# Conditional BuildRequires for cuda-gcc based on Fedora version
%if 0%{?fedora} <= 41
%if 0%{?fedora} >= 40 && 0%{?fedora} <= 41
BuildRequires: gcc13
BuildRequires: gcc13-c++
%global gcc_version 13
%global cuda_version 12.9.1
%global cuda_build 575.57.08
%global cuda_version 12.6.3
%global cuda_build 560.35.05
%elif %{?fedora} >= 42
BuildRequires: gcc14
BuildRequires: gcc14-c++
%global gcc_version 14
%global cuda_version 12.9.1
%global cuda_build 575.57.08
%global cuda_version 12.8.1
%global cuda_build 570.124.06
%endif
%global cuda_dir %{_builddir}/cuda
@@ -97,6 +97,9 @@ tar -xzf %{SOURCE0} -C %{_builddir}/Sunshine
# list directory
ls -a %{_builddir}/Sunshine
# patches
%autopatch -p1
%build
# exit on error
set -e
@@ -171,7 +174,7 @@ function install_cuda() {
--backup \
--directory="%{cuda_dir}" \
--verbose \
< "%{_builddir}/Sunshine/packaging/linux/patches/${architecture}/01-math_functions.patch"
< "%{_builddir}/Sunshine/packaging/linux/fedora/patches/f42/${architecture}/01-math_functions.patch"
fi
}

View File

@@ -19,8 +19,8 @@
"only-arches": [
"x86_64"
],
"url": "https://developer.download.nvidia.com/compute/cuda/12.9.1/local_installers/cuda_12.9.1_575.57.08_linux.run",
"sha256": "0f6d806ddd87230d2adbe8a6006a9d20144fdbda9de2d6acc677daa5d036417a",
"url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux.run",
"sha256": "3729a89cb58f7ca6a46719cff110d6292aec7577585a8d71340f0dbac54fb237",
"dest-filename": "cuda.run"
},
{
@@ -28,8 +28,8 @@
"only-arches": [
"aarch64"
],
"url": "https://developer.download.nvidia.com/compute/cuda/12.9.1/local_installers/cuda_12.9.1_575.57.08_linux_sbsa.run",
"sha256": "64f47ab791a76b6889702425e0755385f5fa216c5a9f061875c7deed5f08cdb6",
"url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux_sbsa.run",
"sha256": "2249408848b705c18b9eadfb5161b52e4e36fcc5753647329cce93db141e5466",
"dest-filename": "cuda.run"
}
]

View File

@@ -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.

View File

@@ -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.

View File

@@ -37,10 +37,6 @@ class @PROJECT_NAME@ < Formula
depends_on "opus"
depends_on "icu4c" => :recommended
on_macos do
depends_on xcode: ["15.3", :build]
end
on_linux do
depends_on "avahi"
depends_on "libayatana-appindicator"
@@ -63,16 +59,6 @@ class @PROJECT_NAME@ < Formula
depends_on "wayland"
end
fails_with :clang do
build 1400
cause "Requires C++23 support"
end
fails_with :gcc do
version "12" # fails with GCC 12.x and earlier
cause "Requires C++23 support"
end
def install
ENV["BRANCH"] = "@GITHUB_BRANCH@"
ENV["BUILD_VERSION"] = "@BUILD_VERSION@"

View File

@@ -1,63 +1,61 @@
#!/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
#!/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

View File

@@ -3,7 +3,6 @@ set -e
# Default value for arguments
appimage_build=0
cuda_patches=0
num_processors=$(nproc)
publisher_name="Third Party Publisher"
publisher_website=""
@@ -29,7 +28,6 @@ Options:
-h, --help Display this help message.
-s, --sudo-off Disable sudo command.
--appimage-build Compile for AppImage, this will not create the AppImage, just the executable.
--cuda-patches Apply cuda patches.
--num-processors The number of processors to use for compilation. Default is the value of 'nproc'.
--publisher-name The name of the publisher (not developer) of the application.
--publisher-website The URL of the publisher's website.
@@ -57,9 +55,6 @@ while getopts ":hs-:" opt; do
appimage_build=1
skip_libva=1
;;
cuda-patches)
cuda_patches=1
;;
num-processors=*)
num_processors="${OPTARG#*=}"
;;
@@ -190,15 +185,7 @@ function add_debian_based_deps() {
fi
}
function add_test_ppa() {
if [ "$ubuntu_test_repo" == 1 ]; then
$package_install_command "software-properties-common"
${sudo_cmd} add-apt-repository ppa:ubuntu-toolchain-r/test -y
fi
}
function add_debian_deps() {
add_test_ppa
add_debian_based_deps
dependencies+=(
"libayatana-appindicator3-dev"
@@ -206,7 +193,11 @@ function add_debian_deps() {
}
function add_ubuntu_deps() {
add_test_ppa
if [ "$ubuntu_test_repo" == 1 ]; then
# allow newer gcc
${sudo_cmd} add-apt-repository ppa:ubuntu-toolchain-r/test -y
fi
add_debian_based_deps
dependencies+=(
"libappindicator3-dev"
@@ -307,24 +298,6 @@ function install_cuda() {
"${build_dir}/cuda.run" --silent --toolkit --toolkitpath="${build_dir}/cuda" --no-opengl-libs --no-man-page --no-drm
rm "${build_dir}/cuda.run"
nvcc_path="${build_dir}/cuda/bin/nvcc"
# run cuda patches
if [ "$cuda_patches" == 1 ]; then
echo "Applying CUDA patches"
local patch_dir="${script_dir}/../packaging/linux/patches/${architecture}"
if [ -d "$patch_dir" ]; then
for patch in "$patch_dir"/*.patch; do
echo "Applying patch: $patch"
patch -p2 \
--backup \
--directory="${build_dir}/cuda" \
--verbose \
< "$patch"
done
else
echo "No patches found for architecture: $architecture"
fi
fi
}
function check_version() {
@@ -487,8 +460,6 @@ 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
@@ -563,26 +534,27 @@ elif grep -q "Debian GNU/Linux 12 (bookworm)" /etc/os-release; then
version="12"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version="12.0.0"
cuda_build="525.60.13"
gcc_version="12"
nvm_node=0
elif grep -q "PLATFORM_ID=\"platform:f40\"" /etc/os-release; then
distro="fedora"
version="40"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version=12.6.3
cuda_build=560.35.05
gcc_version="13"
nvm_node=0
elif grep -q "Debian GNU/Linux 13 (trixie)" /etc/os-release; then
distro="debian"
version="13"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
nvm_node=0
dev_tools_group="Development Tools"
elif grep -q "PLATFORM_ID=\"platform:f41\"" /etc/os-release; then
distro="fedora"
version="41"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version=12.6.3
cuda_build=560.35.05
gcc_version="13"
nvm_node=0
dev_tools_group="development-tools"
@@ -591,8 +563,8 @@ elif grep -q "PLATFORM_ID=\"platform:f42\"" /etc/os-release; then
version="42"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version=12.8.1
cuda_build=570.124.06
gcc_version="14"
nvm_node=0
dev_tools_group="development-tools"
@@ -601,27 +573,27 @@ elif grep -q "Ubuntu 22.04" /etc/os-release; then
version="22.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="13"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=1
elif grep -q "Ubuntu 24.04" /etc/os-release; then
distro="ubuntu"
version="24.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=0
elif grep -q "Ubuntu 25.04" /etc/os-release; then
distro="ubuntu"
version="25.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=0
else
echo "Unsupported Distro or Version"

View File

@@ -504,8 +504,7 @@ namespace config {
{} // wa
}, // display_device
0, // max_bitrate
0 // minimum_fps_target (0 = framerate)
0 // max_bitrate
};
audio_t audio {
@@ -1147,7 +1146,6 @@ 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);
@@ -1421,7 +1419,7 @@ namespace config {
if (!service_ctrl::is_service_running()) {
// If the service isn't running, relaunch ourselves as admin to start it
WCHAR executable[MAX_PATH];
GetModuleFileNameW(nullptr, executable, ARRAYSIZE(executable));
GetModuleFileNameW(NULL, executable, ARRAYSIZE(executable));
SHELLEXECUTEINFOW shell_exec_info {};
shell_exec_info.cbSize = sizeof(shell_exec_info);

View File

@@ -141,7 +141,6 @@ 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 {

View File

@@ -8,7 +8,6 @@
// standard includes
#include <filesystem>
#include <format>
#include <fstream>
#include <set>
@@ -714,7 +713,7 @@ namespace confighttp {
if (const int max_index = static_cast<int>(apps_node.size()) - 1; max_index < 0) {
error = "No applications to delete";
} else {
error = std::format("'index' {} out of range, max index is {}", index, max_index);
error = "'index' out of range, max index is "s + std::to_string(max_index);
}
bad_request(response, request, error);
return;
@@ -731,7 +730,7 @@ namespace confighttp {
proc::refresh(config::stream.file_apps);
output_tree["status"] = true;
output_tree["result"] = std::format("application {} deleted", index);
output_tree["result"] = "application " + std::to_string(index) + " deleted";
send_response(response, output_tree);
} catch (std::exception &e) {
BOOST_LOG(warning) << "DeleteApp: "sv << e.what();

View File

@@ -4,7 +4,6 @@
*/
// standard includes
#include <csignal>
#include <format>
#include <iostream>
#include <thread>
@@ -26,11 +25,13 @@ extern "C" {
using namespace std::literals;
void launch_ui(const std::optional<std::string> &path) {
std::string url = std::format("https://localhost:{}", static_cast<int>(net::map_port(confighttp::PORT_HTTPS)));
if (path) {
url += *path;
}
void launch_ui() {
std::string url = "https://localhost:" + std::to_string(net::map_port(confighttp::PORT_HTTPS));
platf::open_url(url);
}
void launch_ui_with_path(std::string path) {
std::string url = "https://localhost:" + std::to_string(net::map_port(confighttp::PORT_HTTPS)) + path;
platf::open_url(url);
}
@@ -191,8 +192,8 @@ namespace service_ctrl {
}
private:
SC_HANDLE scm_handle = nullptr;
SC_HANDLE service_handle = nullptr;
SC_HANDLE scm_handle = NULL;
SC_HANDLE service_handle = NULL;
};
bool is_service_running() {

View File

@@ -14,13 +14,19 @@
/**
* @brief Launch the Web UI.
* @param path Optional path to append to the base URL.
* @examples
* launch_ui();
* launch_ui("/pin");
* @examples_end
*/
void launch_ui(const std::optional<std::string> &path = std::nullopt);
void launch_ui();
/**
* @brief Launch the Web UI at a specific endpoint.
* @examples
* launch_ui_with_path("/pin");
* @examples_end
*/
void launch_ui_with_path(std::string path);
/**
* @brief Functions for handling command line arguments.

View File

@@ -186,7 +186,7 @@ int main(int argc, char *argv[]) {
wnd_class.lpszClassName = "SunshineSessionMonitorClass";
wnd_class.lpfnWndProc = SessionMonitorWindowProc;
if (!RegisterClassA(&wnd_class)) {
session_monitor_hwnd_promise.set_value(nullptr);
session_monitor_hwnd_promise.set_value(NULL);
BOOST_LOG(error) << "Failed to register session monitor window class"sv << std::endl;
return;
}

View File

@@ -5,9 +5,6 @@
// this include
#include "nvenc_base.h"
// standard includes
#include <format>
// local includes
#include "src/config.h"
#include "src/logging.h"
@@ -430,7 +427,7 @@ namespace nvenc {
extra += " two-pass";
}
if (config.vbv_percentage_increase > 0 && get_encoder_cap(NV_ENC_CAPS_SUPPORT_CUSTOM_VBV_BUF_SIZE)) {
extra += std::format(" vbv+{}", config.vbv_percentage_increase);
extra += " vbv+" + std::to_string(config.vbv_percentage_increase);
}
if (encoder_params.rfi) {
extra += " rfi";
@@ -442,7 +439,7 @@ namespace nvenc {
extra += " spatial-aq";
}
if (enc_config.rcParams.enableMinQP) {
extra += std::format(" qpmin={}", enc_config.rcParams.minQP.qpInterP);
extra += " qpmin=" + std::to_string(enc_config.rcParams.minQP.qpInterP);
}
if (config.insert_filler_data) {
extra += " filler-data";

View File

@@ -12,13 +12,13 @@ namespace nvenc {
nvenc_d3d11::nvenc_d3d11(NV_ENC_DEVICE_TYPE device_type):
nvenc_base(device_type) {
async_event_handle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
async_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
}
nvenc_d3d11::~nvenc_d3d11() {
if (dll) {
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
if (async_event_handle) {
CloseHandle(async_event_handle);
@@ -36,7 +36,7 @@ namespace nvenc {
constexpr auto dll_name = "nvEncodeAPI.dll";
#endif
if ((dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if (auto create_instance = (decltype(NvEncodeAPICreateInstance) *) GetProcAddress(dll, "NvEncodeAPICreateInstance")) {
auto new_nvenc = std::make_unique<NV_ENCODE_API_FUNCTION_LIST>();
new_nvenc->version = min_struct_version(NV_ENCODE_API_FUNCTION_LIST_VER);
@@ -55,7 +55,7 @@ namespace nvenc {
if (dll) {
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
return false;

View File

@@ -39,7 +39,7 @@ namespace nvenc {
bool wait_for_async_event(uint32_t timeout_ms) override;
private:
HMODULE dll = nullptr;
HMODULE dll = NULL;
};
} // namespace nvenc

View File

@@ -63,7 +63,7 @@ namespace nvenc {
constexpr auto dll_name = "nvcuda.dll";
if ((cuda_functions.dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((cuda_functions.dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
auto load_function = [&]<typename T>(T &location, auto symbol) -> bool {
location = (T) GetProcAddress(cuda_functions.dll, symbol);
return location != nullptr;

View File

@@ -56,7 +56,7 @@ namespace nvenc {
autopop_context push_context();
HMODULE dll = nullptr;
HMODULE dll = NULL;
const ID3D11DevicePtr d3d_device;
ID3D11Texture2DPtr d3d_input_texture;

View File

@@ -7,7 +7,6 @@
// standard includes
#include <filesystem>
#include <format>
#include <string>
#include <utility>
@@ -155,7 +154,7 @@ namespace nvhttp {
std::string get_arg(const args_t &args, const char *name, const char *default_value = nullptr) {
auto it = args.find(name);
if (it == std::end(args)) {
if (default_value != nullptr) {
if (default_value != NULL) {
return std::string(default_value);
}
@@ -637,7 +636,7 @@ namespace nvhttp {
tree.put("root.<xmlattr>.status_code", 400);
tree.put(
"root.<xmlattr>.status_message",
std::format("Pin must be 4 digits, {} provided", pin.size())
"Pin must be 4 digits, " + std::to_string(pin.size()) + " provided"
);
return false;
}
@@ -897,15 +896,7 @@ namespace nvhttp {
}
tree.put("root.<xmlattr>.status_code", 200);
tree.put(
"root.sessionUrl0",
std::format(
"{}{}:{}",
launch_session->rtsp_url_scheme,
net::addr_to_url_escaped_string(request->local_endpoint().address()),
static_cast<int>(net::map_port(rtsp_stream::RTSP_SETUP_PORT))
)
);
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme + net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' + std::to_string(net::map_port(rtsp_stream::RTSP_SETUP_PORT)));
tree.put("root.gamesession", 1);
rtsp_stream::launch_session_raise(launch_session);
@@ -987,15 +978,7 @@ namespace nvhttp {
}
tree.put("root.<xmlattr>.status_code", 200);
tree.put(
"root.sessionUrl0",
std::format(
"{}{}:{}",
launch_session->rtsp_url_scheme,
net::addr_to_url_escaped_string(request->local_endpoint().address()),
static_cast<int>(net::map_port(rtsp_stream::RTSP_SETUP_PORT))
)
);
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme + net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' + std::to_string(net::map_port(rtsp_stream::RTSP_SETUP_PORT)));
tree.put("root.resume", 1);
rtsp_stream::launch_session_raise(launch_session);

View File

@@ -4,7 +4,6 @@
*/
// standard includes
#include <fcntl.h>
#include <format>
#include <sstream>
#include <string>
@@ -575,7 +574,7 @@ namespace va {
if (!display) {
char string[1024];
auto bytes = readlink(std::format("/proc/self/fd/{}", fd).c_str(), string, sizeof(string));
auto bytes = readlink(("/proc/self/fd/" + std::to_string(fd)).c_str(), string, sizeof(string));
std::string_view render_device {string, (std::size_t) bytes};

View File

@@ -4,11 +4,8 @@
*/
#define INITGUID
// standard includes
#include <format>
// platform includes
#include <Audioclient.h>
#include <audioclient.h>
#include <avrt.h>
#include <mmdeviceapi.h>
#include <newdev.h>
@@ -171,27 +168,28 @@ namespace {
waveformat.SubFormat == KSDATAFORMAT_SUBTYPE_PCM ? "S" :
"UNKNOWN";
result += std::format("{} {} ", static_cast<int>(waveformat.Samples.wValidBitsPerSample), static_cast<int>(waveformat.Format.nSamplesPerSec));
result += std::to_string(waveformat.Samples.wValidBitsPerSample) + " " +
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;
default:
result += std::format("{} channels (unrecognized)", static_cast<int>(waveformat.Format.nChannels));
result += std::to_string(waveformat.Format.nChannels) + " channels (unrecognized)";
break;
}
@@ -377,7 +375,7 @@ namespace platf::audio {
*ppvInterface = (IMMNotificationClient *) this;
return S_OK;
} else {
*ppvInterface = nullptr;
*ppvInterface = NULL;
return E_NOINTERFACE;
}
}
@@ -679,7 +677,7 @@ namespace platf::audio {
float *sample_buf_pos;
int channels;
HANDLE mmcss_task_handle = nullptr;
HANDLE mmcss_task_handle = NULL;
};
class audio_control_t: public ::platf::audio_control_t {

View File

@@ -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"

View File

@@ -601,12 +601,12 @@ namespace platf::dxgi {
LUID val;
if (OpenProcessToken(GetCurrentProcess(), flags, &token) &&
!!LookupPrivilegeValue(nullptr, SE_INC_BASE_PRIORITY_NAME, &val)) {
!!LookupPrivilegeValue(NULL, SE_INC_BASE_PRIORITY_NAME, &val)) {
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = val;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), nullptr, nullptr)) {
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL)) {
BOOST_LOG(warning) << "Could not set privilege to increase GPU priority";
}
}
@@ -918,20 +918,20 @@ namespace platf::dxgi {
"DXGI_FORMAT_A8P8",
"DXGI_FORMAT_B4G4R4A4_UNORM",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"DXGI_FORMAT_P208",
"DXGI_FORMAT_V208",

View File

@@ -7,7 +7,7 @@
// platform includes
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <directxmath.h>
extern "C" {
#include <libavcodec/avcodec.h>
@@ -1739,7 +1739,7 @@ namespace platf::dxgi {
img->data = nullptr;
if (img->encoder_texture_handle) {
CloseHandle(img->encoder_texture_handle);
img->encoder_texture_handle = nullptr;
img->encoder_texture_handle = NULL;
}
// Initialize format-dependent fields

View File

@@ -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>

View File

@@ -5,7 +5,7 @@
#define WINVER 0x0A00
// platform includes
#include <Windows.h>
#include <windows.h>
// standard includes
#include <cmath>
@@ -293,7 +293,7 @@ namespace platf {
if (gamepad.repeat_task) {
task_pool.cancel(gamepad.repeat_task);
gamepad.repeat_task = nullptr;
gamepad.repeat_task = 0;
}
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
@@ -1452,7 +1452,7 @@ namespace platf {
// Cancel any pending updates. We will requeue one here when we're finished.
if (gamepad.repeat_task) {
task_pool.cancel(gamepad.repeat_task);
gamepad.repeat_task = nullptr;
gamepad.repeat_task = 0;
}
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
@@ -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++;

View File

@@ -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
@@ -117,7 +117,7 @@ namespace platf {
std::filesystem::path appdata() {
WCHAR sunshine_path[MAX_PATH];
GetModuleFileNameW(nullptr, sunshine_path, _countof(sunshine_path));
GetModuleFileNameW(NULL, sunshine_path, _countof(sunshine_path));
return std::filesystem::path {sunshine_path}.remove_filename() / L"config"sv;
}
@@ -410,16 +410,16 @@ namespace platf {
LPPROC_THREAD_ATTRIBUTE_LIST allocate_proc_thread_attr_list(DWORD attribute_count) {
SIZE_T size;
InitializeProcThreadAttributeList(nullptr, attribute_count, 0, &size);
InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size);
auto list = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, size);
if (list == nullptr) {
return nullptr;
if (list == NULL) {
return NULL;
}
if (!InitializeProcThreadAttributeList(list, attribute_count, 0, &size)) {
HeapFree(GetProcessHeap(), 0, list);
return nullptr;
return NULL;
}
return list;
@@ -518,7 +518,7 @@ namespace platf {
// Allocate a process attribute list with space for 2 elements
startup_info.lpAttributeList = allocate_proc_thread_attr_list(2);
if (startup_info.lpAttributeList == nullptr) {
if (startup_info.lpAttributeList == NULL) {
// If the allocation failed, set ec to an appropriate error code and return the structure
ec = std::make_error_code(std::errc::not_enough_memory);
return startup_info;
@@ -530,7 +530,7 @@ namespace platf {
// Populate std handles if the caller gave us a log file to use
startup_info.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
startup_info.StartupInfo.hStdInput = nullptr;
startup_info.StartupInfo.hStdInput = NULL;
startup_info.StartupInfo.hStdOutput = log_file_handle;
startup_info.StartupInfo.hStdError = log_file_handle;
@@ -539,7 +539,7 @@ namespace platf {
//
// Note: The value we point to here must be valid for the lifetime of the attribute list,
// so we need to point into the STARTUPINFO instead of our log_file_variable on the stack.
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &startup_info.StartupInfo.hStdOutput, sizeof(startup_info.StartupInfo.hStdOutput), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &startup_info.StartupInfo.hStdOutput, sizeof(startup_info.StartupInfo.hStdOutput), NULL, NULL);
}
if (job) {
@@ -547,7 +547,7 @@ namespace platf {
//
// Note: The value we point to here must be valid for the lifetime of the attribute list,
// so we take a HANDLE* instead of just a HANDLE to use the caller's stack storage.
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, job, sizeof(*job), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, job, sizeof(*job), NULL, NULL);
}
return startup_info;
@@ -555,11 +555,11 @@ namespace platf {
/**
* @brief This function overrides HKEY_CURRENT_USER and HKEY_CLASSES_ROOT using the provided token.
* @param token The primary token identifying the user to use, or `nullptr` to restore original keys.
* @param token The primary token identifying the user to use, or `NULL` to restore original keys.
* @return `true` if the override or restore operation was successful.
*/
bool override_per_user_predefined_keys(HANDLE token) {
HKEY user_classes_root = nullptr;
HKEY user_classes_root = NULL;
if (token) {
auto err = RegOpenUserClassesRoot(token, 0, GENERIC_ALL, &user_classes_root);
if (err != ERROR_SUCCESS) {
@@ -573,14 +573,14 @@ namespace platf {
}
});
HKEY user_key = nullptr;
HKEY user_key = NULL;
if (token) {
impersonate_current_user(token, [&]() {
// RegOpenCurrentUser() doesn't take a token. It assumes we're impersonating the desired user.
auto err = RegOpenCurrentUser(GENERIC_ALL, &user_key);
if (err != ERROR_SUCCESS) {
BOOST_LOG(error) << "Failed to open user key for target user: "sv << err;
user_key = nullptr;
user_key = NULL;
}
});
if (!user_key) {
@@ -602,7 +602,7 @@ namespace platf {
err = RegOverridePredefKey(HKEY_CURRENT_USER, user_key);
if (err != ERROR_SUCCESS) {
BOOST_LOG(error) << "Failed to override HKEY_CURRENT_USER: "sv << err;
RegOverridePredefKey(HKEY_CLASSES_ROOT, nullptr);
RegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
return false;
}
@@ -671,7 +671,7 @@ namespace platf {
* @details This converts URLs and non-executable file paths into a runnable command like ShellExecute().
* @param raw_cmd The raw command provided by the user.
* @param working_dir The working directory for the new process.
* @param token The user token currently being impersonated or `nullptr` if running as ourselves.
* @param token The user token currently being impersonated or `NULL` if running as ourselves.
* @param creation_flags The creation flags for CreateProcess(), which may be modified by this function.
* @return A command string suitable for use by CreateProcess().
*/
@@ -757,7 +757,7 @@ namespace platf {
}
// Reset per-user keys back to the original value
override_per_user_predefined_keys(nullptr);
override_per_user_predefined_keys(NULL);
}
if (res != S_OK) {
@@ -972,7 +972,7 @@ namespace platf {
ec = impersonate_current_user(user_token, [&]() {
std::wstring env_block = create_environment_block(cloned_env);
std::wstring wcmd = resolve_command_string(cmd, start_dir, user_token, creation_flags);
ret = CreateProcessAsUserW(user_token, nullptr, (LPWSTR) wcmd.c_str(), nullptr, nullptr, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? nullptr : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
ret = CreateProcessAsUserW(user_token, NULL, (LPWSTR) wcmd.c_str(), NULL, NULL, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? NULL : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
});
}
// Otherwise, launch the process using CreateProcessW()
@@ -995,8 +995,8 @@ namespace platf {
}
std::wstring env_block = create_environment_block(cloned_env);
std::wstring wcmd = resolve_command_string(cmd, start_dir, nullptr, creation_flags);
ret = CreateProcessW(nullptr, (LPWSTR) wcmd.c_str(), nullptr, nullptr, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? nullptr : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
std::wstring wcmd = resolve_command_string(cmd, start_dir, NULL, creation_flags);
ret = CreateProcessW(NULL, (LPWSTR) wcmd.c_str(), NULL, NULL, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? NULL : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
}
// Use the results of the launch to create a bp::child object
@@ -1052,7 +1052,7 @@ namespace platf {
static std::once_flag load_wlanapi_once_flag;
std::call_once(load_wlanapi_once_flag, []() {
// wlanapi.dll is not installed by default on Windows Server, so we load it dynamically
HMODULE wlanapi = LoadLibraryExA("wlanapi.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
HMODULE wlanapi = LoadLibraryExA("wlanapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!wlanapi) {
BOOST_LOG(debug) << "wlanapi.dll is not available on this OS"sv;
return;
@@ -1129,7 +1129,7 @@ namespace platf {
fn_WlanFreeMemory(wlan_interface_list);
} else {
fn_WlanCloseHandle(wlan_handle, nullptr);
wlan_handle = nullptr;
wlan_handle = NULL;
}
}
}
@@ -1200,7 +1200,7 @@ namespace platf {
startup_info.StartupInfo.cb = sizeof(startup_info);
WCHAR executable[MAX_PATH];
if (GetModuleFileNameW(nullptr, executable, ARRAYSIZE(executable)) == 0) {
if (GetModuleFileNameW(NULL, executable, ARRAYSIZE(executable)) == 0) {
auto winerr = GetLastError();
BOOST_LOG(fatal) << "Failed to get Sunshine path: "sv << winerr;
return;
@@ -1220,7 +1220,7 @@ namespace platf {
void restart() {
// If we're running standalone, we have to respawn ourselves via CreateProcess().
// If we're running from the service, we should just exit and let it respawn us.
if (GetConsoleWindow() != nullptr) {
if (GetConsoleWindow() != NULL) {
// Avoid racing with the new process by waiting until we're exiting to start it.
atexit(restart_on_exit);
}
@@ -1538,7 +1538,7 @@ namespace platf {
}
virtual ~qos_t() {
if (!fn_QOSRemoveSocketFromFlow(qos_handle, (SOCKET) nullptr, flow_id, 0)) {
if (!fn_QOSRemoveSocketFromFlow(qos_handle, (SOCKET) NULL, flow_id, 0)) {
auto winerr = GetLastError();
BOOST_LOG(warning) << "QOSRemoveSocketFromFlow() failed: "sv << winerr;
}
@@ -1570,7 +1570,7 @@ namespace platf {
static std::once_flag load_qwave_once_flag;
std::call_once(load_qwave_once_flag, []() {
// qWAVE is not installed by default on Windows Server, so we load it dynamically
HMODULE qwave = LoadLibraryExA("qwave.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
HMODULE qwave = LoadLibraryExA("qwave.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!qwave) {
BOOST_LOG(debug) << "qwave.dll is not available on this OS"sv;
return;
@@ -1788,11 +1788,11 @@ namespace platf {
}
operator bool() override {
return timer != nullptr;
return timer != NULL;
}
private:
HANDLE timer = nullptr;
HANDLE timer = NULL;
};
std::unique_ptr<high_precision_timer> create_high_precision_timer() {

View File

@@ -9,7 +9,7 @@
#include <string_view>
// platform includes
#include <Windows.h>
#include <windows.h>
#include <winnt.h>
namespace platf {

View File

@@ -60,7 +60,7 @@ namespace nvprefs {
void driver_settings_t::destroy() {
if (session_handle) {
NvAPI_DRS_DestroySession(session_handle);
session_handle = nullptr;
session_handle = 0;
}
NvAPI_Unload();
}
@@ -105,7 +105,7 @@ namespace nvprefs {
if (swapchain_data) {
NvAPI_Status status;
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_GetBaseProfile(session_handle, &profile_handle);
if (status != NVAPI_OK) {
nvapi_error_message(status);
@@ -168,7 +168,7 @@ namespace nvprefs {
return true;
}
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_GetBaseProfile(session_handle, &profile_handle);
if (status != NVAPI_OK) {
nvapi_error_message(status);
@@ -224,7 +224,7 @@ namespace nvprefs {
NvAPI_UnicodeString profile_name = {};
fill_nvapi_string(profile_name, sunshine_application_profile_name);
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_FindProfileByName(session_handle, profile_name, &profile_handle);
if (status != NVAPI_OK) {

View File

@@ -36,7 +36,7 @@ namespace nvprefs {
bool check_and_modify_application_profile(bool &modified);
private:
NvDRSSessionHandle session_handle = nullptr;
NvDRSSessionHandle session_handle = 0;
};
} // namespace nvprefs

View File

@@ -15,7 +15,7 @@
namespace {
std::map<const char *, void *> interfaces;
HMODULE dll = nullptr;
HMODULE dll = NULL;
template<typename Func, typename... Args>
NvAPI_Status call_interface(const char *name, Args... args) {
@@ -47,7 +47,7 @@ NvAPI_Initialize() {
auto dll_name = "nvapi.dll";
#endif
if ((dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if (auto query_interface = (decltype(nvapi_QueryInterface) *) GetProcAddress(dll, "nvapi_QueryInterface")) {
for (const auto &item : nvapi_interface_table) {
interfaces[item.func] = query_interface(item.id);
@@ -64,7 +64,7 @@ NVAPI_INTERFACE NvAPI_Unload() {
if (dll) {
interfaces.clear();
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
return NVAPI_OK;
}

View File

@@ -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
@@ -21,7 +21,7 @@ namespace nvprefs {
explicit operator bool() const {
auto handle = get();
return handle != nullptr && handle != INVALID_HANDLE_VALUE;
return handle != NULL && handle != INVALID_HANDLE_VALUE;
}
};

View File

@@ -51,7 +51,7 @@ namespace nvprefs {
std::optional<undo_file_t> undo_file_t::open_existing_file(std::filesystem::path file_path, bool &access_denied) {
undo_file_t file;
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_READ | DELETE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_READ | DELETE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
if (file.file_handle) {
access_denied = false;
return file;
@@ -64,7 +64,7 @@ namespace nvprefs {
std::optional<undo_file_t> undo_file_t::create_new_file(std::filesystem::path file_path) {
undo_file_t file;
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_WRITE | STANDARD_RIGHTS_ALL, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr));
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_WRITE | STANDARD_RIGHTS_ALL, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL));
if (file.file_handle) {
// give GENERIC_READ, GENERIC_WRITE and DELETE permissions to Users group

View File

@@ -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

View File

@@ -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";

View File

@@ -12,7 +12,6 @@ extern "C" {
// standard includes
#include <array>
#include <cctype>
#include <format>
#include <set>
#include <unordered_map>
#include <utility>
@@ -865,7 +864,7 @@ namespace rtsp_stream {
session_option.next = &port_option;
// Moonlight merely requires 'server_port=<port>'
auto port_value = std::format("server_port={}", static_cast<int>(port));
auto port_value = "server_port=" + std::to_string(port);
port_option.option = const_cast<char *>("Transport");
port_option.content = port_value.data();

View File

@@ -84,7 +84,7 @@ namespace system_tray {
#ifdef _WIN32
// If we're running in a service, return a special status to
// tell it to terminate too, otherwise it will just respawn us.
if (GetConsoleWindow() == nullptr) {
if (GetConsoleWindow() == NULL) {
lifetime::exit_sunshine(ERROR_SHUTDOWN_IN_PROGRESS, true);
return;
}
@@ -230,10 +230,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON_PLAYING;
tray_update(&tray);
tray.icon = TRAY_ICON_PLAYING;
@@ -251,10 +251,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON_PAUSING;
tray_update(&tray);
char msg[256];
@@ -272,10 +272,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON;
tray_update(&tray);
char msg[256];
@@ -293,10 +293,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON;
tray_update(&tray);
tray.icon = TRAY_ICON;
@@ -305,7 +305,7 @@ namespace system_tray {
tray.notification_icon = TRAY_ICON_LOCKED;
tray.tooltip = PROJECT_NAME;
tray.notification_cb = []() {
launch_ui("/pin");
launch_ui_with_path("/pin");
};
tray_update(&tray);
}

View File

@@ -1890,10 +1890,9 @@ namespace video {
}
});
// 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;
// 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;
auto shutdown_event = mail->event<bool>(mail::shutdown);
auto packets = mail::man->queue<packet_t>(mail::video_packets);
@@ -1944,7 +1943,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(max_frametime)) {
if (auto img = images->pop(minimum_frame_time)) {
frame_timestamp = img->frame_timestamp;
if (session->convert(*img)) {
BOOST_LOG(error) << "Could not convert image"sv;

View File

@@ -179,7 +179,6 @@
"dd_mode_remapping": {"mixed": [], "resolution_only": [], "refresh_rate_only": []},
"dd_wa_hdr_toggle_delay": 0,
"max_bitrate": 0,
"minimum_fps_target": 0
},
},
{

View File

@@ -17,13 +17,6 @@ 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>

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Файлът, в който се запазва текущия журнал на Sunshine.",
"max_bitrate": "Максимална побитова скорост",
"max_bitrate_desc": "Максималната побитова скорост (в Kbps), с която да се кодира потокът. Ако е зададена стойност 0, винаги ще се използва скоростта, поискана от Moonlight.",
"minimum_fps_target": "Минимален целеви брой кадри/сек",
"minimum_fps_target_desc": "Най-малкият действителен брой кадри/сек, до който потокът може да достигне. Стойност 0 се счита за приблизително половината от броя кадри/сек на потока. Препоръчва се стойност 20, ако излъчвате съдържание с 24 или 30 кадъра в секунда.",
"min_threads": "Минимален брой нишки на процесора",
"min_threads_desc": "Увеличаването на стойността леко намалява ефективността на кодирането, но компромисът обикновено си заслужава, тъй като ще се използват повече процесорни ядра за кодиране. Идеалната стойност е най-ниската възможна стойност, при която кодирането може да се извършва надеждно при желаните от настройки за излъчване и използваният хардуер.",
"misc": "Други настройки",

View File

@@ -256,6 +256,8 @@
"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 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.",
"minimum_fps_target": "Minimální cíl FPS",
"minimum_fps_target_desc": "Nejnižší efektivní FPS proud může dosáhnout. Hodnota 0 se považuje za zhruba polovinu FPS streamu. Nastavení 20 se doporučuje, pokud vysíláte 24 nebo 30 fps obsah.",
"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",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Die Datei, in der die aktuellen Logs von Sunshine gespeichert werden.",
"max_bitrate": "Maximale Bitrate",
"max_bitrate_desc": "Die maximale Bitrate (in Kbps), bei der Sunshine den Stream kodiert. Wenn sie auf 0 gesetzt ist, wird sie immer die Bitrate verwenden, die von Mononlight angefordert wird.",
"minimum_fps_target": "Minimales FPS Ziel",
"minimum_fps_target_desc": "Die niedrigste effektive FPS die ein Stream erreichen kann. Ein Wert von 0 wird als ungefähr die Hälfte des FPS des Stream behandelt. Eine Einstellung von 20 wird empfohlen, wenn Sie 24 oder 30 fps Inhalt streamen.",
"min_threads": "Minimale CPU-Thread-Anzahl",
"min_threads_desc": "Die Erhöhung des Wertes verringert die Encoding-Effizienz, aber der Abgleich lohnt sich in der Regel, mehr CPU-Kerne für die Kodierung zu verwenden. Der ideale Wert ist der niedrigste Wert, der zuverlässig an den gewünschten Streaming-Einstellungen auf Ihrer Hardware kodieren kann.",
"misc": "Verschiedene Optionen",

View File

@@ -256,8 +256,6 @@
"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",

View File

@@ -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",

View File

@@ -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",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "El archivo donde se almacenan los registros actuales de Sunshine.",
"max_bitrate": "Tasa de bits máxima",
"max_bitrate_desc": "La tasa de bits máxima (en Kbps) que Sunshine codificará la secuencia. Si se establece en 0, siempre utilizará la tasa de bits solicitada por la luz lunar.",
"minimum_fps_target": "Objetivo mínimo de FPS",
"minimum_fps_target_desc": "El FPS efectivo más bajo que una corriente puede alcanzar. Un valor de 0 es tratado como aproximadamente la mitad del FPS del flujo. Se recomienda un ajuste de 20 si transmite contenido de 24 o 30 fps.",
"min_threads": "Recuento mínimo de hilos de CPU",
"min_threads_desc": "Incrementar el valor reduce ligeramente la eficiencia de la codificación, pero la compensación suele valer la pena para obtener el uso de más núcleos de CPU para la codificación. El valor ideal es el valor más bajo que puede codificar de forma fiable en los ajustes de streaming deseados en su hardware.",
"misc": "Opciones varias",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Le fichier où sont stockés les logs actuels de Sunshine.",
"max_bitrate": "Débit maximum",
"max_bitrate_desc": "Le débit maximum (en Kbps) auquel Sunshine encode le flux. Si réglé sur 0, il utilisera toujours le débit demandé par Lune.",
"minimum_fps_target": "Cible FPS minimale",
"minimum_fps_target_desc": "Le FPS effectif le plus bas qu'un flux peut atteindre. Une valeur de 0 est traitée comme la moitié environ du FPS du flux. Un réglage de 20 est recommandé si vous streamez du contenu de 24 ou 30 images par seconde.",
"min_threads": "Nombre minimum de threads CPU",
"min_threads_desc": "Augmenter la valeur réduit légèrement l'efficacité de l'encodage, mais le compromis vaut généralement la peine de gagner l'utilisation de plus de cœurs CPU pour l'encodage. La valeur idéale est la valeur la plus basse qui peut de manière fiable encoder les paramètres de streaming désirés sur votre matériel.",
"misc": "Options diverses",

View File

@@ -0,0 +1,457 @@
{
"_common": {
"apply": "Alkalmazás",
"auto": "Automatikus",
"autodetect": "Autodetect (ajánlott)",
"beta": "(béta)",
"cancel": "Törölje",
"disabled": "Mozgáskorlátozottak",
"disabled_def": "Kikapcsolva (alapértelmezett)",
"disabled_def_cbox": "Alapértelmezett: nincs bejelölve",
"dismiss": "Elutasíthatod",
"do_cmd": "Do parancs",
"elevated": "Megemelt",
"enabled": "Engedélyezve",
"enabled_def": "Engedélyezve (alapértelmezett)",
"enabled_def_cbox": "Alapértelmezett: ellenőrzött",
"error": "Hiba!",
"note": "Megjegyzés:",
"password": "Jelszó",
"run_as": "Adminként futtatni",
"save": "Mentés",
"see_more": "Lásd még",
"success": "Siker!",
"undo_cmd": "Visszavonás parancs",
"username": "Felhasználónév",
"warning": "Figyelem!"
},
"apps": {
"actions": "Tevékenységek",
"add_cmds": "Parancsok hozzáadása",
"add_new": "Új hozzáadása",
"app_name": "Alkalmazás neve",
"app_name_desc": "Alkalmazás neve, a Moonlight-on feltüntetett módon",
"applications_desc": "Az alkalmazások csak az ügyfél újraindításakor frissülnek.",
"applications_title": "Alkalmazások",
"auto_detach": "Folytassa a streaminget, ha az alkalmazás gyorsan kilép",
"auto_detach_desc": "Ez megpróbálja automatikusan felismerni az olyan indító típusú alkalmazásokat, amelyek gyorsan bezáródnak egy másik program vagy saját példányuk elindítása után. Ha egy indító típusú alkalmazást észlel, azt leválasztott alkalmazásként kezeli.",
"cmd": "Parancs",
"cmd_desc": "A fő alkalmazás elindítása. Ha üres, akkor nem indul alkalmazás.",
"cmd_note": "Ha a parancs futtatható fájljának elérési útvonala szóközöket tartalmaz, akkor idézőjelek közé kell zárnia.",
"cmd_prep_desc": "Az alkalmazás előtt/után futtatandó parancsok listája. Ha bármelyik előkészítő parancs sikertelen, az alkalmazás elindítása megszakad.",
"cmd_prep_name": "Parancsnoki előkészületek",
"covers_found": "Fedelek találtak",
"delete": "Törölje a címet.",
"detached_cmds": "Leválasztott parancsok",
"detached_cmds_add": "Önálló parancs hozzáadása",
"detached_cmds_desc": "A háttérben futtatandó parancsok listája.",
"detached_cmds_note": "Ha a parancs futtatható fájljának elérési útvonala szóközöket tartalmaz, akkor idézőjelek közé kell zárnia.",
"edit": "Szerkesztés",
"env_app_id": "Alkalmazás azonosítója",
"env_app_name": "Alkalmazás neve",
"env_client_audio_config": "Az ügyfél által kért hangkonfiguráció (2.0/5.1/7.1)",
"env_client_enable_sops": "Az ügyfél kérte a játék optimalizálásának lehetőségét az optimális streaminghez (igaz/hamis).",
"env_client_fps": "Az ügyfél által kért FPS (int)",
"env_client_gcmap": "A kért gamepad maszk, bset/bitfield formátumban (int)",
"env_client_hdr": "Az ügyfél engedélyezi a HDR-t (igaz/hamis)",
"env_client_height": "Az ügyfél által kért magasság (int)",
"env_client_host_audio": "Az ügyfél host hangot kért (igaz/hamis)",
"env_client_width": "Az ügyfél által kért szélesség (int)",
"env_displayplacer_example": "Példa - displayplacer a Resolution Automation számára:",
"env_qres_example": "Példa - QRes a felbontás automatizálásához:",
"env_qres_path": "qres útvonal",
"env_var_name": "Var neve",
"env_vars_about": "A környezeti változókról",
"env_vars_desc": "Alapértelmezés szerint minden parancs megkapja ezeket a környezeti változókat:",
"env_xrandr_example": "Példa - Xrandr a felbontás automatizálásához:",
"exit_timeout": "Kilépési időkorlát",
"exit_timeout_desc": "A kilépésre vonatkozó kérés esetén az alkalmazás összes folyamatának méltóságteljes kilépésére várandó másodpercek száma. Ha nincs megadva, az alapértelmezett érték 5 másodpercig várakozik. Ha 0-ra van állítva, az alkalmazás azonnal befejeződik.",
"find_cover": "Fedezet keresése",
"global_prep_desc": "A globális előkészítő parancsok végrehajtásának engedélyezése/letiltása az alkalmazás számára.",
"global_prep_name": "Globális előkészítő parancsok",
"image": "Kép",
"image_desc": "Az ügyfélnek küldött alkalmazás ikon/kép/kép elérési útvonala. A képnek PNG fájlnak kell lennie. Ha nincs megadva, a Sunshine alapértelmezett dobozképet küld.",
"loading": "Betöltés...",
"name": "Név",
"output_desc": "Az a fájl, ahol a parancs kimenete tárolódik, ha nincs megadva, a kimenetet figyelmen kívül hagyjuk.",
"output_name": "Kimenet",
"run_as_desc": "Erre olyan alkalmazásoknál lehet szükség, amelyek megfelelő futtatásához rendszergazdai engedélyek szükségesek.",
"wait_all": "Folytassa a streaminget, amíg az összes alkalmazásfolyamat ki nem lép",
"wait_all_desc": "A streaming addig folytatódik, amíg az alkalmazás által indított összes folyamat le nem zárul. Ha nincs bejelölve, a streaming leáll, amikor az alkalmazás kezdeti folyamata kilép, még akkor is, ha más alkalmazásfolyamatok még futnak.",
"working_dir": "Munkakönyvtár",
"working_dir_desc": "A folyamatnak átadandó munkakönyvtár. Egyes alkalmazások például a munkakönyvtárat használják a konfigurációs fájlok keresésére. Ha nincs megadva, a Sunshine alapértelmezés szerint a parancs szülő könyvtárát fogja használni."
},
"config": {
"adapter_name": "Adapter neve",
"adapter_name_desc_linux_1": "Kézzel adja meg a rögzítéshez használt GPU-t.",
"adapter_name_desc_linux_2": "az összes VAAPI-képes eszköz megtalálása",
"adapter_name_desc_linux_3": "A ``renderD129``-t helyettesítsük a fenti eszközzel, hogy felsoroljuk az eszköz nevét és képességeit. Ahhoz, hogy a Sunshine támogassa, legalább a következőkkel kell rendelkeznie:",
"adapter_name_desc_windows": "Kézzel adja meg a rögzítéshez használt GPU-t. Ha nincs megadva, a GPU automatikusan kiválasztásra kerül. A GPU automatikus kiválasztásához javasoljuk, hogy hagyja üresen ezt a mezőt! Megjegyzés: Ehhez a GPU-hoz csatlakoztatott és bekapcsolt kijelzőnek kell lennie. A megfelelő értékeket a következő paranccsal találhatja meg:",
"adapter_name_placeholder_windows": "Radeon RX 580 sorozat",
"add": "Add",
"address_family": "Cím Család",
"address_family_both": "IPv4+IPv6",
"address_family_desc": "A Sunshine által használt címcsalád beállítása",
"address_family_ipv4": "Csak IPv4",
"always_send_scancodes": "Mindig küldjön kódokat",
"always_send_scancodes_desc": "A scan-kódok küldése javítja a kompatibilitást a játékokkal és alkalmazásokkal, de bizonyos, nem amerikai angol billentyűzetkiosztást használó ügyfeleknél helytelen billentyűzetbevitelt eredményezhet. Engedélyezze, ha a billentyűzetbevitel egyáltalán nem működik bizonyos alkalmazásokban. Tiltja le, ha az ügyfél billentyűi rossz bevitelt generálnak a hoszton.",
"amd_coder": "AMF kódoló (H264)",
"amd_coder_desc": "Lehetővé teszi az entrópia kódolás kiválasztását a minőség vagy a kódolási sebesség előtérbe helyezéséhez. Csak H.264.",
"amd_enforce_hrd": "AMF hipotetikus referencia dekóder (HRD) végrehajtása",
"amd_enforce_hrd_desc": "Növeli az árfolyam-szabályozásra vonatkozó korlátozásokat, hogy megfeleljen a HRD-modell követelményeinek. Ez nagymértékben csökkenti a bitráta-túlcsordulást, de bizonyos kártyákon kódolási leleteket vagy csökkent minőséget okozhat.",
"amd_preanalysis": "AMF előelemzés",
"amd_preanalysis_desc": "Ez lehetővé teszi a sebesség-szabályozás előzetes elemzését, ami növelheti a minőséget a megnövekedett kódolási késleltetés rovására.",
"amd_quality": "AMF minőség",
"amd_quality_balanced": "balanced -- kiegyensúlyozott (alapértelmezett)",
"amd_quality_desc": "Ez szabályozza a kódolási sebesség és a minőség közötti egyensúlyt.",
"amd_quality_group": "AMF minőségi beállítások",
"amd_quality_quality": "minőség -- inkább a minőséget részesítsük előnyben",
"amd_quality_speed": "sebesség -- inkább sebesség",
"amd_rc": "AMF Rate Control",
"amd_rc_cbr": "cbr -- állandó bitráta (ajánlott, ha a HRD engedélyezve van)",
"amd_rc_cqp": "cqp -- állandó qp üzemmód",
"amd_rc_desc": "Ez vezérli a sebességszabályozási módszert, hogy biztosítsa, hogy nem lépjük túl az ügyfél bitrátájának célértékét. A 'cqp' nem alkalmas bitráta-célzásra, és a 'vbr_latency'-n kívül más opciók is a HRD Enforcementtől függenek, hogy segítsenek a bitráta-túllépések korlátozásában.",
"amd_rc_group": "AMF Rate Control beállítások",
"amd_rc_vbr_latency": "vbr_latency -- késleltetéskorlátozott változó bitráta (ajánlott, ha a HRD le van tiltva; alapértelmezett)",
"amd_rc_vbr_peak": "vbr_peak -- csúcsértékkel korlátozott változó bitráta",
"amd_usage": "AMF használat",
"amd_usage_desc": "Ez állítja be az alap kódolási profilt. Az alább bemutatott összes opció felülírja a használati profil egy részhalmazát, de vannak további rejtett beállítások, amelyek máshol nem konfigurálhatók.",
"amd_usage_lowlatency": "lowlatency - alacsony késleltetés (leggyorsabb)",
"amd_usage_lowlatency_high_quality": "lowlatency_high_quality - alacsony késleltetés, magas minőség (gyors)",
"amd_usage_transcoding": "transzkódolás -- transzkódolás (leglassabb)",
"amd_usage_ultralowlatency": "ultralowlatency - ultra alacsony késleltetés (leggyorsabb; alapértelmezett)",
"amd_usage_webcam": "webkamera -- webkamera (lassú)",
"amd_vbaq": "AMF Variancia alapú adaptív kvantálás (VBAQ)",
"amd_vbaq_desc": "Az emberi vizuális rendszer jellemzően kevésbé érzékeny az erősen texturált területeken megjelenő műalkotásokra. A VBAQ módban a pixelvariancia a térbeli textúrák összetettségének jelzésére szolgál, lehetővé téve a kódoló számára, hogy több bitet rendeljen a simább területekhez. E funkció engedélyezése bizonyos tartalmak esetében javítja a szubjektív vizuális minőséget.",
"apply_note": "Kattintson az 'Alkalmaz' gombra a Sunshine újraindításához és a módosítások alkalmazásához. Ezzel minden futó munkamenet megszűnik.",
"audio_sink": "Audio Sink",
"audio_sink_desc_linux": "Az Audio Loopbackhez használt hangkimenet neve. Ha nem adja meg ezt a változót, a pulseaudio az alapértelmezett monitor eszközt fogja kiválasztani. A hangelnyelő nevét bármelyik parancs segítségével megtudhatja:",
"audio_sink_desc_macos": "Az Audio Loopbackhez használt hangkimenet neve. A Sunshine a rendszer korlátai miatt csak a macOS rendszerben érheti el a mikrofonokat. Rendszerhang streameléséhez Soundflower vagy BlackHole használatával.",
"audio_sink_desc_windows": "Kézzel adja meg a rögzítendő hangeszközöket. Ha nincs megadva, az eszköz automatikusan kiválasztásra kerül. Az automatikus eszközkiválasztás használatához erősen ajánlott üresen hagyni ezt a mezőt! Ha több azonos nevű audioeszközzel rendelkezik, az eszközazonosítót a következő paranccsal kaphatja meg:",
"audio_sink_placeholder_macos": "BlackHole 2ch",
"audio_sink_placeholder_windows": "Hangszórók (nagy felbontású hangeszköz)",
"av1_mode": "AV1 támogatás",
"av1_mode_0": "A Sunshine az AV1 támogatását a kódoló képességei alapján hirdeti (ajánlott)",
"av1_mode_1": "A Sunshine nem fogja hirdetni az AV1 támogatását",
"av1_mode_2": "A Sunshine az AV1 Main 8-bites profil támogatását fogja hirdetni",
"av1_mode_3": "A Sunshine az AV1 Main 8-bites és 10-bites (HDR) profilok támogatását hirdeti meg",
"av1_mode_desc": "Lehetővé teszi az ügyfél számára, hogy AV1 Main 8 bites vagy 10 bites videófolyamokat kérjen. Az AV1 kódolása CPU-igényesebb, ezért ennek engedélyezése csökkentheti a teljesítményt szoftveres kódolás esetén.",
"back_button_timeout": "Home/Guide gomb Emulációs időkorlát",
"back_button_timeout_desc": "Ha a Back/Select gombot a megadott számú milliszekundumig lenyomva tartja, a Home/Guide gomb megnyomása utánozódik. Ha < 0 értékre van beállítva (alapértelmezett), a Back/Select gomb nyomva tartása nem emulálja a Home/Guide gombot.",
"capture": "Speciális rögzítési módszer kikényszerítése",
"capture_desc": "Automatikus üzemmódban a Sunshine az elsőt használja, amelyik működik. Az NvFBC javított nvidia illesztőprogramokat igényel.",
"cert": "Tanúsítvány",
"cert_desc": "A webes felhasználói felület és a Moonlight-ügyfél párosításához használt tanúsítvány. A legjobb kompatibilitás érdekében ennek RSA-2048-as nyilvános kulccsal kell rendelkeznie.",
"channels": "Maximális csatlakoztatott ügyfelek",
"channels_desc_1": "A Sunshine lehetővé teszi, hogy egyetlen streaming munkamenetet egyszerre több ügyfél is használhasson.",
"channels_desc_2": "Néhány hardveres kódolónak lehetnek olyan korlátai, amelyek több adatfolyam esetén csökkentik a teljesítményt.",
"coder_cabac": "cabac -- kontextus adaptív bináris aritmetikai kódolás - magasabb minőség",
"coder_cavlc": "cavlc -- kontextus adaptív változó hosszúságú kódolás - gyorsabb dekódolás",
"configuration": "Konfiguráció",
"controller": "Gamepad bemenet engedélyezése",
"controller_desc": "Lehetővé teszi a vendégek számára, hogy gamepaddal / kontrollerrel irányítsák a gazdarendszert.",
"credentials_file": "Hitelesítési fájl",
"credentials_file_desc": "Tárolja a felhasználónevet/jelszót a Sunshine állapotfájljától elkülönítve.",
"dd_config_ensure_active": "A kijelző automatikus aktiválása",
"dd_config_ensure_only_display": "Más kijelzők kikapcsolása és csak a megadott kijelző aktiválása",
"dd_config_ensure_primary": "A kijelző automatikus aktiválása és elsődleges kijelzővé tétele",
"dd_config_label": "Eszköz konfigurációja",
"dd_config_revert_delay": "Config revert késleltetés",
"dd_config_revert_delay_desc": "Kiegészítő késleltetés milliszekundumban, amelyet a konfiguráció visszaállítása előtt várni kell, ha az alkalmazás bezárásra került vagy az utolsó munkamenet befejeződött. Fő célja, hogy simább átmenetet biztosítson az alkalmazások közötti gyors váltáskor.",
"dd_config_revert_on_disconnect": "Konfiguráció visszaállítása a kapcsolat megszakításakor",
"dd_config_revert_on_disconnect_desc": "A konfiguráció visszaállítása az összes ügyfél kapcsolatának megszakításakor az alkalmazás bezárása vagy az utolsó munkamenet befejezése helyett.",
"dd_config_verify_only": "Ellenőrizze, hogy a kijelző engedélyezve van-e",
"dd_hdr_option": "HDR",
"dd_hdr_option_auto": "A HDR üzemmód be-/kikapcsolása az ügyfél kérésének megfelelően (alapértelmezett).",
"dd_hdr_option_disabled": "Ne módosítsa a HDR beállításokat",
"dd_mode_remapping": "Megjelenítési mód átképzése",
"dd_mode_remapping_add": "Remapping bejegyzés hozzáadása",
"dd_mode_remapping_desc_1": "Adjon meg remapping bejegyzéseket a kért felbontás és/vagy frissítési sebesség más értékekre történő módosításához.",
"dd_mode_remapping_desc_2": "A lista felülről lefelé halad, és az első találatot használja fel.",
"dd_mode_remapping_desc_3": "A \"Requested\" mezők üresen hagyhatók, hogy megfeleljenek bármely kért értéknek.",
"dd_mode_remapping_desc_4_final_values_mixed": "Legalább egy \"Végleges\" mezőt meg kell adni. A meg nem adott felbontás vagy frissítési sebesség nem fog megváltozni.",
"dd_mode_remapping_desc_4_final_values_non_mixed": "A \"Final\" mezőt meg kell adni, és nem lehet üres.",
"dd_mode_remapping_desc_5_sops_mixed_only": "A \"Játékbeállítások optimalizálása\" opciónak engedélyezve kell lennie a Moonlight kliensben, különben a felbontási mezőkkel rendelkező bejegyzések kihagyásra kerülnek.",
"dd_mode_remapping_desc_5_sops_resolution_only": "A \"Játékbeállítások optimalizálása\" opciónak engedélyezve kell lennie a Moonlight kliensben, különben a leképezés kihagyásra kerül.",
"dd_mode_remapping_final_refresh_rate": "Végső frissítési sebesség",
"dd_mode_remapping_final_resolution": "Végleges állásfoglalás",
"dd_mode_remapping_requested_fps": "Kért FPS",
"dd_mode_remapping_requested_resolution": "Kért állásfoglalás",
"dd_options_header": "Speciális kijelzőeszköz beállítások",
"dd_refresh_rate_option": "Frissítési sebesség",
"dd_refresh_rate_option_auto": "Az ügyfél által megadott FPS-érték használata (alapértelmezett)",
"dd_refresh_rate_option_disabled": "Ne változtassa meg a frissítési sebességet",
"dd_refresh_rate_option_manual": "Kézzel megadott frissítési sebesség használata",
"dd_refresh_rate_option_manual_desc": "Adja meg a használni kívánt frissítési sebességet",
"dd_resolution_option": "Felbontás",
"dd_resolution_option_auto": "Az ügyfél által megadott felbontás használata (alapértelmezett)",
"dd_resolution_option_disabled": "Ne változtassa meg a felbontást",
"dd_resolution_option_manual": "Kézzel megadott felbontás használata",
"dd_resolution_option_manual_desc": "Adja meg a használni kívánt felbontást",
"dd_resolution_option_ogs_desc": "A \"Játékbeállítások optimalizálása\" opciónak engedélyezve kell lennie a Moonlight kliensben, hogy ez működjön.",
"dd_wa_hdr_toggle_delay_desc_1": "Ha virtuális megjelenítő eszközt (VDD) használ a streaminghez, előfordulhat, hogy a HDR színt helytelenül jeleníti meg. A Sunshine megpróbálhatja enyhíteni ezt a problémát a HDR kikapcsolásával, majd újra bekapcsolásával.",
"dd_wa_hdr_toggle_delay_desc_2": "Ha az érték 0-ra van állítva, a megoldás le van tiltva (alapértelmezett). Ha az érték 0 és 3000 milliszekundum között van, a Sunshine kikapcsolja a HDR-t, vár a megadott ideig, majd újra bekapcsolja a HDR-t. Az ajánlott késleltetési idő a legtöbb esetben 500 milliszekundum körül van.",
"dd_wa_hdr_toggle_delay_desc_3": "NE használja ezt a megoldást, kivéve, ha valóban problémái vannak a HDR-rel, mivel ez közvetlenül befolyásolja a stream indulási idejét!",
"dd_wa_hdr_toggle_delay": "Nagy kontrasztú megoldás HDR esetén",
"ds4_back_as_touchpad_click": "Vissza/kiválasztás az érintőpadra kattintás",
"ds4_back_as_touchpad_click_desc": "A DS4 emuláció kényszerítésekor a Vissza/Választás gombot a Touchpad kattintáshoz kell rendelni.",
"encoder": "Egy adott kódoló kényszerítése",
"encoder_desc": "Kényszerítsen egy adott kódolót, különben a Sunshine a legjobb elérhető opciót fogja kiválasztani. Megjegyzés: Ha Windows alatt hardveres kódolót ad meg, annak meg kell egyeznie azzal a GPU-val, amelyhez a kijelző csatlakoztatva van.",
"encoder_software": "Szoftver",
"external_ip": "Külső IP",
"external_ip_desc": "Ha nincs megadva külső IP-cím, a Sunshine automatikusan felismeri a külső IP-címet.",
"fec_percentage": "FEC százalékos aránya",
"fec_percentage_desc": "A hibajavító csomagok százalékos aránya adatcsomagonként az egyes videóképkockákban. A magasabb értékek több hálózati csomagveszteséget korrigálhatnak, de ennek ára a sávszélesség-használat növekedése.",
"ffmpeg_auto": "auto -- hagyja, hogy az ffmpeg döntsön (alapértelmezett)",
"file_apps": "Alkalmazások fájl",
"file_apps_desc": "Az a fájl, amelyben a Sunshine aktuális alkalmazásai tárolódnak.",
"file_state": "Állami fájl",
"file_state_desc": "A fájl, ahol a Sunshine aktuális állapota tárolódik",
"gamepad": "Emulált gamepad típus",
"gamepad_auto": "Automatikus kiválasztási lehetőségek",
"gamepad_desc": "Válassza ki, hogy milyen típusú gamepadot szeretne emulálni a gazdán.",
"gamepad_ds4": "DS4 (PS4)",
"gamepad_ds4_manual": "DS4 kiválasztási lehetőségek",
"gamepad_ds5": "DS5 (PS5)",
"gamepad_switch": "Nintendo Pro (Switch)",
"gamepad_manual": "Kézi DS4 opciók",
"gamepad_x360": "X360 (Xbox 360)",
"gamepad_xone": "XOne (Xbox One)",
"global_prep_cmd": "Parancsnoki előkészületek",
"global_prep_cmd_desc": "Konfigurálja a bármely alkalmazás futtatása előtt vagy után végrehajtandó parancsok listáját. Ha a megadott előkészítő parancsok bármelyike sikertelen, az alkalmazás indítási folyamata megszakad.",
"hevc_mode": "HEVC támogatás",
"hevc_mode_0": "A Sunshine a HEVC támogatását a kódoló képességei alapján fogja hirdetni (ajánlott)",
"hevc_mode_1": "A Sunshine nem fogja hirdetni a HEVC támogatását",
"hevc_mode_2": "A Sunshine a HEVC fő profil támogatását fogja hirdetni",
"hevc_mode_3": "A Sunshine a HEVC Main és Main10 (HDR) profilok támogatását fogja hirdetni",
"hevc_mode_desc": "Lehetővé teszi az ügyfél számára, hogy HEVC Main vagy HEVC Main10 videófolyamokat kérjen. A HEVC kódolása CPU-igényesebb, ezért ennek engedélyezése csökkentheti a teljesítményt szoftveres kódolás esetén.",
"high_resolution_scrolling": "Nagy felbontású görgetés támogatása",
"high_resolution_scrolling_desc": "Ha engedélyezve van, a Sunshine átadja a Moonlight-ügyfelek nagy felbontású görgetési eseményeit. Ezt hasznos lehet letiltani olyan régebbi alkalmazások esetében, amelyek túl gyorsan görgetnek a nagy felbontású görgetési eseményekkel.",
"install_steam_audio_drivers": "Steam audió illesztőprogramok telepítése",
"install_steam_audio_drivers_desc": "Ha a Steam telepítve van, ez automatikusan telepíti a Steam Streaming Speakers illesztőprogramot az 5.1/7.1 surround hangzás és a host hang elnémításának támogatásához.",
"key_repeat_delay": "Kulcsismétlés késleltetése",
"key_repeat_delay_desc": "Szabályozza, hogy a billentyűk milyen gyorsan ismétlődjenek. A kezdeti késleltetés milliszekundumban a billentyűk ismétlése előtt.",
"key_repeat_frequency": "Kulcs Ismétlési gyakoriság",
"key_repeat_frequency_desc": "Milyen gyakran ismétlődnek a billentyűk másodpercenként. Ez a konfigurálható opció támogatja a tizedesjegyeket.",
"key_rightalt_to_key_win": "A jobb Alt billentyű Windows billentyűhöz való hozzárendelése",
"key_rightalt_to_key_win_desc": "Előfordulhat, hogy a Windows-kulcsot nem tudja közvetlenül a Moonlightból elküldeni. Ezekben az esetekben hasznos lehet, ha a Sunshine úgy gondolja, hogy a jobb Alt billentyű a Windows billentyű.",
"keyboard": "Billentyűzetbemenet engedélyezése",
"keyboard_desc": "Lehetővé teszi a vendégek számára, hogy a billentyűzettel irányítsák a gazdarendszert.",
"lan_encryption_mode": "LAN titkosítási mód",
"lan_encryption_mode_1": "Engedélyezve a támogatott ügyfelek esetében",
"lan_encryption_mode_2": "Minden ügyfél számára kötelező",
"lan_encryption_mode_desc": "Ez határozza meg, hogy a helyi hálózaton keresztüli streaming során mikor kerül sor titkosításra. A titkosítás csökkentheti a streaming teljesítményét, különösen a kisebb teljesítményű hosztokon és klienseken.",
"locale": "Helyszín",
"locale_desc": "A Sunshine felhasználói felületén használt nyelvterület.",
"log_level": "Napló szint",
"log_level_0": "Bővebben",
"log_level_1": "Debug",
"log_level_2": "Info",
"log_level_3": "Figyelmeztetés",
"log_level_4": "Hiba",
"log_level_5": "Végzetes",
"log_level_6": "Nincs",
"log_level_desc": "A minimális naplózási szint, amely a szabványos kimenetre kerül kiírásra",
"log_path": "Naplófájl elérési útvonal",
"log_path_desc": "Az a fájl, amelyben a Sunshine aktuális naplói tárolódnak.",
"max_bitrate": "Maximális bitráta",
"max_bitrate_desc": "A maximális bitráta (Kbps-ban), amellyel a Sunshine kódolni fogja a streamet. Ha 0-ra van állítva, mindig a Moonlight által kért bitrátát fogja használni.",
"minimum_fps_target": "Minimális FPS cél",
"minimum_fps_target_desc": "A legalacsonyabb effektív FPS, amelyet egy stream elérhet. A 0 értéket a folyam FPS-értékének nagyjából felének tekintjük. A 20-as beállítás ajánlott, ha 24 vagy 30fps sebességű tartalmat streamel.",
"min_threads": "Minimális CPU szálszám",
"min_threads_desc": "Az érték növelése kissé csökkenti a kódolás hatékonyságát, de a kompromisszum általában megéri, ha több CPU-magot használhatunk a kódoláshoz. Az ideális érték az a legalacsonyabb érték, amely megbízhatóan kódol a kívánt streaming-beállítások mellett a hardveren.",
"misc": "Egyéb lehetőségek",
"motion_as_ds4": "DS4 gamepad emulálása, ha a kliens gamepad mozgásérzékelők jelenlétét jelzi.",
"motion_as_ds4_desc": "Ha letiltja, a mozgásérzékelőket nem veszi figyelembe a játékvezérlő típusának kiválasztásakor.",
"mouse": "Egérbemenet engedélyezése",
"mouse_desc": "Lehetővé teszi a vendégek számára, hogy az egérrel irányítsák a gazdarendszert.",
"native_pen_touch": "Natív toll/érintés támogatás",
"native_pen_touch_desc": "Ha engedélyezve van, a Sunshine átadja a Moonlight-ügyfelek natív toll/érintés eseményeit. Ezt hasznos lehet letiltani a régebbi, natív toll/érintés támogatással nem rendelkező alkalmazások esetében.",
"notify_pre_releases": "Kiadás előtti értesítések",
"notify_pre_releases_desc": "Akar-e értesítést kapni a Sunshine új, kiadás előtti verzióiról?",
"nvenc_h264_cavlc": "A CAVLC előnyben részesítése a CABAC-kal szemben a H.264-ben",
"nvenc_h264_cavlc_desc": "Az entrópia kódolás egyszerűbb formája. A CAVLC-nek körülbelül 10%-kal több bitrátára van szüksége ugyanahhoz a minőséghez. Csak nagyon régi dekódoló eszközök esetében releváns.",
"nvenc_latency_over_power": "Az alacsonyabb kódolási késleltetés előnyben részesítése az energiatakarékossággal szemben",
"nvenc_latency_over_power_desc": "A Sunshine a maximális GPU-órajelsebességet kéri streamelés közben, hogy csökkentse a kódolási késleltetést. Ennek kikapcsolása nem ajánlott, mivel ez jelentősen megnövekedett kódolási késleltetéshez vezethet.",
"nvenc_opengl_vulkan_on_dxgi": "OpenGL/Vulkan bemutatása a DXGI tetején",
"nvenc_opengl_vulkan_on_dxgi_desc": "A Sunshine nem képes teljes képernyős OpenGL és Vulkan programokat teljes képkocka sebességgel rögzíteni, hacsak nem a DXGI tetején vannak jelen. Ez egy rendszerszintű beállítás, amely a Sunshine programból való kilépéskor visszaáll.",
"nvenc_preset": "Előre beállított teljesítmény",
"nvenc_preset_1": "(leggyorsabb, alapértelmezett)",
"nvenc_preset_7": "(leglassabban)",
"nvenc_preset_desc": "A nagyobb számok javítják a tömörítést (minőséget adott bitráta mellett) a megnövekedett kódolási késleltetés árán. Csak akkor ajánlott változtatni, ha a hálózat vagy a dekóder korlátozza, egyébként hasonló hatás érhető el a bitráta növelésével.",
"nvenc_realtime_hags": "Valós idejű prioritás használata hardveres gyorsított gpu ütemezésben",
"nvenc_realtime_hags_desc": "Jelenleg az NVIDIA illesztőprogramok lefagyhatnak a kódolóban, ha a HAGS engedélyezve van, valós idejű prioritást használnak, és a VRAM kihasználtsága közel van a maximumhoz. Ennek az opciónak a letiltása a prioritást magasra csökkenti, így elkerülhető a lefagyás, ami a GPU nagy terhelésénél a rögzítési teljesítmény csökkenésének árán történik.",
"nvenc_spatial_aq": "Térbeli AQ",
"nvenc_spatial_aq_desc": "A videó lapos régióihoz magasabb QP-értékeket rendelhet. Ajánlott engedélyezni alacsonyabb bitráta mellett történő streamelés esetén.",
"nvenc_twopass": "Kétszeri átjárási mód",
"nvenc_twopass_desc": "Előzetes kódolási lépés hozzáadása. Ez lehetővé teszi több mozgásvektor felismerését, a bitráta jobb elosztását a képkockán belül, és a bitráta-határértékek szigorúbb betartását. A kikapcsolása nem ajánlott, mivel ez esetenként bitráta-túllépéshez és későbbi csomagvesztéshez vezethet.",
"nvenc_twopass_disabled": "Letiltva (leggyorsabb, nem ajánlott)",
"nvenc_twopass_full_res": "Teljes felbontás (lassabb)",
"nvenc_twopass_quarter_res": "Negyedes felbontás (gyorsabb, alapértelmezett)",
"nvenc_vbv_increase": "Egyetlen képkocka VBV/HRD százalékos növekedése",
"nvenc_vbv_increase_desc": "Alapértelmezés szerint a sunshine egykockás VBV/HRD-t használ, ami azt jelenti, hogy a kódolt videóképkocka mérete várhatóan nem haladja meg a kért bitrátát osztva a kért képkocka sebességgel. Ennek a korlátozásnak az enyhítése előnyös lehet, és alacsony késleltetésű változó bitrátaként működhet, de csomagvesztéshez is vezethet, ha a hálózatnak nincs pufferterülete a bitráta-csúcsok kezeléséhez. A maximálisan elfogadott érték 400, ami megfelel az 5x megnövelt kódolt videóképkocka felső mérethatárának.",
"origin_web_ui_allowed": "Origin webes felhasználói felület Engedélyezve",
"origin_web_ui_allowed_desc": "A webes felhasználói felülethez való hozzáférést nem tiltó távoli végpontcím eredete",
"origin_web_ui_allowed_lan": "Csak a LAN-ban lévők férhetnek hozzá a webes felhasználói felülethez",
"origin_web_ui_allowed_pc": "Csak a localhost férhet hozzá a webes felhasználói felülethez",
"origin_web_ui_allowed_wan": "Bárki hozzáférhet a webes felhasználói felülethez",
"output_name_desc_unix": "A Sunshine indítása során meg kell jelenítenie az észlelt kijelzők listáját. Megjegyzés: A zárójelben lévő id értéket kell használnia. Az alábbiakban egy példa látható; a tényleges kimenet a Hibaelhárítás lapon található.",
"output_name_desc_windows": "A rögzítéshez használt kijelzőeszköz azonosítójának manuális megadása. Ha nincs megadva, az elsődleges kijelzőt rögzíti a rendszer. Megjegyzés: Ha fentebb GPU-t adott meg, akkor ennek a kijelzőnek ahhoz a GPU-hoz kell csatlakoznia. A Sunshine indítása során meg kell jelenítenie az észlelt kijelzők listáját. Az alábbiakban egy példa látható; a tényleges kimenet a Hibaelhárítás lapon található.",
"output_name_unix": "Kijelzőszám",
"output_name_windows": "Eszköz azonosítójának megjelenítése",
"ping_timeout": "Ping időkorlát",
"ping_timeout_desc": "Mennyi ideig kell várni milliszekundumban a holdfénytől érkező adatokra a folyam leállítása előtt.",
"pkey": "Privát kulcs",
"pkey_desc": "A webes felhasználói felület és a Moonlight-ügyfél párosításához használt titkos kulcs. A legjobb kompatibilitás érdekében ez egy RSA-2048-as magánkulcs kell, hogy legyen.",
"port": "Port",
"port_alert_1": "A Sunshine nem használhat 1024 alatti portokat!",
"port_alert_2": "A 65535 feletti portok nem elérhetőek!",
"port_desc": "A Sunshine által használt portok családjának beállítása",
"port_http_port_note": "Ezt a portot használja a Moonlighthoz való csatlakozáshoz.",
"port_note": "Megjegyzés:",
"port_port": "Port",
"port_protocol": "Jegyzőkönyv",
"port_tcp": "TCP",
"port_udp": "UDP",
"port_warning": "A webes felhasználói felület internetre való kitettsége biztonsági kockázatot jelent! Saját felelősségre járjon el!",
"port_web_ui": "Webes felhasználói felület",
"qp": "Kvantálási paraméter",
"qp_desc": "Előfordulhat, hogy egyes eszközök nem támogatják a konstans bitsebességet. Ezeknél az eszközöknél a QP-t használják helyette. A magasabb érték nagyobb tömörítést, de kevesebb minőséget jelent.",
"qsv_coder": "QuickSync kódoló (H264)",
"qsv_preset": "QuickSync Előbeállítás",
"qsv_preset_fast": "gyors (alacsony minőség)",
"qsv_preset_faster": "gyorsabb (alacsonyabb minőség)",
"qsv_preset_medium": "közepes (alapértelmezett)",
"qsv_preset_slow": "lassú (jó minőségű)",
"qsv_preset_slower": "lassabb (jobb minőség)",
"qsv_preset_slowest": "leglassabb (legjobb minőség)",
"qsv_preset_veryfast": "leggyorsabb (legalacsonyabb minőség)",
"qsv_slow_hevc": "Lassú HEVC kódolás engedélyezése",
"qsv_slow_hevc_desc": "Ez lehetővé teheti a HEVC kódolást a régebbi Intel GPU-kon, ami a GPU nagyobb kihasználtsága és rosszabb teljesítménye árán érhető el.",
"restart_note": "A Sunshine újraindul, hogy alkalmazza a változtatásokat.",
"stream_audio": "Stream Audio",
"stream_audio_desc": "A hang streamelés vagy sem. Ennek kikapcsolása hasznos lehet fej nélküli kijelzők második monitorként történő streameléséhez.",
"sunshine_name": "Napsugár név",
"sunshine_name_desc": "A Holdfény által megjelenített név. Ha nincs megadva, a számítógép hostnevét használja a rendszer",
"sw_preset": "SW előbeállítások",
"sw_preset_desc": "A kódolási sebesség (kódolt képkockák másodpercenként) és a tömörítési hatékonyság (minőség a bitfolyamban lévő bitenként) közötti kompromisszum optimalizálása. Alapértelmezés szerint szupergyors.",
"sw_preset_fast": "gyors",
"sw_preset_faster": "gyorsabb",
"sw_preset_medium": "közepes",
"sw_preset_slow": "lassú",
"sw_preset_slower": "lassabb",
"sw_preset_superfast": "superfast (alapértelmezett)",
"sw_preset_ultrafast": "ultragyors",
"sw_preset_veryfast": "veryfast",
"sw_preset_veryslow": "veryslow",
"sw_tune": "SW Tune",
"sw_tune_animation": "animáció -- jó rajzfilmekhez; nagyobb deblockingot és több referencia képkockát használ",
"sw_tune_desc": "Hangolási lehetőségek, amelyek az előbeállítás után kerülnek alkalmazásra. Alapértelmezett beállítása nulla lappangási idő.",
"sw_tune_fastdecode": "fastdecode -- gyorsabb dekódolást tesz lehetővé bizonyos szűrők kikapcsolásával",
"sw_tune_film": "film -- kiváló minőségű filmtartalom esetén; csökkenti a deblockingot",
"sw_tune_grain": "szemcsés -- megőrzi a szemcseszerkezetet a régi, szemcsés filmanyagban",
"sw_tune_stillimage": "stillimage -- jó diavetítésszerű tartalomhoz",
"sw_tune_zerolatency": "zerolatency -- gyors kódoláshoz és alacsony késleltetésű streaminghez jó (alapértelmezett)",
"touchpad_as_ds4": "DS4 gamepad emulálása, ha a kliens gamepad érintőtábla jelenlétét jelzi.",
"touchpad_as_ds4_desc": "Ha letiltja, az érintőpad jelenlétét nem veszi figyelembe a rendszer a gamepad típusának kiválasztásakor.",
"upnp": "UPnP",
"upnp_desc": "Porttovábbítás automatikus konfigurálása az interneten keresztüli streaminghez",
"vaapi_strict_rc_buffer": "A H.264/HEVC képkocka-bitráta korlátok szigorú betartása AMD GPU-kon",
"vaapi_strict_rc_buffer_desc": "Ha engedélyezi ezt a beállítást, elkerülheti a hálózaton keresztül történő képkocka kiesést a jelenetváltások során, de a videó minősége csökkenhet mozgás közben.",
"virtual_sink": "Virtuális mosogató",
"virtual_sink_desc": "Kézzel adja meg a használni kívánt virtuális audioeszközt. Ha nincs megadva, az eszköz automatikusan kiválasztásra kerül. Az automatikus eszközkiválasztás használatához erősen ajánlott üresen hagyni ezt a mezőt!",
"virtual_sink_placeholder": "Steam streaming hangszórók",
"vt_coder": "VideoToolbox kódoló",
"vt_realtime": "VideoToolbox valós idejű kódolás",
"vt_software": "VideoToolbox szoftver kódolás",
"vt_software_allowed": "Engedélyezett",
"vt_software_forced": "Kényszerített",
"wan_encryption_mode": "WAN titkosítási mód",
"wan_encryption_mode_1": "Engedélyezve a támogatott ügyfelek számára (alapértelmezett)",
"wan_encryption_mode_2": "Minden ügyfél számára kötelező",
"wan_encryption_mode_desc": "Ez határozza meg, hogy az interneten keresztüli streaming során mikor kerül sor titkosításra. A titkosítás csökkentheti a streaming teljesítményét, különösen a kisebb teljesítményű hosztokon és klienseken."
},
"index": {
"description": "A Sunshine a Moonlight saját szervezésű játékstream hostja.",
"download": "Letöltés",
"installed_version_not_stable": "Ön a Sunshine kiadás előtti verzióját futtatja. Előfordulhatnak hibák vagy egyéb problémák. Kérjük, jelentse a felmerülő problémákat. Köszönjük, hogy segít a Sunshine jobbá tételében!",
"loading_latest": "Legújabb kiadás betöltése...",
"new_pre_release": "Elérhető egy új előzetes verzió!",
"new_stable": "Elérhető egy új stabil verzió!",
"startup_errors": "<b>Figyelem!</b> A Sunshine ezeket a hibákat észlelte az indítás során. <b>KIFEJEZETTEN AJÁNLJUK</b> ezek kijavítását a streaming előtt.",
"version_dirty": "Köszönjük, hogy segítesz a Sunshine jobb szoftverré tételében!",
"version_latest": "Ön a Sunshine legújabb verzióját futtatja",
"welcome": "Helló, Napsugár!"
},
"navbar": {
"applications": "Alkalmazások",
"configuration": "Konfiguráció",
"home": "Home",
"password": "Jelszó módosítása",
"pin": "PIN-KÓD",
"theme_auto": "Auto",
"theme_dark": "Sötét",
"theme_light": "Fény",
"toggle_theme": "Téma",
"troubleshoot": "Hibaelhárítás"
},
"password": {
"confirm_password": "Jelszó megerősítése",
"current_creds": "Jelenlegi megbízólevelek",
"new_creds": "Új megbízólevelek",
"new_username_desc": "Ha nincs megadva, a felhasználónév nem fog változni.",
"password_change": "Jelszó módosítása",
"success_msg": "A jelszó módosítása sikeresen megtörtént! Ez az oldal hamarosan újratöltődik, a böngésző kérni fogja az új hitelesítő adatokat."
},
"pin": {
"device_name": "Eszköz neve",
"pair_failure": "A párosítás sikertelen: Ellenőrizze, hogy a PIN kód helyesen lett-e beírva",
"pair_success": "Siker! Kérjük, ellenőrizze a Holdfényt a folytatáshoz",
"pin_pairing": "PIN párosítás",
"send": "Küldje el a",
"warning_msg": "Győződjön meg róla, hogy hozzáférése van a párosított ügyfélhez. Ez a szoftver teljes irányítást adhat a számítógépének, ezért legyen óvatos!"
},
"resource_card": {
"github_discussions": "GitHub Megbeszélések",
"legal": "Jogi",
"legal_desc": "A szoftver további használatával Ön elfogadja a következő dokumentumokban foglalt feltételeket.",
"license": "Licenc",
"lizardbyte_website": "LizardByte honlapja",
"resources": "Források",
"resources_desc": "Források a Napfényért!",
"third_party_notice": "Harmadik fél közleménye"
},
"troubleshooting": {
"dd_reset": "Tartós kijelzőkészülék beállításainak visszaállítása",
"dd_reset_desc": "Ha a Sunshine elakad a módosított kijelzőeszköz-beállítások visszaállítása során, akkor visszaállíthatja a beállításokat, és manuálisan folytathatja a kijelző állapotának visszaállítását.",
"dd_reset_error": "Hiba a perzisztencia visszaállítása közben!",
"dd_reset_success": "Sikeres visszaállítása kitartás!",
"force_close": "Bezárás erőltetése",
"force_close_desc": "Ha a Moonlight panaszt tesz egy jelenleg futó alkalmazás miatt, az alkalmazás kényszerített bezárása megoldja a problémát.",
"force_close_error": "Hiba az alkalmazás bezárásakor",
"force_close_success": "A pályázat sikeresen lezárult!",
"logs": "Naplók",
"logs_desc": "Nézd meg a Napfény által feltöltött naplókat",
"logs_find": "Találd meg...",
"restart_sunshine": "Napfény újraindítása",
"restart_sunshine_desc": "Ha a Sunshine nem működik megfelelően, próbálja meg újraindítani. Ez megszakítja a futó munkameneteket.",
"restart_sunshine_success": "A Sunshine újraindul",
"troubleshooting": "Hibaelhárítás",
"unpair_all": "Unpair All",
"unpair_all_error": "Hiba a párosítás feloldásakor",
"unpair_all_success": "Minden eszköz nincs párosítva.",
"unpair_desc": "Távolítsa el a párosított eszközöket. Az aktív munkamenettel rendelkező, különállóan nem párosított eszközök továbbra is kapcsolatban maradnak, de nem tudnak munkamenetet indítani vagy folytatni.",
"unpair_single_no_devices": "Nincsenek párosított eszközök.",
"unpair_single_success": "Előfordulhat azonban, hogy az eszköz(ök) még mindig aktív munkamenetben van(nak). A fenti \"Force Close\" (Bezárás kikényszerítése) gomb segítségével fejezze be a nyitott munkameneteket.",
"unpair_single_unknown": "Ismeretlen ügyfél",
"unpair_title": "Eszközök párosításának feloldása"
},
"welcome": {
"confirm_password": "Jelszó megerősítése",
"create_creds": "Mielőtt elkezdené, új felhasználónevet és jelszót kell létrehoznia a webes felhasználói felülethez való hozzáféréshez.",
"create_creds_alert": "A Sunshine webes felhasználói felületének eléréséhez az alábbi hitelesítő adatokra van szükség. Tartsa őket biztonságban, mivel soha többé nem fogja látni őket!",
"greeting": "Üdvözöljük a Sunshine-ban!",
"login": "Bejelentkezés",
"welcome_success": "Ez az oldal hamarosan újratöltődik, és a böngésző kérni fogja az új hitelesítő adatokat."
}
}

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Il file in cui vengono memorizzati i log attuali di Sunshine.",
"max_bitrate": "Bitrate Massimo",
"max_bitrate_desc": "Il bitrate massimo (in Kbps) in cui Sunshine codificherà il flusso. Se impostato a 0, utilizzerà sempre il bitrate richiesto dal Moonlight.",
"minimum_fps_target": "Obiettivo FPS Minimo",
"minimum_fps_target_desc": "Il FPS effettivo più basso può raggiungere un flusso. Un valore di 0 è trattato come circa la metà del FPS del flusso. È consigliata un'impostazione di 20 se il contenuto in streaming è 24 o 30 fps.",
"min_threads": "Conteggio Minimo Thread CPU",
"min_threads_desc": "Aumentare leggermente il valore riduce l'efficienza di codifica, ma di solito ne vale la pena per guadagnare l'impiego di più core della CPU per la codifica. Il valore ideale è il valore più basso che può codificare in modo affidabile in base le impostazioni di streaming desiderate sul vostro hardware.",
"misc": "Opzioni varie",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Sunshineの現在のログが保存されているファイル。",
"max_bitrate": "最大ビットレート",
"max_bitrate_desc": "Sunshineがストリームをエンコードする最大ビットレートKbps単位。0に設定すると、Moonlightが要求するビットレートが常に使用されます。",
"minimum_fps_target": "最小FPSターゲット",
"minimum_fps_target_desc": "ストリームが到達できる最も低い実効FPS。0の値は、ストリームのFPSの約半分として扱われます。 24または30fpsのコンテンツをストリーミングする場合は、20の設定をお勧めします。",
"min_threads": "最小CPUスレッド数",
"min_threads_desc": "値を大きくするとエンコーディングの効率はわずかに低下しますが、通常はエンコーディングにCPUコアをより多く使用する価値があります。 理想的な値は、ハードウェア上の希望のストリーミング設定で確実にエンコードできる最小値です。",
"misc": "その他のオプション",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Sunshine의 현재 로그가 저장된 파일입니다.",
"max_bitrate": "최대 비트",
"max_bitrate_desc": "Sunshine이 스트림을 인코딩할 최대 비트 전송률(Kbps)입니다. 0으로 설정하면 항상 Moonlight에서 요청한 비트레이트를 사용합니다.",
"minimum_fps_target": "최소 FPS 목표",
"minimum_fps_target_desc": "스트림이 도달할 수 있는 가장 낮은 유효 FPS입니다. 값이 0이면 스트림 FPS의 약 절반으로 간주됩니다. 24 또는 30fps 콘텐츠를 스트리밍하는 경우 20을 설정하는 것이 좋습니다.",
"min_threads": "최소 CPU 스레드 수",
"min_threads_desc": "이 값을 높이면 인코딩 효율이 약간 떨어지지만, 일반적으로 인코딩에 더 많은 CPU 코어를 사용할 수 있다는 점에서 그만한 가치가 있습니다. 이상적인 값은 하드웨어에서 원하는 스트리밍 설정으로 안정적으로 인코딩할 수 있는 가장 낮은 값입니다.",
"misc": "기타 옵션",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Plik, w którym przechowywane są bieżące dzienniki Sunshine.",
"max_bitrate": "Maksymalny Bitrate",
"max_bitrate_desc": "Maksymalny bitrate (w Kbps), który Sunshine zakoduje stream. Jeśli ustawiony na 0, zawsze będzie używał bitrate żądany przez Moonlight.",
"minimum_fps_target": "Minimalny cel FPS",
"minimum_fps_target_desc": "Najniższy efektywny strumień FPS może osiągnąć. Wartość 0 jest traktowana jako mniej więcej połowa FPS strumienia. Zalecane jest ustawienie 20 w przypadku zawartości strumienia 24 lub 30 fp.",
"min_threads": "Minimalna liczba wątków procesora",
"min_threads_desc": "Zwiększenie wartości nieznacznie zmniejsza wydajność kodowania, ale kompromis jest zwykle warty tego, aby uzyskać wykorzystanie większej liczby rdzeni procesora do kodowania. Idealną wartością jest najniższa wartość, która pozwala na niezawodne kodowanie przy pożądanych ustawieniach strumieniowania na posiadanym sprzęcie.",
"misc": "Różne opcje",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "O arquivo onde os logs atuais de Sunshine são armazenados.",
"max_bitrate": "Bitrate Máximo",
"max_bitrate_desc": "A taxa de bits máxima (em Kbps) que Sunshine irá codificar o stream. Se definido como 0, ele sempre usará a bitrate solicitada pela luar.",
"minimum_fps_target": "Alvo Mínimo de FPS",
"minimum_fps_target_desc": "O FPS mais baixo efetivo que o fluxo pode alcançar. Um valor de 0 é tratado como cerca de metade do FPS do fluxo. Uma configuração de 20 é recomendada se você transmitir conteúdo de 24 ou 30fps.",
"min_threads": "Contagem mínima de tópicos da CPU",
"min_threads_desc": "Aumentar o valor reduz ligeiramente a eficiência da codificação, mas a troca geralmente vale a pena para ganhar o uso de mais núcleos da CPU para codificação. O valor ideal é o mais baixo que pode codificar, de forma confiável, as configurações de streaming desejadas no seu hardware.",
"misc": "Opções diversas",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "O arquivo em que os registros atuais do Sunshine são armazenados.",
"max_bitrate": "Bitrate Máximo",
"max_bitrate_desc": "A taxa de bits máxima (em Kbps) que Sunshine irá codificar o stream. Se definido como 0, ele sempre usará a bitrate solicitada pela luar.",
"minimum_fps_target": "Alvo Mínimo de FPS",
"minimum_fps_target_desc": "O FPS mais baixo efetivo que o fluxo pode alcançar. Um valor de 0 é tratado como cerca de metade do FPS do fluxo. Uma configuração de 20 é recomendada se você transmitir conteúdo de 24 ou 30fps.",
"min_threads": "Contagem mínima de threads da CPU",
"min_threads_desc": "Aumentar o valor reduz ligeiramente a eficiência da codificação, mas a troca geralmente vale a pena para obter o uso de mais núcleos de CPU para codificação. O valor ideal é o menor valor que pode ser codificado de forma confiável nas configurações de streaming desejadas em seu hardware.",
"misc": "Opções diversas",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Файл, в котором хранятся текущие журналы Sunshine.",
"max_bitrate": "Максимальный битрейт",
"max_bitrate_desc": "Максимальный битрейт (в Кбит/с), которым Sunshine кодирует поток. Если установлено значение 0, он всегда будет использовать битрейт, запрошенный Moonlight.",
"minimum_fps_target": "Минимальная цель FPS",
"minimum_fps_target_desc": "Самый низкий эффективный FPS поток. Значение 0 рассматривается как примерно половина FPS потока. Параметр 20 рекомендуется, если вы транслируете содержимое 24 или 30fps.",
"min_threads": "Минимальное количество потоков ЦП",
"min_threads_desc": "Увеличение значения немного снижает эффективность кодирования, но полученный результат обычно стоит того, так как позволяет использовать больше ядер процессора для кодирования. Идеальное значение - это наименьшее значение, которое может надежно кодировать поток при желаемых настройках на вашем оборудовании.",
"misc": "Прочие параметры",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Filen där de aktuella loggarna av Sunshine lagras.",
"max_bitrate": "Maximal bithastighet",
"max_bitrate_desc": "Maximal bithastighet (i Kbps) som Sunshine kommer att koda strömmen på. Om satt till 0, kommer den alltid att använda den bithastighet som Moonlight begärt.",
"minimum_fps_target": "Minsta FPS mål",
"minimum_fps_target_desc": "Den lägsta effektiva FPS en ström kan nå. Värdet 0 behandlas som ungefär hälften av strömmens FPS. En inställning på 20 rekommenderas om du strömmar 24 eller 30 fps innehåll.",
"min_threads": "Minsta antal CPU-trådar",
"min_threads_desc": "Öka värdet något minskar kodningseffektivitet, men avvägningen är oftast värt det för att få användning av fler CPU-kärnor för kodning. Det ideala värdet är det lägsta värdet som tillförlitligt kan koda på dina önskade strömningsinställningar på din hårdvara.",
"misc": "Diverse alternativ",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Sunshine'ın geçerli günlüklerinin depolandığı dosya.",
"max_bitrate": "Maksimum Bit Hızı",
"max_bitrate_desc": "Sunshine'ın akışı kodlayacağı maksimum bit hızı (Kbps cinsinden). 0 olarak ayarlanırsa, her zaman Moonlight tarafından istenen bit hızını kullanır.",
"minimum_fps_target": "Minimum FPS Hedefi",
"minimum_fps_target_desc": "Bir akışın ulaşabileceği en düşük etkin FPS. 0 değeri, akışın FPS'sinin yaklaşık yarısı olarak kabul edilir. 24 veya 30 fps içerik yayınlıyorsanız 20 ayarı önerilir.",
"min_threads": "Minimum CPU İplik Sayısı",
"min_threads_desc": "Değerin artırılması kodlama verimliliğini biraz azaltır, ancak kodlama için daha fazla CPU çekirdeği kullanımı elde etmek için genellikle buna değer. İdeal değer, donanımınızda istediğiniz akış ayarlarında güvenilir bir şekilde kodlama yapabilen en düşük değerdir.",
"misc": "Çeşitli seçenekler",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Файл, у якому зберігаються поточні логи Sunshine.",
"max_bitrate": "Максимальний бітрейт",
"max_bitrate_desc": "Максимальний бітрейт (в Kbp), який здійснює кодування Sunshine на нього. Якщо встановлено в 0, то він завжди буде використовувати бітрейт із проханням Місячного світла.",
"minimum_fps_target": "Мінімум для FPS цільової цілі",
"minimum_fps_target_desc": "Найменш ефективний FPS потік може досягти. Значення 0 розглядається як приблизно половина FPS. Рекомендується налаштування 20, якщо транслюєте 24 або 30 fps вміст.",
"min_threads": "Мінімальна кількість потоків CPU",
"min_threads_desc": "Збільшення значення дещо знижує ефективність кодування, але цей компроміс зазвичай вартий того, щоб отримати можливість використовувати більше ядер CPU для кодування. Ідеальне значення - це найменше значення, яке може надійно кодувати за бажаних налаштувань стримінгу на вашому обладнанні.",
"misc": "Інші параметри",

View File

@@ -0,0 +1,457 @@
{
"_common": {
"apply": "Áp dụng",
"auto": "Tự động",
"autodetect": "Phát hiện tự động (đề xuất)",
"beta": "(phiên bản thử nghiệm)",
"cancel": "Hủy",
"disabled": "Tắt",
"disabled_def": "Tắt (mặc định)",
"disabled_def_cbox": "Mặc định: không bật",
"dismiss": "Bỏ qua",
"do_cmd": "Thực hiện lệnh",
"elevated": "Nâng cao",
"enabled": "Đã bật",
"enabled_def": "Bật (mặc định)",
"enabled_def_cbox": "Mặc định: đã bật",
"error": "Lỗi!",
"note": "Lưu ý:",
"password": "Mật khẩu",
"run_as": "Chạy với quyền admin",
"save": "Lưu",
"see_more": "Xem thêm",
"success": "Thành công!",
"undo_cmd": "Hủy lệnh",
"username": "Tên đăng nhập",
"warning": "Cảnh báo!"
},
"apps": {
"actions": "Hành động",
"add_cmds": "Thêm lệnh",
"add_new": "Thêm mới",
"app_name": "Tên ứng dụng",
"app_name_desc": "Tên ứng dụng, hiển thị trên Moonlight",
"applications_desc": "Ứng dụng chỉ được làm mới khi Client được khởi động lại.",
"applications_title": "Ứng dụng",
"auto_detach": "Không ngắt stream nếu ứng dụng thoát trong thời gian ngắn",
"auto_detach_desc": "Tùy chọn này sẽ cố gắng tự động nhận diện các ứng dụng dạng launcher, thường thoát ngay sau khi mở một chương trình khác hoặc một phiên bản khác của chính nó.\nKhi phát hiện launcher như vậy, hệ thống sẽ xử lý nó như một ứng dụng tách biệt để tránh ngắt kết nối stream.",
"cmd": "Lệnh",
"cmd_desc": "Ứng dụng chính để khởi động. Nếu để trống, sẽ không khởi động ứng dụng nào.",
"cmd_note": "Nếu đường dẫn đến tệp thực thi lệnh chứa khoảng trắng (space), bạn phải đặt nó trong dấu ngoặc kép.",
"cmd_prep_desc": "Danh sách các lệnh sẽ được chạy trước hoặc sau ứng dụng này. Nếu bất kỳ lệnh chuẩn bị nào bị lỗi, quá trình khởi chạy ứng dụng sẽ bị hủy.",
"cmd_prep_name": "Chuẩn bị lệnh",
"covers_found": "Bìa đã tìm thấy",
"delete": "Xóa",
"detached_cmds": "Lệnh độc lập",
"detached_cmds_add": "Thêm lệnh tách rời",
"detached_cmds_desc": "Danh sách các lệnh cần chạy ở chế độ nền.",
"detached_cmds_note": "Nếu đường dẫn đến tệp thực thi lệnh chứa khoảng trắng (space), bạn phải đặt nó trong dấu ngoặc kép.",
"edit": "Chỉnh sửa",
"env_app_id": "ID ứng dụng",
"env_app_name": "Tên ứng dụng",
"env_client_audio_config": "Cấu hình âm thanh được yêu cầu bởi client (2.0/5.1/7.1)",
"env_client_enable_sops": "Client yêu cầu tùy chọn tối ưu hóa trò chơi cho việc streaming tối ưu (có/không)",
"env_client_fps": "Tốc độ khung hình mỗi giây (FPS) mà client yêu cầu (số nguyên)",
"env_client_gcmap": "The requested gamepad mask, in a bitset/bitfield format (int)",
"env_client_hdr": "HDR được kích hoạt bởi client (true/false)",
"env_client_height": "Chiều cao do client yêu cầu (số nguyên)",
"env_client_host_audio": "Client yêu cầu âm thanh từ host (có/không)",
"env_client_width": "Chiều rộng được yêu cầu bởi client (số nguyên)",
"env_displayplacer_example": "Ví dụ - Công cụ hiển thị cho Tự động hóa độ phân giải:",
"env_qres_example": "Ví dụ - QRes cho Tự động hóa Quyết định:",
"env_qres_path": "Đường dẫn qres",
"env_var_name": "Tên biến",
"env_vars_about": "Về biến môi trường",
"env_vars_desc": "Tất cả các lệnh đều được gán các biến môi trường sau theo mặc định:",
"env_xrandr_example": "Ví dụ - Xrandr cho tự động hóa độ phân giải:",
"exit_timeout": "Thời gian chờ thoát",
"exit_timeout_desc": "Số giây chờ đợi cho tất cả các tiến trình của ứng dụng thoát ra một cách trơn tru khi được yêu cầu thoát. Nếu không được thiết lập, giá trị mặc định là chờ tối đa 5 giây. Nếu được thiết lập thành 0, ứng dụng sẽ bị kết thúc ngay lập tức.",
"find_cover": "Tìm chỗ trú ẩn",
"global_prep_desc": "Bật/Tắt việc thực thi các lệnh chuẩn bị toàn cầu cho ứng dụng này.",
"global_prep_name": "Lệnh chuẩn bị toàn cầu",
"image": "Hình ảnh",
"image_desc": "Đường dẫn đến biểu tượng/hình ảnh sẽ được gửi đến client. Hình ảnh phải là file PNG. Nếu không được thiết lập, Sunshine sẽ gửi hình ảnh mặc định.",
"loading": "Đang tải...",
"name": "Tên",
"output_desc": "Tệp chứa kết quả đầu ra của lệnh. Nếu không được chỉ định, kết quả đầu ra sẽ bị bỏ qua.",
"output_name": "Đầu ra",
"run_as_desc": "Điều này có thể cần thiết cho một số ứng dụng yêu cầu quyền quản trị viên (Administrator) để hoạt động đúng cách.",
"wait_all": "Tiếp tục phát trực tuyến cho đến khi tất cả các tiến trình của ứng dụng kết thúc.",
"wait_all_desc": "Quá trình streaming này sẽ tiếp tục cho đến khi tất cả các tiến trình được ứng dụng khởi chạy đã kết thúc. Khi tùy chọn này không được chọn, stream sẽ dừng lại khi tiến trình chính của ứng dụng kết thúc, ngay cả khi các tiến trình khác của ứng dụng vẫn đang chạy.",
"working_dir": "Thư mục làm việc",
"working_dir_desc": "Thư mục làm việc cần được truyền vào quá trình. Ví dụ, một số ứng dụng sử dụng thư mục làm việc để tìm kiếm các tệp cấu hình. Nếu không được thiết lập, Sunshine sẽ mặc định sử dụng thư mục cha của lệnh."
},
"config": {
"adapter_name": "Adapter Name",
"adapter_name_desc_linux_1": "Chọn GPU cụ thể để sử dụng cho quá trình ghi hình.",
"adapter_name_desc_linux_2": "Tìm tất cả các thiết bị hỗ trợ VAAPI",
"adapter_name_desc_linux_3": "Thay thế ``renderD129`` bằng thiết bị từ trên để liệt kê tên và khả năng của thiết bị. Để được hỗ trợ bởi Sunshine, thiết bị cần phải có ít nhất:",
"adapter_name_desc_windows": "Chỉ định GPU cụ thể để sử dụng cho quá trình capture Nếu không được thiết lập, GPU sẽ được chọn tự động. Chúng tôi khuyến nghị để để trống trường này để sử dụng tính năng chọn GPU tự động! Lưu ý: GPU này phải có màn hình kết nối và đang bật nguồn. Các giá trị phù hợp có thể được tìm thấy bằng cách sử dụng lệnh sau:",
"adapter_name_placeholder_windows": "Radeon RX 580 Series",
"add": "Thêm",
"address_family": "Kiểu địa chỉ mạng",
"address_family_both": "IPv4 và IPv6",
"address_family_desc": "Đặt loại địa chỉ mạng được sử dụng bởi Sunshine",
"address_family_ipv4": "Chỉ hỗ trợ IPv4",
"always_send_scancodes": "Luôn gửi mã quét",
"always_send_scancodes_desc": "Gửi mã quét (scancodes) giúp tăng tính tương thích với các trò chơi và ứng dụng, nhưng có thể dẫn đến nhập liệu bàn phím không chính xác từ một số client không sử dụng bố cục bàn phím tiếng Anh Mỹ. Bật tùy chọn này nếu nhập liệu bàn phím không hoạt động trong một số ứng dụng. Tắt tùy chọn này nếu các phím trên client tạo ra nhập liệu sai trên host.",
"amd_coder": "Mã hóa AMF (H264)",
"amd_coder_desc": "Cho phép bạn chọn mã hóa entropy để ưu tiên chất lượng hoặc tốc độ mã hóa. Chỉ hỗ trợ H.264.",
"amd_enforce_hrd": "Thiết bị giải mã tham chiếu giả định AMF (HRD)",
"amd_enforce_hrd_desc": "Tăng cường các giới hạn kiểm soát tốc độ để đáp ứng yêu cầu của mô hình HRD. Điều này giúp giảm đáng kể hiện tượng tràn bitrate, nhưng có thể gây ra các lỗi mã hóa hoặc giảm chất lượng trên một số thẻ.",
"amd_preanalysis": "Phân tích tiền xử lý AMF",
"amd_preanalysis_desc": "Điều này cho phép thực hiện phân tích trước để kiểm soát tốc độ, có thể cải thiện chất lượng nhưng đồng thời làm tăng độ trễ mã hóa.",
"amd_quality": "Chất lượng AMF",
"amd_quality_balanced": "cân bằng -- cân bằng (mặc định)",
"amd_quality_desc": "Điều này điều chỉnh sự cân bằng giữa tốc độ encode và chất lượng.",
"amd_quality_group": "Cài đặt chất lượng AMF",
"amd_quality_quality": "chất lượng -- ưu tiên chất lượng",
"amd_quality_speed": "Tốc độ -- Ưu tiên tốc độ",
"amd_rc": "Kiểm soát tốc độ AMF",
"amd_rc_cbr": "cbr -- Tốc độ bit cố định (được khuyến nghị nếu HRD được bật)",
"amd_rc_cqp": "cqp -- Chế độ QP cố định",
"amd_rc_desc": "Điều này kiểm soát phương pháp điều chỉnh tốc độ để đảm bảo chúng ta không vượt quá mục tiêu bitrate của khách hàng. 'cqp' không phù hợp cho việc điều chỉnh bitrate, và các tùy chọn khác ngoài 'vbr_latency' phụ thuộc vào HRD Enforcement để giúp hạn chế việc vượt quá bitrate.",
"amd_rc_group": "Cài đặt kiểm soát tốc độ AMF",
"amd_rc_vbr_latency": "vbr_latency -- Tốc độ bit biến đổi có giới hạn độ trễ (được khuyến nghị nếu HRD bị vô hiệu hóa; mặc định)",
"amd_rc_vbr_peak": "vbr_peak -- Tốc độ bit biến đổi có giới hạn đỉnh",
"amd_usage": "Sử dụng AMF",
"amd_usage_desc": "Điều này thiết lập cấu hình encode cơ bản. Tất cả các tùy chọn được trình bày bên dưới sẽ ghi đè lên một phần của cấu hình sử dụng, nhưng có thêm các thiết lập ẩn được áp dụng mà không thể cấu hình ở nơi khác.",
"amd_usage_lowlatency": "lowlatency - độ trễ thấp (nhanh nhất)",
"amd_usage_lowlatency_high_quality": "lowlatency_high_quality - độ trễ thấp, chất lượng cao (nhanh)",
"amd_usage_transcoding": "Chuyển mã -- Chuyển mã (chậm nhất)",
"amd_usage_ultralowlatency": "ultralowlatency - độ trễ cực thấp (nhanh nhất; mặc định)",
"amd_usage_webcam": "webcam -- webcam (chậm)",
"amd_vbaq": "Cơ chế nén thích nghi theo mức độ thay đổi hình ảnh (VBAQ) của AMF",
"amd_vbaq_desc": "Hệ thống thị giác của con người thường ít nhạy cảm hơn với các hiện tượng nhiễu trong các vùng có kết cấu phức tạp. Trong chế độ VBAQ, độ biến thiên của pixel được sử dụng để chỉ ra độ phức tạp của kết cấu không gian, cho phép bộ mã hóa phân bổ nhiều bit hơn cho các vùng mịn hơn. Kích hoạt tính năng này mang lại cải thiện về chất lượng hình ảnh chủ quan với một số nội dung.",
"apply_note": "Nhấp vào 'Áp dụng' để khởi động lại Sunshine và áp dụng các thay đổi. Điều này sẽ kết thúc tất cả các phiên đang chạy.",
"audio_sink": "Bộ thu âm thanh",
"audio_sink_desc_linux": "Tên của thiết bị âm thanh được sử dụng cho vòng lặp âm thanh (Audio Loopback). Nếu bạn không chỉ định biến này, pulseaudio sẽ chọn thiết bị monitor mặc định. Bạn có thể tìm tên của thiết bị âm thanh bằng một trong hai lệnh sau:",
"audio_sink_desc_macos": "Tên của thiết bị đầu ra âm thanh được sử dụng cho Audio Loopback. Sunshine chỉ có thể truy cập micro trên macOS do hạn chế của hệ thống. Để phát âm thanh hệ thống thông qua Soundflower hoặc BlackHole.",
"audio_sink_desc_windows": "Chọn thủ công thiết bị âm thanh cụ thể để ghi âm. Nếu không được thiết lập, thiết bị sẽ được chọn tự động. Chúng tôi khuyến nghị mạnh mẽ để để trống trường này để sử dụng tính năng chọn thiết bị tự động! Nếu bạn có nhiều thiết bị âm thanh có tên giống nhau, bạn có thể lấy ID thiết bị bằng cách sử dụng lệnh sau:",
"audio_sink_placeholder_macos": "Lỗ đen 2ch",
"audio_sink_placeholder_windows": "Loa (Thiết bị âm thanh độ nét cao)",
"av1_mode": "Hỗ trợ AV1",
"av1_mode_0": "Sunshine sẽ quảng cáo hỗ trợ cho AV1 dựa trên khả năng của bộ mã hóa (được khuyến nghị)",
"av1_mode_1": "Sunshine sẽ không quảng cáo hỗ trợ cho AV1.",
"av1_mode_2": "Sunshine sẽ quảng cáo hỗ trợ cho AV1 Main 8-bit profile.",
"av1_mode_3": "Sunshine sẽ quảng cáo hỗ trợ cho các cấu hình AV1 Main 8-bit và 10-bit (HDR).",
"av1_mode_desc": "Cho phép khách hàng yêu cầu luồng video AV1 Main 8-bit hoặc 10-bit. AV1 đòi hỏi nhiều tài nguyên CPU hơn để mã hóa, do đó việc kích hoạt tính năng này có thể làm giảm hiệu suất khi sử dụng mã hóa phần mềm.",
"back_button_timeout": "Thời gian chờ cho nút Home/Hướng dẫn",
"back_button_timeout_desc": "Nếu nút Back/Select được giữ nhấn trong số mili giây đã chỉ định, thao tác nhấn nút Home/Guide sẽ được mô phỏng. Nếu giá trị được đặt nhỏ hơn 0 (mặc định), việc giữ nút Back/Select sẽ không mô phỏng thao tác nhấn nút Home/Guide.",
"capture": "Buộc sử dụng phương pháp chụp cụ thể",
"capture_desc": "Ở chế độ tự động, Sunshine sẽ sử dụng trình điều khiển đầu tiên hoạt động. NvFBC yêu cầu trình điều khiển NVIDIA đã được vá.",
"cert": "Chứng chỉ",
"cert_desc": "Chứng chỉ được sử dụng cho việc ghép nối giao diện người dùng web (web UI) và ứng dụng Moonlight. Để đảm bảo tương thích tốt nhất, chứng chỉ này nên sử dụng khóa công khai RSA-2048.",
"channels": "Số lượng khách hàng kết nối tối đa",
"channels_desc_1": "Ánh sáng mặt trời cho phép một phiên phát trực tuyến duy nhất được chia sẻ đồng thời với nhiều khách hàng.",
"channels_desc_2": "Một số bộ mã hóa phần cứng có thể có các hạn chế làm giảm hiệu suất khi xử lý nhiều luồng.",
"coder_cabac": "cabac -- Mã hóa nhị phân thích ứng theo ngữ cảnh - Chất lượng cao hơn",
"coder_cavlc": "cavlc -- Mã hóa độ dài biến đổi thích ứng với ngữ cảnh - Giải mã nhanh hơn",
"configuration": "Cấu hình",
"controller": "Bật điều khiển bằng gamepad",
"controller_desc": "Cho phép khách điều khiển hệ thống chủ bằng gamepad / bộ điều khiển.",
"credentials_file": "Tệp thông tin xác thực",
"credentials_file_desc": "Lưu tên người dùng/mật khẩu riêng biệt với tệp trạng thái của Sunshine.",
"dd_config_ensure_active": "Bật màn hình tự động",
"dd_config_ensure_only_display": "Tắt các màn hình khác và chỉ kích hoạt màn hình đã chỉ định.",
"dd_config_ensure_primary": "Kích hoạt màn hình tự động và thiết lập nó làm màn hình chính.",
"dd_config_label": "Cấu hình thiết bị",
"dd_config_revert_delay": "Thời gian trễ khôi phục cấu hình",
"dd_config_revert_delay_desc": "Thời gian trễ bổ sung (tính bằng mili giây) để chờ trước khi khôi phục cấu hình khi ứng dụng đã bị đóng hoặc phiên làm việc cuối cùng đã kết thúc. Mục đích chính là cung cấp quá trình chuyển đổi mượt mà hơn khi chuyển đổi nhanh giữa các ứng dụng.",
"dd_config_revert_on_disconnect": "Khôi phục cài đặt gốc khi ngắt kết nối",
"dd_config_revert_on_disconnect_desc": "Khôi phục cấu hình khi tất cả các client ngắt kết nối thay vì khi ứng dụng đóng hoặc phiên làm việc cuối cùng kết thúc.",
"dd_config_verify_only": "Kiểm tra xem màn hình đã được bật chưa.",
"dd_hdr_option": "HDR",
"dd_hdr_option_auto": "Bật/tắt chế độ HDR theo yêu cầu của khách hàng (mặc định)",
"dd_hdr_option_disabled": "Không thay đổi cài đặt HDR.",
"dd_mode_remapping": "Chuyển đổi chế độ hiển thị",
"dd_mode_remapping_add": "Thêm mục remapping",
"dd_mode_remapping_desc_1": "Chỉ định các mục remapping để thay đổi độ phân giải và/hoặc tần số làm mới yêu cầu sang các giá trị khác.",
"dd_mode_remapping_desc_2": "Danh sách được duyệt từ trên xuống dưới và kết quả khớp đầu tiên được sử dụng.",
"dd_mode_remapping_desc_3": "Các trường \"Yêu cầu\" có thể để trống để phù hợp với bất kỳ giá trị nào được yêu cầu.",
"dd_mode_remapping_desc_4_final_values_mixed": "Phải chỉ định ít nhất một trường \"Final\". Độ phân giải hoặc tần số làm mới không được chỉ định sẽ không được thay đổi.",
"dd_mode_remapping_desc_4_final_values_non_mixed": "Trường \"Final\" phải được chỉ định và không được để trống.",
"dd_mode_remapping_desc_5_sops_mixed_only": "Tùy chọn \"Tối ưu hóa cài đặt trò chơi\" phải được bật trong ứng dụng Moonlight, nếu không các mục có trường độ phân giải được chỉ định sẽ bị bỏ qua.",
"dd_mode_remapping_desc_5_sops_resolution_only": "Tùy chọn \"Tối ưu hóa cài đặt trò chơi\" phải được bật trong ứng dụng Moonlight, nếu không quá trình ánh xạ sẽ bị bỏ qua.",
"dd_mode_remapping_final_refresh_rate": "Tần số làm mới cuối cùng",
"dd_mode_remapping_final_resolution": "Quyết định cuối cùng",
"dd_mode_remapping_requested_fps": "Tốc độ khung hình yêu cầu (FPS)",
"dd_mode_remapping_requested_resolution": "Giải pháp được yêu cầu",
"dd_options_header": "Các tùy chọn hiển thị nâng cao",
"dd_refresh_rate_option": "Tần số làm mới",
"dd_refresh_rate_option_auto": "Sử dụng giá trị FPS do khách hàng cung cấp (mặc định)",
"dd_refresh_rate_option_disabled": "Không thay đổi tần số làm mới.",
"dd_refresh_rate_option_manual": "Sử dụng tần số làm mới được nhập thủ công",
"dd_refresh_rate_option_manual_desc": "Nhập tần số làm mới cần sử dụng",
"dd_resolution_option": "Quyết định",
"dd_resolution_option_auto": "Sử dụng độ phân giải do khách hàng cung cấp (mặc định)",
"dd_resolution_option_disabled": "Không thay đổi độ phân giải",
"dd_resolution_option_manual": "Sử dụng độ phân giải được nhập thủ công",
"dd_resolution_option_manual_desc": "Nhập độ phân giải cần sử dụng",
"dd_resolution_option_ogs_desc": "Tùy chọn \"Tối ưu hóa cài đặt trò chơi\" phải được bật trên ứng dụng Moonlight để tính năng này hoạt động.",
"dd_wa_hdr_toggle_delay_desc_1": "Khi sử dụng thiết bị hiển thị ảo (VDD) cho việc phát trực tuyến, màu HDR có thể hiển thị không chính xác. Sunshine có thể thử khắc phục vấn đề này bằng cách tắt HDR và sau đó bật lại.",
"dd_wa_hdr_toggle_delay_desc_2": "Nếu giá trị được đặt là 0, tính năng khắc phục sự cố sẽ bị vô hiệu hóa (mặc định). Nếu giá trị nằm trong khoảng từ 0 đến 3000 mili giây, Sunshine sẽ tắt HDR, chờ trong khoảng thời gian đã chỉ định và sau đó bật HDR lại. Thời gian chờ khuyến nghị là khoảng 500 mili giây trong hầu hết các trường hợp.",
"dd_wa_hdr_toggle_delay_desc_3": "KHÔNG sử dụng giải pháp tạm thời này trừ khi bạn thực sự gặp vấn đề với HDR, vì nó ảnh hưởng trực tiếp đến thời gian bắt đầu phát trực tiếp!",
"dd_wa_hdr_toggle_delay": "Giải pháp thay thế cho HDR có độ tương phản cao",
"ds4_back_as_touchpad_click": "Quay lại bản đồ/Chọn bằng cách nhấp chuột vào bàn di chuột",
"ds4_back_as_touchpad_click_desc": "Khi ép buộc mô phỏng DS4, gán nút Back/Select cho thao tác nhấp chuột trên bàn di chuột.",
"encoder": "Bắt buộc sử dụng bộ mã hóa cụ thể",
"encoder_desc": "Buộc sử dụng bộ mã hóa cụ thể, nếu không Sunshine sẽ tự động chọn tùy chọn tốt nhất có sẵn. Lưu ý: Nếu bạn chỉ định bộ mã hóa phần cứng trên Windows, nó phải trùng khớp với GPU mà màn hình được kết nối.",
"encoder_software": "Phần mềm",
"external_ip": "Địa chỉ IP bên ngoài",
"external_ip_desc": "Nếu không được cung cấp địa chỉ IP bên ngoài, Sunshine sẽ tự động phát hiện địa chỉ IP bên ngoài.",
"fec_percentage": "Tỷ lệ phần trăm FEC",
"fec_percentage_desc": "Tỷ lệ gói tin sửa lỗi trên mỗi gói tin dữ liệu trong mỗi khung hình video. Giá trị cao hơn có thể bù đắp cho việc mất gói tin mạng nhiều hơn, nhưng đổi lại sẽ làm tăng sử dụng băng thông.",
"ffmpeg_auto": "Tự động -- để ffmpeg quyết định (mặc định)",
"file_apps": "Tệp ứng dụng",
"file_apps_desc": "Thư mục chứa các ứng dụng hiện tại của Sunshine.",
"file_state": "Tệp của Nhà nước",
"file_state_desc": "Tệp chứa trạng thái hiện tại của Sunshine",
"gamepad": "Loại bộ điều khiển trò chơi mô phỏng",
"gamepad_auto": "Tùy chọn chọn tự động",
"gamepad_desc": "Chọn loại gamepad muốn mô phỏng trên máy chủ.",
"gamepad_ds4": "DS4 (PlayStation 4)",
"gamepad_ds4_manual": "Các tùy chọn lựa chọn cho DS4",
"gamepad_ds5": "DS5 (PS5)",
"gamepad_switch": "Nintendo Pro (Switch)",
"gamepad_manual": "Các tùy chọn DS4 thủ công",
"gamepad_x360": "X360 (Xbox 360)",
"gamepad_xone": "XOne (Xbox One)",
"global_prep_cmd": "Chuẩn bị lệnh",
"global_prep_cmd_desc": "Cấu hình danh sách các lệnh cần thực thi trước hoặc sau khi chạy bất kỳ ứng dụng nào. Nếu bất kỳ lệnh chuẩn bị nào trong danh sách bị thất bại, quá trình khởi chạy ứng dụng sẽ bị hủy bỏ.",
"hevc_mode": "Hỗ trợ HEVC",
"hevc_mode_0": "Sunshine sẽ quảng cáo hỗ trợ cho HEVC dựa trên khả năng của bộ mã hóa (được khuyến nghị)",
"hevc_mode_1": "Sunshine sẽ không quảng cáo hỗ trợ cho HEVC.",
"hevc_mode_2": "Sunshine sẽ quảng cáo hỗ trợ cho HEVC Main profile.",
"hevc_mode_3": "Sunshine sẽ quảng cáo hỗ trợ cho các cấu hình HEVC Main và Main10 (HDR).",
"hevc_mode_desc": "Cho phép khách hàng yêu cầu luồng video HEVC Main hoặc HEVC Main10. HEVC đòi hỏi nhiều tài nguyên CPU hơn khi mã hóa, do đó việc kích hoạt tính năng này có thể làm giảm hiệu suất khi sử dụng mã hóa phần mềm.",
"high_resolution_scrolling": "Hỗ trợ cuộn với độ phân giải cao",
"high_resolution_scrolling_desc": "Khi được bật, Sunshine sẽ truyền các sự kiện cuộn có độ phân giải cao từ các ứng dụng Moonlight. Tính năng này có thể hữu ích để tắt cho các ứng dụng cũ có tốc độ cuộn quá nhanh khi sử dụng sự kiện cuộn có độ phân giải cao.",
"install_steam_audio_drivers": "Cài đặt trình điều khiển âm thanh Steam",
"install_steam_audio_drivers_desc": "Nếu Steam đã được cài đặt, trình điều khiển loa phát trực tuyến Steam sẽ được cài đặt tự động để hỗ trợ âm thanh vòm 5.1/7.1 và tắt âm thanh của ứng dụng chủ.",
"key_repeat_delay": "Thời gian trễ lặp lại phím",
"key_repeat_delay_desc": "Điều chỉnh tốc độ lặp lại của các phím. Thời gian trễ ban đầu (tính bằng mili giây) trước khi các phím bắt đầu lặp lại.",
"key_repeat_frequency": "Tần suất lặp lại phím",
"key_repeat_frequency_desc": "Tần suất lặp lại của các phím mỗi giây. Tùy chọn này có thể điều chỉnh và hỗ trợ số thập phân.",
"key_rightalt_to_key_win": "Gán phím Alt bên phải cho phím Windows",
"key_rightalt_to_key_win_desc": "Có thể bạn không thể gửi phím Windows từ Moonlight trực tiếp. Trong trường hợp đó, có thể hữu ích khi làm cho Sunshine nghĩ rằng phím Alt bên phải là phím Windows.",
"keyboard": "Bật nhập liệu bằng bàn phím",
"keyboard_desc": "Cho phép khách truy cập điều khiển hệ thống chủ thông qua bàn phím.",
"lan_encryption_mode": "Chế độ mã hóa mạng LAN",
"lan_encryption_mode_1": "Đã kích hoạt cho các khách hàng được hỗ trợ",
"lan_encryption_mode_2": "Yêu cầu đối với tất cả khách hàng",
"lan_encryption_mode_desc": "Điều này xác định thời điểm mã hóa sẽ được sử dụng khi truyền phát qua mạng nội bộ của bạn. Mã hóa có thể làm giảm hiệu suất truyền phát, đặc biệt là trên các máy chủ và thiết bị khách có cấu hình yếu.",
"locale": "Vùng",
"locale_desc": "Ngôn ngữ giao diện người dùng được sử dụng cho Sunshine.",
"log_level": "Mức ghi nhật ký",
"log_level_0": "Chi tiết",
"log_level_1": "Gỡ lỗi",
"log_level_2": "Thông tin",
"log_level_3": "Cảnh báo",
"log_level_4": "Lỗi",
"log_level_5": "Chết người",
"log_level_6": "Không có",
"log_level_desc": "Mức ghi nhật ký tối thiểu được in ra tiêu chuẩn đầu ra.",
"log_path": "Đường dẫn tệp nhật ký",
"log_path_desc": "Tệp chứa các bản ghi hiện tại của Sunshine.",
"max_bitrate": "Tốc độ bit tối đa",
"max_bitrate_desc": "Tốc độ bit tối đa (đơn vị Kbps) mà Sunshine sẽ mã hóa luồng. Nếu đặt thành 0, nó sẽ luôn sử dụng tốc độ bit được yêu cầu bởi Moonlight.",
"minimum_fps_target": "Mục tiêu FPS tối thiểu",
"minimum_fps_target_desc": "Tốc độ khung hình hiệu quả thấp nhất mà luồng có thể đạt được. Giá trị 0 được coi là khoảng một nửa tốc độ khung hình của luồng. Nên thiết lập giá trị 20 nếu bạn phát nội dung có tốc độ khung hình 24 hoặc 30fps.",
"min_threads": "Số luồng CPU tối thiểu",
"min_threads_desc": "Tăng giá trị một chút sẽ làm giảm hiệu suất mã hóa, nhưng sự đánh đổi này thường đáng giá để tận dụng thêm các lõi CPU cho quá trình mã hóa. Giá trị lý tưởng là giá trị thấp nhất có thể mã hóa một cách đáng tin cậy ở cài đặt phát trực tuyến mong muốn trên phần cứng của bạn.",
"misc": "Các tùy chọn khác",
"motion_as_ds4": "Mô phỏng tay cầm DS4 nếu tay cầm của client báo cáo có cảm biến chuyển động.",
"motion_as_ds4_desc": "Nếu bị vô hiệu hóa, cảm biến chuyển động sẽ không được tính đến trong quá trình chọn loại gamepad.",
"mouse": "Bật nhập liệu chuột",
"mouse_desc": "Cho phép khách truy cập điều khiển hệ thống chủ bằng chuột.",
"native_pen_touch": "Hỗ trợ bút cảm ứng và chạm gốc",
"native_pen_touch_desc": "Khi được bật, Sunshine sẽ truyền các sự kiện bút/chạm gốc từ các ứng dụng Moonlight. Tính năng này có thể hữu ích để tắt cho các ứng dụng cũ không hỗ trợ bút/chạm gốc.",
"notify_pre_releases": "Thông báo trước khi phát hành",
"notify_pre_releases_desc": "Có muốn nhận thông báo về các phiên bản thử nghiệm mới của Sunshine không?",
"nvenc_h264_cavlc": "Ưu tiên CAVLC hơn CABAC trong H.264",
"nvenc_h264_cavlc_desc": "Hình thức đơn giản hơn của mã hóa entropy. CAVLC cần khoảng 10% băng thông bit cao hơn để đạt được chất lượng tương đương. Chỉ áp dụng cho các thiết bị giải mã rất cũ.",
"nvenc_latency_over_power": "Ưu tiên độ trễ mã hóa thấp hơn so với tiết kiệm năng lượng.",
"nvenc_latency_over_power_desc": "Sunshine yêu cầu tốc độ đồng hồ GPU tối đa khi phát trực tiếp để giảm độ trễ mã hóa. Việc tắt tính năng này không được khuyến nghị vì có thể dẫn đến độ trễ mã hóa tăng đáng kể.",
"nvenc_opengl_vulkan_on_dxgi": "Hiển thị OpenGL/Vulkan trên nền DXGI",
"nvenc_opengl_vulkan_on_dxgi_desc": "Ánh sáng mặt trời không thể ghi lại các chương trình OpenGL và Vulkan toàn màn hình ở tốc độ khung hình đầy đủ trừ khi chúng được hiển thị trên DXGI. Đây là cài đặt hệ thống và sẽ được khôi phục lại sau khi chương trình Ánh sáng mặt trời kết thúc.",
"nvenc_preset": "Cài đặt sẵn hiệu suất",
"nvenc_preset_1": "(nhanh nhất, mặc định)",
"nvenc_preset_7": "(chậm nhất)",
"nvenc_preset_desc": "Các giá trị cao hơn cải thiện tỷ lệ nén (chất lượng ở cùng bitrate) nhưng làm tăng độ trễ mã hóa. Nên thay đổi chỉ khi bị giới hạn bởi mạng hoặc bộ giải mã, nếu không, hiệu quả tương tự có thể đạt được bằng cách tăng bitrate.",
"nvenc_realtime_hags": "Sử dụng ưu tiên thời gian thực trong lịch trình GPU được tăng tốc phần cứng.",
"nvenc_realtime_hags_desc": "Hiện tại, trình điều khiển NVIDIA có thể bị treo trong trình mã hóa khi tùy chọn HAGS được bật, ưu tiên thời gian thực được sử dụng và sử dụng VRAM gần đạt mức tối đa. Tắt tùy chọn này sẽ hạ ưu tiên xuống mức cao, tránh tình trạng treo nhưng làm giảm hiệu suất ghi hình khi GPU đang hoạt động nặng.",
"nvenc_spatial_aq": "Chất lượng không khí theo không gian",
"nvenc_spatial_aq_desc": "Gán giá trị QP cao hơn cho các vùng phẳng trong video. Được khuyến nghị bật khi phát trực tuyến ở tốc độ bit thấp.",
"nvenc_twopass": "Chế độ hai lần quét",
"nvenc_twopass_desc": "Thêm bước mã hóa sơ bộ. Điều này cho phép phát hiện nhiều vector chuyển động hơn, phân phối bitrate đều hơn trong khung hình và tuân thủ nghiêm ngặt hơn các giới hạn bitrate. Không nên tắt tính năng này vì có thể dẫn đến việc vượt quá bitrate tạm thời và mất gói dữ liệu sau đó.",
"nvenc_twopass_disabled": "Tắt (nhanh nhất, không được khuyến nghị)",
"nvenc_twopass_full_res": "Độ phân giải cao (chậm hơn)",
"nvenc_twopass_quarter_res": "Độ phân giải theo quý (nhanh hơn, mặc định)",
"nvenc_vbv_increase": "Tỷ lệ phần trăm tăng của VBV/HRD trong một khung hình",
"nvenc_vbv_increase_desc": "Theo mặc định, Sunshine sử dụng VBV/HRD một khung hình, có nghĩa là kích thước khung hình video đã mã hóa không được vượt quá tỷ lệ bit yêu cầu chia cho tần số khung hình yêu cầu. Nới lỏng hạn chế này có thể mang lại lợi ích và hoạt động như bitrate biến đổi độ trễ thấp, nhưng cũng có thể dẫn đến mất gói nếu mạng không có dung lượng đệm đủ để xử lý các đỉnh bitrate. Giá trị tối đa được chấp nhận là 400, tương ứng với giới hạn kích thước khung hình video đã mã hóa tăng gấp 5 lần.",
"origin_web_ui_allowed": "Giao diện người dùng web gốc được phép",
"origin_web_ui_allowed_desc": "Nguồn gốc của địa chỉ điểm cuối từ xa không bị từ chối truy cập vào giao diện người dùng web (Web UI).",
"origin_web_ui_allowed_lan": "Chỉ những người trong mạng LAN mới có thể truy cập giao diện người dùng web.",
"origin_web_ui_allowed_pc": "Chỉ máy chủ cục bộ (localhost) mới có thể truy cập giao diện người dùng web (Web UI).",
"origin_web_ui_allowed_wan": "Bất kỳ ai cũng có thể truy cập giao diện người dùng web (Web UI).",
"output_name_desc_unix": "Trong quá trình khởi động Sunshine, bạn sẽ thấy danh sách các màn hình được phát hiện. Lưu ý: Bạn cần sử dụng giá trị ID bên trong dấu ngoặc đơn. Dưới đây là một ví dụ; kết quả thực tế có thể được tìm thấy trong tab Khắc phục sự cố.",
"output_name_desc_windows": "Chỉ định thủ công ID thiết bị hiển thị để sử dụng cho việc ghi hình. Nếu không được thiết lập, thiết bị hiển thị chính sẽ được ghi hình. Lưu ý: Nếu bạn đã chỉ định GPU ở trên, thiết bị hiển thị này phải được kết nối với GPU đó. Trong quá trình khởi động Sunshine, bạn sẽ thấy danh sách các thiết bị hiển thị được phát hiện. Dưới đây là một ví dụ; kết quả thực tế có thể được tìm thấy trong tab Khắc phục sự cố.",
"output_name_unix": "Hiển thị số",
"output_name_windows": "Hiển thị ID thiết bị",
"ping_timeout": "Thời gian chờ ping",
"ping_timeout_desc": "Thời gian chờ (tính bằng mili giây) trước khi ngừng truyền dữ liệu từ Moonlight.",
"pkey": "Khóa riêng",
"pkey_desc": "Khóa riêng tư được sử dụng cho việc ghép nối giữa giao diện web và ứng dụng Moonlight. Để đảm bảo tương thích tốt nhất, khóa riêng tư này nên là khóa RSA-2048.",
"port": "Cảng",
"port_alert_1": "Sunshine không thể sử dụng các cổng dưới 1024!",
"port_alert_2": "Các cổng trên 65535 không khả dụng!",
"port_desc": "Đặt nhóm cổng được sử dụng bởi Sunshine",
"port_http_port_note": "Sử dụng cổng này để kết nối với Moonlight.",
"port_note": "Lưu ý",
"port_port": "Cảng",
"port_protocol": "Quy trình",
"port_tcp": "Giao thức truyền tải liên kết (TCP)",
"port_udp": "UDP (Giao thức dữ liệu không định hướng)",
"port_warning": "Việc phơi bày giao diện người dùng web (Web UI) ra internet là một rủi ro bảo mật! Hãy tiếp tục với rủi ro của riêng bạn!",
"port_web_ui": "Giao diện người dùng web",
"qp": "Tham số lượng tử hóa",
"qp_desc": "Một số thiết bị có thể không hỗ trợ Tốc độ bit cố định (Constant Bit Rate). Đối với những thiết bị này, QP (Quality Profile) sẽ được sử dụng thay thế. Giá trị cao hơn có nghĩa là nén nhiều hơn, nhưng chất lượng sẽ thấp hơn.",
"qsv_coder": "QuickSync Coder (H.264)",
"qsv_preset": "Cài đặt nhanh QuickSync",
"qsv_preset_fast": "Nhanh (chất lượng thấp)",
"qsv_preset_faster": "nhanh hơn (chất lượng thấp hơn)",
"qsv_preset_medium": "Trung bình (mặc định)",
"qsv_preset_slow": "chậm (chất lượng tốt)",
"qsv_preset_slower": "chậm hơn (chất lượng tốt hơn)",
"qsv_preset_slowest": "chậm nhất (chất lượng tốt nhất)",
"qsv_preset_veryfast": "nhanh nhất (chất lượng thấp nhất)",
"qsv_slow_hevc": "Cho phép mã hóa HEVC chậm",
"qsv_slow_hevc_desc": "Điều này có thể cho phép mã hóa HEVC trên các GPU Intel cũ hơn, nhưng sẽ làm tăng sử dụng GPU và giảm hiệu suất.",
"restart_note": "Sunshine đang khởi động lại để áp dụng các thay đổi.",
"stream_audio": "Phát trực tiếp âm thanh",
"stream_audio_desc": "Có nên phát âm thanh hay không. Tắt tính năng này có thể hữu ích khi phát video trên các màn hình không có giao diện người dùng (headless displays) như màn hình phụ.",
"sunshine_name": "Tên Ánh Dương",
"sunshine_name_desc": "Tên hiển thị bởi Moonlight. Nếu không được chỉ định, tên máy chủ của PC sẽ được sử dụng.",
"sw_preset": "Cài đặt sẵn cho SW",
"sw_preset_desc": "Tối ưu hóa sự cân bằng giữa tốc độ mã hóa (số khung hình được mã hóa mỗi giây) và hiệu quả nén (chất lượng trên mỗi bit trong luồng bit). Mặc định là siêu nhanh.",
"sw_preset_fast": "nhanh",
"sw_preset_faster": "nhanh hơn",
"sw_preset_medium": "trung bình",
"sw_preset_slow": "chậm",
"sw_preset_slower": "chậm hơn",
"sw_preset_superfast": "siêu nhanh (mặc định)",
"sw_preset_ultrafast": "siêu nhanh",
"sw_preset_veryfast": "rất nhanh",
"sw_preset_veryslow": "rất chậm",
"sw_tune": "Điều chỉnh phần mềm",
"sw_tune_animation": "Hoạt hình -- phù hợp cho phim hoạt hình; sử dụng thuật toán giảm nhiễu cao hơn và nhiều khung tham chiếu hơn.",
"sw_tune_desc": "Các tùy chọn điều chỉnh, được áp dụng sau khi thiết lập trước. Mặc định là zerolatency.",
"sw_tune_fastdecode": "fastdecode -- cho phép giải mã nhanh hơn bằng cách vô hiệu hóa một số bộ lọc.",
"sw_tune_film": "Phim -- dùng cho nội dung phim chất lượng cao; giảm hiện tượng vỡ khối.",
"sw_tune_grain": "hạt -- giữ nguyên cấu trúc hạt trong vật liệu phim cũ, có hạt.",
"sw_tune_stillimage": "Hình ảnh tĩnh -- Phù hợp cho nội dung dạng trình chiếu.",
"sw_tune_zerolatency": "zerolatency -- phù hợp cho mã hóa nhanh và phát trực tuyến có độ trễ thấp (mặc định)",
"touchpad_as_ds4": "Mô phỏng tay cầm DS4 nếu tay cầm của client báo có bàn di chuột.",
"touchpad_as_ds4_desc": "Nếu tính năng này bị tắt, sự hiện diện của bàn di chuột sẽ không được xem xét trong quá trình chọn loại gamepad.",
"upnp": "UPnP (Tự động phát hiện và chia sẻ thiết bị)",
"upnp_desc": "Tự động cấu hình chuyển tiếp cổng để phát trực tuyến qua Internet.",
"vaapi_strict_rc_buffer": "Thực thi nghiêm ngặt giới hạn tốc độ khung hình cho H.264/HEVC trên GPU AMD.",
"vaapi_strict_rc_buffer_desc": "Bật tùy chọn này có thể tránh tình trạng mất khung hình trên mạng trong quá trình chuyển cảnh, nhưng chất lượng video có thể bị giảm trong quá trình chuyển động.",
"virtual_sink": "Bồn rửa ảo",
"virtual_sink_desc": "Chỉ định thủ công thiết bị âm thanh ảo để sử dụng. Nếu không được thiết lập, thiết bị sẽ được chọn tự động. Chúng tôi khuyến nghị mạnh mẽ để để trống trường này để sử dụng tính năng chọn thiết bị tự động!",
"virtual_sink_placeholder": "Loa phát trực tuyến Steam",
"vt_coder": "VideoToolbox Coder",
"vt_realtime": "VideoToolbox Mã hóa thời gian thực",
"vt_software": "Phần mềm VideoToolbox cho mã hóa video",
"vt_software_allowed": "Được phép",
"vt_software_forced": "Bắt buộc",
"wan_encryption_mode": "Chế độ mã hóa WAN",
"wan_encryption_mode_1": "Được kích hoạt cho các khách hàng được hỗ trợ (mặc định)",
"wan_encryption_mode_2": "Yêu cầu đối với tất cả khách hàng",
"wan_encryption_mode_desc": "Điều này xác định thời điểm mã hóa sẽ được sử dụng khi truyền phát qua Internet. Mã hóa có thể làm giảm hiệu suất truyền phát, đặc biệt là trên các máy chủ và thiết bị khách có cấu hình yếu."
},
"index": {
"description": "Sunshine là một nền tảng phát trực tiếp game tự chủ cho Moonlight.",
"download": "Tải xuống",
"installed_version_not_stable": "Bạn đang sử dụng phiên bản thử nghiệm của Sunshine. Bạn có thể gặp phải lỗi hoặc các vấn đề khác. Vui lòng báo cáo bất kỳ vấn đề nào bạn gặp phải. Cảm ơn bạn đã giúp Sunshine trở thành phần mềm tốt hơn!",
"loading_latest": "Đang tải phiên bản mới nhất...",
"new_pre_release": "Phiên bản thử nghiệm mới đã có sẵn!",
"new_stable": "Phiên bản ổn định mới đã có sẵn!",
"startup_errors": "<b>Lưu ý!</b> Sunshine đã phát hiện các lỗi sau đây trong quá trình khởi động. Chúng tôi <b>KHUYẾN NGHỊ MẠNH MẼ bạn</b> khắc phục các lỗi này trước khi bắt đầu phát trực tuyến.",
"version_dirty": "Cảm ơn bạn đã giúp Sunshine trở thành phần mềm tốt hơn!",
"version_latest": "Bạn đang sử dụng phiên bản mới nhất của Sunshine.",
"welcome": "Chào nắng!"
},
"navbar": {
"applications": "Ứng dụng",
"configuration": "Cấu hình",
"home": "Trang chủ",
"password": "Thay đổi mật khẩu",
"pin": "Mã PIN",
"theme_auto": "Tự động",
"theme_dark": "Tối",
"theme_light": "Ánh sáng",
"toggle_theme": "Chủ đề",
"troubleshoot": "Khắc phục sự cố"
},
"password": {
"confirm_password": "Xác nhận mật khẩu",
"current_creds": "Chứng chỉ hiện tại",
"new_creds": "Chứng chỉ mới",
"new_username_desc": "Nếu không được chỉ định, tên người dùng sẽ không thay đổi.",
"password_change": "Thay đổi mật khẩu",
"success_msg": "Mật khẩu đã được thay đổi thành công! Trang này sẽ được tải lại trong giây lát, trình duyệt của bạn sẽ yêu cầu bạn nhập thông tin đăng nhập mới."
},
"pin": {
"device_name": "Tên thiết bị",
"pair_failure": "Kết nối không thành công: Vui lòng kiểm tra xem mã PIN đã được nhập chính xác chưa.",
"pair_success": "Thành công! Vui lòng kiểm tra Moonlight để tiếp tục.",
"pin_pairing": "Kết nối PIN",
"send": "Gửi",
"warning_msg": "Đảm bảo bạn có quyền truy cập vào máy tính mà bạn đang kết nối. Phần mềm này có thể cho phép kiểm soát hoàn toàn máy tính của bạn, vì vậy hãy cẩn thận!"
},
"resource_card": {
"github_discussions": "Thảo luận trên GitHub",
"legal": "Pháp lý",
"legal_desc": "Bằng cách tiếp tục sử dụng phần mềm này, bạn đồng ý với các điều khoản và điều kiện được quy định trong các tài liệu sau đây.",
"license": "Giấy phép",
"lizardbyte_website": "Trang web LizardByte",
"resources": "Tài nguyên",
"resources_desc": "Tài nguyên cho Ánh nắng!",
"third_party_notice": "Thông báo từ bên thứ ba"
},
"troubleshooting": {
"dd_reset": "Đặt lại cài đặt thiết bị hiển thị cố định",
"dd_reset_desc": "Nếu Sunshine gặp sự cố khi cố gắng khôi phục cài đặt thiết bị hiển thị đã thay đổi, bạn có thể đặt lại cài đặt và tiếp tục khôi phục trạng thái hiển thị thủ công.",
"dd_reset_error": "Lỗi xảy ra trong quá trình khôi phục trạng thái lưu trữ!",
"dd_reset_success": "Thành công trong việc thiết lập lại sự kiên trì!",
"force_close": "Buộc đóng ứng dụng",
"force_close_desc": "Nếu Moonlight báo lỗi về một ứng dụng đang chạy, việc buộc đóng ứng dụng đó sẽ khắc phục sự cố.",
"force_close_error": "Lỗi khi đóng ứng dụng",
"force_close_success": "Đơn đăng ký đã được đóng thành công!",
"logs": "Nhật ký",
"logs_desc": "Xem các bản ghi được tải lên bởi Sunshine",
"logs_find": "Tìm...",
"restart_sunshine": "Khởi động lại Sunshine",
"restart_sunshine_desc": "Nếu Sunshine không hoạt động đúng cách, bạn có thể thử khởi động lại ứng dụng. Điều này sẽ kết thúc tất cả các phiên đang chạy.",
"restart_sunshine_success": "Sunshine đang khởi động lại.",
"troubleshooting": "Khắc phục sự cố",
"unpair_all": "Bỏ ghép tất cả",
"unpair_all_error": "Lỗi khi hủy ghép nối",
"unpair_all_success": "Tất cả các thiết bị đã ngắt kết nối.",
"unpair_desc": "Hãy ngắt kết nối các thiết bị đã ghép nối. Các thiết bị đã ghép nối nhưng đang có phiên hoạt động sẽ vẫn kết nối, nhưng không thể bắt đầu hoặc tiếp tục phiên.",
"unpair_single_no_devices": "Không có thiết bị nào được ghép đôi.",
"unpair_single_success": "Tuy nhiên, thiết bị (các thiết bị) có thể vẫn đang trong phiên hoạt động. Nhấn nút 'Buộc đóng' ở trên để kết thúc tất cả các phiên đang mở.",
"unpair_single_unknown": "Khách hàng không xác định",
"unpair_title": "Ngắt kết nối thiết bị"
},
"welcome": {
"confirm_password": "Xác nhận mật khẩu",
"create_creds": "Trước khi bắt đầu, chúng tôi cần bạn tạo một tên người dùng và mật khẩu mới để truy cập vào giao diện người dùng web (Web UI).",
"create_creds_alert": "Các thông tin đăng nhập sau đây là cần thiết để truy cập giao diện người dùng web của Sunshine. Hãy giữ chúng an toàn, vì bạn sẽ không bao giờ thấy chúng nữa!",
"greeting": "Chào mừng đến với Sunshine!",
"login": "Đăng nhập",
"welcome_success": "Trang này sẽ được tải lại trong giây lát, trình duyệt của bạn sẽ yêu cầu bạn nhập lại thông tin đăng nhập."
}
}

View File

@@ -256,6 +256,8 @@
"log_path_desc": "Sunshine 当前日志存储的文件。",
"max_bitrate": "最大比特率",
"max_bitrate_desc": "Sunshine 的最大比特率(Kbps) 将编码流。如果设置为 0它将始终使用月亮请求的比特率。",
"minimum_fps_target": "最低FPS 目标",
"minimum_fps_target_desc": "一个流可以达到的最低有效的FPS值。0的值被处理为流的 FPS 的大约一半。 如果您流 24 或 30 fps 内容,建议设置为 20。",
"min_threads": "最低 CPU 线程数",
"min_threads_desc": "提高该值会略微降低编码效率,但为了获得更多的 CPU 内核用于编码,通常是值得的。理想值是在您的硬件配置上以所需的串流设置进行可靠编码的最低值。",
"misc": "杂项选项",

View File

@@ -256,6 +256,8 @@
"log_path_desc": "儲存目前 Sunshine 記錄的檔案。",
"max_bitrate": "最大位元率",
"max_bitrate_desc": "Sunshine 會以最大位元率(單位為 Kbps來編碼串流。如果設為0則會使用Moonlight所要求的位元率。",
"minimum_fps_target": "最低 FPS 目標",
"minimum_fps_target_desc": "串流可達到的最低有效 FPS。0 的值會被視為串流 FPS 的一半左右。如果您串流 24 或 30fps 的內容,建議設定為 20。",
"min_threads": "最低 CPU 線程數",
"min_threads_desc": "增加該值會稍微降低編碼效率,但為了能使用更多 CPU 核心進行編碼,這樣的折衷通常是值得的。理想的值是在您的硬體上,能以您所需的串流設定進行可靠編碼的最低值。",
"misc": "其他選項",

View File

@@ -27,8 +27,7 @@ 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
# shellcheck disable=SC2066 # don't split words as we already know this will be a single directory
for i in "${empty_dir}"; do
for i in "${empty_dir}"; do # don't split words as we already know this will be a single directory
echo "Removing empty directory: ${i}"
rmdir "${i}"
done

View File

@@ -4,7 +4,6 @@
*/
#include "../tests_common.h"
#include <format>
#include <src/config.h>
#include <src/display_device.h>
#include <src/rtsp.h>
@@ -474,7 +473,7 @@ namespace {
} else {
const auto [manual_res] = std::get<manual_value_t<res_t>>(input_res);
video_config.dd.resolution_option = manual;
video_config.dd.manual_resolution = std::format("{}x{}", static_cast<int>(manual_res.m_width), static_cast<int>(manual_res.m_height));
video_config.dd.manual_resolution = std::to_string(manual_res.m_width) + "x"s + std::to_string(manual_res.m_height);
}
}

View File

@@ -4,7 +4,6 @@
*/
#include "../tests_common.h"
#include <format>
#include <src/file_handler.h>
struct FileHandlerParentDirectoryTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
@@ -80,13 +79,13 @@ Hey, hey, hey!
TEST_P(FileHandlerTests, WriteFileTest) {
auto [fileNum, content] = GetParam();
const std::string fileName = std::format("write_file_test_{}.txt", fileNum);
std::string fileName = "write_file_test_" + std::to_string(fileNum) + ".txt";
EXPECT_EQ(file_handler::write_file(fileName.c_str(), content), 0);
}
TEST_P(FileHandlerTests, ReadFileTest) {
auto [fileNum, content] = GetParam();
const std::string fileName = std::format("write_file_test_{}.txt", fileNum);
std::string fileName = "write_file_test_" + std::to_string(fileNum) + ".txt";
EXPECT_EQ(file_handler::read_file(fileName.c_str()), content);
}

View File

@@ -5,7 +5,6 @@
#include "../tests_common.h"
#include "../tests_log_checker.h"
#include <format>
#include <random>
#include <src/logging.h>
@@ -40,7 +39,7 @@ TEST_P(LogLevelsTest, PutMessage) {
std::random_device rand_dev;
std::mt19937_64 rand_gen(rand_dev());
auto test_message = std::format("{}{}", rand_gen(), rand_gen());
auto test_message = std::to_string(rand_gen()) + std::to_string(rand_gen());
BOOST_LOG(logger) << test_message;
ASSERT_TRUE(log_checker::line_contains(log_file, test_message));

View File

@@ -5,7 +5,7 @@
#define INITGUID
// platform includes
#include <Audioclient.h>
#include <audioclient.h>
#include <codecvt>
#include <iostream>
#include <locale>

View File

@@ -3,10 +3,9 @@
* @brief Handles launching Sunshine.exe into user sessions as SYSTEM
*/
#define WIN32_LEAN_AND_MEAN
#include <format>
#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
@@ -52,9 +51,9 @@ DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, L
}
HANDLE CreateJobObjectForChildProcess() {
HANDLE job_handle = CreateJobObjectW(nullptr, nullptr);
HANDLE job_handle = CreateJobObjectW(NULL, NULL);
if (!job_handle) {
return nullptr;
return NULL;
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_limit_info = {};
@@ -69,7 +68,7 @@ HANDLE CreateJobObjectForChildProcess() {
if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &job_limit_info, sizeof(job_limit_info))) {
CloseHandle(job_handle);
return nullptr;
return NULL;
}
return job_handle;
@@ -77,16 +76,16 @@ HANDLE CreateJobObjectForChildProcess() {
LPPROC_THREAD_ATTRIBUTE_LIST AllocateProcThreadAttributeList(DWORD attribute_count) {
SIZE_T size;
InitializeProcThreadAttributeList(nullptr, attribute_count, 0, &size);
InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size);
auto list = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, size);
if (list == nullptr) {
return nullptr;
if (list == NULL) {
return NULL;
}
if (!InitializeProcThreadAttributeList(list, attribute_count, 0, &size)) {
HeapFree(GetProcessHeap(), 0, list);
return nullptr;
return NULL;
}
return list;
@@ -95,14 +94,14 @@ LPPROC_THREAD_ATTRIBUTE_LIST AllocateProcThreadAttributeList(DWORD attribute_cou
HANDLE DuplicateTokenForSession(DWORD console_session_id) {
HANDLE current_token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &current_token)) {
return nullptr;
return NULL;
}
// Duplicate our own LocalSystem token
HANDLE new_token;
if (!DuplicateTokenEx(current_token, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &new_token)) {
if (!DuplicateTokenEx(current_token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &new_token)) {
CloseHandle(current_token);
return nullptr;
return NULL;
}
CloseHandle(current_token);
@@ -110,7 +109,7 @@ HANDLE DuplicateTokenForSession(DWORD console_session_id) {
// Change the duplicated token to the console session ID
if (!SetTokenInformation(new_token, TokenSessionId, &console_session_id, sizeof(console_session_id))) {
CloseHandle(new_token);
return nullptr;
return NULL;
}
return new_token;
@@ -124,21 +123,21 @@ HANDLE OpenLogFileHandle() {
wcscat_s(log_file_name, L"sunshine.log");
// The file handle must be inheritable for our child process to use it
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), nullptr, TRUE};
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), NULL, TRUE};
// Overwrite the old sunshine.log
return CreateFileW(log_file_name, GENERIC_WRITE, FILE_SHARE_READ, &security_attributes, CREATE_ALWAYS, 0, nullptr);
return CreateFileW(log_file_name, GENERIC_WRITE, FILE_SHARE_READ, &security_attributes, CREATE_ALWAYS, 0, NULL);
}
bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
WCHAR module_path[MAX_PATH];
GetModuleFileNameW(nullptr, module_path, _countof(module_path));
GetModuleFileNameW(NULL, module_path, _countof(module_path));
std::wstring command;
command += L'"';
command += module_path;
command += L'"';
command += std::format(L" --terminate {}", pid);
command += L" --terminate " + std::to_wstring(pid);
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(startup_info);
@@ -147,7 +146,7 @@ bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
// Execute ourselves as a detached process in the user session with the --terminate argument.
// This will allow us to attach to Sunshine's console and send it a Ctrl-C event.
PROCESS_INFORMATION process_info;
if (!CreateProcessAsUserW(console_token, module_path, (LPWSTR) command.c_str(), nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, nullptr, nullptr, &startup_info, &process_info)) {
if (!CreateProcessAsUserW(console_token, module_path, (LPWSTR) command.c_str(), NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, NULL, NULL, &startup_info, &process_info)) {
return false;
}
@@ -167,8 +166,8 @@ bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, nullptr);
if (service_status_handle == nullptr) {
service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, NULL);
if (service_status_handle == NULL) {
// Nothing we can really do here but terminate ourselves
ExitProcess(GetLastError());
return;
@@ -185,8 +184,8 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
SetServiceStatus(service_status_handle, &service_status);
// Create a manual-reset stop event
stop_event = CreateEventA(nullptr, TRUE, FALSE, nullptr);
if (stop_event == nullptr) {
stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
if (stop_event == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -195,8 +194,8 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
// Create an auto-reset session change event
session_change_event = CreateEventA(nullptr, FALSE, FALSE, nullptr);
if (session_change_event == nullptr) {
session_change_event = CreateEventA(NULL, FALSE, FALSE, NULL);
if (session_change_event == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -218,13 +217,13 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
startup_info.StartupInfo.cb = sizeof(startup_info);
startup_info.StartupInfo.lpDesktop = (LPWSTR) L"winsta0\\default";
startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
startup_info.StartupInfo.hStdInput = nullptr;
startup_info.StartupInfo.hStdInput = NULL;
startup_info.StartupInfo.hStdOutput = log_file_handle;
startup_info.StartupInfo.hStdError = log_file_handle;
// Allocate an attribute list with space for 2 entries
startup_info.lpAttributeList = AllocateProcThreadAttributeList(2);
if (startup_info.lpAttributeList == nullptr) {
if (startup_info.lpAttributeList == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -233,7 +232,7 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
// Only allow Sunshine.exe to inherit the log file handle, not all inheritable handles
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &log_file_handle, sizeof(log_file_handle), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &log_file_handle, sizeof(log_file_handle), NULL, NULL);
// Tell SCM we're running (and stoppable now)
service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE;
@@ -249,22 +248,22 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
auto console_token = DuplicateTokenForSession(console_session_id);
if (console_token == nullptr) {
if (console_token == NULL) {
continue;
}
// Job objects cannot span sessions, so we must create one for each process
auto job_handle = CreateJobObjectForChildProcess();
if (job_handle == nullptr) {
if (job_handle == NULL) {
CloseHandle(console_token);
continue;
}
// Start Sunshine.exe inside our job object
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &job_handle, sizeof(job_handle), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &job_handle, sizeof(job_handle), NULL, NULL);
PROCESS_INFORMATION process_info;
if (!CreateProcessAsUserW(console_token, L"Sunshine.exe", nullptr, nullptr, nullptr, TRUE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, (LPSTARTUPINFOW) &startup_info, &process_info)) {
if (!CreateProcessAsUserW(console_token, L"Sunshine.exe", NULL, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFOW) &startup_info, &process_info)) {
CloseHandle(console_token);
CloseHandle(job_handle);
continue;
@@ -327,7 +326,7 @@ int DoGracefulTermination(DWORD pid) {
}
// Disable our own Ctrl-C handling
SetConsoleCtrlHandler(nullptr, TRUE);
SetConsoleCtrlHandler(NULL, TRUE);
// Send a Ctrl-C event to Sunshine
if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) {
@@ -340,7 +339,7 @@ int DoGracefulTermination(DWORD pid) {
int main(int argc, char *argv[]) {
static const SERVICE_TABLE_ENTRY service_table[] = {
{(LPSTR) SERVICE_NAME, ServiceMain},
{nullptr, nullptr}
{NULL, NULL}
};
// Check if this is a reinvocation of ourselves to send Ctrl-C to Sunshine.exe
@@ -352,7 +351,7 @@ int main(int argc, char *argv[]) {
// We want to use the directory where Sunshine.exe is located instead of system32.
// This requires stripping off 2 path components: the file name and the last folder
WCHAR module_path[MAX_PATH];
GetModuleFileNameW(nullptr, module_path, _countof(module_path));
GetModuleFileNameW(NULL, module_path, _countof(module_path));
for (auto i = 0; i < 2; i++) {
auto last_sep = wcsrchr(module_path, '\\');
if (last_sep) {