1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-09-22 02:31:36 +02:00

Member List

This commit is contained in:
Flam3rboy 2021-05-21 22:16:48 +02:00
parent 671091a13f
commit e434334a21
8 changed files with 112 additions and 63 deletions

14
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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: {

View File

@ -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":

View File

@ -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",
},
},
],
as: "members",
const roles = toObject(
await db
.collection("roles")
.aggregate([
{
$match: {
guild_id,
// hoist: true // TODO: also match @everyone role
},
},
},
])
.toArray();
{ $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",
},
},
{
$unwind: "$user",
},
],
as: "members",
},
},
])
.toArray()
);
Send(this, {
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,
},
});
for (const member of role.members) {
items.push({ member });
}
}
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,
},
});
}

View File

@ -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);
}

View File

@ -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[],
};

View File

@ -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;
}