summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-04-08 04:45:28 +0200
committerFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-04-08 04:45:28 +0200
commitf3f11adb38994472f1e08e28659991f9cc6edf90 (patch)
tree783e803eec33252d407cf621b6fecb5b6ddad3cc /src
parent:zap: use mongoose autopopulate (diff)
downloadserver-f3f11adb38994472f1e08e28659991f9cc6edf90.tar.xz
:page_facing_up: use Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
Diffstat (limited to 'src')
-rw-r--r--src/events/Connection.ts1
-rw-r--r--src/listener/listener.ts18
-rw-r--r--src/opcodes/Identify.ts20
-rw-r--r--src/schema/Identify.ts4
-rw-r--r--src/util/WebSocket.ts2
5 files changed, 39 insertions, 6 deletions
diff --git a/src/events/Connection.ts b/src/events/Connection.ts

index 34274d9c..96c7c441 100644 --- a/src/events/Connection.ts +++ b/src/events/Connection.ts
@@ -9,6 +9,7 @@ import { createDeflate } from "zlib"; // TODO: check rate limit // TODO: specify rate limit in config +// TODO: check msg max size export async function Connection(this: Server, socket: WebSocket, request: IncomingMessage) { try { diff --git a/src/listener/listener.ts b/src/listener/listener.ts
index 82e6fa85..988a791a 100644 --- a/src/listener/listener.ts +++ b/src/listener/listener.ts
@@ -8,12 +8,28 @@ import WebSocket from "../util/WebSocket"; // TODO: Guild Member Update is sent for current-user updates regardless of whether the GUILD_MEMBERS intent is set. // ? How to resubscribe MongooseCache for new dm channel events? Maybe directly send them to the user_id regardless of the channel_id? -> max overhead of creating 10 events in database for dm user group. Or a new field in event -> recipient_ids? +// Sharding: calculate if the current shard id matches the formula: shard_id = (guild_id >> 22) % num_shards +// https://discord.com/developers/docs/topics/gateway#sharding + export async function setupListener(this: WebSocket) { const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); + var guilds = user.guilds; + const shard_count = 10n; + const shard_id = 0n; + + if (shard_count) { + guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + } const eventStream = new MongooseCache( db.collection("events"), - [{ $match: { $or: [{ "fullDocument.guild_id": { $in: user.guilds } }, { "fullDocument.user_id": this.user_id }] } }], + [ + { + $match: { + $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": this.user_id }], + }, + }, + ], { onlyEvents: true } ); await eventStream.init(); diff --git a/src/opcodes/Identify.ts b/src/opcodes/Identify.ts
index 1fa75ec1..584965af 100644 --- a/src/opcodes/Identify.ts +++ b/src/opcodes/Identify.ts
@@ -38,6 +38,19 @@ export async function onIdentify(this: WebSocket, data: Payload) { this.user_id = decoded.id; if (!identify.intents) identify.intents = 0b11111111111111n; 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 || + !this.shard_id || + this.shard_id >= this.shard_count || + this.shard_id < 0 || + this.shard_count <= 0 + ) { + return this.close(CLOSECODES.Invalid_shard); + } + } const members = toObject(await MemberModel.find({ id: this.user_id }).exec()); const merged_members = members.map((x: any) => { @@ -48,8 +61,8 @@ export async function onIdentify(this: WebSocket, data: Payload) { }) as MemberDocument[][]; const user_guild_settings_entries = members.map((x) => x.settings); - const channels = await ChannelModel.find({ recipients: this.user_id }).lean().exec(); - const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); + const channels = await ChannelModel.find({ recipients: this.user_id }).exec(); + const user = await UserModel.findOne({ id: this.user_id }).exec(); if (!user) return this.close(CLOSECODES.Authentication_failed); const public_user = { @@ -113,7 +126,8 @@ export async function onIdentify(this: WebSocket, data: Payload) { partial: false, // TODO partial version: 642, }, - private_channels: channels, + // @ts-ignore + private_channels: toObject(channels), session_id: "", // TODO analytics_token: "", // TODO connected_accounts: [], // TODO diff --git a/src/schema/Identify.ts b/src/schema/Identify.ts
index 3e153fbe..dac5d9cc 100644 --- a/src/schema/Identify.ts +++ b/src/schema/Identify.ts
@@ -25,7 +25,7 @@ export const IdentifySchema = { $presence: ActivitySchema, $compress: Boolean, $large_threshold: Number, - $shard: [Number], + $shard: [BigInt, BigInt], $guild_subscriptions: Boolean, $capabilities: Number, $client_state: { @@ -61,7 +61,7 @@ export interface IdentifySchema { presence?: ActivitySchema; compress?: boolean; large_threshold?: number; - shard?: [number]; + shard?: [bigint, bigint]; guild_subscriptions?: boolean; capabilities?: number; client_state?: { diff --git a/src/util/WebSocket.ts b/src/util/WebSocket.ts
index 566fc3aa..4aad85d0 100644 --- a/src/util/WebSocket.ts +++ b/src/util/WebSocket.ts
@@ -7,6 +7,8 @@ interface WebSocket extends WS { user_id: string; encoding: "etf" | "json"; compress?: "zlib-stream"; + shard_count?: bigint; + shard_id?: bigint; deflate?: Deflate; heartbeatTimeout: NodeJS.Timeout; readyTimeout: NodeJS.Timeout;