Compare commits
10 Commits
3048e6fe20
...
64544e7960
| Author | SHA1 | Date | |
|---|---|---|---|
| 64544e7960 | |||
| 2a31ee5422 | |||
| 8263d8976f | |||
| eb6916ef34 | |||
| 5af21bde88 | |||
| 31866fde35 | |||
| 299b12347f | |||
| 2ac87fdc36 | |||
| a88c01f3b8 | |||
| f5b923c406 |
@@ -80,13 +80,14 @@ jobs:
|
||||
month_day=$(printf "%04d" "$month_day")
|
||||
|
||||
# create the filename
|
||||
file_name="_posts/releases/${year}-${month_day:0:2}-${month_day:2:2}-v${semver}.md"
|
||||
file_name="_posts/releases/${repo_lower}/${year}-${month_day:0:2}-${month_day:2:2}-v${semver}.md"
|
||||
mkdir -p "$(dirname "${file_name}")"
|
||||
|
||||
# create jekyll blog post
|
||||
echo "---" > "${file_name}"
|
||||
echo "layout: release" >> "${file_name}"
|
||||
echo "title: ${{ github.event.repository.name }} ${tag_name} Released" >> "${file_name}"
|
||||
echo "release-tag: ${tag_name}" >> "${file_name}"
|
||||
echo "gh-repo: ${{ github.repository }}" >> "${file_name}"
|
||||
echo "gh-badge: [follow, fork, star]" >> "${file_name}"
|
||||
echo "tags: [release, ${repo_lower}]" >> "${file_name}"
|
||||
|
||||
@@ -81,9 +81,16 @@ jobs:
|
||||
--arg description "${{ github.event.repository.description }}" \
|
||||
'{default_branch: $default_branch}')
|
||||
|
||||
# change the default branch to the latest release
|
||||
curl \
|
||||
-X PATCH \
|
||||
-H "Authorization: Token ${RTD_TOKEN}" \
|
||||
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/ \
|
||||
-H "Content-Type: application/json" \
|
||||
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/ \
|
||||
-d "$json_body"
|
||||
|
||||
# trigger a build for the latest version
|
||||
curl \
|
||||
-X POST \
|
||||
-H "Authorization: Token ${RTD_TOKEN}" \
|
||||
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/versions/latest/builds/
|
||||
|
||||
@@ -198,6 +198,14 @@ if(${SUNSHINE_ENABLE_TRAY})
|
||||
list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/third-party/tray/src/tray_linux.c")
|
||||
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${APPINDICATOR_LIBRARIES} ${LIBNOTIFY_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# flatpak icons must be prefixed with the app id or they will not be included in the flatpak
|
||||
if(${SUNSHINE_BUILD_FLATPAK})
|
||||
set(SUNSHINE_TRAY_PREFIX "${PROJECT_FQDN}")
|
||||
else()
|
||||
set(SUNSHINE_TRAY_PREFIX "sunshine")
|
||||
endif()
|
||||
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_TRAY_PREFIX="${SUNSHINE_TRAY_PREFIX}")
|
||||
else()
|
||||
set(SUNSHINE_TRAY 0)
|
||||
message(STATUS "Tray icon disabled")
|
||||
|
||||
+26
-17
@@ -100,15 +100,31 @@ endif()
|
||||
|
||||
# tray icon
|
||||
if(${SUNSHINE_TRAY} STREQUAL 1)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "sunshine-tray.svg")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-playing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-pausing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
if(NOT ${SUNSHINE_BUILD_FLATPAK})
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "sunshine-tray.svg")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-playing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-pausing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
|
||||
else()
|
||||
# flatpak icons must be prefixed with the app id or they will not be included in the flatpak
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "${PROJECT_FQDN}-tray.svg")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-playing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "${PROJECT_FQDN}-playing.svg")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-pausing.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "${PROJECT_FQDN}-pausing.svg")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
|
||||
RENAME "${PROJECT_FQDN}-locked.svg")
|
||||
endif()
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
||||
${CPACK_DEBIAN_PACKAGE_DEPENDS}, \
|
||||
@@ -128,15 +144,8 @@ else()
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
|
||||
RENAME "${PROJECT_FQDN}.desktop")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_kms.desktop"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
|
||||
RENAME "${PROJECT_FQDN}_kms.desktop")
|
||||
endif()
|
||||
if(${SUNSHINE_BUILD_FLATPAK})
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
|
||||
RENAME "${PROJECT_FQDN}_terminal.desktop")
|
||||
elseif(NOT ${SUNSHINE_BUILD_APPIMAGE})
|
||||
if(NOT ${SUNSHINE_BUILD_APPIMAGE} AND NOT ${SUNSHINE_BUILD_FLATPAK})
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
|
||||
endif()
|
||||
|
||||
@@ -8,10 +8,10 @@ elseif (UNIX)
|
||||
endif()
|
||||
|
||||
if(SUNSHINE_BUILD_FLATPAK)
|
||||
set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${PROJECT_FQDN}")
|
||||
set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=flatpak run --command=sunshine ${PROJECT_FQDN}")
|
||||
set(SUNSHINE_SERVICE_STOP_COMMAND "ExecStop=flatpak kill ${PROJECT_FQDN}")
|
||||
else()
|
||||
set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${SUNSHINE_EXECUTABLE_PATH}")
|
||||
set(SUNSHINE_SERVICE_STOP_COMMAND "")
|
||||
endif()
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
@@ -10,14 +10,12 @@ if(APPLE)
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
# configure the .desktop file
|
||||
set(SUNSHINE_DESKTOP_ICON "sunshine.svg")
|
||||
set(SUNSHINE_DESKTOP_ICON "sunshine")
|
||||
if(${SUNSHINE_BUILD_APPIMAGE})
|
||||
configure_file(packaging/linux/AppImage/sunshine.desktop sunshine.desktop @ONLY)
|
||||
elseif(${SUNSHINE_BUILD_FLATPAK})
|
||||
set(SUNSHINE_DESKTOP_ICON "${PROJECT_FQDN}.svg")
|
||||
set(SUNSHINE_DESKTOP_ICON "${PROJECT_FQDN}")
|
||||
configure_file(packaging/linux/flatpak/sunshine.desktop sunshine.desktop @ONLY)
|
||||
configure_file(packaging/linux/flatpak/sunshine_kms.desktop sunshine_kms.desktop @ONLY)
|
||||
configure_file(packaging/linux/sunshine_terminal.desktop sunshine_terminal.desktop @ONLY)
|
||||
configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml
|
||||
${PROJECT_FQDN}.metainfo.xml @ONLY)
|
||||
else()
|
||||
|
||||
Submodule packaging/linux/flatpak/deps/shared-modules updated: f5d368a31d...26def5f1d2
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
PORT=47990
|
||||
|
||||
if ! curl -k https://localhost:$PORT > /dev/null 2>&1; then
|
||||
(sleep 3 && xdg-open https://localhost:$PORT) &
|
||||
exec sunshine "$@"
|
||||
else
|
||||
echo "Sunshine is already running, opening the web interface..."
|
||||
xdg-open https://localhost:$PORT
|
||||
fi
|
||||
@@ -1,20 +1,9 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=@PROJECT_NAME@
|
||||
Exec=@PROJECT_FQDN@
|
||||
Version=1.0
|
||||
Categories=AudioVideo;Network;RemoteAccess;
|
||||
Comment=@PROJECT_DESCRIPTION@
|
||||
Exec=sunshine.sh
|
||||
Icon=@SUNSHINE_DESKTOP_ICON@
|
||||
Keywords=gamestream;stream;moonlight;remote play;
|
||||
Categories=AudioVideo;Network;RemoteAccess;
|
||||
Actions=RunInTerminal;KMS;
|
||||
|
||||
[Desktop Action RunInTerminal]
|
||||
Name=Run in Terminal
|
||||
Icon=application-x-executable
|
||||
Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_terminal.desktop
|
||||
|
||||
[Desktop Action KMS]
|
||||
Name=Run in Terminal (KMS)
|
||||
Icon=application-x-executable
|
||||
Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_kms.desktop
|
||||
Name=@PROJECT_NAME@
|
||||
Type=Application
|
||||
Version=1.0
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=@PROJECT_NAME@ (KMS)
|
||||
Exec=sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@
|
||||
Terminal=true
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
+14
-23
@@ -54,17 +54,14 @@ namespace http {
|
||||
config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string();
|
||||
}
|
||||
|
||||
if (!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) {
|
||||
if (create_creds(config::nvhttp.pkey, config::nvhttp.cert)) {
|
||||
return -1;
|
||||
}
|
||||
if ((!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) &&
|
||||
create_creds(config::nvhttp.pkey, config::nvhttp.cert)) {
|
||||
return -1;
|
||||
}
|
||||
if (user_creds_exist(config::sunshine.credentials_file)) {
|
||||
if (reload_user_creds(config::sunshine.credentials_file)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!user_creds_exist(config::sunshine.credentials_file)) {
|
||||
BOOST_LOG(info) << "Open the Web UI to set your new username and password and getting started";
|
||||
} else if (reload_user_creds(config::sunshine.credentials_file)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -179,19 +176,15 @@ namespace http {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool download_file(const std::string &url, const std::string &file) {
|
||||
CURL *curl = curl_easy_init();
|
||||
if (curl) {
|
||||
// sonar complains about weak ssl and tls versions
|
||||
// ideally, the setopts should go after the early returns; however sonar cannot detect the fix
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
} else {
|
||||
bool download_file(const std::string &url, const std::string &file, long ssl_version) {
|
||||
// sonar complains about weak ssl and tls versions; however sonar cannot detect the fix
|
||||
CURL *curl = curl_easy_init(); // NOSONAR
|
||||
if (!curl) {
|
||||
BOOST_LOG(error) << "Couldn't create CURL instance";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file_dir = file_handler::get_parent_directory(file);
|
||||
if (!file_handler::make_directory(file_dir)) {
|
||||
if (std::string file_dir = file_handler::get_parent_directory(file); !file_handler::make_directory(file_dir)) {
|
||||
BOOST_LOG(error) << "Couldn't create directory ["sv << file_dir << ']';
|
||||
curl_easy_cleanup(curl);
|
||||
return false;
|
||||
@@ -204,6 +197,7 @@ namespace http {
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, ssl_version); // NOSONAR
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
@@ -219,17 +213,15 @@ namespace http {
|
||||
}
|
||||
|
||||
std::string url_escape(const std::string &url) {
|
||||
CURL *curl = curl_easy_init();
|
||||
char *string = curl_easy_escape(curl, url.c_str(), url.length());
|
||||
char *string = curl_easy_escape(nullptr, url.c_str(), static_cast<int>(url.length()));
|
||||
std::string result(string);
|
||||
curl_free(string);
|
||||
curl_easy_cleanup(curl);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string url_get_host(const std::string &url) {
|
||||
CURLU *curlu = curl_url();
|
||||
curl_url_set(curlu, CURLUPART_URL, url.c_str(), url.length());
|
||||
curl_url_set(curlu, CURLUPART_URL, url.c_str(), static_cast<unsigned int>(url.length()));
|
||||
char *host;
|
||||
if (curl_url_get(curlu, CURLUPART_HOST, &host, 0) != CURLUE_OK) {
|
||||
curl_url_cleanup(curlu);
|
||||
@@ -240,5 +232,4 @@ namespace http {
|
||||
curl_url_cleanup(curlu);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace http
|
||||
|
||||
+4
-1
@@ -4,6 +4,9 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// lib includes
|
||||
#include <curl/curl.h>
|
||||
|
||||
// local includes
|
||||
#include "network.h"
|
||||
#include "thread_safe.h"
|
||||
@@ -20,7 +23,7 @@ namespace http {
|
||||
);
|
||||
|
||||
int reload_user_creds(const std::string &file);
|
||||
bool download_file(const std::string &url, const std::string &file);
|
||||
bool download_file(const std::string &url, const std::string &file, long ssl_version = CURL_SSLVERSION_TLSv1_3);
|
||||
std::string url_escape(const std::string &url);
|
||||
std::string url_get_host(const std::string &url);
|
||||
|
||||
|
||||
+4
-4
@@ -14,10 +14,10 @@
|
||||
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
|
||||
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||
#define TRAY_ICON "sunshine-tray"
|
||||
#define TRAY_ICON_PLAYING "sunshine-playing"
|
||||
#define TRAY_ICON_PAUSING "sunshine-pausing"
|
||||
#define TRAY_ICON_LOCKED "sunshine-locked"
|
||||
#define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
|
||||
#define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
|
||||
#define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"
|
||||
#define TRAY_ICON_LOCKED SUNSHINE_TRAY_PREFIX "-locked"
|
||||
#elif defined(__APPLE__) || defined(__MACH__)
|
||||
#define TRAY_ICON WEB_DIR "images/logo-sunshine-16.png"
|
||||
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing-16.png"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"disabled_def_cbox": "기본값: 선택 안 함",
|
||||
"dismiss": "해제",
|
||||
"do_cmd": "명령 수행",
|
||||
"elevated": "상승",
|
||||
"elevated": "관리자 권한으로 실행",
|
||||
"enabled": "활성화됨",
|
||||
"enabled_def": "활성화됨 (기본값)",
|
||||
"enabled_def_cbox": "기본값: 확인됨",
|
||||
@@ -208,11 +208,11 @@
|
||||
"gamepad_desc": "호스트에서 에뮬레이트할 게임패드 유형을 선택합니다.",
|
||||
"gamepad_ds4": "DS4 (PS4)",
|
||||
"gamepad_ds4_manual": "DS4 선택 옵션",
|
||||
"gamepad_ds5": "DS5(PS5)",
|
||||
"gamepad_switch": "닌텐도 프로(스위치)",
|
||||
"gamepad_ds5": "DS5 (PS5)",
|
||||
"gamepad_switch": "닌텐도 프로 (스위치 컨트롤러)",
|
||||
"gamepad_manual": "DS4 수동 옵션",
|
||||
"gamepad_x360": "X360(Xbox 360)",
|
||||
"gamepad_xone": "XOne(Xbox One)",
|
||||
"gamepad_x360": "X360 (Xbox 360)",
|
||||
"gamepad_xone": "XOne (Xbox One)",
|
||||
"global_prep_cmd": "명령 준비",
|
||||
"global_prep_cmd_desc": "애플리케이션 실행 전 또는 실행 후에 실행할 명령 목록을 구성합니다. 지정된 준비 명령 중 하나라도 실패하면 애플리케이션 실행 프로세스가 중단됩니다.",
|
||||
"hevc_mode": "HEVC 지원",
|
||||
@@ -224,18 +224,18 @@
|
||||
"high_resolution_scrolling": "고해상도 스크롤 지원",
|
||||
"high_resolution_scrolling_desc": "이 옵션을 활성화하면 Sunshine은 Moonlight 클라이언트의 고해상도 스크롤 이벤트를 통과합니다. 고해상도 스크롤 이벤트로 너무 빠르게 스크롤하는 구형 애플리케이션의 경우 이 옵션을 비활성화하면 유용할 수 있습니다.",
|
||||
"install_steam_audio_drivers": "Steam 오디오 드라이버 설치",
|
||||
"install_steam_audio_drivers_desc": "Steam이 설치되어 있으면 5.1/7.1 서라운드 사운드와 호스트 오디오 음소거를 지원하는 Steam 스트리밍 스피커 드라이버가 자동으로 설치됩니다.",
|
||||
"install_steam_audio_drivers_desc": "Steam이 설치되어 있으면 5.1/7.1 서라운드 사운드와 호스트 오디오 음소거를 지원하는 Steam Streaming Speakers 드라이버가 자동으로 설치됩니다.",
|
||||
"key_repeat_delay": "키 반복 지연",
|
||||
"key_repeat_delay_desc": "키가 반복되는 속도를 제어합니다. 키가 반복되기 전 초기 지연 시간(밀리초)입니다.",
|
||||
"key_repeat_delay_desc": "키가 반복되는 속도를 제어합니다. 키가 반복되기 전 초기 지연 시간 (ms) 입니다.",
|
||||
"key_repeat_frequency": "키 반복 빈도",
|
||||
"key_repeat_frequency_desc": "매 초마다 키가 반복되는 빈도. 이 구성 가능한 옵션은 소수를 지원합니다.",
|
||||
"key_repeat_frequency_desc": "매 초마다 키가 반복되는 빈도입니다. (이 옵션은 소수점 입력이 가능합니다.)",
|
||||
"key_rightalt_to_key_win": "오른쪽 Alt 키를 Windows 키로 매핑",
|
||||
"key_rightalt_to_key_win_desc": "달빛에서 Windows 키를 직접 보낼 수 없는 경우가 있을 수 있습니다. 이러한 경우 Sunshine이 오른쪽 Alt 키를 Windows 키로 인식하도록 하는 것이 유용할 수 있습니다.",
|
||||
"keyboard": "키보드 입력 활성화",
|
||||
"keyboard_desc": "게스트가 키보드로 호스트 시스템을 제어할 수 있습니다.",
|
||||
"lan_encryption_mode": "LAN 암호화 모드",
|
||||
"lan_encryption_mode_1": "지원되는 클라이언트에서 사용 가능",
|
||||
"lan_encryption_mode_2": "모든 고객에게 필수",
|
||||
"lan_encryption_mode_2": "모든 사용자에게 필수",
|
||||
"lan_encryption_mode_desc": "로컬 네트워크를 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다.",
|
||||
"locale": "로캘",
|
||||
"locale_desc": "Sunshine의 사용자 인터페이스에 사용되는 로캘입니다.",
|
||||
@@ -255,8 +255,8 @@
|
||||
"min_threads": "최소 CPU 스레드 수",
|
||||
"min_threads_desc": "이 값을 높이면 인코딩 효율이 약간 떨어지지만, 일반적으로 인코딩에 더 많은 CPU 코어를 사용할 수 있다는 점에서 그만한 가치가 있습니다. 이상적인 값은 하드웨어에서 원하는 스트리밍 설정으로 안정적으로 인코딩할 수 있는 가장 낮은 값입니다.",
|
||||
"misc": "기타 옵션",
|
||||
"motion_as_ds4": "클라이언트 게임패드가 모션 센서가 있다고 보고하는 경우 DS4 게임패드 에뮬레이션",
|
||||
"motion_as_ds4_desc": "비활성화하면 게임패드 유형을 선택할 때 모션 센서가 고려되지 않습니다.",
|
||||
"motion_as_ds4": "클라이언트의 게임패드가 모션 기능을 보유중인 경우 DS4 게임패드로 에뮬레이트",
|
||||
"motion_as_ds4_desc": "비활성화시, 게임패드를 선택할 때 모션 센서 유무를 확인하지 않습니다.",
|
||||
"mouse": "마우스 입력 활성화",
|
||||
"mouse_desc": "게스트가 마우스로 호스트 시스템을 제어할 수 있습니다.",
|
||||
"native_pen_touch": "기본 펜/터치 지원",
|
||||
@@ -300,10 +300,10 @@
|
||||
"pkey": "개인 키",
|
||||
"pkey_desc": "웹 UI와 Moonlight 클라이언트 페어링에 사용되는 개인 키입니다. 최상의 호환성을 위해 RSA-2048 개인키를 사용해야 합니다.",
|
||||
"port": "포트",
|
||||
"port_alert_1": "선샤인은 1024 이하의 포트를 사용할 수 없습니다!",
|
||||
"port_alert_2": "65535 이상의 포트는 사용할 수 없습니다!",
|
||||
"port_alert_1": "Sunshine은 1024 이하의 포트를 사용할 수 없습니다, 다시 확인하세요.",
|
||||
"port_alert_2": "65535 이상의 포트는 사용할 수 없습니다, 다시 확인하세요.",
|
||||
"port_desc": "Sunshine에서 사용하는 포트 제품군 설정",
|
||||
"port_http_port_note": "이 포트를 사용하여 문라이트에 연결하세요.",
|
||||
"port_http_port_note": "이 포트를 사용하여 Moonlight에 연결하세요.",
|
||||
"port_note": "참고",
|
||||
"port_port": "포트",
|
||||
"port_protocol": "프로토콜",
|
||||
@@ -315,27 +315,27 @@
|
||||
"qp_desc": "일부 디바이스는 고정 비트 전송률을 지원하지 않을 수 있습니다. 이러한 디바이스에서는 대신 QP가 사용됩니다. 값이 높을수록 압축률이 높아지지만 품질은 떨어집니다.",
|
||||
"qsv_coder": "퀵싱크 코더(H264)",
|
||||
"qsv_preset": "퀵싱크 프리셋",
|
||||
"qsv_preset_fast": "빠름(낮은 품질)",
|
||||
"qsv_preset_faster": "더 빠름(품질 저하)",
|
||||
"qsv_preset_medium": "중간(기본값)",
|
||||
"qsv_preset_slow": "느림(좋은 품질)",
|
||||
"qsv_preset_slower": "느림(더 나은 품질)",
|
||||
"qsv_preset_slowest": "가장 느림(최고 품질)",
|
||||
"qsv_preset_veryfast": "가장 빠름(최저 품질)",
|
||||
"qsv_preset_fast": "빠름 (낮은 품질)",
|
||||
"qsv_preset_faster": "더 빠름 (더 낮은 품질)",
|
||||
"qsv_preset_medium": "중간 (기본값)",
|
||||
"qsv_preset_slow": "느림 (좋은 품질)",
|
||||
"qsv_preset_slower": "더 느림 (더 좋은 품질)",
|
||||
"qsv_preset_slowest": "가장 느림 (최고 품질)",
|
||||
"qsv_preset_veryfast": "가장 빠름 (최저 품질)",
|
||||
"qsv_slow_hevc": "느린 HEVC 인코딩 허용",
|
||||
"qsv_slow_hevc_desc": "이렇게 하면 구형 인텔 GPU에서 HEVC 인코딩이 가능하지만, GPU 사용량이 증가하고 성능이 저하될 수 있습니다.",
|
||||
"restart_note": "변경 사항을 적용하기 위해 Sunshine이 다시 시작됩니다.",
|
||||
"sunshine_name": "선샤인 이름",
|
||||
"sunshine_name_desc": "달빛이 표시하는 이름입니다. 지정하지 않으면 PC의 호스트 이름이 사용됩니다.",
|
||||
"sunshine_name": "Sunshine 이름",
|
||||
"sunshine_name_desc": "Moonlight에서 표시되는 이름입니다. 지정하지 않으면 PC의 이름이 사용됩니다.",
|
||||
"sw_preset": "SW 프리셋",
|
||||
"sw_preset_desc": "인코딩 속도(초당 인코딩 프레임 수)와 압축 효율성(비트스트림의 비트당 품질) 간의 절충점을 최적화합니다. 기본값은 초고속입니다.",
|
||||
"sw_preset_fast": "빠른",
|
||||
"sw_preset_faster": "더 빠르게",
|
||||
"sw_preset_medium": "medium",
|
||||
"sw_preset_slow": "slow",
|
||||
"sw_preset_slower": "느린",
|
||||
"sw_preset_superfast": "초고속(기본값)",
|
||||
"sw_preset_ultrafast": "초고속",
|
||||
"sw_preset_fast": "빠름",
|
||||
"sw_preset_faster": "더 빠름",
|
||||
"sw_preset_medium": "중간",
|
||||
"sw_preset_slow": "느림",
|
||||
"sw_preset_slower": "더 느림",
|
||||
"sw_preset_superfast": "엄청 빠름 (기본값)",
|
||||
"sw_preset_ultrafast": "엄청 빠름",
|
||||
"sw_preset_veryfast": "매우 빠름",
|
||||
"sw_preset_veryslow": "매우 느림",
|
||||
"sw_tune": "SW Tune",
|
||||
@@ -353,8 +353,8 @@
|
||||
"vaapi_strict_rc_buffer": "AMD GPU에서 H.264/HEVC에 대한 프레임 비트레이트 제한을 엄격하게 적용합니다.",
|
||||
"vaapi_strict_rc_buffer_desc": "이 옵션을 활성화하면 장면이 변경되는 동안 네트워크를 통해 프레임이 끊기는 것을 방지할 수 있지만 움직이는 동안 동영상 품질이 저하될 수 있습니다.",
|
||||
"virtual_sink": "가상 싱크",
|
||||
"virtual_sink_desc": "사용할 가상 오디오 장치를 수동으로 지정합니다. 설정하지 않으면 장치가 자동으로 선택됩니다. 자동 장치 선택을 사용하려면 이 필드를 비워 두는 것이 좋습니다!",
|
||||
"virtual_sink_placeholder": "Steam 스트리밍 스피커",
|
||||
"virtual_sink_desc": "사용할 가상 오디오 장치를 수동으로 지정합니다. 설정하지 않으면 자동으로 장치가 선택됩니다. 자동으로 장치를 선택할려면 이 칸을 비우는 것을 권장드립니다.",
|
||||
"virtual_sink_placeholder": "Steam Streaming Speakers",
|
||||
"vt_coder": "비디오 툴박스 코더",
|
||||
"vt_realtime": "비디오툴박스 실시간 인코딩",
|
||||
"vt_software": "비디오툴박스 소프트웨어 인코딩",
|
||||
@@ -362,30 +362,30 @@
|
||||
"vt_software_forced": "강제",
|
||||
"wan_encryption_mode": "WAN 암호화 모드",
|
||||
"wan_encryption_mode_1": "지원되는 클라이언트에 사용(기본값)",
|
||||
"wan_encryption_mode_2": "모든 고객에게 필수",
|
||||
"wan_encryption_mode_2": "모든 사용자에게 필수",
|
||||
"wan_encryption_mode_desc": "인터넷을 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다."
|
||||
},
|
||||
"index": {
|
||||
"description": "선샤인은 문라이트의 자체 호스팅 게임 스트림 호스트입니다.",
|
||||
"description": "Sunshine은 Moonlight의 게임 스트리밍 프로그램 입니다.",
|
||||
"download": "다운로드",
|
||||
"installed_version_not_stable": "선샤인 시험판 버전을 실행 중입니다. 버그나 기타 문제가 발생할 수 있습니다. 문제가 발생하면 신고해 주세요. Sunshine을 더 나은 소프트웨어로 만드는 데 도움을 주셔서 감사합니다!",
|
||||
"loading_latest": "최신 릴리스 로드 중...",
|
||||
"installed_version_not_stable": "Sunshine의 정식 출시 이전 버전을 실행 중입니다. 버그나 기타 문제가 발생할 수 있습니다. 문제가 발생하면 신고해 주세요. Sunshine을 더 나은 소프트웨어로 만드는 데 도움을 주셔서 감사합니다!",
|
||||
"loading_latest": "새로운 업데이트를 확인하는 중...",
|
||||
"new_pre_release": "새로운 사전 출시 버전이 출시되었습니다!",
|
||||
"new_stable": "새로운 안정 버전이 출시되었습니다!",
|
||||
"startup_errors": "<b>주의!</b> 시작 중에 이러한 오류가 감지되었습니다. 스트리밍하기 전에 이 오류를 수정할 <b>것을 강력히 권장합니다</b>.",
|
||||
"version_dirty": "선샤인이 더 나은 소프트웨어가 될 수 있도록 도와주셔서 감사합니다!",
|
||||
"startup_errors": "<b>주의!</b> 시작하는 중에 오류가 감지되었습니다. 스트리밍하기 전에 이 오류를 수정할 것을 <b>강력히 권장합니다.</b>",
|
||||
"version_dirty": "Sunshine이 더 나은 소프트웨어가 될 수 있도록 도와주셔서 감사합니다!",
|
||||
"version_latest": "최신 버전의 Sunshine을 실행 중입니다.",
|
||||
"welcome": "안녕하세요, 선샤인!"
|
||||
"welcome": "반가워요, Sunshine!"
|
||||
},
|
||||
"navbar": {
|
||||
"applications": "애플리케이션",
|
||||
"configuration": "구성",
|
||||
"configuration": "설정",
|
||||
"home": "홈",
|
||||
"password": "비밀번호 변경",
|
||||
"pin": "핀",
|
||||
"theme_auto": "자동",
|
||||
"theme_dark": "Dark",
|
||||
"theme_light": "빛",
|
||||
"theme_dark": "다크 테마",
|
||||
"theme_light": "라이트 테마",
|
||||
"toggle_theme": "테마",
|
||||
"troubleshoot": "문제 해결"
|
||||
},
|
||||
@@ -444,8 +444,8 @@
|
||||
"confirm_password": "비밀번호 확인",
|
||||
"create_creds": "시작하기 전에 웹 UI에 액세스하기 위한 새 사용자 아이디와 비밀번호를 만들어야 합니다.",
|
||||
"create_creds_alert": "선샤인의 웹 UI에 액세스하려면 아래 자격 증명이 필요합니다. 다시는 볼 수 없으니 안전하게 보관하세요!",
|
||||
"greeting": "선샤인에 오신 것을 환영합니다!",
|
||||
"greeting": "Sunshine에 오신 것을 환영합니다!",
|
||||
"login": "로그인",
|
||||
"welcome_success": "이 페이지가 곧 다시 로드되며 브라우저에서 새 자격 증명을 입력하라는 메시지가 표시됩니다."
|
||||
"welcome_success": "이 페이지는 곧 새로고침 될 것이며, 브라우저에서 다시 로그인을 해야 합니다."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,9 +172,9 @@
|
||||
"dd_mode_remapping_desc_5_sops_mixed_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过指定任何分辨率字段的条目。",
|
||||
"dd_mode_remapping_desc_5_sops_resolution_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过映射。",
|
||||
"dd_mode_remapping_final_refresh_rate": "最终刷新率",
|
||||
"dd_mode_remapping_final_resolution": "最后决议",
|
||||
"dd_mode_remapping_final_resolution": "最终分辨率",
|
||||
"dd_mode_remapping_requested_fps": "请求FPS",
|
||||
"dd_mode_remapping_requested_resolution": "请求的决议",
|
||||
"dd_mode_remapping_requested_resolution": "请求的分辨率",
|
||||
"dd_options_header": "高级显示设备选项",
|
||||
"dd_refresh_rate_option": "刷新率",
|
||||
"dd_refresh_rate_option_auto": "使用客户端提供的 FPS 值 (默认)",
|
||||
|
||||
@@ -44,8 +44,8 @@ class SunshineVersion {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < Math.min(3, this.versionParts.length, otherVersionParts.length); i++) {
|
||||
if (this.versionParts[i] > otherVersionParts[i]) {
|
||||
return true;
|
||||
if (this.versionParts[i] !== otherVersionParts[i]) {
|
||||
return this.versionParts[i] > otherVersionParts[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -2,14 +2,19 @@
|
||||
* @file tests/unit/test_httpcommon.cpp
|
||||
* @brief Test src/httpcommon.*.
|
||||
*/
|
||||
// test imports
|
||||
#include "../tests_common.h"
|
||||
|
||||
// lib imports
|
||||
#include <curl/curl.h>
|
||||
|
||||
// local imports
|
||||
#include <src/httpcommon.h>
|
||||
|
||||
struct UrlEscapeTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
|
||||
|
||||
TEST_P(UrlEscapeTest, Run) {
|
||||
auto [input, expected] = GetParam();
|
||||
const auto &[input, expected] = GetParam();
|
||||
ASSERT_EQ(http::url_escape(input), expected);
|
||||
}
|
||||
|
||||
@@ -26,7 +31,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
struct UrlGetHostTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
|
||||
|
||||
TEST_P(UrlGetHostTest, Run) {
|
||||
auto [input, expected] = GetParam();
|
||||
const auto &[input, expected] = GetParam();
|
||||
ASSERT_EQ(http::url_get_host(input), expected);
|
||||
}
|
||||
|
||||
@@ -43,10 +48,10 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
struct DownloadFileTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
|
||||
|
||||
TEST_P(DownloadFileTest, Run) {
|
||||
auto [url, filename] = GetParam();
|
||||
const auto &[url, filename] = GetParam();
|
||||
const std::string test_dir = platf::appdata().string() + "/tests/";
|
||||
std::basic_string path = test_dir + filename;
|
||||
ASSERT_TRUE(http::download_file(url, path));
|
||||
std::string path = test_dir + filename;
|
||||
ASSERT_TRUE(http::download_file(url, path, CURL_SSLVERSION_TLSv1_0));
|
||||
}
|
||||
|
||||
#ifdef SUNSHINE_BUILD_FLATPAK
|
||||
|
||||
Vendored
+1
-1
Submodule third-party/doxyconfig updated: 4c9452482b...4501c7b191
Vendored
+1
-1
Submodule third-party/libdisplaydevice updated: 63599b0765...1975f75add
Vendored
+1
-1
Submodule third-party/tray updated: ebbd14fe6a...d45306e686
Reference in New Issue
Block a user