-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #109 from reactivepixel/dev
1.4.0 Release: Controller Refactor
- Loading branch information
Showing
10 changed files
with
494 additions
and
408 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class BaseCommand { | ||
constructor( | ||
command, example, title, | ||
description, action, responseType = 'reply', | ||
adminOnly = false, showWithHelp = true, allowInDM = false, | ||
) { | ||
this.command = command; | ||
this.example = example; | ||
this.title = title; | ||
this.description = description; | ||
this.showWithHelp = showWithHelp; | ||
this.allowInDM = allowInDM; | ||
this.adminOnly = adminOnly; | ||
this.responseType = responseType; | ||
this.action = action; | ||
} | ||
} | ||
module.exports = BaseCommand; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const util = require('apex-util'); | ||
const { isAdmin } = require('./botUtils.js'); | ||
|
||
class BaseController { | ||
constructor(message) { | ||
// Add middleware to saved message | ||
this.message = BaseController.messageMiddleware(message); | ||
this.commands = []; | ||
} | ||
|
||
// Add extra information to message object | ||
static messageMiddleware(message) { | ||
// Creates an empty object container | ||
const messageContainer = {}; | ||
// Tokenizes the message by space characters, adds to container | ||
messageContainer.parsed = message.content.split(' '); | ||
// Adds message object to container | ||
return Object.assign(message, messageContainer); | ||
} | ||
|
||
onSuccess(commandResponse, command) { | ||
if (commandResponse !== null) { | ||
// Determine how to respond to message | ||
if (command.responseType === 'reply') { | ||
return this.message.reply(commandResponse); | ||
} else if (command.responseType === 'dm') { | ||
return this.message.author.send(commandResponse); | ||
} | ||
} | ||
// Fail safe | ||
return false; | ||
} | ||
|
||
onError(errorMessage = 'I Broke... Beep...Boop...Beep') { | ||
return this.message.reply(errorMessage); | ||
} | ||
|
||
// Execute the command's functionality | ||
run() { | ||
// Loop through each command and map to key | ||
util.log('Looping through controller commands', 0); | ||
Object.keys(this.commands).map((key) => { | ||
// If command matches message | ||
if (this.message.parsed[0].toLowerCase() === this.commands[key].command.toLowerCase()) { | ||
util.log('Matching command found', this.commands[key].command, 2); | ||
|
||
// If user messages the bot a channel-only command | ||
if (!this.commands[key].allowInDM && !this.message.guild) { | ||
return this.onError('Please don\'t use this command directly. Instead use it in a channel on a server. :beers:'); | ||
} | ||
|
||
// If non-admin enters admin command | ||
if (this.commands[key].adminOnly && !isAdmin(this.message.member)) { | ||
return this.onError('You don\'t have permissions to run this command.'); | ||
} | ||
|
||
// Execute command's action | ||
const commandResponse = this.commands[key].action(); | ||
// Handle if command responds or breaks | ||
if (commandResponse) { | ||
this.onSuccess(commandResponse, this.commands[key]); | ||
} else { | ||
this.onError(); | ||
} | ||
} | ||
return this.commands[key]; | ||
}); | ||
} | ||
} | ||
module.exports = BaseController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
exports.generateCode = (n) => { | ||
// Workaround method for Math.pow() and ** operator | ||
const pow = (base, exp) => { | ||
let result = 1; | ||
for (let i = 0; i < exp; i += 1) { | ||
result *= base; | ||
} | ||
return result; | ||
}; | ||
const add = 1; | ||
let max = 12 - add; | ||
let min = 0; | ||
if (n > max) { | ||
return this.generateCode(max) + this.generateCode(n - max); | ||
} | ||
max = pow(10, n + add); | ||
min = max / 10; | ||
const number = Math.floor(Math.random() * (max - (min + 1))) + min; | ||
return ('' + number).substring(add); | ||
}; | ||
|
||
// Checks if person is an admin user, use GuildMember object | ||
exports.isAdmin = (member) => { | ||
const adminRoles = [ | ||
'Admin', 'Armada Officers', 'Armada Officer', 'Fleet Officer', | ||
'Moderator', 'Tester', | ||
]; | ||
if (adminRoles.some(role => member.roles.find('name', role))) { | ||
return true; | ||
} | ||
return false; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,58 @@ | ||
const Discord = require('discord.js'); | ||
const util = require('apex-util'); | ||
const { isAdmin } = require('./botUtils.js'); | ||
|
||
// If Production server default Debug mode to Production Setting | ||
// If production server, set default debug mode to production setting | ||
if (process.env.NODE_ENV === 'production' && !process.env.DEBUG_MODE) process.env.DEBUG_MODE = 0; | ||
|
||
const client = new Discord.Client(); | ||
|
||
// Pre Load Controllers | ||
const ctrls = require('./controllers')(); | ||
// Pre-load controllers | ||
const controllers = require('./controllers')(); | ||
|
||
// Alert when ready | ||
client.on('ready', () => { | ||
util.log('Bot Online and Ready!', 0); | ||
util.log('Bot Online and Ready', 0); | ||
}); | ||
|
||
// Listen for messages | ||
client.on('message', (message) => { | ||
// Check for ! Prefix on message to ensure it is a command | ||
// Check for ! prefix on message to ensure it is a command | ||
if (message.content.charAt(0) === '!') { | ||
util.log('!Cmd Message Received', message.content, 0); | ||
util.log('Command message received', message.content, 0); | ||
|
||
const ctrlResponses = []; | ||
// Build basic help string | ||
let helpString = 'v1.4.0 Discovered Commands:\n\n\t**<> - Required Item\t\t[] - Optional Item**'; | ||
|
||
// Process message against every controller | ||
Object.keys(ctrls).forEach((ctrlKey) => { | ||
if (ctrlKey) { | ||
// initialize the controller | ||
const ctrlInstance = ctrls[ctrlKey](); | ||
|
||
// Determine the method names of each controller | ||
const controllerMethodKeys = Object.keys(ctrlInstance); | ||
util.log('Methods found in controller', controllerMethodKeys, 3); | ||
|
||
// For each method on each controller | ||
Object.keys(controllerMethodKeys).forEach((controllerMethodKey) => { | ||
const methodName = controllerMethodKeys[controllerMethodKey]; | ||
const method = ctrlInstance[methodName]; | ||
|
||
util.log('Looping Through Each Method within each Controller', method, 4); | ||
|
||
// Pass the message to each method of each controller | ||
ctrlResponses.push(method(message)); | ||
Object.keys(controllers).forEach((key) => { | ||
// Instantiate the controller | ||
const controllerInstance = new controllers[key](message); | ||
util.log('Controller instance', controllerInstance, 5); | ||
// Runs commands after constructor is called | ||
controllerInstance.run(); | ||
|
||
// Loop through commands if help command and add to string | ||
if (message.content.toLowerCase() === '!help') { | ||
Object.keys(controllerInstance.commands).forEach((commandKey) => { | ||
const commandInstance = controllerInstance.commands[commandKey]; | ||
// Check if command should be shown in help menu | ||
if (commandInstance.showWithHelp) { | ||
if (commandInstance.adminOnly && isAdmin(message.member)) { | ||
helpString += `\n\n \`${commandInstance.example}\` **- Admin Only** \n\t ${commandInstance.description}`; | ||
} else if (commandInstance.adminOnly && !isAdmin(message.member)) { | ||
helpString += ''; | ||
} else { | ||
helpString += `\n\n \`${commandInstance.example}\` \n\t ${commandInstance.description}`; | ||
} | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
// TODO: Improve help message | ||
// If help command called, display string | ||
if (message.content.toLowerCase() === '!help') { | ||
message.reply('v1.3.2 Discovered Commands: \n `!roles` \n\t List all Armada Roles \n\n `!addRole` RoleName \n\t Adds yourself to a role and the related text/voice rooms. \n\n `!removeRole` RoleName \n\t Removes a role from yourself. \n\n `!addAllRoles` \n\t Add all roles to yourself. \n\n `!removeAllRoles` \n\t Remove all roles from yourself. \n\n `!verify [email protected]` \n\t Self verify that you are a Full Sail Student / Alumni via your Full Sail email account.'); | ||
message.reply(helpString); | ||
} | ||
} | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
const BaseController = require('../baseController.js'); | ||
const Command = require('../baseCommand.js'); | ||
const util = require('apex-util'); | ||
|
||
class ChannelController extends BaseController { | ||
constructor(message) { | ||
super(message); | ||
const controller = this; | ||
this.commands = [ | ||
new Command( | ||
'!channels', | ||
'!channels', | ||
'List All Channels', | ||
'List all available Armada channels.', | ||
this.channelsAction.bind(controller), | ||
'dm', | ||
), | ||
new Command( | ||
'!announce', | ||
'!announce <channel_name>,[channel_name] <message>', | ||
'Announce To Channels', | ||
'Broadcast to multiple channels. Channels are case-sensitive.', | ||
this.announceAction.bind(controller), | ||
'reply', | ||
true, | ||
), | ||
]; | ||
} | ||
|
||
channelsAction() { | ||
const { message } = this; | ||
const channels = []; | ||
message.guild.channels.map(channel => channels.push(channel.name)); | ||
return 'List of all Armada Channels: \n\n' + channels.join('\n'); | ||
} | ||
|
||
announceAction() { | ||
const { message } = this; | ||
const channels = message.parsed[1].split(','); | ||
util.log('Multiple Channels Parsing', channels, 4); | ||
|
||
channels.map((channel) => { | ||
const targetChannel = message.guild.channels.find('name', channel); | ||
const sender = message.author.username; | ||
util.log('Asking API for Channel', targetChannel, 4); | ||
|
||
if (targetChannel === null) { | ||
return '"' + channel + '" is not a known channel. Try `!channels` to get a list of all Channels (They are case-sensitive)'; | ||
} | ||
|
||
// Set parsed value to 2 for message. | ||
let msgParsedIndex = 2; | ||
let preparedMessage = ''; | ||
|
||
// Loop through/join user message by space until end. | ||
while (msgParsedIndex < message.parsed.length) { | ||
// Add spaces after first word | ||
if (msgParsedIndex !== 2) { | ||
preparedMessage += ' '; | ||
} | ||
preparedMessage += message.parsed[msgParsedIndex]; | ||
msgParsedIndex += 1; | ||
} | ||
return targetChannel.send(sender + ' has an announcment: ```' + preparedMessage + '```'); | ||
}); | ||
|
||
return 'Broadcast sent!'; | ||
} | ||
} | ||
|
||
module.exports = ChannelController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.