Add yell, say and die command

pull/2/head
trivernis 5 years ago
parent 6c84aefd96
commit 70cb7d4745

@ -1,7 +1,6 @@
const {src, dest, watch, series, task} = require('gulp'); const {src, dest, watch, series, task} = require('gulp');
const ts = require('gulp-typescript'); const ts = require('gulp-typescript');
const del = require('delete'); const del = require('delete');
const gulp = require('gulp');
function clearDist(cb) { function clearDist(cb) {
del('dist/*', cb); del('dist/*', cb);

@ -13,6 +13,8 @@ import {globalCommands} from "./commands/global";
import {privateCommands} from "./commands/private"; import {privateCommands} from "./commands/private";
import {parseMessage} from "./lib/utils"; import {parseMessage} from "./lib/utils";
import {CommandPermission} from "./lib/CommandPermission"; import {CommandPermission} from "./lib/CommandPermission";
import {Help} from "./commands/global/utility/Help";
import {ExtendedMessage} from "./lib/ExtendedMessage";
const configFile = "config.yaml"; const configFile = "config.yaml";
@ -31,6 +33,7 @@ export class Bot {
* constructor * constructor
*/ */
constructor() { constructor() {
globalCommands.add(Help);
this.config = Bot.loadConfig(); this.config = Bot.loadConfig();
this.logger = new BotLogger(this.config.logging.directory, this.config.logging.level); this.logger = new BotLogger(this.config.logging.directory, this.config.logging.level);
this.client = new Client(); this.client = new Client();
@ -87,7 +90,11 @@ export class Bot {
this.config.prefix, userPermission); this.config.prefix, userPermission);
if (CommandClass) { if (CommandClass) {
const command = new CommandClass(this); const command = new CommandClass(this);
command.invoke(message); try {
await command.invoke(message, new ExtendedMessage(message));
} catch (err) {
this.logger.errorReport(err);
}
} }
} }
} }

@ -0,0 +1,5 @@
export enum CommandCategory {
UTILITY = "Utility",
MUSIC = "Music",
MISC = "Misc",
}

@ -1,6 +1,13 @@
import {CommandCollection} from "../../lib/CommandCollection"; import {CommandCollection} from "../../lib/CommandCollection";
import {Ping} from "./utility/Ping"; import {Ping} from "./utility/Ping";
import {Say} from "./utility/Say";
import { Help } from "./utility/Help";
import {Yell} from "./utility/Yell";
import { Die } from "./utility/Die";
export const globalCommands = new CommandCollection([ export const globalCommands: CommandCollection<any> = new CommandCollection([
Ping, Ping,
Say,
Yell,
Die,
]); ]);

@ -0,0 +1,22 @@
import {Command} from "../../../lib/Command";
import {CommandPermission} from "../../../lib/CommandPermission";
import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
import { Help } from "./Help";
export class Die extends Command {
public static commandName = "die";
public static category = CommandCategory.UTILITY;
public static permission = CommandPermission.OWNER;
public static description = "Kills the bot.";
/**
* Replies with the current ping.
* @param msg
*/
public async invoke(msg: Message): Promise<void> {
await msg.channel.send("AAAAAARRRGGHHH...");
await msg.client.destroy();
process.exit(0);
}
}

