diff --git a/DorkNet.Server.Tests/ClientDtoParityTests.cs b/DorkNet.Server.Tests/ClientDtoParityTests.cs index 6105420..d65ab7d 100644 --- a/DorkNet.Server.Tests/ClientDtoParityTests.cs +++ b/DorkNet.Server.Tests/ClientDtoParityTests.cs @@ -85,8 +85,40 @@ public sealed class ClientDtoParityTests : IClassFixture 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]" : "")}"); + } } + /// 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. + 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() { diff --git a/DorkNet.Server.Tests/data/client-dto-keys-2023.json b/DorkNet.Server.Tests/data/client-dto-keys-2023.json index 461d120..513e7d6 100644 --- a/DorkNet.Server.Tests/data/client-dto-keys-2023.json +++ b/DorkNet.Server.Tests/data/client-dto-keys-2023.json @@ -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" ] } diff --git a/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs b/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs index 23bfe49..2fc0275 100644 --- a/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs +++ b/DorkNet.Server/Controllers/API/Rooms/V2/RoomsController.cs @@ -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(), - 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(), - }, - 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(), - 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(); diff --git a/tools/extract-client-dto-keys.py b/tools/extract-client-dto-keys.py index 5c4215e..8a5070e 100644 --- a/tools/extract-client-dto-keys.py +++ b/tools/extract-client-dto-keys.py @@ -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_]*)"')