Skip to content
This repository has been archived by the owner on Aug 28, 2020. It is now read-only.

Commit

Permalink
v1.0.0-alpha (#696)
Browse files Browse the repository at this point in the history
* initial teams support (#692)

* initial teams support

* update typings

* whoops

* whoops v2

* Add Monitor#allowedTypes (#695)

Limits messages based on the Message#type

* remove client from Piece constructors (#689)

* remove client from Piece constructors

* typings

* Add Monitor#allowedTypes (#695)

Limits messages based on the Message#type

* Text Prompt Rework (#682)

* Text prompt arbitrary user channel (#681)

* [wip] maybe

* fix target mention

* oh right, bots message not theirs

* typings: Update for latest commit

* fix bad rebase

* typings: Fixed missing change in rebase

* typings: Remove all instances of GroupDMChannel

* Abort the prompt if the user retypes the command (#683)

* Abort if command retyped

The way this is done properly is to move much of CommandHandler to internals so there isn't a race between monitor/prompter.

* fix since docs

* fix doc type

* fix some order errors

* fix typo

* minimize impact if original command is edited

* typings

* make guildSettings not a getter once again

* fix crash if you get a message before klasaReady

* more optimal crash protection

* allow flagSupport to be turned off

* seperate argumentError from commandError (#694)

* rename event files that have core klasa functionality (#688)

* fix bad merge?

* fix mentioned bug

* add a retries loop for when discord is tripping over cords

* typos

* fix dm prompt

* fix bad error

* remove duplicate identifier (#699)

* fix(KlasaMessage): reactable not checking READ_MESSAGE_HISTORY permissions

* Update Possible.js

* typings: Add mentionPrefix on the client

* Update Tag.js

* ScheduledTask#catchUp is boolean (#712)

* src: Fix Store reloading broadcast script

* docs: Correct Piece file description

It's to the piece's file, not extendables

* src: Fix Language creation for loading core languages

* typings: Mark Language#store as a LanguageStore

* revert(typings): Revert marking of Language#store as LanguageStore

* add code for proper teams support dependent on d.js imp (#732)

* Update Store.js

* add null to usageDelim typings (#750)

* add null to usageDelim typings

* set eval usage to null to better support pieceDefaults

* Update index.d.ts (#744)

* Update index.d.ts

* Update typings/index.d.ts

Co-Authored-By: Antonio Román <[email protected]>

* require necessary addditions

* update jsdocs

* Fix cooldown response (#743)

* Update cooldown.js

* Update en-US.js

* Update en-US.js

* Update src/inhibitors/cooldown.js

Co-Authored-By: Antonio Román <[email protected]>

* Fix(Typing): Add category and subCategory to PieceCommandJSON (#759)

* Chore(deps): Bump lodash from 4.17.11 to 4.17.14 (#749)

Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.14.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](lodash/lodash@4.17.11...4.17.14)

Signed-off-by: dependabot[bot] <[email protected]>

* Add category and subCategory to PieceCommandJSON

* fix: Resolved memory leak in Schedule

Co-Authored-By: Gryffon Bellish <[email protected]>

Thanks Gryffon for finding the bug!

* Fix no named types (#741)

* Fix no named types

* Update src/lib/util/Type.js

Co-Authored-By: Hutch <[email protected]>

* fix lint

* Remove old method (#767)

* Fix finalizerError typings (#766)

* Fix(Typing): Add string union for EventOptions#emitter (#764)

* Fix(Typing): Add string union for EventOptions#emitter

* Overcomplicate cause why not :p

* remove private message#levelID

the command in the inhibitor/finalizer is not necessarily the message.command if for instance it is a reaction command. Therefore, that command has to be taken account for, not the one potentually on message, making levelID useless. Since it's private nobody should be using it, therefore it's not breaking to remove it.

* bye bye Command#cooldowns

inb4 crying that other pieces don't have types so this is just as bad or worse than "privates in pieces" closes #770

* src: Replace client.shard.id with client.options.shards (#772)

* src: Replace client.shard.id with client.options.shards

* src: Kyra notice

* FIx(Typings): Forgot to import Stopwatch (#773)

* Fix commands being re-run on non-command edits

* Fix a typo (#776)

* Client.use should use the util class (#784)

* Cooldown Inhibitor Change Seconds To Formatted String (#763)

* Update cooldown.js

* Update en-US.js

* Update Duration.js

* Update cooldown.js

* Update cooldown.js

* Update Duration.js

* Update cooldown.js

* Update Duration.js

* Update cooldown.js

* Update cooldown.js

* Update cooldown.js

* Update cooldown.js

* Update cooldown.js

* Update cooldown.js

* Update cooldown.js

* perf(Timestamp): Increased performance and move patterns to maps (#762)

* perf: Avoid megamorphic ICs and increased performance

Now everything is monomorphic and can run fully inlined, yay!

* docs: Documented Timestamp's static properties

* docs: We should switch to TSDocs...

* docs: Fixed type and renamed property

* Timestamp: Remove `tokenRepeatingCounts`

The property has been 👢'd!

* Timestamp: Inline all functions

* Timestamp: Resolve has+get anti-pattern

* Constants: Make TIME.TIMESTAMP.TOKENS a map

And removed `tokenRepeatingCounts` from Timestamp to reduce memory footprint

* Typings: Updated signature for `ConstantsTime.TIMESTAMP.TOKENS`

* fix: Y and YY formats slicing the first two digits instead of the two last

If it's 2019, it should output 19, not 20.

* typings: include klasaReady (#796)

* typings: Added flagSupport to TextPromptOptions

* typings: Add overrides from discord.js to klasa send methods (#794)

* Revert "Cooldown Inhibitor Change Seconds To Formatted String (#763)" (#835)

This reverts commit 2ff196b.

* mention prefix should be checked first

so a prefix of < doesn't break mention prefixes

* Fix(Commands): renamed event and unified end behavior of commands (#865)

* Update disable.js

* Update enable.js

* client.guilds.cache.size (#963)

client.guilds.size is undefined in d.js now

* d.js managers fix for resolveGuild (#956)

Co-authored-by: Gryffon Bellish <[email protected]>
Co-authored-by: Antonio Román <[email protected]>
Co-authored-by: Vlad Frangu <[email protected]>
Co-authored-by: Skillz4Killz <[email protected]>
Co-authored-by: Jacz <[email protected]>
Co-authored-by: Kolkies <[email protected]>
Co-authored-by: Jeroen Claassens <[email protected]>
Co-authored-by: Jacz <[email protected]>
Co-authored-by: Gryffon Bellish <[email protected]>
Co-authored-by: Wingysam <[email protected]>
Co-authored-by: Jonathan Ford <[email protected]>
  • Loading branch information
12 people authored May 22, 2020
1 parent 48e9eed commit 5ca3467
Show file tree
Hide file tree
Showing 46 changed files with 588 additions and 462 deletions.
2 changes: 1 addition & 1 deletion guides/Getting Started/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ new Client({
prefix: '+',
commandEditing: true,
typing: true,
readyMessage: (client) => `Successfully initialized. Ready to serve ${client.guilds.size} guilds.`
readyMessage: (client) => `Successfully initialized. Ready to serve ${client.guilds.cache.size} guilds.`
}).login('your-bot-token');
```

Expand Down
8 changes: 4 additions & 4 deletions guides/Getting Started/UnderstandingPermissionLevels.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ function permissionLevel(message) {
if (message.guild && message.member === message.guild.owner) return true;
case 8:
case 9:
if (message.author === message.client.owner) return true;
if (message.client.owners.has(author)) return true;
break;
case 10:
if (message.author === message.client.owner) return true;
if (message.client.owners.has(author)) return true;
return false;
}
throw 'You don\'t have permission';
Expand Down Expand Up @@ -74,9 +74,9 @@ config.permissionLevels = new PermissionLevels()
* Allows the Bot Owner to use any lower commands
* and causes any command with a permission level 9 or lower to return an error if no check passes.
*/
.add(9, ({ author, client }) => author === client.owner, { break: true })
.add(9, ({ author, client }) => client.owners.has(author), { break: true })
// Allows the bot owner to use Bot Owner only commands, which silently fail for other users.
.add(10, ({ author, client }) => author === client.owner);
.add(10, ({ author, client }) => client.owners.has(author));

new Client(config).login(config.token);
```
Expand Down
4 changes: 2 additions & 2 deletions src/commands/Admin/disable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module.exports = class extends Command {
}

async run(message, [piece]) {
if ((piece.type === 'event' && piece.name === 'message') || (piece.type === 'monitor' && piece.name === 'commandHandler')) {
if ((piece.type === 'event' && piece.name === 'coreMessage') || (piece.type === 'monitor' && piece.name === 'commandHandler')) {
return message.sendLocale('COMMAND_DISABLE_WARN');
}
piece.disable();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.store}.get('${piece.name}').disable();
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.store}.get('${piece.name}').disable();
`);
}
return message.sendLocale('COMMAND_DISABLE', [piece.type, piece.name], { code: 'diff' });
Expand Down
4 changes: 2 additions & 2 deletions src/commands/Admin/enable.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ module.exports = class extends Command {
piece.enable();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.store}.get('${piece.name}').enable();
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.store}.get('${piece.name}').enable();
`);
}
return message.sendCode('diff', message.language.get('COMMAND_ENABLE', piece.type, piece.name));
return message.sendLocale('COMMAND_ENABLE', [piece.type, piece.name], { code: 'diff' });
}

};
3 changes: 2 additions & 1 deletion src/commands/Admin/eval.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ module.exports = class extends Command {
guarded: true,
description: language => language.get('COMMAND_EVAL_DESCRIPTION'),
extendedHelp: language => language.get('COMMAND_EVAL_EXTENDEDHELP'),
usage: '<expression:str>'
usage: '<expression:str>',
usageDelim: null
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/Admin/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = class extends Command {
await piece.init();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') {
if (String(this.options.shards) !== '${this.client.options.shards}') {
const piece = this.${piece.store}.load('${piece.directory}', ${JSON.stringify(path)});
if (piece) piece.init();
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/Admin/reload.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = class extends Command {
await piece.init();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.name}.loadAll().then(() => this.${piece.name}.loadAll());
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.name}.loadAll().then(() => this.${piece.name}.init());
`);
}
return message.sendLocale('COMMAND_RELOAD_ALL', [piece, timer.stop()]);
Expand All @@ -31,7 +31,7 @@ module.exports = class extends Command {
const timer = new Stopwatch();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.store}.get('${piece.name}').reload();
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.store}.get('${piece.name}').reload();
`);
}
return message.sendLocale('COMMAND_RELOAD', [itm.type, itm.name, timer.stop()]);
Expand All @@ -49,7 +49,7 @@ module.exports = class extends Command {
}));
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.pieceStores.map(async (store) => {
if (String(this.options.shards) !== '${this.client.options.shards}') this.pieceStores.map(async (store) => {
await store.loadAll();
await store.init();
});
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Admin/transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = class extends Command {
piece.store.load(piece.store.userDirectory, piece.file);
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.store}.load(${piece.store.userDirectory}, ${JSON.stringify(piece.file)});
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.store}.load(${piece.store.userDirectory}, ${JSON.stringify(piece.file)});
`);
}
return message.sendLocale('COMMAND_TRANSFER_SUCCESS', [piece.type, piece.name]);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Admin/unload.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = class extends Command {
piece.unload();
if (this.client.shard) {
await this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') this.${piece.store}.get('${piece.name}').unload();
if (String(this.options.shards) !== '${this.client.options.shards}') this.${piece.store}.get('${piece.name}').unload();
`);
}
return message.sendLocale('COMMAND_UNLOAD', [piece.type, piece.name]);
Expand Down
9 changes: 9 additions & 0 deletions src/events/argumentError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { Event } = require('klasa');

module.exports = class extends Event {

run(message, command, params, error) {
message.sendMessage(error).catch(err => this.client.emit('wtf', err));
}

};
4 changes: 4 additions & 0 deletions src/events/guildCreate.js → src/events/coreGuildCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'guildCreate' });
}

run(guild) {
if (!guild.available) return;
if (this.client.settings.guildBlacklist.includes(guild.id)) {
Expand Down
4 changes: 4 additions & 0 deletions src/events/guildDelete.js → src/events/coreGuildDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'guildDelete' });
}

run(guild) {
if (this.client.ready && guild.available && !this.client.options.preserveSettings) guild.settings.destroy().catch(() => null);
}
Expand Down
4 changes: 4 additions & 0 deletions src/events/message.js → src/events/coreMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'message' });
}

run(message) {
if (this.client.ready) this.client.monitors.run(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'messageDelete' });
}

run(message) {
if (message.command && message.command.deletable) {
for (const msg of message.responses) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'messageDeleteBulk' });
}

run(messages) {
for (const message of messages.values()) {
if (message.command && message.command.deletable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const { Event } = require('klasa');

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'messageUpdate' });
}

async run(old, message) {
if (this.client.ready && !old.partial && old.content !== message.content) this.client.monitors.run(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ const gateways = ['users', 'clientStorage'];

module.exports = class extends Event {

constructor(...args) {
super(...args, { event: 'settingsUpdateEntry' });
}

run(settings) {
if (gateways.includes(settings.gateway.type)) {
this.client.shard.broadcastEval(`
if (String(this.shard.id) !== '${this.client.shard.id}') {
if (String(this.options.shards) !== '${this.client.options.shards}') {
const entry = this.gateways.${settings.gateway.type}.get('${settings.id}');
if (entry) {
entry._patch(${JSON.stringify(settings)});
Expand Down
21 changes: 18 additions & 3 deletions src/events/onceReady.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const { Event, util } = require('klasa');
const { Team } = require('discord.js');
let retries = 0;

module.exports = class extends Event {

Expand All @@ -10,8 +12,21 @@ module.exports = class extends Event {
}

async run() {
await this.client.fetchApplication();
if (!this.client.options.ownerID) this.client.options.ownerID = this.client.application.owner.id;
try {
await this.client.fetchApplication();
} catch (err) {
if (++retries === 3) return process.exit();
this.client.emit('warning', `Unable to fetchApplication at this time, waiting 5 seconds and retrying. Retries left: ${retries - 3}`);
await util.sleep(5000);
return this.run();
}

if (!this.client.options.owners.length) {
if (this.client.application.owner instanceof Team) this.client.options.owners.push(...this.client.application.owner.members.keys());
else this.client.options.owners.push(this.client.application.owner.id);
}

this.client.mentionPrefix = new RegExp(`^<@!?${this.client.user.id}>`);

this.client.settings = this.client.gateways.clientStorage.get(this.client.user.id, true);
// Added for consistency with other datastores, Client#clients does not exist
Expand All @@ -30,7 +45,7 @@ module.exports = class extends Event {
this.client.emit('log', util.isFunction(this.client.options.readyMessage) ? this.client.options.readyMessage(this.client) : this.client.options.readyMessage);
}

this.client.emit('klasaReady');
return this.client.emit('klasaReady');
}

};
20 changes: 17 additions & 3 deletions src/finalizers/commandCooldown.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
const { Finalizer } = require('klasa');
const { Finalizer, RateLimitManager } = require('klasa');

module.exports = class extends Finalizer {

constructor(...args) {
super(...args);
this.cooldowns = new WeakMap();
}

run(message, command) {
if (command.cooldown <= 0 || message.author === this.client.owner) return;
if (command.cooldown <= 0 || this.client.owners.has(message.author)) return;

try {
command.cooldowns.acquire(message.levelID).drip();
this.getCooldown(message, command).drip();
} catch (err) {
this.client.emit('error', `${message.author.username}[${message.author.id}] has exceeded the RateLimit for ${message.command}`);
}
}

getCooldown(message, command) {
let cooldownManager = this.cooldowns.get(command);
if (!cooldownManager) {
cooldownManager = new RateLimitManager(command.bucket, command.cooldown * 1000);
this.cooldowns.set(command, cooldownManager);
}
return cooldownManager.acquire(message.guild ? message[command.cooldownLevel].id : message.author.id);
}

};
12 changes: 9 additions & 3 deletions src/inhibitors/cooldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ module.exports = class extends Inhibitor {
}

run(message, command) {
if (message.author === this.client.owner || command.cooldown <= 0) return;
if (this.client.owners.has(message.author) || command.cooldown <= 0) return;

const existing = command.cooldowns.get(message.levelID);
let existing;

if (existing && existing.limited) throw message.language.get('INHIBITOR_COOLDOWN', Math.ceil(existing.remainingTime / 1000));
try {
existing = this.client.finalizers.get('commandCooldown').getCooldown(message, command);
} catch (err) {
return;
}

if (existing && existing.limited) throw message.language.get('INHIBITOR_COOLDOWN', Math.ceil(existing.remainingTime / 1000), command.cooldownLevel !== 'author');
}

};
2 changes: 1 addition & 1 deletion src/inhibitors/hidden.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { Inhibitor } = require('klasa');
module.exports = class extends Inhibitor {

run(message, command) {
return command.hidden && message.command !== command && message.author !== this.client.owner;
return command.hidden && message.command !== command && !this.client.owners.has(message.author);
}

};
2 changes: 1 addition & 1 deletion src/inhibitors/slowmode.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = class extends Inhibitor {
}

run(message) {
if (message.author === this.client.owner) return;
if (this.client.owners.has(message.author)) return;

const rateLimit = this.slowmode.acquire(message.author.id);

Expand Down
3 changes: 2 additions & 1 deletion src/languages/en-US.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ module.exports = class extends Language {
// eslint-disable-next-line max-len
MONITOR_COMMAND_HANDLER_REPEATING_REPROMPT: (tag, name, time, cancelOptions) => `${tag} | **${name}** is a repeating argument | You have **${time}** seconds to respond to this prompt with additional valid arguments. Type **${cancelOptions.join('**, **')}** to cancel this prompt.`,
MONITOR_COMMAND_HANDLER_ABORTED: 'Aborted',
INHIBITOR_COOLDOWN: (remaining) => `You have just used this command. You can use this command again in ${remaining} second${remaining === 1 ? '' : 's'}.`,
// eslint-disable-next-line max-len
INHIBITOR_COOLDOWN: (remaining, guildCooldown) => `${guildCooldown ? 'Someone has' : 'You have'} already used this command. You can use this command again in ${remaining} second${remaining === 1 ? '' : 's'}.`,
INHIBITOR_DISABLED_GUILD: 'This command has been disabled by an admin in this guild.',
INHIBITOR_DISABLED_GLOBAL: 'This command has been globally disabled by the bot owner.',
INHIBITOR_MISSING_BOT_PERMS: (missing) => `Insufficient permissions, missing: **${missing}**`,
Expand Down
Loading

0 comments on commit 5ca3467

Please sign in to comment.