code
This commit is contained in:
parent
e23e128850
commit
3e1da96360
10 changed files with 182 additions and 8 deletions
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 {
|
||||
|
@ -10,4 +9,4 @@ export default {
|
|||
run: (message: Message, args: string[]) => {
|
||||
message.reply('I am here');
|
||||
}
|
||||
} as Command;
|
||||
} as Command;
|
||||
|
|
|
@ -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