@ -0,0 +1,99 @@
import {Command} from "../../../lib/Command";
import {Message, RichEmbed} from "discord.js";
import {CommandCollection} from "../../../lib/CommandCollection";
import {globalCommands} from "../index";
import {guildCommands} from "../../guild";
import {privateCommands} from "../../private";
import {CommandCategory} from "../../CommandCategory";
import {ExtendedMessage} from "../../../lib/ExtendedMessage";
import {CommandPermission} from "../../../lib/CommandPermission";
export class Help extends Command {
public static commandName = "help";
public static description = "Shows a help for commands.";
public static usage = "help [<command>]";
public static category = CommandCategory.UTILITY;
public allCommands: CommandCollection<any> = new CommandCollection<any>(
[...globalCommands, ...guildCommands, ...privateCommands]);
/**
* Shows a help embed.
* If an argument is provided the specific help for that command is shown.
* @param msg
* @param exMsg
*/
public invoke(msg: Message, exMsg: ExtendedMessage): void {
const args = exMsg.args;
const helpEmbed = new RichEmbed();
helpEmbed.setTitle("Help");
if (args.length === 0) {
msg.channel.send("", this.getOverviewHelpEmbed(exMsg));
} else {
const commandHelp = this.getCommandHelpEmbed(exMsg);
if (commandHelp) {
msg.channel.send("", commandHelp);
} else {
msg.channel.send(`The command **${args[0]}** could not be found.`);
}
}
}
/**
* Returns a help embed for the provided command.
* @param exMsg
*/
private getCommandHelpEmbed(exMsg: ExtendedMessage): RichEmbed {
const CommandClass = this.allCommands.findByName(exMsg.args[0]);
if (CommandClass) {
const helpEmbed = new RichEmbed();
helpEmbed.setTitle(`Help for **${CommandClass.commandName}**`);
helpEmbed.addField("Description", CommandClass.description || "*No description entity found.*");
helpEmbed.addField("Usage",
`\`${exMsg.prefix}${CommandClass.usage || CommandClass.commandName}\``, true);
let permissionNeeded: string;
switch (CommandClass.permission as CommandPermission) {
case CommandPermission.OWNER:
permissionNeeded = "Owner";
break;
case CommandPermission.ADMIN:
permissionNeeded = "Admin";
break;
case CommandPermission.DJ:
permissionNeeded = "DJ";
break;
case CommandPermission.REGULAR:
default:
permissionNeeded = "None";
break;
}
helpEmbed.addField("Permission Level", permissionNeeded, true);
return helpEmbed;
}
}
/**
* Returns a rich embed containing an overview of all the available commands.
* @param exMsg
*/
private getOverviewHelpEmbed(exMsg: ExtendedMessage): RichEmbed {
const helpEmbed = new RichEmbed();
const commandsByCategory: any = {};
helpEmbed.setDescription(
`Use \`${exMsg.prefix}\`help [command] for more info on a command.`);
for (const CommandClass of this.allCommands) {
const category: string = CommandClass.category;
if (!commandsByCategory[Help.category]) {
commandsByCategory[category] = "";
}
commandsByCategory[category] += `\`${CommandClass.commandName}\`\t`;
}
for (const category in commandsByCategory) {
if (commandsByCategory.hasOwnProperty(category)) {
helpEmbed.addField(category, commandsByCategory[category]);
}
}
return helpEmbed;
}
}

