Update main branch #15
1
@types/Guild.d.ts
vendored
1
@types/Guild.d.ts
vendored
@ -120,6 +120,7 @@ export type GuildData = {
|
|||||||
caseId?: number,
|
caseId?: number,
|
||||||
settings?: GuildSettings,
|
settings?: GuildSettings,
|
||||||
premium?: number,
|
premium?: number,
|
||||||
|
debug?: boolean,
|
||||||
_version?: string,
|
_version?: string,
|
||||||
_imported?: {
|
_imported?: {
|
||||||
[key: string]: boolean | undefined,
|
[key: string]: boolean | undefined,
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
"tables": [
|
"tables": [
|
||||||
"guilds",
|
"guilds",
|
||||||
"attachments",
|
"attachments",
|
||||||
|
"messages",
|
||||||
"permissions",
|
"permissions",
|
||||||
"webhooks",
|
"webhooks",
|
||||||
"wordwatcher",
|
"wordwatcher",
|
||||||
|
59
src/client/components/commands/developer/Debug.ts
Normal file
59
src/client/components/commands/developer/Debug.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { CommandOptionType, CommandParams } from '../../../../../@types/Client.js';
|
||||||
|
import DiscordClient from '../../../DiscordClient.js';
|
||||||
|
import { Command } from '../../../interfaces/index.js';
|
||||||
|
import InvokerWrapper from '../../wrappers/InvokerWrapper.js';
|
||||||
|
|
||||||
|
class DebugCommand extends Command
|
||||||
|
{
|
||||||
|
constructor (client: DiscordClient)
|
||||||
|
{
|
||||||
|
super(client, {
|
||||||
|
name: 'debug',
|
||||||
|
restricted: true,
|
||||||
|
moduleName: 'developer',
|
||||||
|
options: [
|
||||||
|
{ name: 'guild', required: true },
|
||||||
|
{ name: 'enabled', required: true, type: CommandOptionType.BOOLEAN }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute (_invoker: InvokerWrapper, options: CommandParams)
|
||||||
|
{
|
||||||
|
const guildId = options.guild!.asString;
|
||||||
|
return this.enableDebug(guildId, options.enabled?.asBool);
|
||||||
|
}
|
||||||
|
|
||||||
|
async enableDebug (guildId: string, enabled = false)
|
||||||
|
{
|
||||||
|
let output = '';
|
||||||
|
if (this.client.shard)
|
||||||
|
{
|
||||||
|
const result = await this.client.shard.broadcastEval(async (client, context) =>
|
||||||
|
{
|
||||||
|
const bot = client as DiscordClient;
|
||||||
|
const wrapper = await bot.getGuildWrapper(context.guildId);
|
||||||
|
if (!wrapper)
|
||||||
|
return false;
|
||||||
|
await wrapper.setDebug(context.enabled);
|
||||||
|
return `${wrapper.name} (${wrapper.id})`;
|
||||||
|
}, { context: { guildId, enabled } });
|
||||||
|
|
||||||
|
if (!result.some(val => val))
|
||||||
|
return 'No such guild';
|
||||||
|
output = result.find(entry => entry) as string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const wrapper = await this.client.getGuildWrapper(guildId).catch(() => null);
|
||||||
|
if (!wrapper)
|
||||||
|
return 'No such guild';
|
||||||
|
await wrapper.setDebug(enabled);
|
||||||
|
output = `${wrapper.name} (${wrapper.id})`;
|
||||||
|
}
|
||||||
|
return `${enabled ? 'Enabled' : 'Disabled'} debug on **${output}**`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DebugCommand;
|
@ -8,7 +8,6 @@ import MemberWrapper from '../../wrappers/MemberWrapper.js';
|
|||||||
|
|
||||||
class AddroleCommand extends ModerationCommand
|
class AddroleCommand extends ModerationCommand
|
||||||
{
|
{
|
||||||
|
|
||||||
constructor (client: DiscordClient)
|
constructor (client: DiscordClient)
|
||||||
{
|
{
|
||||||
super(client, {
|
super(client, {
|
||||||
@ -43,12 +42,10 @@ class AddroleCommand extends ModerationCommand
|
|||||||
clientPermissions: [ 'ManageRoles' ],
|
clientPermissions: [ 'ManageRoles' ],
|
||||||
skipOptions: [ 'points', 'expiration', 'force', 'prune' ]
|
skipOptions: [ 'points', 'expiration', 'force', 'prune' ]
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute (invoker: InvokerWrapper<true>, { users, roles, ...args }: CommandParams)
|
async execute (invoker: InvokerWrapper<true>, { users, roles, ...args }: CommandParams)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!users)
|
if (!users)
|
||||||
throw new CommandError(invoker, { index: 'MODERATION_MISSING_USERS' });
|
throw new CommandError(invoker, { index: 'MODERATION_MISSING_USERS' });
|
||||||
if (!roles)
|
if (!roles)
|
||||||
@ -66,7 +63,6 @@ class AddroleCommand extends ModerationCommand
|
|||||||
roles: roles.asString
|
roles: roles.asString
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,89 +59,9 @@ class GuildWrapper
|
|||||||
this.#guild = guild;
|
this.#guild = guild;
|
||||||
this.#webhooks = new Collection();
|
this.#webhooks = new Collection();
|
||||||
this.#memberWrappers = new Collection();
|
this.#memberWrappers = new Collection();
|
||||||
this.#debugLog('Created wrapper');
|
this.debug('Created wrapper');
|
||||||
}
|
}
|
||||||
|
|
||||||
// async createPoll ({ user, duration, ...opts }: PollData)
|
|
||||||
// {
|
|
||||||
// // Idk polls that don't have a duration should still be stored somewhere so they can be ended at an arbitrary point
|
|
||||||
// const type = 'poll';
|
|
||||||
// const now = Date.now();
|
|
||||||
// const id = `${type}:${user}:${now}`;
|
|
||||||
// const data = { ...opts, user, id, guild: this.id, type, time: duration * 1000, created: now };
|
|
||||||
// if (duration)
|
|
||||||
// await this.createCallback(data satisfies CallbackData);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async loadCallbacks ()
|
|
||||||
// {
|
|
||||||
// const data = await this.#client.mongodb.callbacks.find<CallbackData>({ guild: this.id });
|
|
||||||
// for (const cb of data)
|
|
||||||
// await this.createCallback(cb, false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async createCallback (data: CallbackData, update = true)
|
|
||||||
// {
|
|
||||||
// const handler = this[`_${data.type}`] as CallbackFn;// .bind(this);
|
|
||||||
// if (!handler)
|
|
||||||
// throw new Error('Invalid callback type');
|
|
||||||
|
|
||||||
// const now = Date.now();
|
|
||||||
// const time = data.created + data.time;
|
|
||||||
// const diff = time - now;
|
|
||||||
// if (diff < 5000)
|
|
||||||
// return handler.bind(this)(data);
|
|
||||||
|
|
||||||
// const cb = { timeout: setTimeout(handler.bind(this), diff, data), data };
|
|
||||||
// this.#callbacks.set(data.id, cb);
|
|
||||||
// if (update)
|
|
||||||
// await this.#client.mongodb.callbacks.updateOne({ id: data.id, guild: this.id }, { $set: data });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async removeCallback (id: string)
|
|
||||||
// {
|
|
||||||
// const cb = this.#callbacks.get(id);
|
|
||||||
// if (cb)
|
|
||||||
// clearTimeout(cb.timeout);
|
|
||||||
// this.#callbacks.delete(id);
|
|
||||||
// await this.#client.mongodb.callbacks.deleteOne({ guild: this.id, id });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async _poll ({ user, message, channel, id, questions, startedIn }: PollData & CallbackData)
|
|
||||||
// { // multichoice,
|
|
||||||
// const startedInChannel = await this.resolveChannel<TextChannel>(startedIn);
|
|
||||||
// const pollChannel = await this.resolveChannel<TextChannel>(channel);
|
|
||||||
// if (pollChannel)
|
|
||||||
// {
|
|
||||||
// const msg = await pollChannel.messages.fetch(message).catch(() => null);
|
|
||||||
// if (msg)
|
|
||||||
// {
|
|
||||||
// const { reactions } = msg;
|
|
||||||
// const reactionEmojis = questions.length ? PollReactions.Multi : PollReactions.Single;
|
|
||||||
// const result: {[key: string]: number} = {};
|
|
||||||
// for (const emoji of reactionEmojis)
|
|
||||||
// {
|
|
||||||
// let reaction = reactions.resolve(emoji);
|
|
||||||
// // eslint-disable-next-line max-depth
|
|
||||||
// if (!reaction)
|
|
||||||
// continue;
|
|
||||||
// // eslint-disable-next-line max-depth
|
|
||||||
// if (reaction.partial)
|
|
||||||
// reaction = await reaction.fetch();
|
|
||||||
// result[emoji] = reaction.count - 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const embed = msg.embeds[0].toJSON();
|
|
||||||
// const results = Object.entries(result).map(([ emoji, count ]) => `${emoji} - ${count}`).join('\n');
|
|
||||||
// embed.description = this.format('COMMAND_POLL_END', { results });
|
|
||||||
// await msg.edit({ embeds: [ embed ] });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// await this.removeCallback(id);
|
|
||||||
// if (startedInChannel)
|
|
||||||
// await startedInChannel.send(this.format('COMMAND_POLL_NOTIFY_STARTER', { user, channel }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
async filterText (member: GuildMember, text: string)
|
async filterText (member: GuildMember, text: string)
|
||||||
{
|
{
|
||||||
const settings = await this.settings();
|
const settings = await this.settings();
|
||||||
@ -289,72 +209,6 @@ class GuildWrapper
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// async _attemptDataImport ()
|
|
||||||
// {
|
|
||||||
// const migratorOptions = {
|
|
||||||
// // host: MONGODB_V2_HOST,
|
|
||||||
// database: 'galacticbot',
|
|
||||||
// version: '2'
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const settingsMigrator = new SettingsMigrator(this.client, this, migratorOptions);
|
|
||||||
// const modlogsMigrator = new InfractionMigrator(this.client, this, migratorOptions);
|
|
||||||
|
|
||||||
// await settingsMigrator.connect();
|
|
||||||
// await modlogsMigrator.connect();
|
|
||||||
|
|
||||||
// let importedSettings = null;
|
|
||||||
// let importedModlogs = null;
|
|
||||||
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// importedSettings = await settingsMigrator.import();
|
|
||||||
// importedModlogs = await modlogsMigrator.import();
|
|
||||||
// importedModlogs.sort((a, b) => a.case - b.case);
|
|
||||||
// }
|
|
||||||
// catch (err)
|
|
||||||
// {
|
|
||||||
// await settingsMigrator.end();
|
|
||||||
// await modlogsMigrator.end();
|
|
||||||
// // Did not find old settings, marking as imported anyway
|
|
||||||
// if (err.message.includes('No old'))
|
|
||||||
// {
|
|
||||||
// await this.updateData({ _imported: { settings: true, modlogs: true } });
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// this.client.logger.error(err.stack);
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// await settingsMigrator.end();
|
|
||||||
// await modlogsMigrator.end();
|
|
||||||
|
|
||||||
// await this.client.mongodb.infractions.deleteMany({ guild: this.id });
|
|
||||||
// await this.client.mongodb.infractions.insertMany(importedModlogs);
|
|
||||||
// this._data.caseId = importedModlogs[importedModlogs.length - 1].case;
|
|
||||||
// await this.updateData({
|
|
||||||
// caseId: this._data.caseId,
|
|
||||||
// premium: importedSettings.premium,
|
|
||||||
// _imported: { settings: true, modlogs: true }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const { webhook, permissions, settings } = importedSettings;
|
|
||||||
// await this.updateSettings(settings);
|
|
||||||
// if (webhook)
|
|
||||||
// {
|
|
||||||
// const hooks = await this.fetchWebhooks().catch(() => null);
|
|
||||||
// const hook = hooks?.get(webhook);
|
|
||||||
// if (hook)
|
|
||||||
// await this.updateWebhook('messages', hook);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (permissions)
|
|
||||||
// await this.#client.mongodb.permissions.updateOne({ guildId: this.id }, permissions);
|
|
||||||
|
|
||||||
|
|
||||||
// return settings;
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a webhook entry in the database
|
* Update a webhook entry in the database
|
||||||
*
|
*
|
||||||
@ -528,11 +382,18 @@ class GuildWrapper
|
|||||||
this.#logger.error(`Database error (guild:${this.id}) :\n${error.stack || error}`);
|
this.#logger.error(`Database error (guild:${this.id}) :\n${error.stack || error}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
#debugLog (log: string)
|
debug (log: string)
|
||||||
{
|
{
|
||||||
|
if (!this.#data || this.#data.debug)
|
||||||
this.#logger.debug(`[${this.name}]: ${log}`);
|
this.#logger.debug(`[${this.name}]: ${log}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setDebug (enabled: boolean)
|
||||||
|
{
|
||||||
|
await this.#client.mongodb.guilds.updateOne({ guildId: this.id }, { $set: { debug: enabled } });
|
||||||
|
this.#data.debug = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrapper Functions */
|
/* Wrapper Functions */
|
||||||
|
|
||||||
fetchAuditLogs<T extends GuildAuditLogsResolvable> (opts: GuildAuditLogsFetchOptions<T>)
|
fetchAuditLogs<T extends GuildAuditLogsResolvable> (opts: GuildAuditLogsFetchOptions<T>)
|
||||||
|
@ -62,10 +62,12 @@ class AddroleInfraction extends Infraction
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.guild.debug(`Adding roles ${this.data.roleIds.join(', ')} to ${this.member.tag} (${this.member.id})`);
|
||||||
await this.member.roles.add(this.data.roleIds, this._reason);
|
await this.member.roles.add(this.data.roleIds, this._reason);
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to add roles (${this.data.roleIds.join(', ')}) to ${this.member.tag} (${this.member.id})\n${error}`);
|
||||||
return this._fail('INFRACTION_ERROR');
|
return this._fail('INFRACTION_ERROR');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ class BanInfraction extends Infraction
|
|||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to ban ${(this.target as UserWrapper).tag} (${this.target!.id}) from ${this.guild.name} (${this.guild.id})\n${error}`);
|
||||||
return this._fail('INFRACTION_ERROR');
|
return this._fail('INFRACTION_ERROR');
|
||||||
}
|
}
|
||||||
await this.handle();
|
await this.handle();
|
||||||
|
@ -4,6 +4,7 @@ import DiscordClient from '../DiscordClient.js';
|
|||||||
import MemberWrapper from '../components/wrappers/MemberWrapper.js';
|
import MemberWrapper from '../components/wrappers/MemberWrapper.js';
|
||||||
import Infraction from '../interfaces/Infraction.js';
|
import Infraction from '../interfaces/Infraction.js';
|
||||||
import { KickData } from '../../../@types/Infractions.js';
|
import { KickData } from '../../../@types/Infractions.js';
|
||||||
|
import UserWrapper from '../components/wrappers/UserWrapper.js';
|
||||||
|
|
||||||
class KickInfraction extends Infraction
|
class KickInfraction extends Infraction
|
||||||
{
|
{
|
||||||
@ -56,6 +57,7 @@ class KickInfraction extends Infraction
|
|||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to kick ${(this.target as UserWrapper).tag} (${this.target!.id}) from ${this.guild.name} (${this.guild.id})\n${error}`);
|
||||||
return this._fail('INFRACTION_ERROR');
|
return this._fail('INFRACTION_ERROR');
|
||||||
}
|
}
|
||||||
await this.handle();
|
await this.handle();
|
||||||
|
@ -59,6 +59,7 @@ class RemoveroleInfraction extends Infraction
|
|||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to remove roles (${this.data.roleIds!.join(', ')}) to ${this.member!.tag} (${this.member!.id})\n${error}`);
|
||||||
return this._fail('INFRACTION_ERROR');
|
return this._fail('INFRACTION_ERROR');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class UnbanInfraction extends Infraction
|
|||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to unban ${this.targetId} in ${this.guild.name} (${this.guild.id})\n${error}`);
|
||||||
return this._fail('INFRACTION_ERROR');
|
return this._fail('INFRACTION_ERROR');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +107,9 @@ class UnmuteInfraction extends Infraction
|
|||||||
{
|
{
|
||||||
this.member!.roles.remove(role, this._reason);
|
this.member!.roles.remove(role, this._reason);
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to unmute ${this.member.tag} (${this.member.id})\n${error}`);
|
||||||
return this._fail('C_UNMUTE_1FAIL');
|
return this._fail('C_UNMUTE_1FAIL');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,8 +132,9 @@ class UnmuteInfraction extends Infraction
|
|||||||
{
|
{
|
||||||
this.member.roles.remove(role, this._reason);
|
this.member.roles.remove(role, this._reason);
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
this.logger.error(`Failed to unmute ${this.member.tag} (${this.member.id})\n${error}`);
|
||||||
return this._fail('C_UNMUTE_1FAIL');
|
return this._fail('C_UNMUTE_1FAIL');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -234,6 +234,10 @@ class Infraction
|
|||||||
}).catch(() => null);
|
}).catch(() => null);
|
||||||
this.#dmLogMessageId = logMessage?.id ?? null;
|
this.#dmLogMessageId = logMessage?.id ?? null;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.logger.debug(`Target not sendable? ${inspect(this.#target)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.#duration)
|
if (this.#duration)
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
},
|
},
|
||||||
"compileOnSave": true,
|
"compileOnSave": true,
|
||||||
"exclude": ["archive", "api"],
|
"exclude": ["archive", "api"],
|
||||||
"include": ["src", "index.ts", "@types"],
|
"include": ["src/**/*", "index.ts", "@types/*"],
|
||||||
"watchOptions": {
|
"watchOptions": {
|
||||||
"watchFile": "useFsEvents",
|
"watchFile": "useFsEvents",
|
||||||
"watchDirectory": "useFsEvents",
|
"watchDirectory": "useFsEvents",
|
||||||
|
Loading…
Reference in New Issue
Block a user