Browser bridge: WebSocket hub + Chromium extension for web games (Xbox Cloud Gaming, GeForce NOW) - #2
Open
Andrei-Kondrykau wants to merge 8 commits into
Open
Andrei-Kondrykau wants to merge 8 commits into
Andrei-Kondrykau wants to merge 8 commits into
Conversation
…Gaming etc.) Web games only see gamepads macOS knows about, and a Switch 2 controller over BLE is not a HID device macOS can pair, so until the virtual-HID entitlement arrives browsers (Xbox Cloud Gaming, GeForce NOW, Luna) had no way to use these controllers. This applies the SDL-bridge idea to the browser: - Output/WebSocketHub.swift: a third sink serving controller state as JSON over ws://127.0.0.1:24810 (loopback only, Network.framework), with rumble coming back and a 15 s ping. - browser/extension: Manifest V3 extension. The service worker owns the socket (extension contexts are outside Chrome's Local Network Access permission), a content script relays to the page, and shim.js wraps navigator.getGamepads() with standard-mapping virtual pads, fires gamepadconnected/disconnected and forwards vibrationActuator effects. - browser/README.md + README: install steps, button table, protocol. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…f checks pass Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ng; note xCloud verification Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Author
|
Update: verified end to end on xbox.com/play with a Pro Controller 2 (Chromium, macOS 27) — sticks, buttons, triggers and rumble work in cloud games. Pushed a docs commit with step-by-step install and a troubleshooting section (browser/README.md). |
… EXTRA_BUTTONS Sites diff consecutive getGamepads() results to detect button edges; a single mutable object made previous and current identical. Extra indices beyond Share are off by default to match real Xbox pads. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Xbox Cloud Gaming parses the vendor id out of gamepad.id and applies vendor-specific glyphs/handling; with a positional layout the Xbox identity is the coherent one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ide delivery telemetry
The page now opens the loopback socket itself (shortest path under a
streaming load) and falls back to the service-worker relay only if the
browser refuses. The shim reports 5 s windows of message-arrival
intervals and getGamepads() call counts as {"t":"stats"}, which the hub
logs and echoes to other clients.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t-in Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Author
|
Follow-up after real play sessions (GeForce NOW in the browser, Pro Controller 2):
|
Owner
|
I'm just getting back to this project. Will review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A third output sink plus a small browser extension, so Switch 2 controllers work in web games (Xbox Cloud Gaming at xbox.com/play, GeForce NOW, Luna, gamepad testers) today, without waiting for the virtual-HID entitlement. Same idea as the SDL bridge, applied to the browser.
Output/WebSocketHub.swift— serves controller state as JSON overws://127.0.0.1:24810(loopback only, Network.framework's built-in WebSocket server, no dependencies). Rumble comes back the other way; a 15 s ping keeps extension service workers alive.browser/extension— Manifest V3, any Chromium browser, loaded unpacked:background.jsowns the socket. Chrome 142+ gates page-initiated loopback connections behind the new Local Network Access permission; extension contexts are not affected, so the socket lives here rather than in the page.bridge.jsrelays between the service worker and the page (strings only across worlds).shim.jswrapsnavigator.getGamepads()with standard-mapping virtual pads placed in free indices next to real gamepads, firesgamepadconnected/gamepaddisconnected, and forwardsvibrationActuator.playEffectto the hub.browser/README.md— install steps, button table, wire protocol; README gets a short section.Buttons are mapped by position by default (bottom face button → standard index 0) so Xbox on-screen prompts match the thumb;
NINTENDO_LABELSinshim.jsswitches to label mapping. The app's remapper runs before the sink, so custom layouts carry over.Why not something else
IOHIDResourceUserClient::initWithTaskin IOHIDFamily accepts only the entitlement — there is no root fallback — so CoreHID stays blocked until Apple answers.Testing
hello,connectedreplay for late clients and the ping verified with a raw WebSocket client; the sink coexists with UDPHub and VirtualHIDSink unchanged.… (STANDARD GAMEPAD Vendor: 057e Product: 2069), mappingstandard, correct axes sign (+Y down), triggers as analog buttons 6/7, rumble events reach the bridge.Ad-hoc build unaffected; no new entitlements or permissions.