Merge pull request #54 from Trivernis/develop

Beta v0.11.0
pull/110/head^2
Trivernis 6 years ago committed by GitHub
commit e52197ce17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,6 +4,21 @@ All notable changes to the discord bot will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- template Files to name `template.yaml`
- loading template file form CommandModule property `templateFile` to loading the `template.yaml` file from the `_templateDir` property (still supporting loading form templateFile)
- ExtendedRichEmbed checks if fields are empty again after replacing values
### Added
- `.template` to commands as a template for a command module with help comments
- *METADATA* property to `template.yaml` files that is used as an anchor for shared command metadata (like `category`)
- `CommandModule` **Misc** with command that are not really fitting into any other module
- option to query this CHANGELOG with `_changes [version]` and `_versions` in the `CommandModule` **Info**
### Removed
- `ExtendedRichEmbed.addNonemptyField` because the overide of `.addField` does the same
## [0.10.1] - 2019-03-03 ## [0.10.1] - 2019-03-03
### Changed ### Changed
- Bugfix on RichEmbed not returning itself on addField and setDescription because of method overide - Bugfix on RichEmbed not returning itself on addField and setDescription because of method overide

@ -86,6 +86,7 @@ class Bot {
messageHandler: this.messageHandler, messageHandler: this.messageHandler,
config: config config: config
}); });
await this.messageHandler.registerCommandModule(require('./lib/commands/MiscCommands').module, {});
this.registerEvents(); this.registerEvents();
} }

@ -187,13 +187,17 @@ class CommandModule {
} }
/** /**
* Loads a template for the object property templateFile or the given argument file. * Loads a template for the module from the this._templateDir directory.
* Loads the template from this.templateFile if the attribute exists.
* @param dir {String} Overides the this._templateDir with this directory.
* @returns {Promise<void>} * @returns {Promise<void>}
* @private * @private
*/ */
async _loadTemplate(file) { async _loadTemplate(dir) {
let templateString = await fsx.readFile(this.templateFile || file, {encoding: 'utf-8'}); if (!this.templateFile)
this._logger.silly(`Loaded Template file ${this.templateFile || file}`); this.templateFile = (dir || this._templateDir) + '/template.yaml';
let templateString = await fsx.readFile(this.templateFile, {encoding: 'utf-8'});
this._logger.silly(`Loaded Template file ${this.templateFile}`);
this.template = yaml.safeLoad(templateString); this.template = yaml.safeLoad(templateString);
} }
@ -219,18 +223,6 @@ class ExtendedRichEmbed extends Discord.RichEmbed {
this.setTimestamp(); this.setTimestamp();
} }
/**
* Adds a Field when a name is given or adds a blank Field otherwise
* @param name {String}
* @param content {String}
* @returns {ExtendedRichEmbed}
*/
addNonemptyField(name, content) {
if (name && name.length > 0 && content && content.length > 0)
this.addField(name, content);
return this;
}
/** /**
* Adds the fields defined in the fields JSON * Adds the fields defined in the fields JSON
* @param fields {JSON} * @param fields {JSON}
@ -238,7 +230,7 @@ class ExtendedRichEmbed extends Discord.RichEmbed {
*/ */
addFields(fields) { addFields(fields) {
for (let [name, value] of Object.entries(fields)) for (let [name, value] of Object.entries(fields))
this.addNonemptyField(name, value); this.addField(name, value);
return this; return this;
} }
@ -252,6 +244,7 @@ class ExtendedRichEmbed extends Discord.RichEmbed {
croppedValue = value.substring(0, 1024); croppedValue = value.substring(0, 1024);
if (croppedValue.length < value.length) if (croppedValue.length < value.length)
croppedValue = croppedValue.replace(/\n.*$/g, ''); croppedValue = croppedValue.replace(/\n.*$/g, '');
if (croppedValue && croppedValue.replace(/\n/g, '').length > 0)
super.setDescription(croppedValue); super.setDescription(croppedValue);
return this; return this;
} }
@ -267,7 +260,10 @@ class ExtendedRichEmbed extends Discord.RichEmbed {
croppedValue = value.substring(0, 1024); croppedValue = value.substring(0, 1024);
if (croppedValue.length < value.length) if (croppedValue.length < value.length)
croppedValue = croppedValue.replace(/\n.*$/g, ''); croppedValue = croppedValue.replace(/\n.*$/g, '');
if (name && croppedValue
&& croppedValue.replace(/\n/g, '').length > 0 && name.replace(/\n/g, '').length > 0)
super.addField(name, croppedValue); super.addField(name, croppedValue);
return this; return this;
} }
} }

