From c22d8167d169b41f2318bcef0a9fdf4117ef3723 Mon Sep 17 00:00:00 2001 From: AlxcBTW <187763517+AlxcBTW@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:15:19 +0100 Subject: [PATCH] Docs: say what is true on main (bridge protocol 1, share play, played with recently, macOS, Linux GPU encode) --- CONTRIBUTING.md | 6 +++--- README.md | 20 +++++++++++--------- docs/DESIGN.md | 12 ++++++------ docs/SOCIAL.md | 2 +- docs/gaps.md | 5 +++-- spec/bridge-protocol.md | 8 ++++---- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8fdb21d..f9820aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to the AnyPlay Network -Issues and pull requests from anyone are welcome here. The rules that hold in every AnyPlay repository (how to contribute, the line the project keeps, and no game data) are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md), and the [Code of Conduct](https://github.com/anyplaynet/.github/blob/main/CODE_OF_CONDUCT.md) applies. This file adds what is specific to this repository. +Issues and pull requests from anyone are welcome here. This repository and the [launcher](https://github.com/anyplaynet/launcher) are open; the cloud, the website, the AnyPS5 fork and the organisation's `.github` repository take contributions from the team only until 25 April 2027. The rules that hold in every AnyPlay repository (how to contribute, the line the project keeps, and no game data) are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md), and the [Code of Conduct](https://github.com/anyplaynet/.github/blob/main/CODE_OF_CONDUCT.md) applies. This file adds what is specific to this repository. ## Before you start @@ -12,7 +12,7 @@ Issues and pull requests from anyone are welcome here. The rules that hold in ev ## Build and test -You need Rust 1.88 or newer. These are the commands CI runs on Windows and on Linux. A pull request needs all of them green: +You need Rust 1.88 or newer. These are the commands CI runs on Windows, Linux and macOS. A pull request needs all of them green: ```sh cargo fmt --all -- --check @@ -52,7 +52,7 @@ Never attach or link game dumps, keys, firmware, saves, platform or publisher to - One topic per pull request, small commits, English commit messages, and a description that says what changed and why. - Fill in the pull request template. -- A pull request needs one review and green CI. CI also checks the links in the Markdown files, the licences of dependencies and security advisories. +- A pull request needs one review and green CI. The first run of a first-time contributor waits for a maintainer's approval. CI also checks the links in the Markdown files, the licences of dependencies and security advisories. - Dependencies must suit both licences below. `cargo-deny` checks this with `deny.toml`. ## Licence diff --git a/README.md b/README.md index 88e86dc..ba28abe 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,14 @@ It reports whether the tunnel went direct or through a relay, the round trip, lo | Path | What it is | |---|---| -| `crates/net` | `anyplay-net`, the net service on each player's PC: account, cloud connection, bridge server, tunnels, voice and screen sharing | +| `crates/net` | `anyplay-net`, the net service on each player's PC: account, cloud connection, bridge server, tunnels, voice, screen sharing and share play | | `crates/bridge-protocol` | the messages between the bridge and the net service | | `crates/control` | the messages between the launcher and the net service | | `crates/api` | the cloud's API, shared by the net service and the [cloud](https://github.com/anyplaynet/cloud) | | `crates/voice` | `anyplay-voice`, the party voice engine | +| `crates/proof` | `anyplay-proof`, device keys, proofs of possession and PKCE for the cloud API | | `crates/fake-game` | `anyplay-fake-game`, a game's side of the bridge, for tests and for trying the network without a game | -| `crates/share`, `crates/share-worker` | the share-screen media path, and the worker program that captures, encodes and shows the picture | +| `crates/share`, `crates/share-worker` | the media path for share screen and share play, and the worker program that captures, encodes and shows the picture, records clips and broadcasts | | `crates/discord` | an optional Discord Social SDK seam, off by default ([ADR 0022](docs/adr/0022-discord-social-sdk.md)) | | `crates/probe` | `anyplay-probe`, which measures a tunnel | | `spec/` | the network's own specifications: [bridge protocol](spec/bridge-protocol.md), [control protocol](spec/control-protocol.md), [cloud API](spec/cloud-api.md), [portal API](spec/portal-api.md), [web API groups](spec/web-api/README.md) and more | @@ -67,14 +68,15 @@ The network without games is live at anyplaynet.com, and the launcher uses it. |---|---| | Accounts, friends, presence, messages, notifications | Done and live. | | Parties with voice and push to talk | Done and live. | -| Share screen to a party | Done. Game sound is Windows only. | -| Broadcast to Twitch, YouTube or RTMP | Done on Windows, with the game's sound; `rtmp://` and `rtmps://`. | -| Join links, Find Players, captures and clips sent to friends | Done. | -| Bridge: sign-in, identity, NAT type, web API forwarding, push events, online-permission check, peer-to-peer datagrams and streams | Merged in the fork. The end-to-end CI that runs the bridge against the net service is in review. | +| Share screen to a party | Done for the streamer on Windows, Linux and macOS. Game sound comes from Windows and macOS. A Mac cannot watch yet. | +| Broadcast to Twitch, YouTube or RTMP | Done on Windows, Linux and macOS; `rtmp://` and `rtmps://`. The game's sound is sent from Windows; elsewhere the track is silence. | +| Clips (the last seconds of a game, saved on the PC) | Done on Windows, Linux (GPU encode through NVENC or VA-API) and macOS. | +| Join links, Find Players, played with recently, captures and clips sent to friends | Done. | +| Bridge: sign-in, identity, NAT type, web API forwarding, push events, online-permission check, peer-to-peer datagrams and streams | Merged in the fork, speaking bridge protocol 1: the bridge and the net service prove the game start's token to each other with an HMAC challenge, and protocol 0 is no longer spoken ([ADR 0039](docs/adr/0039-the-bridge-proves-the-token-instead-of-sending-it.md)). The end-to-end CI that runs the bridge against the net service is in review. | | Web API groups answered for games | `userProfile` and `communicationRestrictionStatus`. Every other group is refused and logged. | | A first game played together over the internet | Not yet. This is phase 4 of the [roadmap](docs/DESIGN.md#roadmap). | | Measuring tunnels between two real networks | Waiting for a second network (phase 0). | -| Share play (taking over a friend's pad) | Designed, not built. | +| Share play (taking over a friend's pad) | Built in the net service, the cloud and the worker, and tested with fakes. The engine side (frame ring, guest pad, a second user) is in review in the fork. The launcher keeps it hidden and the public cloud keeps it off until a legal review. | | Several cloud nodes | Not built. The cloud runs as one node. | [docs/gaps.md](docs/gaps.md) lists what each part still lacks. @@ -91,13 +93,13 @@ cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace ``` -Every pull request runs these on Windows and Linux. The parsers are fuzzed every night ([fuzz/](fuzz/README.md)). Start with the [design](docs/DESIGN.md); the words are in [CONTEXT.md](CONTEXT.md). Issues and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). The rules shared by every AnyPlay repository are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md). +Every pull request runs these on Windows, Linux and macOS. The parsers are fuzzed every night ([fuzz/](fuzz/README.md)). Start with the [design](docs/DESIGN.md); the words are in [CONTEXT.md](CONTEXT.md). Issues and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). The rules shared by every AnyPlay repository are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md). ### macOS `cargo build --release --locked -p anyplay-net --features devices` builds a native service with CoreAudio microphone and speaker support. CI builds and tests it on macOS as well as Windows and Linux. The launcher embeds the matching binary at build time with `ANYPLAY_NET_EMBED` and starts it over standard input/output with an explicit per-user data folder. -Run standalone with `--data ` or use its default under `~/Library/Application Support/AnyPlay/net`. Sign-ins use the macOS Keychain when available; `--file-credentials` is intended for isolated tests. Microphone access belongs to the launcher app's privacy prompt. Share-screen capture and Discord's optional SDK are separate platform integrations; this does not add them or a game engine bridge. +Run standalone with `--data ` or use its default under `~/Library/Application Support/AnyPlay/net`. Sign-ins use the macOS Keychain when available; `--file-credentials` is intended for isolated tests. Microphone access belongs to the launcher app's privacy prompt. On a Mac the share worker captures with ScreenCaptureKit and encodes with VideoToolbox ([ADR 0036](docs/adr/0036-macos-captures-with-screencapturekit-and-encodes-with-videotoolbox.md)), for share screen, clips and broadcast, and needs the Screen Recording permission. Discord's optional SDK is a separate integration, and there is no game engine bridge for macOS. ## Community diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 3a85684..c3a1018 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -27,7 +27,7 @@ These hold for every line of code and every public statement. [ADR 0021](adr/002 The bridge is small on purpose. It forwards; it does not translate. - **Switched on by the launcher.** The launcher sets `ANYPS5_NET_ENDPOINT` (a loopback port) and `ANYPS5_NET_TOKEN` (a secret for one game start). Without them every library behaves as it does today: offline and signed out. -- **One connection** to the net service, speaking the [bridge protocol](../spec/bridge-protocol.md). Request bodies pass through as opaque bytes, so the engine needs no JSON, WebSocket or ICE code. +- **One connection** to the net service, speaking the [bridge protocol](../spec/bridge-protocol.md) (version 1: both sides prove the game start's token with an HMAC challenge instead of sending it, [ADR 0039](adr/0039-the-bridge-proves-the-token-instead-of-sending-it.md)). Request bodies pass through as opaque bytes, so the engine needs no JSON, WebSocket or ICE code. - **What it forwards:** - sign-in state and its changes, reachability, the handle and account ID; - the online-permission check. The target is the network's own rule: signed in and not banned, for play on the AnyPlay network only ([ADR 0021](adr/0021-the-line-is-drawn-at-the-law.md)). The bridge answers it by this rule; @@ -50,8 +50,8 @@ A separate process that the launcher starts and watches ([ADR 0004](adr/0004-net - **Membership follows the party's revision.** Every accepted copy of the party goes to the hub, which closes connections to members who left or changed their key, forgets them in the engine, and dials new ones; a copy with an older revision never gets there. A dial that fails is repeated with a pause of 0.5 s growing to 30 s. - **Sound devices** sit behind the `devices` feature of `anyplay-net` (cpal). Release builds on Windows and Linux are built with `--features devices`; on Linux that needs the ALSA headers (`libasound2-dev`). Without the feature, which is what `cargo build` and the usual CI jobs use, the service builds and runs and voice answers that this build has no sound devices. A CI job builds and lints the feature on both systems. - The launcher gets a `voice` event with the state, who is speaking and each link, at most ten a second, and sets push-to-talk, mode, volume, mute and the devices with the commands in the [control protocol](../spec/control-protocol.md). The launcher never sees tunnel keys. -- **Share screen** ([spec](../spec/screen-share.md), [ADR 0023](adr/0023-share-screen-is-watch-only-and-asks-the-cloud-for-nothing.md)). The watch-only part of share play: a player streams their game to the party, whose members choose to watch. A connection with the ALPN `anyplay/screen/0`, dialed by the streamer to each party member, carries share play's datagrams; no cloud state, no `share.enabled`. Built, with game sound on Windows; the share worker also publishes the picture live over RTMP for broadcasts. -- **Share play** ([spec](../spec/share-play.md), [ADR 0019](adr/0019-share-play-streams-through-a-worker.md); designed; built so far: the part that share screen uses, the bridge's `0x05xx` kinds with the frame ring and the guest pad on both sides of the bridge, and the host's pad rules. Not built: the invitation, the cloud's `Share` and the share connection). A third connection on the tunnels' endpoint, with the ALPN `anyplay/share/0`, carries a game's picture and sound to one party member and that member's pad states back. A separate share worker encodes and decodes; the net service checks who connects, validates and rate-limits pad states, and forwards datagrams. +- **Share screen** ([spec](../spec/screen-share.md), [ADR 0023](adr/0023-share-screen-is-watch-only-and-asks-the-cloud-for-nothing.md)). The watch-only part of share play: a player streams their game to the party, whose members choose to watch. A connection with the ALPN `anyplay/screen/0`, dialed by the streamer to each party member, carries share play's datagrams; no cloud state, no `share.enabled`. Built, with game sound on Windows and macOS (the streamer on macOS too, the viewer not yet); the share worker also publishes the picture live over RTMP for broadcasts, and keeps the last seconds of a game for [clips](../spec/clips.md). +- **Share play** ([spec](../spec/share-play.md), [ADR 0019](adr/0019-share-play-streams-through-a-worker.md); built here and tested with fakes: the part that share screen uses, the bridge's `0x05xx` kinds with the frame ring and the guest pad, the host's pad rules, the invitation, the cloud's `Share` and the share connection. Open: the engine side in the fork and the launcher's share window). A third connection on the tunnels' endpoint, with the ALPN `anyplay/share/0`, carries a game's picture and sound to one party member and that member's pad states back. A separate share worker encodes and decodes; the net service checks who connects, validates and rate-limits pad states, and forwards datagrams. - **Version guard** before every join. ### Cloud ([anyplaynet/cloud](https://github.com/anyplaynet/cloud)) @@ -111,10 +111,10 @@ A link such as `anyps5://v1/join/…` never starts a game by itself; it opens th | 5 More | matchmaking, leaderboards, save backups | by choice | | S1–S6 Social | profiles and trophies, parties and messages, voice, feed and boards, share play, web profiles and sign-in ([SOCIAL.md](SOCIAL.md)) | each phase as SOCIAL.md says | -Where it stands (26 October 2026): +Where it stands (27 October 2026): -- **Phase 1 is done and live.** The cloud runs at anyplaynet.com as one node, and the launcher's online area uses it: accounts, friends, presence, messages, parties, voice and share screen. The social phases S1 to S6 are nearly done: share screen, the watch-only part of S5, is built, and handing a pad to a friend is open. -- **Phase 2 is nearly done.** In the AnyPS5 fork, sign-in, identity, NAT type, web API forwarding, push events, the online-permission check and the frame tests are merged (anyplaynet/AnyPS5#7, #10, #24). The end-to-end CI that runs the bridge against the net service is in review (#9). The net service measures the NAT type from iroh's net report and answers `userProfile` and `communicationRestrictionStatus`. +- **Phase 1 is done and live.** The cloud runs at anyplaynet.com as one node, and the launcher's online area uses it: accounts, friends, presence, messages, parties, voice and share screen. The social phases S1 to S6 are nearly done: share screen, the watch-only part of S5, is live, and share play (handing a pad to a friend) is built in the net service and the cloud but waits for the engine side. +- **Phase 2 is nearly done.** In the AnyPS5 fork, sign-in, identity, NAT type, web API forwarding, push events, the online-permission check and the frame tests are merged (anyplaynet/AnyPS5#7, #10, #24), and so is bridge protocol 1 (#31, network#125). The end-to-end CI that runs the bridge against the net service is in review (#9). The net service measures the NAT type from iroh's net report and answers `userProfile` and `communicationRestrictionStatus`. - **Phase 3 is mostly done.** The fork carries peer-to-peer datagrams, session signaling and streams (#11, #12); fake games exchange packets through tunnels in CI. - **Phase 4 is open.** The first game played together over the internet is not there yet. The current target is a game that reaches its title screen. - **Phase 0 waits.** The probe is ready; a measurement between two real networks needs a second network. diff --git a/docs/SOCIAL.md b/docs/SOCIAL.md index 01978ee..b0f9ec8 100644 --- a/docs/SOCIAL.md +++ b/docs/SOCIAL.md @@ -79,6 +79,6 @@ A queue of reports with the reported content attached, actions with a stated rea | S5 Share play | streaming a game to a friend, taking over a pad | a friend without the game plays a level of it; the [plan](share-play-plan.md) splits it into watch, hand over and play together, each with numbers | | S6 Web and sign-in | web profiles, passkeys, Apple, Google and Discord sign-in, moderation queue | a public profile opens in a browser; a player signs in with a passkey | -Where it stands (26 October 2026): S1 to S4 and S6 are nearly done and live in the launcher, with parties, voice, messages, the feed and web profiles. Of S5, share screen is built (on Windows with game sound); handing a pad to a friend is not. The numbers in each phase's "done when" are not all measured on real networks yet. +Where it stands (27 October 2026): S1 to S4 and S6 are nearly done and live in the launcher, with parties, voice, messages, the feed and web profiles. Of S5, share screen is built (for the streamer on Windows, Linux and macOS, with game sound on Windows and macOS), and share play is built in the net service and the cloud and tested with fakes; it waits for the engine side and for a launcher window. The numbers in each phase's "done when" are not all measured on real networks yet. The infrastructure work in [anyplaynet/cloud](https://github.com/anyplaynet/cloud/blob/main/docs/ARCHITECTURE.md) runs beside these phases; every feature here is built for the cluster from its first line. diff --git a/docs/gaps.md b/docs/gaps.md index 919e4ed..a4e0cbe 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -24,10 +24,11 @@ Merged in the fork: sign-in, identity, NAT type, web API forwarding, push events - the pump runs on a Tokio timer, which on Windows can tick only every 15 ms or so rather than every 5 ms; the engine's queue allows for that, but a thread of its own would be steadier; - no gain or level meter before a talk, no per-device sample-rate choice (the device's default is used); - phase S3 is done when a party of four talks with relay only switched on, which needs a real run. -- **Share play**: designed ([spec](../spec/share-play.md), [plan](share-play-plan.md)). Only the watch-only part, share screen, is built. Handing a pad to a friend needs a tap in the engine (frame, sound, pad), the cloud's share records, and a legal review before a public cloud turns it on. The numbers in the plan have not been measured between two real networks. -- **Share screen sound**: Windows only. Capture needs Windows 10 build 20348 or later (process loopback); on an older one the stream has no sound and the picture goes on. It is sent from a thread of its own, not strictly before the video of the same instant, and the viewer does not hold the picture back when the two drift apart. The viewer decodes the sound on the window's loop, 20 ms ahead of the speakers, so anything that stops that loop for longer (Windows' own loop while the window is dragged or resized) is heard as a gap. In-band forward error correction at the expected 10% loss makes Opus code the band below 8 kHz with its speech coder (hybrid mode) instead of the music coder: a lost packet is rebuilt better than concealment can (9 dB against -1 dB on music), at a cost to every packet's quality; the trade-off is not measured by ear yet. The capture and the speakers are compiled and linted for Windows, but no test plays a game's sound: the tests use a tone and a clock in place of the speakers. +- **Share play**: built in the net service, the cloud and the worker, and tested with fakes only ([spec](../spec/share-play.md), [plan](share-play-plan.md)): the invitation, the share connection, the modes, the stream and input delay, `share_quality`. Missing: the engine side in a real title (the frame ring, the guest's pad and a second user are open in the fork, anyplaynet/AnyPS5#29 and #30), the launcher's share window (the launcher keeps share play hidden), and a legal review before a public cloud turns it on. The numbers in the plan have not been measured between two real networks. +- **Share screen sound**: Windows and macOS. On a Mac the streamer hears the game's applications through ScreenCaptureKit, and a game whose processes the system does not list as an application has no sound; a Mac has no viewer window yet, so it cannot watch. On Windows capture needs Windows 10 build 20348 or later (process loopback); on an older one the stream has no sound and the picture goes on. It is sent from a thread of its own, not strictly before the video of the same instant, and the viewer does not hold the picture back when the two drift apart. The viewer decodes the sound on the window's loop, 20 ms ahead of the speakers, so anything that stops that loop for longer (Windows' own loop while the window is dragged or resized) is heard as a gap. In-band forward error correction at the expected 10% loss makes Opus code the band below 8 kHz with its speech coder (hybrid mode) instead of the music coder: a lost packet is rebuilt better than concealment can (9 dB against -1 dB on music), at a cost to every packet's quality; the trade-off is not measured by ear yet. The capture and the speakers are compiled and linted for Windows, but no test plays a game's sound: the tests use a tone and a clock in place of the speakers. - **Share screen on Linux**: the worker captures the window the player picks in the portal and encodes it on the GPU through NVENC (NVIDIA) or VA-API (Intel, AMD), loaded from the system and probed at start ([ADR 0037](adr/0037-linux-encodes-on-the-gpu-through-vaapi-and-nvenc.md)), else with Cisco's OpenH264 in software (720p30). Clips work on Linux with the same hardware encoders. The two GPU paths are tested with fakes and by a round trip that skips without a GPU: they have not run on real hardware in CI, and the first run on each vendor's GPU is still to be done. Clips ask the player for the game's window in the portal dialog each time a game starts. Missing: game sound on Linux, at either end; hardware decoding. The worker links the system's `libpipewire-0.3` and does not start without it, so a Linux PC without PipeWire can neither share nor watch. - **Matchmaking, leaderboards, cloud saves**: not started (phase 5). +- **Bridge protocol 1** ([ADR 0039](adr/0039-the-bridge-proves-the-token-instead-of-sending-it.md)): the HMAC challenge is merged on both sides (here #125, in the fork #31). Protocol 0 is no longer spoken, so a bridge built before it must be updated. - **Fuzzing beyond the parsers**: the parsers of both protocols are fuzzed every night ([fuzz](../fuzz/README.md)); what the net service does with the messages they read, and what it reads from the cloud, is tested with fixed cases only. ## Cloud (anyplaynet/cloud) diff --git a/spec/bridge-protocol.md b/spec/bridge-protocol.md index bbd8521..dd03794 100644 --- a/spec/bridge-protocol.md +++ b/spec/bridge-protocol.md @@ -23,7 +23,7 @@ Every message is one frame. All integers are little-endian. |---|---|---|---| | 0 | 4 | `length` | Payload length in bytes, at most 16 MiB (16,777,216). | | 4 | 2 | `kind` | What the payload is; see below. | -| 6 | 2 | `flags` | Senders write 0. Receivers ignore it in version 0. | +| 6 | 2 | `flags` | Senders write 0. Receivers ignore it in version 1. | | 8 | 4 | `request` | 0 for an event. A request carries a number unique on this connection, and its reply carries the same number. | | 12 | `length` | payload | Depends on `kind`. | @@ -32,7 +32,7 @@ A receiver that reads a `length` above the limit closes the connection. A frame - An **event** has `request` 0 and gets no answer. - A **request** has a `request` number other than 0. Its **reply** has the same number and the kind of the request with the top bit set (`kind | 0x8000`). - A receiver that does not know the kind of a request answers with **unsupported** (`0x8000`, empty payload) and the request's number. -- Only the bridge sends requests in version 0. Several may be open at once; replies can come in any order. +- The bridge sends most requests. The net service sends one, `share open` (`0x0501`, [Share play](#share-play-0x05xx)). Several may be open at once; replies can come in any order. ## Payloads @@ -112,7 +112,7 @@ The hello frame with the bridge nonce above is 46 bytes: `22 00 00 00` (length 3 | `0x0102` | feature | bridge → service | `user_id: i32`, `feature: u32` | - **state** comes right after welcome and again whenever a field changes. The bridge keeps the last one and answers the game's questions about sign-in, identity and NAT from it without waiting. - - `signed_in` is 1 while the player is signed in to the network and not banned, else 0. The online-permission check does not follow it yet. [ADR 0021](../docs/adr/0021-the-line-is-drawn-at-the-law.md) makes it follow: signed in and not banned, for the AnyPlay network only. + - `signed_in` is 1 while the player is signed in to the network and not banned, else 0. The bridge answers the online-permission check by the same rule, for the AnyPlay network only ([ADR 0021](../docs/adr/0021-the-line-is-drawn-at-the-law.md)). - `account_id` and `handle` are 0 and empty while signed out. A handle has at most 16 ASCII characters. - `nat_type` is 1, 2 or 3 as the platform counts NAT types, or 0 while unknown. The net service measures it over IPv4 with iroh's net report: 1 when the relays answer its UDP address probes and the public address they see is one of the PC's own; 2 while it is connected to a relay (every peer can reach it through the relay) or when the NAT shows the same public address to every relay; 3 when UDP works but neither holds; 0 when neither a relay nor UDP answers. A net service on relay only is never 1. A change comes as a new `state`. - `address` is the player's own virtual address, 0 when it has none. It is the address the player has in the session the launcher shows, else the one the cloud names for the account. It can change when the player enters a session, and `state` is sent again then. @@ -244,7 +244,7 @@ The first user is Minecraft: Bedrock Edition in its LAN mode. What public source ### Share play (`0x05xx`) -Version 0, implemented in `crates/bridge-protocol` (the net service's side) and in the AnyPS5 bridge. The frame ring, the pad rules and the host's override are in the [share play spec](share-play.md); this is the wire. +Part of version 1. The net service's side is in `crates/bridge-protocol`; the bridge's side is open in the AnyPS5 fork (anyplaynet/AnyPS5#29). The frame ring, the pad rules and the host's override are in the [share play spec](share-play.md); this is the wire. | Kind | Name | Direction | Payload | |---|---|---|---|