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:
Alexa
2026-07-28 11:27:35 +03:00
parent 078d576383
commit 4a1ac47007
4 changed files with 1103 additions and 47 deletions
@@ -85,7 +85,39 @@ 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()
@@ -8,6 +8,11 @@
"Price",
"ModifiedAt"
],
"ABJLKAFOPMP": [
"GiftDropIds",
"Message",
"SubscriptionPurchase"
],
"ACKNGEEHHAE": [
"RoomId",
"SubRoomId",
@@ -24,6 +29,11 @@
"DefaultBroadcastPermissions",
"CanRequestBroadcastPermissions"
],
"ADAFNGNADFH": [
"InviteeAccountId",
"CreatedAt",
"VerifiedAt"
],
"ADDGMGGOLHM": [
"BlobName",
"Title",
@@ -31,6 +41,20 @@
"ThumbnailBlobName",
"SourceUrl"
],
"ADMGGPDGKCE": [
"Msg",
"Id"
],
"AECJMONHBHM": [
"ClubId",
"LastReadAnnouncementId",
"Announcements"
],
"AEGADMDIKNE": [
"Value",
"Success",
"Error"
],
"AEGCKMKICFG": [
"AccountId",
"UserName",
@@ -45,6 +69,19 @@
"CreatedAt",
"IsJunior"
],
"AEHFGHPLNDO": [
"AccountId",
"LastVisitedAt"
],
"AFHCKGCJNFM": [
"Msg",
"Id"
],
"AFJDLEFKNFP": [
"Value",
"Success",
"Error"
],
"AHJKILCAGML": [
"ChallengeId",
"Name",
@@ -78,12 +115,20 @@
"Platform",
"CreatedAt"
],
"AKKPACEJJFK": [
"Msg",
"Id"
],
"ALGKCAKCFAJ": [
"BalanceUpdates",
"Balance",
"CurrencyType",
"Platform"
],
"ALJPHDEAHBK": [
"Result",
"Tags"
],
"AMPFGJPKHOD": [
"Device_code",
"User_code",
@@ -118,6 +163,11 @@
"CreatedAt",
"ModifiedAt"
],
"ANPJKOOEEBB": [
"Identifier",
"Genuine",
"GenuineCheckAvailable"
],
"AOAACMFGAGK": [
"ChallengeMapId",
"ChallengeThemeString",
@@ -159,6 +209,23 @@
"CurrencyType",
"Platform"
],
"BBFGGPEMLLE": [
"Value",
"Success",
"Error"
],
"BBMJLKMGFGA": [
"Msg",
"Id"
],
"BCEJDGGBBHC": [
"Price",
"CurrencyId"
],
"BCMOCNHAJCL": [
"Status",
"Consumable"
],
"BGFBJCIOIFP": [
"SkuId",
"Name",
@@ -176,6 +243,20 @@
"ShouldAppearInTokenStore",
"Data"
],
"BIMHOENEGII": [
"Group",
"IsCompleted",
"ClearedAt"
],
"BJHOKILBIML": [
"FeedItemType",
"FeedItemId"
],
"BKCOBJILFEI": [
"KeepsakeFeatureEnabled",
"KeepsakeRoomLimit",
"SocialXpBoostEnabled"
],
"BKFOGBGPLFP": [
"SavedImageId",
"ImageName",
@@ -217,6 +298,19 @@
"ClubhouseRoomId",
"ClubType"
],
"BLPIIBBPOJM": [
"Action",
"Reason",
"Error"
],
"BLPNLMALDAC": [
"AccountId",
"Bio"
],
"BPAPIKPFDAH": [
"Difficulty",
"EN_US"
],
"BPHCOIBNCDP": [
"ClubId",
"Type",
@@ -227,6 +321,14 @@
"EditPermissionSettings",
"BanUnban"
],
"CAAJPHFCIPK": [
"ReportCategory",
"Reason"
],
"CAEHDIMCGLD": [
"Msg",
"Id"
],
"CAKCKAMAAPP": [
"ClubId",
"LastAnnouncementId",
@@ -241,6 +343,21 @@
"Contents",
"ModerationState"
],
"CBNEDELBFAJ": [
"Clubs",
"TotalClubs",
"ContinuationToken"
],
"CCAGOJFGLLO": [
"FeedItemType",
"FeedItemId",
"FeedAlgorithmVersion"
],
"CCKEEAMMHPJ": [
"UnityAssetId",
"CreatedByAccountId",
"BakedUnityAssets"
],
"CDEDNEPPPND": [
"LevelProgressionMaps",
"DailyObjectives",
@@ -313,6 +430,10 @@
"CanRequestBroadcastPermissions",
"BroadcastingRoomInstanceId"
],
"CGACOKHBJCB": [
"Msg",
"Id"
],
"CGCKIMIEHNM": [
"Name",
"Description",
@@ -336,6 +457,11 @@
"Stats",
"RankingContext"
],
"CHEMHPGCJBM": [
"PlayerId",
"Score",
"Rank"
],
"CHKOLCGMCKJ": [
"ReportBudget",
"FilterType",
@@ -418,6 +544,15 @@
"AvatarItemId",
"IsBaseAvatarItem"
],
"CMBHBADOOAF": [
"Msg",
"Id"
],
"CMHEJKENPBH": [
"TriggerType",
"TriggerId",
"TriggeredAt"
],
"CMLNDGCIPIH": [
"Index",
"Group",
@@ -426,6 +561,29 @@
"IsCompleted",
"HasClaimedReward"
],
"CNFFPECMOHE": [
"Value",
"Success",
"Error"
],
"CNNAFLNKDCL": [
"AccountId",
"KeepsakeInstanceId",
"CollectedAt"
],
"CNNEAFEIMPP": [
"Msg",
"Id"
],
"COIELAHKALG": [
"Enabled",
"Key",
"Region"
],
"DCECPNPOEFG": [
"Msg",
"Id"
],
"DDDLCGDEPNH": [
"PlayerEventResponseId",
"PlayerEventId",
@@ -433,6 +591,33 @@
"CreatedAt",
"Type"
],
"DDFBPFOBIAO": [
"ImageName",
"Accessibility"
],
"DDFNNBDLBKF": [
"AccountId",
"ClubId",
"SubscriberCount"
],
"DEIDIGKKLHE": [
"Results",
"TotalResults"
],
"DFKDBJMNKCO": [
"Event",
"NewSubscription"
],
"DHAPGKPJDKH": [
"Value",
"Success",
"Error"
],
"DHMKNFOLCGM": [
"Value",
"Success",
"Error"
],
"DICIOFKDIEE": [
"Season",
"Name",
@@ -446,6 +631,69 @@
"NextUpdate",
"NewUntil"
],
"DIEEOOKELHG": [
"AccountId",
"IsRecentHistoryVisible"
],
"DILNAKMDJOF": [
"RoomId",
"SubRoomId",
"KeepsakeCategory"
],
"DJCLNEEBAJP": [
"Value",
"Success",
"Error"
],
"DJFEOAGKKAK": [
"FreshnessSeconds",
"Url"
],
"DJFIAOIFLDI": [
"Memberships",
"TotalMemberships",
"ContinuationToken"
],
"DJHIABKJLBD": [
"RoomInstanceId",
"PhotonAccessToken",
"Permissions"
],
"DKHBLLDMDHB": [
"Msg",
"Id"
],
"DKMBKPLABAG": [
"Type",
"Score"
],
"DKNKIEOODHK": [
"Value",
"Success",
"Error"
],
"DLJCLHBGADL": [
"Msg",
"Id"
],
"DNBAAJILMPE": [
"RoomId",
"ClubId",
"PlayerCount"
],
"DOINHLNFOCP": [
"Msg",
"Id"
],
"DOJEJNECAAI": [
"Value",
"Success",
"Error"
],
"DOMOBFDIAJA": [
"AccountId",
"CheeredAt"
],
"DPHFOPBAAPN": [
"PlayerId",
"StatChannel",
@@ -453,6 +701,15 @@
"FilterType",
"SortAscending"
],
"DPIECEMDKPL": [
"CreatorPlayerId",
"Data",
"IsValid"
],
"DPKHIGPMCIP": [
"InviteId",
"Name"
],
"DPNLANKOHON": [
"AccountId",
"CurrencyId",
@@ -469,6 +726,16 @@
"NMTOKENS",
"NOTATION"
],
"EACKMEGHIGM": [
"AccountId",
"ClubId",
"CreatedAt"
],
"ECEBBLBCFKO": [
"AccountId",
"BannedByAccountId",
"BanStartTime"
],
"ECHJAKNMEEC": [
"KeepsakeRoomListId",
"ProgressionEventId",
@@ -488,6 +755,19 @@
"Platform",
"CurrencyType"
],
"EDMKBBPGJAB": [
"Balance",
"RoomKeyResponse"
],
"EEAAGIJHLOJ": [
"PlayerEvent",
"Result",
"TagModifyResult"
],
"EHFKGCIDOFL": [
"Results",
"TotalResults"
],
"EHKEOCKBCDH": [
"Items",
"FeedInstanceId",
@@ -511,6 +791,14 @@
"Type",
"Order"
],
"EJIHDJDKKEC": [
"AccountId",
"RoomKeyId"
],
"EJNFJPNOFFO": [
"Msg",
"Id"
],
"EKEFFNBIOHJ": [
"ChatThreadId",
"LastReadMessageId",
@@ -571,6 +859,28 @@
"PlayerEventInviteEmails",
"PlayerEventReminderEmails"
],
"ENJDEONHNMO": [
"Created",
"Responses"
],
"EOFEKNIHNNC": [
"PlayerEventId",
"BroadcastRoomInstanceId"
],
"EOILOIMIJLJ": [
"Value",
"Success",
"Error"
],
"EOIMIBBJBCB": [
"ImageName",
"Title",
"Subtitle"
],
"EPPPACFECMH": [
"Type",
"Reference"
],
"EncodingTable": [
"Big5",
"GB2312",
@@ -580,6 +890,15 @@
"IBM861",
"IBM869"
],
"FAMGNALGHPN": [
"Msg",
"Id"
],
"FBNOJCDDBJK": [
"XPAwardStrings",
"TotalXPAwarded",
"NewProgress"
],
"FCIBLPCOODP": [
"RoomConsumableId",
"RoomId",
@@ -590,6 +909,34 @@
"PurchaseCurrencyId",
"ModifiedAt"
],
"FCJNIBGKHDM": [
"ClubId",
"MembershipType"
],
"FDPFICCCJNM": [
"Msg",
"Id"
],
"FEJOMKJBOOE": [
"RoomId",
"EarningsDistributionMapping",
"EarningsDistributionMethod"
],
"FIFFMMLKKCJ": [
"PlayerId",
"Level",
"XP"
],
"FJJIJOGNMCP": [
"ReferralRewardTierId",
"RequiredReferralCount",
"RewardSelectionCount"
],
"FJNBDGFCLOF": [
"Value",
"Success",
"Error"
],
"FKANCKLCCDI": [
"Id",
"FromPlayerId",
@@ -608,6 +955,41 @@
"PlatformsToSpawnOn",
"BalanceType"
],
"FKPPDBLFKHJ": [
"Msg",
"Id"
],
"FLEDNKHKIND": [
"InfluencerIds",
"ContinuationToken"
],
"FLELPHJDLNG": [
"Filename",
"Hash",
"OwnershipProof"
],
"FLMCOHEGJEI": [
"RequiresEliteUpgrade",
"GiftDrop",
"SeasonXpBoost"
],
"FMIDLABJCLM": [
"Strings",
"StringPackageVersion"
],
"FMKALNIKMKF": [
"AccountId",
"MembershipType"
],
"FMNDPHMOIIH": [
"Msg",
"Id"
],
"FNDBGOGAIFL": [
"Value",
"Success",
"Error"
],
"FNIDAIDJBBO": [
"PlayerID",
"RelationshipType",
@@ -615,6 +997,10 @@
"Ignored",
"Favorited"
],
"FNNAJDFFICN": [
"ReportId",
"Client"
],
"FOIMFMEEGDI": [
"SupportsJoinInProgress",
"UseLevelBasedMatchmaking",
@@ -634,6 +1020,20 @@
"MaxPlayers",
"Accessibility"
],
"FOKKDBJEFOO": [
"Value",
"Success",
"Error"
],
"FOOOKJCPBKC": [
"Msg",
"Id"
],
"FPGBBCLENDA": [
"StorefrontType",
"NextUpdate",
"NewUntil"
],
"FPLGJGDJIJG": [
"StorefrontType",
"PurchasableItemId",
@@ -642,6 +1042,10 @@
"CouponConsumablePlayerMappingId",
"Gift"
],
"FPNMHECOPPF": [
"UpdateResponse",
"Data"
],
"FPNOOOFJBJF": [
"RankStart",
"RankEnd",
@@ -725,6 +1129,10 @@
"Delta",
"Press"
],
"GACOLGJKHBI": [
"VersionStatus",
"UpdateNotificationStage"
],
"GAGIJHJGFJD": [
"AccountId",
"CurrencyId",
@@ -732,6 +1140,18 @@
"AmountAwarded",
"AwardedAt"
],
"GAODOHODBDE": [
"FailedInvites",
"Result"
],
"GBPDOLJBABB": [
"Success",
"Message"
],
"GBPHFPMCGHH": [
"Subscription",
"PlatformAccountSubscribedPlayerId"
],
"GCKGIDLDBNH": [
"Error",
"Error_description",
@@ -749,6 +1169,26 @@
"MicSpamSamplePercentageForForceMuteToEnd",
"MicSpamWarningStateVolumeMultiplier"
],
"GEEKOKDMAHG": [
"AccountId",
"ApiKey"
],
"GEGADPCDGBO": [
"Tag",
"Type"
],
"GEMBOCLPFGE": [
"AccountId",
"FavoritedAt"
],
"GFCIGEIEPGH": [
"Msg",
"Id"
],
"GFGBAAADKEL": [
"Msg",
"Id"
],
"GFGKDCENJMB": [
"AccountId",
"Xp",
@@ -757,6 +1197,10 @@
"BonusRewardsCollected",
"XpBoostLastPurchasedAt"
],
"GFHNJMMBHFD": [
"PlayerEventId",
"Type"
],
"GFIHPOOFHLC": [
"AnnouncementId",
"CreatorAccountId",
@@ -784,6 +1228,14 @@
"CheerGreatHost",
"CheerSportsman"
],
"GGFHKCDELJH": [
"Id",
"Link"
],
"GHBIGGJKPFI": [
"Events",
"ContinuationToken"
],
"GIFNHCGDNEM": [
"Platform",
"PlatformId",
@@ -792,6 +1244,21 @@
"RequirePassword",
"RefreshToken"
],
"GIJCKEDKGLH": [
"ReportCategory",
"PlayerEventId",
"Details"
],
"GJGLBNABMNL": [
"CreatorAccountId",
"ClubId",
"MembershipType"
],
"GKFBDCHILOD": [
"Value",
"Success",
"Error"
],
"GLEGPFFPDBE": [
"DataBlob",
"DataBlobHash",
@@ -841,6 +1308,15 @@
"Url",
"RedemptionUrl"
],
"GMBGBPNMGBA": [
"Status",
"Invention",
"InventionVersion"
],
"GMDIDJMOEBB": [
"Objectives",
"ObjectiveGroups"
],
"GMFJIAMOIEO": [
"SubscriptionId",
"RecNetPlayerId",
@@ -854,6 +1330,10 @@
"CreatedAt",
"ModifiedAt"
],
"GMNMHECGEGD": [
"CurrencyType",
"BalanceAdds"
],
"GNIPAKCCOOE": [
"ProgressionEventId",
"Name",
@@ -918,6 +1398,22 @@
"Stats",
"RankingContext"
],
"GUISkin": [
"HorizontalSliderThumbExtent",
"VerticalSliderThumbExtent"
],
"HADOHMCCLEO": [
"Msg",
"Id"
],
"HBKAFCAEFCC": [
"CreatedAt",
"Comment"
],
"HDLOMAGLILM": [
"Msg",
"Id"
],
"HDOJMEBCAGP": [
"Permission",
"Role",
@@ -925,6 +1421,34 @@
"Type",
"Value"
],
"HECILPKCKMK": [
"FeaturedRoomGroupId",
"Name",
"Rooms"
],
"HEIPMIFEFEE": [
"Value",
"Success",
"Error"
],
"HEKMOMJFFGJ": [
"Value",
"Success",
"Error"
],
"HFHNOHAODOF": [
"ValidTill",
"Images"
],
"HFODJDLIJPG": [
"TargetPlayerId",
"RoomName",
"ActionCode"
],
"HGJDGKFIOCK": [
"Msg",
"Id"
],
"HHJLCKPJOIA": [
"PlayerId",
"StatusVisibility",
@@ -935,6 +1459,10 @@
"AppVersion",
"ClientJoinData"
],
"HHOJLJGGNKN": [
"Msg",
"Id"
],
"HIKOJENMDKE": [
"KeepsakeCategoryId",
"VisualId",
@@ -943,6 +1471,20 @@
"IconOutlineImageName",
"IconFilledImageName"
],
"HIOJNFKGAOK": [
"Value",
"Success",
"Error"
],
"HIOPBEPNFOO": [
"Value",
"Success",
"Error"
],
"HJKLIIPPPEM": [
"PlayerEvent",
"PlayerEventResponse"
],
"HJOIJBMAIPO": [
"PlaylistId",
"Name",
@@ -967,6 +1509,11 @@
"Stats",
"RankingContext"
],
"HJOKFJKKEJM": [
"BalanceUpdateResult",
"TokenBalanceResponse",
"OperationResult"
],
"HJPEABLEEKL": [
"RoomConsumableId",
"RoomId",
@@ -975,6 +1522,10 @@
"ImageName",
"PriceAndCurrency"
],
"HKAGNIGNBOJ": [
"Msg",
"Id"
],
"HKIJINJGBGD": [
"Type",
"User_id",
@@ -983,6 +1534,49 @@
"Gameplay_session_id",
"Transaction_id"
],
"HKPKGOPHLHE": [
"RoomInstanceCount",
"PlayerCount"
],
"HLDLKOPNDPF": [
"Value",
"Success",
"Error"
],
"HMDONHHKKGA": [
"PinnedFilters",
"PopularFilters",
"TrendingFilters"
],
"HMGHGBMGNJG": [
"Msg",
"Id"
],
"HMKMGPNMHBM": [
"Instances",
"CollectionRecords",
"KeepsakeProgressionEventIds"
],
"HMMFNEEAFGP": [
"Results",
"TotalResults"
],
"HNLGHDMNMDB": [
"UpdateResponse",
"Data"
],
"HOGIMIPDDGP": [
"ImageName",
"ImageUrl"
],
"HPAKKJFOFDF": [
"Msg",
"Id"
],
"HPEGLGGMNMC": [
"ChatThread",
"ChatResult"
],
"HPMMKFGDAEC": [
"PlayerEventId",
"CreatorPlayerId",
@@ -1002,6 +1596,11 @@
"CanRequestBroadcastPermissions",
"BroadcastingRoomInstanceId"
],
"IACBFJEMJMJ": [
"Value",
"Success",
"Error"
],
"IAPMDDFENDD": [
"PurchasableItemId",
"CouponConsumablePlayerMappingId",
@@ -1029,6 +1628,44 @@
"CheerCount",
"CommentCount"
],
"ICMBGNCJMJG": [
"Value",
"Success",
"Error"
],
"ICNLODNGFJJ": [
"Value",
"Success",
"Error"
],
"IDBFKCFEAHM": [
"BalanceUpdateResult",
"CurrencyBalanceResponse",
"OperationResult"
],
"IDBLMMAGACO": [
"Key",
"Value"
],
"IDFEIMCEMCC": [
"Level",
"Period",
"IsAutoRenewing"
],
"IEIKHFIPDMD": [
"CurrencyType",
"Price",
"StorefrontSaleData"
],
"IFFEHJEPKOH": [
"ReferralsVerifiedCount",
"PlayerReferralRewards"
],
"IFLDEEGLKFG": [
"Level",
"RequiredXp",
"GiftDropId"
],
"IGMCJEFBJCF": [
"ServerTime",
"PlayerId",
@@ -1040,12 +1677,30 @@
"AppVersion",
"ClientJoinData"
],
"IGNECOJDECH": [
"Info",
"ReferrerId"
],
"IHGDKHPLIGH": [
"RoomId",
"RoomName",
"ImageName"
],
"IJFKOMJBJMI": [
"StatChannel",
"RoomId",
"StatValue",
"CurrentStatValue"
],
"ILAHMLLJDLE": [
"Value",
"Success",
"Error"
],
"ILEHDPADJJF": [
"Nouns",
"Adjectives"
],
"ILJOBJDPBNJ": [
"Name",
"Description",
@@ -1127,6 +1782,14 @@
"MemberPermissions",
"MyMembershipType"
],
"JBGKGCLPCHP": [
"Results",
"TotalResults"
],
"JBIEJIKHBMG": [
"SeedRoom",
"Rooms"
],
"JCPFCOEEELK": [
"AccountId",
"CurrencyId",
@@ -1155,6 +1818,14 @@
"MaxPlayers",
"Accessibility"
],
"JEBCHNDADKK": [
"ConcurrencyCodes",
"ExpectedPriceAndCurrency"
],
"JFEKPNOKFBP": [
"Msg",
"Id"
],
"JGJFCFAFGCM": [
"TotalXP",
"Level",
@@ -1164,6 +1835,10 @@
"NextLevelXPThreshold",
"NextLevelAcornReward"
],
"JHNAJMDHFKH": [
"Msg",
"Id"
],
"JICIOMDBPDO": [
"Id",
"ConsumableItemDesc",
@@ -1174,6 +1849,10 @@
"IsActive",
"IsTransferable"
],
"JIOEIEENGNO": [
"Msg",
"Id"
],
"JJEKBGHDCEG": [
"Tier",
"Rewards",
@@ -1199,6 +1878,10 @@
"GiftContext",
"GiftRarity"
],
"JKJHOAKNOCF": [
"CurrentConcurrencyCode",
"NewConcurrencyCode"
],
"JLIBBFMMLFF": [
"CurrencyType",
"BalanceAddType",
@@ -1211,6 +1894,18 @@
"RateLimit",
"BalanceInGiftBox"
],
"JLNFEFHNFBP": [
"Title",
"Description"
],
"JLNKMODEKKM": [
"BaseAvatarItemId",
"BaseAvatarItemColor"
],
"JMJLMOJCBCK": [
"UpdateResponse",
"Data"
],
"JNFDPPCIPHG": [
"CategoryId",
"Importance",
@@ -1253,6 +1948,14 @@
"Stats",
"RankingContext"
],
"JPKBLKGJNCA": [
"Msg",
"Id"
],
"JPLIIMKJAEL": [
"AccountId",
"DisallowInAppPurchases"
],
"JPNMBICAMEE": [
"RoomInstanceId",
"RoomId",
@@ -1261,12 +1964,51 @@
"CreatedAt",
"PlayerIds"
],
"JsonParser_NestedType_JsonValue": [
"False",
"True"
],
"KAONMCEONPF": [
"Name",
"Price",
"ProductId"
],
"KBHFIPFPCMN": [
"Msg",
"Id"
],
"KBLOCDGCGFA": [
"Msg",
"Id"
],
"KBMAAKAIPLE": [
"UpdateResponse",
"Data"
],
"KCMDEFMLDJF": [
"Balance",
"CurrencyType",
"BalanceType",
"Data"
],
"KDAHIOHGPBN": [
"Value",
"Success",
"Error"
],
"KDJILJAIDFG": [
"RoomId",
"Count"
],
"KEOLHAONMIF": [
"Value",
"Success",
"Error"
],
"KFAOOJLFCGC": [
"Msg",
"Id"
],
"KFPHOKPEMOF": [
"ItemType",
"ItemId",
@@ -1279,6 +2021,20 @@
"CreatedAt",
"ModifiedAt"
],
"KGNFNBHMAFL": [
"Value",
"Success",
"Error"
],
"KHBGNAMFAHK": [
"Msg",
"Id"
],
"KHFKIJEGPDG": [
"AccountId",
"RoomKeyId",
"DoesPlayerOwnRoomKey"
],
"KIANAKFJGCP": [
"FeaturedPlayer",
"FeaturedRoomGroup",
@@ -1292,6 +2048,10 @@
"CurrencyType",
"Platform"
],
"KJEIGGBIIHP": [
"SavedImageId",
"IsCheered"
],
"KKOHONLGIHL": [
"Id",
"FromPlayerId",
@@ -1301,12 +2061,32 @@
"RoomId",
"PlayerEventId"
],
"KLHCKBPJKPF_NestedType_DHKPMMHMIJF_NestedType_KKNKAJBPNPC": [
"SerializeUnsafe",
"ToJsonString"
],
"KMBHAKAHNGH": [
"Room",
"SubRoomDataSave"
],
"KMHNOGNHDLO": [
"SubscriptionSeasonMilestoneId",
"SeasonId",
"StartAt",
"GiftDrops"
],
"KNGMIABFJHK": [
"CurrencyBalanceResponse",
"TokenBalanceResponse"
],
"KOEEACLMAFE": [
"Referrals",
"ContinuationToken"
],
"KPEIHOCIGGE": [
"Msg",
"Id"
],
"KPMMGJELBPP": [
"WindowSize",
"PlayerId",
@@ -1356,6 +2136,24 @@
"MaxPlayers",
"Accessibility"
],
"LDGHHCCJAMC": [
"Status",
"RoomKey"
],
"LEEAJGDIOHI": [
"Value",
"Success",
"Error"
],
"LEINHCHGFON": [
"Msg",
"Id"
],
"LEMIBENHABD": [
"Value",
"Success",
"Error"
],
"LIJHBNDJKNP": [
"RewardSelectionId",
"RewardType",
@@ -1367,6 +2165,19 @@
"Subscriber_GiftDrop3",
"CreatedAt"
],
"LIODMDILCAJ": [
"Value",
"Success",
"Error"
],
"LKBGCOELLIN": [
"CurrencyId",
"PurchaseOffers"
],
"LKJLPNENINM": [
"RoomKeyResponse",
"BalanceUpdateResponse"
],
"LKJPKMBEPCG": [
"PrefabName",
"ModificationGuid",
@@ -1382,18 +2193,34 @@
"Filename",
"Hash"
],
"LKMEPPOFHLK": [
"Msg",
"Id"
],
"LMCCNLLHLCJ": [
"Success",
"Error"
],
"LMEECKCCPHG": [
"AccountId",
"Role",
"LastChangedByAccountId",
"InvitedRole"
],
"LMHKHIJIDEO": [
"SavedImageId",
"Cheer"
],
"LNMAMOCCBAK": [
"Filename",
"UnityAssetId",
"CreatedByAccountId",
"BakedUnityAssets"
],
"LOEHGGMCKAM": [
"ChatResult",
"SnoozedUntil"
],
"LOOLOADLJPG": [
"SubscriptionSeasonId",
"Name",
@@ -1410,6 +2237,15 @@
"SupportsQuest2",
"SupportsMobile"
],
"LPFAFIGAIOE": [
"Status",
"InventoryItem"
],
"MACBLLENLFD": [
"Value",
"Success",
"Error"
],
"MADLMAFINGF": [
"KeepsakeInstanceId",
"KeepsakeCategoryConfigId",
@@ -1417,12 +2253,24 @@
"RoomId",
"SubRoomId"
],
"MAHHAAEGEEP": [
"InventionResponse",
"BalanceUpdateResponse"
],
"MBFADJPOGDI": [
"Msg",
"Id"
],
"MCDADMNCDEI": [
"WishlistItemId",
"AccountId",
"PurchasableItemId",
"CreatedAt"
],
"MCMPJPNBJBI": [
"Msg",
"Id"
],
"MEBAFOGDHBB": [
"PurchaseCampaignId",
"PurchaseReminder",
@@ -1446,6 +2294,11 @@
"PositionY",
"PositionZ"
],
"MFNBIPCHKHC": [
"MembershipRequests",
"TotalMembershipRequests",
"ContinuationToken"
],
"MGOLBEMMNDA": [
"BalanceAddType",
"BaseAward",
@@ -1456,6 +2309,28 @@
"Platform",
"BalanceInGiftBox"
],
"MIFGPMGEMEK": [
"RefreshesAt",
"RefreshIntervalMinutes",
"Room"
],
"MIHDILLIAFE": [
"Instances",
"CollectionRecords"
],
"MIHJPKMLADF": [
"Msg",
"Id"
],
"MIHKAJFMIPE": [
"RoomId",
"CurrencyId"
],
"MJGHCJDOJLH": [
"Value",
"Success",
"Error"
],
"MJJDCIAIDKI": [
"HasEliteUpgrade",
"HasEliteUpgradePlatformMask",
@@ -1477,18 +2352,98 @@
"CreatedAt",
"IsJunior"
],
"MJNABIBJDMO": [
"Order",
"Objective",
"Count"
],
"MKAIABAJIAJ": [
"CustomAvatarItemId",
"BodyPart"
],
"MKBLHNGJOBA": [
"Msg",
"Id"
],
"MLHBPDKBABN": [
"CheerCount",
"FavoriteCount",
"VisitorCount",
"VisitCount"
],
"MMDMDIJLIEH": [
"Msg",
"Id"
],
"MMFCMCPCAJP": [
"ChatMessage",
"ChatResult"
],
"MMPLMIAEBLE": [
"Msg",
"Id"
],
"MOJLGDKFECO": [
"InvitedPlayerId",
"Result"
],
"MOLNFPGNEGP": [
"Value",
"Success",
"Error"
],
"MOMDMDMGEOA": [
"ItemType",
"ItemId"
],
"Matchmaking": [
"PlayerId",
"RoomInstanceId"
],
"NAGNGCMPGOP": [
"RoomId",
"KeepsakeInstanceIds"
],
"NAPOKFHELLC": [
"Multiplier",
"BalanceAddType"
],
"NBGPICODFEE": [
"Value",
"Success",
"Error"
],
"NCBBKAMCPBC": [
"Msg",
"Id"
],
"NCHBANKEJMP": [
"Results",
"TotalResults"
],
"NDIIFIGNAAM": [
"Error",
"Identifier",
"Genuine",
"GenuineCheckAvailable"
],
"NEJOPOKDPKE": [
"Msg",
"Id"
],
"NEKEOJFNCCJ": [
"UpdateResponse",
"Data"
],
"NFBJOAGJHME": [
"Value",
"Success",
"Error"
],
"NGCPIKDINEI": [
"Provider",
"Data"
],
"NHGOFGABJIN": [
"RoomInstanceId",
"RoomId",
@@ -1519,6 +2474,15 @@
"JiraUrl",
"Comments"
],
"NKMEHOHCKOH": [
"Value",
"Success",
"Error"
],
"NLIAAGLJBNN": [
"Results",
"TotalResults"
],
"NMGHOIMEJIK": [
"Name",
"Description",
@@ -1557,6 +2521,11 @@
"Stats",
"RankingContext"
],
"OBACBEGPKAK": [
"ReportCategory",
"Details",
"ReportedPlayerId"
],
"OBGIGMCOMDE": [
"AdCarouselItemId",
"ImageName",
@@ -1565,6 +2534,28 @@
"PurchasableItemIds",
"PurchaseReminderId"
],
"OBIBPCLDPGA": [
"Message",
"MoreInfoUrl"
],
"OCFNOBAONAP": [
"Cheered",
"Favorited",
"LastVisitedAt"
],
"OCGICPIMNEB": [
"ErrorCode",
"RoomInstance"
],
"ODNKLIIJIOH": [
"Msg",
"Id"
],
"OEHMNIAOAOH": [
"Value",
"Success",
"Error"
],
"OFGIPBHIAGF": [
"ProgressionEventPurchasableXpBoostId",
"Cost",
@@ -1582,6 +2573,23 @@
"SubRoomData",
"SavedByAccountId"
],
"OGCMIDEFOEE": [
"ChatResult",
"IsFavorited"
],
"OGEDLCFDDIO": [
"Msg",
"Id"
],
"OHNEMFHCBIJ": [
"Value",
"Success",
"Error"
],
"OKHGCKDIILD": [
"ImageName",
"Index"
],
"OLACHOEDKFB": [
"ReportCategory",
"YesVotes",
@@ -1594,6 +2602,10 @@
"BalanceType",
"Data"
],
"OLKCALBDDOI": [
"Msg",
"Id"
],
"OLPHKLCPFEF": [
"InventionId",
"ReplicationId",
@@ -1605,6 +2617,11 @@
"BlobName",
"BlobHash"
],
"OMAPLLOIDNA": [
"ToPlayerIds",
"Message",
"GiftContext"
],
"ONGJBLFBHGC": [
"PurchasableItemId",
"Type",
@@ -1615,18 +2632,40 @@
"AvailableUntil",
"NewUntil"
],
"OOGKPMKKJBE": [
"SalePercent",
"SaleStartDate",
"SaleEndDate"
],
"PAKGKIKFGAE": [
"Id",
"TitleOverride",
"UrlOverride"
],
"PCBAACNNDBH": [
"FriendlyImageName",
"ImageName",
"StartTime",
"EndTime"
],
"PCMLHLIBLNJ": [
"Tag",
"Type"
],
"PCODFCJECKL": [
"Msg",
"Id"
],
"PCPOMPIAFMA": [
"Key",
"Value",
"StartTime",
"EndTime"
],
"PDGENCNGCJI": [
"RoomId",
"Ids"
],
"PDIFGFKAMBG": [
"PlayerCount",
"IsFull",
@@ -1648,6 +2687,11 @@
"CanRequestBroadcastPermissions",
"BroadcastingRoomInstanceId"
],
"PECGEJAAMHB": [
"Balance",
"CurrencyType",
"Platform"
],
"PELEHJLMKJO": [
"SubRoomDataSaveId",
"SubRoomId",
@@ -1677,6 +2721,14 @@
"Anonymous",
"GiftContext"
],
"PJPBJKLDMNA": [
"Results",
"TotalResults"
],
"PKCMBJFBHBO": [
"TotalXp",
"SocialBoostXp"
],
"PLLNLPADHCN": [
"Resolution",
"Language",
@@ -1710,6 +2762,10 @@
"OnDeviceRegained",
"OnControlsChanged"
],
"PlayerInputManager": [
"OnPlayerJoined",
"OnPlayerLeft"
],
"StringHelpers": [
"Mouse",
"Mice",
@@ -1745,5 +2801,15 @@
"PostalCode",
"BusinessCategory",
"TelephoneNumber"
],
"XSDSchema": [
"True",
"False",
"Name"
],
"XmlTreeGen": [
"Namespace",
"Unique",
"Attribute"
]
}
@@ -1795,7 +1795,6 @@ public class RoomsController(
{
Type = RoomTagTypeForWire(t),
Tag = t,
IsPrimaryGenre = false,
})
.ToArray();
@@ -2006,7 +2005,6 @@ public class RoomsController(
RoomId = room.Id,
Name = s.Name,
UnityAssetId = s.StudioUnityAssetId,
SubRoomUnityAssetId = s.StudioUnityAssetId,
UnityAsset = unityAsset?.Filename ?? string.Empty,
UnityAssetHash = string.Empty,
DataBlob = dataBlob,
@@ -2017,36 +2015,6 @@ public class RoomsController(
MaxPlayers = s.MaxPlayers,
Accessibility = room.Accessibility,
UnitySceneId = s.RoomSceneLocationId,
CurrentSave = new
{
SubRoomDataSaveId = s.StudioSubRoomDataSaveId ?? 0L,
SubRoomId = (long)s.OrderIndex,
UnityAssetId = s.StudioUnityAssetId,
SubRoomUnityAssetId = s.StudioUnityAssetId,
CreatedByAccountId = room.CreatorPlayerId,
ReferencedUnityAssetIds = Array.Empty<string>(),
DataBlob = dataBlob,
DataBlobHash = (string?)null,
PersistenceVersion = saveVersion,
OMVersion = 0,
SavedByAccountId = room.CreatorPlayerId,
SavedOnPlatform = 0,
SavedOnDeviceClass = 2,
Description = string.Empty,
ModerationState = 0,
CreatedAt = (s.DataModifiedAt == default ? DateTime.UtcNow : s.DataModifiedAt)
.ToString("yyyy-MM-ddTHH:mm:ssZ"),
UgcSubVersion = saveVersion,
UnityAssetHash = string.Empty,
UnityAsset = unityAssetParent,
UnityAssetFilename = unityAsset?.Filename ?? string.Empty,
BakedUnityAssets = bakedAssets,
UnitySubAssets = Array.Empty<object>(),
},
LastModeratedSaveModerationState = 0,
DefaultMatchmakingPolicy = 0,
ShouldAutoStageSaves = true,
StagedSubRoomDataSaveId = (long?)null,
};
}).ToArray()
: new object[]
@@ -2063,7 +2031,6 @@ public class RoomsController(
RoomId = room.Id,
Name = "Home",
UnityAssetId = string.Empty,
SubRoomUnityAssetId = string.Empty,
UnityAsset = string.Empty,
UnityAssetHash = string.Empty,
// Same rule as the populated branch: honour the override,
@@ -2076,15 +2043,6 @@ public class RoomsController(
MaxPlayers = 8,
Accessibility = room.Accessibility,
UnitySceneId = room.LocationReplicationId,
CurrentSave = new
{
SubRoomDataSaveId = 0L,
SubRoomId = 0L,
UnityAssetId = string.Empty,
SubRoomUnityAssetId = string.Empty,
ReferencedUnityAssetIds = Array.Empty<string>(),
DataBlob = dataBlobName,
},
},
};
@@ -2102,7 +2060,6 @@ public class RoomsController(
{
Type = RoomTagTypeForWire(t),
Tag = t,
IsPrimaryGenre = false,
})
.ToArray();
@@ -3384,7 +3341,6 @@ public class RoomsController(
{
Type = RoomTagTypeForWire(t),
Tag = t,
IsPrimaryGenre = false,
})
.ToList();
+5 -3
View File
@@ -35,9 +35,11 @@ import re
import sys
from pathlib import Path
# A type with only a couple of fields is usually a wrapper or a false positive
# (enum name tables register short literal runs too). Real wire DTOs are wider.
MIN_FIELDS = 4
# Two is deliberate, not lax. Several real wire DTOs are exactly that small —
# a room tag is {Tag, Type} — and a higher floor hides them, which is how an
# invented third key on the tag object went unnoticed. The alias rule in
# fields_in() is what rejects false positives, not the field count.
MIN_FIELDS = 2
LITERAL = re.compile(r'Move \w+, "([A-Za-z][A-Za-z0-9_]*)"')