- Data-protection keys are encrypted (AES-256-GCM, key derived from the
server secret) before they reach the DataProtectionKeys table.
- /link only follows local return paths and keeps the form when a
signed-in visitor has an identity waiting to be linked.
- A failed sign-out says so instead of reloading as if it worked.
Players sign in to the website, and admins to the admin panel, with an
OpenID Connect provider (DorkNet:SignIn:*). The first sign-in links the
provider identity (issuer + subject) to a DorkNet account with that
account's password; after that the provider sign-in is enough.
- Cookie sessions per host, keys persisted in the database so redeploys
keep people signed in; unlink, deletion or a ban ends the session.
- Link attempts limited to 5 failures per 15 minutes per identity and
per username.
- Admin panel: "Sign in with ..." exchanges the session for the usual
admin tokens via GET /api/admin/v1/sso (IsAdmin still required).
- Downloads: optional DorkNet:Downloads:RequireSignIn serves the
manifest and files only to signed-in players; the Downloads and Quest
pages offer sign-in instead.
- Website: sign-in in the header, /link and /account pages.
The game client's login is unchanged.
Review follow-ups:
- The downloads routes now answer only on the apex (the site's host) and 404
on every other accepted host, so the game's open API/CDN subdomains can't
serve the builds.
- Install on Quest passes its own file to the Quest page instead of always
picking the newest release.
- Waiting for the bucket's headers is limited to 30 s; the body still streams
without a limit.
- Dispose the upstream request message; use LINQ in FindFile.
When the server is pointed at the bucket CI publishes builds to
(DorkNet:Downloads:BaseUrl), the site lists them on a new Downloads page and
the Quest page offers "Latest build" next to "Choose file".
The server reads manifest.json and the files over HTTP on the internal network
and streams them through with Range support (DownloadsController); only files
the manifest lists are served. The xapk reader now reads from a byte source,
either the picked File or the server URL via Range requests, so the browser
installer streams the APK and OBB to the headset without downloading the
package first. Unset, both features stay hidden.
Patches the Quest build of Rec Room 2023.03.21 (20230317 / 2128210, the
same appVersion as the PC client) to connect to a DorkNet server, using
one native hook library loaded via DT_NEEDED on libmain.so.
- host rewrite onto <svc>.<ServerHost> or a {service}-dev.example.com template
- Photon app ids and region injection (PhotonRegion must match PC)
- TLS / pinning / image-signature bypass, integrity callbacks neutralised
- no-Meta-account build; the server treats platform id 0/1/blank as a
placeholder and keys those accounts by device id
- build.ps1 -Obb packages a DorkNet-<ver>.xapk with one-command
installers for Windows and macOS/Linux; app is named via AppName
- README, docs/quest.md and NOTICE updated; credits RecFlare and
And64InlineHook (MIT)
Tested on a Quest 2: all hooks arm, requests reach the dev server.
MelonLoader (DorkNet.ClientMod) is the sole client patcher now, so drop
the BepInEx plugin and its BepInEx-only installer:
- delete the DorkNet.ClientPatch project + tools/install-plugin.ps1
- drop the project from DorkNet.sln
- README / architecture / deploy docs: present DorkNet.ClientMod
(install-melon.ps1) as the patcher instead of the BepInEx plugin
- fix install-melon.ps1 fallback hint that pointed at the deleted
install-plugin.ps1
- tidy stray 'BepInEx port' comments in Mod.cs / PhotonCustomAuthController
Legacy-cleanup paths that REMOVE an old BepInEx install (install-legacy-client.ps1,
the old_plugin_paths entry in build-patcher-zip.ps1) are kept intentionally.
Targets Rec Room 2020.12.18 client.
Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces the dorknet-clientpatch-{key}.zip
Release asset the launcher fetches.
- .github/workflows/release.yml — auto-publishes both Release assets
on v1-december-* tag push.
Scrubbed via maintainer-side scrub-for-public.ps1: same drop rules as
the prior import, plus build-patcher-zip.ps1 added to the tools/
allow-list so it survives the scrub.