diff --git a/DorkNet.Server/Controllers/Admin/AdminController.cs b/DorkNet.Server/Controllers/Admin/AdminController.cs index 298bde0..f95e432 100644 --- a/DorkNet.Server/Controllers/Admin/AdminController.cs +++ b/DorkNet.Server/Controllers/Admin/AdminController.cs @@ -975,7 +975,8 @@ public class AdminController( double? HotScore, int? State, string? ImageName, - int? MaxCapacity); + int? MaxCapacity, + bool? IsAGRoom); /// POST api/admin/v1/rooms/{id}/props — partial /// update of room properties. Only the non-null fields in the @@ -1005,6 +1006,20 @@ public class AdminController( room.MaxCapacity = Math.Clamp(cap, 1, 80); changes.Add($"maxCapacity={room.MaxCapacity}"); } + if (body.IsAGRoom is bool ag) + { + // IsAGRoom is what the client reads as IsRRO. True: load the + // baked scene from the client's own assets AND consult the + // client-baked AGRoomRuntimeConfig table (which, per original, + // decides e.g. whether creation is allowed — Rec Center yes, Rec + // Royale no). False: treat the room as a custom room (roles and + // blob decide everything). Flipping a CLONE of a baked original + // to false is the server-side experiment for "editable Rec + // Royale"; whether the client still loads the baked scene for a + // non-original is what that experiment answers. + room.IsAGRoom = ag; + changes.Add($"isAGRoom={ag}"); + } if (changes.Count == 0) return Ok(new { room.Id, unchanged = true }); diff --git a/DorkNet.Server/admin-ui/src/pages/Room.tsx b/DorkNet.Server/admin-ui/src/pages/Room.tsx index 395ddf8..4a6eae7 100644 --- a/DorkNet.Server/admin-ui/src/pages/Room.tsx +++ b/DorkNet.Server/admin-ui/src/pages/Room.tsx @@ -165,6 +165,7 @@ function GeneralTab({ room, onSaved }: { room: RoomDetail; onSaved: () => void } const [description, setDescription] = useState(room.description); const [accessibility, setAccessibility] = useState(room.accessibility); const [cloningAllowed, setCloningAllowed] = useState(room.cloningAllowed); + const [isAGRoom, setIsAGRoom] = useState(room.isAGRoom); const [tagsCsv, setTagsCsv] = useState(room.tagsCsv); const [hotScore, setHotScore] = useState(String(room.hotScore)); const [imageName, setImageName] = useState(room.imageName); @@ -176,6 +177,7 @@ function GeneralTab({ room, onSaved }: { room: RoomDetail; onSaved: () => void } setDescription(room.description); setAccessibility(room.accessibility); setCloningAllowed(room.cloningAllowed); + setIsAGRoom(room.isAGRoom); setTagsCsv(room.tagsCsv); setHotScore(String(room.hotScore)); setImageName(room.imageName); @@ -193,6 +195,7 @@ function GeneralTab({ room, onSaved }: { room: RoomDetail; onSaved: () => void } Description: description, Accessibility: accessibility, CloningAllowed: cloningAllowed, + IsAGRoom: isAGRoom, TagsCsv: tagsCsv, HotScore: Number.isFinite(hot) ? hot : undefined, ImageName: imageName, @@ -283,6 +286,14 @@ function GeneralTab({ room, onSaved }: { room: RoomDetail; onSaved: () => void } /> Cloning allowed +