@ -1,9 +1,11 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {CommandPermission} from "../../../lib/CommandPermission"; import {CommandPermission} from "../../../lib/CommandPermission";
import {Message} from "discord.js"; import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
export class Ping extends Command { export class Ping extends Command {
public static commandName = "ping"; public static commandName = "ping";
public static category = CommandCategory.UTILITY;
public static permission = CommandPermission.REGULAR; public static permission = CommandPermission.REGULAR;
public static description = "Replies with the bots ping."; public static description = "Replies with the bots ping.";

@ -0,0 +1,26 @@
import {Command} from "../../../lib/Command";
import {CommandPermission} from "../../../lib/CommandPermission";
import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
import { Help } from "./Help";
export class Say extends Command {
public static commandName = "say";
public static category = CommandCategory.UTILITY;
public static permission = CommandPermission.REGULAR;
public static description = "Replies with what you said.";
/**
* Replies with the current ping.
* @param msg
*/
public invoke(msg: Message): void {
const msgContents = Say.getArgs(msg.content);
msgContents.shift();
const replyContent = msgContents.join(" ");
if (replyContent.replace(/\s/g, "").length > 0) {
msg.channel.send(replyContent);
}
}
}

@ -0,0 +1,26 @@
import {Command} from "../../../lib/Command";
import {CommandPermission} from "../../../lib/CommandPermission";
import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
import { Help } from "./Help";
export class Yell extends Command {
public static commandName = "yell";
public static category = CommandCategory.UTILITY;
public static permission = CommandPermission.REGULAR;
public static description = "Yells what you said.";
/**
* Replies with the current ping.
* @param msg
*/
public invoke(msg: Message): void {
const msgContents = Yell.getArgs(msg.content);
msgContents.shift();
const replyContent = msgContents.join(" ");
if (replyContent.replace(/\s/g, "").length > 0) {
msg.channel.send(replyContent.toUpperCase());
}
}
}

@ -1,10 +1,14 @@
import {Message} from "discord.js"; import {Message} from "discord.js";
import {GuildCommand} from "../../../lib/GuildCommand"; import {GuildCommand} from "../../../lib/GuildCommand";
import {CommandPermission} from "../../../lib/CommandPermission"; import {CommandPermission} from "../../../lib/CommandPermission";
import {CommandCategory} from "../../CommandCategory";
export class AddAdminRoles extends GuildCommand { export class AddAdminRoles extends GuildCommand {
public static commandName = "addAdminRoles"; public static commandName = "addAdminRoles";
public static description = "Adds roles to the recognized admin roles for command permissions.";
public static usage = "addAdminRoles <roleName>...";
public static permission = CommandPermission.ADMIN; public static permission = CommandPermission.ADMIN;
public static category = CommandCategory.UTILITY;
/** /**
* Adds an admin role to the admin role setting on the server * Adds an admin role to the admin role setting on the server

@ -1,11 +1,14 @@
import {CommandPermission} from "../../../lib/CommandPermission"; import {CommandPermission} from "../../../lib/CommandPermission";
import {GuildCommand} from "../../../lib/GuildCommand"; import {GuildCommand} from "../../../lib/GuildCommand";
import {Message} from "discord.js"; import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
export class RemoveAdminRoles extends GuildCommand { export class RemoveAdminRoles extends GuildCommand {
public static commandName = "removeAdminRoles"; public static commandName = "removeAdminRoles";
public static description = "Removes one or more roles from the configured roles"; public static description = "Removes one or more roles from the configured roles";
public static usage = "removeAdminRoles <roleName>...";
public static permission = CommandPermission.ADMIN; public static permission = CommandPermission.ADMIN;
public static category = CommandCategory.UTILITY;
/** /**
* Removes all specified roles from the admin roles. * Removes all specified roles from the admin roles.

@ -1,10 +1,14 @@
import {GuildCommand} from "../../../lib/GuildCommand"; import {GuildCommand} from "../../../lib/GuildCommand";
import {CommandPermission} from "../../../lib/CommandPermission"; import {CommandPermission} from "../../../lib/CommandPermission";
import {Message} from "discord.js"; import {Message} from "discord.js";
import {CommandCategory} from "../../CommandCategory";
export class SetPrefix extends GuildCommand { export class SetPrefix extends GuildCommand {
public static commandName = "setPrefix"; public static commandName = "setPrefix";
public static permission = CommandPermission.ADMIN; public static permission = CommandPermission.ADMIN;
public static category = CommandCategory.UTILITY;
public static description = "Sets the command prefix for the guild.";
public static usage = "setPrefix <prefix>";
/** /**
* Sets the prefix for a guild. * Sets the prefix for a guild.

@ -1,6 +1,9 @@
import {Message, MessageReaction} from "discord.js"; import {Message, MessageReaction} from "discord.js";
import {CommandPermission} from "./CommandPermission"; import {CommandPermission} from "./CommandPermission";
import {Bot} from "../Bot"; import {Bot} from "../Bot";
import {basename} from "path";
import {CommandCategory} from "../commands/CommandCategory";
import {ExtendedMessage} from "./ExtendedMessage";
export abstract class Command { export abstract class Command {
@ -16,6 +19,11 @@ export abstract class Command {
*/ */
public static description: string; public static description: string;
/**
* The category of the command
*/
public static category: CommandCategory;
/** /**
* The time to live in seconds before the instance is deleted. * The time to live in seconds before the instance is deleted.
*/ */
@ -29,14 +37,14 @@ export abstract class Command {
/** /**
* The permission required to run this command * The permission required to run this command
*/ */
public static permission: CommandPermission; public static permission: CommandPermission = CommandPermission.REGULAR;
protected constructor(bot: Bot) { protected constructor(bot: Bot) {
this.bot = bot; this.bot = bot;
this.createdAt = Date.now(); this.createdAt = Date.now();
} }
public invoke?(msg: Message): Promise<void>|void; public invoke?(msg: Message, exMsg: ExtendedMessage): Promise<void>|void;
/** /**
* A function that is executed when the answer to the command was sent. * A function that is executed when the answer to the command was sent.

@ -0,0 +1,26 @@
import {Message} from "discord.js";
const messageRegex: RegExp = /^(.)(\w+)\s*(.*)$/;
/**
* A class for parsing messages in an easier to handle format.
*/
export class ExtendedMessage {
public readonly originalMessage: Message;
public readonly content: string;
public readonly prefix: string;
public readonly commandName: string;
public readonly argString: string;
public readonly args: string[];
constructor(message: Message) {
this.originalMessage = message;
this.content = message.content;
const matches = this.content.match(messageRegex);
this.prefix = matches[1];
this.commandName = matches[2];
this.argString = matches[3];
this.args = matches[3].split(/\s+/).filter((s) => s.length > 0);
}
}

@ -6,10 +6,11 @@ import {CommandPermission} from "./CommandPermission";
import {CommandCollection} from "./CommandCollection"; import {CommandCollection} from "./CommandCollection";
import {guildCommands} from "../commands/guild"; import {guildCommands} from "../commands/guild";
import {globalCommands} from "../commands/global"; import {globalCommands} from "../commands/global";
import {Command} from "./Command";
import {BotLogger} from "./utils/BotLogger"; import {BotLogger} from "./utils/BotLogger";
import {ProxyEventEmitter} from "./utils/ProxyEventEmitter"; import {ProxyEventEmitter} from "./utils/ProxyEventEmitter";
import {parseMessage} from "./utils"; import {parseMessage} from "./utils";
import {ExtendedMessage} from "./ExtendedMessage";
import { Help } from "../commands/global/utility/Help";
/** /**
* Handles all guild related tasks. * Handles all guild related tasks.
@ -69,7 +70,11 @@ export class GuildHandler {
if (CommandClass) { if (CommandClass) {
const command = new CommandClass(this.bot, this); const command = new CommandClass(this.bot, this);
await command.invoke(message); try {
await command.invoke(message, new ExtendedMessage(message));
} catch (err) {
this.logger.errorReport(err);
}
} }
} }
@ -88,7 +93,10 @@ export class GuildHandler {
private getMembersHighestRole(guildMember: GuildMember) { private getMembersHighestRole(guildMember: GuildMember) {
const adminRoles = this.guildSettings.adminRoles; const adminRoles = this.guildSettings.adminRoles;
const djRoles = this.guildSettings.djRoles; const djRoles = this.guildSettings.djRoles;
if (adminRoles.find((role) => GuildHandler.memberHasRole(guildMember, role))) {
if (this.bot.config.owners.includes(guildMember.user.tag)) {
return CommandPermission.OWNER;
} else if (adminRoles.find((role) => GuildHandler.memberHasRole(guildMember, role))) {
return CommandPermission.ADMIN; return CommandPermission.ADMIN;
} else if (djRoles.find((role) => GuildHandler.memberHasRole(guildMember, role))) { } else if (djRoles.find((role) => GuildHandler.memberHasRole(guildMember, role))) {
return CommandPermission.DJ; return CommandPermission.DJ;

Loading…
Cancel
Save