diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
deleted file mode 100644
index e62c1570..00000000
--- a/gateway/src/opcodes/Identify.ts
+++ /dev/null
@@ -1,298 +0,0 @@
-import { WebSocket, Payload } from "@fosscord/gateway";
-import {
- checkToken,
- Intents,
- Member,
- ReadyEventData,
- User,
- Session,
- EVENTEnum,
- Config,
- PublicMember,
- PublicUser,
- PrivateUserProjection,
- ReadState,
- Application,
- emitEvent,
- SessionsReplace,
- PrivateSessionProjection,
- MemberPrivateProjection,
- PresenceUpdateEvent,
- UserSettings,
- IdentifySchema,
-} from "@fosscord/util";
-import { Send } from "../util/Send";
-import { CLOSECODES, OPCODES } from "../util/Constants";
-import { genSessionId } from "../util/SessionUtils";
-import { setupListener } from "../listener/listener";
-// import experiments from "./experiments.json";
-const experiments: any = [];
-import { check } from "./instanceOf";
-import { Recipient } from "@fosscord/util";
-import { OrmUtils } from "@fosscord/util";
-
-// TODO: user sharding
-// TODO: check privileged intents, if defined in the config
-// TODO: check if already identified
-
-export async function onIdentify(this: WebSocket, data: Payload) {
- clearTimeout(this.readyTimeout);
- check.call(this, IdentifySchema, data.d);
-
- const identify: IdentifySchema = data.d;
-
- try {
- const { jwtSecret } = Config.get().security;
- var { decoded } = await checkToken(identify.token, jwtSecret); // will throw an error if invalid
- } catch (error) {
- console.error("invalid token", error);
- return this.close(CLOSECODES.Authentication_failed);
- }
- this.user_id = decoded.id;
-
- const session_id = genSessionId();
- this.session_id = session_id; //Set the session of the WebSocket object
-
- const [user, read_states, members, recipients, session, application] =
- await Promise.all([
- User.findOneOrFail({
- where: { id: this.user_id },
- relations: ["relationships", "relationships.to", "settings"],
- select: [...PrivateUserProjection, "relationships"],
- }),
- ReadState.find({ where: { user_id: this.user_id } }),
- Member.find({
- where: { id: this.user_id },
- select: MemberPrivateProjection,
- relations: [
- "guild",
- "guild.channels",
- "guild.emojis",
- "guild.emojis.user",
- "guild.roles",
- "guild.stickers",
- "user",
- "roles",
- ],
- }),
- Recipient.find({
- where: { user_id: this.user_id, closed: false },
- relations: [
- "channel",
- "channel.recipients",
- "channel.recipients.user",
- ],
- // TODO: public user selection
- }),
- // save the session and delete it when the websocket is closed
- await OrmUtils.mergeDeep(new Session(), {
- user_id: this.user_id,
- session_id: session_id,
- // TODO: check if status is only one of: online, dnd, offline, idle
- status: identify.presence?.status || "offline", //does the session always start as online?
- client_info: {
- //TODO read from identity
- client: "desktop",
- os: identify.properties?.os,
- version: 0,
- },
- activities: [],
- }).save(),
- Application.findOne({ where: { id: this.user_id } }),
- ]);
-
- if (!user) return this.close(CLOSECODES.Authentication_failed);
- if (!user.settings) { //settings may not exist after updating...
- user.settings = new UserSettings();
- user.settings.id = user.id;
- await user.settings.save();
- }
-
- if (!identify.intents) identify.intents = BigInt("0x6ffffffff");
- this.intents = new Intents(identify.intents);
- if (identify.shard) {
- this.shard_id = identify.shard[0];
- this.shard_count = identify.shard[1];
- if (
- this.shard_count == null ||
- this.shard_id == null ||
- this.shard_id >= this.shard_count ||
- this.shard_id < 0 ||
- this.shard_count <= 0
- ) {
- console.log(identify.shard);
- return this.close(CLOSECODES.Invalid_shard);
- }
- }
- let users: PublicUser[] = [];
-
- const merged_members = members.map((x: Member) => {
- return [
- {
- ...x,
- roles: x.roles.map((x) => x.id),
- settings: undefined,
- guild: undefined,
- },
- ];
- }) as PublicMember[][];
- let guilds = members.map((x) => ({ ...x.guild, joined_at: x.joined_at }));
-
- // @ts-ignore
- guilds = guilds.map((guild) => {
- if (user.bot) {
- setTimeout(() => {
- Send(this, {
- op: OPCODES.Dispatch,
- t: EVENTEnum.GuildCreate,
- s: this.sequence++,
- d: guild,
- });
- }, 500);
- return { id: guild.id, unavailable: true };
- }
-
- return guild;
- });
-
- const user_guild_settings_entries = members.map((x) => x.settings);
-
- const channels = recipients.map((x) => {
- // @ts-ignore
- x.channel.recipients = x.channel.recipients?.map((x) => x.user);
- //TODO is this needed? check if users in group dm that are not friends are sent in the READY event
- users = users.concat(x.channel.recipients as unknown as User[]);
- if (x.channel.isDm()) {
- x.channel.recipients = x.channel.recipients!.filter(
- (x) => x.id !== this.user_id
- );
- }
- return x.channel;
- });
-
- for (let relation of user.relationships) {
- const related_user = relation.to;
- const public_related_user = {
- username: related_user.username,
- discriminator: related_user.discriminator,
- id: related_user.id,
- public_flags: related_user.public_flags,
- avatar: related_user.avatar,
- bot: related_user.bot,
- bio: related_user.bio,
- premium_since: user.premium_since
- };
- users.push(public_related_user);
- }
-
- setImmediate(async () => {
- // run in seperate "promise context" because ready payload is not dependent on those events
- emitEvent({
- event: "SESSIONS_REPLACE",
- user_id: this.user_id,
- data: await Session.find({
- where: { user_id: this.user_id },
- select: PrivateSessionProjection,
- }),
- } as SessionsReplace);
- emitEvent({
- event: "PRESENCE_UPDATE",
- user_id: this.user_id,
- data: {
- user: await User.getPublicUser(this.user_id),
- activities: session.activities,
- client_status: session?.client_info,
- status: session.status,
- },
- } as PresenceUpdateEvent);
- });
-
- read_states.forEach((s: any) => {
- s.id = s.channel_id;
- delete s.user_id;
- delete s.channel_id;
- });
-
- const privateUser = {
- avatar: user.avatar,
- mobile: user.mobile,
- desktop: user.desktop,
- discriminator: user.discriminator,
- email: user.email,
- flags: user.flags,
- id: user.id,
- mfa_enabled: user.mfa_enabled,
- nsfw_allowed: user.nsfw_allowed,
- phone: user.phone,
- premium: user.premium,
- premium_type: user.premium_type,
- public_flags: user.public_flags,
- username: user.username,
- verified: user.verified,
- bot: user.bot,
- accent_color: user.accent_color || 0,
- banner: user.banner,
- bio: user.bio,
- premium_since: user.premium_since
- };
-
- const d: ReadyEventData = {
- v: 8,
- application: {id: application?.id??'', flags: application?.flags??0}, //TODO: check this code!
- user: privateUser,
- user_settings: user.settings,
- // @ts-ignore
- guilds: guilds.map((x) => {
- // @ts-ignore
- x.guild_hashes = {}; // @ts-ignore
- x.guild_scheduled_events = []; // @ts-ignore
- x.threads = [];
- return x;
- }),
- guild_experiments: [], // TODO
- geo_ordered_rtc_regions: [], // TODO
- relationships: user.relationships.map((x) => x.toPublicRelationship()),
- read_state: {
- entries: read_states,
- partial: false,
- version: 304128,
- },
- user_guild_settings: {
- entries: user_guild_settings_entries,
- partial: false, // TODO partial
- version: 642,
- },
- private_channels: channels,
- session_id: session_id,
- analytics_token: "", // TODO
- connected_accounts: [], // TODO
- consents: {
- personalization: {
- consented: false, // TODO
- },
- },
- country_code: user.settings.locale,
- friend_suggestion_count: 0, // TODO
- // @ts-ignore
- experiments: experiments, // TODO
- guild_join_requests: [], // TODO what is this?
- users: users.filter((x) => x).unique(),
- merged_members: merged_members,
- // shard // TODO: only for user sharding
- };
-
- // TODO: send real proper data structure
- await Send(this, {
- op: OPCODES.Dispatch,
- t: EVENTEnum.Ready,
- s: this.sequence++,
- d,
- });
-
- //TODO send READY_SUPPLEMENTAL
- //TODO send GUILD_MEMBER_LIST_UPDATE
- //TODO send SESSIONS_REPLACE
- //TODO send VOICE_STATE_UPDATE to let the client know if another device is already connected to a voice channel
-
- await setupListener.call(this);
-}
|