Skip to content

Cordial 0.5.0 — the app bridge, and a register of what is missing

Choose a tag to compare

@luohoa97 luohoa97 released this 05 Aug 09:07
· 445 commits to main since this release

The app bridge, a register of what is missing, and a kernel sandbox under
plugins.

The app bridge was never given its surface or platform params

Sober makes 87 JNIAppBridge calls during a join; Cordial made 3. Both
UpdateSurfaceAppWithPlatformParams and UpdateSurfaceGameWithPlatformParams
are now driven after StartApp, with CORDIAL_SKIP_UPDATE_SURFACE=1 as the
control.

Whether this fixes the 304 disconnect is untested. It needs a join run on a
real account and has not had one. INFERRED.

Error 304 is not what it looked like

The join succeeds: connection at 4.0 s, replication for roughly 61 s, then
Disconnect reason received: 304 from the server. The websocket to
10.110.101.222:5052 that looked like the cause is a red herring — Sober opens
the identical connection and plays for 942 s. KeyRing is identical between the
two.

A register of everything unimplemented

Unresolved JNI symbols, called libc stubs, unregistered natives and placeholder
returns, printed as one report at exit. The JNI half only populates when libjnivm
is built with CORDIAL_JNI_TRACE=1, and the report says so when the section is
empty
— an empty list was very nearly published as "zero unresolved symbols",
which would have been a false negative produced by a switched-off instrument.

Graphics gets an explicit OpenGL ES option

And loses the FastFlag that never worked. FStringDebugGraphicsPreferredBackend
was measured to be inert: libroblox.so imports zero Vulkan symbols and 91
EGL/GL ones, and picks its backend by dlopen. Selection now works by
withholding the virtual libvulkan soname, which is the mechanism that actually
decides it.

A kernel sandbox under the plugin process

bwrap with --unshare-all, a private tmpfs and the entry module bound
read-only, sitting below Deno's zero permissions and the capability broker. Its
absence is a downgrade rather than a hole, and every spawn prints which layers
are in force. See ADR-018.

A Flatpak grant deliberately not taken. --talk-name=org.freedesktop.Flatpak
would have let Cordial create sub-sandboxes inside Flatpak — and, because
flatpak-spawn --sandbox and --host are the same D-Bus name, would equally
have handed every plugin arbitrary command execution on the host. A Flatpak
install keeps two layers instead of three; that is the correct trade.

Everything else

  • Ctrl+V pastes into any Roblox text box or chat.
  • The queued-link banner was showing part of an auth ticket. summarise()
    truncated a deep link to 64 characters, which was enough to include it. Fixed,
    with a test that a synthetic ticket cannot appear in the banner.
  • Updates: the build window is a changelog with one button under it, sourced
    from Roblox's Creator Hub release-notes table and rendered from markdown.
  • Download on Wi-Fi was the metered switch wearing the wrong name. One switch
    now: download on metered connections, off by default.
  • Per-profile VPN gate (#8): a profile marked vpn-required refuses to launch
    without pvpn rather than leaking the connection.
  • Deep links reach the engine; roblox-player:// does not, and the README says
    which does.

Known broken

Text fields do not paint while focused. The pointer is not captured in first
person. X11 fullscreen segfaults. Web views are unimplemented. Audio initialises
and then fails with FMOD_ERR_OUTPUT_INIT (51) at about t=3.3 s on a signed-in
session.


cargo test --workspace: 460 passed, 0 failed.

Cordial ships no Roblox code, APK or assets — you supply the Android client
yourself. There is no script execution, no hooking and no memory access; those
are absent from the API rather than disabled
(ADR-001).