Merge remote-tracking branch 'sunshine/master'
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
# install dependencies for C++ analysis
|
||||
set -e
|
||||
|
||||
# setup homebrew for x86_64
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
|
||||
# install dependencies
|
||||
dependencies=(
|
||||
"boost"
|
||||
|
||||
@@ -25,6 +25,9 @@ install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/service/"
|
||||
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/migration/"
|
||||
DESTINATION "scripts"
|
||||
COMPONENT assets)
|
||||
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/path/"
|
||||
DESTINATION "scripts"
|
||||
COMPONENT assets)
|
||||
|
||||
# Configurable options for the service
|
||||
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/autostart/"
|
||||
@@ -69,6 +72,7 @@ SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
|
||||
IfSilent +2 0
|
||||
# ExecShell 'open' 'https://docs.lizardbyte.dev/projects/sunshine'
|
||||
nsExec::ExecToLog 'icacls \\\"$INSTDIR\\\" /reset'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\update-path.bat\\\" add'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\drivers\\\\sudovda\\\\install.bat\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\migrate-config.bat\\\"'
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\add-firewall-rule.bat\\\"'
|
||||
@@ -99,16 +103,18 @@ set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
|
||||
'Do you want to remove $INSTDIR (this includes the configuration, cover images, and settings)?' \
|
||||
/SD IDNO IDNO NoDelete
|
||||
RMDir /r \\\"$INSTDIR\\\"; skipped if no
|
||||
nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\update-path.bat\\\" remove'
|
||||
NoDelete:
|
||||
")
|
||||
|
||||
# Adding an option for the start menu
|
||||
set(CPACK_NSIS_MODIFY_PATH "OFF")
|
||||
set(CPACK_NSIS_MODIFY_PATH OFF)
|
||||
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
# This will be shown on the installed apps Windows settings
|
||||
set(CPACK_NSIS_INSTALLED_ICON_NAME "sunshine.exe")
|
||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA
|
||||
"${CPACK_NSIS_CREATE_ICONS_EXTRA}
|
||||
SetOutPath '\$INSTDIR'
|
||||
CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' \
|
||||
'\$INSTDIR\\\\sunshine.exe' '--shortcut'
|
||||
")
|
||||
|
||||
@@ -335,8 +335,6 @@ recommended for most users. No support will be provided!}
|
||||
scripts/uninstall-service.bat
|
||||
```
|
||||
|
||||
To uninstall, delete the extracted directory which contains the `sunshine.exe` file.
|
||||
|
||||
## Initial Setup
|
||||
After installation, some initial setup is required.
|
||||
|
||||
|
||||
@@ -118,6 +118,16 @@ system. You may also want to enable decoders, however that is not required for S
|
||||
```
|
||||
}
|
||||
|
||||
### Input not working
|
||||
After installation, the `udev` rules need to be reloaded. Our post-install script tries to do this for you
|
||||
automatically, but if it fails you may need to restart your system.
|
||||
|
||||
If the input is still not working, you may need to add your user to the `input` group.
|
||||
|
||||
```bash
|
||||
sudo usermod -aG input $USER
|
||||
```
|
||||
|
||||
@note{Other build options are listed in the
|
||||
[meson options](https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/meson_options.txt) file.}
|
||||
|
||||
|
||||
@@ -538,11 +538,11 @@ ext-js:
|
||||
<div class="card-footer p-3 px-4">
|
||||
<a class="latest-button btn btn-outline-light me-3 mb-3 d-none" href="https://github.com/LizardByte/Sunshine/releases/latest" target="_blank">
|
||||
<i class="fa-fw fab fa-github"></i>
|
||||
Latest: <span id="latest-version"></span>
|
||||
Latest: <span id="latest-version" class="crowdin-ignore"></span>
|
||||
</a>
|
||||
<a class="beta-button btn btn-outline-light me-3 mb-3 d-none" href="#" target="_blank">
|
||||
<i class="fa-fw fas fa-flask"></i>
|
||||
Beta: <span id="beta-version"></span>
|
||||
Beta: <span id="beta-version" class="crowdin-ignore"></span>
|
||||
</a>
|
||||
<a class="btn btn-outline-light me-3 mb-3" href="https://github.com/LizardByte/pacman-repo" target="_blank">
|
||||
<i class="fa-fw fab fa-linux"></i>
|
||||
@@ -577,16 +577,21 @@ ext-js:
|
||||
// Filter the releases to get only the stable releases
|
||||
const stableReleases = data.filter(release => !release.prerelease);
|
||||
|
||||
const latestButton = document.querySelector('.latest-button');
|
||||
const latestVersion = document.querySelector('#latest-version');
|
||||
const betaButton = document.querySelector('.beta-button');
|
||||
const betaVersion = document.querySelector('#beta-version');
|
||||
|
||||
// If there are no stable releases, hide the latest download button
|
||||
if (stableReleases.length === 0) {
|
||||
document.querySelector('.latest-button').classList.add('d-none');
|
||||
latestButton.classList.add('d-none');
|
||||
} else {
|
||||
// Show the latest download button
|
||||
document.querySelector('.latest-button').classList.remove('d-none');
|
||||
latestButton.classList.remove('d-none');
|
||||
|
||||
// Get the latest stable release
|
||||
const latestStableRelease = stableReleases[0];
|
||||
document.querySelector('#latest-version').textContent = latestStableRelease.tag_name;
|
||||
latestVersion.textContent = latestStableRelease.tag_name;
|
||||
|
||||
// If there is a pre-release, update the href attribute of the anchor tag
|
||||
if (preReleases.length > 0) {
|
||||
@@ -598,16 +603,16 @@ ext-js:
|
||||
|
||||
// If the pre-release is newer, update the href attribute of the anchor tag
|
||||
if (preReleaseDate > stableReleaseDate) {
|
||||
document.querySelector('.beta-button').href = latestPreRelease.html_url;
|
||||
document.querySelector('#beta-version').textContent = latestPreRelease.tag_name;
|
||||
document.querySelector('.beta-button').classList.remove('d-none');
|
||||
betaButton.href = latestPreRelease.html_url;
|
||||
betaVersion.textContent = latestPreRelease.tag_name;
|
||||
betaButton.classList.remove('d-none');
|
||||
} else {
|
||||
// If the pre-release is older, hide the button
|
||||
document.querySelector('.beta-button').classList.add('d-none');
|
||||
betaButton.classList.add('d-none');
|
||||
}
|
||||
} else {
|
||||
// If there is no pre-release, hide the button
|
||||
document.querySelector('.beta-button').classList.add('d-none');
|
||||
betaButton.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"serve": "serve ./tests/fixtures/http --no-port-switching"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lizardbyte/shared-web": "2025.221.2011",
|
||||
"@lizardbyte/shared-web": "2025.326.11214",
|
||||
"vue": "3.5.13",
|
||||
"vue-i18n": "11.1.2"
|
||||
},
|
||||
|
||||
Submodule packaging/linux/flatpak/deps/shared-modules updated: a6c788b38f...1f8e591b26
@@ -50,14 +50,32 @@
|
||||
"name": "libXmu",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://xorg.freedesktop.org/archive/individual/lib/libXmu-1.2.1.tar.gz",
|
||||
"sha256": "bf0902583dd1123856c11e0a5085bd3c6e9886fbbd44954464975fd7d52eb599",
|
||||
"type": "git",
|
||||
"url": "https://github.com/LizardByte-infrastructure/libxmu.git",
|
||||
"tag": "libXmu-1.2.1",
|
||||
"commit": "792f80402ee06ce69bca3a8f2a84295999c3a170",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 1785,
|
||||
"stable-only": true,
|
||||
"url-template": "https://xorg.freedesktop.org/archive/individual/lib/libXmu-$version.tar.gz"
|
||||
"tag-template": "libXmu-$version"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "font-util",
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/LizardByte-infrastructure/font-util.git",
|
||||
"tag": "font-util-1.4.1",
|
||||
"commit": "b5ca142f81a6f14eddb23be050291d1c25514777",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 15055,
|
||||
"stable-only": true,
|
||||
"tag-template": "font-util-$version"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -66,14 +84,15 @@
|
||||
"name": "libfontenc",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://xorg.freedesktop.org/archive/individual/lib/libfontenc-1.1.8.tar.xz",
|
||||
"sha256": "7b02c3d405236e0d86806b1de9d6868fe60c313628b38350b032914aa4fd14c6",
|
||||
"type": "git",
|
||||
"url": "https://github.com/LizardByte-infrastructure/libfontenc.git",
|
||||
"tag": "libfontenc-1.1.8",
|
||||
"commit": "92a85fda2acb4e14ec0b2f6d8fe3eaf2b687218c",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 1613,
|
||||
"stable-only": true,
|
||||
"url-template": "https://xorg.freedesktop.org/archive/individual/lib/libfontenc-$version.tar.xz"
|
||||
"tag-template": "libfontenc-$version"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -97,34 +116,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "font-util",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://xorg.freedesktop.org/archive/individual/font/font-util-1.4.1.tar.gz",
|
||||
"sha256": "f029ae80cdd75d89bee7f7af61c21e07982adfb9f72344a158b99f91f77ef5ed",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 15055,
|
||||
"stable-only": true,
|
||||
"url-template": "https://xorg.freedesktop.org/archive/individual/font/font-util-$version.tar.gz"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "xvfb-libXfont2",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://xorg.freedesktop.org/archive/individual/lib/libXfont2-2.0.6.tar.gz",
|
||||
"sha256": "a944df7b6837c8fa2067f6a5fc25d89b0acc4011cd0bc085106a03557fb502fc",
|
||||
"type": "git",
|
||||
"url": "https://github.com/LizardByte-infrastructure/libxfont.git",
|
||||
"tag": "libXfont2-2.0.6",
|
||||
"commit": "d54aaf2483df6a1f98fadc09004157e657b7f73e",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 17165,
|
||||
"stable-only": true,
|
||||
"url-template": "https://xorg.freedesktop.org/archive/individual/lib/libXfont2-$version.tar.gz"
|
||||
"tag-template": "libXfont2-$version"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,4 +8,4 @@ echo Sunshine User Service has been removed.
|
||||
|
||||
# Udev rule
|
||||
flatpak-spawn --host pkexec sh -c "rm /etc/udev/rules.d/60-sunshine.rules"
|
||||
echo Mouse permission removed. Restart computer to take effect.
|
||||
echo Input rules removed. Restart computer to take effect.
|
||||
|
||||
@@ -665,9 +665,13 @@ namespace config {
|
||||
// Lists might contain newlines
|
||||
if (*begin_val == '[') {
|
||||
endl = skip_list(begin_val + 1, end);
|
||||
if (endl == end) {
|
||||
std::cout << "Warning: Config option ["sv << to_string(begin, end_name) << "] Missing ']'"sv;
|
||||
|
||||
// Check if we reached the end of the file without finding a closing bracket
|
||||
// We know we have a valid closing bracket if:
|
||||
// 1. We didn't reach the end, or
|
||||
// 2. We reached the end but the last character was the matching closing bracket
|
||||
if (endl == end && end == begin_val + 1) {
|
||||
BOOST_LOG(warning) << "config: Missing ']' in config option: " << to_string(begin, end_name);
|
||||
return std::make_pair(endl, std::nullopt);
|
||||
}
|
||||
}
|
||||
@@ -1027,7 +1031,7 @@ namespace config {
|
||||
|
||||
// The list needs to be a multiple of 2
|
||||
if (list.size() % 2) {
|
||||
std::cout << "Warning: expected "sv << name << " to have a multiple of two elements --> not "sv << list.size() << std::endl;
|
||||
BOOST_LOG(warning) << "config: expected "sv << name << " to have a multiple of two elements --> not "sv << list.size();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1057,7 +1061,7 @@ namespace config {
|
||||
config::sunshine.flags[config::flag::UPNP].flip();
|
||||
break;
|
||||
default:
|
||||
std::cout << "Warning: Unrecognized flag: ["sv << *line << ']' << std::endl;
|
||||
BOOST_LOG(warning) << "config: Unrecognized flag: ["sv << *line << ']' << std::endl;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@@ -1083,11 +1087,7 @@ namespace config {
|
||||
}
|
||||
|
||||
for (auto &[name, val] : vars) {
|
||||
#ifdef _WIN32
|
||||
std::cout << "["sv << name << "] -- ["sv << utf8ToAcp(val) << ']' << std::endl;
|
||||
#else
|
||||
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
|
||||
#endif
|
||||
BOOST_LOG(info) << "config: '"sv << name << "' = "sv << val;
|
||||
}
|
||||
|
||||
bool_f(vars, "headless_mode", video.headless_mode);
|
||||
@@ -1485,7 +1485,7 @@ namespace config {
|
||||
shell_exec_info.nShow = SW_NORMAL;
|
||||
if (!ShellExecuteExW(&shell_exec_info)) {
|
||||
auto winerr = GetLastError();
|
||||
std::cout << "Error: ShellExecuteEx() failed:"sv << winerr << std::endl;
|
||||
BOOST_LOG(error) << "Failed executing shell command: " << winerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,10 +108,6 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
mail::man = std::make_shared<safe::mail_raw_t>();
|
||||
|
||||
if (config::parse(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto log_deinit_guard = logging::init(config::sunshine.min_log_level, config::sunshine.log_file);
|
||||
if (!log_deinit_guard) {
|
||||
BOOST_LOG(error) << "Logging failed to initialize"sv;
|
||||
@@ -125,6 +121,11 @@ int main(int argc, char *argv[]) {
|
||||
// Log publisher metadata
|
||||
log_publisher_data();
|
||||
|
||||
// parse config file
|
||||
if (config::parse(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!config::sunshine.cmd.name.empty()) {
|
||||
auto fn = cmd_to_func.find(config::sunshine.cmd.name);
|
||||
if (fn == std::end(cmd_to_func)) {
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace platf {
|
||||
rumble_triggers, ///< Rumble triggers
|
||||
set_motion_event_state, ///< Set motion event state
|
||||
set_rgb_led, ///< Set RGB LED
|
||||
set_adaptive_triggers, ///< Set adaptive triggers
|
||||
};
|
||||
|
||||
struct gamepad_feedback_msg_t {
|
||||
@@ -142,6 +143,14 @@ namespace platf {
|
||||
return msg;
|
||||
}
|
||||
|
||||
static gamepad_feedback_msg_t make_adaptive_triggers(std::uint16_t id, uint8_t event_flags, uint8_t type_left, uint8_t type_right, const std::array<uint8_t, 10> &left, const std::array<uint8_t, 10> &right) {
|
||||
gamepad_feedback_msg_t msg;
|
||||
msg.type = gamepad_feedback_e::set_adaptive_triggers;
|
||||
msg.id = id;
|
||||
msg.data.adaptive_triggers = {.event_flags = event_flags, .type_left = type_left, .type_right = type_right, .left = left, .right = right};
|
||||
return msg;
|
||||
}
|
||||
|
||||
gamepad_feedback_e type;
|
||||
std::uint16_t id;
|
||||
|
||||
@@ -166,6 +175,15 @@ namespace platf {
|
||||
std::uint8_t g;
|
||||
std::uint8_t b;
|
||||
} rgb_led;
|
||||
|
||||
struct {
|
||||
uint16_t controllerNumber;
|
||||
uint8_t event_flags;
|
||||
uint8_t type_left;
|
||||
uint8_t type_right;
|
||||
std::array<uint8_t, 10> left;
|
||||
std::array<uint8_t, 10> right;
|
||||
} adaptive_triggers;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace platf::gamepad {
|
||||
}
|
||||
|
||||
auto create_ds5() {
|
||||
return inputtino::PS5Joypad::create({.name = "Sunshine DualSense (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
|
||||
return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
|
||||
}
|
||||
|
||||
int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) {
|
||||
@@ -152,6 +152,10 @@ namespace platf::gamepad {
|
||||
gamepad->last_rgb_led = msg;
|
||||
});
|
||||
|
||||
(*ds5).set_on_trigger_effect([feedback_queue, idx = id.clientRelativeIndex](const inputtino::PS5Joypad::TriggerEffect &trigger_effect) {
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_adaptive_triggers(idx, trigger_effect.event_flags, trigger_effect.type_left, trigger_effect.type_right, trigger_effect.left, trigger_effect.right));
|
||||
});
|
||||
|
||||
// Activate the motion sensors
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_ACCEL, 100));
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_GYRO, 100));
|
||||
|
||||
@@ -52,6 +52,7 @@ extern "C" {
|
||||
#define IDX_EXEC_SERVER_CMD 15
|
||||
#define IDX_SET_CLIPBOARD 16
|
||||
#define IDX_FILE_TRANSFER_NONCE_REQUEST 17
|
||||
#define IDX_SET_ADAPTIVE_TRIGGERS 18
|
||||
|
||||
static const short packetTypes[] = {
|
||||
0x0305, // Start A
|
||||
@@ -72,6 +73,7 @@ static const short packetTypes[] = {
|
||||
0x3000, // Execute Server Command (Apollo protocol extension)
|
||||
0x3001, // Set Clipboard (Apollo protocol extension)
|
||||
0x3002, // File transfer nonce request (Apollo protocol extension)
|
||||
0x5503, // Set Adaptive triggers (Sunshine protocol extension)
|
||||
};
|
||||
|
||||
namespace asio = boost::asio;
|
||||
@@ -193,6 +195,21 @@ namespace stream {
|
||||
std::uint8_t b;
|
||||
};
|
||||
|
||||
struct control_adaptive_triggers_t {
|
||||
control_header_v2 header;
|
||||
|
||||
std::uint16_t id;
|
||||
/**
|
||||
* 0x04 - Right trigger
|
||||
* 0x08 - Left trigger
|
||||
*/
|
||||
std::uint8_t event_flags;
|
||||
std::uint8_t type_left;
|
||||
std::uint8_t type_right;
|
||||
std::uint8_t left[DS_EFFECT_PAYLOAD_SIZE];
|
||||
std::uint8_t right[DS_EFFECT_PAYLOAD_SIZE];
|
||||
};
|
||||
|
||||
struct control_hdr_mode_t {
|
||||
control_header_v2 header;
|
||||
|
||||
@@ -846,6 +863,22 @@ namespace stream {
|
||||
plaintext.b = data.b;
|
||||
|
||||
BOOST_LOG(verbose) << "RGB: "sv << msg.id << " :: "sv << util::hex(data.r).to_string_view() << util::hex(data.g).to_string_view() << util::hex(data.b).to_string_view();
|
||||
std::array<std::uint8_t, sizeof(control_encrypted_t) + crypto::cipher::round_to_pkcs7_padded(sizeof(plaintext)) + crypto::cipher::tag_size>
|
||||
encrypted_payload;
|
||||
|
||||
payload = encode_control(session, util::view(plaintext), encrypted_payload);
|
||||
} else if (msg.type == platf::gamepad_feedback_e::set_adaptive_triggers) {
|
||||
control_adaptive_triggers_t plaintext;
|
||||
plaintext.header.type = packetTypes[IDX_SET_ADAPTIVE_TRIGGERS];
|
||||
plaintext.header.payloadLength = sizeof(plaintext) - sizeof(control_header_v2);
|
||||
|
||||
plaintext.id = util::endian::little(msg.id);
|
||||
plaintext.event_flags = msg.data.adaptive_triggers.event_flags;
|
||||
plaintext.type_left = msg.data.adaptive_triggers.type_left;
|
||||
std::ranges::copy(msg.data.adaptive_triggers.left, plaintext.left);
|
||||
plaintext.type_right = msg.data.adaptive_triggers.type_right;
|
||||
std::ranges::copy(msg.data.adaptive_triggers.right, plaintext.right);
|
||||
|
||||
std::array<std::uint8_t, sizeof(control_encrypted_t) + crypto::cipher::round_to_pkcs7_padded(sizeof(plaintext)) + crypto::cipher::tag_size>
|
||||
encrypted_payload;
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@
|
||||
<b>{{ $t('_common.success') }}</b> {{ $t('config.restart_note') }}
|
||||
</div>
|
||||
<div class="mb-3 buttons">
|
||||
<button class="btn btn-primary" @click="save">{{ $t('_common.save') }}</button>
|
||||
<button class="btn btn-success mx-2" @click="apply" v-if="saved && !restarted">{{ $t('_common.apply') }}</button>
|
||||
<button class="btn btn-primary mr-3" @click="save">{{ $t('_common.save') }}</button>
|
||||
<button class="btn btn-success" @click="apply" v-if="saved && !restarted">{{ $t('_common.apply') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,2 +1,11 @@
|
||||
# Allows Sunshine to acces /dev/uinput
|
||||
KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"
|
||||
|
||||
# Allows Sunshine to access /dev/uhid
|
||||
KERNEL=="uhid", TAG+="uaccess"
|
||||
|
||||
# Joypads
|
||||
KERNEL=="hidraw*" ATTRS{name}=="Sunshine PS5 (virtual) pad" MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEMS=="input", ATTRS{name}=="Sunshine X-Box One (virtual) pad", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEMS=="input", ATTRS{name}=="Sunshine gamepad (virtual) motion sensors", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEMS=="input", ATTRS{name}=="Sunshine Nintendo (virtual) pad", MODE="0660", TAG+="uaccess"
|
||||
|
||||
@@ -7,17 +7,12 @@ rem Note: We use exit code 2 to indicate success because either 0 or 1 may be re
|
||||
rem based on the PowerShell version if an exception occurs.
|
||||
powershell -c Exit $(if ((Get-Item "$env:SystemRoot\System32\drivers\ViGEmBus.sys").VersionInfo.FileVersion -ge [System.Version]"1.17") { 2 } Else { 1 })
|
||||
if %ERRORLEVEL% EQU 2 (
|
||||
goto skip
|
||||
echo "The installed version is 1.17 or later, no update needed. Exiting."
|
||||
exit /b 0
|
||||
)
|
||||
goto continue
|
||||
|
||||
:skip
|
||||
echo "The installed version is 1.17 or later, no update needed. Exiting."
|
||||
exit /b 0
|
||||
|
||||
:continue
|
||||
rem Get temp directory
|
||||
set temp_dir=%temp%/Sunshine
|
||||
set temp_dir=%temp%/Apollo
|
||||
|
||||
rem Create temp directory if it doesn't exist
|
||||
if not exist "%temp_dir%" mkdir "%temp_dir%"
|
||||
|
||||
111
src_assets/windows/misc/path/update-path.bat
Normal file
111
src_assets/windows/misc/path/update-path.bat
Normal file
@@ -0,0 +1,111 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
rem Check if parameter is provided
|
||||
if "%~1"=="" (
|
||||
echo Usage: %0 [add^|remove]
|
||||
echo add - Adds Apollo directories to system PATH
|
||||
echo remove - Removes Apollo directories from system PATH
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
rem Get Apollo root directory
|
||||
for %%I in ("%~dp0\..") do set "ROOT_DIR=%%~fI"
|
||||
echo Apollo root directory: !ROOT_DIR!
|
||||
|
||||
rem Define directories to add to path
|
||||
set "PATHS_TO_MANAGE[0]=!ROOT_DIR!"
|
||||
set "PATHS_TO_MANAGE[1]=!ROOT_DIR!\tools"
|
||||
|
||||
rem System path registry location
|
||||
set "KEY_NAME=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
|
||||
set "VALUE_NAME=Path"
|
||||
|
||||
rem Get the current path
|
||||
for /f "tokens=2*" %%A in ('reg query "%KEY_NAME%" /v "%VALUE_NAME%"') do set "CURRENT_PATH=%%B"
|
||||
echo Current path: !CURRENT_PATH!
|
||||
|
||||
rem Check if adding to path
|
||||
if /i "%~1"=="add" (
|
||||
set "NEW_PATH=!CURRENT_PATH!"
|
||||
|
||||
rem Process each directory to add
|
||||
for /L %%i in (0,1,1) do (
|
||||
set "DIR_TO_ADD=!PATHS_TO_MANAGE[%%i]!"
|
||||
|
||||
rem Check if path already contains this directory
|
||||
echo "!CURRENT_PATH!" | findstr /i /c:"!DIR_TO_ADD!" > nul
|
||||
if !ERRORLEVEL!==0 (
|
||||
echo !DIR_TO_ADD! already in path
|
||||
) else (
|
||||
echo Adding to path: !DIR_TO_ADD!
|
||||
set "NEW_PATH=!NEW_PATH!;!DIR_TO_ADD!"
|
||||
)
|
||||
)
|
||||
|
||||
rem Only update if path was changed
|
||||
if "!NEW_PATH!" neq "!CURRENT_PATH!" (
|
||||
rem Set the new path in the registry
|
||||
reg add "%KEY_NAME%" /v "%VALUE_NAME%" /t REG_EXPAND_SZ /d "!NEW_PATH!" /f
|
||||
if !ERRORLEVEL!==0 (
|
||||
echo Successfully added Apollo directories to PATH
|
||||
) else (
|
||||
echo Failed to add Apollo directories to PATH
|
||||
)
|
||||
) else (
|
||||
echo No changes needed to PATH
|
||||
)
|
||||
exit /b !ERRORLEVEL!
|
||||
)
|
||||
|
||||
rem Check if removing from path
|
||||
if /i "%~1"=="remove" (
|
||||
set "CHANGES_MADE=0"
|
||||
|
||||
rem Process each directory to remove
|
||||
for /L %%i in (0,1,1) do (
|
||||
set "DIR_TO_REMOVE=!PATHS_TO_MANAGE[%%i]!"
|
||||
|
||||
rem Check if path contains this directory
|
||||
echo "!CURRENT_PATH!" | findstr /i /c:"!DIR_TO_REMOVE!" > nul
|
||||
if !ERRORLEVEL!==0 (
|
||||
echo Removing from path: !DIR_TO_REMOVE!
|
||||
|
||||
rem Build a new path by parsing and filtering the current path
|
||||
set "NEW_PATH="
|
||||
for %%p in ("!CURRENT_PATH:;=" "!") do (
|
||||
set "PART=%%~p"
|
||||
if /i "!PART!" NEQ "!DIR_TO_REMOVE!" (
|
||||
if defined NEW_PATH (
|
||||
set "NEW_PATH=!NEW_PATH!;!PART!"
|
||||
) else (
|
||||
set "NEW_PATH=!PART!"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
set "CURRENT_PATH=!NEW_PATH!"
|
||||
set "CHANGES_MADE=1"
|
||||
) else (
|
||||
echo !DIR_TO_REMOVE! not found in path
|
||||
)
|
||||
)
|
||||
|
||||
rem Only update if path was changed
|
||||
if "!CHANGES_MADE!"=="1" (
|
||||
rem Set the new path in the registry
|
||||
reg add "%KEY_NAME%" /v "%VALUE_NAME%" /t REG_EXPAND_SZ /d "!CURRENT_PATH!" /f
|
||||
if !ERRORLEVEL!==0 (
|
||||
echo Successfully removed Apollo directories from PATH
|
||||
) else (
|
||||
echo Failed to remove Apollo directories from PATH
|
||||
)
|
||||
) else (
|
||||
echo No changes needed to PATH
|
||||
)
|
||||
exit /b !ERRORLEVEL!
|
||||
)
|
||||
|
||||
echo Unknown parameter: %~1
|
||||
echo Usage: %0 [add^|remove]
|
||||
exit /b 1
|
||||
2
third-party/build-deps
vendored
2
third-party/build-deps
vendored
Submodule third-party/build-deps updated: 0f8f2af955...b567d3c479
2
third-party/inputtino
vendored
2
third-party/inputtino
vendored
Submodule third-party/inputtino updated: 1170b1e4ad...fd136cfe49
2
third-party/moonlight-common-c
vendored
2
third-party/moonlight-common-c
vendored
Submodule third-party/moonlight-common-c updated: 40bec19cc1...40a4e68787
Reference in New Issue
Block a user