mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 15:08:47 -07:00
feat: Enhance room save flow documentation and tests to ensure all required fields are present; update validation logic for Room and SubRoomDataSave
This commit is contained in:
@@ -78,13 +78,20 @@ public sealed class RoomSave2023Tests : IClassFixture<DorkNetServerFactory>
|
|||||||
|
|
||||||
// 2023 commit-response contract (NEOPBOMGIOG): value must carry
|
// 2023 commit-response contract (NEOPBOMGIOG): value must carry
|
||||||
// BOTH a Room and a SubRoomDataSave or the client's post-parse
|
// BOTH a Room and a SubRoomDataSave or the client's post-parse
|
||||||
// validator NREs and the watch shows "Failed to save room".
|
// Dispose walk NREs and the watch shows "Failed to save room".
|
||||||
var value = json.RootElement.GetProperty("value");
|
var value = json.RootElement.GetProperty("value");
|
||||||
Assert.Equal(JsonValueKind.Object, value.GetProperty("Room").ValueKind);
|
var roomDto = value.GetProperty("Room");
|
||||||
|
Assert.Equal(JsonValueKind.Object, roomDto.ValueKind);
|
||||||
|
// Keys the FGCPNAACHIK mapper reads and its Dispose walk derefs.
|
||||||
|
foreach (var key in new[] { "RoomId", "DataBlob", "MaxPlayers", "ToxmodEnabled", "RankingContext", "SubRooms", "Roles", "Tags", "Stats" })
|
||||||
|
Assert.True(roomDto.TryGetProperty(key, out _), $"Room missing '{key}': {responseText}");
|
||||||
|
Assert.Equal(JsonValueKind.Object, roomDto.GetProperty("RankingContext").ValueKind);
|
||||||
|
|
||||||
var save = value.GetProperty("SubRoomDataSave");
|
var save = value.GetProperty("SubRoomDataSave");
|
||||||
Assert.Equal(blobName, save.GetProperty("DataBlob").GetString());
|
Assert.Equal(blobName, save.GetProperty("DataBlob").GetString());
|
||||||
Assert.True(save.TryGetProperty("SubRoomDataSaveId", out _), responseText);
|
// Keys the JKIFFPPAJNK save mapper reads.
|
||||||
Assert.True(save.TryGetProperty("CreatedAt", out _), responseText);
|
foreach (var key in new[] { "SubRoomDataSaveId", "SubRoomId", "UnityAssetId", "DataBlobHash", "SavedByAccountId", "Description", "CreatedAt" })
|
||||||
|
Assert.True(save.TryGetProperty(key, out _), $"SubRoomDataSave missing '{key}': {responseText}");
|
||||||
|
|
||||||
await using (var scope = _factory.Services.CreateAsyncScope())
|
await using (var scope = _factory.Services.CreateAsyncScope())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -700,6 +700,12 @@ public class RoomsController(
|
|||||||
ReferencedUnityAssetIds = Array.Empty<string>(),
|
ReferencedUnityAssetIds = Array.Empty<string>(),
|
||||||
DataBlob = dataBlob,
|
DataBlob = dataBlob,
|
||||||
DataBlobName = dataBlob,
|
DataBlobName = dataBlob,
|
||||||
|
// DataBlobHash + Description are read by the save mapper
|
||||||
|
// (JKIFFPPAJNK / PELEHJLMKJO) that the SaveRoom commit
|
||||||
|
// response deserializes; omitting them leaves nulls the
|
||||||
|
// response Dispose walk trips on.
|
||||||
|
DataBlobHash = (string?)null,
|
||||||
|
Description = string.Empty,
|
||||||
PersistenceVersion = 41,
|
PersistenceVersion = 41,
|
||||||
OMVersion = 0,
|
OMVersion = 0,
|
||||||
SavedByAccountId = room.CreatorPlayerId,
|
SavedByAccountId = room.CreatorPlayerId,
|
||||||
@@ -1978,6 +1984,26 @@ public class RoomsController(
|
|||||||
},
|
},
|
||||||
PublishState = 0,
|
PublishState = 0,
|
||||||
MaxPlayerCalculationMode = room.MaxPlayerCalculationMode,
|
MaxPlayerCalculationMode = room.MaxPlayerCalculationMode,
|
||||||
|
// 2023's room-details mapper (FGCPNAACHIK / GLEGPFFPDBE) reads
|
||||||
|
// these top-level keys and its Dispose walk (NEOPBOMGIOG.
|
||||||
|
// FKDDCNLJOLF, reached via the SaveRoom commit response)
|
||||||
|
// dereferences them — a missing RankingContext object or the
|
||||||
|
// DataBlob/MaxPlayers/ToxmodEnabled scalars leaves a null the
|
||||||
|
// walk NREs on ("Failed to save room" toast despite a
|
||||||
|
// persisted save). Emit them so the room DTO round-trips
|
||||||
|
// through the strict save-response path, not just the
|
||||||
|
// include-masked GET rooms/{id} path.
|
||||||
|
DataBlob = dataBlobName,
|
||||||
|
DataBlobHash = (string?)null,
|
||||||
|
MaxPlayers = sceneRows is { Count: > 0 } ? sceneRows[0].MaxPlayers : room.MaxCapacity,
|
||||||
|
ToxmodEnabled = false,
|
||||||
|
RankingContext = new
|
||||||
|
{
|
||||||
|
RoomId = room.Id,
|
||||||
|
Score = 0.0,
|
||||||
|
Rank = 0,
|
||||||
|
RankingType = 0,
|
||||||
|
},
|
||||||
SubRooms = subRooms,
|
SubRooms = subRooms,
|
||||||
Roles = wireRoles,
|
Roles = wireRoles,
|
||||||
LoadScreens = JsonArrayOrEmpty(room.LoadScreensJson),
|
LoadScreens = JsonArrayOrEmpty(room.LoadScreensJson),
|
||||||
|
|||||||
@@ -52,12 +52,20 @@ on 2026-07-07. Diagnosed while fixing "Failed to save room" /
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The client's post-parse validator NREs if `Room` or
|
The client parses each field then runs a **Dispose walk**
|
||||||
`SubRoomDataSave` is missing — the save persists server-side but the
|
(`NEOPBOMGIOG.FKDDCNLJOLF`, reached from the SaveRoom commit
|
||||||
watch shows "Failed to save room". `SubRoomDataSave` keys per the
|
continuation) that dereferences the mapped children — a missing
|
||||||
`JKIFFPPAJNK` mapper (`PELEHJLMKJO`): SubRoomDataSaveId, SubRoomId,
|
nested object or scalar leaves a null it NREs on, and the save
|
||||||
UnityAssetId, DataBlob, DataBlobHash, SavedByAccountId,
|
persists server-side but the watch shows "Failed to save room". So
|
||||||
SavedOnPlatform, SavedOnDeviceClass, Description, CreatedAt.
|
the `Room` DTO must carry every key the `FGCPNAACHIK` mapper
|
||||||
|
(`GLEGPFFPDBE`) reads, including the ones the include-masked
|
||||||
|
`GET rooms/{id}` path gets away without: **DataBlob**,
|
||||||
|
**DataBlobHash**, **MaxPlayers**, **ToxmodEnabled**, and a non-null
|
||||||
|
**RankingContext** object, plus SubRooms/Roles/Tags/Stats.
|
||||||
|
`SubRoomDataSave` keys per the `JKIFFPPAJNK` mapper (`PELEHJLMKJO`):
|
||||||
|
SubRoomDataSaveId, SubRoomId, UnityAssetId, DataBlob, **DataBlobHash**,
|
||||||
|
SavedByAccountId, SavedOnPlatform, SavedOnDeviceClass, **Description**,
|
||||||
|
CreatedAt.
|
||||||
|
|
||||||
Server handling: `StorageController.Upload` (FileType 6 →
|
Server handling: `StorageController.Upload` (FileType 6 →
|
||||||
`UploadGenericAsync("roommeta")`, CDN-servable) and
|
`UploadGenericAsync("roommeta")`, CDN-servable) and
|
||||||
|
|||||||
Reference in New Issue
Block a user