From 5e0874c8f3dc9784c255153352a86f0650da7a9c Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Thu, 14 Aug 2025 13:57:01 +0200 Subject: [PATCH 1/5] feat(input/linux): allow ds5 gamepads to have a fixed device mac based on gamepad global index --- docs/configuration.md | 24 +++++++++++++++++ src/config.cpp | 1 + src/config.h | 1 + .../linux/input/inputtino_gamepad.cpp | 12 ++++++--- .../common/assets/web/configs/tabs/Inputs.vue | 26 +++++++++++++++++++ .../assets/web/public/assets/locale/en.json | 3 +++ 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index a1ae900c368..70e2a97bec4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -416,6 +416,30 @@ editing the `conf` file in a text editor. Use the examples as reference. +### ds5_inputtino_randomize_mac + + + + + + + + + + + + + + +
Description + Randomize the MAC-Address for the generated virtual controller. + @hint{Only applies on linux for gamepads created as PS5-style controllers} +
Default@code{} + enabled + @endcode
Example@code{} + ds5_inputtino_randomize_mac = enabled + @endcode
+ ### back_button_timeout diff --git a/src/config.cpp b/src/config.cpp index 24ef2a084e0..5268af669d5 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1216,6 +1216,7 @@ namespace config { bool_f(vars, "ds4_back_as_touchpad_click", input.ds4_back_as_touchpad_click); bool_f(vars, "motion_as_ds4", input.motion_as_ds4); bool_f(vars, "touchpad_as_ds4", input.touchpad_as_ds4); + bool_f(vars, "ds5_inputtino_randomize_mac", input.ds5_inputtino_randomize_mac); bool_f(vars, "mouse", input.mouse); bool_f(vars, "keyboard", input.keyboard); diff --git a/src/config.h b/src/config.h index 287efaf5a0a..cda1f7c69e4 100644 --- a/src/config.h +++ b/src/config.h @@ -193,6 +193,7 @@ namespace config { bool ds4_back_as_touchpad_click; bool motion_as_ds4; bool touchpad_as_ds4; + bool ds5_inputtino_randomize_mac; bool keyboard; bool mouse; diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index 438146317c6..350d6ae3d5c 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -42,8 +42,14 @@ namespace platf::gamepad { .version = 0x8111}); } - auto create_ds5() { - return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111}); + auto create_ds5(int globalIndex) { + if (!config::input.ds5_inputtino_randomize_mac && globalIndex >= 0 && globalIndex <= 255) { + // Generate private virtual device MAC based on gamepad globalIndex between 0 (00) and 255 (ff) + std::string device_mac = std::format("02:00:00:00:00:{:#02x}", globalIndex); + return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys=device_mac, .device_uniq=device_mac}); + } else { + 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) { @@ -138,7 +144,7 @@ namespace platf::gamepad { } case DualSenseWired: { - auto ds5 = create_ds5(); + auto ds5 = create_ds5(id.globalIndex); if (ds5) { (*ds5).set_on_rumble(on_rumble_fn); (*ds5).set_on_led([feedback_queue, idx = id.clientRelativeIndex, gamepad](int r, int g, int b) { diff --git a/src_assets/common/assets/web/configs/tabs/Inputs.vue b/src_assets/common/assets/web/configs/tabs/Inputs.vue index 2e7a081f85a..d639c5e12ed 100644 --- a/src_assets/common/assets/web/configs/tabs/Inputs.vue +++ b/src_assets/common/assets/web/configs/tabs/Inputs.vue @@ -89,6 +89,32 @@ const config = ref(props.config) + diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index 160c138682f..ab3907c1dc9 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -195,6 +195,8 @@ "dd_wa_hdr_toggle_delay": "High-contrast workaround for HDR", "ds4_back_as_touchpad_click": "Map Back/Select to Touchpad Click", "ds4_back_as_touchpad_click_desc": "When forcing DS4 emulation, map Back/Select to Touchpad Click", + "ds5_inputtino_randomize_mac": "Randomize virtual controller MAC", + "ds5_inputtino_randomize_mac_desc": "Upon controller registration use a random MAC instead of one based on the controllers internal index to avoid mixing configuration settings of different controllers when the are swapped on client-side.", "encoder": "Force a Specific Encoder", "encoder_desc": "Force a specific encoder, otherwise Sunshine will select the best available option. Note: If you specify a hardware encoder on Windows, it must match the GPU where the display is connected.", "encoder_software": "Software", @@ -213,6 +215,7 @@ "gamepad_ds4": "DS4 (PS4)", "gamepad_ds4_manual": "DS4 selection options", "gamepad_ds5": "DS5 (PS5)", + "gamepad_ds5_manual": "DS5 selection options", "gamepad_switch": "Nintendo Pro (Switch)", "gamepad_manual": "Manual DS4 options", "gamepad_x360": "X360 (Xbox 360)", From 4335094c4865d9506df88d19f1fb1865099a465c Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Thu, 14 Aug 2025 16:04:14 +0200 Subject: [PATCH 2/5] Update create_ds5 function as suggested + refactor to match other controllers formatting --- src/platform/linux/input/inputtino_gamepad.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index 350d6ae3d5c..d1bef1ae79a 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -43,13 +43,22 @@ namespace platf::gamepad { } auto create_ds5(int globalIndex) { + std::string device_mac; + if (!config::input.ds5_inputtino_randomize_mac && globalIndex >= 0 && globalIndex <= 255) { // Generate private virtual device MAC based on gamepad globalIndex between 0 (00) and 255 (ff) - std::string device_mac = std::format("02:00:00:00:00:{:#02x}", globalIndex); - return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys=device_mac, .device_uniq=device_mac}); + device_mac = std::format("02:00:00:00:00:{:#02x}", globalIndex); } else { - return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111}); + // Inputtino checks empty() to generate a random MAC + device_mac = ""; } + + return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", + .vendor_id = 0x054C, + .product_id = 0x0CE6, + .version = 0x8111, + .device_phys=device_mac, + .device_uniq=device_mac}); } int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) { From e968f3be87e57ec263957d36072971aa851fa777 Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Thu, 14 Aug 2025 20:27:18 +0200 Subject: [PATCH 3/5] Fix indents and supported_gamepad probing by using index -1 to force a random MAC --- src/platform/linux/input/inputtino_gamepad.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index d1bef1ae79a..dc4ac523e0e 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -54,11 +54,11 @@ namespace platf::gamepad { } return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", - .vendor_id = 0x054C, - .product_id = 0x0CE6, - .version = 0x8111, - .device_phys=device_mac, - .device_uniq=device_mac}); + .vendor_id = 0x054C, + .product_id = 0x0CE6, + .version = 0x8111, + .device_phys=device_mac, + .device_uniq=device_mac}); } int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) { @@ -282,7 +282,7 @@ namespace platf::gamepad { return gps; } - auto ds5 = create_ds5(); + auto ds5 = create_ds5(-1); // Index -1 will result in a random MAC virtual device, which is fine for probing auto switchPro = create_switch(); auto xOne = create_xbox_one(); From 8da818535652a1df73f6311a1468b3e34e73c399 Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Fri, 15 Aug 2025 08:40:43 +0200 Subject: [PATCH 4/5] Remove leading base prefix for generated mac --- src/platform/linux/input/inputtino_gamepad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index dc4ac523e0e..97c375b173a 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -47,7 +47,7 @@ namespace platf::gamepad { if (!config::input.ds5_inputtino_randomize_mac && globalIndex >= 0 && globalIndex <= 255) { // Generate private virtual device MAC based on gamepad globalIndex between 0 (00) and 255 (ff) - device_mac = std::format("02:00:00:00:00:{:#02x}", globalIndex); + device_mac = std::format("02:00:00:00:00:{:02x}", globalIndex); } else { // Inputtino checks empty() to generate a random MAC device_mac = ""; From 77a9a62df3af65ab8244f79ed3fe28b96b5edabc Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Sat, 16 Aug 2025 18:12:28 +0200 Subject: [PATCH 5/5] Add requested changes and fix lint errors --- src/platform/linux/input/inputtino_gamepad.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index 97c375b173a..7e782b59b21 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -43,22 +43,14 @@ namespace platf::gamepad { } auto create_ds5(int globalIndex) { - std::string device_mac; + std::string device_mac = ""; // Inputtino checks empty() to generate a random MAC if (!config::input.ds5_inputtino_randomize_mac && globalIndex >= 0 && globalIndex <= 255) { // Generate private virtual device MAC based on gamepad globalIndex between 0 (00) and 255 (ff) device_mac = std::format("02:00:00:00:00:{:02x}", globalIndex); - } else { - // Inputtino checks empty() to generate a random MAC - device_mac = ""; } - return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", - .vendor_id = 0x054C, - .product_id = 0x0CE6, - .version = 0x8111, - .device_phys=device_mac, - .device_uniq=device_mac}); + return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys = device_mac, .device_uniq = device_mac}); } int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) { @@ -282,7 +274,7 @@ namespace platf::gamepad { return gps; } - auto ds5 = create_ds5(-1); // Index -1 will result in a random MAC virtual device, which is fine for probing + auto ds5 = create_ds5(-1); // Index -1 will result in a random MAC virtual device, which is fine for probing auto switchPro = create_switch(); auto xOne = create_xbox_one();