From b4e2c0c4d5538b945f9d597c6410a6f84b315084 Mon Sep 17 00:00:00 2001 From: Almeida Date: Fri, 29 Jul 2022 09:47:05 +0100 Subject: [PATCH] fix(MessageMentions): `ignoreRepliedUser` option in `has()` (#8202) --- .../src/structures/MessageMentions.js | 45 ++++++++++++++++--- packages/discord.js/typings/index.d.ts | 2 + 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/discord.js/src/structures/MessageMentions.js b/packages/discord.js/src/structures/MessageMentions.js index 125d0f102..b142a6c68 100644 --- a/packages/discord.js/src/structures/MessageMentions.js +++ b/packages/discord.js/src/structures/MessageMentions.js @@ -133,6 +133,13 @@ class MessageMentions { */ this._channels = null; + /** + * Cached users for {@link MessageMentions#parsedUsers} + * @type {?Collection} + * @private + */ + this._parsedUsers = null; + /** * Crossposted channel data. * @typedef {Object} CrosspostedChannel @@ -208,6 +215,23 @@ class MessageMentions { return this._channels; } + /** + * Any user mentions that were included in the message content + * Order as they appear first in the message content + * @type {Collection} + * @readonly + */ + get parsedUsers() { + if (this._parsedUsers) return this._parsedUsers; + this._parsedUsers = new Collection(); + let matches; + while ((matches = this.constructor.UsersPattern.exec(this._content)) !== null) { + const user = this.client.users.cache.get(matches[1]); + if (user) this._parsedUsers.set(user.id, user); + } + return this._parsedUsers; + } + /** * Options used to check for a mention. * @typedef {Object} MessageMentionsHasOptions @@ -227,16 +251,23 @@ class MessageMentions { */ has(data, { ignoreDirect = false, ignoreRoles = false, ignoreRepliedUser = false, ignoreEveryone = false } = {}) { const user = this.client.users.resolve(data); - const role = this.guild?.roles.resolve(data); - const channel = this.client.channels.resolve(data); - if (!ignoreRepliedUser && this.users.has(this.repliedUser?.id) && this.repliedUser?.id === user?.id) return true; + if (!ignoreEveryone && user && this.everyone) return true; + + const userWasRepliedTo = user && this.repliedUser?.id === user.id; + + if (!ignoreRepliedUser && userWasRepliedTo && this.users.has(user.id)) return true; + if (!ignoreDirect) { - if (this.users.has(user?.id)) return true; - if (this.roles.has(role?.id)) return true; - if (this.channels.has(channel?.id)) return true; + if (user && (!ignoreRepliedUser || this.parsedUsers.has(user.id)) && this.users.has(user.id)) return true; + + const role = this.guild?.roles.resolve(data); + if (role && this.roles.has(role.id)) return true; + + const channel = this.client.channels.resolve(data); + if (channel && this.channels.has(channel.id)) return true; } - if (user && !ignoreEveryone && this.everyone) return true; + if (!ignoreRoles) { const member = this.guild?.members.resolve(data); if (member) { diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index b12a61a73..857db6880 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1865,6 +1865,7 @@ export class MessageMentions { private _channels: Collection | null; private readonly _content: string; private _members: Collection | null; + private _parsedUsers: Collection | null; public get channels(): Collection; public readonly client: Client; @@ -1872,6 +1873,7 @@ export class MessageMentions { public readonly guild: Guild; public has(data: UserResolvable | RoleResolvable | ChannelResolvable, options?: MessageMentionsHasOptions): boolean; public get members(): Collection | null; + public get parsedUsers(): Collection; public repliedUser: User | null; public roles: Collection; public users: Collection;