Feature/48 database (#114)
* Add database and default values * Add ability to save a setting to the database * Get commands and events to use database * Setup and config command * Update commands to check roles per server * Different rules per server Signed-off-by: Ethan Lane <ethan@vylpes.com> * Different prefix per server Signed-off-by: Ethan Lane <ethan@vylpes.com> * Add verification system Signed-off-by: Ethan Lane <ethan@vylpes.com> * Disabled commands per server * Add devmode for default prefix * Update embeds * Fix broken tests
This commit is contained in:
parent
c8edd1b4c5
commit
6a00c49ef3
53 changed files with 1816 additions and 373 deletions
|
@ -1,5 +1,7 @@
|
|||
import { Client } from "discord.js";
|
||||
import * as dotenv from "dotenv";
|
||||
import { createConnection } from "typeorm";
|
||||
import DefaultValues from "../constants/DefaultValues";
|
||||
import ICommandItem from "../contracts/ICommandItem";
|
||||
import IEventItem from "../contracts/IEventItem";
|
||||
import { Command } from "../type/command";
|
||||
|
@ -23,10 +25,12 @@ export class CoreClient extends Client {
|
|||
return this._eventItems;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
constructor(devmode: boolean = false) {
|
||||
super();
|
||||
dotenv.config();
|
||||
|
||||
DefaultValues.useDevPrefix = devmode;
|
||||
|
||||
this._commandItems = [];
|
||||
this._eventItems = [];
|
||||
|
||||
|
@ -34,11 +38,16 @@ export class CoreClient extends Client {
|
|||
this._util = new Util();
|
||||
}
|
||||
|
||||
public start() {
|
||||
if (!process.env.BOT_TOKEN) throw "BOT_TOKEN is not defined in .env";
|
||||
if (!process.env.BOT_PREFIX) throw "BOT_PREFIX is not defined in .env";
|
||||
if (!process.env.FOLDERS_COMMANDS) throw "FOLDERS_COMMANDS is not defined in .env";
|
||||
if (!process.env.FOLDERS_EVENTS) throw "FOLDERS_EVENTS is not defined in .env";
|
||||
public async start() {
|
||||
if (!process.env.BOT_TOKEN) {
|
||||
console.error("BOT_TOKEN is not defined in .env");
|
||||
return;
|
||||
}
|
||||
|
||||
await createConnection().catch(e => {
|
||||
console.error(e);
|
||||
return;
|
||||
});
|
||||
|
||||
super.on("message", (message) => this._events.onMessage(message, this._commandItems));
|
||||
super.on("ready", this._events.onReady);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Message } from "discord.js";
|
||||
import { IBaseResponse } from "../contracts/IBaseResponse";
|
||||
import ICommandItem from "../contracts/ICommandItem";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import { Util } from "./util";
|
||||
|
||||
export interface IEventResponse extends IBaseResponse {
|
||||
|
@ -21,7 +22,7 @@ export class Events {
|
|||
|
||||
// Emit when a message is sent
|
||||
// Used to check for commands
|
||||
public onMessage(message: Message, commands: ICommandItem[]): IEventResponse {
|
||||
public async onMessage(message: Message, commands: ICommandItem[]): Promise<IEventResponse> {
|
||||
if (!message.guild) return {
|
||||
valid: false,
|
||||
message: "Message was not sent in a guild, ignoring.",
|
||||
|
@ -32,7 +33,14 @@ export class Events {
|
|||
message: "Message was sent by a bot, ignoring.",
|
||||
};
|
||||
|
||||
const prefix = process.env.BOT_PREFIX as string;
|
||||
const prefix = await SettingsHelper.GetSetting("bot.prefix", message.guild.id);
|
||||
|
||||
if (!prefix) {
|
||||
return {
|
||||
valid: false,
|
||||
message: "Prefix not found",
|
||||
};
|
||||
}
|
||||
|
||||
if (message.content.substring(0, prefix.length).toLowerCase() == prefix.toLowerCase()) {
|
||||
const args = message.content.substring(prefix.length).split(" ");
|
||||
|
@ -43,7 +51,7 @@ export class Events {
|
|||
message: "Command name was not found",
|
||||
};
|
||||
|
||||
const res = this._util.loadCommand(name, args, message, commands);
|
||||
const res = await this._util.loadCommand(name, args, message, commands);
|
||||
|
||||
if (!res.valid) {
|
||||
return {
|
||||
|
|
|
@ -7,6 +7,10 @@ import { Event } from "../type/event";
|
|||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
import ICommandItem from "../contracts/ICommandItem";
|
||||
import IEventItem from "../contracts/IEventItem";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import StringTools from "../helpers/StringTools";
|
||||
import { CommandResponse } from "../constants/CommandResponse";
|
||||
import ErrorMessages from "../constants/ErrorMessages";
|
||||
|
||||
export interface IUtilResponse extends IBaseResponse {
|
||||
context?: {
|
||||
|
@ -18,13 +22,19 @@ export interface IUtilResponse extends IBaseResponse {
|
|||
|
||||
// Util Class
|
||||
export class Util {
|
||||
public loadCommand(name: string, args: string[], message: Message, commands: ICommandItem[]): IUtilResponse {
|
||||
public async loadCommand(name: string, args: string[], message: Message, commands: ICommandItem[]): Promise<IUtilResponse> {
|
||||
if (!message.member) return {
|
||||
valid: false,
|
||||
message: "Member is not part of message",
|
||||
};
|
||||
|
||||
const disabledCommands = process.env.COMMANDS_DISABLED?.split(',');
|
||||
if (!message.guild) return {
|
||||
valid: false,
|
||||
message: "Message is not part of a guild",
|
||||
};
|
||||
|
||||
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", message.guild?.id);
|
||||
const disabledCommands = disabledCommandsString?.split(",");
|
||||
|
||||
if (disabledCommands?.find(x => x == name)) {
|
||||
message.reply(process.env.COMMANDS_DISABLED_MESSAGE || "This command is disabled.");
|
||||
|
@ -51,13 +61,26 @@ export class Util {
|
|||
const requiredRoles = item.Command._roles;
|
||||
|
||||
for (const i in requiredRoles) {
|
||||
if (!message.member.roles.cache.find(role => role.name == requiredRoles[i])) {
|
||||
message.reply(`You require the \`${requiredRoles[i]}\` role to run this command`);
|
||||
if (message.guild) {
|
||||
const setting = await SettingsHelper.GetSetting(`role.${requiredRoles[i]}`, message.guild?.id);
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message: `You require the \`${requiredRoles[i]}\` role to run this command`
|
||||
};
|
||||
if (!setting) {
|
||||
message.reply("Unable to verify if you have this role, please contact your bot administrator");
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message: "Unable to verify if you have this role, please contact your bot administrator"
|
||||
};
|
||||
}
|
||||
|
||||
if (!message.member.roles.cache.find(role => role.name == setting)) {
|
||||
message.reply(`You require the \`${StringTools.Capitalise(setting)}\` role to run this command`);
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message: `You require the \`${StringTools.Capitalise(setting)}\` role to run this command`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +90,27 @@ export class Util {
|
|||
message: message
|
||||
};
|
||||
|
||||
const precheckResponse = item.Command.precheck(context);
|
||||
const precheckAsyncResponse = await item.Command.precheckAsync(context);
|
||||
|
||||
if (precheckResponse != CommandResponse.Ok) {
|
||||
message.reply(ErrorMessages.GetErrorMessage(precheckResponse));
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message: ErrorMessages.GetErrorMessage(precheckResponse)
|
||||
};
|
||||
}
|
||||
|
||||
if (precheckAsyncResponse != CommandResponse.Ok) {
|
||||
message.reply(ErrorMessages.GetErrorMessage(precheckAsyncResponse));
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message: ErrorMessages.GetErrorMessage(precheckAsyncResponse)
|
||||
};
|
||||
}
|
||||
|
||||
item.Command.execute(context);
|
||||
|
||||
return {
|
||||
|
|
|
@ -12,7 +12,7 @@ export default class Ban extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ export default class Ban extends Command {
|
|||
|
||||
await targetMember.ban({ reason: `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}` });
|
||||
|
||||
logEmbed.SendToModLogsChannel();
|
||||
await logEmbed.SendToModLogsChannel();
|
||||
publicEmbed.SendToCurrentChannel();
|
||||
|
||||
return {
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class Clear extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
|
|
94
src/commands/code.ts
Normal file
94
src/commands/code.ts
Normal file
|
@ -0,0 +1,94 @@
|
|||
import { CommandResponse } from "../constants/CommandResponse";
|
||||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import StringTools from "../helpers/StringTools";
|
||||
import { Command } from "../type/command";
|
||||
|
||||
export default class Code extends Command {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
public override async precheckAsync(context: ICommandContext): Promise<CommandResponse> {
|
||||
if (!context.message.guild){
|
||||
return CommandResponse.NotInServer;
|
||||
}
|
||||
|
||||
const isEnabled = await SettingsHelper.GetSetting("verification.enabled", context.message.guild?.id);
|
||||
|
||||
if (!isEnabled) {
|
||||
return CommandResponse.FeatureDisabled;
|
||||
}
|
||||
|
||||
if (isEnabled.toLocaleLowerCase() != 'true') {
|
||||
return CommandResponse.FeatureDisabled;
|
||||
}
|
||||
|
||||
return CommandResponse.Ok;
|
||||
}
|
||||
|
||||
public override async execute(context: ICommandContext) {
|
||||
const action = context.args[0];
|
||||
|
||||
switch (action) {
|
||||
case "randomise":
|
||||
await this.Randomise(context);
|
||||
break;
|
||||
case "embed":
|
||||
await this.SendEmbed(context);
|
||||
break;
|
||||
default:
|
||||
await this.SendUsage(context);
|
||||
}
|
||||
}
|
||||
|
||||
private async SendUsage(context: ICommandContext) {
|
||||
const description = [
|
||||
"USAGE: <randomise|embed>",
|
||||
"",
|
||||
"randomise: Sets the server's entry code to a random code",
|
||||
"embed: Sends an embed with the server's entry code"
|
||||
].join("\n");
|
||||
|
||||
const embed = new PublicEmbed(context, "", description);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async Randomise(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const randomCode = StringTools.RandomString(5);
|
||||
|
||||
await SettingsHelper.SetSetting("verification.code", context.message.guild.id, randomCode);
|
||||
|
||||
const embed = new PublicEmbed(context, "Code", `Entry code has been set to \`${randomCode}\``);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async SendEmbed(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const code = await SettingsHelper.GetSetting("verification.code", context.message.guild.id);
|
||||
|
||||
if (!code || code == "") {
|
||||
const errorEmbed = new ErrorEmbed(context, "There is no code for this server setup.");
|
||||
errorEmbed.SendToCurrentChannel();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const embed = new PublicEmbed(context, "Entry Code", code!);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
}
|
136
src/commands/config.ts
Normal file
136
src/commands/config.ts
Normal file
|
@ -0,0 +1,136 @@
|
|||
import { Guild } from "discord.js";
|
||||
import { readFileSync } from "fs";
|
||||
import { CommandResponse } from "../constants/CommandResponse";
|
||||
import DefaultValues from "../constants/DefaultValues";
|
||||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||
import Server from "../entity/Server";
|
||||
import Setting from "../entity/Setting";
|
||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||
import { Command } from "../type/command";
|
||||
|
||||
export default class Config extends Command {
|
||||
constructor() {
|
||||
super();
|
||||
super._category = "Administration";
|
||||
super._roles = [
|
||||
"administrator"
|
||||
]
|
||||
}
|
||||
|
||||
public override async precheckAsync(context: ICommandContext): Promise<CommandResponse> {
|
||||
if (!context.message.guild) {
|
||||
return CommandResponse.ServerNotSetup;
|
||||
}
|
||||
|
||||
const server = await Server.FetchOneById<Server>(Server, context.message.guild?.id, [
|
||||
"Settings",
|
||||
]);
|
||||
|
||||
if (!server) {
|
||||
return CommandResponse.ServerNotSetup;
|
||||
}
|
||||
|
||||
return CommandResponse.Ok;
|
||||
}
|
||||
|
||||
public override async execute(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const server = await Server.FetchOneById<Server>(Server, context.message.guild?.id, [
|
||||
"Settings",
|
||||
]);
|
||||
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
const key = context.args[0];
|
||||
const action = context.args[1];
|
||||
const value = context.args.splice(2).join(" ");
|
||||
|
||||
if (!key) {
|
||||
this.SendHelpText(context);
|
||||
} else if (!action) {
|
||||
this.GetValue(context, server, key);
|
||||
} else {
|
||||
switch(action) {
|
||||
case 'reset':
|
||||
this.ResetValue(context, server, key);
|
||||
break;
|
||||
case 'set':
|
||||
if (!value) {
|
||||
const errorEmbed = new ErrorEmbed(context, "Value is required when setting");
|
||||
errorEmbed.SendToCurrentChannel();
|
||||
return;
|
||||
}
|
||||
|
||||
this.SetValue(context, server, key, value);
|
||||
break;
|
||||
default:
|
||||
const errorEmbed = new ErrorEmbed(context, "Action must be either set or reset");
|
||||
errorEmbed.SendToCurrentChannel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async SendHelpText(context: ICommandContext) {
|
||||
const description = readFileSync(`${process.cwd()}/data/config.txt`).toString();
|
||||
|
||||
const embed = new PublicEmbed(context, "Config", description);
|
||||
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async GetValue(context: ICommandContext, server: Server, key: string) {
|
||||
const setting = server.Settings.filter(x => x.Key == key)[0];
|
||||
|
||||
if (setting) {
|
||||
const embed = new PublicEmbed(context, "", `${key}: ${setting.Value}`);
|
||||
embed.SendToCurrentChannel();
|
||||
} else {
|
||||
const embed = new PublicEmbed(context, "", `${key}: ${DefaultValues.GetValue(key)} <DEFAULT>`);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
}
|
||||
|
||||
private async ResetValue(context: ICommandContext, server: Server, key: string) {
|
||||
const setting = server.Settings.filter(x => x.Key == key)[0];
|
||||
|
||||
if (!setting) {
|
||||
const embed = new PublicEmbed(context, "", "Setting has been reset");
|
||||
embed.SendToCurrentChannel();
|
||||
return;
|
||||
}
|
||||
|
||||
await Setting.Remove(Setting, setting);
|
||||
|
||||
const embed = new PublicEmbed(context, "", "Setting has been reset");
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async SetValue(context: ICommandContext, server: Server, key: string, value: string) {
|
||||
const setting = server.Settings.filter(x => x.Key == key)[0];
|
||||
|
||||
if (setting) {
|
||||
setting.UpdateBasicDetails(key, value);
|
||||
|
||||
await setting.Save(Setting, setting);
|
||||
} else {
|
||||
const newSetting = new Setting(key, value);
|
||||
|
||||
await newSetting.Save(Setting, newSetting);
|
||||
|
||||
server.AddSettingToServer(newSetting);
|
||||
|
||||
await server.Save(Server, server);
|
||||
}
|
||||
|
||||
const embed = new PublicEmbed(context, "", "Setting has been set");
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
}
|
96
src/commands/disable.ts
Normal file
96
src/commands/disable.ts
Normal file
|
@ -0,0 +1,96 @@
|
|||
import { CommandResponse } from "../constants/CommandResponse";
|
||||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import StringTools from "../helpers/StringTools";
|
||||
import { Command } from "../type/command";
|
||||
|
||||
export default class Disable extends Command {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
public override async execute(context: ICommandContext) {
|
||||
const action = context.args[0];
|
||||
|
||||
switch (action) {
|
||||
case "add":
|
||||
await this.Add(context);
|
||||
break;
|
||||
case "remove":
|
||||
await this.Remove(context);
|
||||
break;
|
||||
default:
|
||||
await this.SendUsage(context);
|
||||
}
|
||||
}
|
||||
|
||||
private async SendUsage(context: ICommandContext) {
|
||||
const description = [
|
||||
"USAGE: <add|remove> <name>",
|
||||
"",
|
||||
"add: Adds the command name to the server's disabled command string",
|
||||
"remove: Removes the command name from the server's disabled command string",
|
||||
"name: The name of the command to enable/disable"
|
||||
].join("\n");
|
||||
|
||||
const embed = new PublicEmbed(context, "", description);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async Add(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const commandName = context.args[1];
|
||||
|
||||
if (!commandName) {
|
||||
this.SendUsage(context);
|
||||
return;
|
||||
}
|
||||
|
||||
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", context.message.guild.id);
|
||||
const disabledCommands = disabledCommandsString != "" ? disabledCommandsString?.split(",") : [];
|
||||
|
||||
disabledCommands?.push(commandName);
|
||||
|
||||
await SettingsHelper.SetSetting("commands.disabled", context.message.guild.id, disabledCommands!.join(","));
|
||||
|
||||
const embed = new PublicEmbed(context, "", `Disabled command: ${commandName}`);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
|
||||
private async Remove(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const commandName = context.args[1];
|
||||
|
||||
if (!commandName) {
|
||||
this.SendUsage(context);
|
||||
return;
|
||||
}
|
||||
|
||||
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", context.message.guild.id);
|
||||
const disabledCommands = disabledCommandsString != "" ? disabledCommandsString?.split(",") : [];
|
||||
|
||||
const disabledCommandsInstance = disabledCommands?.findIndex(x => x == commandName);
|
||||
|
||||
if (disabledCommandsInstance! > -1) {
|
||||
disabledCommands?.splice(disabledCommandsInstance!, 1);
|
||||
}
|
||||
|
||||
await SettingsHelper.SetSetting("commands.disabled", context.message.guild.id, disabledCommands!.join(","));
|
||||
|
||||
const embed = new PublicEmbed(context, "", `Enabled command: ${commandName}`);
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ export default class Kick extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ export default class Kick extends Command {
|
|||
|
||||
await targetMember.kick(`Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`);
|
||||
|
||||
logEmbed.SendToModLogsChannel();
|
||||
await logEmbed.SendToModLogsChannel();
|
||||
publicEmbed.SendToCurrentChannel();
|
||||
|
||||
return {
|
||||
|
|
|
@ -12,7 +12,7 @@ export default class Mute extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export default class Mute extends Command {
|
|||
|
||||
await targetMember.roles.add(mutedRole, `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`);
|
||||
|
||||
logEmbed.SendToModLogsChannel();
|
||||
await logEmbed.SendToModLogsChannel();
|
||||
publicEmbed.SendToCurrentChannel();
|
||||
|
||||
return {
|
||||
|
|
|
@ -18,12 +18,12 @@ export default class Rules extends Command {
|
|||
|
||||
super._category = "Admin";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"administrator"
|
||||
];
|
||||
}
|
||||
|
||||
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||
if (!existsSync(`${process.cwd()}/${process.env.COMMANDS_RULES_FILE!}`)) {
|
||||
if (!existsSync(`${process.cwd()}/data/rules/${context.message.guild?.id}.json`)) {
|
||||
const errorEmbed = new ErrorEmbed(context, "Rules file doesn't exist");
|
||||
errorEmbed.SendToCurrentChannel();
|
||||
|
||||
|
@ -33,7 +33,7 @@ export default class Rules extends Command {
|
|||
};
|
||||
}
|
||||
|
||||
const rulesFile = readFileSync(`${process.cwd()}/${process.env.COMMANDS_RULES_FILE}`).toString();
|
||||
const rulesFile = readFileSync(`${process.cwd()}/data/rules/${context.message.guild?.id}.json`).toString();
|
||||
const rules = JSON.parse(rulesFile) as IRules[];
|
||||
|
||||
const embeds: PublicEmbed[] = [];
|
||||
|
|
37
src/commands/setup.ts
Normal file
37
src/commands/setup.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||
import Server from "../entity/Server";
|
||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||
import { Command } from "../type/command";
|
||||
|
||||
export default class Setup extends Command {
|
||||
constructor() {
|
||||
super();
|
||||
super._category = "Administration";
|
||||
super._roles = [
|
||||
"moderator"
|
||||
]
|
||||
}
|
||||
|
||||
public override async execute(context: ICommandContext) {
|
||||
if (!context.message.guild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const server = await Server.FetchOneById(Server, context.message.guild?.id);
|
||||
|
||||
if (server) {
|
||||
const embed = new ErrorEmbed(context, "This server has already been setup, please configure using the config command");
|
||||
embed.SendToCurrentChannel();
|
||||
return;
|
||||
}
|
||||
|
||||
const newServer = new Server(context.message.guild?.id);
|
||||
|
||||
await newServer.Save(Server, newServer);
|
||||
|
||||
const embed = new PublicEmbed(context, "Success", "Please configure using the config command");
|
||||
embed.SendToCurrentChannel();
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ export default class Unmute extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export default class Unmute extends Command {
|
|||
|
||||
await targetMember.roles.remove(mutedRole, `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`);
|
||||
|
||||
logEmbed.SendToModLogsChannel();
|
||||
await logEmbed.SendToModLogsChannel();
|
||||
publicEmbed.SendToCurrentChannel();
|
||||
|
||||
return {
|
||||
|
|
|
@ -11,11 +11,11 @@ export default class Warn extends Command {
|
|||
|
||||
super._category = "Moderation";
|
||||
super._roles = [
|
||||
process.env.ROLES_MODERATOR!
|
||||
"moderator"
|
||||
];
|
||||
}
|
||||
|
||||
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||
const user = context.message.mentions.users.first();
|
||||
|
||||
if (!user) {
|
||||
|
@ -60,7 +60,7 @@ export default class Warn extends Command {
|
|||
const publicEmbed = new PublicEmbed(context, "", `${user} has been warned`);
|
||||
publicEmbed.AddReason(reason);
|
||||
|
||||
logEmbed.SendToModLogsChannel();
|
||||
await logEmbed.SendToModLogsChannel();
|
||||
publicEmbed.SendToCurrentChannel();
|
||||
|
||||
return {
|
||||
|
|
7
src/constants/CommandResponse.ts
Normal file
7
src/constants/CommandResponse.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export enum CommandResponse {
|
||||
Ok,
|
||||
Unauthorised,
|
||||
ServerNotSetup,
|
||||
NotInServer,
|
||||
FeatureDisabled,
|
||||
}
|
56
src/constants/DefaultValues.ts
Normal file
56
src/constants/DefaultValues.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
export default class DefaultValues {
|
||||
public static values: ISettingValue[] = [];
|
||||
public static useDevPrefix: boolean = false;
|
||||
|
||||
public static GetValue(key: string): string | undefined {
|
||||
this.SetValues();
|
||||
|
||||
const res = this.values.find(x => x.Key == key);
|
||||
|
||||
if (!res) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return res.Value;
|
||||
}
|
||||
|
||||
private static SetValues() {
|
||||
if (this.values.length == 0) {
|
||||
// Bot
|
||||
if (this.useDevPrefix) {
|
||||
this.values.push({ Key: "bot.prefix", Value: "d!" });
|
||||
} else {
|
||||
this.values.push({ Key: "bot.prefix", Value: "v!" });
|
||||
}
|
||||
|
||||
// Commands
|
||||
this.values.push({ Key: "commands.disabled", Value: "" });
|
||||
this.values.push({ Key: "commands.disabled.message", Value: "This command is disabled." });
|
||||
|
||||
// Role (Command)
|
||||
this.values.push({ Key: "role.assignable", Value: "" });
|
||||
this.values.push({ Key: "role.moderator", Value: "Moderator" });
|
||||
this.values.push({ Key: "role.administrator", Value: "Administrator"});
|
||||
this.values.push({ Key: "role.muted", Value: "Muted" });
|
||||
|
||||
// Rules (Command)
|
||||
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
||||
|
||||
// Channels
|
||||
this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
|
||||
this.values.push({ Key: "channels.logs.member", Value: "member-logs" });
|
||||
this.values.push({ Key: "channels.logs.mod", Value: "mod-logs" });
|
||||
|
||||
// Verification
|
||||
this.values.push({ Key: "verification.enabled", Value: "false" });
|
||||
this.values.push({ Key: "verification.channel", Value: "entry" });
|
||||
this.values.push({ Key: "verification.role", Value: "Entry" });
|
||||
this.values.push({ Key: "verification.code", Value: "" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface ISettingValue {
|
||||
Key: string,
|
||||
Value: string,
|
||||
};
|
|
@ -1,5 +1,27 @@
|
|||
import { CommandResponse } from "./CommandResponse";
|
||||
|
||||
export default class ErrorMessages {
|
||||
public static readonly InsufficientBotPermissions = "Unable to do this action, am I missing permissions?";
|
||||
public static readonly ChannelNotFound = "Unable to find channel";
|
||||
public static readonly RoleNotFound = "Unable to find role";
|
||||
|
||||
public static readonly UserUnauthorised = "You are not authorised to use this command";
|
||||
public static readonly ServerNotSetup = "This server hasn't been setup yet, please run the setup command";
|
||||
public static readonly NotInServer = "This command requires to be ran inside of a server";
|
||||
public static readonly FeatureDisabled = "This feature is currently disabled by a server moderator";
|
||||
|
||||
public static GetErrorMessage(response: CommandResponse): string {
|
||||
switch (response) {
|
||||
case CommandResponse.Unauthorised:
|
||||
return this.UserUnauthorised;
|
||||
case CommandResponse.ServerNotSetup:
|
||||
return this.ServerNotSetup;
|
||||
case CommandResponse.NotInServer:
|
||||
return this.NotInServer;
|
||||
case CommandResponse.FeatureDisabled:
|
||||
return this.FeatureDisabled;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
68
src/contracts/BaseEntity.ts
Normal file
68
src/contracts/BaseEntity.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import { Column, DeepPartial, EntityTarget, getConnection, PrimaryColumn } from "typeorm";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
export default class BaseEntity {
|
||||
constructor() {
|
||||
this.Id = v4();
|
||||
|
||||
this.WhenCreated = new Date();
|
||||
this.WhenUpdated = new Date();
|
||||
}
|
||||
|
||||
@PrimaryColumn()
|
||||
Id: string;
|
||||
|
||||
@Column()
|
||||
WhenCreated: Date;
|
||||
|
||||
@Column()
|
||||
WhenUpdated: Date;
|
||||
|
||||
public async Save<T>(target: EntityTarget<T>, entity: DeepPartial<T>): Promise<void> {
|
||||
this.WhenUpdated = new Date();
|
||||
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository<T>(target);
|
||||
|
||||
await repository.save(entity);
|
||||
}
|
||||
|
||||
public static async Remove<T>(target: EntityTarget<T>, entity: T): Promise<void> {
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository<T>(target);
|
||||
|
||||
await repository.remove(entity);
|
||||
}
|
||||
|
||||
public static async FetchAll<T>(target: EntityTarget<T>, relations?: string[]): Promise<T[]> {
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository<T>(target);
|
||||
|
||||
const all = await repository.find({ relations: relations || [] });
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
public static async FetchOneById<T>(target: EntityTarget<T>, id: string, relations?: string[]): Promise<T | undefined> {
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository<T>(target);
|
||||
|
||||
const single = await repository.findOne(id, { relations: relations || [] });
|
||||
|
||||
return single;
|
||||
}
|
||||
|
||||
public static async Any<T>(target: EntityTarget<T>): Promise<boolean> {
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository<T>(target);
|
||||
|
||||
const any = await repository.find();
|
||||
|
||||
return any.length > 0;
|
||||
}
|
||||
}
|
19
src/entity/Server.ts
Normal file
19
src/entity/Server.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { Column, Entity, getConnection, OneToMany } from "typeorm";
|
||||
import BaseEntity from "../contracts/BaseEntity";
|
||||
import Setting from "./Setting";
|
||||
|
||||
@Entity()
|
||||
export default class Server extends BaseEntity {
|
||||
constructor(serverId: string) {
|
||||
super();
|
||||
|
||||
this.Id = serverId;
|
||||
}
|
||||
|
||||
@OneToMany(() => Setting, x => x.Server)
|
||||
Settings: Setting[];
|
||||
|
||||
public AddSettingToServer(setting: Setting) {
|
||||
this.Settings.push(setting);
|
||||
}
|
||||
}
|
37
src/entity/Setting.ts
Normal file
37
src/entity/Setting.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { Column, Entity, getConnection, ManyToOne } from "typeorm";
|
||||
import BaseEntity from "../contracts/BaseEntity";
|
||||
import Server from "./Server";
|
||||
|
||||
@Entity()
|
||||
export default class Setting extends BaseEntity {
|
||||
constructor(key: string, value: string) {
|
||||
super();
|
||||
|
||||
this.Key = key;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
@Column()
|
||||
Key: string;
|
||||
|
||||
@Column()
|
||||
Value: string;
|
||||
|
||||
@ManyToOne(() => Server, x => x.Settings)
|
||||
Server: Server;
|
||||
|
||||
public UpdateBasicDetails(key: string, value: string) {
|
||||
this.Key = key;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public static async FetchOneByKey(key: string, relations?: string[]): Promise<Setting | undefined> {
|
||||
const connection = getConnection();
|
||||
|
||||
const repository = connection.getRepository(Setting);
|
||||
|
||||
const single = await repository.findOne({ Key: key }, { relations: relations || [] });
|
||||
|
||||
return single;
|
||||
}
|
||||
}
|
|
@ -9,37 +9,37 @@ export default class MemberEvents extends Event {
|
|||
super();
|
||||
}
|
||||
|
||||
public override guildMemberAdd(member: GuildMember): IEventReturnContext {
|
||||
public override async guildMemberAdd(member: GuildMember): Promise<IEventReturnContext> {
|
||||
const embed = new EventEmbed(member.guild, "Member Joined");
|
||||
embed.AddUser("User", member.user, true);
|
||||
embed.addField("Created", member.user.createdAt);
|
||||
embed.setFooter(`Id: ${member.user.id}`);
|
||||
|
||||
embed.SendToMemberLogsChannel();
|
||||
await embed.SendToMemberLogsChannel();
|
||||
|
||||
return {
|
||||
embeds: [embed]
|
||||
};
|
||||
}
|
||||
|
||||
public override guildMemberRemove(member: GuildMember): IEventReturnContext {
|
||||
public override async guildMemberRemove(member: GuildMember): Promise<IEventReturnContext> {
|
||||
const embed = new EventEmbed(member.guild, "Member Left");
|
||||
embed.AddUser("User", member.user, true);
|
||||
embed.addField("Joined", member.joinedAt);
|
||||
embed.setFooter(`Id: ${member.user.id}`);
|
||||
|
||||
embed.SendToMemberLogsChannel();
|
||||
await embed.SendToMemberLogsChannel();
|
||||
|
||||
return {
|
||||
embeds: [embed]
|
||||
};
|
||||
}
|
||||
|
||||
public override guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember): IEventReturnContext {
|
||||
public override async guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember): Promise<IEventReturnContext> {
|
||||
const handler = new GuildMemberUpdate(oldMember, newMember);
|
||||
|
||||
if (oldMember.nickname != newMember.nickname) { // Nickname change
|
||||
handler.NicknameChanged();
|
||||
await handler.NicknameChanged();
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class GuildMemberUpdate {
|
|||
this.newMember = newMember;
|
||||
}
|
||||
|
||||
public NicknameChanged(): IEventReturnContext {
|
||||
public async NicknameChanged(): Promise<IEventReturnContext> {
|
||||
const oldNickname = this.oldMember.nickname || "*none*";
|
||||
const newNickname = this.newMember.nickname || "*none*";
|
||||
|
||||
|
@ -21,7 +21,7 @@ export default class GuildMemberUpdate {
|
|||
embed.addField("After", newNickname, true);
|
||||
embed.setFooter(`Id: ${this.newMember.user.id}`);
|
||||
|
||||
embed.SendToMemberLogsChannel();
|
||||
await embed.SendToMemberLogsChannel();
|
||||
|
||||
return {
|
||||
embeds: [embed]
|
||||
|
|
|
@ -2,13 +2,15 @@ import { Event } from "../type/event";
|
|||
import { Message } from "discord.js";
|
||||
import EventEmbed from "../helpers/embeds/EventEmbed";
|
||||
import IEventReturnContext from "../contracts/IEventReturnContext";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import OnMessage from "./MessageEvents/OnMessage";
|
||||
|
||||
export default class MessageEvents extends Event {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public override messageDelete(message: Message): IEventReturnContext {
|
||||
public override async messageDelete(message: Message): Promise<IEventReturnContext> {
|
||||
if (!message.guild) {
|
||||
return {
|
||||
embeds: []
|
||||
|
@ -30,14 +32,14 @@ export default class MessageEvents extends Event {
|
|||
embed.addField("Attachments", `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\``);
|
||||
}
|
||||
|
||||
embed.SendToMessageLogsChannel();
|
||||
await embed.SendToMessageLogsChannel();
|
||||
|
||||
return {
|
||||
embeds: [embed]
|
||||
};
|
||||
}
|
||||
|
||||
public override messageUpdate(oldMessage: Message, newMessage: Message): IEventReturnContext {
|
||||
public override async messageUpdate(oldMessage: Message, newMessage: Message): Promise<IEventReturnContext> {
|
||||
if (!newMessage.guild){
|
||||
return {
|
||||
embeds: []
|
||||
|
@ -62,10 +64,21 @@ export default class MessageEvents extends Event {
|
|||
embed.addField("Before", `\`\`\`${oldMessage.content || "*none*"}\`\`\``);
|
||||
embed.addField("After", `\`\`\`${newMessage.content || "*none*"}\`\`\``);
|
||||
|
||||
embed.SendToMessageLogsChannel();
|
||||
await embed.SendToMessageLogsChannel();
|
||||
|
||||
return {
|
||||
embeds: [embed]
|
||||
};
|
||||
}
|
||||
|
||||
public override async message(message: Message) {
|
||||
if (!message.guild) return;
|
||||
if (message.author.bot) return;
|
||||
|
||||
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
|
||||
|
||||
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {
|
||||
await OnMessage.VerificationCheck(message);
|
||||
}
|
||||
}
|
||||
}
|
59
src/events/MessageEvents/OnMessage.ts
Normal file
59
src/events/MessageEvents/OnMessage.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
import { Message as Message } from "discord.js";
|
||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||
|
||||
export default class OnMessage {
|
||||
public static async VerificationCheck(message: Message) {
|
||||
if (!message.guild) return;
|
||||
|
||||
const verificationChannel = await SettingsHelper.GetSetting("verification.channel", message.guild.id);
|
||||
|
||||
if (!verificationChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = message.guild.channels.cache.find(x => x.name == verificationChannel);
|
||||
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentChannel = message.guild.channels.cache.find(x => x == message.channel);
|
||||
|
||||
if (!currentChannel || currentChannel.name != verificationChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const verificationCode = await SettingsHelper.GetSetting("verification.code", message.guild.id);
|
||||
|
||||
if (!verificationCode || verificationCode == "") {
|
||||
await message.reply("`verification.code` is not set inside of the server's config. Please contact the server's mod team.");
|
||||
await message.delete();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const verificationRoleName = await SettingsHelper.GetSetting("verification.role", message.guild.id);
|
||||
|
||||
if (!verificationRoleName) {
|
||||
await message.reply("`verification.role` is not set inside of the server's config. Please contact the server's mod team.");
|
||||
await message.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
const role = message.guild.roles.cache.find(x => x.name == verificationRoleName);
|
||||
|
||||
if (!role) {
|
||||
await message.reply("The entry role configured for this server does not exist. Please contact the server's mod team.");
|
||||
await message.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.content.toLocaleLowerCase() != verificationCode.toLocaleLowerCase()) {
|
||||
await message.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
await message.member?.roles.add(role);
|
||||
await message.delete();
|
||||
}
|
||||
}
|
50
src/helpers/SettingsHelper.ts
Normal file
50
src/helpers/SettingsHelper.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { getConnection } from "typeorm";
|
||||
import DefaultValues from "../constants/DefaultValues";
|
||||
import Server from "../entity/Server";
|
||||
import Setting from "../entity/Setting";
|
||||
|
||||
export default class SettingsHelper {
|
||||
public static async GetSetting(key: string, serverId: string): Promise<string | undefined> {
|
||||
const server = await Server.FetchOneById(Server, serverId, [
|
||||
"Settings"
|
||||
]);
|
||||
|
||||
if (!server) {
|
||||
return DefaultValues.GetValue(key);
|
||||
}
|
||||
|
||||
const setting = server.Settings.filter(x => x.Key == key)[0];
|
||||
|
||||
if (!setting) {
|
||||
return DefaultValues.GetValue(key);
|
||||
}
|
||||
|
||||
return setting.Value;
|
||||
}
|
||||
|
||||
public static async SetSetting(key: string, serverId: string, value: string): Promise<void> {
|
||||
const server = await Server.FetchOneById(Server, serverId, [
|
||||
"Settings"
|
||||
]);
|
||||
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
const setting = server.Settings.filter(x => x.Key == key)[0];
|
||||
|
||||
if (setting) {
|
||||
setting.UpdateBasicDetails(key, value);
|
||||
|
||||
await setting.Save(Setting, setting);
|
||||
} else {
|
||||
const newSetting = new Setting(key, value);
|
||||
|
||||
await newSetting.Save(Setting, newSetting);
|
||||
|
||||
server.AddSettingToServer(newSetting);
|
||||
|
||||
await server.Save(Server, server);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,4 +12,17 @@ export default class StringTools {
|
|||
|
||||
return result.join(" ");
|
||||
}
|
||||
|
||||
public static RandomString(length: number) {
|
||||
let result = "";
|
||||
|
||||
const characters = 'abcdefghkmnpqrstuvwxyz23456789';
|
||||
const charactersLength = characters.length;
|
||||
|
||||
for ( var i = 0; i < length; i++ ) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ export default class ErrorEmbed extends MessageEmbed {
|
|||
constructor(context: ICommandContext, message: String) {
|
||||
super();
|
||||
|
||||
super.setColor(process.env.EMBED_COLOUR_ERROR!);
|
||||
super.setColor(0xd52803);
|
||||
super.setDescription(message);
|
||||
|
||||
this.context = context;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { MessageEmbed, TextChannel, User, Guild } from "discord.js";
|
||||
import { ICommandContext } from "../../contracts/ICommandContext";
|
||||
import SettingsHelper from "../SettingsHelper";
|
||||
|
||||
export default class EventEmbed extends MessageEmbed {
|
||||
public guild: Guild;
|
||||
|
@ -6,7 +8,7 @@ export default class EventEmbed extends MessageEmbed {
|
|||
constructor(guild: Guild, title: string) {
|
||||
super();
|
||||
|
||||
super.setColor(process.env.EMBED_COLOUR!);
|
||||
super.setColor(0x3050ba);
|
||||
super.setTitle(title);
|
||||
|
||||
this.guild = guild;
|
||||
|
@ -38,15 +40,33 @@ export default class EventEmbed extends MessageEmbed {
|
|||
channel.send(this);
|
||||
}
|
||||
|
||||
public SendToMessageLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MESSAGE!)
|
||||
public async SendToMessageLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.message", this.guild.id);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
|
||||
public SendToMemberLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MEMBER!)
|
||||
public async SendToMemberLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.member", this.guild.id);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
|
||||
public SendToModLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MOD!)
|
||||
public async SendToModLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.mod", this.guild.id);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { MessageEmbed, TextChannel, User } from "discord.js";
|
||||
import ErrorMessages from "../../constants/ErrorMessages";
|
||||
import { ICommandContext } from "../../contracts/ICommandContext";
|
||||
import SettingsHelper from "../SettingsHelper";
|
||||
import ErrorEmbed from "./ErrorEmbed";
|
||||
|
||||
export default class LogEmbed extends MessageEmbed {
|
||||
|
@ -9,7 +10,7 @@ export default class LogEmbed extends MessageEmbed {
|
|||
constructor(context: ICommandContext, title: string) {
|
||||
super();
|
||||
|
||||
super.setColor(process.env.EMBED_COLOUR!);
|
||||
super.setColor(0x3050ba);
|
||||
super.setTitle(title);
|
||||
|
||||
this.context = context;
|
||||
|
@ -46,15 +47,33 @@ export default class LogEmbed extends MessageEmbed {
|
|||
channel.send(this);
|
||||
}
|
||||
|
||||
public SendToMessageLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MESSAGE!)
|
||||
public async SendToMessageLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.message", this.context.message.guild?.id!);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
|
||||
public SendToMemberLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MEMBER!)
|
||||
public async SendToMemberLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.member", this.context.message.guild?.id!);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
|
||||
public SendToModLogsChannel() {
|
||||
this.SendToChannel(process.env.CHANNELS_LOGS_MOD!)
|
||||
public async SendToModLogsChannel() {
|
||||
const channelName = await SettingsHelper.GetSetting("channels.logs.mod", this.context.message.guild?.id!);
|
||||
|
||||
if (!channelName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.SendToChannel(channelName);
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ export default class PublicEmbed extends MessageEmbed {
|
|||
constructor(context: ICommandContext, title: string, description: string) {
|
||||
super();
|
||||
|
||||
super.setColor(process.env.EMBED_COLOUR!);
|
||||
super.setColor(0x3050ba);
|
||||
super.setTitle(title);
|
||||
super.setDescription(description);
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@ import { CoreClient } from "./client/client";
|
|||
import About from "./commands/about";
|
||||
import Ban from "./commands/ban";
|
||||
import Clear from "./commands/clear";
|
||||
import Code from "./commands/code";
|
||||
import Config from "./commands/config";
|
||||
import Disable from "./commands/disable";
|
||||
import Evaluate from "./commands/eval";
|
||||
import Help from "./commands/help";
|
||||
import Kick from "./commands/kick";
|
||||
|
@ -9,12 +12,13 @@ import Mute from "./commands/mute";
|
|||
import Poll from "./commands/poll";
|
||||
import Role from "./commands/role";
|
||||
import Rules from "./commands/rules";
|
||||
import Setup from "./commands/setup";
|
||||
import Unmute from "./commands/unmute";
|
||||
import Warn from "./commands/warn";
|
||||
import MemberEvents from "./events/MemberEvents";
|
||||
import MessageEvents from "./events/MessageEvents";
|
||||
|
||||
export default class Register {
|
||||
export default class Registry {
|
||||
public static RegisterCommands(client: CoreClient) {
|
||||
client.RegisterCommand("about", new About());
|
||||
client.RegisterCommand("ban", new Ban());
|
||||
|
@ -28,6 +32,10 @@ export default class Register {
|
|||
client.RegisterCommand("rules", new Rules());
|
||||
client.RegisterCommand("unmute", new Unmute());
|
||||
client.RegisterCommand("warn", new Warn());
|
||||
client.RegisterCommand("setup", new Setup());
|
||||
client.RegisterCommand("config", new Config());
|
||||
client.RegisterCommand("code", new Code());
|
||||
client.RegisterCommand("disable", new Disable())
|
||||
}
|
||||
|
||||
public static RegisterEvents(client: CoreClient) {
|
|
@ -1,3 +1,4 @@
|
|||
import { CommandResponse } from "../constants/CommandResponse";
|
||||
import { ICommandContext } from "../contracts/ICommandContext";
|
||||
|
||||
export class Command {
|
||||
|
@ -9,6 +10,14 @@ export class Command {
|
|||
this._roles = [];
|
||||
}
|
||||
|
||||
public precheck(context: ICommandContext): CommandResponse {
|
||||
return CommandResponse.Ok;
|
||||
}
|
||||
|
||||
public async precheckAsync(context: ICommandContext): Promise<CommandResponse> {
|
||||
return CommandResponse.Ok;
|
||||
}
|
||||
|
||||
public execute(context: ICommandContext) {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
import { CoreClient } from "./client/client";
|
||||
import * as dotenv from "dotenv";
|
||||
import Register from "./Register";
|
||||
import registry from "./registry";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const requiredConfigs = [
|
||||
"EMBED_COLOUR",
|
||||
"EMBED_COLOUR_ERROR",
|
||||
"ROLES_MODERATOR",
|
||||
"ROLES_MUTED",
|
||||
"CHANNELS_LOGS_MESSAGE",
|
||||
"CHANNELS_LOGS_MEMBER",
|
||||
"CHANNELS_LOGS_MOD",
|
||||
"COMMANDS_ROLE_ROLES",
|
||||
"COMMANDS_RULES_FILE"
|
||||
const requiredConfigs: string[] = [
|
||||
"BOT_TOKEN",
|
||||
"BOT_VER",
|
||||
"BOT_AUTHOR",
|
||||
"BOT_DATE",
|
||||
"BOT_OWNERID",
|
||||
];
|
||||
|
||||
requiredConfigs.forEach(config => {
|
||||
|
@ -22,9 +18,11 @@ requiredConfigs.forEach(config => {
|
|||
}
|
||||
});
|
||||
|
||||
const client = new CoreClient();
|
||||
const devmode = process.argv.find(x => x.toLowerCase() == "--dev") != null;
|
||||
|
||||
Register.RegisterCommands(client);
|
||||
Register.RegisterEvents(client);
|
||||
const client = new CoreClient(devmode);
|
||||
|
||||
registry.RegisterCommands(client);
|
||||
registry.RegisterEvents(client);
|
||||
|
||||
client.start();
|
Loading…
Add table
Add a link
Reference in a new issue