mirror of
				https://github.com/janderedev/automod.git
				synced 2025-11-04 10:34:50 +00:00 
			
		
		
		
	code
This commit is contained in:
		
							parent
							
								
									e23e128850
								
							
						
					
					
						commit
						3e1da96360
					
				
							
								
								
									
										14
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
{
 | 
			
		||||
    // Use IntelliSense to learn about possible attributes.
 | 
			
		||||
    // Hover to view descriptions of existing attributes.
 | 
			
		||||
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 | 
			
		||||
    "version": "0.2.0",
 | 
			
		||||
    "configurations": [
 | 
			
		||||
        {
 | 
			
		||||
            "command": "yarn dev",
 | 
			
		||||
            "name": "Debug",
 | 
			
		||||
            "request": "launch",
 | 
			
		||||
            "type": "node-terminal"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/bot/commands/debug.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/bot/commands/debug.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
import Command from "../../struct/Command";
 | 
			
		||||
import { Message } from "revolt.js/dist/maps/Messages";
 | 
			
		||||
import { hasPerm } from "../util";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'debug',
 | 
			
		||||
    aliases: null,
 | 
			
		||||
    description: 'give info helpful for development and debugging',
 | 
			
		||||
    serverOnly: false,
 | 
			
		||||
    run: (message: Message, args: string[]) => {
 | 
			
		||||
        message.reply(`Server ID: ${message.channel?.server_id || 'None'}\n`
 | 
			
		||||
                    + `Channel ID: ${message.channel_id}\n`
 | 
			
		||||
                    + `User ID: ${message.author_id}`);
 | 
			
		||||
 | 
			
		||||
        console.log(hasPerm(message.member!, 'BanMembers'));
 | 
			
		||||
    }
 | 
			
		||||
} as Command;
 | 
			
		||||
							
								
								
									
										20
									
								
								src/bot/commands/ping.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/bot/commands/ping.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
import Command from "../../struct/Command";
 | 
			
		||||
import { Message } from "revolt.js/dist/maps/Messages";
 | 
			
		||||
import { client } from "../..";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'ping',
 | 
			
		||||
    aliases: null,
 | 
			
		||||
    description: 'ping pong',
 | 
			
		||||
    serverOnly: false,
 | 
			
		||||
    run: async (message: Message, args: string[]) => {
 | 
			
		||||
        let now = Date.now();
 | 
			
		||||
        message.reply(`Measuring...`)
 | 
			
		||||
            ?.catch(console.error)
 | 
			
		||||
            .then(msg => {
 | 
			
		||||
                msg?.edit({ content:  `## Ping Pong!\n`
 | 
			
		||||
                                    + `WS: \`${client.websocket.ping ?? '--'}ms\`\n`
 | 
			
		||||
                                    + `Msg: \`${Math.round(Date.now() - now) / 2}ms\`` });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
} as Command;
 | 
			
		||||
							
								
								
									
										74
									
								
								src/bot/commands/prefix.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/bot/commands/prefix.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
import Command from "../../struct/Command";
 | 
			
		||||
import { Message } from "revolt.js/dist/maps/Messages";
 | 
			
		||||
import { client } from "../..";
 | 
			
		||||
import ServerConfig from "../../struct/ServerConfig";
 | 
			
		||||
import { DEFAULT_PREFIX } from "../modules/command_handler";
 | 
			
		||||
import { hasPerm } from "../util";
 | 
			
		||||
 | 
			
		||||
const SYNTAX = '/prefix set [new prefix]; /prefix get; prefix clear';
 | 
			
		||||
const MENTION_TEXT = 'You can also @mention me instead of using the prefix.';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'prefix',
 | 
			
		||||
    aliases: null,
 | 
			
		||||
    description: 'modify prefix',
 | 
			
		||||
    syntax: SYNTAX,
 | 
			
		||||
    serverOnly: true,
 | 
			
		||||
    run: async (message: Message, args: string[]) => {
 | 
			
		||||
        let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.channel?.server_id })) ?? {};
 | 
			
		||||
        switch(args[0]?.toLowerCase()) {
 | 
			
		||||
            case 'set':
 | 
			
		||||
                if (!hasPerm(message.member!, 'ManageServer')) return message.reply('You need ManageServer permission for this.');
 | 
			
		||||
 | 
			
		||||
                args.shift();
 | 
			
		||||
                if (args.length == 0) return message.reply('You need to specify a prefix.');
 | 
			
		||||
                let newPrefix = args.join(' ').trim();
 | 
			
		||||
                let oldPrefix = config.prefix ?? DEFAULT_PREFIX;
 | 
			
		||||
 | 
			
		||||
                let val = validatePrefix(newPrefix);
 | 
			
		||||
                if (typeof val != 'boolean') {
 | 
			
		||||
                    return message.reply(val);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await client.db.get('servers').update({ 'id': message.channel?.server_id }, { $set: { 'prefix': newPrefix } });
 | 
			
		||||
 | 
			
		||||
                message.reply(`✅ Prefix has been changed from \`${oldPrefix}\` to \`${newPrefix}\`.\n${MENTION_TEXT}`);
 | 
			
		||||
            break;
 | 
			
		||||
            case 'get':
 | 
			
		||||
            case undefined:
 | 
			
		||||
                if (config.prefix) message.reply(`This server's prefix is \`${config.prefix}\`.\n${MENTION_TEXT}`);
 | 
			
		||||
                else message.reply(`This server uses the default prefix \`${DEFAULT_PREFIX}\`.\n${MENTION_TEXT}`);
 | 
			
		||||
            break;
 | 
			
		||||
            case 'clear':
 | 
			
		||||
            case 'reset':
 | 
			
		||||
                if (!hasPerm(message.member!, 'ManageServer')) return message.reply('You need ManageServer permission for this.');
 | 
			
		||||
                
 | 
			
		||||
                if (config.prefix != null) {
 | 
			
		||||
                    await client.db.get('servers').update({ 'id': message.channel?.server_id }, { $set: { 'prefix': null } });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                message.reply(`✅ Prefix has been reset to the default: \`${DEFAULT_PREFIX}\`.`);
 | 
			
		||||
            break;
 | 
			
		||||
            default:
 | 
			
		||||
                message.reply(`Unknown action. Correct syntax: \`${SYNTAX}\``);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
} as Command;
 | 
			
		||||
 | 
			
		||||
function validatePrefix(prefix: string): string|true {
 | 
			
		||||
    // Check length
 | 
			
		||||
    if (prefix.length > 32) return 'Prefix may not be longer than 32 characters';
 | 
			
		||||
 | 
			
		||||
    // Check for forbidden characters
 | 
			
		||||
    let matched = [];
 | 
			
		||||
    for (const char of ['`', '\n', '#']) {
 | 
			
		||||
        if (prefix.indexOf(char) > -1) matched.push(char);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (matched.length > 0) return `Prefix may not contain the following characters: `
 | 
			
		||||
                                + `${matched.map(char => char).join(', ')
 | 
			
		||||
                                .replace(new RegExp('\n', 'g'), '\\n')}`;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
import Command from "../../struct/Command";
 | 
			
		||||
import { client } from "../..";
 | 
			
		||||
import { Message } from "revolt.js/dist/maps/Messages";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,9 +20,9 @@ function getDBUrl() {
 | 
			
		|||
 | 
			
		||||
    // mongodb://username:password@hostname:port/dbname
 | 
			
		||||
    let dburl = 'mongodb://';
 | 
			
		||||
    dburl += env['DB_USERNAME'] ?? 'root';
 | 
			
		||||
    if (env['DB_PASSWORD']) dburl += `:${env['DB_PASSWORD']}`;
 | 
			
		||||
    dburl += `@${env['DB_HOST']}`; // DB_HOST is assumed to contain the port
 | 
			
		||||
    if (env['DB_USERNAME']) dburl += env['DB_USERNAME'];
 | 
			
		||||
    if (env['DB_PASS']) dburl += `:${env['DB_PASS']}`;
 | 
			
		||||
    dburl += `${process.env['DB_USERNAME'] ? '@' : ''}${env['DB_HOST']}`; // DB_HOST is assumed to contain the port
 | 
			
		||||
    dburl += `/${env['DB_NAME'] ?? 'automod'}`;
 | 
			
		||||
 | 
			
		||||
    return dburl;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ import logger from "../logger";
 | 
			
		|||
import { client } from "../../index";
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import ServerConfig from "../../struct/ServerConfig";
 | 
			
		||||
 | 
			
		||||
const DEFAULT_PREFIX = process.env['PREFIX'] ?? '/';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,17 +13,29 @@ let commands: Command[] = fs.readdirSync(path.join(__dirname, '..', 'commands'))
 | 
			
		|||
 | 
			
		||||
client.on('message', async message => {
 | 
			
		||||
    logger.debug(`Message -> ${message.content}`);
 | 
			
		||||
    if (typeof message.content != 'string') return; // Ignore system messages
 | 
			
		||||
    if (typeof message.content != 'string' || message.author_id == client.user?._id || !message.channel) return;
 | 
			
		||||
 | 
			
		||||
    if (!message.content.startsWith(DEFAULT_PREFIX)) return;
 | 
			
		||||
    let config: ServerConfig = (await client.db.get('servers').findOne({ 'id': message.channel?.server_id })) ?? {};
 | 
			
		||||
    let guildPrefix = config.prefix ?? DEFAULT_PREFIX;
 | 
			
		||||
 | 
			
		||||
    let args = message.content.split(' ');
 | 
			
		||||
    let cmdName = args.shift()?.substr(DEFAULT_PREFIX.length);
 | 
			
		||||
    let cmdName = args.shift() ?? '';
 | 
			
		||||
 | 
			
		||||
    if (cmdName.startsWith(`<@${client.user?._id}>`)) {
 | 
			
		||||
        cmdName = cmdName.substr(`<@${client.user?._id}>`.length);
 | 
			
		||||
        if (!cmdName) cmdName = args.shift() ?? ''; // Space between mention and command name
 | 
			
		||||
    } else if (cmdName.startsWith(guildPrefix)) {
 | 
			
		||||
        cmdName = cmdName.substr(guildPrefix.length);
 | 
			
		||||
        if (config.spaceAfterPrefix && !cmdName) cmdName = args.shift() ?? '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!cmdName) return;
 | 
			
		||||
 | 
			
		||||
    let cmd = commands.find(c => c.name == cmdName || (c.aliases?.indexOf(cmdName!) ?? -1) > -1);
 | 
			
		||||
    if (!cmd) return;
 | 
			
		||||
 | 
			
		||||
    logger.info(`Command: ${message.author?.username} in ${message.channel?.server?.name}: ${message.content}`);
 | 
			
		||||
 | 
			
		||||
    if (cmd.serverOnly && !message.channel?.server) {
 | 
			
		||||
        return message.reply('This command is not available in direct messages.');
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -33,3 +46,5 @@ client.on('message', async message => {
 | 
			
		|||
        message.reply(`### An error has occurred:\n\`\`\`js\n${e}\n\`\`\``);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export { DEFAULT_PREFIX }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								src/bot/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/bot/util.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
import { Member } from "revolt.js/dist/maps/Members";
 | 
			
		||||
 | 
			
		||||
let ServerPermissions = {
 | 
			
		||||
    ['View' as string]: 1 << 0,
 | 
			
		||||
    ['ManageRoles' as string]: 1 << 1,
 | 
			
		||||
    ['ManageChannels' as string]: 1 << 2,
 | 
			
		||||
    ['ManageServer' as string]: 1 << 3,
 | 
			
		||||
    ['KickMembers' as string]: 1 << 4,
 | 
			
		||||
    ['BanMembers' as string]: 1 << 5,
 | 
			
		||||
    ['ChangeNickname' as string]: 1 << 12,
 | 
			
		||||
    ['ManageNicknames' as string]: 1 << 13,
 | 
			
		||||
    ['ChangeAvatar' as string]: 1 << 14,
 | 
			
		||||
    ['RemoveAvatars' as string]: 1 << 15,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function hasPerm(member: Member, perm:  'View'|'ManageRoles'|'ManageChannels'|'ManageServer'|  // its late and im tired
 | 
			
		||||
                                        'KickMembers'|'BanMembers'|'ChangeNickname'|           // dont judge my code
 | 
			
		||||
                                        'ManageNicknames'|'ChangeAvatar'|'RemoveAvatars') {
 | 
			
		||||
    let p = ServerPermissions[perm];
 | 
			
		||||
    if (member.server?.owner == member.user?._id) return true;
 | 
			
		||||
    
 | 
			
		||||
    // TODO how the fuck do bitfields work
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { hasPerm }
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ class Command {
 | 
			
		|||
    name: string;
 | 
			
		||||
    aliases: string[] | null;
 | 
			
		||||
    description: string | null;
 | 
			
		||||
    syntax?: string | null;
 | 
			
		||||
    run: Function;
 | 
			
		||||
    serverOnly: boolean;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								src/struct/ServerConfig.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/struct/ServerConfig.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
class ServerConfig {
 | 
			
		||||
    id: string | undefined;
 | 
			
		||||
    prefix: string | undefined;
 | 
			
		||||
    spaceAfterPrefix: boolean | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default ServerConfig;
 | 
			
		||||
		Loading…
	
		Reference in a new issue