@ -0,0 +1,45 @@
/* template index.js. Doesn't implement actual commands */
const cmdLib = require('../../CommandLib'); // required for command objects
/**
* A description what the command module includes and why. Doesn't need to list commands but explains
* category of the defined commands aswell as the scope.
*/
class TemplateCommandModule extends cmdLib.CommandModule {
/**
* @param opts {Object} properties: --- define the properties the opts object needs aswell as the type
* bot - the instance of the bot
*/
constructor(opts) {
super(cmdLib.CommandScopes.Global); // call constructor of superclass with the scope of the module
this._templateDir = __dirname; // define the current directory as directory for the template.yaml file
this._bot = opts.bot; // define opts attributes as private properties of the module class
}
/**
* Defines and registers commands to the commandHandler.
* @param commandHandler {CommandHandler}
*/
async register(commandHandler) {
await this._loadTemplate(); // loads the template file to the property this.template.
let templateCommand = new cmdLib.Command( // create a new instance of Command
this.template.template_command, // pass the template to the constructor
new cmdLib.Answer(() => { // pass a new instance of Answer to the constructor
/* Command Logic */
return this.template.response.not_implemented; // this command just returns the answer not_implemented
})
);
// register the commands on the commandHandler
commandHandler.registerCommand(templateCommand); // register the command to the handler
}
}
// set the export properties
Object.assign(exports, {
module: TemplateCommandModule // Export the commandModule as module property. This is the default.
});

@ -0,0 +1,16 @@
# see yaml references (learnxinyminutes.com/docs/yaml/)
METADATA: &METADATA
category: template # [optional if defined in commands]
permission: all # [optional if defined in commands]
template_command:
<<: *METADATA # include the predefined metadata for the command
name: templateCommand # [required] the name of the command for execution
usage: _templateCommand [templateArg] # [optional] overides the default help that generates from name and args
permission: owner # [optional if in METADATA] overiedes the metadata value for permission
description: > # [required] the description entry for the command help.
A template for a command
response: # [optional] predefine responses that can be used in the command logic
not_implemented: >
This command is not implemented.

