123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- // We need some kind of module resolver for @shared/db. We use module-alias.
- require("module-alias/register");
- import dotenv from "dotenv";
- if (process.env.NODE_ENV == "dev") {
- dotenv.config({
- path: "../.env"
- });
- dotenv.config({
- path: "../db.env"
- });
- process.env.TYPEORM_HOST = "localhost";
- process.env.TYPEORM_USERNAME = process.env.DB_USERNAME;
- process.env.TYPEORM_PASSWORD = process.env.DB_PASSWORD;
- process.env.TYPEORM_DATABASE = process.env.DB_NAME;
- }
- import * as fs from "fs";
- import * as path from "path";
- import { client } from "./client";
- import * as mCmd from "./model/command";
- import "reflect-metadata";
- import { createConnection, getConnectionOptions } from "typeorm";
- import { getNumberEnums } from "./util";
- import { DB_ENTITIES } from "@shared/db/entities";
- import { BOT_COMMAND_DESCRIPTOR } from "./model/command";
- const REACT_PROBABILITY = 0.3;
- async function trigger(type: mCmd.ActionType, ...params: any[]) {
- let actionDone = false;
- let actions = botEvents[type];
- for (let i = 0; i < actions.length; i++) {
- const action = actions[i] as (...args: any[]) => boolean | Promise<boolean>;
- let actionResult = action(actionDone, ...params);
- if (actionResult instanceof Promise)
- actionDone = (await actionResult) || actionDone;
- else
- actionDone = actionResult || actionDone;
- }
- return actionDone;
- }
- let commandSets: mCmd.ICommand[] = [];
- let botCommands: mCmd.IBotCommand[] = [];
- let botEvents: { [event in mCmd.ActionType]: mCmd.BotAction[] } = getNumberEnums(mCmd.ActionType).reduce((p, c) => { p[c] = []; return p; }, {} as any);
- let startActions: Array<() => void | Promise<void>> = [];
- client.bot.on('ready', async () => {
- console.log("Starting up NoctBot!");
- client.botUser.setActivity(process.env.NODE_ENV == "dev" ? "Maintenance" : "@NoctBot help", {
- type: "PLAYING"
- });
- for (let i = 0; i < startActions.length; i++) {
- const action = startActions[i];
- let val = action();
- if (val instanceof Promise)
- await val;
- }
- console.log("NoctBot is ready!");
- });
- client.bot.on("message", async m => {
- if (m.author.id == client.botUser.id)
- return;
- if(process.env.FOOLS == "TRUE" && (m.channel.id == "297109482905796608" || m.channel.id == "429295461099110402") && Math.random() <= 0.01) {
- const neighs = ["*NEIGH*", "neeeeeigh!", "Gimme carrots!", "NEEEEIIIIGH", "**N E I G H**"];
- await m.channel.send(neighs[Math.floor(Math.random() * neighs.length)]);
- return;
- }
- let content = m.cleanContent.trim();
- if (await trigger(mCmd.ActionType.MESSAGE, m, content))
- return;
- if (m.mentions.users.size > 0 && m.mentions.users.has(client.botUser.id)) {
- if (m.content.trim().startsWith(client.botUser.id) || m.content.trim().startsWith(client.botUser.discriminator)) {
- content = content.substring(`@${client.botUser.username}`.length).trim();
- let lowerCaseContent = content.toLowerCase();
- for (let c of botCommands) {
- if (typeof (c.pattern) == "string" && lowerCaseContent.startsWith(c.pattern)) {
- c.action(m, content);
- return;
- }
- else if (c.pattern instanceof RegExp) {
- let result = c.pattern.exec(content);
- if (result != null) {
- c.action(m, content, result);
- return;
- }
- }
- }
- if (await trigger(mCmd.ActionType.DIRECT_MENTION, m, lowerCaseContent))
- return;
- }
- if (await trigger(mCmd.ActionType.INDIRECT_MENTION, m))
- return;
- }
- await trigger(mCmd.ActionType.POST_MESSAGE);
- });
- client.bot.on("messageReactionAdd", (r, u) => {
- if (Math.random() <= REACT_PROBABILITY && !u.bot) {
- console.log(`Reacting to message ${r.message.id} because user ${u.tag} reacted to it`);
- r.message.react(r.emoji);
- }
- });
- function loadCommand(mod: any) {
- for (let i in mod) {
- if (!mod.hasOwnProperty(i))
- continue;
- let commandClass = mod[i] as any;
- // Ensure this is indeed a command class
- if (!commandClass.prototype || commandClass.prototype.BOT_COMMAND !== BOT_COMMAND_DESCRIPTOR)
- continue;
- let cmd = new commandClass() as mCmd.ICommand;
- commandSets.push(cmd);
- if (cmd._botCommands)
- botCommands.push(...cmd._botCommands.map(c => ({ ...c, action: c.action.bind(cmd) })));
- if (cmd._botEvents)
- for (let [i, event] of Object.entries(cmd._botEvents)) {
- botEvents[+i as mCmd.ActionType].push((event as Function).bind(cmd));
- }
- if(cmd.onStart)
- startActions.push(cmd.onStart.bind(cmd));
- }
- }
- export function getDocumentation() {
- return botCommands.filter(m => m.documentation !== undefined).map(m => ({
- name: m.pattern.toString(),
- doc: m.documentation?.description,
- example: m.documentation?.example,
- auth: m.auth || false
- }));
- }
- async function main() {
- await createConnection({
- ...await getConnectionOptions(),
- entities: DB_ENTITIES
- });
- let commandsPath = path.resolve(path.dirname(module.filename), "commands");
- let files = fs.readdirSync(commandsPath);
- for (const file of files) {
- let ext = path.extname(file);
- if (ext != ".js")
- continue;
- loadCommand(require(path.resolve(commandsPath, file)));
- }
- client.bot.login(process.env.BOT_TOKEN);
- }
- main();
|