mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
fix invites
This commit is contained in:
@@ -15,6 +15,55 @@ export enum RoomInstanceType {
|
||||
Clubhouse = 5,
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Type` byte on a messaging `Message` — how the client dispatches a message it
|
||||
* receives (a game invite renders the join prompt, a text message the chat bubble, …).
|
||||
* Distinct from the notify hub's {@link NotificationType}: a message is delivered *as*
|
||||
* a `MessageReceived` (NotificationType 2) notification whose payload is a `Message`,
|
||||
* and this enum is that inner `Message.Type`. Mirrors the reference's `MessageType`.
|
||||
*/
|
||||
export enum MessageType {
|
||||
GameInvite = 0,
|
||||
GameInviteDeclined = 1,
|
||||
GameJoinFailed = 2,
|
||||
PartyActivitySwitch = 3,
|
||||
FriendInvite = 4,
|
||||
VoteToKick = 5,
|
||||
GameInviteV2 = 6,
|
||||
PartyActivitySwitchV2 = 7,
|
||||
RequestGameInvite = 10,
|
||||
RequestGameInviteDeclined = 11,
|
||||
FriendStatusOnline = 20,
|
||||
TextMessage = 30,
|
||||
FriendRequestAccepted = 40,
|
||||
PlayerCheer = 50,
|
||||
PlayerCheerAnonymous = 51,
|
||||
RoomCoOwnerAdded = 60,
|
||||
RoomCoOwnerRemoved = 61,
|
||||
RoomCoOwnerInvited = 62,
|
||||
CreatorPublishedNewRoom = 70,
|
||||
PlayerAttendingEvent = 80,
|
||||
PlayerEventInvitation = 81,
|
||||
DeprecatedGroupInvitation = 90,
|
||||
DeprecatedPlayerJoinedGroup = 91,
|
||||
CoachMessage = 100,
|
||||
NewRoomComments = 110,
|
||||
PartyUpRequest = 120,
|
||||
FriendIntroduction = 130,
|
||||
ClubMemberInvited = 200,
|
||||
ClubModeratorInvited = 201,
|
||||
ClubCoownerInvited = 202,
|
||||
VirtualClubAnnouncementRoomPublished = 100000,
|
||||
VirtualClubAnnouncementInventionPublished = 100001,
|
||||
VirtualClubAnnouncementGeneric = 100002,
|
||||
VirtualClubAnnouncementPlayerEventPublished = 100003,
|
||||
VirtualClubAnnouncementClub = 100004,
|
||||
VirtualClubAnnouncementPlayer = 100005,
|
||||
VirtualClubAnnouncementCode = 100006,
|
||||
VirtualClubAnnouncementPhoto = 100007,
|
||||
VirtualRoomNotification = 100008,
|
||||
}
|
||||
|
||||
/** A room's (or image's) visibility, matching the client's `RoomAccessibility`. */
|
||||
export enum Accessibility {
|
||||
Private = 0,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { RoomInstanceType, Accessibility, Role } from './enums'
|
||||
export { RoomInstanceType, Accessibility, Role, MessageType } from './enums'
|
||||
export * from './accounts-db'
|
||||
export * from './clubs-db'
|
||||
export * from './images-db'
|
||||
@@ -7,3 +7,4 @@ export * from './rooms-db'
|
||||
export * from './room-instance-db'
|
||||
export * from './presence-db'
|
||||
export * from './gifts-db'
|
||||
export * from './relationships-db'
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Read-only access to the friendship graph on the shared `recflare` D1 database.
|
||||
*
|
||||
* The `relationship` table's schema and every mutation are owned by the `api` worker
|
||||
* (apps/api/src/relationships-db.ts, migrations/0001_relationship.sql). This module is
|
||||
* the shared *reader* other workers need: the `match` worker looks up a player's friends
|
||||
* to push a presence update to them when the player changes rooms. It only SELECTs the
|
||||
* three columns that identify a friendship (requester/target/type), so it stays
|
||||
* decoupled from the favorited/ignored/muted flag columns api layers on top.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `relationship_type` for a mutual friendship — mirror of api's `RelationshipType.Friend`.
|
||||
* Pending requests (1 sent / 2 received) and bare ignore/mute rows (0) are not friends.
|
||||
*/
|
||||
const FRIEND_RELATIONSHIP_TYPE = 3
|
||||
|
||||
/**
|
||||
* The account ids of a player's mutual friends. Exactly one relationship row exists per
|
||||
* unordered pair, with the player on either side, so this reads both directions and
|
||||
* returns whichever id isn't the player. Non-friend rows are excluded; the order is
|
||||
* unspecified.
|
||||
*/
|
||||
export async function getFriendIds(db: D1Database, playerId: number): Promise<number[]> {
|
||||
const { results } = await db
|
||||
.prepare(
|
||||
`SELECT requester_id, target_id FROM relationship
|
||||
WHERE relationship_type = ?2 AND (requester_id = ?1 OR target_id = ?1)`
|
||||
)
|
||||
.bind(playerId, FRIEND_RELATIONSHIP_TYPE)
|
||||
.all<{ requester_id: number; target_id: number }>()
|
||||
return results.map((r) => (r.requester_id === playerId ? r.target_id : r.requester_id))
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether two players are mutual friends. The single relationship row for the pair sits
|
||||
* in either direction, so both are checked. A targeted single-row read — cheaper than
|
||||
* {@link getFriendIds} when all you need is "are these two friends?" (e.g. gating a
|
||||
* follow-a-friend matchmake).
|
||||
*/
|
||||
export async function areFriends(
|
||||
db: D1Database,
|
||||
playerId: number,
|
||||
otherId: number
|
||||
): Promise<boolean> {
|
||||
const row = await db
|
||||
.prepare(
|
||||
`SELECT 1 AS ok FROM relationship
|
||||
WHERE relationship_type = ?3
|
||||
AND ((requester_id = ?1 AND target_id = ?2) OR (requester_id = ?2 AND target_id = ?1))
|
||||
LIMIT 1`
|
||||
)
|
||||
.bind(playerId, otherId, FRIEND_RELATIONSHIP_TYPE)
|
||||
.first<{ ok: number }>()
|
||||
return row !== null
|
||||
}
|
||||
Reference in New Issue
Block a user