From 83d7ff1fcef1f048a872d05e6a8c27c4aa596c18 Mon Sep 17 00:00:00 2001 From: Ibrahim Ansari Date: Sat, 1 Sep 2018 13:50:26 +0530 Subject: [PATCH] Build a basic client for phase 3. Some implementation is left but we're done here, it's nearly complete. MongoDB and cache integration untested, no command uses it at the moment. --- server/bot/client.ts | 99 ++++++++++++++++++++++++++++++++----- server/bot/imports/types.ts | 27 +++++++++- 2 files changed, 114 insertions(+), 12 deletions(-) diff --git a/server/bot/client.ts b/server/bot/client.ts index 7072b74..3044b00 100644 --- a/server/bot/client.ts +++ b/server/bot/client.ts @@ -1,11 +1,35 @@ -// import { Message } from 'eris' +// eslint-disable-next-line standard/object-curly-even-spacing +import { Message, Client /*, CommandGenerator */ } from 'eris' +import { DB, Command as IveBotCommand } from './imports/types' +import { Db } from 'mongodb' -/* export class Command { - constructor (command) { +export class Command { + name: string // eslint-disable-next-line no-undef + aliases: string[] // eslint-disable-next-line no-undef + generators: (client: Client, db?: DB, mongoDB?: Db) => ({ // eslint-disable-next-line no-undef + generator: string|Function // CommandGenerator, + // eslint-disable-next-line no-undef + postGenerator: (message: Message, args: string[], sent?: Message) => void + }) + argsRequired: boolean // eslint-disable-line no-undef + caseInsensitive: boolean // eslint-disable-line no-undef + deleteCommand: boolean // eslint-disable-line no-undef + guildOnly: boolean // eslint-disable-line no-undef + dmOnly: boolean // eslint-disable-line no-undef + description: string // eslint-disable-line no-undef + fullDescription: string // eslint-disable-line no-undef + usage: string // eslint-disable-line no-undef + example: string // eslint-disable-line no-undef + hidden: boolean // eslint-disable-line no-undef + // eslint-disable-next-line no-undef + requirements: { // eslint-disable-next-line no-undef + userIDs: string[], roleNames: string[], custom: Function, permissions: {}, roleIDs: string[] + } + + constructor (command: IveBotCommand) { this.name = command.name this.aliases = command.aliases - this.generator = command.generator - this.postGenerator = command.postGenerator // serves as hooks. + this.generators = command.generators // Options. this.argsRequired = command.opts.argsRequired this.caseInsensitive = command.opts.caseInsensitive @@ -22,25 +46,78 @@ // No cooldown implementation. // No reaction implementation. } -} */ +} -/* export class CommandParser { +export class CommandParser { commands: { [name: string]: Command } // eslint-disable-line no-undef - constructor () { + client: Client // eslint-disable-line no-undef + tempDB: DB // eslint-disable-line no-undef + db: Db // eslint-disable-line no-undef + constructor (client: Client, tempDB: DB, db: Db) { this.commands = {} + this.client = client + this.tempDB = tempDB + this.db = db } - registerCommand (command) { + registerCommand (command: IveBotCommand) { this.commands[command.name] = new Command(command) } - permissionCheck (command: Command, message: Message) { + requirementsCheck (command: Command, message: Message) { + if (!command.requirements) return true + // No role name or ID impl. + const userIDs = command.requirements.userIDs + ? command.requirements.userIDs.includes(message.author.id) + : true + const custom = command.requirements.custom ? command.requirements.custom() : true + const permissions = command.requirements.permissions + ? Object.assign( + message.member.permission.json, command.requirements.permissions + ) === message.member.permission.json + : true + return userIDs || custom || permissions + } + + async executeCommand (command: Command, message: Message) { + const session = command.generators(this.client, this.tempDB, this.db) + const args = message.content.split(' ') + args.shift() + if (!this.requirementsCheck(command, message)) return + let messageToSend = typeof session.generator === 'function' + ? session.generator(message, args) + : session.generator + // No Array or Promise support lel. + // if (messageToSend instanceof Promise) messageToSend = await messageToSend + // if (messageToSend instanceof Array) messageToSend = messageToSend[Math.floor(Math.random() * messageToSend.length)] + let sent + if (messageToSend) sent = await message.channel.createMessage(messageToSend) + if (session.postGenerator) session.postGenerator(message, args, sent) + } + + onMessage (message: Message) { + // We need to add calls for the other message callback. + const commandExec = message.content.split(' ')[0].substr(1) + if (!commandExec.startsWith('/')) return // Don't process it if it's not a command. + // Check for the commands in this.commands. + const keys = Object.keys(this.commands) + for (let i = 0; i < keys.length; i++) { + if (commandExec === keys[i]) { + // Execute command. + this.executeCommand(this.commands[keys[i]], message) + break + } else if (this.commands[keys[i]].aliases.includes(commandExec)) { + // Execute command. + break + } + } } -} */ +} // class CommandParser // We don't construct.. or maybe we do just a bit. // Now we add registerCommand // { name, ...opts, generator, postGenerator } hmm +// We have alias and all sorts of checks because we need to be cautious.. // now we add onMessage // Execute permission checker, then generator and postGenerator // if no command call the other callback in index.ts just cuz yeah diff --git a/server/bot/imports/types.ts b/server/bot/imports/types.ts index f8f50fe..823b3d1 100644 --- a/server/bot/imports/types.ts +++ b/server/bot/imports/types.ts @@ -1,6 +1,6 @@ // Flow our types. /* eslint-disable no-undef */ -import { CommandGenerator } from 'eris' +import { CommandGenerator, Client, Message } from 'eris' import IveBotCommandClient, { IveBotCommandOptions } from './CustomClient' import { Db } from 'mongodb' @@ -10,6 +10,31 @@ export type IveBotCommand = (client: IveBotCommandClient, db?: DB, mongoDB?: Db) opts: IveBotCommandOptions, name: string } +export type Command = { + // eslint-disable-next-line no-use-before-define + opts: CommandOptions, + aliases: string[], + name: string, + generators: (client: Client, db?: DB, mongoDB?: Db) => ({ + generator: string|Function // CommandGenerator, + postGenerator: (message: Message, args: string[], sent?: Message) => void + }) +} +export type CommandOptions = { + argsRequired: boolean + caseInsensitive: boolean + deleteCommand: boolean + guildOnly: boolean + dmOnly: boolean + description: string + fullDescription: string + usage: string + example: string + hidden: boolean + requirements: { + userIDs: string[], roleNames: string[], custom: Function, permissions: {}, roleIDs: string[] + } +} export type FalseUser = { id: string, username: string, discriminator: string } export type DB = {