Commit Graph

27 Commits

Author SHA1 Message Date
Alexa fd2153d82b fix: 2023 room instances, publish, role permissions and co-owner invites
- Room roles: list the creator as Creator (255), not CoOwner (30). The
  client takes the local role from the Roles list and only lets a player
  edit roles below their own (Creator excepted), so the creator could not
  edit Co-Owner and Creator permissions. Enforce the role ladder on the
  server (RoomRoleRules), let invitees accept (PUT roles/{me} role=30) and
  reject (PUT roles/{me}/invite role=0), send message Types 62/60/61, and
  push RoomUpdate after every role change.
- Permissions: persist PUT subrooms/{sub}/permissions cells in a new
  RoomRolePermissions table, serve them from photon_access_token (plus a
  roomserver/ twin) and push PhotonAccessToken to the sub-room.
- Publish: player-owned rooms are never IsRRO on the wire; the client
  hides Publish and every room setting for an RRO.
- Sub-rooms: wire SubRoomId = OrderIndex + 1 (the client will not load a
  sub-room with id 0), new rooms always get a named Home sub-room, and a
  startup pass repairs rooms without one.
- Instance browser: per-room Redis presence index, live players only,
  private instances for the people allowed in, real IsFull.
- Room/sub-room settings: creator or accepted co-owner everywhere.
2026-10-24 23:22:53 +03:00
Alexa 6ee1d6f9b3 fix: presence, profile edits, outfit menu and RecNetResult writes for the 2023 client
Every change below was checked against the 2023-03-21 client disassembly;
file:line evidence is in the code comments and in
docs/recroom-2023-client-api-complete.md.

Presence
- matchmake/none means "online, in no room" (its only caller is
  TryGoToOfflineRoom, which ignores the reply). The server used to keep the
  old room or invent a dorm, so the next heartbeat looked out of sync and
  the client cancelled its load to chase that room.
- The join watchdog no longer clears presence 30 s into a long room load;
  it is a 3 minute backstop that drops the room only.
- One fan-out (PresenceBroadcastService) for every transition: deferred
  joins, matchmake/none, logout, failed joins, visibility changes, SignalR
  connect/disconnect. isOnline is sent on its own; pushes never go to the
  subject, because a self push moves the player.
- Online-status visibility (Public / Friends / Favorites / Appear offline)
  is stored and honoured by GET /player and by the live pushes.

Profile
- PUT account/me/{emoji,personalpronouns,identityflags,bannerimage} were
  404; added with the client's real form keys and persisted (new Players
  columns plus migration). Every account read now returns them, and edits
  push AccountUpdate to everyone.

Outfit menu
- Saved outfits kept OutfitSelectionsV2 and CustomAvatarItems, so loading a
  slot restores what was saved instead of a stale outfit.
- isCreationAllowedForAccount answers the {Success, Error} envelope the
  client parses; minPriceForPublicItem is a bare int; gifts/generate accepts
  form bodies; lockeditems returns the full owned-item shape; colourways no
  longer share their base item's AvatarItemId.

RecNetResult writes
- About 40 writes look status-only but parse the body as {Success, Error}.
  An empty 200 showed "Failed to ..." after the server applied the change,
  and a body without Success threw "Error message cannot be null". Clubs,
  announcements, keepsakes, comments/read, subscriptions, purchase offers
  and privacy settings now answer RecNetResult.
- Login token and device-code grants are real; remoteauth approves the
  device code; createlogintoken returns a bare string.
- New: incentivizedreferrals/referrals, account/bulk/{email,phone},
  GET strings, account/me/confirmphone, PlayMenuCarouselOrdering_1.
  Route inventory and coverage test extended to match.

README now describes the 2023 branch.
2026-10-15 14:08:11 +03:00
Alexa 36e64e99ba feat: lift the CircuitsV2 limits, Rec Royale night mode, RRO room blobs
CircuitsV2 limits are served as UGC.CircuitsV2.Limit.* gameconfig keys and
are editable from admin Settings. Retail drops any send over 5 RPCs/frame
or 1024 bytes/60 frames; both network budgets now default to 1,000,000,000.
The creation limits are raised too, each against the hazard the client
binary shows for it:

- Chips 3000 -> 30000: the chip-culling manager preallocates four
  List<Chip>(Chips), so the 1M clamp stays.
