feat(commands): added cooldowns
This commit is contained in:
parent
46bd8b6190
commit
7d870f06fb
6 changed files with 36 additions and 4 deletions
|
@ -19,8 +19,6 @@ import config from 'config';
|
||||||
import { Client, Message, MessageButton, MessageEmbed, MessageSelectMenu, MessageSelectOptionData } from 'discord.js';
|
import { Client, Message, MessageButton, MessageEmbed, MessageSelectMenu, MessageSelectOptionData } from 'discord.js';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
// TODO: Redo this mf
|
|
||||||
|
|
||||||
export default class extends Command {
|
export default class extends Command {
|
||||||
public constructor(client: Client, file: string) {
|
public constructor(client: Client, file: string) {
|
||||||
super(client, file, {
|
super(client, file, {
|
||||||
|
|
30
src/index.ts
30
src/index.ts
|
@ -24,6 +24,7 @@ import { ECommandRunIn, ELoggingScope } from '@utils/types';
|
||||||
import { walkDir } from '@utils/utils';
|
import { walkDir } from '@utils/utils';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import config from 'config';
|
import config from 'config';
|
||||||
|
import { Collection } from 'discord.js';
|
||||||
import figlet from 'figlet';
|
import figlet from 'figlet';
|
||||||
import gradient from 'gradient-string';
|
import gradient from 'gradient-string';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
@ -36,6 +37,7 @@ import { Validator } from 'jsonschema';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import process from 'process';
|
import process from 'process';
|
||||||
|
|
||||||
|
const commandCooldowns: Collection<string, Collection<string, number>> = new Collection();
|
||||||
let isBotReady = false;
|
let isBotReady = false;
|
||||||
|
|
||||||
info('Starting bot... Please wait!', ELoggingScope.Startup);
|
info('Starting bot... Please wait!', ELoggingScope.Startup);
|
||||||
|
@ -89,19 +91,47 @@ client.on('message', async (msg) => {
|
||||||
|
|
||||||
if(findCommand.options.ownerOnly && msg.author.id !== config.get('owner')) {
|
if(findCommand.options.ownerOnly && msg.author.id !== config.get('owner')) {
|
||||||
await msg.reply(i18next.t('commands:errors.ownerOnly'));
|
await msg.reply(i18next.t('commands:errors.ownerOnly'));
|
||||||
|
msg.channel.stopTyping();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((findCommand.options.runIn === ECommandRunIn.DM) && msg.channel.type !== 'dm') {
|
if((findCommand.options.runIn === ECommandRunIn.DM) && msg.channel.type !== 'dm') {
|
||||||
await msg.reply(i18next.t('commands:errors.dmsOnly'));
|
await msg.reply(i18next.t('commands:errors.dmsOnly'));
|
||||||
|
msg.channel.stopTyping();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((findCommand.options.runIn === ECommandRunIn.Server) && msg.channel.type !== 'text') {
|
if((findCommand.options.runIn === ECommandRunIn.Server) && msg.channel.type !== 'text') {
|
||||||
await msg.reply(i18next.t('commands:errors.serverOnly'));
|
await msg.reply(i18next.t('commands:errors.serverOnly'));
|
||||||
|
msg.channel.stopTyping();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(msg.author.id !== config.get('owner')) {
|
||||||
|
if(!commandCooldowns.has(findCommand.options.name!)) {
|
||||||
|
commandCooldowns.set(findCommand.options.name!, new Collection());
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
const timestamps = commandCooldowns.get(findCommand.options.name!);
|
||||||
|
const cooldownAmount = findCommand.options.cooldown! * 1000;
|
||||||
|
|
||||||
|
if(timestamps!.has(msg.author.id)) {
|
||||||
|
const expirationTime = timestamps!.get(msg.author.id)! + cooldownAmount;
|
||||||
|
|
||||||
|
if(now < expirationTime) {
|
||||||
|
const timeLeft = (expirationTime - now) / 1000;
|
||||||
|
|
||||||
|
await msg.reply(i18next.t('commands:errors.cooldownError', { time: timeLeft.toFixed(1), command: findCommand.options.name }));
|
||||||
|
msg.channel.stopTyping();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamps!.set(msg.author.id, now);
|
||||||
|
setTimeout(() => timestamps!.delete(msg.author.id), cooldownAmount);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
info(`Command ${findCommand.options.name} is being ran in ${msg.guild ? msg.guild.name : 'DMs'} by ${msg.author.username}`, ELoggingScope.Command);
|
info(`Command ${findCommand.options.name} is being ran in ${msg.guild ? msg.guild.name : 'DMs'} by ${msg.author.username}`, ELoggingScope.Command);
|
||||||
await findCommand.run(msg, ...args);
|
await findCommand.run(msg, ...args);
|
||||||
|
|
|
@ -31,6 +31,7 @@ export default abstract class Command {
|
||||||
const defaultOptions: ICommandOptions = {
|
const defaultOptions: ICommandOptions = {
|
||||||
name: path.basename(this.file, path.extname(this.file)),
|
name: path.basename(this.file, path.extname(this.file)),
|
||||||
group: path.basename(path.dirname(this.file)) === 'commands' ? '' : path.basename(path.dirname(this.file)),
|
group: path.basename(path.dirname(this.file)) === 'commands' ? '' : path.basename(path.dirname(this.file)),
|
||||||
|
cooldown: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.options = config.util.extendDeep(defaultOptions, options);
|
this.options = config.util.extendDeep(defaultOptions, options);
|
||||||
|
|
|
@ -37,6 +37,7 @@ export interface ICommandOptions {
|
||||||
extendedDescription?: string;
|
extendedDescription?: string;
|
||||||
usage?: string;
|
usage?: string;
|
||||||
ownerOnly?: boolean;
|
ownerOnly?: boolean;
|
||||||
|
cooldown?: number;
|
||||||
runIn?: ECommandRunIn;
|
runIn?: ECommandRunIn;
|
||||||
args?: {
|
args?: {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
"ownerOnly": "Only the bot owner can run this command!",
|
"ownerOnly": "Only the bot owner can run this command!",
|
||||||
"dmsOnly": "You can only run this command in DMs!",
|
"dmsOnly": "You can only run this command in DMs!",
|
||||||
"serverOnly": "You can only run this command in a server!",
|
"serverOnly": "You can only run this command in a server!",
|
||||||
"runError": "I'm sorry but an error has occurred while running this command! Please file an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```"
|
"runError": "I'm sorry but an error has occurred while running this command! Please file an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```",
|
||||||
|
"cooldownError": "Please wait { $time } more second(s) before reusing the `{ $command }` command."
|
||||||
},
|
},
|
||||||
"generic": {
|
"generic": {
|
||||||
"noShortDescription": "No short description given!",
|
"noShortDescription": "No short description given!",
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
"ownerOnly": "Onwy the bot ownyew can wun this command ^w^",
|
"ownerOnly": "Onwy the bot ownyew can wun this command ^w^",
|
||||||
"dmsOnly": "You can onwy wun this command in DMs owo",
|
"dmsOnly": "You can onwy wun this command in DMs owo",
|
||||||
"serverOnly": "You can onwy wun this command in a sewvew owo",
|
"serverOnly": "You can onwy wun this command in a sewvew owo",
|
||||||
"runError": "I'm sowwy but an ewwow has occuwwed whiwe wunnying this command ;;w;; Pwease fiwe an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```"
|
"runError": "I'm sowwy but an ewwow has occuwwed whiwe wunnying this command ;;w;; Pwease fiwe an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```",
|
||||||
|
"cooldownError": "Pwease wait { $time } mowe second(s) befowe weusing the `{ $command }` command."
|
||||||
},
|
},
|
||||||
"generic": {
|
"generic": {
|
||||||
"noShortDescription": "Nyo showt descwiption given >w<",
|
"noShortDescription": "Nyo showt descwiption given >w<",
|
||||||
|
|
Reference in a new issue