diff --git a/package-lock.json b/package-lock.json
index d72c6705..7a294f73 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "@fosscord/server-util": "^1.0.7",
+ "@fosscord/server-util": "^1.2.1",
"dotenv": "^8.2.0",
"jsonwebtoken": "^8.5.1",
"lambert-server": "^1.1.7",
@@ -30,9 +30,9 @@
}
},
"node_modules/@fosscord/server-util": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.0.7.tgz",
- "integrity": "sha512-3vBPCt+lwMS7wk+iRvv+V8qBSnEdNifpPxX97Lfjje/TSWI17Kg29y3BmcGJRC5TwIHTLFtgpNLmZmruhv7ziQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.2.1.tgz",
+ "integrity": "sha512-NAAmwDizkjR52O6ZUds+XOH8ydjo///T2EH0scuFF3HtAMjD8Yphgo7+GIKrNt5FfkTR3ma0ycrZLZe0TBE+1A==",
"dependencies": {
"@types/jsonwebtoken": "^8.5.0",
"@types/mongoose-autopopulate": "^0.10.1",
@@ -2134,9 +2134,9 @@
},
"dependencies": {
"@fosscord/server-util": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.0.7.tgz",
- "integrity": "sha512-3vBPCt+lwMS7wk+iRvv+V8qBSnEdNifpPxX97Lfjje/TSWI17Kg29y3BmcGJRC5TwIHTLFtgpNLmZmruhv7ziQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.2.1.tgz",
+ "integrity": "sha512-NAAmwDizkjR52O6ZUds+XOH8ydjo///T2EH0scuFF3HtAMjD8Yphgo7+GIKrNt5FfkTR3ma0ycrZLZe0TBE+1A==",
"requires": {
"@types/jsonwebtoken": "^8.5.0",
"@types/mongoose-autopopulate": "^0.10.1",
diff --git a/package.json b/package.json
index 74087264..32c9fb85 100644
--- a/package.json
+++ b/package.json
@@ -5,16 +5,15 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "start": "npm run build:util && npm run build && node dist/",
+ "start": "npm run build && node dist/",
"build": "npx tsc -b .",
- "build:util": "npx tsc -b ./node_modules/@fosscord/server-util/",
"dev": "tsnd --respawn src/index.ts"
},
"keywords": [],
"author": "Fosscord",
"license": "ISC",
"dependencies": {
- "@fosscord/server-util": "^1.0.7",
+ "@fosscord/server-util": "^1.2.1",
"dotenv": "^8.2.0",
"jsonwebtoken": "^8.5.1",
"lambert-server": "^1.1.7",
diff --git a/src/Server.ts b/src/Server.ts
index 149883c2..193bdad1 100644
--- a/src/Server.ts
+++ b/src/Server.ts
@@ -6,6 +6,9 @@ import { Server as WebSocketServer } from "ws";
import { Connection } from "./events/Connection";
import Config from "./util/Config";
+// TODO: only listen/start the server if everything got initalized
+// https://www.npmjs.com/package/ws use "External HTTP/S server" and listen manually at the end of listen()
+
var port = Number(process.env.PORT);
if (isNaN(port)) port = 3002;
@@ -14,6 +17,7 @@ export class Server {
constructor() {
this.ws = new WebSocketServer({
port,
+
maxPayload: 4096,
// perMessageDeflate: {
// zlibDeflateOptions: {
diff --git a/src/listener/listener.ts b/src/listener/listener.ts
index 282ebfd5..8183f70c 100644
--- a/src/listener/listener.ts
+++ b/src/listener/listener.ts
@@ -17,7 +17,7 @@ export interface DispatchOpts {
guilds: Array<string>;
}
-function getPipeline(this: WebSocket, guilds: string[], channels: string[]) {
+function getPipeline(this: WebSocket, guilds: string[], channels: string[] = []) {
if (this.shard_count) {
guilds = guilds.filter((x) => (BigInt(x) >> 22n) % this.shard_count === this.shard_id);
}
@@ -54,12 +54,7 @@ export async function setupListener(this: WebSocket) {
export async function dispatch(this: WebSocket, document: Event, { eventStream, guilds }: DispatchOpts) {
var permission = new Permissions("ADMINISTRATOR"); // default permission for dms
console.log("event", document);
-
- if (document.guild_id) {
- if (!this.intents.has("GUILDS")) return;
- const channel_id = document.channel_id || document.data?.channel_id;
- permission = await getPermission(this.user_id, document.guild_id, channel_id);
- }
+ var channel_id = document.channel_id || document.data?.channel_id;
if (document.event === "GUILD_CREATE") {
guilds.push(document.data.id);
@@ -67,12 +62,19 @@ export async function dispatch(this: WebSocket, document: Event, { eventStream,
} else if (document.event === "GUILD_DELETE") {
guilds.remove(document.guild_id);
eventStream.changeStream(getPipeline.call(this, guilds));
+ } else if (document.event === "CHANNEL_DELETE") channel_id = null;
+ if (document.guild_id && !this.intents.has("GUILDS")) return;
+
+ try {
+ permission = await getPermission(this.user_id, document.guild_id, channel_id);
+ } catch (e) {
+ permission = new Permissions();
}
// check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents
switch (document.event) {
- case "GUILD_CREATE":
case "GUILD_DELETE":
+ case "GUILD_CREATE":
case "GUILD_UPDATE":
case "GUILD_ROLE_CREATE":
case "GUILD_ROLE_UPDATE":
diff --git a/src/opcodes/LazyRequest.ts b/src/opcodes/LazyRequest.ts
index ba7278f0..1d52ff3c 100644
--- a/src/opcodes/LazyRequest.ts
+++ b/src/opcodes/LazyRequest.ts
@@ -1,5 +1,13 @@
// @ts-nocheck WIP
-import { db, getPermission, MemberModel, MongooseCache, PublicUserProjection, RoleModel } from "@fosscord/server-util";
+import {
+ db,
+ getPermission,
+ MemberModel,
+ MongooseCache,
+ PublicUserProjection,
+ RoleModel,
+ toObject,
+} from "@fosscord/server-util";
import { LazyRequest } from "../schema/LazyRequest";
import { OPCODES, Payload } from "../util/Constants";
import { Send } from "../util/Send";
@@ -9,7 +17,6 @@ import { check } from "./instanceOf";
// TODO: config: if want to list all members (even those who are offline) sorted by role, or just those who are online
export async function onLazyRequest(this: WebSocket, { d }: Payload) {
- return; // WIP
// TODO: check data
check.call(this, LazyRequest, d);
const { guild_id, typing, channels, activities } = d as LazyRequest;
@@ -17,37 +24,63 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
const permissions = await getPermission(this.user_id, guild_id);
// MongoDB query to retrieve all hoisted roles and join them with the members and users collection
- const roles = await db
- .collection("roles")
- .aggregate([
- { $match: { guild_id, hoist: true } },
- { $sort: { position: 1 } },
- {
- $lookup: {
- from: "members",
- let: { id: "$id" },
- pipeline: [
- { $match: { $expr: { $in: ["$$id", "$roles"] } } },
- { $limit: 1 },
- {
- $lookup: {
- from: "users",
- let: { user_id: "$id" },
- pipeline: [
- { $match: { $expr: { $eq: ["$id", "$$user_id"] } } },
- { $project: PublicUserProjection },
- ],
- as: "user",
+ const roles = toObject(
+ await db
+ .collection("roles")
+ .aggregate([
+ {
+ $match: {
+ guild_id,
+ // hoist: true // TODO: also match @everyone role
+ },
+ },
+ { $sort: { position: 1 } },
+ {
+ $lookup: {
+ from: "members",
+ let: { id: "$id" },
+ pipeline: [
+ { $match: { $expr: { $in: ["$$id", "$roles"] } } },
+ { $limit: 1 },
+ {
+ $lookup: {
+ from: "users",
+ let: { user_id: "$id" },
+ pipeline: [
+ { $match: { $expr: { $eq: ["$id", "$$user_id"] } } },
+ { $project: PublicUserProjection },
+ ],
+ as: "user",
+ },
},
- },
- ],
- as: "members",
+ {
+ $unwind: "$user",
+ },
+ ],
+ as: "members",
+ },
},
+ ])
+ .toArray()
+ );
+
+ const groups = roles.map((x) => ({ id: x.id === guild_id ? "online" : x.id, count: x.members.length }));
+ const member_count = roles.reduce((a, b) => b.members.length + a, 0);
+ const items = [];
+
+ for (const role of roles) {
+ items.push({
+ group: {
+ count: role.members.length,
+ id: role.id,
},
- ])
- .toArray();
+ });
+ for (const member of role.members) {
+ items.push({ member });
+ }
+ }
- Send(this, {
+ return Send(this, {
op: OPCODES.Dispatch,
s: this.sequence++,
t: "GUILD_MEMBER_LIST_UPDATE",
@@ -56,14 +89,14 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
{
range: [0, 99],
op: "SYNC",
- items: [{ group: { id: "online", count: 0 } }],
+ items: items,
},
],
- online_count: 1,
- member_count: 1,
+ online_count: member_count, // TODO count online count
+ member_count,
id: "everyone",
guild_id,
- groups: [{ id: "online", count: 1 }],
+ groups,
},
});
}
diff --git a/src/opcodes/Resume.ts b/src/opcodes/Resume.ts
index 3c54b5c7..4efde9b0 100644
--- a/src/opcodes/Resume.ts
+++ b/src/opcodes/Resume.ts
@@ -1,7 +1,14 @@
import { CLOSECODES, Payload } from "../util/Constants";
+import { Send } from "../util/Send";
import WebSocket from "../util/WebSocket";
-export function onResume(this: WebSocket, data: Payload) {
- return this.close(CLOSECODES.Invalid_session);
+export async function onResume(this: WebSocket, data: Payload) {
+ console.log("Got Resume -> cancel not implemented");
+ await Send(this, {
+ op: 9,
+ d: false,
+ });
+
+ // return this.close(CLOSECODES.Invalid_session);
}
diff --git a/src/schema/LazyRequest.ts b/src/schema/LazyRequest.ts
index b8c51431..6a2ecb67 100644
--- a/src/schema/LazyRequest.ts
+++ b/src/schema/LazyRequest.ts
@@ -1,15 +1,17 @@
export interface LazyRequest {
- activities: boolean;
- channels: Record<string, [number, number]>;
guild_id: string;
- threads: boolean;
- typing: true;
+ channels?: Record<string, [number, number]>;
+ activities?: boolean;
+ threads?: boolean;
+ typing?: true;
+ members?: any[];
}
export const LazyRequest = {
- activities: Boolean,
- channels: Object,
guild_id: String,
- threads: Boolean,
- typing: Boolean,
+ $activities: Boolean,
+ $channels: Object,
+ $typing: Boolean,
+ $threads: Boolean,
+ $members: [] as any[],
};
diff --git a/src/schema/VoiceStateUpdate.ts.ts b/src/schema/VoiceStateUpdate.ts.ts
index 5e3e35e0..ccadda60 100644
--- a/src/schema/VoiceStateUpdate.ts.ts
+++ b/src/schema/VoiceStateUpdate.ts.ts
@@ -3,6 +3,7 @@ export const VoiceStateUpdateSchema = {
channel_id: String,
self_mute: Boolean,
self_deaf: Boolean,
+ self_video: Boolean,
};
export interface VoiceStateUpdateSchema {
@@ -10,4 +11,5 @@ export interface VoiceStateUpdateSchema {
channel_id: string;
self_mute: boolean;
self_deaf: boolean;
+ self_video: boolean;
}
|