diff --git a/DorkNet.Server.Tests/RoomSave2023Tests.cs b/DorkNet.Server.Tests/RoomSave2023Tests.cs index 373f5f1..2b486aa 100644 --- a/DorkNet.Server.Tests/RoomSave2023Tests.cs +++ b/DorkNet.Server.Tests/RoomSave2023Tests.cs @@ -76,21 +76,21 @@ public sealed class RoomSave2023Tests : IClassFixture using var json = JsonDocument.Parse(responseText); Assert.True(json.RootElement.GetProperty("success").GetBoolean(), responseText); - // 2023 commit-response contract (NEOPBOMGIOG): value must carry - // BOTH a Room and a SubRoomDataSave or the client's post-parse - // Dispose walk NREs and the watch shows "Failed to save room". + // 2023 commit-response contract (NEOPBOMGIOG): value carries a + // Room and a SubRoomDataSave. The Room reuses the exact GET + // rooms/{id} shape (BuildRoomServerDetails) — do NOT bolt extra + // keys onto it: the room-details mapper is strict about value + // shapes and an invented RankingContext object broke every + // room-details parse ("Malformed Response"). See befd590 revert. var value = json.RootElement.GetProperty("value"); 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" }) + foreach (var key in new[] { "RoomId", "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"); Assert.Equal(blobName, save.GetProperty("DataBlob").GetString()); - // Keys the JKIFFPPAJNK save mapper reads. - foreach (var key in new[] { "SubRoomDataSaveId", "SubRoomId", "UnityAssetId", "DataBlobHash", "SavedByAccountId", "Description", "CreatedAt" }) + foreach (var key in new[] { "SubRoomDataSaveId", "SubRoomId", "UnityAssetId", "SavedByAccountId", "CreatedAt" }) Assert.True(save.TryGetProperty(key, out _), $"SubRoomDataSave missing '{key}': {responseText}"); await using (var scope = _factory.Services.CreateAsyncScope()) diff --git a/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs b/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs index 6be4c55..99584c5 100644 --- a/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs +++ b/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs @@ -700,12 +700,6 @@ public class RoomsController( ReferencedUnityAssetIds = Array.Empty(), DataBlob = 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, OMVersion = 0, SavedByAccountId = room.CreatorPlayerId, @@ -1984,26 +1978,6 @@ public class RoomsController( }, PublishState = 0, 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, Roles = wireRoles, LoadScreens = JsonArrayOrEmpty(room.LoadScreensJson),