Skip to content

Add support for Nethernet transport - #774

Draft
extremeheat wants to merge 1 commit into
masterfrom
nethernet
Draft

Add support for Nethernet transport#774
extremeheat wants to merge 1 commit into
masterfrom
nethernet

Conversation

@extremeheat

Copy link
Copy Markdown
Member

Adds support for the Nethernet transport alternative to RakNet now used on Realms

Target branch for continuing work in #533 by @LucienHH

* Implement Nethernet spec

* Add WebSocket signalling channel

* Add Nethernet ping advertisement

* Add Session handling

* Add nethernet transport

* Fix tests

* Correctly build credentials

* Use active broadcast address

* Fix signalling handling

* Downgrade to werift v0.19.9

* Lint

* Remove unnecessary ping

* Remove debug logs

* Send initial discovery request

* Rename `Signal` to `NethernetSignal`

* Compression, batching and protocol fixes

* Use correct buffer

* Update to latest pauth API

* Use static arguments

* Linting

* Move protocol to `node-nethernet`

* Fix connecting via signalling

* Move  nethernet properties under .nethernet.*

* Create nethernet_local.js

* Remove node-fetch

* Rename rta to session

* Implement ServerData

* Cleanup unused methods

* Lint

* Update to support PrismarineJS/nethernet

* Update Nethernet signalling support and update advertisement

* Update auth

* fix(nethernet): get ICE before offer and disable trickle candidates

The realms server expects the full ice candidate list to be bundled with
the offer. Trickled candidates are silently ignored on the server,
resulting in the handshake never completing.

* feat(signal): add jsonrpc protocol support and fix endpoint

New bedrock signalling servers use a different endpoint and the jsonrpc
format instead of the old Type/From/Message format. The old endpoint
was wss://signal.franchise.minecraft-services.net/ws/v1.0/signaling/<id>,
the new one is wss://<host>/ws/v1.0/messaging/connect with the network
id passed in the jsonrpc message body instead of the url.

- constructor now accepts an object with options.protocol and
  options.host
- init() connects to the new endpoint and uses randomUUID() for
  session-id and request-id headers instead of networkId and Date.now()
- write() sends jsonrpc or legacy format based on `this.protocol`
- onMessage() Signal case now calls parseSignalMessage() instead of
  SignalStructure.fromString() directly so both formats work
- onMessage() now has a default case that catches inbound jsonrpc
  messages and routes them to onJsonRpcMessage()
- added onJsonRpcMessage() method
- added parseSignalMessage() helper that tries jsonrpc first, falls back
  to SignalStructure.fromString() for legacy format
- added parseJsonRpcSignal() helper that extracts signal data from a
  jsonrpc payload

* feat(auth): handle NETHERNET_JSONRPC realm join in realmAuthenticate

Realms on current minecraft versions return networkProtocol:
`NETHERNET_JSONRPC` from the join endpoint instead of a host:port
address. `realmAuthenticate` now detects this and sets the nethernet
transport, networkId, and signalling host.

* feat(signal): automatically fall back to jsonrpc if legacy signalling fails

* feat(client): pass signalling host from realmAuthenticate to NethernetSignal

* fix(auth): use raw join endpoint and set options for NETHERNET_JSONRPC

realm.getAddress() strips networkProtocol from the response so we lose the
`NETHERNET_JSONRPC` flag. Call the raw `/worlds/{id}/join` endpoint
so we can get networkProtocol, address, and sessionRegionData.

For `NETHERNET_JSONRPC` realms: set skipPing, set `_signallingProtocol`
to `jsonrpc`, and `_signallingHost` to the regional signal server. Also
pass minecraftVersion to RealmAPI.from so the Realms API does not reject
the request with `unknown_client_version`.

* fix(client): init nethernet early and pass signalling protocol option

Two fixes for NetherNet Realms support:
1. `this.nethernet ??= {}` before NethernetClient creation so the object
   exists even when realmAuthenticate sets the backend after
   construction.
2. Forward `_signallingProtocol` to NethernetSignal so it knows to use
   the jsonrpc endpoint instead of the legacy endpoint.

* fix(createClient): read skipPing from client.options

realmAuthenticate adds skipPing, transport, networkId, etc. to
`client.options` after the Client is constructed. The original code
checked the `options` closure variable which is not the same object,
so skipPing was never seen as true and the client tried to ping a
nethernet uuid as a host, leading to a connect timeout.

* feat(signal): rewrite NethernetSignal for JSON-RPC signalling API

NetherNet Realms use a different signalling server endpoint and protocol
than legacy Realms:

- Endpoint: /ws/v1.0/messaging/connect
- TURN creds: Signaling_TurnAuth_v1_0 request/response
- Send signals: `Signaling_SendClientMessage_v1_0` with a message field
  containing `Signaling_WebRtc_v1_0` jsonrpc payload (which carries
  our local nethernet id so the server can route CONNECTRESPONSE back)
- Receive signals: `Signaling_ReceiveMessage_v1_0` server notifications
- Keep-alive: `System_Ping_v1_0` every 5 s

The class now detects the protocol from options.protocol ('jsonrpc' or
'legacy') and falls back from legacy to jsonrpc on close if credentials
were never received allowing compatibility with older Realms that still
use the legacy endpoint/format.

---------

Co-authored-by: unknown <lucienharryholloway@hotmail.co.uk>
Co-authored-by: extremeheat <extreme@protonmail.ch>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​xbox-rta@​2.2.0731009986100
Addednpm/​json-bigint@​1.0.010010010075100
Addednpm/​ws@​8.21.39910010093100

View full report

@extremeheat extremeheat changed the title Add support for Nethernet transport (#735) Add support for Nethernet transport Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants