diff --git a/.flake8 b/.flake8 index 2d028b2d..2ea73951 100644 --- a/.flake8 +++ b/.flake8 @@ -1,7 +1,6 @@ [flake8] filename = - *.py, - *.pys + *.py max-line-length = 120 extend-exclude = venv/ diff --git a/.github/workflows/common-lint.yml b/.github/workflows/common-lint.yml new file mode 100644 index 00000000..4a62b245 --- /dev/null +++ b/.github/workflows/common-lint.yml @@ -0,0 +1,245 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# Common linting. + +name: common lint + +on: + pull_request: + branches: [master] + types: [opened, synchronize, reopened] + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +jobs: + lint: + name: Common Lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade \ + pip \ + setuptools \ + wheel \ + cmakelang \ + flake8 \ + nb-clean \ + nbqa[toolchain] + + - name: C++ - find files + id: cpp_files + run: | + # find files + found_files=$(find . -type f \ + -iname "*.c" -o \ + -iname "*.cpp" -o \ + -iname "*.h" -o \ + -iname "*.hpp" -o \ + -iname "*.m" -o \ + -iname "*.mm" \ + ) + ignore_files=$(find . -type f -iname ".clang-format-ignore") + + # Loop through each C++ file + for file in $found_files; do + for ignore_file in $ignore_files; do + ignore_directory=$(dirname "$ignore_file") + # if directory of ignore_file is beginning of file + if [[ "$file" == "$ignore_directory"* ]]; then + echo "ignoring file: ${file}" + found_files="${found_files//${file}/}" + break 1 + fi + done + done + + # remove empty lines + found_files=$(echo "$found_files" | sed '/^\s*$/d') + + echo "found cpp files: ${found_files}" + + # do not quote to keep this as a single line + echo found_files=${found_files} >> $GITHUB_OUTPUT + + - name: C++ - Clang format lint + if: always() && steps.cpp_files.outputs.found_files + uses: DoozyX/clang-format-lint-action@v0.18 + with: + source: ${{ steps.cpp_files.outputs.found_files }} + extensions: 'c,cpp,h,hpp,m,mm' + style: file + inplace: false + + - name: CMake - find files + id: cmake_files + if: always() + run: | + # find files + found_files=$(find . -type f -iname "CMakeLists.txt" -o -iname "*.cmake") + ignore_files=$(find . -type f -iname ".cmake-lint-ignore") + + # Loop through each C++ file + for file in $found_files; do + for ignore_file in $ignore_files; do + ignore_directory=$(dirname "$ignore_file") + # if directory of ignore_file is beginning of file + if [[ "$file" == "$ignore_directory"* ]]; then + echo "ignoring file: ${file}" + found_files="${found_files//${file}/}" + break 1 + fi + done + done + + # remove empty lines + found_files=$(echo "$found_files" | sed '/^\s*$/d') + + echo "found cmake files: ${found_files}" + + # do not quote to keep this as a single line + echo found_files=${found_files} >> $GITHUB_OUTPUT + + - name: CMake - cmake-lint + if: always() && steps.cmake_files.outputs.found_files + run: | + cmake-lint --line-width 120 --tab-size 4 ${{ steps.cmake_files.outputs.found_files }} + + - name: Docker - find files + id: dokcer_files + if: always() + run: | + found_files=$(find . -type f -iname "Dockerfile" -o -iname "*.dockerfile") + + echo "found_files: ${found_files}" + + # do not quote to keep this as a single line + echo found_files=${found_files} >> $GITHUB_OUTPUT + + - name: Docker - hadolint + if: always() && steps.dokcer_files.outputs.found_files + run: | + docker pull hadolint/hadolint + + # create hadolint config file + cat < .hadolint.yaml + --- + ignored: + - DL3008 + - DL3013 + - DL3016 + - DL3018 + - DL3028 + - DL3059 + EOF + + failed=0 + failed_files="" + + for file in ${{ steps.dokcer_files.outputs.found_files }}; do + echo "::group::${file}" + docker run --rm -i \ + -e "NO_COLOR=0" \ + -e "HADOLINT_VERBOSE=1" \ + -v $(pwd)/.hadolint.yaml:/.config/hadolint.yaml \ + hadolint/hadolint < $file || { + failed=1 + failed_files="$failed_files $file" + } + echo "::endgroup::" + done + + if [ $failed -ne 0 ]; then + echo "::error:: hadolint failed for the following files: $failed_files" + exit 1 + fi + + - name: Python - flake8 + if: always() + run: | + python -m flake8 \ + --color=always \ + --verbose + + - name: Python - nbqa flake8 + if: always() + run: | + python -m nbqa flake8 \ + --color=always \ + --verbose \ + . + + - name: Python - nb-clean + if: always() + run: | + output=$(find . -name '*.ipynb' -exec nb-clean check {} \;) + + # fail if there are any issues + if [ -n "$output" ]; then + echo "$output" + exit 1 + fi + + - name: YAML - find files + id: yaml_files + if: always() + run: | + # space separated list of files + FILES=.clang-format + + # empty placeholder + found_files="" + + for FILE in ${FILES}; do + if [ -f "$FILE" ] + then + found_files="$found_files $FILE" + fi + done + + echo "found_files=${found_files}" >> $GITHUB_OUTPUT + + - name: YAML - yamllint + id: yamllint + if: always() + uses: ibiqlik/action-yamllint@v3 + with: + # https://yamllint.readthedocs.io/en/stable/configuration.html#default-configuration + config_data: | + extends: default + rules: + comments: + level: error + document-start: + level: error + line-length: + max: 120 + new-line-at-end-of-file: + level: error + new-lines: + type: unix + truthy: + # GitHub uses "on" for workflow event triggers + # .clang-format file has options of "Yes" "No" that will be caught by this, so changed to "warning" + allowed-values: ['true', 'false', 'on'] + check-keys: true + level: warning + file_or_dir: . ${{ steps.yaml_files.outputs.found_files }} + + - name: YAML - log + if: always() && steps.yamllint.outcome == 'failure' + run: | + cat "${{ steps.yamllint.outputs.logfile }}" >> $GITHUB_STEP_SUMMARY diff --git a/DOCKER_README.md b/DOCKER_README.md index 2ff7bbf8..0d9d1f4c 100644 --- a/DOCKER_README.md +++ b/DOCKER_README.md @@ -169,3 +169,8 @@ The architectures supported by these images are shown in the table below. | [Changelog](docs/changelog.md) | [Third-Party Packages](docs/third_party_packages.md) | + +
+ + [TOC] +
diff --git a/docs/app_examples.md b/docs/app_examples.md index 990064de..33ad3c34 100644 --- a/docs/app_examples.md +++ b/docs/app_examples.md @@ -323,3 +323,8 @@ values in most JSON.} | [Configuration](configuration.md) | [Guides](guides.md) | + +
+ + [TOC] +
diff --git a/docs/building.md b/docs/building.md index 502b0a1c..6d0e7c47 100644 --- a/docs/building.md +++ b/docs/building.md @@ -160,3 +160,8 @@ It may be beneficial to build remotely in some cases. This will enable easier bu | [Troubleshooting](troubleshooting.md) | [Contributing](contributing.md) | + +
+ + [TOC] +
diff --git a/docs/changelog.md b/docs/changelog.md index f975767a..9cf35f26 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -15,3 +15,8 @@ | [Getting Started](getting_started.md) | [Docker](../DOCKER_README.md) | + +
+ + [TOC] +
diff --git a/docs/configuration.md b/docs/configuration.md index 98bab79a..fe1d3b7e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2454,3 +2454,8 @@ editing the `conf` file in a text editor. Use the examples as reference. | [Legal](legal.md) | [App Examples](app_examples.md) | + +
+ + [TOC] +
diff --git a/docs/contributing.md b/docs/contributing.md index 33b78062..dfc98c3c 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -28,7 +28,7 @@ Read our contribution guide in our organization level Sunshine and related LizardByte projects are being localized into various languages. The default language is `en` (English). -![](https://app.lizardbyte.dev/uno/crowdin/LizardByte_graph.svg) +![](https://app.lizardbyte.dev/dashboard/crowdin/LizardByte_graph.svg) @admonition{Community | We are looking for language coordinators to help approve translations. The goal is to have the bars above filled with green! @@ -193,3 +193,8 @@ maintainers to run the tests locally. | [Building](building.md) | [Source Code](../third-party/doxyconfig/docs/source_code.md) | + +
+ + [TOC] +
diff --git a/docs/gamestream_migration.md b/docs/gamestream_migration.md index 274ad0e0..8a8699b7 100644 --- a/docs/gamestream_migration.md +++ b/docs/gamestream_migration.md @@ -29,3 +29,8 @@ Sunshine does have some limitations, as compared to Nvidia GameStream. | [Third-party Packages](third_party_packages.md) | [Legal](legal.md) | + +
+ + [TOC] +
diff --git a/docs/getting_started.md b/docs/getting_started.md index a9bd5561..d121813e 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -570,4 +570,9 @@ Tutorials and Guides are community generated. Want to contribute? Reach out to u +
+ + [TOC] +
+ [latest-release]: https://github.com/LizardByte/Sunshine/releases/latest diff --git a/docs/guides.md b/docs/guides.md index c0f592d7..2069a3b5 100644 --- a/docs/guides.md +++ b/docs/guides.md @@ -532,3 +532,8 @@ going up and down. This device will be referred to as Voicemeeter Input.} | [App Examples](app_examples.md) | [Performance Tuning](performance_tuning.md) | + +
+ + [TOC] +
diff --git a/docs/legal.md b/docs/legal.md index aee2effe..161791a6 100644 --- a/docs/legal.md +++ b/docs/legal.md @@ -25,3 +25,8 @@ concerns about using Sunshine in a commercial setting, we recommend consulting w | [Gamestream Migration](gamestream_migration.md) | [Configuration](configuration.md) | + +
+ + [TOC] +
diff --git a/docs/performance_tuning.md b/docs/performance_tuning.md index e055d5aa..79612142 100644 --- a/docs/performance_tuning.md +++ b/docs/performance_tuning.md @@ -18,3 +18,8 @@ Enabling *Fast Sync* in Nvidia settings may help reduce latency. | [Guides](guides.md) | [Troubleshooting](troubleshooting.md) | + +
+ + [TOC] +
diff --git a/docs/third_party_packages.md b/docs/third_party_packages.md index e89dd19b..1793b4ce 100644 --- a/docs/third_party_packages.md +++ b/docs/third_party_packages.md @@ -24,3 +24,8 @@ | [Docker](../DOCKER_README.md) | [Gamestream Migration](gamestream_migration.md) | + +
+ + [TOC] +
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index baf106f1..da91630d 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -143,25 +143,24 @@ often grub is used to load the kernel and set its command line.) ### AMD encoding latency issues If you notice unexpectedly high encoding latencies (e.g. in Moonlight's -performance overlay) or strong fluctuations thereof, this is due to -[missing support](https://gitlab.freedesktop.org/drm/amd/-/issues/3336) -in Mesa/libva for AMD's low latency encoder mode. This is particularly -problematic at higher resolutions (4K). - -Only the most recent development versions of mesa include support for this -low-latency mode. It will be included in Mesa-24.2. - -In order to enable it, Sunshine has to be started with a special environment -variable: +performance overlay) or strong fluctuations thereof, your system's Mesa +libraries are outdated (<24.2). This is particularly problematic at higher +resolutions (4K). +Starting with Mesa-24.2 applications can request a +[low-latency mode](https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30039) +by running them with a special +[environment variable](https://docs.mesa3d.org/envvars.html#envvar-AMD_DEBUG): ```bash -AMD_DEBUG=lowlatencyenc sunshine +export AMD_DEBUG=lowlatencyenc ``` +Sunshine sets this variable automatically, no manual +configuration is needed. -To check whether low-latency mode is being used, one can watch the `VCLK` and -`DCLK` frequencies in `amdgpu_top`. Without this encoder tuning both clock -frequencies will fluctuate strongly, whereas with active low-latency encoding -they will stay high as long as the encoder is used. +To check whether low-latency mode is being used, one can watch the VCLK and DCLK +frequencies in amdgpu_top. Without this encoder tuning both clock frequencies +will fluctuate strongly, whereas with active low-latency encoding they will stay +high as long as the encoder is used. ### Gamescope compatibility Some users have reported stuttering issues when streaming games running within Gamescope. @@ -198,3 +197,8 @@ permissions on the disk. | [Performance Tuning](performance_tuning.md) | [Building](building.md) | + +
+ + [TOC] +
diff --git a/package.json b/package.json index b4332c3a..a379c67e 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,13 @@ "dev": "vite build --watch" }, "dependencies": { - "@fortawesome/fontawesome-free": "6.6.0", - "@popperjs/core": "2.11.8", - "@vitejs/plugin-vue": "4.6.2", - "bootstrap": "5.3.3", - "vite": "4.5.2", - "vite-plugin-ejs": "1.6.4", - "vue": "3.4.38", + "@lizardbyte/shared-web": "2024.901.195233", + "vue": "3.5.3", "vue-i18n": "9.14.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "4.6.2", + "vite": "4.5.2", + "vite-plugin-ejs": "1.6.4" } } diff --git a/packaging/linux/Arch/PKGBUILD b/packaging/linux/Arch/PKGBUILD index e8eb8521..135e88a8 100644 --- a/packaging/linux/Arch/PKGBUILD +++ b/packaging/linux/Arch/PKGBUILD @@ -84,7 +84,7 @@ build() { -D CMAKE_INSTALL_PREFIX=/usr \ -D SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ -D SUNSHINE_ASSETS_DIR="share/sunshine" \ - -D SUNSHINE_PUBLSIHER_NAME='LizardByte' \ + -D SUNSHINE_PUBLISHER_NAME='LizardByte' \ -D SUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \ -D SUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml index f5e90739..156b40c5 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml @@ -77,7 +77,7 @@ modules: - -DSUNSHINE_ENABLE_X11=ON - -DSUNSHINE_ENABLE_DRM=ON - -DSUNSHINE_ENABLE_CUDA=ON - - -DSUNSHINE_PUBLSIHER_NAME='LizardByte' + - -DSUNSHINE_PUBLISHER_NAME='LizardByte' -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' sources: diff --git a/packaging/macos/Portfile b/packaging/macos/Portfile index a2a9eb5e..8c48d31e 100644 --- a/packaging/macos/Portfile +++ b/packaging/macos/Portfile @@ -44,7 +44,7 @@ configure.args -DBOOST_USE_STATIC=ON \ -DBUILD_WERROR=ON \ -DCMAKE_INSTALL_PREFIX=${prefix} \ -DSUNSHINE_ASSETS_DIR=etc/sunshine/assets \ - -DSUNSHINE_PUBLSIHER_NAME='LizardByte' \ + -DSUNSHINE_PUBLISHER_NAME='LizardByte' \ -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \ -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' diff --git a/packaging/sunshine.rb b/packaging/sunshine.rb index a8d9a661..7f01d155 100644 --- a/packaging/sunshine.rb +++ b/packaging/sunshine.rb @@ -71,7 +71,7 @@ class @PROJECT_NAME@ < Formula -DSUNSHINE_ASSETS_DIR=sunshine/assets -DSUNSHINE_BUILD_HOMEBREW=ON -DSUNSHINE_ENABLE_TRAY=OFF - -DSUNSHINE_PUBLSIHER_NAME='LizardByte' + -DSUNSHINE_PUBLISHER_NAME='LizardByte' -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' ] diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 9536d816..cf4ab098 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -150,15 +150,14 @@ namespace nvhttp { }; struct client_t { - std::vector certs; std::vector named_devices; }; struct pair_session_t { struct { std::string uniqueID; - std::string deviceName; std::string cert; + std::string name; } client; std::unique_ptr cipher_key; @@ -288,7 +287,6 @@ namespace nvhttp { named_cert.cert = el.get_value(); named_cert.uuid = uuid_util::uuid_t::generate().string(); client.named_devices.emplace_back(named_cert); - client.certs.emplace_back(named_cert.cert); } } } @@ -301,15 +299,11 @@ namespace nvhttp { named_cert.cert = el.get_child("cert").get_value(); named_cert.uuid = el.get_child("uuid").get_value(); client.named_devices.emplace_back(named_cert); - client.certs.emplace_back(named_cert.cert); } } // Empty certificate chain and import certs from file cert_chain.clear(); - for (auto &cert : client.certs) { - cert_chain.add(crypto::x509(cert)); - } for (auto &named_cert : client.named_devices) { cert_chain.add(crypto::x509(named_cert.cert)); } @@ -318,17 +312,13 @@ namespace nvhttp { } void - update_id_client(const std::string &uniqueID, std::string &&cert, op_e op) { - switch (op) { - case op_e::ADD: { - client_t &client = client_root; - client.certs.emplace_back(std::move(cert)); - } break; - case op_e::REMOVE: - client_t client; - client_root = client; - break; - } + add_authorized_client(const std::string &name, std::string &&cert) { + client_t &client = client_root; + named_cert_t named_cert; + named_cert.name = name; + named_cert.cert = std::move(cert); + named_cert.uuid = uuid_util::uuid_t::generate().string(); + client.named_devices.emplace_back(named_cert); if (!config::sunshine.flags[config::flag::FRESH_STATE]) { save_state(); @@ -500,15 +490,7 @@ namespace nvhttp { add_cert->raise(crypto::x509(client.cert)); auto it = map_id_sess.find(client.uniqueID); - - // set up named cert - named_cert_t named_cert; - named_cert.name = client.deviceName; - named_cert.cert = client.cert; - named_cert.uuid = uuid_util::uuid_t::generate().string(); - client_root.named_devices.emplace_back(named_cert); - - update_id_client(client.uniqueID, std::move(client.cert), op_e::ADD); + add_authorized_client(client.name, std::move(client.cert)); map_id_sess.erase(it); } else { @@ -611,7 +593,7 @@ namespace nvhttp { } sess.client.uniqueID = std::move(uniqID); - sess.client.deviceName = std::move(deviceName); + sess.client.name = std::move(deviceName); sess.client.cert = util::from_hex_vec(get_arg(args, "clientcert"), true); BOOST_LOG(debug) << sess.client.cert; @@ -632,7 +614,7 @@ namespace nvhttp { if (hash.to_string_view() == it->second) { if (!otp_device_name.empty()) { - ptr->second.client.deviceName = std::move(otp_device_name); + ptr->second.client.name = std::move(otp_device_name); } getservercert(ptr->second, tree, one_time_pin); @@ -715,7 +697,7 @@ namespace nvhttp { getservercert(sess, tree, pin); if (!name.empty()) { - sess.client.deviceName = name; + sess.client.name = name; } // response to the request for pin @@ -1268,18 +1250,6 @@ namespace nvhttp { client_t &client = client_root; for (auto it = client.named_devices.begin(); it != client.named_devices.end();) { if ((*it).uuid == uuid) { - // Find matching cert and remove it - for (auto cert = client.certs.begin(); cert != client.certs.end();) { - if ((*cert) == (*it).cert) { - cert = client.certs.erase(cert); - removed++; - } - else { - ++cert; - } - } - - // And then remove the named cert it = client.named_devices.erase(it); removed++; } diff --git a/src/platform/linux/graphics.cpp b/src/platform/linux/graphics.cpp index 2ba97759..8ffba667 100644 --- a/src/platform/linux/graphics.cpp +++ b/src/platform/linux/graphics.cpp @@ -19,7 +19,7 @@ extern "C" { // They aren't likely to change any time soon. #define fourcc_code(a, b, c, d) ((std::uint32_t)(a) | ((std::uint32_t)(b) << 8) | \ ((std::uint32_t)(c) << 16) | ((std::uint32_t)(d) << 24)) -#define fourcc_mod_code(vendor, val) ((((uint64_t) vendor) << 56) | ((val) &0x00ffffffffffffffULL)) +#define fourcc_mod_code(vendor, val) ((((uint64_t) vendor) << 56) | ((val) & 0x00ffffffffffffffULL)) #define DRM_FORMAT_MOD_INVALID fourcc_mod_code(0, ((1ULL << 56) - 1)) #if !defined(SUNSHINE_SHADERS_DIR) // for testing this needs to be defined in cmake as we don't do an install diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 3947d20f..d00b8dc9 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -1002,7 +1002,7 @@ namespace platf { init() { // enable low latency mode for AMD // https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30039 - set_env("AMD_DEBUG", "lowlatency"); + set_env("AMD_DEBUG", "lowlatencyenc"); // These are allowed to fail. gbm::init(); diff --git a/src/platform/linux/x11grab.cpp b/src/platform/linux/x11grab.cpp index bcb2ff30..44c37609 100644 --- a/src/platform/linux/x11grab.cpp +++ b/src/platform/linux/x11grab.cpp @@ -618,8 +618,7 @@ namespace platf { } ~shm_attr_t() override { - while (!task_pool.cancel(refresh_task_id)) - ; + while (!task_pool.cancel(refresh_task_id)); } capture_e diff --git a/src/platform/windows/display_wgc.cpp b/src/platform/windows/display_wgc.cpp index 1df60fcd..d50e9ccf 100644 --- a/src/platform/windows/display_wgc.cpp +++ b/src/platform/windows/display_wgc.cpp @@ -37,7 +37,7 @@ namespace winrt { #if WINRT_IMPL_HAS_DECLSPEC_UUID __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")) #endif - IDirect3DDxgiInterfaceAccess: ::IUnknown { + IDirect3DDxgiInterfaceAccess: ::IUnknown { virtual HRESULT __stdcall GetInterface(REFIID id, void **object) = 0; }; } // namespace winrt diff --git a/src_assets/common/assets/web/public/assets/locale/zh.json b/src_assets/common/assets/web/public/assets/locale/zh.json index 4bb22818..b38c06f7 100644 --- a/src_assets/common/assets/web/public/assets/locale/zh.json +++ b/src_assets/common/assets/web/public/assets/locale/zh.json @@ -52,7 +52,7 @@ "env_client_fps": "客户端请求的帧率 (int)", "env_client_gcmap": "客户端请求的游戏手柄掩码,采用 bitset/bitfield 格式 (int)", "env_client_hdr": "HDR 已被客户端启用 (true/false)", - "env_client_height": "客户端请求的分辨率的高度 (int)", + "env_client_height": "客户端请求的高度 (int)", "env_client_host_audio": "客户端请求在主机播放声音 (true/false)", "env_client_width": "客户端请求的分辨率的宽度 (int)", "env_displayplacer_example": "示例 - 使用 displayplacer 自动更改分辨率:", @@ -74,7 +74,7 @@ "output_desc": "存储命令输出的文件,如果未指定,输出将被忽略", "output_name": "输出", "run_as_desc": "这可能是某些需要管理员权限才能正常运行的应用程序所必需的。", - "wait_all": "继续串流直到所有应用进程终止", + "wait_all": "继续串流直到所有应用进程退出", "wait_all_desc": "这将继续串流直到应用程序启动的所有进程终止。 当未选中时,串流将在初始应用进程终止时停止,即使其他应用进程仍在运行。", "working_dir": "工作目录", "working_dir_desc": "应传递给进程的工作目录。例如,某些应用程序使用工作目录搜索配置文件。如果不设置,Apollo 将默认使用命令的父目录", @@ -181,7 +181,7 @@ "follow_client_hdr_desc": "根据客户端请求自动设置串流屏幕 HDR 的开关。(不建议启用)", "gamepad": "模拟游戏手柄类型", "gamepad_auto": "自动选择选项", - "gamepad_desc": "选择要在主机上模拟的游戏手柄类型", + "gamepad_desc": "选择要在主机上模拟的游戏手表类型", "gamepad_ds4": "DS4 (PS4)", "gamepad_ds5": "DS5 (PS5)", "gamepad_switch": "Nintendo Pro (Switch)", @@ -294,7 +294,7 @@ "port_web_ui": "Web UI", "qp": "量化参数 (QP)", "qp_desc": "某些设备可能不支持恒定码率。对于这些设备,则使用 QP 代替。数值越大,压缩率越高,但质量越差。", - "qsv_coder": "QuickSync Coder (H264)", + "qsv_coder": "QSV 编码器 (H264)", "qsv_preset": "QSV 编码器预设", "qsv_preset_fast": "fast - 较快(较低质量)", "qsv_preset_faster": "faster - 更快(更低质量)",