Commit Graph

18 Commits

Author SHA1 Message Date
Alexa cf3aa29ba2 fix: address the 15 CodeRabbit findings from the wire-audit review
Security:
- roomcode PUT now requires instance ownership (any player could plant
  or relocate codes on foreign private instances)
- /platformid/{accountId} requires auth (anonymous Steam/Oculus id
  enumeration oracle)
- request tracing no longer captures successful /thread bodies by
  default (chat messages landed unredacted in logs); opt in via
  Trace__SuccessBodyPaths
- anonymous action-link renewal clamped to 720h per consume

Data integrity:
- buyPurchaseReminder upserts its objective sentinel (second purchase
  threw UNIQUE after the wallet was debited)
- progression reward gift + idempotency sentinel commit in one
  transaction (crash between them double-minted the reward)
- ClubPermissionsGalleryAndModeration migration defaults corrected to
  the entity contract (CommentsJson '[]', ClubChatEnabled true); new
  one-shot ClubChatDefaultRepair migration fixes databases that
  applied the wrong defaults; bootstrap repairs '' CommentsJson rows
- admin subroom-maxplayers audit entry commits with the mutation
- account purge covers CustomAvatarItems (ownership deleted, created
  items reassigned to the system account)
- duplicate photo reports ignored while one is unresolved

Stability:
- bootstrap only swallows the expected duplicate-column error; locked
  databases and schema failures now fail startup instead of the first
  endpoint
- clone blob write failure degrades to an empty sub-room instead of a
  500 after the clone row committed
- resumed photo-feed cursor stamped DateTimeKind.Utc (Npgsql rejects
  Unspecified for timestamptz)
- unreadcounts queries per requested room instead of materialising the
  whole comment keyspace

Tests:
- destroys-the-probe-session template guard is case-insensitive

74/74 tests pass.
2026-08-02 01:16:38 +03:00
Alexa 9f173193a7 fix: a cloned template carries its content instead of starting empty
Cloning a first-party template (RecCenter and friends) deliberately left the
new room with no blob, on the reasoning that its content is baked client
geometry and any blob is just a MakerPen overlay. That left the copy with
nothing to load.

The copy flow is what exposes it. IBEOONPEELF.GetRoomData / GetRoomMetadata
fetch "/room/{blob}" from the CDN as part of copying and throw a
BCPHBJHOIEM-family exception when that does not give them a usable room —
surfacing as the bare "Failed to copy room: Exception of type 'CEMNLBKJABA'"
with no message. For a name nothing is stored under, the CDN synthesises a
~1.8 KB stub: room_1583_dorknet_v8.dat served 1872 bytes where the source's
room_100_v1.dat is 10,930. The clone that DID work carried real content.

Since GiveCloneItsOwnBlobsAsync copies the bytes under the clone's own name,
the original worry — inheriting an overlay on a SHARED template — no longer
applies: nothing is shared either way. IsFirstPartyTemplate had no other
callers and is gone.

The existing assertion that a template clone must have NO blob encoded the
belief this replaces, so it now asserts the clone carries content. The
"doesn't share the source's object" half is covered by
RoomCloneShapeTests.Clone_does_not_reference_the_source_rooms_blob, which runs
with a real object store; this suite has none and deliberately falls back to
keeping the reference.
2026-07-28 12:00:15 +03:00
Alexa 9c9f1841d6 feat: cloned rooms get their own copy of the source's save data
Cloning was a shallow copy: the new room's scenes kept pointing at the SOURCE
room's blob until someone saved over them. So every clone of a room shared one
object, a clone read as "already has content" while owning none of it, and the
room a player copied stayed load-bearing for their copy indefinitely. Cloning
RecCenter produced rooms whose data blob was literally room_100_v1.dat, which
is visible in the join log.

Each sub-room's bytes are now copied into the clone's own namespace, keyed by
the CLONE's room id so BlobRouter files them under that room's prefix. Sub-room
0 takes the canonical default name, which matters because the details builder
falls back to exactly that name when a room has no recorded blob — writing the
copy there means both the recorded and the fallback path resolve to real
content. Each copy also gets a RoomDataBlobs row so it is tracked like any
other save.

Two cases deliberately do not clear a reference:

- With no object store configured there is nothing to copy, and a blob name is
  only a reference; clearing it would throw away the player's edits, which is
  strictly worse than the shared reference. That path keeps the old shallow
  behaviour, which is also what the existing user-room clone test asserts.
- A source object that is missing or unreadable leaves the clone empty rather
  than failing the request. The room and its sub-rooms are already committed by
  that point, so a hard failure would strand a half-made room, and an unsaved
  source clones to an empty room anyway.

Everywhere else a reference is either replaced by a real copy or cleared — it
is never left pointing into another room.
2026-07-28 10:28:50 +03:00
Alexa 90e069ee4b fix: second pass over the 2023-client wire defects, plus a coverage harness
Fourteen agents worked one server file each over the audit's open findings,
re-verifying every claim against the client binary before changing anything.
Route+verb coverage against the recovered client inventory is now 474/522
(90.8%), up from 86.2% when the harness was first wired up.

Adds ClientRouteCoverageTests, which turns "are we compliant?" into a number
instead of an opinion. It reads data/client-routes-2023.tsv — every request the
2023-03-21 client can issue, recovered from the binary — and asserts each one
has a handler under the verb the client actually uses, separating "no handler"
from "handler exists, wrong verb" since those have different fixes. Remaining
gaps live in KnownGaps, which is expected to shrink and never grow.

