initial commit; add events system
This commit is contained in:
parent
2e7834b17e
commit
fc1f05ae0c
11 changed files with 532 additions and 0 deletions
112
bot.js
Normal file
112
bot.js
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
import { createRequire } from 'module';
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
import Eris from 'eris';
|
||||||
|
import Logger, { levels } from './logger.js';
|
||||||
|
import CommandParser, { Command } from './parser.js';
|
||||||
|
import { filename, dirname } from './utils.js';
|
||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
const cfg = require('./config.json');
|
||||||
|
if (!fs.existsSync('./whitelist.json')) {
|
||||||
|
fs.writeFileSync('./whitelist.json', '{}');
|
||||||
|
}
|
||||||
|
|
||||||
|
const whitelist = require('./whitelist.json');
|
||||||
|
const dir = dirname(import.meta.url);
|
||||||
|
|
||||||
|
const bot = new Eris(cfg.token);
|
||||||
|
|
||||||
|
global.ctx = {
|
||||||
|
bot: bot,
|
||||||
|
log_level: levels[cfg.log_level.toUpperCase()] || levels.WARN,
|
||||||
|
set_ctx: (key, value) => {
|
||||||
|
global.ctx[key] = value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const log = new Logger(filename(import.meta.url), global.ctx.log_level);
|
||||||
|
const parse = new CommandParser(global.ctx, cfg.prefix || undefined);
|
||||||
|
|
||||||
|
const checkUser = (user) => {
|
||||||
|
if (cfg.user_whitelist.includes(user.id) || (whitelist.user && whitelist.user.includes(user.id))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.info(`user not on whitelist: ${user.username}`);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const checkGuild = (guild) => {
|
||||||
|
if (cfg.whitelist.includes(guild.id) || (whitelist.guild && whitelist.guild.includes(guild.id))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.info(`guild not on whitelist: ${guild.name}`);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveWhitelist = () => {
|
||||||
|
let data = JSON.stringify(whitelist);
|
||||||
|
fs.writeFileSync('./whitelist.json', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
global.ctx.whitelist = {
|
||||||
|
guild: checkGuild,
|
||||||
|
user: checkUser,
|
||||||
|
save: saveWhitelist,
|
||||||
|
wl: whitelist,
|
||||||
|
};
|
||||||
|
|
||||||
|
const listeners = {}
|
||||||
|
|
||||||
|
bot.on('ready', () => {
|
||||||
|
log.info('ready recieved.');
|
||||||
|
bot.guilds.forEach((guild) => checkGuild(guild));
|
||||||
|
});
|
||||||
|
|
||||||
|
bot.on('messageCreate', (msg) => parse.parseMsg(msg, global.ctx));
|
||||||
|
|
||||||
|
bot.on('error', (err) => log.error(err.toString()));
|
||||||
|
|
||||||
|
bot.connect();
|
||||||
|
|
||||||
|
async function load_commands() {
|
||||||
|
for (let file of files) {
|
||||||
|
let p = path.join(cmd_dir, file);
|
||||||
|
log.debug('loading ' + p);
|
||||||
|
let obj;
|
||||||
|
try {
|
||||||
|
obj = await import('file:////' + p);
|
||||||
|
} catch (e) {
|
||||||
|
log.warn(`loading file ${file}, ran into issue: ${e.stack}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (obj.default != undefined) {
|
||||||
|
if (obj.default.constructor.name == 'CommandInitializer') {
|
||||||
|
obj.default.initialize(global.ctx);
|
||||||
|
let cmds = obj.default.getCommands();
|
||||||
|
if (parse.isCmd(cmds)) {
|
||||||
|
parse.addCommand(cmds);
|
||||||
|
} else if (cmds.constructor.name == 'Array') {
|
||||||
|
for (let cmd of cmds) {
|
||||||
|
parse.addCommand(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let events = obj.default.getEvents();
|
||||||
|
if (events != undefined) {
|
||||||
|
for (let event in events) {
|
||||||
|
if (!listeners[event]) {
|
||||||
|
listeners[event] = []
|
||||||
|
}
|
||||||
|
listeners[event].push(events[event])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn('module ' + file + ' returned an undefined module.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let cmd_dir = path.join(dir, 'cmd');
|
||||||
|
log.trace(dir);
|
||||||
|
let files = fs.readdirSync(cmd_dir);
|
||||||
|
load_commands();
|
94
cmd/perm.js
Normal file
94
cmd/perm.js
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import { CommandInitializer, Command } from '../parser.js';
|
||||||
|
|
||||||
|
const initializer = new CommandInitializer();
|
||||||
|
|
||||||
|
class WhitelistUser extends Command {
|
||||||
|
name = 'wu';
|
||||||
|
whitelist = true;
|
||||||
|
func = async function (msg, args, ctx) {
|
||||||
|
let user = await ctx.bot.users.get(args[0].trim());
|
||||||
|
this.log.debug(msg.channel.guild.members);
|
||||||
|
this.log.debug(user);
|
||||||
|
if (!user) {
|
||||||
|
user = msg.channel.guild.members.get(args[0].trim());
|
||||||
|
this.log.debug(user);
|
||||||
|
if (!user) {
|
||||||
|
user = (await msg.channel.guild.fetchMembers({ userIDs: [args[0]] }))[0];
|
||||||
|
this.log.debug(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (user.username) {
|
||||||
|
if (!ctx.whitelist.wl) {
|
||||||
|
ctx.whitelist.wl = {
|
||||||
|
user: [],
|
||||||
|
guild: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let list = ctx.whitelist.wl.user || [];
|
||||||
|
if (!list.includes(args[0])) {
|
||||||
|
list.push(args[0]);
|
||||||
|
ctx.whitelist.wl.user = list;
|
||||||
|
ctx.whitelist.save();
|
||||||
|
msg.channel.createMessage(`added user "${user.username}#${user.discriminator}" (${args[0]}) to whitelist`);
|
||||||
|
} else {
|
||||||
|
msg.channel.createMessage('user already whitelisted');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.channel.createMessage(`user with id ${args[0]} could not be found`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
initializer.addCommand(new WhitelistUser());
|
||||||
|
|
||||||
|
class WhitelistGuild extends Command {
|
||||||
|
name = 'wg';
|
||||||
|
whitelist = true;
|
||||||
|
func = async function (msg, args, ctx) {
|
||||||
|
let guild = await ctx.bot.guilds.get(args[0]);
|
||||||
|
if (guild && guild.name) {
|
||||||
|
if (!ctx.whitelist.wl) {
|
||||||
|
ctx.whitelist.wl = {
|
||||||
|
user: [],
|
||||||
|
guild: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let list = ctx.whitelist.wl.guild || [];
|
||||||
|
if (!list.includes(args[0])) {
|
||||||
|
list.push(args[0]);
|
||||||
|
ctx.whitelist.wl.guild = list;
|
||||||
|
ctx.whitelist.save();
|
||||||
|
msg.channel.createMessage(`added guild "${guild.name}" (${args[0]}) to whitelist`);
|
||||||
|
} else {
|
||||||
|
msg.channel.createMessage('guild already whitelisted');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.channel.createMessage(`guild with id ${args[0]} could not be found`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
initializer.addCommand(new WhitelistGuild());
|
||||||
|
|
||||||
|
class Purge extends Command {
|
||||||
|
name = 'purge';
|
||||||
|
whitelist = true;
|
||||||
|
func = async function (msg, args, ctx) {
|
||||||
|
let guilds = await ctx.bot.guilds;
|
||||||
|
let whitelist = ctx.whitelist.guild;
|
||||||
|
let purged = 0;
|
||||||
|
guilds.forEach((guild) => {
|
||||||
|
if (!whitelist(guild)) {
|
||||||
|
this.log.info(`purging guild ${guild.name} (${guild.id})`);
|
||||||
|
guild.leave();
|
||||||
|
purged++;
|
||||||
|
} else {
|
||||||
|
this.log.debug(`keeping guild ${guild.name} (${guild.id})`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
msg.channel.createMessage(`purged ${purged} guilds.`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
initializer.addCommand(new Purge());
|
||||||
|
|
||||||
|
export default initializer;
|
52
cmd/reg.js
Normal file
52
cmd/reg.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import { CommandInitializer, Command } from '../parser.js';
|
||||||
|
import Logger, { levels } from '../logger.js';
|
||||||
|
import { filename } from '../utils.js';
|
||||||
|
|
||||||
|
const initializer = new CommandInitializer();
|
||||||
|
const log = new Logger(filename(import.meta.url), global.ctx.log_level);
|
||||||
|
|
||||||
|
class PingCommand extends Command {
|
||||||
|
name = 'ping';
|
||||||
|
func(msg, args, ctx) {
|
||||||
|
msg.channel.createMessage('p').then((m) => {
|
||||||
|
m.edit(
|
||||||
|
`rtt: ${Math.floor(m.timestamp - msg.timestamp)}, gateway: ${
|
||||||
|
ctx.bot.shards.get(ctx.bot.guildShardMap[ctx.bot.channelGuildMap[msg.channel.id]] || 0).latency
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializer.addCommand(new PingCommand());
|
||||||
|
|
||||||
|
class RestartCommand extends Command {
|
||||||
|
name = 'restart';
|
||||||
|
func(msg, args, ctx) {
|
||||||
|
msg.channel.createMessage('restarting.').then(() => {
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializer.addCommand(new RestartCommand());
|
||||||
|
|
||||||
|
class EvalCommand extends Command {
|
||||||
|
name = 'eval';
|
||||||
|
whitelist = true;
|
||||||
|
func(msg, args, ctx) {
|
||||||
|
log.debug('evaluating ' + args[0]);
|
||||||
|
let result = eval(args[0]);
|
||||||
|
log.debug('result is: \n' + result);
|
||||||
|
if (result.length <= 1999) {
|
||||||
|
msg.channel.createMessage(result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.channel.createMessage("result too long, see logs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializer.addCommand(new EvalCommand());
|
||||||
|
|
||||||
|
export default initializer;
|
7
config.json
Normal file
7
config.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"token": "MjY3Mzg2MTUyMzIxOTQxNTA1.WHFMwg.KgEUojOa43UL43yqUy9-TKz05tY",
|
||||||
|
"log_level": "DEBUG",
|
||||||
|
"prefix": "p.",
|
||||||
|
"whitelist": ["656579275008245830"],
|
||||||
|
"user_whitelist": ["123601647258697730"]
|
||||||
|
}
|
56
logger.js
Normal file
56
logger.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
export const levels = {
|
||||||
|
TRACE: 5,
|
||||||
|
DEBUG: 4,
|
||||||
|
INFO: 3,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 1,
|
||||||
|
PANIC: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Logger {
|
||||||
|
constructor(name, level) {
|
||||||
|
console.log(`created new logger for ${name} with level ${level}`);
|
||||||
|
this.sn(name);
|
||||||
|
this.s(level);
|
||||||
|
}
|
||||||
|
n = 'DEFAULT';
|
||||||
|
l = 0;
|
||||||
|
sn(n) {
|
||||||
|
this.n = n;
|
||||||
|
}
|
||||||
|
s(l) {
|
||||||
|
if (l && l.constructor === Number) {
|
||||||
|
this.l = l;
|
||||||
|
} else {
|
||||||
|
this.l = levels[l];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lo(l, m) {
|
||||||
|
if (l <= this.l) {
|
||||||
|
let level = Object.keys(levels).find((key) => levels[key] === l);
|
||||||
|
let ms = typeof m == 'object' ? JSON.stringify(m) : m;
|
||||||
|
console.log(`${level} [${this.n}]: ${ms}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace(msg) {
|
||||||
|
this.lo(levels.TRACE, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(msg) {
|
||||||
|
this.lo(levels.DEBUG, msg);
|
||||||
|
}
|
||||||
|
info(msg) {
|
||||||
|
this.lo(levels.INFO, msg);
|
||||||
|
}
|
||||||
|
warn(msg) {
|
||||||
|
this.lo(levels.WARN, msg);
|
||||||
|
}
|
||||||
|
error(msg) {
|
||||||
|
this.lo(levels.ERROR, msg);
|
||||||
|
}
|
||||||
|
panic(msg) {
|
||||||
|
this.lo(levels.PANIC, msg);
|
||||||
|
}
|
||||||
|
}
|
19
package.json
Normal file
19
package.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"type": "module",
|
||||||
|
"name": "pinbot",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "a bot to manage pins (and also other stuff!)",
|
||||||
|
"main": "bot.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@ssh.gitdab.com:jane/pinbot.git"
|
||||||
|
},
|
||||||
|
"author": "jane petrovna (jane@j4.pm)",
|
||||||
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
|
"dependencies": {
|
||||||
|
"eris": "^0.15.0"
|
||||||
|
}
|
||||||
|
}
|
133
parser.js
Normal file
133
parser.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import Logger, { levels } from './logger.js';
|
||||||
|
import { filename } from './utils.js';
|
||||||
|
|
||||||
|
export class Command {
|
||||||
|
init(ctx, log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
log;
|
||||||
|
name = 'DEFAULT';
|
||||||
|
whitelist = false;
|
||||||
|
func() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandInitializer {
|
||||||
|
commands = [];
|
||||||
|
uninitialized = [];
|
||||||
|
events = {};
|
||||||
|
|
||||||
|
initialize(ctx) {
|
||||||
|
for (let index in this.uninitialized) {
|
||||||
|
this.initCommand(this.uninitialized[index], ctx);
|
||||||
|
delete this.uninitialized[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initCommand(cmd, ctx) {
|
||||||
|
cmd.init(ctx, new Logger(`cmd.${cmd.name}`, ctx.log_level));
|
||||||
|
this.commands.push(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand(cmd) {
|
||||||
|
this.uninitialized.push(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvent(event, func) {
|
||||||
|
if (!events[event]) {
|
||||||
|
events[event] = [];
|
||||||
|
}
|
||||||
|
events[event].push(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCommands() {
|
||||||
|
return this.commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEvents() {
|
||||||
|
return this.events;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CommandParser {
|
||||||
|
constructor(ctx, prefix = ';') {
|
||||||
|
this.log = new Logger(filename(import.meta.url), ctx.log_level);
|
||||||
|
this.prefix = prefix ? prefix : this.prefix || ';';
|
||||||
|
}
|
||||||
|
log;
|
||||||
|
prefix;
|
||||||
|
commands = [];
|
||||||
|
|
||||||
|
addCommand(cmd) {
|
||||||
|
this.log.trace(`cmd to add: ${JSON.stringify(cmd)}`);
|
||||||
|
if (this.isCmd(cmd)) {
|
||||||
|
this.commands.push(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCmd(str) {
|
||||||
|
let results = this.commands.filter((c) => c.name == str);
|
||||||
|
|
||||||
|
return results.length ? results[0] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
isCmd(cmd) {
|
||||||
|
return typeof cmd == 'object' && cmd instanceof Command;
|
||||||
|
}
|
||||||
|
|
||||||
|
getArgsList(split) {
|
||||||
|
let parsed_args = [];
|
||||||
|
let join_index = -1;
|
||||||
|
let add = true;
|
||||||
|
for (let index in split) {
|
||||||
|
if (split[index].startsWith('```')) {
|
||||||
|
join_index = index;
|
||||||
|
add = false;
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
parsed_args.push(split[index]);
|
||||||
|
}
|
||||||
|
if (split[index].endsWith('```') && join_index != -1) {
|
||||||
|
let joined = split
|
||||||
|
.slice(join_index, index + 1)
|
||||||
|
.join(' ')
|
||||||
|
.replace(/```/g, '');
|
||||||
|
parsed_args.push(joined);
|
||||||
|
add = true;
|
||||||
|
join_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseMsg(msg, ctx) {
|
||||||
|
if (msg.author.bot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (msg.channel.guild && !ctx.whitelist.guild(msg.channel.guild)) {
|
||||||
|
msg.channel.createMessage('guild not whitelisted');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.log.trace(msg.content);
|
||||||
|
this.log.trace(msg.content.startsWith(this.prefix));
|
||||||
|
this.log.trace(msg.content[0]);
|
||||||
|
this.log.trace(this.prefix);
|
||||||
|
if (msg.content.startsWith(this.prefix)) {
|
||||||
|
let snip = msg.content.slice(this.prefix.length);
|
||||||
|
let unsep = snip.split(' ');
|
||||||
|
let res = this.hasCmd(unsep[0]);
|
||||||
|
let args = this.getArgsList(unsep.slice(1));
|
||||||
|
this.log.trace(snip);
|
||||||
|
this.log.trace(res);
|
||||||
|
this.log.trace(args);
|
||||||
|
|
||||||
|
if (res != undefined) {
|
||||||
|
this.log.debug(`execute function ${res.name}`);
|
||||||
|
if (res.whitelist && !ctx.whitelist.user(msg.author)) {
|
||||||
|
msg.channel.createMessage('not whitelisted');
|
||||||
|
} else {
|
||||||
|
res.func(msg, args, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
pnpm-lock.yaml
Normal file
41
pnpm-lock.yaml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
dependencies:
|
||||||
|
eris: 0.15.0
|
||||||
|
lockfileVersion: 5.2
|
||||||
|
packages:
|
||||||
|
/eris/0.15.0:
|
||||||
|
dependencies:
|
||||||
|
ws: 7.4.4
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=10.4.0'
|
||||||
|
optionalDependencies:
|
||||||
|
opusscript: 0.0.8
|
||||||
|
tweetnacl: 1.0.3
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-muBdi5XyMXdxFQ8xUG6yofq40/Z02CHlqJP7zIdHhpdDiHvFM/mybGiFAHuoSYcsVTTvEfbUaAJ+SDEmMjARYw==
|
||||||
|
/opusscript/0.0.8:
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==
|
||||||
|
/tweetnacl/1.0.3:
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
||||||
|
/ws/7.4.4:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=8.3.0'
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: ^5.0.2
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
|
||||||
|
specifiers:
|
||||||
|
eris: ^0.15.0
|
2
start.sh
Normal file
2
start.sh
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
git pull
|
||||||
|
pnpm start
|
15
utils.js
Normal file
15
utils.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import path from "path";
|
||||||
|
import {platform} from "process";
|
||||||
|
|
||||||
|
export function filename(url) {
|
||||||
|
let __filename = new URL(url).pathname;
|
||||||
|
return path.basename(__filename, ".js");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dirname(url) {
|
||||||
|
let __filename = new URL(url).pathname;
|
||||||
|
let __dirname = path.dirname(__filename);
|
||||||
|
return platform == "win32"
|
||||||
|
? __dirname.slice(1)
|
||||||
|
: __dirname;
|
||||||
|
}
|
1
whitelist.json
Normal file
1
whitelist.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"guild":["656579275008245830","823796249832194088"],"user":["123601647258697730"]}
|
Loading…
Reference in a new issue