From 60505a2519ce68b1ca27ffad1077be936124ca50 Mon Sep 17 00:00:00 2001 From: Devin Zuczek Date: Sun, 9 Aug 2026 01:08:23 -0400 Subject: [PATCH] add matchmake error enums from dump --- apps/match/src/match.app.ts | 21 +++++++------ packages/domain/src/enums.ts | 59 ++++++++++++++++++++++++++++++++++++ packages/domain/src/index.ts | 2 +- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/apps/match/src/match.app.ts b/apps/match/src/match.app.ts index c3f0389..99e84b9 100644 --- a/apps/match/src/match.app.ts +++ b/apps/match/src/match.app.ts @@ -25,6 +25,7 @@ import { getRoomInstanceSummariesByRoom, isClubMember, isPlayerBannedFromRoom, + MatchmakingErrorCode, MessageType, recordRoomVisit, refreshInstanceFullness, @@ -293,16 +294,16 @@ async function enterRoom(c: Context, id: number, roomInstance: RoomInstance await notifyFriendsPresence(c, id) } -/** MatchmakingErrorCode.NoSuchRoom — returned when a room isn't in the DB. */ -const NO_SUCH_ROOM = 20 +/** Returned when a room isn't in the DB — and for every other opaque refusal. */ +const NO_SUCH_ROOM = MatchmakingErrorCode.NoSuchRoom /** - * MatchmakingErrorCode for "you are banned from this room". Unlike the opaque - * NoSuchRoom every other refusal answers, a banned player is told why: they already - * know the room exists, so there's nothing to hide, and the client can say so instead - * of showing a room that mysteriously fails to load. + * "You are banned from this room". Unlike the opaque NoSuchRoom every other refusal + * answers, a banned player is told why: they already know the room exists, so there's + * nothing to hide, and the client can say so instead of showing a room that + * mysteriously fails to load. */ -const BANNED_FROM_ROOM = 55 +const BANNED_FROM_ROOM = MatchmakingErrorCode.BannedFromRoom /** The notifications hub is a single global DO instance (see the `notify` worker). */ const HUB_INSTANCE = 'global' @@ -513,8 +514,8 @@ async function inviteParty( * there (NoSuchRoom) from one the caller is banned from — those answer different codes. */ type ResolvedInstance = - | { instance: RoomInstance; errorCode: 0 } - | { instance: null; errorCode: number } + | { instance: RoomInstance; errorCode: MatchmakingErrorCode.Success } + | { instance: null; errorCode: MatchmakingErrorCode } /** * Resolve a room by `:room` path segment (numeric id or name) from D1, then find a @@ -584,7 +585,7 @@ async function resolveRoomInstance( instance.photonRoomId, f.subRoomId ), - errorCode: 0, + errorCode: MatchmakingErrorCode.Success, } } diff --git a/packages/domain/src/enums.ts b/packages/domain/src/enums.ts index b7c96b2..6464e22 100644 --- a/packages/domain/src/enums.ts +++ b/packages/domain/src/enums.ts @@ -83,6 +83,65 @@ export enum Accessibility { Dev_Unlisted = 4, } +/** + * The `errorCode` a matchmaking response carries, matching the client's + * `MatchmakingErrorCode`. `Success` (0) comes with an instance; every other code comes + * with a null one. The numbering is sparse — these are the client's declared values, + * gaps included, so don't renumber or fill them in. + * + * We only ever answer a few of these. Most refusals are deliberately opaque + * ({@link MatchmakingErrorCode.NoSuchRoom}), since telling someone a room exists but is + * closed to them leaks more than it helps; {@link MatchmakingErrorCode.BannedFromRoom} + * is the exception, because a banned player already knows the room is there. The rest + * are here so a code seen in a client log has a name. + */ +export enum MatchmakingErrorCode { + UnknownError = -1, + Success = 0, + NoSuchGame = 1, + PlayerNotOnline = 2, + InsufficientSpace = 3, + EventNotStarted = 4, + EventAlreadyFinished = 5, + BlockedFromRoom = 7, + JuniorNotAllowed = 11, + Banned = 12, + AlreadyInBestInstance = 13, + InsufficientRelationship = 14, + UpdateRequired = 16, + AlreadyInTargetInstance = 17, + UGCNotAllowed = 19, + NoSuchRoom = 20, + RoomIsNotActive = 22, + RoomBlockedByCreator = 23, + RoomIsPrivate = 25, + RoomInstanceIsPrivate = 26, + DeviceClassNotSupported = 30, + DeviceClassNotSupportedByRoomOwner = 31, + MovementModeNotSupportedByRoomOwner = 32, + EventIsPrivate = 35, + EventIsFull = 36, + RoomInviteExpired = 40, + NoAvailableRegion = 45, + NotorietyTooPoor = 50, + BannedFromRoom = 55, + NoSuchClub = 70, + ClubHasNoClubhouse = 71, + ClubIsNotActive = 73, + NotAMemberOfClub = 74, + BannedFromClub = 75, + InstanceJoinNotPermitted = 76, + LevelTooLow = 77, + ChatPartyInviteNotFound = 78, + ChatPartyInviteModerated = 79, + ChatMessageNotAnInvite = 80, + DeveloperOnly = 81, + RRPlusRequired = 82, + MetaJuniorAccountRestriction = 83, + NotExclusivelyLoggedIn = 84, + AccountDoesNotExist = 85, +} + /** * A room-role tier (the `Role` byte on a room's `Roles` entries), matching the * client's values. Host and Moderator are limited-permission helper tiers; CoOwner diff --git a/packages/domain/src/index.ts b/packages/domain/src/index.ts index 448fa4c..5e4b33c 100644 --- a/packages/domain/src/index.ts +++ b/packages/domain/src/index.ts @@ -1,4 +1,4 @@ -export { RoomInstanceType, Accessibility, Role, MessageType } from './enums' +export { RoomInstanceType, Accessibility, Role, MessageType, MatchmakingErrorCode } from './enums' export * from './accounts-db' export * from './clubs-db' export * from './images-db'