MongooseCache resubscription

This commit is contained in:
notsapinho 2021-04-08 11:40:57 -03:00
parent f3f11adb38
commit 953d7bd3d2
2 changed files with 175 additions and 159 deletions

View File

@ -20,6 +20,7 @@
"lambert-db": "^1.1.8", "lambert-db": "^1.1.8",
"lambert-server": "^1.1.7", "lambert-server": "^1.1.7",
"missing-native-js-functions": "^1.2.3", "missing-native-js-functions": "^1.2.3",
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"typescript": "^4.2.3", "typescript": "^4.2.3",
"uuid": "^8.3.2", "uuid": "^8.3.2",
@ -27,6 +28,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"@types/mongoose-autopopulate": "^0.10.1",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"@types/ws": "^7.4.0" "@types/ws": "^7.4.0"
} }

View File

@ -12,174 +12,188 @@ import WebSocket from "../util/WebSocket";
// https://discord.com/developers/docs/topics/gateway#sharding // https://discord.com/developers/docs/topics/gateway#sharding
export async function setupListener(this: WebSocket) { export async function setupListener(this: WebSocket) {
const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); const user = await UserModel.findOne({ id: this.user_id }).lean().exec();
var guilds = user.guilds; var guilds = user.guilds;
const shard_count = 10n; const shard_count = 10n;
const shard_id = 0n; const shard_id = 0n;
if (shard_count) { if (shard_count) {
guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id);
} }
const eventStream = new MongooseCache( const eventStream = new MongooseCache(
db.collection("events"), db.collection("events"),
[ [
{ {
$match: { $match: {
$or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": this.user_id }], $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": user.id }]
}, }
}, }
], ],
{ onlyEvents: true } {
); onlyEvents: true
await eventStream.init(); }
eventStream.on("insert", dispatch.bind(this)); );
this.once("close", () => eventStream.destroy()); await eventStream.init();
eventStream.on("insert", async (document) => {
dispatch.call(this, document);
const newUser = await UserModel.findOne({ id: user.id }).lean().exec();
var newGuilds = user.guilds;
if (shard_count) {
newGuilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id);
}
eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: newGuilds } }, { "fullDocument.user_id": newUser.id }] } }]);
});
this.once("close", () => eventStream.destroy());
} }
export async function dispatch(this: WebSocket, document: Event) { export async function dispatch(this: WebSocket, document: Event) {
var permission = new Permissions("ADMINISTRATOR"); // default permission for dms var permission = new Permissions("ADMINISTRATOR"); // default permission for dms
console.log("event", document); console.log("event", document);
if (document.guild_id) { if (document.guild_id) {
if (!this.intents.has("GUILDS")) return; if (!this.intents.has("GUILDS")) return;
const channel_id = document.channel_id || document.data?.channel_id; const channel_id = document.channel_id || document.data?.channel_id;
permission = await getPermission(this.user_id, document.guild_id, channel_id); permission = await getPermission(this.user_id, document.guild_id, channel_id);
} }
// check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents
switch (document.event) { switch (document.event) {
case "GUILD_CREATE": case "GUILD_CREATE":
case "GUILD_DELETE": case "GUILD_DELETE":
case "GUILD_UPDATE": case "GUILD_UPDATE":
case "GUILD_ROLE_CREATE": case "GUILD_ROLE_CREATE":
case "GUILD_ROLE_UPDATE": case "GUILD_ROLE_UPDATE":
case "GUILD_ROLE_DELETE": case "GUILD_ROLE_DELETE":
case "CHANNEL_CREATE": case "CHANNEL_CREATE":
case "CHANNEL_DELETE": case "CHANNEL_DELETE":
case "CHANNEL_UPDATE": case "CHANNEL_UPDATE":
// gets sent if GUILDS intent is set (already checked in if document.guild_id) // gets sent if GUILDS intent is set (already checked in if document.guild_id)
break; break;
case "GUILD_INTEGRATIONS_UPDATE": case "GUILD_INTEGRATIONS_UPDATE":
if (!this.intents.has("GUILD_INTEGRATIONS")) return; if (!this.intents.has("GUILD_INTEGRATIONS")) return;
break; break;
case "WEBHOOKS_UPDATE": case "WEBHOOKS_UPDATE":
if (!this.intents.has("GUILD_WEBHOOKS")) return; if (!this.intents.has("GUILD_WEBHOOKS")) return;
break; break;
case "GUILD_EMOJI_UPDATE": case "GUILD_EMOJI_UPDATE":
if (!this.intents.has("GUILD_EMOJIS")) return; if (!this.intents.has("GUILD_EMOJIS")) return;
break; break;
// only send them, if the user subscribed for this part of the member list, or is a bot // only send them, if the user subscribed for this part of the member list, or is a bot
case "GUILD_MEMBER_ADD": case "GUILD_MEMBER_ADD":
case "GUILD_MEMBER_REMOVE": case "GUILD_MEMBER_REMOVE":
case "GUILD_MEMBER_UPDATE": case "GUILD_MEMBER_UPDATE":
if (!this.intents.has("GUILD_MEMBERS")) return; if (!this.intents.has("GUILD_MEMBERS")) return;
break; break;
case "VOICE_STATE_UPDATE": case "VOICE_STATE_UPDATE":
if (!this.intents.has("GUILD_VOICE_STATES")) return; if (!this.intents.has("GUILD_VOICE_STATES")) return;
break; break;
case "GUILD_BAN_ADD": case "GUILD_BAN_ADD":
case "GUILD_BAN_REMOVE": case "GUILD_BAN_REMOVE":
if (!this.intents.has("GUILD_BANS")) return; if (!this.intents.has("GUILD_BANS")) return;
break; break;
case "INVITE_CREATE": case "INVITE_CREATE":
case "INVITE_DELETE": case "INVITE_DELETE":
if (!this.intents.has("GUILD_INVITES")) return; if (!this.intents.has("GUILD_INVITES")) return;
case "PRESENCE_UPDATE": case "PRESENCE_UPDATE":
if (!this.intents.has("GUILD_PRESENCES")) return; if (!this.intents.has("GUILD_PRESENCES")) return;
break; break;
case "MESSAGE_CREATE": case "MESSAGE_CREATE":
case "MESSAGE_DELETE": case "MESSAGE_DELETE":
case "MESSAGE_DELETE_BULK": case "MESSAGE_DELETE_BULK":
case "MESSAGE_UPDATE": case "MESSAGE_UPDATE":
case "CHANNEL_PINS_UPDATE": case "CHANNEL_PINS_UPDATE":
if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return; if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return;
if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return; if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return;
break; break;
case "MESSAGE_REACTION_ADD": case "MESSAGE_REACTION_ADD":
case "MESSAGE_REACTION_REMOVE": case "MESSAGE_REACTION_REMOVE":
case "MESSAGE_REACTION_REMOVE_ALL": case "MESSAGE_REACTION_REMOVE_ALL":
case "MESSAGE_REACTION_REMOVE_EMOJI": case "MESSAGE_REACTION_REMOVE_EMOJI":
if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return; if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return;
if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return; if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return;
break; break;
case "TYPING_START": case "TYPING_START":
if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return; if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return;
if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return; if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return;
break; break;
case "READY": // will be sent by the gateway case "READY": // will be sent by the gateway
case "USER_UPDATE": case "USER_UPDATE":
case "APPLICATION_COMMAND_CREATE": case "APPLICATION_COMMAND_CREATE":
case "APPLICATION_COMMAND_DELETE": case "APPLICATION_COMMAND_DELETE":
case "APPLICATION_COMMAND_UPDATE": case "APPLICATION_COMMAND_UPDATE":
default: default:
// Any events not defined in an intent are considered "passthrough" and will always be sent to you. // Any events not defined in an intent are considered "passthrough" and will always be sent to you.
break; break;
} }
// check permissions // check permissions
switch (document.event) { switch (document.event) {
case "GUILD_INTEGRATIONS_UPDATE": case "GUILD_INTEGRATIONS_UPDATE":
if (!permission.has("MANAGE_GUILD")) return; if (!permission.has("MANAGE_GUILD")) return;
break; break;
case "WEBHOOKS_UPDATE": case "WEBHOOKS_UPDATE":
if (!permission.has("MANAGE_WEBHOOKS")) return; if (!permission.has("MANAGE_WEBHOOKS")) return;
break; break;
case "GUILD_MEMBER_ADD": case "GUILD_MEMBER_ADD":
case "GUILD_MEMBER_REMOVE": case "GUILD_MEMBER_REMOVE":
case "GUILD_MEMBER_UPDATE": case "GUILD_MEMBER_UPDATE":
// only send them, if the user subscribed for this part of the member list, or is a bot // only send them, if the user subscribed for this part of the member list, or is a bot
break; break;
case "GUILD_BAN_ADD": case "GUILD_BAN_ADD":
case "GUILD_BAN_REMOVE": case "GUILD_BAN_REMOVE":
if (!permission.has("BAN_MEMBERS")) break; if (!permission.has("BAN_MEMBERS")) break;
break; break;
case "INVITE_CREATE": case "INVITE_CREATE":
case "INVITE_DELETE": case "INVITE_DELETE":
if (!permission.has("MANAGE_GUILD")) break; if (!permission.has("MANAGE_GUILD")) break;
case "PRESENCE_UPDATE": case "PRESENCE_UPDATE":
break; break;
case "VOICE_STATE_UPDATE": case "VOICE_STATE_UPDATE":
case "MESSAGE_CREATE": case "MESSAGE_CREATE":
case "MESSAGE_DELETE": case "MESSAGE_DELETE":
case "MESSAGE_DELETE_BULK": case "MESSAGE_DELETE_BULK":
case "MESSAGE_UPDATE": case "MESSAGE_UPDATE":
case "CHANNEL_PINS_UPDATE": case "CHANNEL_PINS_UPDATE":
case "MESSAGE_REACTION_ADD": case "MESSAGE_REACTION_ADD":
case "MESSAGE_REACTION_REMOVE": case "MESSAGE_REACTION_REMOVE":
case "MESSAGE_REACTION_REMOVE_ALL": case "MESSAGE_REACTION_REMOVE_ALL":
case "MESSAGE_REACTION_REMOVE_EMOJI": case "MESSAGE_REACTION_REMOVE_EMOJI":
case "TYPING_START": case "TYPING_START":
// only gets send if the user is alowed to view the current channel // only gets send if the user is alowed to view the current channel
if (!permission.has("VIEW_CHANNEL")) return; if (!permission.has("VIEW_CHANNEL")) return;
break; break;
case "GUILD_CREATE": case "GUILD_CREATE":
case "GUILD_DELETE": case "GUILD_DELETE":
case "GUILD_UPDATE": case "GUILD_UPDATE":
case "GUILD_ROLE_CREATE": case "GUILD_ROLE_CREATE":
case "GUILD_ROLE_UPDATE": case "GUILD_ROLE_UPDATE":
case "GUILD_ROLE_DELETE": case "GUILD_ROLE_DELETE":
case "CHANNEL_CREATE": case "CHANNEL_CREATE":
case "CHANNEL_DELETE": case "CHANNEL_DELETE":
case "CHANNEL_UPDATE": case "CHANNEL_UPDATE":
case "GUILD_EMOJI_UPDATE": case "GUILD_EMOJI_UPDATE":
case "READY": // will be sent by the gateway case "READY": // will be sent by the gateway
case "USER_UPDATE": case "USER_UPDATE":
case "APPLICATION_COMMAND_CREATE": case "APPLICATION_COMMAND_CREATE":
case "APPLICATION_COMMAND_DELETE": case "APPLICATION_COMMAND_DELETE":
case "APPLICATION_COMMAND_UPDATE": case "APPLICATION_COMMAND_UPDATE":
default: default:
// always gets sent // always gets sent
// Any events not defined in an intent are considered "passthrough" and will always be sent // Any events not defined in an intent are considered "passthrough" and will always be sent
break; break;
} }
return Send(this, { return Send(this, {
op: OPCODES.Dispatch, op: OPCODES.Dispatch,
t: document.event, t: document.event,
d: document.data, d: document.data,
s: this.sequence++, s: this.sequence++
}); });
} }