mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2025-01-10 18:06:27 +02:00
feat: guild bans
This commit is contained in:
parent
ca38235309
commit
30cd5413c4
@ -3,6 +3,7 @@ const {
|
|||||||
GatewayIntentBits,
|
GatewayIntentBits,
|
||||||
Partials,
|
Partials,
|
||||||
} = require('discord.js');
|
} = require('discord.js');
|
||||||
|
const logger = require('./lib/logger');
|
||||||
const { PrismaClient } = require('@prisma/client');
|
const { PrismaClient } = require('@prisma/client');
|
||||||
const Keyv = require('keyv');
|
const Keyv = require('keyv');
|
||||||
const I18n = require('@eartharoid/i18n');
|
const I18n = require('@eartharoid/i18n');
|
||||||
@ -14,7 +15,7 @@ const sqliteMiddleware = require('./lib/middleware/prisma-sqlite');
|
|||||||
const ms = require('ms');
|
const ms = require('ms');
|
||||||
|
|
||||||
module.exports = class Client extends FrameworkClient {
|
module.exports = class Client extends FrameworkClient {
|
||||||
constructor(config, log) {
|
constructor() {
|
||||||
super(
|
super(
|
||||||
{
|
{
|
||||||
intents: [
|
intents: [
|
||||||
@ -39,6 +40,12 @@ module.exports = class Client extends FrameworkClient {
|
|||||||
{ baseDir: __dirname },
|
{ baseDir: __dirname },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.config = {};
|
||||||
|
this.log = {};
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(reload = false) {
|
||||||
const locales = {};
|
const locales = {};
|
||||||
fs.readdirSync(join(__dirname, 'i18n'))
|
fs.readdirSync(join(__dirname, 'i18n'))
|
||||||
.filter(file => file.endsWith('.yml'))
|
.filter(file => file.endsWith('.yml'))
|
||||||
@ -48,30 +55,57 @@ module.exports = class Client extends FrameworkClient {
|
|||||||
locales[name] = YAML.parse(data);
|
locales[name] = YAML.parse(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.keyv = new Keyv();
|
|
||||||
/** @type {I18n} */
|
/** @type {I18n} */
|
||||||
this.i18n = new I18n('en-GB', locales);
|
this.i18n = new I18n('en-GB', locales);
|
||||||
/** @type {TicketManager} */
|
|
||||||
this.tickets = new TicketManager(this);
|
// to maintain references, these shouldn't be reassigned
|
||||||
this.config = config;
|
Object.assign(this.config, YAML.parse(fs.readFileSync('./user/config.yml', 'utf8')));
|
||||||
this.log = log;
|
Object.assign(this.log, logger(this.config));
|
||||||
this.supers = (process.env.SUPER ?? '').split(',');
|
|
||||||
/** @param {import('discord.js/typings').Interaction} interaction */
|
this.banned_guilds = new Set(
|
||||||
this.commands.interceptor = async interaction => {
|
(() => {
|
||||||
if (!interaction.inGuild()) return;
|
let array = fs.readFileSync('./user/banned-guilds.txt', 'utf8').trim().split(/\r?\n/);
|
||||||
const id = interaction.guildId;
|
if (array[0] === '') array = [];
|
||||||
const cacheKey = `cache/known/guild:${id}`;
|
return array;
|
||||||
if (await this.keyv.has(cacheKey)) return;
|
})(),
|
||||||
await this.prisma.guild.upsert({
|
);
|
||||||
create: {
|
this.log.info(`${this.banned_guilds.size} guilds are banned`);
|
||||||
id,
|
|
||||||
locale: this.i18n.locales.find(locale => locale === interaction.guild.preferredLocale), // undefined if not supported
|
if (reload) {
|
||||||
},
|
await this.initAfterLogin();
|
||||||
update: {},
|
} else {
|
||||||
where: { id },
|
this.keyv = new Keyv();
|
||||||
});
|
|
||||||
await this.keyv.set(cacheKey, true);
|
this.tickets = new TicketManager(this);
|
||||||
};
|
|
||||||
|
this.supers = (process.env.SUPER ?? '').split(',');
|
||||||
|
|
||||||
|
/** @param {import('discord.js/typings').Interaction} interaction */
|
||||||
|
this.commands.interceptor = async interaction => {
|
||||||
|
if (!interaction.inGuild()) return;
|
||||||
|
const id = interaction.guildId;
|
||||||
|
const cacheKey = `cache/known/guild:${id}`;
|
||||||
|
if (await this.keyv.has(cacheKey)) return;
|
||||||
|
await this.prisma.guild.upsert({
|
||||||
|
create: {
|
||||||
|
id,
|
||||||
|
locale: this.i18n.locales.find(locale => locale === interaction.guild.preferredLocale), // undefined if not supported
|
||||||
|
},
|
||||||
|
update: {},
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
await this.keyv.set(cacheKey, true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async initAfterLogin() {
|
||||||
|
for (const id of this.banned_guilds) {
|
||||||
|
if (this.guilds.cache.has(id)) {
|
||||||
|
this.log.info(`Leaving banned guild ${id}`);
|
||||||
|
await this.guilds.cache.get(id).leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(token) {
|
async login(token) {
|
||||||
@ -86,7 +120,7 @@ module.exports = class Client extends FrameworkClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.DB_PROVIDER === 'sqlite' && !process.env.DB_CONNECTION_URL) {
|
if (process.env.DB_PROVIDER === 'sqlite' && !process.env.DB_CONNECTION_URL) {
|
||||||
prisma_options.datasources = { db: { url:'file:' + join(process.cwd(), './user/database.db') } };
|
prisma_options.datasources = { db: { url: 'file:' + join(process.cwd(), './user/database.db') } };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {PrismaClient} */
|
/** @type {PrismaClient} */
|
||||||
|
@ -105,6 +105,14 @@ module.exports = async client => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (client.banned_guilds.has(guildId)) {
|
||||||
|
return res.code(451).send({
|
||||||
|
error: 'Unavailable For Legal Reasons',
|
||||||
|
message: 'This guild has been banned for breaking the terms of service.',
|
||||||
|
statusCode: 451,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
const guildMember = await guild.members.fetch(userId);
|
const guildMember = await guild.members.fetch(userId);
|
||||||
const isAdmin = await getPrivilegeLevel(guildMember) >= 2;
|
const isAdmin = await getPrivilegeLevel(guildMember) >= 2;
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
|
37
src/index.js
37
src/index.js
@ -37,6 +37,7 @@ if (!semver.satisfies(process.versions.node, pkg.engines.node)) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check cwd
|
||||||
const base_dir = path.resolve(path.join(__dirname, '../'));
|
const base_dir = path.resolve(path.join(__dirname, '../'));
|
||||||
const cwd = path.resolve(process.cwd());
|
const cwd = path.resolve(process.cwd());
|
||||||
if (base_dir !== cwd) {
|
if (base_dir !== cwd) {
|
||||||
@ -49,26 +50,17 @@ if (base_dir !== cwd) {
|
|||||||
console.log(colours.blueBright(' Learn more at https://lnk.earth/dt-cwd.'));
|
console.log(colours.blueBright(' Learn more at https://lnk.earth/dt-cwd.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// this could be done first, but then there would be no banner :(
|
|
||||||
process.env.NODE_ENV ??= 'production'; // make sure NODE_ENV is set
|
process.env.NODE_ENV ??= 'production'; // make sure NODE_ENV is set
|
||||||
require('./env').load(); // load and check environment variables
|
require('./env').load(); // load and check environment variables
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const YAML = require('yaml');
|
const YAML = require('yaml');
|
||||||
const logger = require('./lib/logger');
|
const logger = require('./lib/logger');
|
||||||
const Client = require('./client');
|
|
||||||
const http = require('./http');
|
|
||||||
|
|
||||||
// user directory may or may not exist depending on if sqlite is being used
|
// create a Logger using the default config
|
||||||
// so the config file could be missing even though the directory exists
|
// and set listeners as early as possible.
|
||||||
if (!fs.existsSync('./user/config.yml')) {
|
let config = YAML.parse(fs.readFileSync(path.join(__dirname, 'user/config.yml'), 'utf8'));
|
||||||
console.log('The config file does not exist, copying defaults...');
|
let log = logger(config);
|
||||||
fs.cpSync(path.join(__dirname, 'user'), './user', { recursive: true });
|
|
||||||
console.log('Created user directory at', path.join(cwd, 'user'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = YAML.parse(fs.readFileSync('./user/config.yml', 'utf8'));
|
|
||||||
const log = logger(config);
|
|
||||||
|
|
||||||
process.on('uncaughtException', (error, origin) => {
|
process.on('uncaughtException', (error, origin) => {
|
||||||
log.notice(`Discord Tickets v${pkg.version} on Node.js ${process.version} (${process.platform})`);
|
log.notice(`Discord Tickets v${pkg.version} on Node.js ${process.version} (${process.platform})`);
|
||||||
@ -78,7 +70,26 @@ process.on('uncaughtException', (error, origin) => {
|
|||||||
|
|
||||||
process.on('warning', warning => log.warn(warning.stack || warning));
|
process.on('warning', warning => log.warn(warning.stack || warning));
|
||||||
|
|
||||||
|
const Client = require('./client');
|
||||||
|
const http = require('./http');
|
||||||
|
|
||||||
|
// the `user` directory may or may not exist depending on if sqlite is being used.
|
||||||
|
// copy any files that don't already exist
|
||||||
|
fs.cpSync(path.join(__dirname, 'user'), './user', {
|
||||||
|
force: false,
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// initialise the framework and client,
|
||||||
|
// which also loads the custom config and creates a new Logger.
|
||||||
const client = new Client(config, log);
|
const client = new Client(config, log);
|
||||||
|
|
||||||
|
// allow any config changes to affect the above listeners
|
||||||
|
// as long as these `client` properties are not reassigned.
|
||||||
|
config = client.config;
|
||||||
|
log = client.log;
|
||||||
|
|
||||||
|
// start the bot and then the web server
|
||||||
client.login().then(() => {
|
client.login().then(() => {
|
||||||
http(client);
|
http(client);
|
||||||
});
|
});
|
||||||
|
@ -33,6 +33,8 @@ module.exports = class extends Listener {
|
|||||||
process.title = 'tickets';
|
process.title = 'tickets';
|
||||||
client.log.success('Connected to Discord as "%s" over %d shards', client.user.tag, client.ws.shards.size);
|
client.log.success('Connected to Discord as "%s" over %d shards', client.user.tag, client.ws.shards.size);
|
||||||
|
|
||||||
|
await client.initAfterLogin();
|
||||||
|
|
||||||
// fill cache
|
// fill cache
|
||||||
await sync(client);
|
await sync(client);
|
||||||
|
|
||||||
|
21
src/stdin/reload.js
Normal file
21
src/stdin/reload.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const { StdinCommand } = require('@eartharoid/dbf');
|
||||||
|
|
||||||
|
module.exports = class extends StdinCommand {
|
||||||
|
constructor(client, options) {
|
||||||
|
super(client, {
|
||||||
|
...options,
|
||||||
|
id: 'reload',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run() {
|
||||||
|
this.client.log.warn('Reloading is not the same as restarting!');
|
||||||
|
this.client.log.info('Reinitialising client...');
|
||||||
|
await this.client.init(true);
|
||||||
|
this.client.log.success('Client reinitialised');
|
||||||
|
// TODO: fix this
|
||||||
|
// this.client.log.info('Reloading module components...');
|
||||||
|
// this.client.mods.forEach(mod => mod.components.forEach(component => component.reload()));
|
||||||
|
// this.client.log.success('Components reloaded');
|
||||||
|
}
|
||||||
|
};
|
0
src/user/banned-guilds.txt
Normal file
0
src/user/banned-guilds.txt
Normal file
Loading…
Reference in New Issue
Block a user