@ -1,6 +1,5 @@
const cmdLib = require('../../CommandLib'), const cmdLib = require('../../CommandLib'),
anilistApi = require('../../api/AnilistApi'), anilistApi = require('../../api/AnilistApi');
location = './lib/commands/AnilistApiCommands';
/** /**
* The AniList commands are all commands that interact with the anilist api. * The AniList commands are all commands that interact with the anilist api.
@ -169,7 +168,7 @@ class AniListCommandModule extends cmdLib.CommandModule {
constructor() { constructor() {
super(cmdLib.CommandScopes.Global); super(cmdLib.CommandScopes.Global);
this.templateFile = location + '/AniListCommandsTemplate.yaml'; this._templateDir = __dirname;
this.template = null; this.template = null;
} }

@ -1,58 +1,57 @@
METADATA: &METADATA
category: AniList
permission: all
anime_search: anime_search:
<<: *METADATA
name: alAnime name: alAnime
permission: all
usage: alAnime [search query] usage: alAnime [search query]
description: > description: >
Searches [AniList.co](https://anilist.co) for the anime *title* or *id* and returns information about Searches [AniList.co](https://anilist.co) for the anime *title* or *id* and returns information about
it if there is a result. The staff members are not included because the message would grow too big. it if there is a result. The staff members are not included because the message would grow too big.
category: AniList
response: response:
not_found: > not_found: >
I couldn't find the anime you were searching for :( I couldn't find the anime you were searching for :(
anime_staff_search: anime_staff_search:
<<: *METADATA
name: alAnimeStaff name: alAnimeStaff
permission: all
usage: alAnimeStaff [search query] usage: alAnimeStaff [search query]
description: > description: >
Searches [AniList.co](https://anilist.co) for the anime *title* or *id* and returns all staff members. Searches [AniList.co](https://anilist.co) for the anime *title* or *id* and returns all staff members.
category: AniList
response: response:
not_found: > not_found: >
I couldn't find the anime you were searching for :( I couldn't find the anime you were searching for :(
manga_search: manga_search:
<<: *METADATA
name: alManga name: alManga
permission: all
usage: alManga [search query] usage: alManga [search query]
description: > description: >
Searches [AniList.co](https://anilist.co) for the manga *title* or *id* and returns information about Searches [AniList.co](https://anilist.co) for the manga *title* or *id* and returns information about
it if there is a result. it if there is a result.
category: AniList
response: response:
not_found: > not_found: >
I couldn't find the manga you were searching for :( I couldn't find the manga you were searching for :(
staff_search: staff_search:
<<: *METADATA
name: alStaff name: alStaff
permission: all
usage: alStaff [search query] usage: alStaff [search query]
description: > description: >
Searches [AniList.co](https://anilist.co) for the staff member *name* or *id* and returns information about Searches [AniList.co](https://anilist.co) for the staff member *name* or *id* and returns information about
the member aswell as roles in media. the member aswell as roles in media.
category: AniList
response: response:
not_found: > not_found: >
I couldn't find the staff member you were searching for :( I couldn't find the staff member you were searching for :(
character_search: character_search:
<<: *METADATA
name: alCharacter name: alCharacter
permission: all
usage: alCharacter [search query] usage: alCharacter [search query]
description: > description: >
Searches [AniList.co](https://anilist.co) for the character *name* or *id* and returns information about Searches [AniList.co](https://anilist.co) for the character *name* or *id* and returns information about
the character aswell as media roles. the character aswell as media roles.
category: AniList
response: response:
not_found: > not_found: >
I couldn't find the character member you were searching for :( I couldn't find the character member you were searching for :(

@ -1,6 +1,6 @@
const cmdLib = require('../../CommandLib'), const cmdLib = require('../../CommandLib'),
utils = require('../../utils'), fsx = require('fs-extra'),
location = './lib/commands/InfoCommands'; utils = require('../../utils');
/** /**
* Info commands provide information about the bot. These informations are * Info commands provide information about the bot. These informations are
@ -16,7 +16,7 @@ class InfoCommandModule extends cmdLib.CommandModule {
*/ */
constructor(opts) { constructor(opts) {
super(cmdLib.CommandScopes.Global); super(cmdLib.CommandScopes.Global);
this.templateFile = location + '/InfoCommandsTemplate.yaml'; this._templateDir = __dirname;
this._client = opts.client; this._client = opts.client;
this._messageHandler = opts.messageHandler; this._messageHandler = opts.messageHandler;
} }
@ -43,8 +43,58 @@ class InfoCommandModule extends cmdLib.CommandModule {
return helpEmbed; return helpEmbed;
} }
async _loadChangelog() {
try {
let changelog = (await fsx.readFile('CHANGELOG.md', {encoding: 'utf-8'})).replace(/\r\n/g, '\n');
let entries = changelog.split(/\n## /);
let changes = {};
let latestVersion = null;
this._logger.debug(`Found ${entries.length} changelog entries`);
for (let entry of entries) {
let title = '';
let version = '';
let date = '';
let titleMatch = entry.match(/^.*?\n/g);
if (titleMatch && titleMatch.length > 0)
title = titleMatch[0].replace(/\n/, '');
let versionMatch = title.match(/\[.*?]/);
if (versionMatch && versionMatch.length > 0)
version = versionMatch[0].replace(/^\[|]$/g, '');
if (!latestVersion && version && version.length > 0)
latestVersion = version;
let dateMatch = title.match(/\d{4}-\d{2}-\d{2}/);
if (version && version.length > 0) {
changes[version] = {
date: date,
title: title,
segments: {}
};
if (dateMatch && dateMatch.length > 0)
date = dateMatch[0];
let segments = entry.replace(title.replace(/\n/, ''), '').split(/\n### /);
for (let segment of segments) {
let segmentTitle = '';
let titleMatch = segment.match(/^.*?\n/);
if (titleMatch && titleMatch.length > 0)
segmentTitle = titleMatch[0].replace(/\n/, '');
changes[version].segments[segmentTitle] = segment.replace(segmentTitle, '');
}
}
}
changes.latest = changes[latestVersion];
this._changes = changes;
} catch (err) {
this._logger.warn(err.message);
this._logger.debug(err.stack);
}
}
async register(commandHandler) { async register(commandHandler) {
await this._loadTemplate(); await this._loadTemplate();
await this._loadChangelog();
let about = new cmdLib.Command( let about = new cmdLib.Command(
this.template.about, this.template.about,
@ -99,13 +149,52 @@ class InfoCommandModule extends cmdLib.CommandModule {
}) })
); );
let changes = new cmdLib.Command(
this.template.changes,
new cmdLib.Answer((m, k) => {
try {
if (!k.version)
return new cmdLib.ExtendedRichEmbed(this._changes.latest.title)
.addFields(this._changes.latest.segments)
.setColor(this.template.changes.embed_color)
.attachFile('CHANGELOG.md');
else
return new cmdLib.ExtendedRichEmbed(this._changes[k.version].title)
.addFields(this._changes[k.version].segments)
.setColor(this.template.changes.embed_color)
.attachFile('CHANGELOG.md');
} catch (err) {
this._logger.verbose(err.message);
this._logger.silly(err.stack);
return this.template.changes.response.not_found;
}
})
);
let versions = new cmdLib.Command(
this.template.versions,
new cmdLib.Answer(() => {
try {
return new cmdLib.ExtendedRichEmbed('CHANGELOG.md Versions')
.setDescription(Object.keys(this._changes).join('\n'))
.setColor(this.template.versions.embed_color);
} catch (err) {
this._logger.verbose(err.message);
this._logger.silly(err.stack);
return this.template.versions.response.not_found;
}
})
);
// register commands // register commands
commandHandler commandHandler
.registerCommand(about) .registerCommand(about)
.registerCommand(ping) .registerCommand(ping)
.registerCommand(uptime) .registerCommand(uptime)
.registerCommand(guilds) .registerCommand(guilds)
.registerCommand(help); .registerCommand(help)
.registerCommand(changes)
.registerCommand(versions);
} }
} }

