wrapper related
This commit is contained in:
parent
0d50e925e6
commit
8e1e5c6c24
@ -1,14 +1,15 @@
|
|||||||
const { Client } = require('discord.js');
|
const { Client, Collection } = require('discord.js');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
|
||||||
const { Logger, Intercom, EventHooker, LocaleLoader, Registry, Dispatcher, Resolver } = require('./client/');
|
const { Intercom, EventHooker, LocaleLoader, Registry, Dispatcher, Resolver, ModerationManager, RateLimiter } = require('./client/');
|
||||||
const { Observer, Command, Setting, Inhibitor } = require('./interfaces/');
|
const { Observer, Command, Setting, Inhibitor } = require('./interfaces/');
|
||||||
|
const { Logger } = require('../utilities');
|
||||||
const StorageManager = require('./storage/StorageManager.js');
|
const StorageManager = require('./storage/StorageManager.js');
|
||||||
|
|
||||||
const { DefaultGuild } = require('../constants/');
|
const { DefaultGuild, DefaultUser } = require('../constants/');
|
||||||
|
|
||||||
const options = require('../../options.json');
|
const options = require('../../options.json');
|
||||||
const RateLimiter = require('./client/RateLimiter');
|
const { GuildWrapper, UserWrapper } = require('./client/wrappers');
|
||||||
|
|
||||||
const Constants = {
|
const Constants = {
|
||||||
ComponentTypes: {
|
ComponentTypes: {
|
||||||
@ -29,7 +30,7 @@ class DiscordClient extends Client {
|
|||||||
...options.discord.clientOptions
|
...options.discord.clientOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
this.logger = new Logger(this);
|
this.logger = new Logger({ name: 'Client' });
|
||||||
this.eventHooker = new EventHooker(this);
|
this.eventHooker = new EventHooker(this);
|
||||||
this.intercom = new Intercom(this);
|
this.intercom = new Intercom(this);
|
||||||
this.dispatcher = new Dispatcher(this);
|
this.dispatcher = new Dispatcher(this);
|
||||||
@ -38,12 +39,16 @@ class DiscordClient extends Client {
|
|||||||
this.registry = new Registry(this);
|
this.registry = new Registry(this);
|
||||||
this.resolver = new Resolver(this);
|
this.resolver = new Resolver(this);
|
||||||
this.rateLimiter = new RateLimiter(this);
|
this.rateLimiter = new RateLimiter(this);
|
||||||
|
this.moderationManager = new ModerationManager(this);
|
||||||
|
|
||||||
|
// Originally used for evals, but being replaced by the wrappers collections
|
||||||
this.wrapperClasses = {
|
this.wrapperClasses = {
|
||||||
...require('./client/wrappers')
|
...require('./client/wrappers')
|
||||||
};
|
};
|
||||||
|
this.guildWrappers = new Collection();
|
||||||
|
this.userWrappers = new Collection();
|
||||||
|
|
||||||
this._defaultConfig = null;
|
this._defaultConfig = {};
|
||||||
this._activity = 0;
|
this._activity = 0;
|
||||||
this._options = options;
|
this._options = options;
|
||||||
this._built = false;
|
this._built = false;
|
||||||
@ -58,6 +63,14 @@ class DiscordClient extends Client {
|
|||||||
|
|
||||||
this._loadEevents();
|
this._loadEevents();
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
this.logger.error(`Uncaught exception:\n${err.stack || err}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (err) => {
|
||||||
|
this.logger.error(`Unhandled rejection:\n${err.stack || err}`);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async build() {
|
async build() {
|
||||||
@ -85,17 +98,31 @@ class DiscordClient extends Client {
|
|||||||
this.logger.info(`Built client in ${Date.now()-beforeTime}ms.`);
|
this.logger.info(`Built client in ${Date.now()-beforeTime}ms.`);
|
||||||
|
|
||||||
await super.login();
|
await super.login();
|
||||||
|
await this.ready();
|
||||||
|
|
||||||
this.emit('built');
|
|
||||||
this._built = true;
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig() {
|
// Wait until the client is actually ready, i.e. all structures from discord are created
|
||||||
if(this._defaultConfig) return this._defaultConfig;
|
ready() {
|
||||||
const settings = this.registry.components.filter((c) => c._type === 'setting');
|
|
||||||
let def = DefaultGuild;
|
return new Promise((resolve) => {
|
||||||
|
if (this._built) return resolve();
|
||||||
|
this.once('ready', () => {
|
||||||
|
this._createWrappers();
|
||||||
|
this._built = true;
|
||||||
|
this.emit('built');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig(type) {
|
||||||
|
if(this._defaultConfig[type]) return this._defaultConfig[type];
|
||||||
|
const settings = this.registry.components.filter((c) => c._type === 'setting' && c.resolve === type);
|
||||||
|
let def = type === 'GUILD' ? DefaultGuild : DefaultUser;
|
||||||
for(const setting of settings.values()) {
|
for(const setting of settings.values()) {
|
||||||
if(setting.default !== null) {
|
if(setting.default !== null) {
|
||||||
def = {
|
def = {
|
||||||
@ -104,7 +131,7 @@ class DiscordClient extends Client {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._defaultConfig = def;
|
this._defaultConfig[type] = def;
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +167,7 @@ class DiscordClient extends Client {
|
|||||||
|
|
||||||
this.eventHooker.hook('ready', () => {
|
this.eventHooker.hook('ready', () => {
|
||||||
const guilds = this.guilds.cache.size;
|
const guilds = this.guilds.cache.size;
|
||||||
this.logger.info(`Client connected to ${chalk.bold(this.user.tag)} with ${chalk.bold(`${guilds} guild${guilds === 1 ? '' : 's'}`)}.`);
|
this.logger.status(`Client ready, connected to ${chalk.bold(this.user.tag)} with ${chalk.bold(`${guilds} guild${guilds === 1 ? '' : 's'}`)}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.eventHooker.hook('componentUpdate', ({ component, type }) => {
|
this.eventHooker.hook('componentUpdate', ({ component, type }) => {
|
||||||
@ -149,10 +176,12 @@ class DiscordClient extends Client {
|
|||||||
|
|
||||||
this.eventHooker.hook('guildCreate', (guild) => {
|
this.eventHooker.hook('guildCreate', (guild) => {
|
||||||
this.logger.debug(`${chalk.bold('[GUILD]')} Joined guild ${chalk.bold(guild.name)} (${guild.id}).`);
|
this.logger.debug(`${chalk.bold('[GUILD]')} Joined guild ${chalk.bold(guild.name)} (${guild.id}).`);
|
||||||
|
this.guildWrappers.set(guild.id, new GuildWrapper(this, guild));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.eventHooker.hook('guildDelete', (guild) => {
|
this.eventHooker.hook('guildDelete', (guild) => {
|
||||||
this.logger.debug(`${chalk.bold('[GUILD]')} Left guild ${chalk.bold(guild.name)} (${guild.id}).`);
|
this.logger.debug(`${chalk.bold('[GUILD]')} Left guild ${chalk.bold(guild.name)} (${guild.id}).`);
|
||||||
|
this.guildWrappers.delete(guild.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.eventHooker.hook('shardDisconect', () => {
|
this.eventHooker.hook('shardDisconect', () => {
|
||||||
@ -177,6 +206,39 @@ class DiscordClient extends Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_createWrappers() {
|
||||||
|
|
||||||
|
this.guilds.cache.forEach((guild) => {
|
||||||
|
this.guildWrappers.set(guild.id, new GuildWrapper(this, guild));
|
||||||
|
});
|
||||||
|
this.logger.info(`Created guild wrappers`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getGuildWrapper(id) {
|
||||||
|
|
||||||
|
if (this.guildWrappers.has(id)) return this.guildWrappers.get(id);
|
||||||
|
|
||||||
|
const wrapper = new GuildWrapper(this, this.guilds.cache.get(id));
|
||||||
|
this.guildWrappers.set(id, wrapper);
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUserWrapper(id) {
|
||||||
|
|
||||||
|
if (this.userWrappers.has(id)) return this.userWrappers.get(id);
|
||||||
|
|
||||||
|
const user = await this.users.fetch(id);
|
||||||
|
const wrapper = new UserWrapper(this, user);
|
||||||
|
this.userWrappers.set(id, wrapper);
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DiscordClient;
|
module.exports = DiscordClient;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
const { stripIndents } = require('common-tags');
|
const { stripIndents } = require('common-tags');
|
||||||
const { User } = require('discord.js');
|
const { User, GuildMember } = require('discord.js');
|
||||||
const { Collection } = require('@discordjs/collection');
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
|
||||||
const { Emojis, Constants } = require('../../constants');
|
const { Emojis, Constants } = require('../../constants');
|
||||||
const Util = require('../../Util.js');
|
const { Util, Logger } = require('../../utilities');
|
||||||
const { Warn, Unmute, Mute, Kick, Softban, Unban, Ban, Addrole, Removerole, Lockdown, Unlockdown } = require('../components/infractions');
|
const { Warn, Unmute, Mute, Kick, Softban, Unban, Ban, Addrole, Removerole, Lockdown, Unlockdown } = require('../components/infractions');
|
||||||
const Logger = require('./Logger');
|
|
||||||
const Constant = {
|
const Constant = {
|
||||||
MaxTargets: 10, //10+(10*premium-tier), theoretical max = 40
|
MaxTargets: 10, //10+(10*premium-tier), theoretical max = 40
|
||||||
Infractions: {
|
Infractions: {
|
||||||
@ -36,7 +36,7 @@ class ModerationManager {
|
|||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.callbacks = new Collection();
|
this.callbacks = new Collection();
|
||||||
this.logger = new Logger(this);
|
this.logger = new Logger({ name: 'ModMngr' });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,39 +189,45 @@ class ModerationManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async handleAutomod(Infraction, info) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async _handleTarget(Infraction, target, info) {
|
async _handleTarget(Infraction, target, info) {
|
||||||
const { guild, reason, force } = info;
|
|
||||||
const { autoModeration, moderationPoints } = guild._settings;
|
const { reason, force, wrapper } = info;
|
||||||
|
const { automod, modpoints } = wrapper._settings;
|
||||||
const { type } = Infraction;
|
const { type } = Infraction;
|
||||||
|
const { guild } = wrapper;
|
||||||
|
const targetWrapper = target instanceof User || target instanceof GuildMember ?
|
||||||
|
await this.client.getUserWrapper(target.id) :
|
||||||
|
target; // TODO: Channel wrapper if necessary
|
||||||
|
|
||||||
let points = 0,
|
let points = 0,
|
||||||
expiration = 0;
|
expiration = 0;
|
||||||
if (moderationPoints.enabled) {
|
if (modpoints.enabled) {
|
||||||
points = info.points || moderationPoints.points[type];
|
points = info.points || modpoints.points[type];
|
||||||
expiration = info.expiration || moderationPoints.expirations[type];
|
expiration = info.expiration || modpoints.expirations[type];
|
||||||
for (const [phrase, amount] of Object.entries(moderationPoints.associations)) {
|
for (const [phrase, amount] of Object.entries(modpoints.associations)) {
|
||||||
if (reason.toLowerCase().includes(phrase)) points = amount;
|
if (reason.toLowerCase().includes(phrase)) points = amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const verify = async (infraction, escalated = false) => {
|
const verify = async (infraction, escalated = false) => {
|
||||||
|
|
||||||
let verification = infraction.verify(info.executor, target, info.channel);
|
const verification = await infraction.verify(info.executor, target, info.channel);
|
||||||
if (verification instanceof Promise) verification = await verification;
|
|
||||||
|
|
||||||
if (verification.error) return verification;
|
if (verification.error) return verification;
|
||||||
|
|
||||||
if (infraction.targetType === 'USER') {
|
if (infraction.targetType === 'USER') {
|
||||||
const userTarget = target instanceof User ? target : target.user;
|
const oldPoints = await targetWrapper.totalPoints(guild);
|
||||||
const oldPoints = await userTarget.totalPoints(guild);
|
|
||||||
|
|
||||||
const newPoints = oldPoints + infraction.points;
|
const newPoints = oldPoints + infraction.points;
|
||||||
if (autoModeration.enabled && points > 0 && !force && !escalated) {
|
if (automod.enabled && points > 0 && !force && !escalated) {
|
||||||
let result = null;
|
let result = null;
|
||||||
for (let [threshold, action] of Object.entries(autoModeration.thresholds)) { //eslint-disable-line prefer-const
|
for (let [threshold, action] of Object.entries(automod.thresholds)) { //eslint-disable-line prefer-const
|
||||||
threshold = parseInt(threshold);
|
threshold = parseInt(threshold);
|
||||||
if (oldPoints >= threshold) {
|
if (oldPoints >= threshold) {
|
||||||
if (autoModeration.usePrevious) {
|
if (automod.usePrevious) {
|
||||||
result = {
|
result = {
|
||||||
threshold,
|
threshold,
|
||||||
...action
|
...action
|
||||||
@ -255,7 +261,7 @@ class ModerationManager {
|
|||||||
type,
|
type,
|
||||||
message: info.message || null,
|
message: info.message || null,
|
||||||
arguments: info.arguments,
|
arguments: info.arguments,
|
||||||
guild: info.guild,
|
guild: info.wrapper,
|
||||||
channel: info.channel,
|
channel: info.channel,
|
||||||
executor: info.executor,
|
executor: info.executor,
|
||||||
reason: info.reason,
|
reason: info.reason,
|
||||||
@ -276,11 +282,11 @@ class ModerationManager {
|
|||||||
message: info.message || null,
|
message: info.message || null,
|
||||||
arguments: info.arguments,
|
arguments: info.arguments,
|
||||||
type: escalationClass.type,
|
type: escalationClass.type,
|
||||||
guild: info.guild,
|
guild: info.wrapper,
|
||||||
channel: info.channel,
|
channel: info.channel,
|
||||||
executor: info.executor,
|
executor: info.executor,
|
||||||
reason: stripIndents`${reason}
|
reason: stripIndents`${reason}
|
||||||
*${guild.format('INFRACTION_AUTOMODESCALATION')}*`,
|
*${wrapper.format('INFRACTION_AUTOMODESCALATION')}*`,
|
||||||
duration: info.duration,
|
duration: info.duration,
|
||||||
data: info.data,
|
data: info.data,
|
||||||
points,
|
points,
|
||||||
@ -294,7 +300,7 @@ class ModerationManager {
|
|||||||
if (response.error) return response;
|
if (response.error) return response;
|
||||||
|
|
||||||
if (response.infraction.targetType === 'USER') {
|
if (response.infraction.targetType === 'USER') {
|
||||||
response.infraction.totalPoints = await response.infraction.target.totalPoints(guild, {
|
response.infraction.totalPoints = await targetWrapper.totalPoints(guild, {
|
||||||
points, expiration, timestamp: response.infraction.timestamp
|
points, expiration, timestamp: response.infraction.timestamp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -324,8 +330,7 @@ class ModerationManager {
|
|||||||
for (const arg of Object.values(message.arguments)) {
|
for (const arg of Object.values(message.arguments)) {
|
||||||
// console.log(arg, targets);
|
// console.log(arg, targets);
|
||||||
if (actions[arg.name]) {
|
if (actions[arg.name]) {
|
||||||
let action = actions[arg.name](message, arg, targets);
|
const action = await actions[arg.name](message, arg, targets);
|
||||||
if (action instanceof Promise) action = await action;
|
|
||||||
responses[arg.name] = action;
|
responses[arg.name] = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user