Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cooldown): add cooldownFilteredUsers to exempt users from the cooldown precondition #249

Merged
merged 1 commit into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/lib/structures/Command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AliasPiece, AliasPieceOptions, PieceContext } from '@sapphire/pieces';
import { Awaited, isNullish } from '@sapphire/utilities';
import { Message, PermissionResolvable, Permissions } from 'discord.js';
import { Message, PermissionResolvable, Permissions, Snowflake } from 'discord.js';
import * as Lexure from 'lexure';
import { Args } from '../parsers/Args';
import { BucketScope } from '../types/Enums';
Expand Down Expand Up @@ -154,10 +154,12 @@ export abstract class Command<T = Args> extends AliasPiece {
protected parseConstructorPreConditionsCooldown(options: CommandOptions) {
const limit = options.cooldownLimit ?? 1;
const delay = options.cooldownDelay ?? 0;
const filteredUsers = options.cooldownFilteredUsers;

if (limit && delay) {
this.preconditions.append({
name: CommandPreConditions.Cooldown,
context: { scope: options.cooldownScope ?? BucketScope.User, limit, delay }
context: { scope: options.cooldownScope ?? BucketScope.User, limit, delay, filteredUsers }
});
}
}
Expand Down Expand Up @@ -344,6 +346,14 @@ export interface CommandOptions extends AliasPieceOptions, FlagStrategyOptions {
*/
cooldownScope?: BucketScope;

/**
* The users that are exempt from the Cooldown precondition.
* Use this to filter out someone like a bot owner
* @since 2.0.0
* @default undefined
*/
cooldownFilteredUsers?: Snowflake[];

/**
* The required permissions for the client.
* @since 2.0.0
Expand Down
8 changes: 2 additions & 6 deletions src/lib/structures/Precondition.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Piece, PieceContext, PieceOptions } from '@sapphire/pieces';
import type { Awaited } from '@sapphire/utilities';
import type { Message, Permissions } from 'discord.js';
import type { CooldownContext } from '../../preconditions/Cooldown';
import { PreconditionError } from '../errors/PreconditionError';
import type { UserError } from '../errors/UserError';
import { err, ok, Result } from '../parsers/Result';
import type { BucketScope } from '../types/Enums';
import type { Command } from './Command';

export type PreconditionResult = Awaited<Result<unknown, UserError>>;
Expand Down Expand Up @@ -81,11 +81,7 @@ export abstract class Precondition extends Piece {
* ```
*/
export interface Preconditions {
Cooldown: {
scope?: BucketScope;
delay: number;
limit?: number;
};
Cooldown: CooldownContext;
DMOnly: never;
Enabled: never;
GuildNewsOnly: never;
Expand Down
6 changes: 5 additions & 1 deletion src/preconditions/Cooldown.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RateLimitManager } from '@sapphire/ratelimits';
import type { Message } from 'discord.js';
import type { Message, Snowflake } from 'discord.js';
import { Identifiers } from '../lib/errors/Identifiers';
import type { Command } from '../lib/structures/Command';
import { Precondition, PreconditionContext } from '../lib/structures/Precondition';
Expand All @@ -9,6 +9,7 @@ export interface CooldownContext extends PreconditionContext {
scope?: BucketScope;
delay: number;
limit?: number;
filteredUsers?: Snowflake[];
}

export class CorePrecondition extends Precondition {
Expand All @@ -21,6 +22,9 @@ export class CorePrecondition extends Precondition {
// If there is no delay (undefined, null, 0), return ok:
if (!context.delay) return this.ok();

// If the user has provided any filtered users and the message author is in that array, return ok:
if (context.filteredUsers?.includes(message.author.id)) return this.ok();

const ratelimit = this.getManager(command, context).acquire(this.getId(message, context));
if (ratelimit.limited) {
const remaining = ratelimit.remainingTime;
Expand Down