diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index 319635c4..abbe77a5 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -51,6 +51,7 @@ import { Sticker, VoiceState, UserSettingsProtos, + ReadyEventDataV6, } from "@spacebar/util"; import { check } from "./instanceOf"; import { In } from "typeorm"; @@ -539,60 +540,114 @@ export async function onIdentify(this: WebSocket, data: Payload) { }); const remapReadStateIdsTime = taskSw.getElapsedAndReset(); - const d: ReadyEventData = { - v: 9, - application: application ? { id: application.id, flags: application.flags } : undefined, + const base = { user: user.toPrivateUser(), - user_settings: user.settings, - user_settings_proto: settingsProtos?.userSettings ? PreloadedUserSettings.toBase64(settingsProtos.userSettings) : undefined, - user_settings_proto_json: settingsProtos?.userSettings ? PreloadedUserSettings.toJson(settingsProtos.userSettings) : undefined, - guilds: this.capabilities.has(Capabilities.FLAGS.CLIENT_STATE_V2) ? guilds.map((x) => new ReadyGuildDTO(x).toJSON()) : guilds, - relationships: user.relationships.map((x) => x.toPublicRelationship()), - read_state: { - entries: read_states, - partial: false, - version: 0, // TODO - }, - user_guild_settings: { - entries: user_guild_settings_entries, - partial: false, - version: 0, // TODO - }, - private_channels: channels, - presences: [], session_id: this.session_id, - country_code: user.settings.locale, // TODO: do ip analysis instead - users: Array.from(users), - merged_members: merged_members, - sessions: allSessions, - - resume_gateway_url: Config.get().gateway.endpointClient || Config.get().gateway.endpointPublic || "ws://127.0.0.1:3001", - - // lol hack whatever - required_action: Config.get().login.requireVerification && !user.verified ? "REQUIRE_VERIFIED_EMAIL" : undefined, - - consents: { - personalization: { - consented: false, // TODO - }, - }, - experiments: [], - guild_join_requests: [], - connected_accounts: [], - guild_experiments: [], - geo_ordered_rtc_regions: [], - api_code_version: 1, - friend_suggestion_count: 0, - analytics_token: "", - tutorial: null, - session_type: "normal", // TODO - auth_session_id_hash: "", // TODO - notification_settings: { - // ???? - flags: 0, - }, - game_relationships: [], + resume_gateway_url: + Config.get().gateway.endpointClient || + Config.get().gateway.endpointPublic || + "ws://127.0.0.1:3001", }; + + let d: ReadyEventData | ReadyEventDataV6; + + if (this.version === 6) { + d = { + v: 6, + ...base, + heartbeat_interval: 45_000, + guilds, + private_channels: channels, + presences: [], + relationships: user.relationships.map((x) => x.toPublicRelationship()), + users: Array.from(users), + notes: [], + user_settings: user.settings, + read_state: read_states, + experiments: [], + guild_experiments: [], + user_guild_settings: [], + merged_members, + sessions: allSessions.map((s) => ({ + session_id: s.session_id, + client_info: { + client: s.client_info?.client ?? "unknown", + os: s.client_info?.os ?? "unknown", + version: s.client_info?.version ?? null, + }, + })), + connected_accounts: [], + friend_suggestion_count: 0, + analytics_token: "", + tutorial: { + indicators_suppressed: true, + indicators_confirmed: [], + }, + notification_settings: { + flags: null, + }, + game_relationships: [{}], + application: application + ? { id: application.id, flags: application.flags } + : null, + }; + } else { + d = { + v: 9, + ...base, + user_settings: user.settings, + user_settings_proto: settingsProtos?.userSettings + ? PreloadedUserSettings.toBase64(settingsProtos.userSettings) + : undefined, + user_settings_proto_json: settingsProtos?.userSettings + ? PreloadedUserSettings.toJson(settingsProtos.userSettings) + : undefined, + guilds: this.capabilities.has(Capabilities.FLAGS.CLIENT_STATE_V2) + ? guilds.map((x) => new ReadyGuildDTO(x).toJSON()) + : guilds, + relationships: user.relationships.map((x) => x.toPublicRelationship()), + read_state: { + entries: read_states, + partial: false, + version: 0, + }, + user_guild_settings: { + entries: user_guild_settings_entries, + partial: false, + version: 0, + }, + private_channels: channels, + presences: [], + country_code: user.settings.locale, + users: Array.from(users), + merged_members, + sessions: allSessions, + required_action: + Config.get().login.requireVerification && !user.verified + ? "REQUIRE_VERIFIED_EMAIL" + : undefined, + consents: { + personalization: { consented: false }, + }, + experiments: [], + guild_join_requests: [], + connected_accounts: [], + guild_experiments: [], + geo_ordered_rtc_regions: [], + api_code_version: 1, + friend_suggestion_count: 0, + analytics_token: "", + tutorial: null, + session_type: "normal", + auth_session_id_hash: "", + notification_settings: { flags: 0 }, + game_relationships: [], + application: application + ? { id: application.id, flags: application.flags } + : undefined, + }; + } + const buildReadyEventDataTime = taskSw.getElapsedAndReset(); const _trace = [ gatewayShardName, diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts index bc64c171..3ead35e0 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts @@ -64,6 +64,53 @@ export interface PublicRelationship { // ! END Custom Events that shouldn't get sent to the client but processed by the server +export interface ReadyEventDataV6 { + v: 6; + session_id: string; + resume_gateway_url: string; + heartbeat_interval: number; + user: UserPrivate; + guilds: GuildOrUnavailable[]; + private_channels: ReadyPrivateChannel[]; + presences: Presence[]; + relationships: PublicRelationship[]; + users: PublicUser[]; + notes: { + id: string; + note: string; + }[]; + user_settings: UserSettings; + read_state: ReadState[]; + experiments: unknown[]; + guild_experiments: unknown[]; + user_guild_settings: unknown[]; + merged_members: PublicMember[][]; + sessions: { + session_id: string; + client_info: { + client: string; + os: string; + version: number | null; + }; + }[]; + connected_accounts: ConnectedAccount[]; + friend_suggestion_count: number; + analytics_token: string; + tutorial: { + indicators_suppressed: boolean; + indicators_confirmed: string[]; + }; + notification_settings: { + flags: number | null; + }; + game_relationships: unknown[]; + application: { + id: string; + flags: number; + } | null; + _trace?: string[]; +} + export interface ReadyEventData { v: number; user: UserPrivate;