mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 23:48:45 -07:00
fix: nested room-details objects carry only keys the client reads
Extends the parity check into the payload's nested objects — sub-room 0, the
first role, stats and the first tag each have their own generated reader, and a
key set that disagrees with one of those breaks the room just as hard as a
wrong top-level set.
It immediately found seven invented keys. Six on every sub-room (CurrentSave,
DefaultMatchmakingPolicy, LastModeratedSaveModerationState, ShouldAutoStageSaves,
StagedSubRoomDataSaveId, SubRoomUnityAssetId) and IsPrimaryGenre on every tag,
whose real shape is exactly {Tag, Type}. Six of the seven appear NOWHERE in the
decompile; SubRoomUnityAssetId exists but belongs to another DTO, not this one.
The extractor's minimum field count drops from 4 to 2, which is what let this
hide: a room tag has two fields, so a 4-field floor skipped its reader entirely
and the invented third key had nothing to be checked against. The alias rule in
fields_in() is what rejects false positives — the field count never was.
This does not explain the clone failure on its own: the captured response
carries all 41 top-level keys and is still rejected. But it removes the whole
class of "we send something the reader has no slot for" from the search.
This commit is contained in:
@@ -85,8 +85,40 @@ public sealed class ClientDtoParityTests : IClassFixture<DorkNetServerFactory>
|
||||
Assert.True(response.IsSuccessStatusCode, $"GET /rooms/{roomId} -> {(int)response.StatusCode}: {body}");
|
||||
|
||||
AssertKeyParity(RoomDetailsReader, body, $"GET rooms/{roomId}");
|
||||
|
||||
// The reader walks into the nested objects too, and a wrong key set
|
||||
// there fails exactly the same way — a 200 the client throws on.
|
||||
var details = JsonDocument.Parse(body).RootElement;
|
||||
foreach (var (property, reader) in NestedReaders)
|
||||
{
|
||||
if (!details.TryGetProperty(property, out var value)) continue;
|
||||
|
||||
var element = value.ValueKind switch
|
||||
{
|
||||
JsonValueKind.Array when value.GetArrayLength() > 0 => value[0],
|
||||
JsonValueKind.Object => value,
|
||||
_ => default,
|
||||
};
|
||||
if (element.ValueKind != JsonValueKind.Object) continue;
|
||||
|
||||
AssertKeyParity(reader, element.GetRawText(),
|
||||
$"GET rooms/{roomId} → {property}{(value.ValueKind == JsonValueKind.Array ? "[0]" : "")}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Nested objects in the room-details payload and the reader each
|
||||
/// one is deserialised by. Sub-room 0, the first role, the stats object and
|
||||
/// the first tag all have their own generated readers, and a key set that
|
||||
/// disagrees with them breaks the whole room just as hard as a wrong
|
||||
/// top-level one.</summary>
|
||||
private static readonly (string Property, string Reader)[] NestedReaders =
|
||||
[
|
||||
("SubRooms", "JDEKAFDPGBE"),
|
||||
("Roles", "LMEECKCCPHG"),
|
||||
("Stats", "MLHBPDKBABN"),
|
||||
("Tags", "GEGADPCDGBO"),
|
||||
];
|
||||
|
||||
[Fact]
|
||||
public async Task Chat_thread_carries_exactly_the_keys_the_client_reads()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user