Also fixes a real blind spot in EndpointContractDiscovery: it only collected
HttpMethodAttribute, so an action carrying a bare [Route] with no verb attribute
was invisible to it. The CDN's unity_assets handler is exactly that shape, which
had been showing up as a phantom gap.

Notable findings from this pass:

- The club permissions envelope key is literally "Type", not "MembershipType"
  as the audit's suggested fix guessed. Read off the generated reader, then
  cross-checked against the 2020 decompile — the int bitmask we were emitting
  was wrong for BOTH client generations, not just 2023.
- Room-consumable purchase responses carry OperationResult as an OBJECT
  { Status, InventoryItem }; the scalar operation enum belongs in
  BalanceUpdateResult. The base type OKHNOPLBOFP holds a single BGHBAILNNJJ,
  which exposes exactly those two properties. A test asserting the old scalar
  shape was corrected rather than the code.
- buyProgressionEventXpBoost blind-inserted an ObjectiveProgress row whose
  (PlayerId, Key) is unique, so a second purchase of the same boost threw
  "UNIQUE constraint failed" and 500'd AFTER taking the player's currency.
  Now an upsert.

Agents were forbidden from faking fixes they could not complete in their own
file, and several correctly refused: club role permissions, club additional
image slots, announcement meta, MinLevel/ClubChatEnabled, currency purchase
offer ordering, and room-key image/currency columns all need new entities or
columns. Those are deliberately left for a single coherent schema change rather
than stubbed out here.
2026-07-28 08:50:58 +03:00
Alexa 289072583e feat: Enhance room management and moderation APIs
- Added support for multiple tag filters in HotRoomServer endpoint, allowing clients to query hot rooms with multiple tags.
- Introduced a new DeleteRoom endpoint for owners to soft-archive their rooms, ensuring room data integrity.
- Updated MagicDoor endpoint to return a structured response including refresh timing.
- Improved reporting functionality to handle form submissions correctly, ensuring room reports are persisted.
- Refactored per-field mutation endpoints to support both legacy and new client formats, accommodating changes in request structure.
- Implemented a multi-field payload reader to handle complex requests more efficiently.
- Enhanced logging for room code management to track player actions and conflicts.
2026-07-27 23:54:25 +03:00
Alexa 6ee018b844 feat: Implement private room cloning and instance management; ensure cloned rooms start private and funnel joins into a single instance 2026-07-13 12:10:12 +03:00
Alexa 690e77f520 feat: Enhance room cloning functionality; add support for roomserver routes and blob management for first-party templates 2026-07-13 11:51:20 +03:00
Alexa e4126e38ce feat: Inherit IsAGRoom property from source for proper cloning of RRO rooms; ensure compatibility with baked geometry loading 2026-07-13 01:16:54 +03:00
Alexa a2ffb5ef4b feat: Update room properties to support cloning for RRO/AG base rooms; adjust moderation logic for cloning permissions 2026-07-13 01:04:10 +03:00
Alexa 1152d9ba48 feat: Update room cloning API to accept multiple content types for name input; enhance compatibility with 2023 client 2026-07-13 01:00:00 +03:00
Alexa 5460cc3601 feat: Add regression tests for room cloning functionality; ensure cloned rooms return full details 2026-07-13 00:54:12 +03:00
Alexa 2c749c2677 feat: Implement base room management; add API endpoints for retrieving and setting curated base rooms 2026-07-13 00:40:35 +03:00
Alexa 2795d2ed7d feat: Enhance room cloning functionality; ensure cloned rooms include source scenes for complete structure 2026-07-13 00:15:57 +03:00
Alexa 312ecbbdc8 feat: Add account privacy settings endpoint
- Implemented new endpoints for retrieving account privacy settings.
- Added fields for privacy preferences such as profile visibility, online status, and activity visibility.

feat: Extend play menu tags functionality

- Updated PlayMenuTagsRequest to include TrendingTags.
- Modified SetPlayMenuTags to handle trending tags.
- Enhanced logging to include trending tags.

fix: Increase maximum archive size for room zip imports

- Updated MaxArchiveBytes from 12GB to 25GB in RoomZipImportController.

feat: Improve CDN image handling

- Added local image path resolution for room images.
- Implemented lazy loading of room image aliases from JSON file.

feat: Enhance match player presence resolution

- Updated ResolveDataBlobForPresenceAsync to consider sub-room IDs and private instance status.

feat: Extend RoomEntity with new properties

- Added AllowNewUsers, MinLevel, MaxPlayerCalculationMode, LoadScreensJson, PromoImagesJson, and PromoExternalContentJson fields.

feat: Update database schema for new room properties

- Added new columns to the Rooms table for AllowNewUsers, MinLevel, MaxPlayerCalculationMode, LoadScreensJson, PromoImagesJson, and PromoExternalContentJson.

feat: Implement platform notifications controller

- Created PlatformNotificationsController for managing user notification preferences.
- Added endpoints for retrieving and setting notification preferences and categories.
2026-06-25 01:23:57 +03:00
Alexa 7e765bb536 Add share cam permission for public rooms: enable desktop/share screen access in public rooms without host/mod/co-owner requirement 2026-06-03 02:46:04 +03:00
Alexa 93833c8b93 Enhance room ownership validation: allow co-owners to access rooms; refactor accessibility endpoint to support multiple content types and improve request handling 2026-06-03 01:13:36 +03:00
Alexa 143d3a9a07 Refactor room role permissions: enhance role checks for saving and overlaying data; introduce editable role data for RRO rooms 2026-06-02 15:40:53 +03:00
Alexa 4edf25b2d5 Import december-2020-12-18 from private repo (scrubbed 2026-05-27)
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.
2026-05-27 01:04:12 +03:00