@ -1,9 +1,12 @@
METADATA: &METADATA
category: Info
permission: all
about: about:
<<: *METADATA
name: about name: about
description: > description: >
Shows information about this Discord Bot. Shows information about this Discord Bot.
permission: all
category: Info
response: response:
about_icon: | about_icon: |
This icon war created by [blackrose14344](https://www.deviantart.com/blackrose14344). This icon war created by [blackrose14344](https://www.deviantart.com/blackrose14344).
@ -13,32 +16,50 @@ about:
More about this bot [here](https://github.com/Trivernis/discordbot.js). More about this bot [here](https://github.com/Trivernis/discordbot.js).
ping: ping:
<<: *METADATA
name: ping name: ping
description: > description: >
Answers with the current average ping of the bot. Answers with the current average ping of the bot.
permission: all
category: Info
uptime: uptime:
<<: *METADATA
name: uptime name: uptime
description: > description: >
Answers with the uptime of the bot. Answers with the uptime of the bot.
permission: all
category: Info
guilds: guilds:
<<: *METADATA
name: guilds name: guilds
description: > description: >
Answers with the number of guilds the bot has joined Answers with the number of guilds the bot has joined
permission: owner permission: owner
category: Info
help: help:
<<: *METADATA
name: help name: help
description: > description: >
Shows help for bot ocmmands. Shows help for bot ocmmands.
permission: all
category: Info
embed_color: 0xffffff embed_color: 0xffffff
args: args:
- command - command
changes:
<<: *METADATA
name: changes
description: >
Shows the changes of the current release or a specific previous.
embed_color: 0xaabbcc
args:
- version
response:
not_found: >
I could not find the changelog for the version you were looking for.
versions:
<<: *METADATA
name: versions
description: >
Shows all versions present in the CHANGELOG.
embed_color: 0xaabbcc
response:
not_found: >
I could not find any versions.

@ -0,0 +1,82 @@
/* template index.js. Doesn't implement actual commands */
const cmdLib = require('../../CommandLib');
/**
* Several commands that are that special that they can't be included in any other module.
*/
/**
* Async delay
* @param seconds {Number}
*/
function delay(seconds) {
return new Promise((resolve) => {
setTimeout(resolve, seconds * 1000);
});
}
class TemplateCommandModule extends cmdLib.CommandModule {
constructor() {
super(cmdLib.CommandScopes.Global);
this._templateDir = __dirname;
}
/**
* Defines and registers commands to the commandHandler.
* @param commandHandler {CommandHandler}
*/
async register(commandHandler) {
await this._loadTemplate();
let sayCommand = new cmdLib.Command(
this.template.say,
new cmdLib.Answer((m, k, s) => {
return s.replace(/^"|"$/g, '');
})
);
let delayCommand = new cmdLib.Command(
this.template.delay,
new cmdLib.Answer(async (m, k) => {
this._logger.silly(`Delaying for ${k.seconds} seconds`);
await delay(k.seconds);
})
);
let chooseCommand = new cmdLib.Command(
this.template.choose,
new cmdLib.Answer(async (m, k, s) => {
let options = s.split(',').map(x => {
if (x) {
let strippedValue = x.replace(/^\s+|\s+$/, '');
if (strippedValue.length === 0)
return null;
else
return strippedValue;
} else {
return null;
}
}).filter(x => x);
if (options.length === 0) {
return this.template.choose.response.no_options;
} else {
this._logger.silly(`Choosing from ${options.join(', ')}`);
let item = options[Math.floor(Math.random() * options.length)];
return `I've chosen ${item.replace(/^"|"$|^\s+|\s+$/g, '')}`;
}
})
);
/* Register commands to handler */
commandHandler
.registerCommand(sayCommand)
.registerCommand(delayCommand)
.registerCommand(chooseCommand);
}
}
Object.assign(exports, {
module: TemplateCommandModule
});

@ -0,0 +1,29 @@
METADATA: &METADATA
category: Misc
permission: all
say:
<<: *METADATA
name: say
usage: say [...message]
description: >
The bot says what you defined in the message argument
delay:
<<: *METADATA
name: delay
usage: delay
args:
- seconds
description: >
Set a delay in seconds. Useful for command sequences.
choose:
<<: *METADATA
name: choose
usage: choose [opt-1], [opt-2], ..., [opt-n]
description: >
Chooses randomly from one of the options
response:
no_options: >
You need to define options for me to choose from.

@ -1,7 +1,6 @@
const cmdLib = require('../../CommandLib'), const cmdLib = require('../../CommandLib'),
utils = require('../../utils'), utils = require('../../utils'),
config = require('../../../config'), config = require('../../../config');
location = './lib/commands/MusicCommands';
function checkPermission(msg, rolePerm) { function checkPermission(msg, rolePerm) {
if (!rolePerm || ['all', 'any', 'everyone'].includes(rolePerm)) if (!rolePerm || ['all', 'any', 'everyone'].includes(rolePerm))
@ -27,7 +26,7 @@ class MusicCommandModule extends cmdLib.CommandModule {
*/ */
constructor(opts) { constructor(opts) {
super(cmdLib.CommandScopes.Guild); super(cmdLib.CommandScopes.Guild);
this.templateFile = location + '/MusicCommandsTemplate.yaml'; this._templateDir = __dirname;
this._getGuildHandler = opts.getGuildHandler; this._getGuildHandler = opts.getGuildHandler;
} }

@ -1,9 +1,12 @@
METADATA: &METADATA
category: Music
permission: all
play: play:
<<: *METADATA
name: play name: play
description: > description: >
Adds the url to the YouTube video or YouTube playlist into the queue. Adds the url to the YouTube video or YouTube playlist into the queue.
permission: all
category: Music
args: args:
- url - url
response: response:
@ -19,12 +22,11 @@ play:
You need to join a VoiceChannel to request media playback. You need to join a VoiceChannel to request media playback.
play_next: play_next:
<<: *METADATA
name: playnext name: playnext
description: > description: >
Adds the url to the YouTube video or YouTube playlist into the queue as Adds the url to the YouTube video or YouTube playlist into the queue as
next playing song. next playing song.
permission: all
category: Music
args: args:
- url - url
response: response:
@ -40,21 +42,19 @@ play_next:
You need to join a VoiceChannel to request media playback. You need to join a VoiceChannel to request media playback.
join: join:
<<: *METADATA
name: join name: join
description: > description: >
Joins the VoiceChannel you are in. Joins the VoiceChannel you are in.
permission: all
category: Music
response: response:
no_voicechannel: > no_voicechannel: >
You need to join a VoiceChannel for me to join. You need to join a VoiceChannel for me to join.
stop: stop:
<<: *METADATA
name: stop name: stop
description: > description: >
Stops the media playback and leaves the VoiceChannel. Stops the media playback and leaves the VoiceChannel.
permission: all
category: Music
response: response:
success: > success: >
Stopped music playback. Stopped music playback.
@ -62,11 +62,10 @@ stop:
I'm not playing music at the moment. What do you want me to stop? I'm not playing music at the moment. What do you want me to stop?
pause: pause:
<<: *METADATA
name: pause name: pause
description: > description: >
Pauses the media playback. Pauses the media playback.
permission: all
category: Music
response: response:
success: > success: >
Paused playback. Paused playback.
@ -74,11 +73,10 @@ pause:
I'm not playing music at the moment. I'm not playing music at the moment.
resume: resume:
<<: *METADATA
name: resume name: resume
description: > description: >
Resumes the media playback. Resumes the media playback.
permission: all
category: Music
response: response:
success: > success: >
Resumed playback. Resumed playback.
@ -86,11 +84,10 @@ resume:
I'm not playing music at the moment. I'm not playing music at the moment.
skip: skip:
<<: *METADATA
name: skip name: skip
description: > description: >
Skips the currently playing song. Skips the currently playing song.
permission: all
category: Music
response: response:
success: > success: >
Skipped to the next song. Skipped to the next song.
@ -98,48 +95,44 @@ skip:
I'm not playing music at the moment. I'm not playing music at the moment.
clear: clear:
<<: *METADATA
name: clear name: clear
description: > description: >
Clears the media queue. Clears the media queue.
permission: musicPlayer permission: dj
category: Music
response: response:
success: > success: >
The media queue has been cleared. The media queue has been cleared.
media_queue: media_queue:
<<: *METADATA
name: queue name: queue
descriptions: > descriptions: >
Shows the next ten songs in the media queue. Shows the next ten songs in the media queue.
permission: all
category: Music
media_current: media_current:
<<: *METADATA
name: np name: np
description: > description: >
Shows the currently playing song. Shows the currently playing song.
permission: all
category: Music
response: response:
not_playing: > not_playing: >
I'm not playing music at the moment. I'm not playing music at the moment.
shuffle: shuffle:
<<: *METADATA
name: shuffle name: shuffle
description: > description: >
Shuffles the media queue Shuffles the media queue
permission: all
category: Music
response: response:
success: > success: >
The queue has been shuffled. The queue has been shuffled.
toggle_repeat: toggle_repeat:
<<: *METADATA
name: repeat name: repeat
description: > description: >
Toggles listening o repeat. Toggles listening o repeat.
permission: all
category: Music
response: response:
repeat_true: > repeat_true: >
Listening on repeat now! Listening on repeat now!
@ -147,32 +140,31 @@ toggle_repeat:
Not listening on repeat anymore. Not listening on repeat anymore.
save_media: save_media:
<<: *METADATA
name: savemedia name: savemedia
description: > description: >
Saves the YouTube URL with a specific name. Saves the YouTube URL with a specific name.
permission: dj permission: dj
category: Music
args: args:
- url - url
usage: savemedia [url] [name...] usage: savemedia [url] [name...]
delete_media: delete_media:
<<: *METADATA
name: deletemedia name: deletemedia
description: > description: >
Deletes a saved YouTube URL from saved media. Deletes a saved YouTube URL from saved media.
permission: dj permission: dj
category: Music
usage: deletemedia [name] usage: deletemedia [name]
response: response:
no_name: > no_name: >
You must provide a name for the media to delete. You must provide a name for the media to delete.
saved_media: saved_media:
<<: *METADATA
name: savedmedia name: savedmedia
description: > description: >
Shows all saved YouTube URLs. Shows all saved YouTube URLs.
permission: all
category: Music
response: response:
no_saved: > no_saved: >
There are no saved YouTube URLs :( There are no saved YouTube URLs :(

@ -1,5 +1,4 @@
const cmdLib = require('../../CommandLib'), const cmdLib = require('../../CommandLib');
location = './lib/commands/ServerUtilityCommands';
/** /**
* This command module includes utility commands for the server. * This command module includes utility commands for the server.
@ -14,7 +13,7 @@ class ServerUtilityCommandModule extends cmdLib.CommandModule {
*/ */
constructor(opts) { constructor(opts) {
super(cmdLib.CommandScopes.Guild); super(cmdLib.CommandScopes.Guild);
this.templateFile = location + '/ServerUtilityCommandsTemplate.yaml'; this._templateDir = __dirname;
this._messageHandler = opts.messageHandler; this._messageHandler = opts.messageHandler;
this._getGuildHandler = opts.getGuildHandler; this._getGuildHandler = opts.getGuildHandler;
this._config = opts.config; this._config = opts.config;

@ -1,9 +1,13 @@
METADATA: &METADATA
category: Server Utility
permission: all
save_cmd: save_cmd:
<<: *METADATA
name: savecmd name: savecmd
description: > description: >
Saves a sequence of commands under a new name. Saves a sequence of commands under a new name.
permission: moderator permission: moderator
category: Server Utility
usage: savecmd [cmdname] [cmdsequence] usage: savecmd [cmdname] [cmdsequence]
args: args:
- name - name
@ -17,30 +21,28 @@ save_cmd:
This sequence executes too long serial chains. This sequence executes too long serial chains.
delete_cmd: delete_cmd:
<<: *METADATA
name: deletecmd name: deletecmd
description: > description: >
Deletes a saved command. Deletes a saved command.
permission: moderator permission: moderator
category: Server Utility
args: args:
- name - name
saved_cmd: saved_cmd:
<<: *METADATA
name: savedcmd name: savedcmd
description: > description: >
Lists all saved commands. Lists all saved commands.
category: Server Utility
permission: all
response: response:
no_commands: > no_commands: >
There are no saved commands. There are no saved commands.
execute: execute:
<<: *METADATA
name: execute name: execute
description: > description: >
Executes a saved command. Executes a saved command.
permission: all
category: Server Utility
args: args:
- name - name
response: response:

@ -1,5 +1,4 @@
const cmdLib = require('../../CommandLib'), const cmdLib = require('../../CommandLib');
location = './lib/commands/UtilityCommands';
/** /**
* Utility commands are all commands that allow the user to control the behaviour of the * Utility commands are all commands that allow the user to control the behaviour of the
@ -18,7 +17,7 @@ class UtilityCommandModule extends cmdLib.CommandModule {
*/ */
constructor(opts) { constructor(opts) {
super(cmdLib.CommandScopes.User); super(cmdLib.CommandScopes.User);
this.templateFile = location + '/UtilityCommandsTemplate.yaml'; this._templateDir = __dirname;
this._bot = opts.bot; this._bot = opts.bot;
this._config = opts.config; this._config = opts.config;
} }

@ -1,42 +1,42 @@
METADATA: &METADATA
category: Utility
permission: owner
shutdown: shutdown:
<<: *METADATA
name: shutdown name: shutdown
description: > description: >
Shuts down the bot. Shuts down the bot.
permission: owner
category: Utility
add_presence: add_presence:
<<: *METADATA
name: addpresence name: addpresence
description: > description: >
Adds a Rich Presence to the bot. Adds a Rich Presence to the bot.
permission: owner
category: Utility
usage: addpresence [presence] usage: addpresence [presence]
rotate_presence: rotate_presence:
<<: *METADATA
name: rotatepresence name: rotatepresence
description: > description: >
Forces a presence rotation Forces a presence rotation
permission: owner
category: Utility
create_user: create_user:
<<: *METADATA
name: createuser name: createuser
description: > description: >
Creates a user for the webinterface. Creates a user for the webinterface.
permission: owner
category: Utility
args: args:
- username - username
- password - password
- scope - scope
bugreport: bugreport:
<<: *METADATA
name: bug name: bug
permission: all
description: > description: >
Get information about where to report bugs. Get information about where to report bugs.
permission: all
category: Utility
response: response:
title: > title: >
You want to report a bug? You want to report a bug?
Loading…
Cancel
Save