- Compute 50000 -> 500000: a per-frame budget with no allocation; the 10M
  cap keeps its counters from wrapping.
- CloudValues 100 -> 1000, InkPerChip 15 -> 0: InkPerChip is an ink COST,
  multiplied by min(chips, CloudValues), so lowering it is the increase.
  The clamps tighten to 10000 / 30000 to keep that product from overflowing
  (the room ink cap is a hard-coded 30000).
- UnculledChips / VisibleChips 500 -> 3000: render-cost counts only.

Room save uploads may now be up to 100 MB (Kestrel's 30 MB default would
413 a big circuits room). Contract and evidence:
docs/recroom-2023-circuitsv2-limits.md.

Also includes the Rec Royale night mode client feature
(docs/recroom-2023-scene-moods.md) and the admin blob enable/reset for
baked RRO sub-rooms.
2026-10-15 14:07:54 +03:00
Alexa 933c7eb51c feat: close the last route gaps — 100% client route+verb coverage
Every HTTP request the 2023-03-21 client can issue now reaches a handler under
the verb it actually uses: 522/522, with an empty KnownGaps allowlist. The
coverage test asserts it, so a regression fails the build rather than becoming
a 404 in the wild.

The six routes left after the previous pass all needed storage that did not
exist, so they are done here as one schema change rather than stubbed:

- ClubRolePermissionEntity (ClubId, MembershipType, six bools) backs
  PUT club/{id}/permissions/{role}. A club with no stored row falls back to the
  derived default policy, so every club that predates the table behaves exactly
  as before. Partial writes keep the values they currently resolve to, so a
  client that omits a field cannot silently revoke a permission.
- ClubAdditionalImageEntity (ClubId, Slot, ImageName) backs the gallery. The
  details envelope now emits real {ImageName, Slot} rows instead of an empty
  array, and DELETE clears a slot.
- ClubEntity.MinLevel and ClubEntity.ClubChatEnabled back their setters and are
  read back by hasDisabledClubChat and the Club wire shape, which previously
  reported hardcoded defaults.
- ChatMessageEntity.ModerationState backs PUT thread/message/{id}/moderate,
  gated so an author can retract their own message but only club moderators and
  admins can action anyone else's.
- TestCaseEntity.CommentsJson backs the QA comment endpoint, appending rather
  than overwriting so a second tester's note cannot erase the first.

Also corrects the Joinability comment on ClubEntity, which documented
1=RequestToJoin / 2=InviteOnly. The real enum is Open=0, InviteOnly=1,
AskToJoin=2 — the inverted reading the requesttojoin handler was already fixed
away from, left behind where it could mislead the next change.
2026-07-28 09:19:35 +03:00
Alexa 327dcb789c fix: correct 2023-03-21 client wire contracts across the API and notify surfaces
Audits every route the March-2023 client can call against what this server
actually serves, and fixes the defects that were breaking gameplay. Adds
docs/recroom-2023-client-api-complete.md as the reference: ~500 route
literals across 13 subsystems, with verb, request/response shape, and a
per-subsystem diff. 315 defects catalogued; the ones fixed here are listed
in its "Already fixed" table.

Path coverage was never the problem — 465 of 506 routes already had
handlers. The failures were in shape, and they cluster into four causes:

- Wrong verb. The verb is a BestHTTP.HTTPMethods ordinal (GET=0 .. PATCH=5),
  confirmed from that enum's static constructor. Routes registered POST-only
  while the client PUTs returned 405, which made room consumables neither
  buyable nor consumable and blocked every room-key edit.
- Bare scalar wrapped in an object. The client reads `1000`, not
  `{"Limit":1000}`; the issuing method signature says which. Wrapping makes
  the deserializer throw and the feature dies silently.
- [FromBody] vs form-urlencoded. The client sends nearly every write as form
  data, which an [ApiController] action bound [FromBody] rejects with 415
  before the handler runs. This alone broke all 13 club member-management
  endpoints. Adds Binding/FormOrJsonModelBinder so this is fixed once.
- Notify dispatch keys. Both enum overloads of the client's RegisterHandler
  lower the id via Int32.ToString() and register only that numeric key, and
  lookup is a case-sensitive TryGetValue that returns silently on a miss. We
  were sending the enum NAME for most ids, so friend-request updates, forced
  logout, maintenance broadcasts, live balance and consumable updates, and
  invention moderation pushes all evaporated with no error anywhere.

Notable behavioural bugs fixed:

- Editing a club announcement deleted it: PUT was a third binding on the
  delete handler. Split apart, and the missing create route added.
- leaderboard/CheckAndSetStat did not exist. The 2023 client has no SetStat
  literal at all, so every leaderboard score it wrote was discarded.
- Setting a club clubhouse cleared it: the handler read roomId from the query
  while the client sends it in the body, then wrote the resulting null.
- Club join requests were inverted (the enum is Open=0, InviteOnly=1,
  AskToJoin=2), so ask-to-join clubs rejected everyone and invite-only clubs
  quietly admitted them.
- Room bans were pushed as id 24, for which the client registers no handler;
  they now go out as ModerationKick with IsBan, so the ban takes effect
  immediately instead of at next login.
- Room-key ownership queries answered for the wrong player, and "has anyone
  bought this key" asked "did I buy it" — always false for the creator.

Also persists settings that were previously acknowledged and dropped
(playlist accessibility/restrictions/level-voting/warning, per-player status
visibility, VR movement mode and avoid-juniors, custom room codes), which is
what the new columns in the migration are for.

One test asserted the old nested PriceAndCurrency response shape; the
client's consumable formatter has no such key and reads Price and
PurchaseCurrencyId flat, so the test was corrected alongside the handler.
2026-07-27 23:27:23 +03:00
Alexa e93bbb14cb feat: Implement room blob version clamp toggle; add settings endpoint and UI support for managing version clamping of imported rooms 2026-07-16 23:34:55 +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 757308b44d feat: Update PlayerCheer and Avatar handling; enhance API responses and add new fields for 2023 client compatibility 2026-07-12 23:54:11 +03:00
Alexa e27b06ce5b feat: Implement "everyone owns all avatar items" toggle; update server settings, controller logic, and admin UI 2026-07-09 11:37:47 +03:00
Alexa 74951d5c30 feat: Implement quest reward chest functionality; enhance gift generation and consumption logic, update database schema, and add tests for new behavior 2026-07-08 02:40:42 +03:00
Alexa 892c27ffea feat: Implement quest reward system with item selection and storage; update related services and database schema 2026-07-08 01:51:55 +03:00
Alexa fc60c9bf40 Refactor URL coverage documentation and update StoreService for color variants
- Updated `url-coverage.md` to clarify the behavior of the `api/rooms/v2/myRecent` endpoint.
- Enhanced `StoreService.cs` to include new properties for color variants: `combination_id` and `descriptor`.
- Modified logic in `StoreService` to validate color variants based on the new descriptor instead of swatch GUID.
- Updated database bootstrap scripts to create new tables for `RoomConsumables` and `RoomConsumableOwnership`, including necessary indexes.
- Revised README to reflect changes in debugging options and the introduction of `DorkNet.DebugMod`.
- Updated documentation on request expectations to clarify server-side behavior for room visibility.
- Enhanced installation script to provide clearer instructions for enabling the debug console.
- Added a new document detailing the process for dumping avatar items and color variants from the Rec Room client.
2026-07-07 14:28:40 +03:00
Alexa 628f430645 Add Charades word lists management, profanity filter, and matchmaking routes (#41)
* feat: add 3D Charades word lists management and profanity filter toggle

- Implemented Charades word lists management in the admin UI, allowing for unlimited named word lists with difficulty settings.
- Added functionality to bind live card slots to specific word lists, with automatic fallback to built-in lists.
- Introduced a profanity filter toggle in server settings, enabling or disabling the server-side profanity filter.
- Updated database schema to support new features, including additional columns for profanity filter status and charades slot bindings.
- Enhanced documentation to reflect new features and their usage.

* feat: add identityserver-signing.pfx to .gitignore

* feat: add new matchmake routes for player, event, club, and code
2026-07-02 10:11:18 +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 1d4777e3da feat: Enhance RoomZipImportController to support Unity asset bundles
- Added support for .assetbundle files in RoomZipImportController.
- Introduced new properties in RoomSceneEntity for handling Studio asset metadata.
- Updated ZipImport method to handle asset bundles during bulk imports.
- Enhanced CdnController to serve Unity asset bundles via a new route.
- Modified GoToController to include Unity asset ID in matchmaking responses.
- Updated database schema to accommodate new fields related to Studio asset bundles.
- Improved URL coverage documentation to reflect new routes for asset bundles.
2026-06-24 16:11:21 +03:00
Alexa 70980bf3b6 feat: Add new API controllers for progression events, room consumables, currencies, earnings distributions, screen share reports, subscription seasons, and UGC purchasables
- Implemented ProgressionEventsController to handle progression event retrieval and active events.
- Created RoomConsumablesController for listing and purchasing room consumables.
- Developed RoomCurrenciesController for managing room currencies, including creation, updates, and balance retrieval.
- Added RoomEarningsDistributionsController to fetch earnings distribution data for rooms.
- Introduced ScreenShareReportsController for reporting screen share incidents.
- Established SubscriptionSeasonsController to provide current subscription season details and rewards.
- Launched UgcPurchasablesController for managing user-generated content purchasables, including bulk operations.
- Added new data entities for customization and room economy, including custom avatar items, room currencies, and UGC purchasables.
2026-06-22 16:08:23 +03:00
Alexa 482c73e1bc feat: Implement adjustable room capacity and quest team size
- Added MaxCapacity property to RoomEntity and updated related controllers to utilize it.
- Modified RoomsController to set MaxPlayers based on room's MaxCapacity.
- Introduced QuestTeamSize class to dynamically adjust quest party sizes beyond the default limit.
- Updated DevMenu to include options for debugging and managing room settings.
- Created UI elements for adjusting MaxCapacity in the admin interface.
- Added configuration file for DevMenu with default settings.
2026-06-08 01:27:30 +03:00
Alexa 73d77dffb6 feat: enhance inventory schema to support longer ItemSlug and add GiftBox equipment payload handling 2026-06-06 22:50:42 +03:00
Alexa 31c53b9070 Refactor presence tracking: replace OnlinePresenceService with PlayerPresenceService for improved activity management and streamline message handling logic 2026-06-06 00:37:19 +03:00
Alexa fe1c2c53e3 Refactor leaderboard logic: incorporate room context into leaderboard stats and channel metadata handling 2026-06-05 23:55:26 +03:00
Alexa e2f169cdea Refactor RelationshipsController: merge relationship rows for accurate status representation and enhance gifting functionality in AdminController and Gift component 2026-06-04 15:55:59 +03:00
Alexa 8dfe4c8d63 Implement "Everyone is friends" toggle: add global friends functionality with server settings and UI integration 2026-06-04 13:40:15 +03:00
Alexa ef440bedaa Add game configuration management: implement endpoints for retrieving and updating discovered game configurations; enhance database schema and UI integration 2026-06-02 17:14:39 +03:00
Alexa 810ba0992c Add Rec Center doors management: implement endpoints for retrieving and updating door configurations; enhance database schema and UI integration 2026-06-02 17:08:42 +03:00
Alexa 218d92f856 Implement Play Menu Tags management: add endpoints for retrieving and updating tags; enhance database schema and UI integration 2026-06-02 16:46:28 +03:00
Alexa 3480ca21fa signup codes: admin-issued invite codes + site /join redemption
While account creation is disabled, the only way in is now an
admin-issued single-use signup code (Discord-invite style), redeemed on
the public site's /join page.

Because the 2020 watch login is device-id-bound with no code field, the
flow captures it server-side instead: a new device refused at the
signups-disabled gate (PlatformLogin / account create) is stashed in a
PendingDevices table keyed by the real client IP (CF-Connecting-IP aware).
The /join page then shows the player the device their own client just
reported, they enter their code + username, and the account is minted
bound to that device — so the next launch logs straight in via the
existing device-id path. No watch changes.

- SignupCodeEntity (code, descriptor, optional expiry, redeemer) +
  PendingDeviceEntity; idempotent CREATE TABLE in DatabaseBootstrap so
  both providers pick them up without a new migration.
- SignupCodeService: generate / list / revoke / redeem + pending-device
  capture, single-use + expiry + revoke validation.
- Admin: GET/POST signup-codes + revoke endpoints and a Signup codes
  admin-ui page (generate with descriptor/expiry, status table, revoke).
- Public: anonymous /api/site/v1/join pending-devices + redeem, and a
  /join site page (+ header link).
- README documents the flow + the post-Initial table-create approach.
2026-05-31 20:00:35 +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