update db structure to let init work correctly
This commit is contained in:
parent
ef08cd779a
commit
76e007e2e4
|
@ -2,10 +2,11 @@
|
||||||
// DATA WILL BE LOST IF DB ALREADY EXISTS, RUN AT OWN RISK
|
// DATA WILL BE LOST IF DB ALREADY EXISTS, RUN AT OWN RISK
|
||||||
|
|
||||||
import config from '../config.ts';
|
import config from '../config.ts';
|
||||||
import { dbClient } from '../src/db.ts';
|
import dbClient from '../src/db/client.ts';
|
||||||
|
|
||||||
console.log('Attempting to create DB');
|
console.log('Attempting to create DB');
|
||||||
await dbClient.execute(`CREATE SCHEMA IF NOT EXISTS ${config.db.name};`);
|
await dbClient.execute(`CREATE SCHEMA IF NOT EXISTS ${config.db.name};`);
|
||||||
|
console.log('test');
|
||||||
await dbClient.execute(`USE ${config.db.name}`);
|
await dbClient.execute(`USE ${config.db.name}`);
|
||||||
console.log('DB created');
|
console.log('DB created');
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,47 @@
|
||||||
// This file will populate the tables with default values
|
// This file will populate the tables with default values
|
||||||
|
|
||||||
import config from '../config.ts';
|
import config from '../config.ts';
|
||||||
import { dbClient } from '../src/db.ts';
|
import dbClient from '../src/db/client.ts';
|
||||||
|
|
||||||
console.log('Attempting to populate DB Admin API key');
|
console.log('Attempting to populate DB Admin API key');
|
||||||
await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [config.api.admin, config.api.adminKey]).catch((e) => {
|
await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [config.api.admin, config.api.adminKey]).catch((e) => {
|
||||||
console.log('Failed to insert into database', e);
|
console.log('Failed to insert into database', e);
|
||||||
});
|
});
|
||||||
console.log('Inesrtion done');
|
console.log('Inesrtion done');
|
||||||
|
|
||||||
console.log('Attempting to insert default commands into command_cnt');
|
console.log('Attempting to insert default commands into command_cnt');
|
||||||
const commands = ['ping', 'rip', 'rollhelp', 'help', 'info', 'version', 'report', 'stats', 'roll', 'emojis', 'api', 'privacy', 'mention', 'audit', 'heatmap', 'rollDecorators', 'opt-out', 'opt-in'];
|
const commands = [
|
||||||
|
'ping',
|
||||||
|
'rip',
|
||||||
|
'rollhelp',
|
||||||
|
'help',
|
||||||
|
'info',
|
||||||
|
'version',
|
||||||
|
'report',
|
||||||
|
'stats',
|
||||||
|
'roll',
|
||||||
|
'emojis',
|
||||||
|
'api',
|
||||||
|
'privacy',
|
||||||
|
'mention',
|
||||||
|
'audit',
|
||||||
|
'heatmap',
|
||||||
|
'rollDecorators',
|
||||||
|
'opt-out',
|
||||||
|
'opt-in',
|
||||||
|
];
|
||||||
for (const command of commands) {
|
for (const command of commands) {
|
||||||
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => {
|
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => {
|
||||||
console.log(`Failed to insert ${command} into database`, e);
|
console.log(`Failed to insert ${command} into database`, e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log('Insertion done');
|
console.log('Insertion done');
|
||||||
|
|
||||||
console.log('Attempting to insert default hours into roll_time_heatmap');
|
console.log('Attempting to insert default hours into roll_time_heatmap');
|
||||||
for (let i = 0; i <= 23; i++) {
|
for (let i = 0; i <= 23; i++) {
|
||||||
await dbClient.execute('INSERT INTO roll_time_heatmap(hour) values(?)', [i]).catch((e) => {
|
await dbClient.execute('INSERT INTO roll_time_heatmap(hour) values(?)', [i]).catch((e) => {
|
||||||
console.log(`Failed to insert hour ${i} into database`, e);
|
console.log(`Failed to insert hour ${i} into database`, e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log('Insertion done');
|
console.log('Insertion done');
|
||||||
|
|
||||||
|
|
572
mod.ts
572
mod.ts
|
@ -7,25 +7,26 @@
|
||||||
import config from './config.ts';
|
import config from './config.ts';
|
||||||
import { DEBUG, DEVMODE, LOCALMODE } from './flags.ts';
|
import { DEBUG, DEVMODE, LOCALMODE } from './flags.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
botId,
|
botId,
|
||||||
cache,
|
cache,
|
||||||
DiscordActivityTypes,
|
DiscordActivityTypes,
|
||||||
DiscordenoGuild,
|
DiscordenoGuild,
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
editBotNickname,
|
editBotNickname,
|
||||||
editBotStatus,
|
editBotStatus,
|
||||||
initLog,
|
initLog,
|
||||||
Intents,
|
Intents,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
sendMessage,
|
sendMessage,
|
||||||
startBot,
|
startBot,
|
||||||
} from './deps.ts';
|
} from './deps.ts';
|
||||||
import api from './src/api.ts';
|
import api from './src/api.ts';
|
||||||
import { dbClient, ignoreList } from './src/db.ts';
|
import dbClient from './src/db/client.ts';
|
||||||
|
import { ignoreList } from './src/db/common.ts';
|
||||||
import commands from './src/commands/_index.ts';
|
import commands from './src/commands/_index.ts';
|
||||||
import intervals from './src/intervals.ts';
|
import intervals from './src/intervals.ts';
|
||||||
import { successColor, warnColor } from './src/commandUtils.ts';
|
import { successColor, warnColor } from './src/commandUtils.ts';
|
||||||
|
@ -36,283 +37,302 @@ initLog('logs', DEBUG);
|
||||||
|
|
||||||
// Start up the Discord Bot
|
// Start up the Discord Bot
|
||||||
startBot({
|
startBot({
|
||||||
token: LOCALMODE ? config.localtoken : config.token,
|
token: LOCALMODE ? config.localtoken : config.token,
|
||||||
intents: [Intents.GuildMessages, Intents.DirectMessages, Intents.Guilds],
|
intents: [Intents.GuildMessages, Intents.DirectMessages, Intents.Guilds],
|
||||||
eventHandlers: {
|
eventHandlers: {
|
||||||
ready: () => {
|
ready: () => {
|
||||||
log(LT.INFO, `${config.name} Logged in!`);
|
log(LT.INFO, `${config.name} Logged in!`);
|
||||||
editBotStatus({
|
editBotStatus({
|
||||||
activities: [{
|
activities: [
|
||||||
name: 'Booting up . . .',
|
{
|
||||||
type: DiscordActivityTypes.Game,
|
name: 'Booting up . . .',
|
||||||
createdAt: new Date().getTime(),
|
type: DiscordActivityTypes.Game,
|
||||||
}],
|
createdAt: new Date().getTime(),
|
||||||
status: 'online',
|
},
|
||||||
});
|
],
|
||||||
|
status: 'online',
|
||||||
|
});
|
||||||
|
|
||||||
// Interval to rotate the status text every 30 seconds to show off more commands
|
// Interval to rotate the status text every 30 seconds to show off more commands
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
log(LT.LOG, 'Changing bot status');
|
log(LT.LOG, 'Changing bot status');
|
||||||
try {
|
try {
|
||||||
// Wrapped in try-catch due to hard crash possible
|
// Wrapped in try-catch due to hard crash possible
|
||||||
editBotStatus({
|
editBotStatus({
|
||||||
activities: [{
|
activities: [
|
||||||
name: await intervals.getRandomStatus(),
|
{
|
||||||
type: DiscordActivityTypes.Game,
|
name: await intervals.getRandomStatus(),
|
||||||
createdAt: new Date().getTime(),
|
type: DiscordActivityTypes.Game,
|
||||||
}],
|
createdAt: new Date().getTime(),
|
||||||
status: 'online',
|
},
|
||||||
});
|
],
|
||||||
} catch (e) {
|
status: 'online',
|
||||||
log(LT.ERROR, `Failed to update status: ${JSON.stringify(e)}`);
|
});
|
||||||
}
|
} catch (e) {
|
||||||
}, 30000);
|
log(LT.ERROR, `Failed to update status: ${JSON.stringify(e)}`);
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
// Interval to update bot list stats every 24 hours
|
// Interval to update bot list stats every 24 hours
|
||||||
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : setInterval(() => {
|
LOCALMODE
|
||||||
log(LT.LOG, 'Updating all bot lists statistics');
|
? log(LT.INFO, 'updateListStatistics not running')
|
||||||
intervals.updateListStatistics(botId, cache.guilds.size + cache.dispatchedGuildIds.size);
|
: setInterval(() => {
|
||||||
}, 86400000);
|
log(LT.LOG, 'Updating all bot lists statistics');
|
||||||
|
intervals.updateListStatistics(botId, cache.guilds.size + cache.dispatchedGuildIds.size);
|
||||||
|
}, 86400000);
|
||||||
|
|
||||||
// Interval to update hourlyRates every hour
|
// Interval to update hourlyRates every hour
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
log(LT.LOG, 'Updating all command hourlyRates');
|
log(LT.LOG, 'Updating all command hourlyRates');
|
||||||
intervals.updateHourlyRates();
|
intervals.updateHourlyRates();
|
||||||
}, 3600000);
|
}, 3600000);
|
||||||
|
|
||||||
// Interval to update heatmap.png every hour
|
// Interval to update heatmap.png every hour
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
log(LT.LOG, 'Updating heatmap.png');
|
log(LT.LOG, 'Updating heatmap.png');
|
||||||
intervals.updateHeatmapPng();
|
intervals.updateHeatmapPng();
|
||||||
}, 3600000);
|
}, 3600000);
|
||||||
|
|
||||||
// setTimeout added to make sure the startup message does not error out
|
// setTimeout added to make sure the startup message does not error out
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
LOCALMODE && editBotNickname(config.devServer, `LOCAL - ${config.name}`);
|
LOCALMODE && editBotNickname(config.devServer, `LOCAL - ${config.name}`);
|
||||||
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : intervals.updateListStatistics(botId, cache.guilds.size + cache.dispatchedGuildIds.size);
|
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : intervals.updateListStatistics(botId, cache.guilds.size + cache.dispatchedGuildIds.size);
|
||||||
intervals.updateHourlyRates();
|
intervals.updateHourlyRates();
|
||||||
intervals.updateHeatmapPng();
|
intervals.updateHeatmapPng();
|
||||||
editBotStatus({
|
editBotStatus({
|
||||||
activities: [{
|
activities: [
|
||||||
name: 'Booting Complete',
|
{
|
||||||
type: DiscordActivityTypes.Game,
|
name: 'Booting Complete',
|
||||||
createdAt: new Date().getTime(),
|
type: DiscordActivityTypes.Game,
|
||||||
}],
|
createdAt: new Date().getTime(),
|
||||||
status: 'online',
|
},
|
||||||
});
|
],
|
||||||
sendMessage(config.logChannel, {
|
status: 'online',
|
||||||
embeds: [{
|
});
|
||||||
title: `${config.name} is now Online`,
|
sendMessage(config.logChannel, {
|
||||||
color: successColor,
|
embeds: [
|
||||||
fields: [
|
{
|
||||||
{
|
title: `${config.name} is now Online`,
|
||||||
name: 'Version:',
|
color: successColor,
|
||||||
value: `${config.version}`,
|
fields: [
|
||||||
inline: true,
|
{
|
||||||
},
|
name: 'Version:',
|
||||||
],
|
value: `${config.version}`,
|
||||||
}],
|
inline: true,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:88', 'Startup', e));
|
},
|
||||||
}, 1000);
|
],
|
||||||
},
|
},
|
||||||
guildCreate: (guild: DiscordenoGuild) => {
|
],
|
||||||
log(LT.LOG, `Handling joining guild ${JSON.stringify(guild)}`);
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:88', 'Startup', e));
|
||||||
sendMessage(config.logChannel, {
|
}, 1000);
|
||||||
embeds: [{
|
},
|
||||||
title: 'New Guild Joined!',
|
guildCreate: (guild: DiscordenoGuild) => {
|
||||||
color: successColor,
|
log(LT.LOG, `Handling joining guild ${JSON.stringify(guild)}`);
|
||||||
fields: [
|
sendMessage(config.logChannel, {
|
||||||
{
|
embeds: [
|
||||||
name: 'Name:',
|
{
|
||||||
value: `${guild.name}`,
|
title: 'New Guild Joined!',
|
||||||
inline: true,
|
color: successColor,
|
||||||
},
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Id:',
|
name: 'Name:',
|
||||||
value: `${guild.id}`,
|
value: `${guild.name}`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Member Count:',
|
name: 'Id:',
|
||||||
value: `${guild.memberCount}`,
|
value: `${guild.id}`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
}],
|
name: 'Member Count:',
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:95', 'Join Guild', e));
|
value: `${guild.memberCount}`,
|
||||||
},
|
inline: true,
|
||||||
guildDelete: (guild: DiscordenoGuild) => {
|
},
|
||||||
log(LT.LOG, `Handling leaving guild ${JSON.stringify(guild)}`);
|
],
|
||||||
sendMessage(config.logChannel, {
|
},
|
||||||
embeds: [{
|
],
|
||||||
title: 'Removed from Guild',
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:95', 'Join Guild', e));
|
||||||
color: warnColor,
|
},
|
||||||
fields: [
|
guildDelete: (guild: DiscordenoGuild) => {
|
||||||
{
|
log(LT.LOG, `Handling leaving guild ${JSON.stringify(guild)}`);
|
||||||
name: 'Name:',
|
sendMessage(config.logChannel, {
|
||||||
value: `${guild.name}`,
|
embeds: [
|
||||||
inline: true,
|
{
|
||||||
},
|
title: 'Removed from Guild',
|
||||||
{
|
color: warnColor,
|
||||||
name: 'Id:',
|
fields: [
|
||||||
value: `${guild.id}`,
|
{
|
||||||
inline: true,
|
name: 'Name:',
|
||||||
},
|
value: `${guild.name}`,
|
||||||
{
|
inline: true,
|
||||||
name: 'Member Count:',
|
},
|
||||||
value: `${guild.memberCount}`,
|
{
|
||||||
inline: true,
|
name: 'Id:',
|
||||||
},
|
value: `${guild.id}`,
|
||||||
],
|
inline: true,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:99', 'Leave Guild', e));
|
{
|
||||||
dbClient.execute('DELETE FROM allowed_guilds WHERE guildid = ? AND banned = 0', [guild.id]).catch((e) => utils.commonLoggers.dbError('mod.ts:100', 'delete from', e));
|
name: 'Member Count:',
|
||||||
},
|
value: `${guild.memberCount}`,
|
||||||
debug: DEVMODE ? (dmsg) => log(LT.LOG, `Debug Message | ${JSON.stringify(dmsg)}`) : undefined,
|
inline: true,
|
||||||
messageCreate: (message: DiscordenoMessage) => {
|
},
|
||||||
// Ignore all other bots
|
],
|
||||||
if (message.isBot) return;
|
},
|
||||||
|
],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:99', 'Leave Guild', e));
|
||||||
|
dbClient
|
||||||
|
.execute('DELETE FROM allowed_guilds WHERE guildid = ? AND banned = 0', [guild.id])
|
||||||
|
.catch((e) => utils.commonLoggers.dbError('mod.ts:100', 'delete from', e));
|
||||||
|
},
|
||||||
|
debug: DEVMODE ? (dmsg) => log(LT.LOG, `Debug Message | ${JSON.stringify(dmsg)}`) : undefined,
|
||||||
|
messageCreate: (message: DiscordenoMessage) => {
|
||||||
|
// Ignore all other bots
|
||||||
|
if (message.isBot) return;
|
||||||
|
|
||||||
// Ignore users who requested to be ignored
|
// Ignore users who requested to be ignored
|
||||||
if (ignoreList.includes(message.authorId) && (!message.content.startsWith(`${config.prefix}opt-in`) || message.guildId !== 0n)) return;
|
if (ignoreList.includes(message.authorId) && (!message.content.startsWith(`${config.prefix}opt-in`) || message.guildId !== 0n)) return;
|
||||||
|
|
||||||
// Ignore all messages that are not commands
|
// Ignore all messages that are not commands
|
||||||
if (message.content.indexOf(config.prefix) !== 0) {
|
if (message.content.indexOf(config.prefix) !== 0) {
|
||||||
// Handle @bot messages
|
// Handle @bot messages
|
||||||
if (message.mentionedUserIds[0] === botId && (message.content.trim().startsWith(`<@${botId}>`) || message.content.trim().startsWith(`<@!${botId}>`))) {
|
if (message.mentionedUserIds[0] === botId && (message.content.trim().startsWith(`<@${botId}>`) || message.content.trim().startsWith(`<@!${botId}>`))) {
|
||||||
commands.handleMentions(message);
|
commands.handleMentions(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return as we are done handling this command
|
// return as we are done handling this command
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(LT.LOG, `Handling ${config.prefix}command message: ${JSON.stringify(message)}`);
|
log(LT.LOG, `Handling ${config.prefix}command message: ${JSON.stringify(message)}`);
|
||||||
|
|
||||||
// Split into standard command + args format
|
// Split into standard command + args format
|
||||||
const args = message.content.slice(config.prefix.length).trim().split(/[ \n]+/g);
|
const args = message.content
|
||||||
const command = args.shift()?.toLowerCase();
|
.slice(config.prefix.length)
|
||||||
|
.trim()
|
||||||
|
.split(/[ \n]+/g);
|
||||||
|
const command = args.shift()?.toLowerCase();
|
||||||
|
|
||||||
// All commands below here
|
// All commands below here
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'opt-out':
|
case 'opt-out':
|
||||||
case 'ignore-me':
|
case 'ignore-me':
|
||||||
// [[opt-out or [[ignore-me
|
// [[opt-out or [[ignore-me
|
||||||
// Tells the bot to add you to the ignore list.
|
// Tells the bot to add you to the ignore list.
|
||||||
commands.optOut(message);
|
commands.optOut(message);
|
||||||
break;
|
break;
|
||||||
case 'opt-in':
|
case 'opt-in':
|
||||||
// [[opt-in
|
// [[opt-in
|
||||||
// Tells the bot to remove you from the ignore list.
|
// Tells the bot to remove you from the ignore list.
|
||||||
commands.optIn(message);
|
commands.optIn(message);
|
||||||
break;
|
break;
|
||||||
case 'ping':
|
case 'ping':
|
||||||
// [[ping
|
// [[ping
|
||||||
// Its a ping test, what else do you want.
|
// Its a ping test, what else do you want.
|
||||||
commands.ping(message);
|
commands.ping(message);
|
||||||
break;
|
break;
|
||||||
case 'rip':
|
case 'rip':
|
||||||
case 'memory':
|
case 'memory':
|
||||||
// [[rip [[memory
|
// [[rip [[memory
|
||||||
// Displays a short message I wanted to include
|
// Displays a short message I wanted to include
|
||||||
commands.rip(message);
|
commands.rip(message);
|
||||||
break;
|
break;
|
||||||
case 'rollhelp':
|
case 'rollhelp':
|
||||||
case 'rh':
|
case 'rh':
|
||||||
case 'hr':
|
case 'hr':
|
||||||
case '??':
|
case '??':
|
||||||
// [[rollhelp or [[rh or [[hr or [[??
|
// [[rollhelp or [[rh or [[hr or [[??
|
||||||
// Help command specifically for the roll command
|
// Help command specifically for the roll command
|
||||||
commands.rollHelp(message);
|
commands.rollHelp(message);
|
||||||
break;
|
break;
|
||||||
case 'rolldecorators':
|
case 'rolldecorators':
|
||||||
case 'rd':
|
case 'rd':
|
||||||
case 'dr':
|
case 'dr':
|
||||||
case '???':
|
case '???':
|
||||||
// [[rollDecorators or [[rd or [[dr or [[???
|
// [[rollDecorators or [[rd or [[dr or [[???
|
||||||
// Help command specifically for the roll command decorators
|
// Help command specifically for the roll command decorators
|
||||||
commands.rollDecorators(message);
|
commands.rollDecorators(message);
|
||||||
break;
|
break;
|
||||||
case 'help':
|
case 'help':
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
// [[help or [[h or [[?
|
// [[help or [[h or [[?
|
||||||
// Help command, prints from help file
|
// Help command, prints from help file
|
||||||
commands.help(message);
|
commands.help(message);
|
||||||
break;
|
break;
|
||||||
case 'info':
|
case 'info':
|
||||||
case 'i':
|
case 'i':
|
||||||
// [[info or [[i
|
// [[info or [[i
|
||||||
// Info command, prints short desc on bot and some links
|
// Info command, prints short desc on bot and some links
|
||||||
commands.info(message);
|
commands.info(message);
|
||||||
break;
|
break;
|
||||||
case 'privacy':
|
case 'privacy':
|
||||||
// [[privacy
|
// [[privacy
|
||||||
// Privacy command, prints short desc on bot's privacy policy
|
// Privacy command, prints short desc on bot's privacy policy
|
||||||
commands.privacy(message);
|
commands.privacy(message);
|
||||||
break;
|
break;
|
||||||
case 'version':
|
case 'version':
|
||||||
case 'v':
|
case 'v':
|
||||||
// [[version or [[v
|
// [[version or [[v
|
||||||
// Returns version of the bot
|
// Returns version of the bot
|
||||||
commands.version(message);
|
commands.version(message);
|
||||||
break;
|
break;
|
||||||
case 'report':
|
case 'report':
|
||||||
case 'r':
|
case 'r':
|
||||||
// [[report or [[r (command that failed)
|
// [[report or [[r (command that failed)
|
||||||
// Manually report a failed roll
|
// Manually report a failed roll
|
||||||
commands.report(message, args);
|
commands.report(message, args);
|
||||||
break;
|
break;
|
||||||
case 'stats':
|
case 'stats':
|
||||||
case 's':
|
case 's':
|
||||||
// [[stats or [[s
|
// [[stats or [[s
|
||||||
// Displays stats on the bot
|
// Displays stats on the bot
|
||||||
commands.stats(message);
|
commands.stats(message);
|
||||||
break;
|
break;
|
||||||
case 'api':
|
case 'api':
|
||||||
// [[api arg
|
// [[api arg
|
||||||
// API sub commands
|
// API sub commands
|
||||||
commands.api(message, args);
|
commands.api(message, args);
|
||||||
break;
|
break;
|
||||||
case 'audit':
|
case 'audit':
|
||||||
// [[audit arg
|
// [[audit arg
|
||||||
// Audit sub commands
|
// Audit sub commands
|
||||||
commands.audit(message, args);
|
commands.audit(message, args);
|
||||||
break;
|
break;
|
||||||
case 'heatmap':
|
case 'heatmap':
|
||||||
case 'hm':
|
case 'hm':
|
||||||
// [[heatmap or [[hm
|
// [[heatmap or [[hm
|
||||||
// Audit sub commands
|
// Audit sub commands
|
||||||
commands.heatmap(message);
|
commands.heatmap(message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Non-standard commands
|
// Non-standard commands
|
||||||
if (command?.startsWith('xdy')) {
|
if (command?.startsWith('xdy')) {
|
||||||
// [[xdydz (aka someone copy pasted the template as a roll)
|
// [[xdydz (aka someone copy pasted the template as a roll)
|
||||||
// Help command specifically for the roll command
|
// Help command specifically for the roll command
|
||||||
commands.rollHelp(message);
|
commands.rollHelp(message);
|
||||||
} else if (command && (`${command}${args.join('')}`).indexOf(config.postfix) > -1) {
|
} else if (command && `${command}${args.join('')}`.indexOf(config.postfix) > -1) {
|
||||||
// [[roll]]
|
// [[roll]]
|
||||||
// Dice rolling commence!
|
// Dice rolling commence!
|
||||||
commands.roll(message, args, command);
|
commands.roll(message, args, command);
|
||||||
} else if (command) {
|
} else if (command) {
|
||||||
// [[emoji or [[emojialias
|
// [[emoji or [[emojialias
|
||||||
// Check if the unhandled command is an emoji request
|
// Check if the unhandled command is an emoji request
|
||||||
commands.emoji(message, command);
|
commands.emoji(message, command);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start up the command prompt for debug usage
|
// Start up the command prompt for debug usage
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
utils.cmdPrompt(config.logChannel, config.name);
|
utils.cmdPrompt(config.logChannel, config.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start up the API for rolling from third party apps (like excel macros)
|
// Start up the API for rolling from third party apps (like excel macros)
|
||||||
if (config.api.enable) {
|
if (config.api.enable) {
|
||||||
api.start();
|
api.start();
|
||||||
}
|
}
|
||||||
|
|
390
src/api.ts
390
src/api.ts
|
@ -6,217 +6,219 @@
|
||||||
|
|
||||||
import config from '../config.ts';
|
import config from '../config.ts';
|
||||||
import {
|
import {
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../deps.ts';
|
} from '../deps.ts';
|
||||||
import { dbClient } from './db.ts';
|
import dbClient from './db/client.ts';
|
||||||
import endpoints from './endpoints/_index.ts';
|
import endpoints from './endpoints/_index.ts';
|
||||||
import stdResp from './endpoints/stdResponses.ts';
|
import stdResp from './endpoints/stdResponses.ts';
|
||||||
|
|
||||||
// start() returns nothing
|
// start() returns nothing
|
||||||
// start initializes and runs the entire API for the bot
|
// start initializes and runs the entire API for the bot
|
||||||
const start = async (): Promise<void> => {
|
const start = async (): Promise<void> => {
|
||||||
const server = Deno.listen({ port: config.api.port });
|
const server = Deno.listen({ port: config.api.port });
|
||||||
log(LT.INFO, `HTTP api running at: http://localhost:${config.api.port}/`);
|
log(LT.INFO, `HTTP api running at: http://localhost:${config.api.port}/`);
|
||||||
|
|
||||||
// rateLimitTime holds all users with the last time they started a rate limit timer
|
// rateLimitTime holds all users with the last time they started a rate limit timer
|
||||||
const rateLimitTime = new Map<string, number>();
|
const rateLimitTime = new Map<string, number>();
|
||||||
// rateLimitCnt holds the number of times the user has called the api in the current rate limit timer
|
// rateLimitCnt holds the number of times the user has called the api in the current rate limit timer
|
||||||
const rateLimitCnt = new Map<string, number>();
|
const rateLimitCnt = new Map<string, number>();
|
||||||
|
|
||||||
// Catching every request made to the server
|
// Catching every request made to the server
|
||||||
for await (const conn of server) {
|
for await (const conn of server) {
|
||||||
(async () => {
|
(async () => {
|
||||||
const httpConn = Deno.serveHttp(conn);
|
const httpConn = Deno.serveHttp(conn);
|
||||||
for await (const requestEvent of httpConn) {
|
for await (const requestEvent of httpConn) {
|
||||||
const request = requestEvent.request;
|
const request = requestEvent.request;
|
||||||
log(LT.LOG, `Handling request: ${JSON.stringify(request.headers)} | ${JSON.stringify(request.method)} | ${JSON.stringify(request.url)}`);
|
log(LT.LOG, `Handling request: ${JSON.stringify(request.headers)} | ${JSON.stringify(request.method)} | ${JSON.stringify(request.url)}`);
|
||||||
// Check if user is authenticated to be using this API
|
// Check if user is authenticated to be using this API
|
||||||
let authenticated = false;
|
let authenticated = false;
|
||||||
let rateLimited = false;
|
let rateLimited = false;
|
||||||
let updateRateLimitTime = false;
|
let updateRateLimitTime = false;
|
||||||
let apiUserid = 0n;
|
let apiUserid = 0n;
|
||||||
let apiUseridStr = '';
|
let apiUseridStr = '';
|
||||||
let apiUserEmail = '';
|
let apiUserEmail = '';
|
||||||
let apiUserDelCode = '';
|
let apiUserDelCode = '';
|
||||||
|
|
||||||
// Check the requests API key
|
// Check the requests API key
|
||||||
if (request.headers.has('X-Api-Key')) {
|
if (request.headers.has('X-Api-Key')) {
|
||||||
// Get the userid and flags for the specific key
|
// Get the userid and flags for the specific key
|
||||||
const dbApiQuery = await dbClient.query('SELECT userid, email, deleteCode FROM all_keys WHERE apiKey = ? AND active = 1 AND banned = 0', [request.headers.get('X-Api-Key')]);
|
const dbApiQuery = await dbClient.query('SELECT userid, email, deleteCode FROM all_keys WHERE apiKey = ? AND active = 1 AND banned = 0', [
|
||||||
|
request.headers.get('X-Api-Key'),
|
||||||
|
]);
|
||||||
|
|
||||||
// If only one user returned, is not banned, and is currently active, mark as authenticated
|
// If only one user returned, is not banned, and is currently active, mark as authenticated
|
||||||
if (dbApiQuery.length === 1) {
|
if (dbApiQuery.length === 1) {
|
||||||
apiUserid = BigInt(dbApiQuery[0].userid);
|
apiUserid = BigInt(dbApiQuery[0].userid);
|
||||||
apiUserEmail = dbApiQuery[0].email;
|
apiUserEmail = dbApiQuery[0].email;
|
||||||
apiUserDelCode = dbApiQuery[0].deleteCode;
|
apiUserDelCode = dbApiQuery[0].deleteCode;
|
||||||
authenticated = true;
|
authenticated = true;
|
||||||
|
|
||||||
// Rate limiting inits
|
// Rate limiting inits
|
||||||
apiUseridStr = apiUserid.toString();
|
apiUseridStr = apiUserid.toString();
|
||||||
const apiTimeNow = new Date().getTime();
|
const apiTimeNow = new Date().getTime();
|
||||||
|
|
||||||
// Check if user has sent a request recently
|
// Check if user has sent a request recently
|
||||||
if (rateLimitTime.has(apiUseridStr) && (((rateLimitTime.get(apiUseridStr) || 0) + config.api.rateLimitTime) > apiTimeNow)) {
|
if (rateLimitTime.has(apiUseridStr) && (rateLimitTime.get(apiUseridStr) || 0) + config.api.rateLimitTime > apiTimeNow) {
|
||||||
// Get current count
|
// Get current count
|
||||||
const currentCnt = rateLimitCnt.get(apiUseridStr) || 0;
|
const currentCnt = rateLimitCnt.get(apiUseridStr) || 0;
|
||||||
if (currentCnt < config.api.rateLimitCnt) {
|
if (currentCnt < config.api.rateLimitCnt) {
|
||||||
// Limit not yet exceeded, update count
|
// Limit not yet exceeded, update count
|
||||||
rateLimitCnt.set(apiUseridStr, currentCnt + 1);
|
rateLimitCnt.set(apiUseridStr, currentCnt + 1);
|
||||||
} else {
|
} else {
|
||||||
// Limit exceeded, prevent API use
|
// Limit exceeded, prevent API use
|
||||||
rateLimited = true;
|
rateLimited = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Update the maps
|
// Update the maps
|
||||||
updateRateLimitTime = true;
|
updateRateLimitTime = true;
|
||||||
rateLimitCnt.set(apiUseridStr, 1);
|
rateLimitCnt.set(apiUseridStr, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rateLimited) {
|
if (!rateLimited) {
|
||||||
// Get path and query as a string
|
// Get path and query as a string
|
||||||
const [urlPath, tempQ] = request.url.split('?');
|
const [urlPath, tempQ] = request.url.split('?');
|
||||||
const path = urlPath.split('api')[1];
|
const path = urlPath.split('api')[1];
|
||||||
|
|
||||||
// Turn the query into a map (if it exists)
|
// Turn the query into a map (if it exists)
|
||||||
const query = new Map<string, string>();
|
const query = new Map<string, string>();
|
||||||
if (tempQ !== undefined) {
|
if (tempQ !== undefined) {
|
||||||
tempQ.split('&').forEach((e: string) => {
|
tempQ.split('&').forEach((e: string) => {
|
||||||
log(LT.LOG, `Parsing request query ${request} ${e}`);
|
log(LT.LOG, `Parsing request query ${request} ${e}`);
|
||||||
const [option, params] = e.split('=');
|
const [option, params] = e.split('=');
|
||||||
query.set(option.toLowerCase(), params);
|
query.set(option.toLowerCase(), params);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
// Handle the authenticated request
|
// Handle the authenticated request
|
||||||
switch (request.method) {
|
switch (request.method) {
|
||||||
case 'GET':
|
case 'GET':
|
||||||
switch (path.toLowerCase()) {
|
switch (path.toLowerCase()) {
|
||||||
case '/key':
|
case '/key':
|
||||||
case '/key/':
|
case '/key/':
|
||||||
endpoints.get.apiKeyAdmin(requestEvent, query, apiUserid);
|
endpoints.get.apiKeyAdmin(requestEvent, query, apiUserid);
|
||||||
break;
|
break;
|
||||||
case '/channel':
|
case '/channel':
|
||||||
case '/channel/':
|
case '/channel/':
|
||||||
endpoints.get.apiChannel(requestEvent, query, apiUserid);
|
endpoints.get.apiChannel(requestEvent, query, apiUserid);
|
||||||
break;
|
break;
|
||||||
case '/roll':
|
case '/roll':
|
||||||
case '/roll/':
|
case '/roll/':
|
||||||
endpoints.get.apiRoll(requestEvent, query, apiUserid);
|
endpoints.get.apiRoll(requestEvent, query, apiUserid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.NotFound('Auth Get'));
|
requestEvent.respondWith(stdResp.NotFound('Auth Get'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'POST':
|
case 'POST':
|
||||||
switch (path.toLowerCase()) {
|
switch (path.toLowerCase()) {
|
||||||
case '/channel/add':
|
case '/channel/add':
|
||||||
case '/channel/add/':
|
case '/channel/add/':
|
||||||
endpoints.post.apiChannelAdd(requestEvent, query, apiUserid);
|
endpoints.post.apiChannelAdd(requestEvent, query, apiUserid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.NotFound('Auth Post'));
|
requestEvent.respondWith(stdResp.NotFound('Auth Post'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'PUT':
|
case 'PUT':
|
||||||
switch (path.toLowerCase()) {
|
switch (path.toLowerCase()) {
|
||||||
case '/key/ban':
|
case '/key/ban':
|
||||||
case '/key/ban/':
|
case '/key/ban/':
|
||||||
case '/key/unban':
|
case '/key/unban':
|
||||||
case '/key/unban/':
|
case '/key/unban/':
|
||||||
case '/key/activate':
|
case '/key/activate':
|
||||||
case '/key/activate/':
|
case '/key/activate/':
|
||||||
case '/key/deactivate':
|
case '/key/deactivate':
|
||||||
case '/key/deactivate/':
|
case '/key/deactivate/':
|
||||||
endpoints.put.apiKeyManage(requestEvent, query, apiUserid, path);
|
endpoints.put.apiKeyManage(requestEvent, query, apiUserid, path);
|
||||||
break;
|
break;
|
||||||
case '/channel/ban':
|
case '/channel/ban':
|
||||||
case '/channel/ban/':
|
case '/channel/ban/':
|
||||||
case '/channel/unban':
|
case '/channel/unban':
|
||||||
case '/channel/unban/':
|
case '/channel/unban/':
|
||||||
endpoints.put.apiChannelManageBan(requestEvent, query, apiUserid, path);
|
endpoints.put.apiChannelManageBan(requestEvent, query, apiUserid, path);
|
||||||
break;
|
break;
|
||||||
case '/channel/activate':
|
case '/channel/activate':
|
||||||
case '/channel/activate/':
|
case '/channel/activate/':
|
||||||
case '/channel/deactivate':
|
case '/channel/deactivate':
|
||||||
case '/channel/deactivate/':
|
case '/channel/deactivate/':
|
||||||
endpoints.put.apiChannelManageActive(requestEvent, query, apiUserid, path);
|
endpoints.put.apiChannelManageActive(requestEvent, query, apiUserid, path);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.NotFound('Auth Put'));
|
requestEvent.respondWith(stdResp.NotFound('Auth Put'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'DELETE':
|
case 'DELETE':
|
||||||
switch (path.toLowerCase()) {
|
switch (path.toLowerCase()) {
|
||||||
case '/key/delete':
|
case '/key/delete':
|
||||||
case '/key/delete/':
|
case '/key/delete/':
|
||||||
endpoints.delete.apiKeyDelete(requestEvent, query, apiUserid, apiUserEmail, apiUserDelCode);
|
endpoints.delete.apiKeyDelete(requestEvent, query, apiUserid, apiUserEmail, apiUserDelCode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.NotFound('Auth Del'));
|
requestEvent.respondWith(stdResp.NotFound('Auth Del'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.MethodNotAllowed('Auth'));
|
requestEvent.respondWith(stdResp.MethodNotAllowed('Auth'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update rate limit details
|
// Update rate limit details
|
||||||
if (updateRateLimitTime) {
|
if (updateRateLimitTime) {
|
||||||
const apiTimeNow = new Date().getTime();
|
const apiTimeNow = new Date().getTime();
|
||||||
rateLimitTime.set(apiUseridStr, apiTimeNow);
|
rateLimitTime.set(apiUseridStr, apiTimeNow);
|
||||||
}
|
}
|
||||||
} else if (!authenticated) {
|
} else if (!authenticated) {
|
||||||
// Handle the unathenticated request
|
// Handle the unathenticated request
|
||||||
switch (request.method) {
|
switch (request.method) {
|
||||||
case 'GET':
|
case 'GET':
|
||||||
switch (path.toLowerCase()) {
|
switch (path.toLowerCase()) {
|
||||||
case '/key':
|
case '/key':
|
||||||
case '/key/':
|
case '/key/':
|
||||||
endpoints.get.apiKey(requestEvent, query);
|
endpoints.get.apiKey(requestEvent, query);
|
||||||
break;
|
break;
|
||||||
case '/heatmap.png':
|
case '/heatmap.png':
|
||||||
endpoints.get.heatmapPng(requestEvent);
|
endpoints.get.heatmapPng(requestEvent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.NotFound('NoAuth Get'));
|
requestEvent.respondWith(stdResp.NotFound('NoAuth Get'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.MethodNotAllowed('NoAuth'));
|
requestEvent.respondWith(stdResp.MethodNotAllowed('NoAuth'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
requestEvent.respondWith(stdResp.Forbidden('What are you trying to do?'));
|
requestEvent.respondWith(stdResp.Forbidden('What are you trying to do?'));
|
||||||
}
|
}
|
||||||
} else if (authenticated && rateLimited) {
|
} else if (authenticated && rateLimited) {
|
||||||
// Alert API user that they are doing this too often
|
// Alert API user that they are doing this too often
|
||||||
requestEvent.respondWith(stdResp.TooManyRequests('Slow down, servers are expensive and this bot is free to use.'));
|
requestEvent.respondWith(stdResp.TooManyRequests('Slow down, servers are expensive and this bot is free to use.'));
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('Why are you here?'));
|
requestEvent.respondWith(stdResp.Forbidden('Why are you here?'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default { start };
|
export default { start };
|
||||||
|
|
|
@ -1,74 +1,84 @@
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
hasGuildPermissions,
|
hasGuildPermissions,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import apiCommands from './apiCmd/_index.ts';
|
import apiCommands from './apiCmd/_index.ts';
|
||||||
import { failColor } from '../commandUtils.ts';
|
import { failColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const api = async (message: DiscordenoMessage, args: string[]) => {
|
export const api = async (message: DiscordenoMessage, args: string[]) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('api')).catch((e) => utils.commonLoggers.dbError('apiCmd.ts:16', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('api')).catch((e) => utils.commonLoggers.dbError('apiCmd.ts:16', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
// Local apiArg in lowercase
|
// Local apiArg in lowercase
|
||||||
const apiArg = (args[0] || 'help').toLowerCase();
|
const apiArg = (args[0] || 'help').toLowerCase();
|
||||||
|
|
||||||
// Alert users who DM the bot that this command is for guilds only
|
// Alert users who DM the bot that this command is for guilds only
|
||||||
if (message.guildId === 0n) {
|
if (message.guildId === 0n) {
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: failColor,
|
embeds: [
|
||||||
title: 'API commands are only available in guilds.',
|
{
|
||||||
}],
|
color: failColor,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('apiCmd.ts:30', message, e));
|
title: 'API commands are only available in guilds.',
|
||||||
return;
|
},
|
||||||
}
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('apiCmd.ts:30', message, e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Makes sure the user is authenticated to run the API command
|
// Makes sure the user is authenticated to run the API command
|
||||||
if (await hasGuildPermissions(message.authorId, message.guildId, ['ADMINISTRATOR'])) {
|
if (await hasGuildPermissions(message.authorId, message.guildId, ['ADMINISTRATOR'])) {
|
||||||
switch (apiArg) {
|
switch (apiArg) {
|
||||||
case 'help':
|
case 'help':
|
||||||
case 'h':
|
case 'h':
|
||||||
// [[api help
|
// [[api help
|
||||||
// Shows API help details
|
// Shows API help details
|
||||||
apiCommands.help(message);
|
apiCommands.help(message);
|
||||||
break;
|
break;
|
||||||
case 'allow':
|
case 'allow':
|
||||||
case 'block':
|
case 'block':
|
||||||
case 'enable':
|
case 'enable':
|
||||||
case 'disable':
|
case 'disable':
|
||||||
// [[api allow/block
|
// [[api allow/block
|
||||||
// Lets a guild admin allow or ban API rolls from happening in said guild
|
// Lets a guild admin allow or ban API rolls from happening in said guild
|
||||||
apiCommands.allowBlock(message, apiArg);
|
apiCommands.allowBlock(message, apiArg);
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
// [[api delete
|
// [[api delete
|
||||||
// Lets a guild admin delete their server from the database
|
// Lets a guild admin delete their server from the database
|
||||||
apiCommands.deleteGuild(message);
|
apiCommands.deleteGuild(message);
|
||||||
break;
|
break;
|
||||||
case 'status':
|
case 'status':
|
||||||
// [[api status
|
// [[api status
|
||||||
// Lets a guild admin check the status of API rolling in said guild
|
// Lets a guild admin check the status of API rolling in said guild
|
||||||
apiCommands.status(message);
|
apiCommands.status(message);
|
||||||
break;
|
break;
|
||||||
case 'show-warn':
|
case 'show-warn':
|
||||||
case 'hide-warn':
|
case 'hide-warn':
|
||||||
// [[api show-warn/hide-warn
|
// [[api show-warn/hide-warn
|
||||||
// Lets a guild admin decide if the API warning should be shown on messages from the API
|
// Lets a guild admin decide if the API warning should be shown on messages from the API
|
||||||
apiCommands.showHideWarn(message, apiArg);
|
apiCommands.showHideWarn(message, apiArg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: failColor,
|
embeds: [
|
||||||
title: 'API commands are powerful and can only be used by guild Owners and Admins.',
|
{
|
||||||
description: 'For information on how to use the API, please check the GitHub README for more information [here](https://github.com/Burn-E99/TheArtificer).',
|
color: failColor,
|
||||||
}],
|
title: 'API commands are powerful and can only be used by guild Owners and Admins.',
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('apiCmd.ts:77', message, e));
|
description:
|
||||||
}
|
'For information on how to use the API, please check the GitHub README for more information [here](https://github.com/Burn-E99/TheArtificer).',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('apiCmd.ts:77', message, e));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,42 +1,52 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { generateApiFailed, generateApiSuccess } from '../../commandUtils.ts';
|
import { generateApiFailed, generateApiSuccess } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const allowBlock = async (message: DiscordenoMessage, apiArg: string) => {
|
export const allowBlock = async (message: DiscordenoMessage, apiArg: string) => {
|
||||||
let errorOutInitial = false;
|
let errorOutInitial = false;
|
||||||
const guildQuery = await dbClient.query(`SELECT guildid, channelid FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId]).catch((e0) => {
|
const guildQuery = await dbClient
|
||||||
utils.commonLoggers.dbError('allowBlock.ts:15', 'query', e0);
|
.query(`SELECT guildid, channelid FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId])
|
||||||
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:16', message, e));
|
.catch((e0) => {
|
||||||
errorOutInitial = true;
|
utils.commonLoggers.dbError('allowBlock.ts:15', 'query', e0);
|
||||||
});
|
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:16', message, e));
|
||||||
if (errorOutInitial) return;
|
errorOutInitial = true;
|
||||||
|
});
|
||||||
|
if (errorOutInitial) return;
|
||||||
|
|
||||||
let errorOut = false;
|
let errorOut = false;
|
||||||
if (guildQuery.length === 0) {
|
if (guildQuery.length === 0) {
|
||||||
// Since guild is not in our DB, add it in
|
// Since guild is not in our DB, add it in
|
||||||
await dbClient.execute(`INSERT INTO allowed_guilds(guildid,channelid,active) values(?,?,?)`, [message.guildId, message.channelId, (apiArg === 'allow' || apiArg === 'enable') ? 1 : 0]).catch(
|
await dbClient
|
||||||
(e0) => {
|
.execute(`INSERT INTO allowed_guilds(guildid,channelid,active) values(?,?,?)`, [
|
||||||
utils.commonLoggers.dbError('allowBlock:26', 'insert into', e0);
|
message.guildId,
|
||||||
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:27', message, e));
|
message.channelId,
|
||||||
errorOut = true;
|
apiArg === 'allow' || apiArg === 'enable' ? 1 : 0,
|
||||||
},
|
])
|
||||||
);
|
.catch((e0) => {
|
||||||
} else {
|
utils.commonLoggers.dbError('allowBlock:26', 'insert into', e0);
|
||||||
// Since guild is in our DB, update it
|
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:27', message, e));
|
||||||
await dbClient.execute(`UPDATE allowed_guilds SET active = ? WHERE guildid = ? AND channelid = ?`, [(apiArg === 'allow' || apiArg === 'enable') ? 1 : 0, message.guildId, message.channelId]).catch(
|
errorOut = true;
|
||||||
(e0) => {
|
});
|
||||||
utils.commonLoggers.dbError('allowBlock.ts:35', 'update', e0);
|
} else {
|
||||||
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:36', message, e));
|
// Since guild is in our DB, update it
|
||||||
errorOut = true;
|
await dbClient
|
||||||
},
|
.execute(`UPDATE allowed_guilds SET active = ? WHERE guildid = ? AND channelid = ?`, [
|
||||||
);
|
apiArg === 'allow' || apiArg === 'enable' ? 1 : 0,
|
||||||
}
|
message.guildId,
|
||||||
if (errorOut) return;
|
message.channelId,
|
||||||
|
])
|
||||||
|
.catch((e0) => {
|
||||||
|
utils.commonLoggers.dbError('allowBlock.ts:35', 'update', e0);
|
||||||
|
message.send(generateApiFailed(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:36', message, e));
|
||||||
|
errorOut = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (errorOut) return;
|
||||||
|
|
||||||
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
||||||
message.send(generateApiSuccess(`${apiArg}ed`)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:44', message, e));
|
message.send(generateApiSuccess(`${apiArg}ed`)).catch((e: Error) => utils.commonLoggers.messageSendError('allowBlock.ts:44', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +1,39 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { failColor, successColor } from '../../commandUtils.ts';
|
import { failColor, successColor } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const deleteGuild = async (message: DiscordenoMessage) => {
|
export const deleteGuild = async (message: DiscordenoMessage) => {
|
||||||
let errorOut = false;
|
let errorOut = false;
|
||||||
await dbClient.execute(`DELETE FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId]).catch((e0) => {
|
await dbClient.execute(`DELETE FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId]).catch((e0) => {
|
||||||
utils.commonLoggers.dbError('deleteGuild.ts:15', 'query', e0);
|
utils.commonLoggers.dbError('deleteGuild.ts:15', 'query', e0);
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: failColor,
|
embeds: [
|
||||||
title: 'Failed to delete this guild from the database.',
|
{
|
||||||
description: 'If this issue persists, please report this to the developers.',
|
color: failColor,
|
||||||
}],
|
title: 'Failed to delete this guild from the database.',
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('deleteGuild.ts:22', message, e));
|
description: 'If this issue persists, please report this to the developers.',
|
||||||
errorOut = true;
|
},
|
||||||
});
|
],
|
||||||
if (errorOut) return;
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('deleteGuild.ts:22', message, e));
|
||||||
|
errorOut = true;
|
||||||
|
});
|
||||||
|
if (errorOut) return;
|
||||||
|
|
||||||
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: successColor,
|
embeds: [
|
||||||
title: 'This guild\'s API setting has been removed from The Artifier\'s Database.',
|
{
|
||||||
}],
|
color: successColor,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('deleteGuild.ts:33', message, e));
|
title: "This guild's API setting has been removed from The Artifier's Database.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('deleteGuild.ts:33', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,38 +1,48 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { generateApiFailed, generateApiSuccess } from '../../commandUtils.ts';
|
import { generateApiFailed, generateApiSuccess } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const showHideWarn = async (message: DiscordenoMessage, apiArg: string) => {
|
export const showHideWarn = async (message: DiscordenoMessage, apiArg: string) => {
|
||||||
let errorOutInitial = false;
|
let errorOutInitial = false;
|
||||||
const guildQuery = await dbClient.query(`SELECT guildid, channelid FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId]).catch((e0) => {
|
const guildQuery = await dbClient
|
||||||
utils.commonLoggers.dbError('showHideWarn.ts:15', 'query', e0);
|
.query(`SELECT guildid, channelid FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId])
|
||||||
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:16', message, e));
|
.catch((e0) => {
|
||||||
errorOutInitial = true;
|
utils.commonLoggers.dbError('showHideWarn.ts:15', 'query', e0);
|
||||||
});
|
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:16', message, e));
|
||||||
if (errorOutInitial) return;
|
errorOutInitial = true;
|
||||||
|
});
|
||||||
|
if (errorOutInitial) return;
|
||||||
|
|
||||||
let errorOut = false;
|
let errorOut = false;
|
||||||
if (guildQuery.length === 0) {
|
if (guildQuery.length === 0) {
|
||||||
// Since guild is not in our DB, add it in
|
// Since guild is not in our DB, add it in
|
||||||
await dbClient.execute(`INSERT INTO allowed_guilds(guildid,channelid,hidewarn) values(?,?,?)`, [message.guildId, message.channelId, (apiArg === 'hide-warn') ? 1 : 0]).catch((e0) => {
|
await dbClient
|
||||||
utils.commonLoggers.dbError('showHideWarn.ts:25', 'insert inot', e0);
|
.execute(`INSERT INTO allowed_guilds(guildid,channelid,hidewarn) values(?,?,?)`, [message.guildId, message.channelId, apiArg === 'hide-warn' ? 1 : 0])
|
||||||
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:26', message, e));
|
.catch((e0) => {
|
||||||
errorOut = true;
|
utils.commonLoggers.dbError('showHideWarn.ts:25', 'insert inot', e0);
|
||||||
});
|
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:26', message, e));
|
||||||
} else {
|
errorOut = true;
|
||||||
// Since guild is in our DB, update it
|
});
|
||||||
await dbClient.execute(`UPDATE allowed_guilds SET hidewarn = ? WHERE guildid = ? AND channelid = ?`, [(apiArg === 'hide-warn') ? 1 : 0, message.guildId, message.channelId]).catch((e0) => {
|
} else {
|
||||||
utils.commonLoggers.dbError('showHideWarn.ts:32', 'update', e0);
|
// Since guild is in our DB, update it
|
||||||
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:33', message, e));
|
await dbClient
|
||||||
errorOut = true;
|
.execute(`UPDATE allowed_guilds SET hidewarn = ? WHERE guildid = ? AND channelid = ?`, [
|
||||||
});
|
apiArg === 'hide-warn' ? 1 : 0,
|
||||||
}
|
message.guildId,
|
||||||
if (errorOut) return;
|
message.channelId,
|
||||||
|
])
|
||||||
|
.catch((e0) => {
|
||||||
|
utils.commonLoggers.dbError('showHideWarn.ts:32', 'update', e0);
|
||||||
|
message.send(generateApiFailed(`${apiArg} on`)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:33', message, e));
|
||||||
|
errorOut = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (errorOut) return;
|
||||||
|
|
||||||
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
// We won't get here if there's any errors, so we know it has bee successful, so report as such
|
||||||
message.send(generateApiSuccess(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:40', message, e));
|
message.send(generateApiSuccess(apiArg)).catch((e: Error) => utils.commonLoggers.messageSendError('showHideWarn.ts:40', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,37 +1,43 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { failColor, generateApiStatus } from '../../commandUtils.ts';
|
import { failColor, generateApiStatus } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const status = async (message: DiscordenoMessage) => {
|
export const status = async (message: DiscordenoMessage) => {
|
||||||
// Get status of guild from the db
|
// Get status of guild from the db
|
||||||
let errorOut = false;
|
let errorOut = false;
|
||||||
const guildQuery = await dbClient.query(`SELECT active, banned FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId]).catch((e0) => {
|
const guildQuery = await dbClient
|
||||||
utils.commonLoggers.dbError('status.ts:16', 'query', e0);
|
.query(`SELECT active, banned FROM allowed_guilds WHERE guildid = ? AND channelid = ?`, [message.guildId, message.channelId])
|
||||||
message.send({
|
.catch((e0) => {
|
||||||
embeds: [{
|
utils.commonLoggers.dbError('status.ts:16', 'query', e0);
|
||||||
color: failColor,
|
message
|
||||||
title: 'Failed to check API rolls status for this guild.',
|
.send({
|
||||||
description: 'If this issue persists, please report this to the developers.',
|
embeds: [
|
||||||
}],
|
{
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:23', message, e));
|
color: failColor,
|
||||||
errorOut = true;
|
title: 'Failed to check API rolls status for this guild.',
|
||||||
});
|
description: 'If this issue persists, please report this to the developers.',
|
||||||
if (errorOut) return;
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:23', message, e));
|
||||||
|
errorOut = true;
|
||||||
|
});
|
||||||
|
if (errorOut) return;
|
||||||
|
|
||||||
// Check if we got an item back or not
|
// Check if we got an item back or not
|
||||||
if (guildQuery.length > 0) {
|
if (guildQuery.length > 0) {
|
||||||
// Check if guild is banned from using API and return appropriate message
|
// Check if guild is banned from using API and return appropriate message
|
||||||
if (guildQuery[0].banned) {
|
if (guildQuery[0].banned) {
|
||||||
message.send(generateApiStatus(true, false)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:32', message, e));
|
message.send(generateApiStatus(true, false)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:32', message, e));
|
||||||
} else {
|
} else {
|
||||||
message.send(generateApiStatus(false, guildQuery[0].active)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:34', message, e));
|
message.send(generateApiStatus(false, guildQuery[0].active)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:34', message, e));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Guild is not in DB, therefore they are blocked
|
// Guild is not in DB, therefore they are blocked
|
||||||
message.send(generateApiStatus(false, false)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:38', message, e));
|
message.send(generateApiStatus(false, false)).catch((e: Error) => utils.commonLoggers.messageSendError('status.ts:38', message, e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,48 +1,53 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import auditCommands from './auditCmd/_index.ts';
|
import auditCommands from './auditCmd/_index.ts';
|
||||||
import { failColor } from '../commandUtils.ts';
|
import { failColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const audit = async (message: DiscordenoMessage, args: string[]) => {
|
export const audit = async (message: DiscordenoMessage, args: string[]) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('audit')).catch((e) => utils.commonLoggers.dbError('audit.ts:16', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('audit')).catch((e) => utils.commonLoggers.dbError('audit.ts:16', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
// Local apiArg in lowercase
|
// Local apiArg in lowercase
|
||||||
const auditArg = (args[0] || 'help').toLowerCase();
|
const auditArg = (args[0] || 'help').toLowerCase();
|
||||||
|
|
||||||
// Makes sure the user is authenticated to run the API command
|
// Makes sure the user is authenticated to run the API command
|
||||||
if (message.authorId === config.api.admin) {
|
if (message.authorId === config.api.admin) {
|
||||||
switch (auditArg) {
|
switch (auditArg) {
|
||||||
case 'help':
|
case 'help':
|
||||||
case 'h':
|
case 'h':
|
||||||
// [[audit help or [[audit h
|
// [[audit help or [[audit h
|
||||||
// Shows API help details
|
// Shows API help details
|
||||||
auditCommands.auditHelp(message);
|
auditCommands.auditHelp(message);
|
||||||
break;
|
break;
|
||||||
case 'db':
|
case 'db':
|
||||||
// [[audit db
|
// [[audit db
|
||||||
// Shows current DB table sizes
|
// Shows current DB table sizes
|
||||||
auditCommands.auditDB(message);
|
auditCommands.auditDB(message);
|
||||||
break;
|
break;
|
||||||
case 'guilds':
|
case 'guilds':
|
||||||
// [[audit guilds
|
// [[audit guilds
|
||||||
// Shows breakdown of guilds and detials on them
|
// Shows breakdown of guilds and detials on them
|
||||||
auditCommands.auditGuilds(message);
|
auditCommands.auditGuilds(message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: failColor,
|
embeds: [
|
||||||
title: `Audit commands are powerful and can only be used by ${config.name}'s owner.`,
|
{
|
||||||
}],
|
color: failColor,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('audit.ts:51', message, e));
|
title: `Audit commands are powerful and can only be used by ${config.name}'s owner.`,
|
||||||
}
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('audit.ts:51', message, e));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,42 +1,44 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
EmbedField,
|
EmbedField,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { infoColor2 } from '../../commandUtils.ts';
|
import { infoColor2 } from '../../commandUtils.ts';
|
||||||
import { compilingStats } from '../../commonEmbeds.ts';
|
import { compilingStats } from '../../commonEmbeds.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const auditDB = async (message: DiscordenoMessage) => {
|
export const auditDB = async (message: DiscordenoMessage) => {
|
||||||
try {
|
try {
|
||||||
const m = await message.send(compilingStats);
|
const m = await message.send(compilingStats);
|
||||||
|
|
||||||
// Get DB statistics
|
// Get DB statistics
|
||||||
const auditQuery = await dbClient.query(`SELECT * FROM db_size;`).catch((e) => utils.commonLoggers.dbError('auditDB.ts:19', 'query', e));
|
const auditQuery = await dbClient.query(`SELECT * FROM db_size;`).catch((e) => utils.commonLoggers.dbError('auditDB.ts:19', 'query', e));
|
||||||
|
|
||||||
// Turn all tables into embed fields, currently only properly will handle 25 tables, but we'll fix that when artificer gets 26 tables
|
// Turn all tables into embed fields, currently only properly will handle 25 tables, but we'll fix that when artificer gets 26 tables
|
||||||
const embedFields: Array<EmbedField> = [];
|
const embedFields: Array<EmbedField> = [];
|
||||||
auditQuery.forEach((row: any) => {
|
auditQuery.forEach((row: any) => {
|
||||||
embedFields.push({
|
embedFields.push({
|
||||||
name: `${row.table}`,
|
name: `${row.table}`,
|
||||||
value: `**Size:** ${row.size} MB
|
value: `**Size:** ${row.size} MB
|
||||||
**Rows:** ${row.rows}`,
|
**Rows:** ${row.rows}`,
|
||||||
inline: true,
|
inline: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send the results
|
// Send the results
|
||||||
m.edit({
|
m.edit({
|
||||||
embeds: [{
|
embeds: [
|
||||||
color: infoColor2,
|
{
|
||||||
title: 'Database Audit',
|
color: infoColor2,
|
||||||
description: 'Lists all tables with their current size and row count.',
|
title: 'Database Audit',
|
||||||
timestamp: new Date().toISOString(),
|
description: 'Lists all tables with their current size and row count.',
|
||||||
fields: embedFields,
|
timestamp: new Date().toISOString(),
|
||||||
}],
|
fields: embedFields,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageEditError('auditDB.ts:43', message, e));
|
},
|
||||||
} catch (e) {
|
],
|
||||||
utils.commonLoggers.messageSendError('auditDB.ts:45', message, e);
|
}).catch((e: Error) => utils.commonLoggers.messageEditError('auditDB.ts:43', message, e));
|
||||||
}
|
} catch (e) {
|
||||||
|
utils.commonLoggers.messageSendError('auditDB.ts:45', message, e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { EmojiConf } from '../mod.d.ts';
|
import { EmojiConf } from '../mod.d.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
@ -13,28 +14,30 @@ import utils from '../utils.ts';
|
||||||
const allEmojiAliases: string[] = [];
|
const allEmojiAliases: string[] = [];
|
||||||
|
|
||||||
config.emojis.forEach((emji: EmojiConf) => {
|
config.emojis.forEach((emji: EmojiConf) => {
|
||||||
allEmojiAliases.push(...emji.aliases);
|
allEmojiAliases.push(...emji.aliases);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const emoji = (message: DiscordenoMessage, command: string) => {
|
export const emoji = (message: DiscordenoMessage, command: string) => {
|
||||||
// shortcut
|
// shortcut
|
||||||
if (allEmojiAliases.indexOf(command)) {
|
if (allEmojiAliases.indexOf(command)) {
|
||||||
// Start looping thru the possible emojis
|
// Start looping thru the possible emojis
|
||||||
config.emojis.some((emji: EmojiConf) => {
|
config.emojis.some((emji: EmojiConf) => {
|
||||||
log(LT.LOG, `Checking if command was emoji ${JSON.stringify(emji)}`);
|
log(LT.LOG, `Checking if command was emoji ${JSON.stringify(emji)}`);
|
||||||
// If a match gets found
|
// If a match gets found
|
||||||
if (emji.aliases.indexOf(command || '') > -1) {
|
if (emji.aliases.indexOf(command || '') > -1) {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('emojis')).catch((e) => utils.commonLoggers.dbError('emojis.ts:28', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('emojis')).catch((e) => utils.commonLoggers.dbError('emojis.ts:28', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
// Send the needed emoji
|
// Send the needed emoji
|
||||||
message.send(`<${emji.animated ? 'a' : ''}:${emji.name}:${emji.id}>`).catch((e: Error) => utils.commonLoggers.messageSendError('emoji.ts:33', message, e));
|
message
|
||||||
// And attempt to delete if needed
|
.send(`<${emji.animated ? 'a' : ''}:${emji.name}:${emji.id}>`)
|
||||||
if (emji.deleteSender) {
|
.catch((e: Error) => utils.commonLoggers.messageSendError('emoji.ts:33', message, e));
|
||||||
message.delete().catch((e: Error) => utils.commonLoggers.messageDeleteError('emoji.ts:36', message, e));
|
// And attempt to delete if needed
|
||||||
}
|
if (emji.deleteSender) {
|
||||||
return true;
|
message.delete().catch((e: Error) => utils.commonLoggers.messageDeleteError('emoji.ts:36', message, e));
|
||||||
}
|
}
|
||||||
});
|
return true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +1,38 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor1 } from '../commandUtils.ts';
|
import { infoColor1 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const handleMentions = (message: DiscordenoMessage) => {
|
export const handleMentions = (message: DiscordenoMessage) => {
|
||||||
log(LT.LOG, `Handling @mention message: ${JSON.stringify(message)}`);
|
log(LT.LOG, `Handling @mention message: ${JSON.stringify(message)}`);
|
||||||
|
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('mention')).catch((e) => utils.commonLoggers.dbError('handleMentions.ts:17', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('mention')).catch((e) => utils.commonLoggers.dbError('handleMentions.ts:17', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor1,
|
embeds: [
|
||||||
title: `Hello! I am ${config.name}!`,
|
{
|
||||||
fields: [{
|
color: infoColor1,
|
||||||
name: 'I am a bot that specializes in rolling dice and doing basic algebra.',
|
title: `Hello! I am ${config.name}!`,
|
||||||
value: `To learn about my available commands, please run \`${config.prefix}help\`.
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'I am a bot that specializes in rolling dice and doing basic algebra.',
|
||||||
|
value: `To learn about my available commands, please run \`${config.prefix}help\`.
|
||||||
|
|
||||||
Want me to ignore you? Simply run \`${config.prefix}opt-out\` and ${config.name} will no longer read your messages or respond to you.`,
|
Want me to ignore you? Simply run \`${config.prefix}opt-out\` and ${config.name} will no longer read your messages or respond to you.`,
|
||||||
}],
|
},
|
||||||
}],
|
],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('handleMentions.ts:30', message, e));
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('handleMentions.ts:30', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { failColor, infoColor2 } from '../commandUtils.ts';
|
import { failColor, infoColor2 } from '../commandUtils.ts';
|
||||||
|
@ -9,33 +10,41 @@ import utils from '../utils.ts';
|
||||||
import intervals from '../intervals.ts';
|
import intervals from '../intervals.ts';
|
||||||
|
|
||||||
export const heatmap = async (message: DiscordenoMessage) => {
|
export const heatmap = async (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('heatmap')).catch((e) => utils.commonLoggers.dbError('heatmap.ts:14', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('heatmap')).catch((e) => utils.commonLoggers.dbError('heatmap.ts:14', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
if (config.api.enable) {
|
if (config.api.enable) {
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
title: 'Roll Heatmap',
|
embeds: [
|
||||||
description: `Over time, this image will show a nice pattern of when rolls are requested the most.
|
{
|
||||||
|
title: 'Roll Heatmap',
|
||||||
|
description: `Over time, this image will show a nice pattern of when rolls are requested the most.
|
||||||
|
|
||||||
Least Rolls: ${intervals.getMinRollCnt()}
|
Least Rolls: ${intervals.getMinRollCnt()}
|
||||||
Most Rolls: ${intervals.getMaxRollCnt()}`,
|
Most Rolls: ${intervals.getMaxRollCnt()}`,
|
||||||
footer: {
|
footer: {
|
||||||
text: 'Data is shown in US Eastern Time. | This heatmap uses data starting 6/26/2022.',
|
text: 'Data is shown in US Eastern Time. | This heatmap uses data starting 6/26/2022.',
|
||||||
},
|
},
|
||||||
color: infoColor2,
|
color: infoColor2,
|
||||||
image: {
|
image: {
|
||||||
url: `${config.api.publicDomain}api/heatmap.png`,
|
url: `${config.api.publicDomain}api/heatmap.png`,
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
}).catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e));
|
],
|
||||||
} else {
|
})
|
||||||
message.send({
|
.catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e));
|
||||||
embeds: [{
|
} else {
|
||||||
title: 'Roll Heatmap Disabled',
|
message
|
||||||
description: 'This command requires the bot\'s API to be enabled. If you are the host of this bot, check your `config.ts` file to enable it.',
|
.send({
|
||||||
color: failColor,
|
embeds: [
|
||||||
}],
|
{
|
||||||
}).catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e));
|
title: 'Roll Heatmap Disabled',
|
||||||
}
|
description: "This command requires the bot's API to be enabled. If you are the host of this bot, check your `config.ts` file to enable it.",
|
||||||
|
color: failColor,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,98 +1,102 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor2 } from '../commandUtils.ts';
|
import { infoColor2 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const help = (message: DiscordenoMessage) => {
|
export const help = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('help')).catch((e) => utils.commonLoggers.dbError('htlp.ts:15', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('help')).catch((e) => utils.commonLoggers.dbError('htlp.ts:15', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor2,
|
embeds: [
|
||||||
title: 'The Artificer\'s Available Commands:',
|
{
|
||||||
fields: [
|
color: infoColor2,
|
||||||
{
|
title: "The Artificer's Available Commands:",
|
||||||
name: `\`${config.prefix}?\``,
|
fields: [
|
||||||
value: 'This command',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}?\``,
|
||||||
},
|
value: 'This command',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}rollhelp\` or \`${config.prefix}??\``,
|
},
|
||||||
value: `Details on how to use the roll command, listed as \`${config.prefix}xdy...${config.postfix}\` below`,
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}rollhelp\` or \`${config.prefix}??\``,
|
||||||
},
|
value: `Details on how to use the roll command, listed as \`${config.prefix}xdy...${config.postfix}\` below`,
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}rollDecorators\` or \`${config.prefix}???\``,
|
},
|
||||||
value: `Details on how to use decorators on the roll command`,
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}rollDecorators\` or \`${config.prefix}???\``,
|
||||||
},
|
value: `Details on how to use decorators on the roll command`,
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}api [subcommand]\``,
|
},
|
||||||
value: `Administrative tools for the bots's API, run \`${config.prefix}api help\` for more details`,
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}api [subcommand]\``,
|
||||||
},
|
value: `Administrative tools for the bots's API, run \`${config.prefix}api help\` for more details`,
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}ping\``,
|
},
|
||||||
value: 'Pings the bot to check connectivity',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}ping\``,
|
||||||
},
|
value: 'Pings the bot to check connectivity',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}info\``,
|
},
|
||||||
value: 'Prints some information and links relating to the bot',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}info\``,
|
||||||
},
|
value: 'Prints some information and links relating to the bot',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}privacy\``,
|
},
|
||||||
value: 'Prints some information about the Privacy Policy',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}privacy\``,
|
||||||
},
|
value: 'Prints some information about the Privacy Policy',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}version\``,
|
},
|
||||||
value: 'Prints the bots version',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}version\``,
|
||||||
},
|
value: 'Prints the bots version',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}popcat\``,
|
},
|
||||||
value: 'Popcat',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}popcat\``,
|
||||||
},
|
value: 'Popcat',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}report [text]\``,
|
},
|
||||||
value: 'Report a command that failed to run',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}report [text]\``,
|
||||||
},
|
value: 'Report a command that failed to run',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}stats\``,
|
},
|
||||||
value: 'Statistics on the bot',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}stats\``,
|
||||||
},
|
value: 'Statistics on the bot',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}heatmap\``,
|
},
|
||||||
value: 'Heatmap of when the roll command is run the most',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}heatmap\``,
|
||||||
},
|
value: 'Heatmap of when the roll command is run the most',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}opt-out\` or \`${config.prefix}ignore-me\``,
|
},
|
||||||
value: 'Adds you to an ignore list so the bot will never respond to you',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}opt-out\` or \`${config.prefix}ignore-me\``,
|
||||||
},
|
value: 'Adds you to an ignore list so the bot will never respond to you',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}opt-in\` **Available via DM ONLY**`,
|
},
|
||||||
value: 'Removes you from the ignore list',
|
{
|
||||||
inline: true,
|
name: `\`${config.prefix}opt-in\` **Available via DM ONLY**`,
|
||||||
},
|
value: 'Removes you from the ignore list',
|
||||||
{
|
inline: true,
|
||||||
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
},
|
||||||
value:
|
{
|
||||||
`Rolls all configs requested, you may repeat the command multiple times in the same message (just ensure you close each roll with \`${config.postfix}\`), run \`${config.prefix}??\` for more details`,
|
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
||||||
inline: true,
|
value: `Rolls all configs requested, you may repeat the command multiple times in the same message (just ensure you close each roll with \`${config.postfix}\`), run \`${config.prefix}??\` for more details`,
|
||||||
},
|
inline: true,
|
||||||
],
|
},
|
||||||
}],
|
],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('help.ts:82', message, e));
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('help.ts:82', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,24 +1,29 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor2 } from '../commandUtils.ts';
|
import { infoColor2 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const info = (message: DiscordenoMessage) => {
|
export const info = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('info')).catch((e) => utils.commonLoggers.dbError('info.ts:12', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('info')).catch((e) => utils.commonLoggers.dbError('info.ts:12', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor2,
|
embeds: [
|
||||||
title: `${config.name}, a Discord bot that specializing in rolling dice and calculating math`,
|
{
|
||||||
description: `${config.name} is developed by Ean AKA Burn_E99.
|
color: infoColor2,
|
||||||
|
title: `${config.name}, a Discord bot that specializing in rolling dice and calculating math`,
|
||||||
|
description: `${config.name} is developed by Ean AKA Burn_E99.
|
||||||
Additional information can be found on my website [here](https://discord.burne99.com/TheArtificer/).
|
Additional information can be found on my website [here](https://discord.burne99.com/TheArtificer/).
|
||||||
Want to check out my source code? Check it out [here](https://github.com/Burn-E99/TheArtificer).
|
Want to check out my source code? Check it out [here](https://github.com/Burn-E99/TheArtificer).
|
||||||
Need help with this bot? Join my support server [here](https://discord.gg/peHASXMZYv).`,
|
Need help with this bot? Join my support server [here](https://discord.gg/peHASXMZYv).`,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('info.ts:23', message, e));
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('info.ts:23', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,39 +1,48 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, ignoreList, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries, ignoreList } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { failColor, successColor } from '../commandUtils.ts';
|
import { failColor, successColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const optIn = async (message: DiscordenoMessage) => {
|
export const optIn = async (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optIn.ts:11', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optIn.ts:11', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
const idIdx = ignoreList.indexOf(message.authorId);
|
const idIdx = ignoreList.indexOf(message.authorId);
|
||||||
if (idIdx !== -1) {
|
if (idIdx !== -1) {
|
||||||
try {
|
try {
|
||||||
ignoreList.splice(idIdx, 1);
|
ignoreList.splice(idIdx, 1);
|
||||||
await dbClient.execute('DELETE FROM ignore_list WHERE userid = ?', [message.authorId]);
|
await dbClient.execute('DELETE FROM ignore_list WHERE userid = ?', [message.authorId]);
|
||||||
|
|
||||||
message.reply({
|
message
|
||||||
embeds: [{
|
.reply({
|
||||||
color: successColor,
|
embeds: [
|
||||||
title: `${config.name} will now respond to you again.`,
|
{
|
||||||
description: `If you want ${config.name} to ignore to you again, please run the following command:
|
color: successColor,
|
||||||
|
title: `${config.name} will now respond to you again.`,
|
||||||
|
description: `If you want ${config.name} to ignore to you again, please run the following command:
|
||||||
|
|
||||||
\`${config.prefix}opt-out\``,
|
\`${config.prefix}opt-out\``,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
],
|
||||||
} catch (err) {
|
})
|
||||||
message.reply({
|
.catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
||||||
embeds: [{
|
} catch (err) {
|
||||||
color: failColor,
|
message
|
||||||
title: 'Opt-In failed',
|
.reply({
|
||||||
description: 'Please try the command again. If the issue persists, please join the support server, linked in my About Me section.',
|
embeds: [
|
||||||
}],
|
{
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
color: failColor,
|
||||||
}
|
title: 'Opt-In failed',
|
||||||
}
|
description: 'Please try the command again. If the issue persists, please join the support server, linked in my About Me section.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,36 +1,45 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, ignoreList, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries, ignoreList } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { failColor, successColor } from '../commandUtils.ts';
|
import { failColor, successColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const optOut = async (message: DiscordenoMessage) => {
|
export const optOut = async (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optOut.ts:11', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optOut.ts:11', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ignoreList.push(message.authorId);
|
ignoreList.push(message.authorId);
|
||||||
await dbClient.execute('INSERT INTO ignore_list(userid) values(?)', [message.authorId]);
|
await dbClient.execute('INSERT INTO ignore_list(userid) values(?)', [message.authorId]);
|
||||||
|
|
||||||
message.reply({
|
message
|
||||||
embeds: [{
|
.reply({
|
||||||
color: successColor,
|
embeds: [
|
||||||
title: `${config.name} will no longer respond to you.`,
|
{
|
||||||
description: `If you want ${config.name} to respond to you again, please DM ${config.name} the following command:
|
color: successColor,
|
||||||
|
title: `${config.name} will no longer respond to you.`,
|
||||||
|
description: `If you want ${config.name} to respond to you again, please DM ${config.name} the following command:
|
||||||
|
|
||||||
\`${config.prefix}opt-in\``,
|
\`${config.prefix}opt-in\``,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:25', message, e));
|
],
|
||||||
} catch (err) {
|
})
|
||||||
message.reply({
|
.catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:25', message, e));
|
||||||
embeds: [{
|
} catch (err) {
|
||||||
color: failColor,
|
message
|
||||||
title: 'Opt-Out failed',
|
.reply({
|
||||||
description: `Please try the command again. If the issue persists, please report this using the \`${config.prefix}report opt-out failed\` command.`,
|
embeds: [
|
||||||
}],
|
{
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:33', message, e));
|
color: failColor,
|
||||||
}
|
title: 'Opt-Out failed',
|
||||||
|
description: `Please try the command again. If the issue persists, please report this using the \`${config.prefix}report opt-out failed\` command.`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:33', message, e));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { generatePing } from '../commandUtils.ts';
|
import { generatePing } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const ping = async (message: DiscordenoMessage) => {
|
export const ping = async (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('ping')).catch((e) => utils.commonLoggers.dbError('ping.ts:14', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('ping')).catch((e) => utils.commonLoggers.dbError('ping.ts:14', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
// Calculates ping between sending a message and editing it, giving a nice round-trip latency.
|
// Calculates ping between sending a message and editing it, giving a nice round-trip latency.
|
||||||
try {
|
try {
|
||||||
const m = await message.send(generatePing(-1));
|
const m = await message.send(generatePing(-1));
|
||||||
m.edit(generatePing(m.timestamp - message.timestamp));
|
m.edit(generatePing(m.timestamp - message.timestamp));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
utils.commonLoggers.messageSendError('ping.ts:23', message, e);
|
utils.commonLoggers.messageSendError('ping.ts:23', message, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +1,37 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor1 } from '../commandUtils.ts';
|
import { infoColor1 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const privacy = (message: DiscordenoMessage) => {
|
export const privacy = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('privacy')).catch((e) => utils.commonLoggers.dbError('privacy.ts:15', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('privacy')).catch((e) => utils.commonLoggers.dbError('privacy.ts:15', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor1,
|
embeds: [
|
||||||
title: 'Privacy Policy',
|
{
|
||||||
fields: [{
|
color: infoColor1,
|
||||||
name: 'The Artificer does not track or collect user information via Discord.',
|
title: 'Privacy Policy',
|
||||||
value:
|
fields: [
|
||||||
`The only user submitted information that is stored is submitted via the \`${config.prefix}report\` command. This information is only stored for a short period of time in a location that only the Developer of The Artificer can see.
|
{
|
||||||
|
name: 'The Artificer does not track or collect user information via Discord.',
|
||||||
|
value: `The only user submitted information that is stored is submitted via the \`${config.prefix}report\` command. This information is only stored for a short period of time in a location that only the Developer of The Artificer can see.
|
||||||
|
|
||||||
For more details, please check out the Privacy Policy on the GitHub [here](https://github.com/Burn-E99/TheArtificer/blob/master/PRIVACY.md).
|
For more details, please check out the Privacy Policy on the GitHub [here](https://github.com/Burn-E99/TheArtificer/blob/master/PRIVACY.md).
|
||||||
|
|
||||||
Terms of Service can also be found on GitHub [here](https://github.com/Burn-E99/TheArtificer/blob/master/TERMS.md).
|
Terms of Service can also be found on GitHub [here](https://github.com/Burn-E99/TheArtificer/blob/master/TERMS.md).
|
||||||
|
|
||||||
Want me to ignore you? Simply run \`${config.prefix}opt-out\` and ${config.name} will no longer read your messages or respond to you.`,
|
Want me to ignore you? Simply run \`${config.prefix}opt-out\` and ${config.name} will no longer read your messages or respond to you.`,
|
||||||
}],
|
},
|
||||||
}],
|
],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('privacy.ts:33', message, e));
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('privacy.ts:33', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,34 +1,43 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
sendMessage,
|
sendMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { failColor, generateReport, successColor } from '../commandUtils.ts';
|
import { failColor, generateReport, successColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const report = (message: DiscordenoMessage, args: string[]) => {
|
export const report = (message: DiscordenoMessage, args: string[]) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('report')).catch((e) => utils.commonLoggers.dbError('report.ts:17', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('report')).catch((e) => utils.commonLoggers.dbError('report.ts:17', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
if (args.join(' ')) {
|
if (args.join(' ')) {
|
||||||
sendMessage(config.reportChannel, generateReport(args.join(' '))).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:22', message, e));
|
sendMessage(config.reportChannel, generateReport(args.join(' '))).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:22', message, e));
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: successColor,
|
embeds: [
|
||||||
title: 'Failed command has been reported to my developer.',
|
{
|
||||||
description: `For more in depth support, and information about planned maintenance, please join the support server [here](https://discord.gg/peHASXMZYv).`,
|
color: successColor,
|
||||||
}],
|
title: 'Failed command has been reported to my developer.',
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:29', message, e));
|
description: `For more in depth support, and information about planned maintenance, please join the support server [here](https://discord.gg/peHASXMZYv).`,
|
||||||
} else {
|
},
|
||||||
message.send({
|
],
|
||||||
embeds: [{
|
})
|
||||||
color: failColor,
|
.catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:29', message, e));
|
||||||
title: 'Please provide a short description of what failed',
|
} else {
|
||||||
description: 'Providing a short description helps my developer quickly diagnose what went wrong.',
|
message
|
||||||
}],
|
.send({
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:37', message, e));
|
embeds: [
|
||||||
}
|
{
|
||||||
|
color: failColor,
|
||||||
|
title: 'Please provide a short description of what failed',
|
||||||
|
description: 'Providing a short description helps my developer quickly diagnose what went wrong.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:37', message, e));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor2 } from '../commandUtils.ts';
|
import { infoColor2 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const rip = (message: DiscordenoMessage) => {
|
export const rip = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('rip')).catch((e) => utils.commonLoggers.dbError('rip.ts:14', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('rip')).catch((e) => utils.commonLoggers.dbError('rip.ts:14', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor2,
|
embeds: [
|
||||||
title: 'The Artificer was built in memory of my Grandmother, Babka',
|
{
|
||||||
description: `With much love, Ean
|
color: infoColor2,
|
||||||
|
title: 'The Artificer was built in memory of my Grandmother, Babka',
|
||||||
|
description: `With much love, Ean
|
||||||
|
|
||||||
December 21, 2020`,
|
December 21, 2020`,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('rip.ts:26', message, e));
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('rip.ts:26', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { DEVMODE } from '../../flags.ts';
|
import { DEVMODE } from '../../flags.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { rollingEmbed, warnColor } from '../commandUtils.ts';
|
import { rollingEmbed, warnColor } from '../commandUtils.ts';
|
||||||
import rollFuncs from './roll/_index.ts';
|
import rollFuncs from './roll/_index.ts';
|
||||||
|
@ -15,49 +16,51 @@ import { QueuedRoll } from '../mod.d.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const roll = async (message: DiscordenoMessage, args: string[], command: string) => {
|
export const roll = async (message: DiscordenoMessage, args: string[], command: string) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
const currDateTime = new Date();
|
const currDateTime = new Date();
|
||||||
dbClient.execute(queries.callIncCnt('roll')).catch((e) => utils.commonLoggers.dbError('roll.ts:20', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('roll')).catch((e) => utils.commonLoggers.dbError('roll.ts:20', 'call sproc INC_CNT on', e));
|
||||||
dbClient.execute(queries.callIncHeatmap(currDateTime)).catch((e) => utils.commonLoggers.dbError('roll.ts:21', 'update', e));
|
dbClient.execute(queries.callIncHeatmap(currDateTime)).catch((e) => utils.commonLoggers.dbError('roll.ts:21', 'update', e));
|
||||||
|
|
||||||
// If DEVMODE is on, only allow this command to be used in the devServer
|
// If DEVMODE is on, only allow this command to be used in the devServer
|
||||||
if (DEVMODE && message.guildId !== config.devServer) {
|
if (DEVMODE && message.guildId !== config.devServer) {
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: warnColor,
|
embeds: [
|
||||||
title: 'Command is in development, please try again later.',
|
{
|
||||||
}],
|
color: warnColor,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('roll.ts:30', message, e));
|
title: 'Command is in development, please try again later.',
|
||||||
return;
|
},
|
||||||
}
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('roll.ts:30', message, e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Rest of this command is in a try-catch to protect all sends/edits from erroring out
|
// Rest of this command is in a try-catch to protect all sends/edits from erroring out
|
||||||
try {
|
try {
|
||||||
const originalCommand = `${config.prefix}${command} ${args.join(' ')}`;
|
const originalCommand = `${config.prefix}${command} ${args.join(' ')}`;
|
||||||
|
|
||||||
const m = await message.reply(rollingEmbed);
|
const m = await message.reply(rollingEmbed);
|
||||||
|
|
||||||
// Get modifiers from command
|
// Get modifiers from command
|
||||||
const modifiers = rollFuncs.getModifiers(m, args, command, originalCommand);
|
const modifiers = rollFuncs.getModifiers(m, args, command, originalCommand);
|
||||||
|
|
||||||
// Return early if the modifiers were invalid
|
// Return early if the modifiers were invalid
|
||||||
if (!modifiers.valid) {
|
if (!modifiers.valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in
|
// Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in
|
||||||
const rollCmd = message.content.substring(2);
|
const rollCmd = message.content.substring(2);
|
||||||
|
|
||||||
queueRoll(
|
queueRoll(<QueuedRoll>{
|
||||||
<QueuedRoll> {
|
apiRoll: false,
|
||||||
apiRoll: false,
|
dd: { m, message },
|
||||||
dd: { m, message },
|
rollCmd,
|
||||||
rollCmd,
|
modifiers,
|
||||||
modifiers,
|
originalCommand,
|
||||||
originalCommand,
|
});
|
||||||
},
|
} catch (e) {
|
||||||
);
|
log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`);
|
||||||
} catch (e) {
|
}
|
||||||
log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,117 +1,130 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { DEVMODE } from '../../../flags.ts';
|
import { DEVMODE } from '../../../flags.ts';
|
||||||
import { dbClient, queries } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
|
import { queries } from '../../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { generateRollError } from '../../commandUtils.ts';
|
import { generateRollError } from '../../commandUtils.ts';
|
||||||
import { RollModifiers } from '../../mod.d.ts';
|
import { RollModifiers } from '../../mod.d.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const getModifiers = (m: DiscordenoMessage, args: string[], command: string, originalCommand: string): RollModifiers => {
|
export const getModifiers = (m: DiscordenoMessage, args: string[], command: string, originalCommand: string): RollModifiers => {
|
||||||
const errorType = 'Modifiers invalid:';
|
const errorType = 'Modifiers invalid:';
|
||||||
const modifiers: RollModifiers = {
|
const modifiers: RollModifiers = {
|
||||||
noDetails: false,
|
noDetails: false,
|
||||||
superNoDetails: false,
|
superNoDetails: false,
|
||||||
spoiler: '',
|
spoiler: '',
|
||||||
maxRoll: false,
|
maxRoll: false,
|
||||||
nominalRoll: false,
|
nominalRoll: false,
|
||||||
gmRoll: false,
|
gmRoll: false,
|
||||||
gms: [],
|
gms: [],
|
||||||
order: '',
|
order: '',
|
||||||
valid: false,
|
valid: false,
|
||||||
count: false,
|
count: false,
|
||||||
apiWarn: '',
|
apiWarn: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if any of the args are command flags and pull those out into the modifiers object
|
// Check if any of the args are command flags and pull those out into the modifiers object
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
log(LT.LOG, `Checking ${command}${args.join(' ')} for command modifiers ${i}`);
|
log(LT.LOG, `Checking ${command}${args.join(' ')} for command modifiers ${i}`);
|
||||||
let defaultCase = false;
|
let defaultCase = false;
|
||||||
switch (args[i].toLowerCase()) {
|
switch (args[i].toLowerCase()) {
|
||||||
case '-c':
|
case '-c':
|
||||||
modifiers.count = true;
|
modifiers.count = true;
|
||||||
break;
|
break;
|
||||||
case '-nd':
|
case '-nd':
|
||||||
modifiers.noDetails = true;
|
modifiers.noDetails = true;
|
||||||
break;
|
break;
|
||||||
case '-snd':
|
case '-snd':
|
||||||
modifiers.superNoDetails = true;
|
modifiers.superNoDetails = true;
|
||||||
break;
|
break;
|
||||||
case '-s':
|
case '-s':
|
||||||
modifiers.spoiler = '||';
|
modifiers.spoiler = '||';
|
||||||
break;
|
break;
|
||||||
case '-m':
|
case '-m':
|
||||||
modifiers.maxRoll = true;
|
modifiers.maxRoll = true;
|
||||||
break;
|
break;
|
||||||
case '-n':
|
case '-n':
|
||||||
modifiers.nominalRoll = true;
|
modifiers.nominalRoll = true;
|
||||||
break;
|
break;
|
||||||
case '-gm':
|
case '-gm':
|
||||||
modifiers.gmRoll = true;
|
modifiers.gmRoll = true;
|
||||||
|
|
||||||
// -gm is a little more complex, as we must get all of the GMs that need to be DMd
|
// -gm is a little more complex, as we must get all of the GMs that need to be DMd
|
||||||
while (((i + 1) < args.length) && args[i + 1].startsWith('<@')) {
|
while (i + 1 < args.length && args[i + 1].startsWith('<@')) {
|
||||||
log(LT.LOG, `Finding all GMs, checking args ${JSON.stringify(args)}`);
|
log(LT.LOG, `Finding all GMs, checking args ${JSON.stringify(args)}`);
|
||||||
// Keep looping thru the rest of the args until one does not start with the discord mention code
|
// Keep looping thru the rest of the args until one does not start with the discord mention code
|
||||||
modifiers.gms.push(args[i + 1].replace(/!/g, ''));
|
modifiers.gms.push(args[i + 1].replace(/!/g, ''));
|
||||||
args.splice(i + 1, 1);
|
args.splice(i + 1, 1);
|
||||||
}
|
}
|
||||||
if (modifiers.gms.length < 1) {
|
if (modifiers.gms.length < 1) {
|
||||||
// If -gm is on and none were found, throw an error
|
// If -gm is on and none were found, throw an error
|
||||||
m.edit(generateRollError(errorType, 'Must specifiy at least one GM by @mentioning them')).catch((e) => utils.commonLoggers.messageEditError('getModifiers.ts:66', m, e));
|
m.edit(generateRollError(errorType, 'Must specifiy at least one GM by @mentioning them')).catch((e) =>
|
||||||
|
utils.commonLoggers.messageEditError('getModifiers.ts:66', m, e)
|
||||||
|
);
|
||||||
|
|
||||||
if (DEVMODE && config.logRolls) {
|
if (DEVMODE && config.logRolls) {
|
||||||
// If enabled, log rolls so we can verify the bots math
|
// If enabled, log rolls so we can verify the bots math
|
||||||
dbClient.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'NoGMsFound', m.id]).catch((e) => utils.commonLoggers.dbError('getModifiers.ts:72', 'insert into', e));
|
dbClient
|
||||||
}
|
.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'NoGMsFound', m.id])
|
||||||
return modifiers;
|
.catch((e) => utils.commonLoggers.dbError('getModifiers.ts:72', 'insert into', e));
|
||||||
}
|
}
|
||||||
break;
|
return modifiers;
|
||||||
case '-o':
|
}
|
||||||
// Shift the -o out of the array so the next item is the direction
|
break;
|
||||||
args.splice(i, 1);
|
case '-o':
|
||||||
|
// Shift the -o out of the array so the next item is the direction
|
||||||
|
args.splice(i, 1);
|
||||||
|
|
||||||
if (!args[i] || args[i].toLowerCase()[0] !== 'd' && args[i].toLowerCase()[0] !== 'a') {
|
if (!args[i] || (args[i].toLowerCase()[0] !== 'd' && args[i].toLowerCase()[0] !== 'a')) {
|
||||||
// If -o is on and asc or desc was not specified, error out
|
// If -o is on and asc or desc was not specified, error out
|
||||||
m.edit(generateRollError(errorType, 'Must specifiy `a` or `d` to order the rolls ascending or descending')).catch((e) => utils.commonLoggers.messageEditError('getModifiers.ts:81', m, e));
|
m.edit(generateRollError(errorType, 'Must specifiy `a` or `d` to order the rolls ascending or descending')).catch((e) =>
|
||||||
|
utils.commonLoggers.messageEditError('getModifiers.ts:81', m, e)
|
||||||
|
);
|
||||||
|
|
||||||
if (DEVMODE && config.logRolls) {
|
if (DEVMODE && config.logRolls) {
|
||||||
// If enabled, log rolls so we can verify the bots math
|
// If enabled, log rolls so we can verify the bots math
|
||||||
dbClient.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'NoOrderFound', m.id]).catch((e) => utils.commonLoggers.dbError('getModifiers.ts:89', 'insert into', e));
|
dbClient
|
||||||
}
|
.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'NoOrderFound', m.id])
|
||||||
return modifiers;
|
.catch((e) => utils.commonLoggers.dbError('getModifiers.ts:89', 'insert into', e));
|
||||||
}
|
}
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
modifiers.order = args[i].toLowerCase()[0];
|
modifiers.order = args[i].toLowerCase()[0];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Default case should not mess with the array
|
// Default case should not mess with the array
|
||||||
defaultCase = true;
|
defaultCase = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defaultCase) {
|
if (!defaultCase) {
|
||||||
args.splice(i, 1);
|
args.splice(i, 1);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// maxRoll and nominalRoll cannot both be on, throw an error
|
// maxRoll and nominalRoll cannot both be on, throw an error
|
||||||
if (modifiers.maxRoll && modifiers.nominalRoll) {
|
if (modifiers.maxRoll && modifiers.nominalRoll) {
|
||||||
m.edit(generateRollError(errorType, 'Cannot maximise and nominise the roll at the same time')).catch((e) => utils.commonLoggers.messageEditError('getModifiers.ts:106', m, e));
|
m.edit(generateRollError(errorType, 'Cannot maximise and nominise the roll at the same time')).catch((e) =>
|
||||||
|
utils.commonLoggers.messageEditError('getModifiers.ts:106', m, e)
|
||||||
|
);
|
||||||
|
|
||||||
if (DEVMODE && config.logRolls) {
|
if (DEVMODE && config.logRolls) {
|
||||||
// If enabled, log rolls so we can verify the bots math
|
// If enabled, log rolls so we can verify the bots math
|
||||||
dbClient.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'MaxAndNominal', m.id]).catch((e) => utils.commonLoggers.dbError('getModifiers.ts:120', 'insert into', e));
|
dbClient
|
||||||
}
|
.execute(queries.insertRollLogCmd(0, 1), [originalCommand, 'MaxAndNominal', m.id])
|
||||||
return modifiers;
|
.catch((e) => utils.commonLoggers.dbError('getModifiers.ts:120', 'insert into', e));
|
||||||
}
|
}
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
modifiers.valid = true;
|
modifiers.valid = true;
|
||||||
return modifiers;
|
return modifiers;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,71 +1,75 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor2 } from '../commandUtils.ts';
|
import { infoColor2 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const rollDecorators = (message: DiscordenoMessage) => {
|
export const rollDecorators = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('rollDecorators')).catch((e) => utils.commonLoggers.dbError('rollHelp.ts:15', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('rollDecorators')).catch((e) => utils.commonLoggers.dbError('rollHelp.ts:15', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [
|
.send({
|
||||||
{
|
embeds: [
|
||||||
color: infoColor2,
|
{
|
||||||
title: 'Roll Command Decorators:',
|
color: infoColor2,
|
||||||
description: `This command also has some useful decorators that can used. These decorators simply need to be placed after all rolls in the message.
|
title: 'Roll Command Decorators:',
|
||||||
|
description: `This command also has some useful decorators that can used. These decorators simply need to be placed after all rolls in the message.
|
||||||
|
|
||||||
Examples: \`${config.prefix}d20${config.postfix} -nd\`, \`${config.prefix}d20${config.postfix} -nd -s\`, \`${config.prefix}d20${config.postfix} ${config.prefix}d20${config.postfix} ${config.prefix}d20${config.postfix} -o a\``,
|
Examples: \`${config.prefix}d20${config.postfix} -nd\`, \`${config.prefix}d20${config.postfix} -nd -s\`, \`${config.prefix}d20${config.postfix} ${config.prefix}d20${config.postfix} ${config.prefix}d20${config.postfix} -o a\``,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: '`-nd` - No Details',
|
name: '`-nd` - No Details',
|
||||||
value: 'Suppresses all details of the requested roll',
|
value: 'Suppresses all details of the requested roll',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`-snd` - Super No Details',
|
name: '`-snd` - Super No Details',
|
||||||
value: 'Suppresses all details of the requested roll and hides no details message',
|
value: 'Suppresses all details of the requested roll and hides no details message',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`-s` - Spoiler',
|
name: '`-s` - Spoiler',
|
||||||
value: 'Spoilers all details of the requested roll',
|
value: 'Spoilers all details of the requested roll',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`-m` - Maximize Roll',
|
name: '`-m` - Maximize Roll',
|
||||||
value: 'Rolls the theoretical maximum roll, cannot be used with -n',
|
value: 'Rolls the theoretical maximum roll, cannot be used with -n',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`-n` - Nominal Roll',
|
name: '`-n` - Nominal Roll',
|
||||||
value: 'Rolls the theoretical nominal roll, cannot be used with -m',
|
value: 'Rolls the theoretical nominal roll, cannot be used with -m',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`-gm @user1 @user2 @usern` - GM Roll',
|
name: '`-gm @user1 @user2 @usern` - GM Roll',
|
||||||
value: 'Rolls the requested roll in GM mode, suppressing all publicly shown results and details and sending the results directly to the specified GMs',
|
value:
|
||||||
inline: true,
|
'Rolls the requested roll in GM mode, suppressing all publicly shown results and details and sending the results directly to the specified GMs',
|
||||||
},
|
inline: true,
|
||||||
{
|
},
|
||||||
name: '`-c` - Count Rolls',
|
{
|
||||||
value: 'Shows the Count Embed, containing the count of successful rolls, failed rolls, rerolls, drops, and explosions',
|
name: '`-c` - Count Rolls',
|
||||||
inline: true,
|
value: 'Shows the Count Embed, containing the count of successful rolls, failed rolls, rerolls, drops, and explosions',
|
||||||
},
|
inline: true,
|
||||||
{
|
},
|
||||||
name: '`-o [direction]` - Order Roll',
|
{
|
||||||
value: `Rolls the requested roll and orders the results in the requested direction
|
name: '`-o [direction]` - Order Roll',
|
||||||
|
value: `Rolls the requested roll and orders the results in the requested direction
|
||||||
|
|
||||||
Available directions:
|
Available directions:
|
||||||
\`a\` - Ascending (least to greatest)
|
\`a\` - Ascending (least to greatest)
|
||||||
\`d\` - Descending (greatest to least)`,
|
\`d\` - Descending (greatest to least)`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('rollHelp.ts:247', message, e));
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('rollHelp.ts:247', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,262 +1,275 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor1, infoColor2, successColor } from '../commandUtils.ts';
|
import { infoColor1, infoColor2, successColor } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const rollHelp = (message: DiscordenoMessage) => {
|
export const rollHelp = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('rollhelp')).catch((e) => utils.commonLoggers.dbError('rollHelp.ts:15', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('rollhelp')).catch((e) => utils.commonLoggers.dbError('rollHelp.ts:15', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [
|
.send({
|
||||||
{
|
embeds: [
|
||||||
color: infoColor1,
|
{
|
||||||
title: 'The Artificer\'s Roll Command Details:',
|
color: infoColor1,
|
||||||
description: `You can chain as many of these options as you want, as long as the option does not disallow it.
|
title: "The Artificer's Roll Command Details:",
|
||||||
|
description: `You can chain as many of these options as you want, as long as the option does not disallow it.
|
||||||
|
|
||||||
This command also can fully solve math equations with parenthesis.
|
This command also can fully solve math equations with parenthesis.
|
||||||
|
|
||||||
The Artificer supports most of the [Roll20 formatting](https://artificer.eanm.dev/roll20). More details and examples can be found [here](https://artificer.eanm.dev/roll20).
|
The Artificer supports most of the [Roll20 formatting](https://artificer.eanm.dev/roll20). More details and examples can be found [here](https://artificer.eanm.dev/roll20).
|
||||||
|
|
||||||
Run \`[[???\` or \`[[rollDecorators\` for details on the roll decorators.`,
|
Run \`[[???\` or \`[[rollDecorators\` for details on the roll decorators.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: infoColor2,
|
color: infoColor2,
|
||||||
title: 'Roll20 Dice Options:',
|
title: 'Roll20 Dice Options:',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
||||||
value: `Rolls all configs requested, you may repeat the command multiple times in the same message (just ensure you close each roll with \`${config.postfix}\`)`,
|
value: `Rolls all configs requested, you may repeat the command multiple times in the same message (just ensure you close each roll with \`${config.postfix}\`)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`x` [Optional]',
|
name: '`x` [Optional]',
|
||||||
value: `Number of dice to roll, if omitted, 1 is used
|
value: `Number of dice to roll, if omitted, 1 is used
|
||||||
Additionally, replace \`x\` with \`F\` to roll Fate dice`,
|
Additionally, replace \`x\` with \`F\` to roll Fate dice`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`dy` [Required]',
|
name: '`dy` [Required]',
|
||||||
value: 'Size of dice to roll, `d20` = 20 sided die',
|
value: 'Size of dice to roll, `d20` = 20 sided die',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`dz` or `dlz` [Optional]',
|
name: '`dz` or `dlz` [Optional]',
|
||||||
value: 'Drops the lowest `z` dice, cannot be used with `kz`',
|
value: 'Drops the lowest `z` dice, cannot be used with `kz`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`kz` or `khz` [Optional]',
|
name: '`kz` or `khz` [Optional]',
|
||||||
value: 'Keeps the highest `z` dice, cannot be used with `dz`',
|
value: 'Keeps the highest `z` dice, cannot be used with `dz`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`dhz` [Optional]',
|
name: '`dhz` [Optional]',
|
||||||
value: 'Drops the highest `z` dice, cannot be used with `kz`',
|
value: 'Drops the highest `z` dice, cannot be used with `kz`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`klz` [Optional]',
|
name: '`klz` [Optional]',
|
||||||
value: 'Keeps the lowest `z` dice, cannot be used with `dz`',
|
value: 'Keeps the lowest `z` dice, cannot be used with `dz`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`ra` or `r=q` [Optional]',
|
name: '`ra` or `r=q` [Optional]',
|
||||||
value: 'Rerolls any rolls that match `a`, `r3` will reroll every die that land on 3, throwing out old rolls, cannot be used with `ro`',
|
value: 'Rerolls any rolls that match `a`, `r3` will reroll every die that land on 3, throwing out old rolls, cannot be used with `ro`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`r<q` [Optional]',
|
name: '`r<q` [Optional]',
|
||||||
value: 'Rerolls any rolls that are less than or equal to `a`, `r3` will reroll every die that land on 3, 2, or 1, throwing out old rolls, cannot be used with `ro`',
|
value:
|
||||||
inline: true,
|
'Rerolls any rolls that are less than or equal to `a`, `r3` will reroll every die that land on 3, 2, or 1, throwing out old rolls, cannot be used with `ro`',
|
||||||
},
|
inline: true,
|
||||||
{
|
},
|
||||||
name: '`r>q` [Optional]',
|
{
|
||||||
value: 'Rerolls any rolls that are greater than or equal to `a`, `r3` will reroll every die that land on 3 or greater, throwing out old rolls, cannot be used with `ro`',
|
name: '`r>q` [Optional]',
|
||||||
inline: true,
|
value:
|
||||||
},
|
'Rerolls any rolls that are greater than or equal to `a`, `r3` will reroll every die that land on 3 or greater, throwing out old rolls, cannot be used with `ro`',
|
||||||
{
|
inline: true,
|
||||||
name: '`roa` or `ro=q` [Optional]',
|
},
|
||||||
value: 'Rerolls any rolls that match `a`, `ro3` will reroll each die that lands on 3 ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
{
|
||||||
inline: true,
|
name: '`roa` or `ro=q` [Optional]',
|
||||||
},
|
value:
|
||||||
{
|
'Rerolls any rolls that match `a`, `ro3` will reroll each die that lands on 3 ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
||||||
name: '`ro<q` [Optional]',
|
inline: true,
|
||||||
value: 'Rerolls any rolls that are less than or equal to `a`, `ro3` will reroll each die that lands on 3, 2, or 1 ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
},
|
||||||
inline: true,
|
{
|
||||||
},
|
name: '`ro<q` [Optional]',
|
||||||
{
|
value:
|
||||||
name: '`ro>q` [Optional]',
|
'Rerolls any rolls that are less than or equal to `a`, `ro3` will reroll each die that lands on 3, 2, or 1 ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
||||||
value: 'Rerolls any rolls that are greater than or equal to `a`, `ro3` will reroll each die that lands on 3 or greater ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
inline: true,
|
||||||
inline: true,
|
},
|
||||||
},
|
{
|
||||||
{
|
name: '`ro>q` [Optional]',
|
||||||
name: '`csq` or `cs=q` [Optional]',
|
value:
|
||||||
value: 'Changes crit score to `q`',
|
'Rerolls any rolls that are greater than or equal to `a`, `ro3` will reroll each die that lands on 3 or greater ONLY ONE TIME, throwing out old rolls, cannot be used with `r`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`cs<q` [Optional]',
|
name: '`csq` or `cs=q` [Optional]',
|
||||||
value: 'Changes crit score to be less than or equal to `q`',
|
value: 'Changes crit score to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`cs>q` [Optional]',
|
name: '`cs<q` [Optional]',
|
||||||
value: 'Changes crit score to be greater than or equal to `q`',
|
value: 'Changes crit score to be less than or equal to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`cfq` or `cf=q` [Optional]',
|
name: '`cs>q` [Optional]',
|
||||||
value: 'Changes crit fail to `q`',
|
value: 'Changes crit score to be greater than or equal to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`cf<q` [Optional]',
|
name: '`cfq` or `cf=q` [Optional]',
|
||||||
value: 'Changes crit fail to be less than or equal to `q`',
|
value: 'Changes crit fail to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`cf>q` [Optional]',
|
name: '`cf<q` [Optional]',
|
||||||
value: 'Changes crit fail to be greater than or equal to `q`',
|
value: 'Changes crit fail to be less than or equal to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!` [Optional]',
|
name: '`cf>q` [Optional]',
|
||||||
value: 'Exploding, rolls another `dy` for every crit success',
|
value: 'Changes crit fail to be greater than or equal to `q`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!o` [Optional]',
|
name: '`!` [Optional]',
|
||||||
value: 'Exploding Once, rolls one `dy` for each original crit success',
|
value: 'Exploding, rolls another `dy` for every crit success',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!p` [Optional]',
|
name: '`!o` [Optional]',
|
||||||
value: 'Penetrating Explosion, rolls one `dy` for each crit success, but subtracts one from each resulting explosion',
|
value: 'Exploding Once, rolls one `dy` for each original crit success',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!!` [Optional]',
|
name: '`!p` [Optional]',
|
||||||
value: 'Compounding Explosion, rolls one `dy` for each crit success, but adds the resulting explosion to the die that caused this explosion',
|
value: 'Penetrating Explosion, rolls one `dy` for each crit success, but subtracts one from each resulting explosion',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!=u` [Optional]',
|
name: '`!!` [Optional]',
|
||||||
value: 'Explode on `u`, rolls another `dy` for every die that lands on `u`',
|
value: 'Compounding Explosion, rolls one `dy` for each crit success, but adds the resulting explosion to the die that caused this explosion',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!>u` [Optional]',
|
name: '`!=u` [Optional]',
|
||||||
value: 'Explode on `u` and greater, rolls another `dy` for every die that lands on `u` or greater',
|
value: 'Explode on `u`, rolls another `dy` for every die that lands on `u`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
},
|
name: '`!>u` [Optional]',
|
||||||
{
|
value: 'Explode on `u` and greater, rolls another `dy` for every die that lands on `u` or greater',
|
||||||
color: infoColor2,
|
inline: true,
|
||||||
fields: [
|
},
|
||||||
{
|
],
|
||||||
name: '`!<u` [Optional]',
|
},
|
||||||
value: 'Explode on `u` and under, rolls another `dy` for every die that lands on `u` or less',
|
{
|
||||||
inline: true,
|
color: infoColor2,
|
||||||
},
|
fields: [
|
||||||
{
|
{
|
||||||
name: '`!o=u` [Optional]',
|
name: '`!<u` [Optional]',
|
||||||
value: 'Explodes Once on `u`, rolls another `dy` for each original die that landed on `u`',
|
value: 'Explode on `u` and under, rolls another `dy` for every die that lands on `u` or less',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!o>u` [Optional]',
|
name: '`!o=u` [Optional]',
|
||||||
value: 'Explode Once on `u` and greater, rolls another `dy` for each original die that landed on `u` or greater',
|
value: 'Explodes Once on `u`, rolls another `dy` for each original die that landed on `u`',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!o<u` [Optional]',
|
name: '`!o>u` [Optional]',
|
||||||
value: 'Explode Once on `u` and under, rolls another `dy` for each original die that landed on `u` or less',
|
value: 'Explode Once on `u` and greater, rolls another `dy` for each original die that landed on `u` or greater',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!p=u` [Optional]',
|
name: '`!o<u` [Optional]',
|
||||||
value: 'Penetrating Explosion on `u`, rolls one `dy` for each die that lands on `u`, but subtracts one from each resulting explosion',
|
value: 'Explode Once on `u` and under, rolls another `dy` for each original die that landed on `u` or less',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!p>u` [Optional]',
|
name: '`!p=u` [Optional]',
|
||||||
value: 'Penetrating Explosion on `u` and greater, rolls one `dy` for each die that lands on `u` or greater, but subtracts one from each resulting explosion',
|
value: 'Penetrating Explosion on `u`, rolls one `dy` for each die that lands on `u`, but subtracts one from each resulting explosion',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '`!p<u` [Optional]',
|
name: '`!p>u` [Optional]',
|
||||||
value: 'Penetrating Explosion on `u` and under, rolls one `dy` for each die that lands on `u` or under, but subtracts one from each resulting explosion',
|
value:
|
||||||
inline: true,
|
'Penetrating Explosion on `u` and greater, rolls one `dy` for each die that lands on `u` or greater, but subtracts one from each resulting explosion',
|
||||||
},
|
inline: true,
|
||||||
{
|
},
|
||||||
name: '`!!=u` [Optional]',
|
{
|
||||||
value: 'Compounding Explosion on `u`, rolls one `dy` for each die that lands on `u`, but adds the resulting explosion to the die that caused this explosion',
|
name: '`!p<u` [Optional]',
|
||||||
inline: true,
|
value:
|
||||||
},
|
'Penetrating Explosion on `u` and under, rolls one `dy` for each die that lands on `u` or under, but subtracts one from each resulting explosion',
|
||||||
{
|
inline: true,
|
||||||
name: '`!!>u` [Optional]',
|
},
|
||||||
value: 'Compounding Explosion on `u` and greater, rolls one `dy` for each die that lands on `u` or greater, but adds the resulting explosion to the die that caused this explosion',
|
{
|
||||||
inline: true,
|
name: '`!!=u` [Optional]',
|
||||||
},
|
value:
|
||||||
{
|
'Compounding Explosion on `u`, rolls one `dy` for each die that lands on `u`, but adds the resulting explosion to the die that caused this explosion',
|
||||||
name: '`!!<u` [Optional]',
|
inline: true,
|
||||||
value: 'Compounding Explosion on `u` and under, rolls one `dy` for each die that lands on `u` or under, but adds the resulting explosion to the die that caused this explosion',
|
},
|
||||||
inline: true,
|
{
|
||||||
},
|
name: '`!!>u` [Optional]',
|
||||||
],
|
value:
|
||||||
},
|
'Compounding Explosion on `u` and greater, rolls one `dy` for each die that lands on `u` or greater, but adds the resulting explosion to the die that caused this explosion',
|
||||||
{
|
inline: true,
|
||||||
color: infoColor1,
|
},
|
||||||
title: 'Custom Dice Options',
|
{
|
||||||
fields: [
|
name: '`!!<u` [Optional]',
|
||||||
{
|
value:
|
||||||
name: 'CWOD Rolling',
|
'Compounding Explosion on `u` and under, rolls one `dy` for each die that lands on `u` or under, but adds the resulting explosion to the die that caused this explosion',
|
||||||
value: `\`${config.prefix}xcwody${config.postfix}\`
|
inline: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: infoColor1,
|
||||||
|
title: 'Custom Dice Options',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'CWOD Rolling',
|
||||||
|
value: `\`${config.prefix}xcwody${config.postfix}\`
|
||||||
\`x\` - Number of CWOD dice to roll
|
\`x\` - Number of CWOD dice to roll
|
||||||
\`y\` - Difficulty to roll at`,
|
\`y\` - Difficulty to roll at`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'OVA Rolling',
|
name: 'OVA Rolling',
|
||||||
value: `\`${config.prefix}xovady${config.postfix}\`
|
value: `\`${config.prefix}xovady${config.postfix}\`
|
||||||
\`x\` - Number of OVA dice to roll
|
\`x\` - Number of OVA dice to roll
|
||||||
\`y\` - Size of the die to roll (defaults to 6 if omitted)`,
|
\`y\` - Size of the die to roll (defaults to 6 if omitted)`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: successColor,
|
color: successColor,
|
||||||
title: 'Results Formatting:',
|
title: 'Results Formatting:',
|
||||||
description: 'The results have some formatting applied on them to provide details on what happened during this roll.',
|
description: 'The results have some formatting applied on them to provide details on what happened during this roll.',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Bold',
|
name: 'Bold',
|
||||||
value: 'Critical successes will be **bolded**.',
|
value: 'Critical successes will be **bolded**.',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Underline',
|
name: 'Underline',
|
||||||
value: 'Critical fails will be __underlined__.',
|
value: 'Critical fails will be __underlined__.',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Strikethrough',
|
name: 'Strikethrough',
|
||||||
value: 'Rolls that were dropped or rerolled ~~crossed out~~.',
|
value: 'Rolls that were dropped or rerolled ~~crossed out~~.',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Exclamation mark (`!`)',
|
name: 'Exclamation mark (`!`)',
|
||||||
value: 'Rolls that were caused by an explosion have an exclamation mark (`!`) after them.',
|
value: 'Rolls that were caused by an explosion have an exclamation mark (`!`) after them.',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('rollHelp.ts:247', message, e));
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('rollHelp.ts:247', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,36 +1,49 @@
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
cache,
|
cache,
|
||||||
cacheHandlers,
|
cacheHandlers,
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { generateStats } from '../commandUtils.ts';
|
import { generateStats } from '../commandUtils.ts';
|
||||||
import { compilingStats } from '../commonEmbeds.ts';
|
import { compilingStats } from '../commonEmbeds.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const stats = async (message: DiscordenoMessage) => {
|
export const stats = async (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('stats')).catch((e) => utils.commonLoggers.dbError('stats.ts:14', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('stats')).catch((e) => utils.commonLoggers.dbError('stats.ts:14', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const m = await message.send(compilingStats);
|
const m = await message.send(compilingStats);
|
||||||
|
|
||||||
// Calculate how many times commands have been run
|
// Calculate how many times commands have been run
|
||||||
const rollQuery = await dbClient.query(`SELECT count, hourlyRate FROM command_cnt WHERE command = "roll";`).catch((e) => utils.commonLoggers.dbError('stats.ts:23', 'query', e));
|
const rollQuery = await dbClient
|
||||||
const totalQuery = await dbClient.query(`SELECT SUM(count) as count, SUM(hourlyRate) as hourlyRate FROM command_cnt;`).catch((e) => utils.commonLoggers.dbError('stats.ts:24', 'query', e));
|
.query(`SELECT count, hourlyRate FROM command_cnt WHERE command = "roll";`)
|
||||||
const rolls = BigInt(rollQuery[0].count);
|
.catch((e) => utils.commonLoggers.dbError('stats.ts:23', 'query', e));
|
||||||
const rollRate = parseFloat(rollQuery[0].hourlyRate);
|
const totalQuery = await dbClient
|
||||||
const total = BigInt(totalQuery[0].count);
|
.query(`SELECT SUM(count) as count, SUM(hourlyRate) as hourlyRate FROM command_cnt;`)
|
||||||
const totalRate = parseFloat(totalQuery[0].hourlyRate);
|
.catch((e) => utils.commonLoggers.dbError('stats.ts:24', 'query', e));
|
||||||
|
const rolls = BigInt(rollQuery[0].count);
|
||||||
|
const rollRate = parseFloat(rollQuery[0].hourlyRate);
|
||||||
|
const total = BigInt(totalQuery[0].count);
|
||||||
|
const totalRate = parseFloat(totalQuery[0].hourlyRate);
|
||||||
|
|
||||||
const cachedGuilds = await cacheHandlers.size('guilds');
|
const cachedGuilds = await cacheHandlers.size('guilds');
|
||||||
const cachedChannels = await cacheHandlers.size('channels');
|
const cachedChannels = await cacheHandlers.size('channels');
|
||||||
const cachedMembers = await cacheHandlers.size('members');
|
const cachedMembers = await cacheHandlers.size('members');
|
||||||
m.edit(generateStats(cachedGuilds + cache.dispatchedGuildIds.size, cachedChannels + cache.dispatchedChannelIds.size, cachedMembers, rolls, total - rolls, rollRate, totalRate - rollRate)).catch((
|
m.edit(
|
||||||
e: Error,
|
generateStats(
|
||||||
) => utils.commonLoggers.messageEditError('stats.ts:38', m, e));
|
cachedGuilds + cache.dispatchedGuildIds.size,
|
||||||
} catch (e) {
|
cachedChannels + cache.dispatchedChannelIds.size,
|
||||||
utils.commonLoggers.messageSendError('stats.ts:41', message, e);
|
cachedMembers,
|
||||||
}
|
rolls,
|
||||||
|
total - rolls,
|
||||||
|
rollRate,
|
||||||
|
totalRate - rollRate
|
||||||
|
)
|
||||||
|
).catch((e: Error) => utils.commonLoggers.messageEditError('stats.ts:38', m, e));
|
||||||
|
} catch (e) {
|
||||||
|
utils.commonLoggers.messageSendError('stats.ts:41', message, e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { infoColor1 } from '../commandUtils.ts';
|
import { infoColor1 } from '../commandUtils.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
export const version = (message: DiscordenoMessage) => {
|
export const version = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('version')).catch((e) => utils.commonLoggers.dbError('version.ts:15', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('version')).catch((e) => utils.commonLoggers.dbError('version.ts:15', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message
|
||||||
embeds: [{
|
.send({
|
||||||
color: infoColor1,
|
embeds: [
|
||||||
title: `My current version is ${config.version}`,
|
{
|
||||||
}],
|
color: infoColor1,
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('version.ts:24', message, e));
|
title: `My current version is ${config.version}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((e: Error) => utils.commonLoggers.messageSendError('version.ts:24', message, e));
|
||||||
};
|
};
|
||||||
|
|
30
src/db.ts
30
src/db.ts
|
@ -1,30 +0,0 @@
|
||||||
import config from '../config.ts';
|
|
||||||
import { Client } from '../deps.ts';
|
|
||||||
import { LOCALMODE } from '../flags.ts';
|
|
||||||
|
|
||||||
type UserIdObj = {
|
|
||||||
userid: bigint;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const dbClient = await new Client().connect({
|
|
||||||
hostname: LOCALMODE ? config.db.localhost : config.db.host,
|
|
||||||
port: config.db.port,
|
|
||||||
db: config.db.name,
|
|
||||||
username: config.db.username,
|
|
||||||
password: config.db.password,
|
|
||||||
});
|
|
||||||
|
|
||||||
// List of userIds who have requested that the bot ignore them
|
|
||||||
export const ignoreList: Array<bigint> = [];
|
|
||||||
const dbIgnoreList = await dbClient.query('SELECT * FROM ignore_list');
|
|
||||||
dbIgnoreList.forEach((userIdObj: UserIdObj) => {
|
|
||||||
ignoreList.push(userIdObj.userid);
|
|
||||||
});
|
|
||||||
|
|
||||||
export const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
|
||||||
|
|
||||||
export const queries = {
|
|
||||||
insertRollLogCmd: (api: number, error: number) => `INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,${api},${error})`,
|
|
||||||
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
|
|
||||||
callIncHeatmap: (dateObj: Date) => `CALL INC_HEATMAP("${weekDays[dateObj.getDay()]}", ${dateObj.getHours()});`,
|
|
||||||
};
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import config from '../../config.ts';
|
||||||
|
import { Client } from '../../deps.ts';
|
||||||
|
import { LOCALMODE } from '../../flags.ts';
|
||||||
|
|
||||||
|
const dbClient = await new Client().connect({
|
||||||
|
hostname: LOCALMODE ? config.db.localhost : config.db.host,
|
||||||
|
port: config.db.port,
|
||||||
|
db: config.db.name,
|
||||||
|
username: config.db.username,
|
||||||
|
password: config.db.password,
|
||||||
|
debug: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default dbClient;
|
|
@ -0,0 +1,20 @@
|
||||||
|
import dbClient from './client.ts';
|
||||||
|
|
||||||
|
type UserIdObj = {
|
||||||
|
userid: bigint;
|
||||||
|
};
|
||||||
|
|
||||||
|
// List of userIds who have requested that the bot ignore them
|
||||||
|
export const ignoreList: Array<bigint> = [];
|
||||||
|
const dbIgnoreList = await dbClient.query('SELECT * FROM ignore_list');
|
||||||
|
dbIgnoreList.forEach((userIdObj: UserIdObj) => {
|
||||||
|
ignoreList.push(userIdObj.userid);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
||||||
|
|
||||||
|
export const queries = {
|
||||||
|
insertRollLogCmd: (api: number, error: number) => `INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,${api},${error})`,
|
||||||
|
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
|
||||||
|
callIncHeatmap: (dateObj: Date) => `CALL INC_HEATMAP("${weekDays[dateObj.getDay()]}", ${dateObj.getHours()});`,
|
||||||
|
};
|
|
@ -1,83 +1,89 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// nanoid deps
|
// nanoid deps
|
||||||
nanoid,
|
nanoid,
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
sendMessage,
|
sendMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { generateApiDeleteEmail } from '../../commandUtils.ts';
|
import { generateApiDeleteEmail } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
|
|
||||||
export const apiKeyDelete = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, apiUserEmail: string, apiUserDelCode: string) => {
|
export const apiKeyDelete = async (
|
||||||
if (query.has('user') && ((query.get('user') || '').length > 0) && query.has('email') && ((query.get('email') || '').length > 0)) {
|
requestEvent: Deno.RequestEvent,
|
||||||
if (apiUserid === BigInt(query.get('user') || '0') && apiUserEmail === query.get('email')) {
|
query: Map<string, string>,
|
||||||
if (query.has('code') && ((query.get('code') || '').length > 0)) {
|
apiUserid: BigInt,
|
||||||
if ((query.get('code') || '') === apiUserDelCode) {
|
apiUserEmail: string,
|
||||||
// User has recieved their delete code and we need to delete the account now
|
apiUserDelCode: string
|
||||||
let erroredOut = false;
|
) => {
|
||||||
|
if (query.has('user') && (query.get('user') || '').length > 0 && query.has('email') && (query.get('email') || '').length > 0) {
|
||||||
|
if (apiUserid === BigInt(query.get('user') || '0') && apiUserEmail === query.get('email')) {
|
||||||
|
if (query.has('code') && (query.get('code') || '').length > 0) {
|
||||||
|
if ((query.get('code') || '') === apiUserDelCode) {
|
||||||
|
// User has recieved their delete code and we need to delete the account now
|
||||||
|
let erroredOut = false;
|
||||||
|
|
||||||
await dbClient.execute('DELETE FROM allowed_channels WHERE userid = ?', [apiUserid]).catch((e) => {
|
await dbClient.execute('DELETE FROM allowed_channels WHERE userid = ?', [apiUserid]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiKeyDelete.ts:25', 'insert into', e);
|
utils.commonLoggers.dbError('apiKeyDelete.ts:25', 'insert into', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Channel Clean Failed.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Channel Clean Failed.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbClient.execute('DELETE FROM all_keys WHERE userid = ?', [apiUserid]).catch((e) => {
|
await dbClient.execute('DELETE FROM all_keys WHERE userid = ?', [apiUserid]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiKeyDelete.ts:34', 'delete from', e);
|
utils.commonLoggers.dbError('apiKeyDelete.ts:34', 'delete from', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Delete Key Failed.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Delete Key Failed.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send OK as response to indicate key deletion was successful
|
// Send OK as response to indicate key deletion was successful
|
||||||
requestEvent.respondWith(stdResp.OK('You have been removed from the DB, Goodbye.'));
|
requestEvent.respondWith(stdResp.OK('You have been removed from the DB, Goodbye.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('Invalid Delete Code.'));
|
requestEvent.respondWith(stdResp.Forbidden('Invalid Delete Code.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// User does not have their delete code yet, so we need to generate one and email it to them
|
// User does not have their delete code yet, so we need to generate one and email it to them
|
||||||
const deleteCode = await nanoid(10);
|
const deleteCode = await nanoid(10);
|
||||||
|
|
||||||
let erroredOut = false;
|
let erroredOut = false;
|
||||||
|
|
||||||
// Execute the DB modification
|
// Execute the DB modification
|
||||||
await dbClient.execute('UPDATE all_keys SET deleteCode = ? WHERE userid = ?', [deleteCode, apiUserid]).catch((e) => {
|
await dbClient.execute('UPDATE all_keys SET deleteCode = ? WHERE userid = ?', [deleteCode, apiUserid]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiKeyDelete.ts:57', 'update', e);
|
utils.commonLoggers.dbError('apiKeyDelete.ts:57', 'update', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Delete Code Failed'));
|
requestEvent.respondWith(stdResp.InternalServerError('Delete Code Failed'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Send" the email
|
// "Send" the email
|
||||||
await sendMessage(config.api.email, generateApiDeleteEmail(apiUserEmail, deleteCode)).catch(() => {
|
await sendMessage(config.api.email, generateApiDeleteEmail(apiUserEmail, deleteCode)).catch(() => {
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to send email.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to send email.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send API key as response
|
// Send API key as response
|
||||||
requestEvent.respondWith(stdResp.FailedDependency('Please look for an email containing a Delete Key and run this query again with said key.'));
|
requestEvent.respondWith(stdResp.FailedDependency('Please look for an email containing a Delete Key and run this query again with said key.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('You can only delete your own key.'));
|
requestEvent.respondWith(stdResp.Forbidden('You can only delete your own key.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiChannel = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
export const apiChannel = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
||||||
if (query.has('user') && ((query.get('user') || '').length > 0)) {
|
if (query.has('user') && (query.get('user') || '').length > 0) {
|
||||||
if (apiUserid === BigInt(query.get('user') || '0')) {
|
if (apiUserid === BigInt(query.get('user') || '0')) {
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let erroredOut = false;
|
let erroredOut = false;
|
||||||
|
|
||||||
// Get all channels userid has authorized
|
// Get all channels userid has authorized
|
||||||
const dbAllowedChannelQuery = await dbClient.query('SELECT * FROM allowed_channels WHERE userid = ?', [apiUserid]).catch((e) => {
|
const dbAllowedChannelQuery = await dbClient.query('SELECT * FROM allowed_channels WHERE userid = ?', [apiUserid]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiChannel.ts', 'query', e);
|
utils.commonLoggers.dbError('apiChannel.ts', 'query', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to get channels.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to get channels.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Customized strinification to handle BigInts correctly
|
// Customized strinification to handle BigInts correctly
|
||||||
const returnChannels = JSON.stringify(dbAllowedChannelQuery, (_key, value) => (typeof value === 'bigint' ? value.toString() : value));
|
const returnChannels = JSON.stringify(dbAllowedChannelQuery, (_key, value) => (typeof value === 'bigint' ? value.toString() : value));
|
||||||
// Send channel list as response
|
// Send channel list as response
|
||||||
requestEvent.respondWith(stdResp.OK(returnChannels));
|
requestEvent.respondWith(stdResp.OK(returnChannels));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('You can only view your own channels.'));
|
requestEvent.respondWith(stdResp.Forbidden('You can only view your own channels.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// nanoid deps
|
// nanoid deps
|
||||||
nanoid,
|
nanoid,
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
sendMessage,
|
sendMessage,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { generateApiKeyEmail } from '../../commandUtils.ts';
|
import { generateApiKeyEmail } from '../../commandUtils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
|
|
||||||
export const apiKey = async (requestEvent: Deno.RequestEvent, query: Map<string, string>) => {
|
export const apiKey = async (requestEvent: Deno.RequestEvent, query: Map<string, string>) => {
|
||||||
if ((query.has('user') && ((query.get('user') || '').length > 0)) && (query.has('email') && ((query.get('email') || '').length > 0))) {
|
if (query.has('user') && (query.get('user') || '').length > 0 && query.has('email') && (query.get('email') || '').length > 0) {
|
||||||
// Generate new secure key
|
// Generate new secure key
|
||||||
const newKey = await nanoid(25);
|
const newKey = await nanoid(25);
|
||||||
|
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let erroredOut = false;
|
let erroredOut = false;
|
||||||
|
|
||||||
// Insert new key/user pair into the db
|
// Insert new key/user pair into the db
|
||||||
await dbClient.execute('INSERT INTO all_keys(userid,apiKey,email) values(?,?,?)', [BigInt(query.get('user') || '0'), newKey, (query.get('email') || '').toLowerCase()]).catch(
|
await dbClient
|
||||||
(e) => {
|
.execute('INSERT INTO all_keys(userid,apiKey,email) values(?,?,?)', [BigInt(query.get('user') || '0'), newKey, (query.get('email') || '').toLowerCase()])
|
||||||
utils.commonLoggers.dbError('apiKey.ts:27', 'insert into', e);
|
.catch((e) => {
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to store key.'));
|
utils.commonLoggers.dbError('apiKey.ts:27', 'insert into', e);
|
||||||
erroredOut = true;
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to store key.'));
|
||||||
},
|
erroredOut = true;
|
||||||
);
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Send" the email
|
// "Send" the email
|
||||||
await sendMessage(config.api.email, generateApiKeyEmail(query.get('email') || 'no email', newKey)).catch(() => {
|
await sendMessage(config.api.email, generateApiKeyEmail(query.get('email') || 'no email', newKey)).catch(() => {
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to send email.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to send email.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send basic OK to indicate key has been sent
|
// Send basic OK to indicate key has been sent
|
||||||
requestEvent.respondWith(stdResp.OK('Email Sent.'));
|
requestEvent.respondWith(stdResp.OK('Email Sent.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// nanoid deps
|
// nanoid deps
|
||||||
nanoid,
|
nanoid,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiKeyAdmin = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
export const apiKeyAdmin = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
||||||
if ((query.has('user') && ((query.get('user') || '').length > 0)) && (query.has('a') && ((query.get('a') || '').length > 0))) {
|
if (query.has('user') && (query.get('user') || '').length > 0 && query.has('a') && (query.get('a') || '').length > 0) {
|
||||||
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
||||||
// Generate new secure key
|
// Generate new secure key
|
||||||
const newKey = await nanoid(25);
|
const newKey = await nanoid(25);
|
||||||
|
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let erroredOut = false;
|
let erroredOut = false;
|
||||||
|
|
||||||
// Insert new key/user pair into the db
|
// Insert new key/user pair into the db
|
||||||
await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [apiUserid, newKey]).catch((e) => {
|
await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [apiUserid, newKey]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiKeyAdmin.ts:24', 'insert into', e);
|
utils.commonLoggers.dbError('apiKeyAdmin.ts:24', 'insert into', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to store key.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to store key.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send API key as response
|
// Send API key as response
|
||||||
requestEvent.respondWith(stdResp.OK(JSON.stringify({ 'key': newKey, 'userid': query.get('user') })));
|
requestEvent.respondWith(stdResp.OK(JSON.stringify({ key: newKey, userid: query.get('user') })));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Only allow the db admin to use this API
|
// Only allow the db admin to use this API
|
||||||
requestEvent.respondWith(stdResp.Forbidden(stdResp.Strings.restricted));
|
requestEvent.respondWith(stdResp.Forbidden(stdResp.Strings.restricted));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient, queries } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
cache,
|
cache,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
import { QueuedRoll, RollModifiers } from '../../mod.d.ts';
|
import { QueuedRoll, RollModifiers } from '../../mod.d.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
@ -15,107 +15,116 @@ import stdResp from '../stdResponses.ts';
|
||||||
const apiWarning = `The following roll was conducted using my built in API. If someone in this channel did not request this roll, please report API abuse here: <${config.api.supportURL}>`;
|
const apiWarning = `The following roll was conducted using my built in API. If someone in this channel did not request this roll, please report API abuse here: <${config.api.supportURL}>`;
|
||||||
|
|
||||||
export const apiRoll = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
export const apiRoll = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
||||||
// Make sure query contains all the needed parts
|
// Make sure query contains all the needed parts
|
||||||
if (
|
if (
|
||||||
(query.has('rollstr') && ((query.get('rollstr') || '').length > 0)) && (query.has('channel') && ((query.get('channel') || '').length > 0)) &&
|
query.has('rollstr') &&
|
||||||
(query.has('user') && ((query.get('user') || '').length > 0))
|
(query.get('rollstr') || '').length > 0 &&
|
||||||
) {
|
query.has('channel') &&
|
||||||
if (query.has('n') && query.has('m')) {
|
(query.get('channel') || '').length > 0 &&
|
||||||
// Alert API user that they shouldn't be doing this
|
query.has('user') &&
|
||||||
requestEvent.respondWith(stdResp.BadRequest('Cannot have both \'n\' and \'m\'.'));
|
(query.get('user') || '').length > 0
|
||||||
return;
|
) {
|
||||||
}
|
if (query.has('n') && query.has('m')) {
|
||||||
|
// Alert API user that they shouldn't be doing this
|
||||||
|
requestEvent.respondWith(stdResp.BadRequest("Cannot have both 'n' and 'm'."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if user is authenticated to use this endpoint
|
// Check if user is authenticated to use this endpoint
|
||||||
let authorized = false;
|
let authorized = false;
|
||||||
let hideWarn = false;
|
let hideWarn = false;
|
||||||
|
|
||||||
// Check if the db has the requested userid/channelid combo, and that the requested userid matches the userid linked with the api key
|
// Check if the db has the requested userid/channelid combo, and that the requested userid matches the userid linked with the api key
|
||||||
const dbChannelQuery = await dbClient.query('SELECT active, banned FROM allowed_channels WHERE userid = ? AND channelid = ?', [apiUserid, BigInt(query.get('channel') || '0')]);
|
const dbChannelQuery = await dbClient.query('SELECT active, banned FROM allowed_channels WHERE userid = ? AND channelid = ?', [
|
||||||
if (dbChannelQuery.length === 1 && (apiUserid === BigInt(query.get('user') || '0')) && dbChannelQuery[0].active && !dbChannelQuery[0].banned) {
|
apiUserid,
|
||||||
// Get the guild from the channel and make sure user is in said guild
|
BigInt(query.get('channel') || '0'),
|
||||||
const guild = cache.channels.get(BigInt(query.get('channel') || ''))?.guild;
|
]);
|
||||||
if (guild && guild.members.get(BigInt(query.get('user') || ''))?.id) {
|
if (dbChannelQuery.length === 1 && apiUserid === BigInt(query.get('user') || '0') && dbChannelQuery[0].active && !dbChannelQuery[0].banned) {
|
||||||
const dbGuildQuery = await dbClient.query('SELECT active, banned, hidewarn FROM allowed_guilds WHERE guildid = ? AND channelid = ?', [
|
// Get the guild from the channel and make sure user is in said guild
|
||||||
guild.id,
|
const guild = cache.channels.get(BigInt(query.get('channel') || ''))?.guild;
|
||||||
BigInt(query.get('channel') || '0'),
|
if (guild && guild.members.get(BigInt(query.get('user') || ''))?.id) {
|
||||||
]);
|
const dbGuildQuery = await dbClient.query('SELECT active, banned, hidewarn FROM allowed_guilds WHERE guildid = ? AND channelid = ?', [
|
||||||
|
guild.id,
|
||||||
|
BigInt(query.get('channel') || '0'),
|
||||||
|
]);
|
||||||
|
|
||||||
// Make sure guild allows API rolls
|
// Make sure guild allows API rolls
|
||||||
if (dbGuildQuery.length === 1 && dbGuildQuery[0].active && !dbGuildQuery[0].banned) {
|
if (dbGuildQuery.length === 1 && dbGuildQuery[0].active && !dbGuildQuery[0].banned) {
|
||||||
authorized = true;
|
authorized = true;
|
||||||
hideWarn = dbGuildQuery[0].hidewarn;
|
hideWarn = dbGuildQuery[0].hidewarn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authorized) {
|
if (authorized) {
|
||||||
// Rest of this command is in a try-catch to protect all sends/edits from erroring out
|
// Rest of this command is in a try-catch to protect all sends/edits from erroring out
|
||||||
try {
|
try {
|
||||||
// Make sure rollCmd is not undefined
|
// Make sure rollCmd is not undefined
|
||||||
let rollCmd = query.get('rollstr') || '';
|
let rollCmd = query.get('rollstr') || '';
|
||||||
const originalCommand = query.get('rollstr');
|
const originalCommand = query.get('rollstr');
|
||||||
|
|
||||||
if (rollCmd.length === 0) {
|
if (rollCmd.length === 0) {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest('rollCmd is required.'));
|
requestEvent.respondWith(stdResp.BadRequest('rollCmd is required.'));
|
||||||
|
|
||||||
// Always log API rolls for abuse detection
|
// Always log API rolls for abuse detection
|
||||||
dbClient.execute(queries.insertRollLogCmd(1, 1), [originalCommand, 'EmptyInput', null]).catch((e) => utils.commonLoggers.dbError('apiRoll.ts:65', 'insert', e));
|
dbClient
|
||||||
return;
|
.execute(queries.insertRollLogCmd(1, 1), [originalCommand, 'EmptyInput', null])
|
||||||
}
|
.catch((e) => utils.commonLoggers.dbError('apiRoll.ts:65', 'insert', e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (query.has('o') && (query.get('o')?.toLowerCase() !== 'd' && query.get('o')?.toLowerCase() !== 'a')) {
|
if (query.has('o') && query.get('o')?.toLowerCase() !== 'd' && query.get('o')?.toLowerCase() !== 'a') {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest('Order must be set to \'a\' or \'d\'.'));
|
requestEvent.respondWith(stdResp.BadRequest("Order must be set to 'a' or 'd'."));
|
||||||
|
|
||||||
// Always log API rolls for abuse detection
|
// Always log API rolls for abuse detection
|
||||||
dbClient.execute(queries.insertRollLogCmd(1, 1), [originalCommand, 'BadOrder', null]).catch((e) => utils.commonLoggers.dbError('apiRoll.ts:66', 'insert', e));
|
dbClient
|
||||||
return;
|
.execute(queries.insertRollLogCmd(1, 1), [originalCommand, 'BadOrder', null])
|
||||||
}
|
.catch((e) => utils.commonLoggers.dbError('apiRoll.ts:66', 'insert', e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clip off the leading prefix. API calls must be formatted with a prefix at the start to match how commands are sent in Discord
|
// Clip off the leading prefix. API calls must be formatted with a prefix at the start to match how commands are sent in Discord
|
||||||
rollCmd = rollCmd.substring(rollCmd.indexOf(config.prefix) + 2).replace(/%20/g, ' ');
|
rollCmd = rollCmd.substring(rollCmd.indexOf(config.prefix) + 2).replace(/%20/g, ' ');
|
||||||
|
|
||||||
const modifiers: RollModifiers = {
|
const modifiers: RollModifiers = {
|
||||||
noDetails: query.has('nd'),
|
noDetails: query.has('nd'),
|
||||||
superNoDetails: query.has('snd'),
|
superNoDetails: query.has('snd'),
|
||||||
spoiler: query.has('s') ? '||' : '',
|
spoiler: query.has('s') ? '||' : '',
|
||||||
maxRoll: query.has('m'),
|
maxRoll: query.has('m'),
|
||||||
nominalRoll: query.has('n'),
|
nominalRoll: query.has('n'),
|
||||||
gmRoll: query.has('gms'),
|
gmRoll: query.has('gms'),
|
||||||
gms: query.has('gms') ? (query.get('gms') || '').split(',') : [],
|
gms: query.has('gms') ? (query.get('gms') || '').split(',') : [],
|
||||||
order: query.has('o') ? (query.get('o')?.toLowerCase() || '') : '',
|
order: query.has('o') ? query.get('o')?.toLowerCase() || '' : '',
|
||||||
count: query.has('c'),
|
count: query.has('c'),
|
||||||
valid: true,
|
valid: true,
|
||||||
apiWarn: hideWarn ? '' : apiWarning,
|
apiWarn: hideWarn ? '' : apiWarning,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse the roll and get the return text
|
// Parse the roll and get the return text
|
||||||
await queueRoll(
|
await queueRoll(<QueuedRoll>{
|
||||||
<QueuedRoll> {
|
apiRoll: true,
|
||||||
apiRoll: true,
|
api: { requestEvent, channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
|
||||||
api: { requestEvent, channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
|
rollCmd,
|
||||||
rollCmd,
|
modifiers,
|
||||||
modifiers,
|
originalCommand,
|
||||||
originalCommand,
|
});
|
||||||
},
|
} catch (err) {
|
||||||
);
|
// Handle any errors we missed
|
||||||
} catch (err) {
|
log(LT.ERROR, `Unhandled Error: ${JSON.stringify(err)}`);
|
||||||
// Handle any errors we missed
|
requestEvent.respondWith(stdResp.InternalServerError('Something went wrong.'));
|
||||||
log(LT.ERROR, `Unhandled Error: ${JSON.stringify(err)}`);
|
}
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Something went wrong.'));
|
} else {
|
||||||
}
|
// Alert API user that they messed up
|
||||||
} else {
|
requestEvent.respondWith(
|
||||||
// Alert API user that they messed up
|
stdResp.Forbidden(
|
||||||
requestEvent.respondWith(
|
`Verify you are a member of the guild you are sending this roll to. If you are, the ${config.name} may not have that registered, please send a message in the guild so ${config.name} can register this. This registration is temporary, so if you see this error again, just poke your server again.`
|
||||||
stdResp.Forbidden(
|
)
|
||||||
`Verify you are a member of the guild you are sending this roll to. If you are, the ${config.name} may not have that registered, please send a message in the guild so ${config.name} can register this. This registration is temporary, so if you see this error again, just poke your server again.`,
|
);
|
||||||
),
|
}
|
||||||
);
|
} else {
|
||||||
}
|
// Alert API user that they shouldn't be doing this
|
||||||
} else {
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
// Alert API user that they shouldn't be doing this
|
}
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import {
|
import {
|
||||||
// httpd deps
|
// httpd deps
|
||||||
Status,
|
STATUS_CODE,
|
||||||
STATUS_TEXT,
|
STATUS_TEXT,
|
||||||
} from '../../../deps.ts';
|
} from '../../../deps.ts';
|
||||||
|
|
||||||
export const heatmapPng = async (requestEvent: Deno.RequestEvent) => {
|
export const heatmapPng = async (requestEvent: Deno.RequestEvent) => {
|
||||||
const file = Deno.readFileSync('./src/endpoints/gets/heatmap.png');
|
const file = Deno.readFileSync('./src/endpoints/gets/heatmap.png');
|
||||||
const imageHeaders = new Headers();
|
const imageHeaders = new Headers();
|
||||||
imageHeaders.append('Content-Type', 'image/png');
|
imageHeaders.append('Content-Type', 'image/png');
|
||||||
// Send basic OK to indicate key has been sent
|
// Send basic OK to indicate key has been sent
|
||||||
requestEvent.respondWith(
|
requestEvent.respondWith(
|
||||||
new Response(file, {
|
new Response(file, {
|
||||||
status: Status.OK,
|
status: STATUS_CODE.OK,
|
||||||
statusText: STATUS_TEXT[Status.OK],
|
statusText: STATUS_TEXT[STATUS_CODE.OK],
|
||||||
headers: imageHeaders,
|
headers: imageHeaders,
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiChannelAdd = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
export const apiChannelAdd = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt) => {
|
||||||
if ((query.has('user') && ((query.get('user') || '').length > 0)) && (query.has('channel') && ((query.get('channel') || '').length > 0))) {
|
if (query.has('user') && (query.get('user') || '').length > 0 && query.has('channel') && (query.get('channel') || '').length > 0) {
|
||||||
if (apiUserid === BigInt(query.get('user') || '0')) {
|
if (apiUserid === BigInt(query.get('user') || '0')) {
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let erroredOut = false;
|
let erroredOut = false;
|
||||||
|
|
||||||
// Insert new user/channel pair into the db
|
// Insert new user/channel pair into the db
|
||||||
await dbClient.execute('INSERT INTO allowed_channels(userid,channelid) values(?,?)', [apiUserid, BigInt(query.get('channel') || '0')]).catch((e) => {
|
await dbClient.execute('INSERT INTO allowed_channels(userid,channelid) values(?,?)', [apiUserid, BigInt(query.get('channel') || '0')]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiChannelAdd.ts:17', 'insert into', e);
|
utils.commonLoggers.dbError('apiChannelAdd.ts:17', 'insert into', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to store channel.'));
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to store channel.'));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send OK to indicate modification was successful
|
// Send OK to indicate modification was successful
|
||||||
requestEvent.respondWith(stdResp.OK('Successfully added channel.'));
|
requestEvent.respondWith(stdResp.OK('Successfully added channel.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('You can only add channels to your key.'));
|
requestEvent.respondWith(stdResp.Forbidden('You can only add channels to your key.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,41 +1,44 @@
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiChannelManageActive = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
export const apiChannelManageActive = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
||||||
if ((query.has('channel') && ((query.get('channel') || '').length > 0)) && (query.has('user') && ((query.get('user') || '').length > 0))) {
|
if (query.has('channel') && (query.get('channel') || '').length > 0 && query.has('user') && (query.get('user') || '').length > 0) {
|
||||||
if (apiUserid === BigInt(query.get('user') || '0')) {
|
if (apiUserid === BigInt(query.get('user') || '0')) {
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let value, erroredOut = false;
|
let value,
|
||||||
|
erroredOut = false;
|
||||||
|
|
||||||
// Determine value to set
|
// Determine value to set
|
||||||
if (path.toLowerCase().indexOf('de') > 0) {
|
if (path.toLowerCase().indexOf('de') > 0) {
|
||||||
value = 0;
|
value = 0;
|
||||||
} else {
|
} else {
|
||||||
value = 1;
|
value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the requested entry
|
// Update the requested entry
|
||||||
await dbClient.execute('UPDATE allowed_channels SET active = ? WHERE userid = ? AND channelid = ?', [value, apiUserid, BigInt(query.get('channel') || '0')]).catch((e) => {
|
await dbClient
|
||||||
utils.commonLoggers.dbError('apiChannelManageActive.ts:25', 'update', e);
|
.execute('UPDATE allowed_channels SET active = ? WHERE userid = ? AND channelid = ?', [value, apiUserid, BigInt(query.get('channel') || '0')])
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to update channel.'));
|
.catch((e) => {
|
||||||
erroredOut = true;
|
utils.commonLoggers.dbError('apiChannelManageActive.ts:25', 'update', e);
|
||||||
});
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to update channel.'));
|
||||||
|
erroredOut = true;
|
||||||
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send API key as response
|
// Send API key as response
|
||||||
requestEvent.respondWith(stdResp.OK(`Successfully active to ${value}.`));
|
requestEvent.respondWith(stdResp.OK(`Successfully active to ${value}.`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('You can only manage your own channels.'));
|
requestEvent.respondWith(stdResp.Forbidden('You can only manage your own channels.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +1,52 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiChannelManageBan = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
export const apiChannelManageBan = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
||||||
if (
|
if (
|
||||||
(query.has('a') && ((query.get('a') || '').length > 0)) && (query.has('channel') && ((query.get('channel') || '').length > 0)) &&
|
query.has('a') &&
|
||||||
(query.has('user') && ((query.get('user') || '').length > 0))
|
(query.get('a') || '').length > 0 &&
|
||||||
) {
|
query.has('channel') &&
|
||||||
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
(query.get('channel') || '').length > 0 &&
|
||||||
// Flag to see if there is an error inside the catch
|
query.has('user') &&
|
||||||
let value, erroredOut = false;
|
(query.get('user') || '').length > 0
|
||||||
|
) {
|
||||||
|
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
||||||
|
// Flag to see if there is an error inside the catch
|
||||||
|
let value,
|
||||||
|
erroredOut = false;
|
||||||
|
|
||||||
// Determine value to set
|
// Determine value to set
|
||||||
if (path.toLowerCase().indexOf('un') > 0) {
|
if (path.toLowerCase().indexOf('un') > 0) {
|
||||||
value = 0;
|
value = 0;
|
||||||
} else {
|
} else {
|
||||||
value = 1;
|
value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the DB modification
|
// Execute the DB modification
|
||||||
await dbClient.execute('UPDATE allowed_channels SET banned = ? WHERE userid = ? AND channelid = ?', [value, apiUserid, BigInt(query.get('channel') || '0')]).catch((e) => {
|
await dbClient
|
||||||
utils.commonLoggers.dbError('apiChannelManageBan.ts:28', 'update', e);
|
.execute('UPDATE allowed_channels SET banned = ? WHERE userid = ? AND channelid = ?', [value, apiUserid, BigInt(query.get('channel') || '0')])
|
||||||
requestEvent.respondWith(stdResp.InternalServerError('Failed to update channel.'));
|
.catch((e) => {
|
||||||
erroredOut = true;
|
utils.commonLoggers.dbError('apiChannelManageBan.ts:28', 'update', e);
|
||||||
});
|
requestEvent.respondWith(stdResp.InternalServerError('Failed to update channel.'));
|
||||||
|
erroredOut = true;
|
||||||
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send OK to indicate modification was successful
|
// Send OK to indicate modification was successful
|
||||||
requestEvent.respondWith(stdResp.OK(`Successfully active to ${value}.`));
|
requestEvent.respondWith(stdResp.OK(`Successfully active to ${value}.`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden(stdResp.Strings.restricted));
|
requestEvent.respondWith(stdResp.Forbidden(stdResp.Strings.restricted));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import { dbClient } from '../../db.ts';
|
import dbClient from '../../db/client.ts';
|
||||||
import stdResp from '../stdResponses.ts';
|
import stdResp from '../stdResponses.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
export const apiKeyManage = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
export const apiKeyManage = async (requestEvent: Deno.RequestEvent, query: Map<string, string>, apiUserid: BigInt, path: string) => {
|
||||||
if ((query.has('a') && ((query.get('a') || '').length > 0)) && (query.has('user') && ((query.get('user') || '').length > 0))) {
|
if (query.has('a') && (query.get('a') || '').length > 0 && query.has('user') && (query.get('user') || '').length > 0) {
|
||||||
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
if (apiUserid === config.api.admin && apiUserid === BigInt(query.get('a') || '0')) {
|
||||||
// Flag to see if there is an error inside the catch
|
// Flag to see if there is an error inside the catch
|
||||||
let key: string,
|
let key: string,
|
||||||
value: number,
|
value: number,
|
||||||
erroredOut = false;
|
erroredOut = false;
|
||||||
|
|
||||||
// Determine key to edit
|
// Determine key to edit
|
||||||
if (path.toLowerCase().indexOf('ban') > 0) {
|
if (path.toLowerCase().indexOf('ban') > 0) {
|
||||||
key = 'banned';
|
key = 'banned';
|
||||||
} else {
|
} else {
|
||||||
key = 'active';
|
key = 'active';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine value to set
|
// Determine value to set
|
||||||
if (path.toLowerCase().indexOf('de') > 0 || path.toLowerCase().indexOf('un') > 0) {
|
if (path.toLowerCase().indexOf('de') > 0 || path.toLowerCase().indexOf('un') > 0) {
|
||||||
value = 0;
|
value = 0;
|
||||||
} else {
|
} else {
|
||||||
value = 1;
|
value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the DB modification
|
// Execute the DB modification
|
||||||
await dbClient.execute('UPDATE all_keys SET ?? = ? WHERE userid = ?', [key, value, apiUserid]).catch((e) => {
|
await dbClient.execute('UPDATE all_keys SET ?? = ? WHERE userid = ?', [key, value, apiUserid]).catch((e) => {
|
||||||
utils.commonLoggers.dbError('apiKeyManage.ts', 'update', e);
|
utils.commonLoggers.dbError('apiKeyManage.ts', 'update', e);
|
||||||
requestEvent.respondWith(stdResp.InternalServerError(`Failed to ${key} to ${value}.`));
|
requestEvent.respondWith(stdResp.InternalServerError(`Failed to ${key} to ${value}.`));
|
||||||
erroredOut = true;
|
erroredOut = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exit this case now if catch errored
|
// Exit this case now if catch errored
|
||||||
if (erroredOut) {
|
if (erroredOut) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send OK as response to indicate modification was successful
|
// Send OK as response to indicate modification was successful
|
||||||
requestEvent.respondWith(stdResp.OK(`Successfully ${key} to ${value}.`));
|
requestEvent.respondWith(stdResp.OK(`Successfully ${key} to ${value}.`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they shouldn't be doing this
|
// Alert API user that they shouldn't be doing this
|
||||||
requestEvent.respondWith(stdResp.Forbidden('You can only manage your own key.'));
|
requestEvent.respondWith(stdResp.Forbidden('You can only manage your own key.'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Alert API user that they messed up
|
// Alert API user that they messed up
|
||||||
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
requestEvent.respondWith(stdResp.BadRequest(stdResp.Strings.missingParams));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
import {
|
import {
|
||||||
// httpd deps
|
// httpd deps
|
||||||
Status,
|
StatusCode,
|
||||||
STATUS_TEXT,
|
STATUS_CODE,
|
||||||
|
STATUS_TEXT,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
|
|
||||||
const genericResponse = (customText: string, status: Status) => new Response(customText || STATUS_TEXT[status], { status: status, statusText: STATUS_TEXT[status] });
|
const genericResponse = (customText: string, status: StatusCode) =>
|
||||||
|
new Response(customText || STATUS_TEXT[status], { status: status, statusText: STATUS_TEXT[status] });
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
BadRequest: (customText: string) => genericResponse(customText, Status.BadRequest),
|
BadRequest: (customText: string) => genericResponse(customText, STATUS_CODE.BadRequest),
|
||||||
FailedDependency: (customText: string) => genericResponse(customText, Status.FailedDependency),
|
FailedDependency: (customText: string) => genericResponse(customText, STATUS_CODE.FailedDependency),
|
||||||
InternalServerError: (customText: string) => genericResponse(customText, Status.InternalServerError),
|
InternalServerError: (customText: string) => genericResponse(customText, STATUS_CODE.InternalServerError),
|
||||||
Forbidden: (customText: string) => genericResponse(customText, Status.Forbidden),
|
Forbidden: (customText: string) => genericResponse(customText, STATUS_CODE.Forbidden),
|
||||||
MethodNotAllowed: (customText: string) => genericResponse(customText, Status.MethodNotAllowed),
|
MethodNotAllowed: (customText: string) => genericResponse(customText, STATUS_CODE.MethodNotAllowed),
|
||||||
NotFound: (customText: string) => genericResponse(customText, Status.NotFound),
|
NotFound: (customText: string) => genericResponse(customText, STATUS_CODE.NotFound),
|
||||||
OK: (customText: string) => genericResponse(customText, Status.OK),
|
OK: (customText: string) => genericResponse(customText, STATUS_CODE.OK),
|
||||||
RequestTimeout: (customText: string) => genericResponse(customText, Status.RequestTimeout),
|
RequestTimeout: (customText: string) => genericResponse(customText, STATUS_CODE.RequestTimeout),
|
||||||
TooManyRequests: (customText: string) => genericResponse(customText, Status.TooManyRequests),
|
TooManyRequests: (customText: string) => genericResponse(customText, STATUS_CODE.TooManyRequests),
|
||||||
Strings: {
|
Strings: {
|
||||||
missingParams: 'Missing Parameters.',
|
missingParams: 'Missing Parameters.',
|
||||||
restricted: 'This API is restricted.',
|
restricted: 'This API is restricted.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
309
src/intervals.ts
309
src/intervals.ts
|
@ -5,66 +5,67 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
cache,
|
cache,
|
||||||
cacheHandlers,
|
cacheHandlers,
|
||||||
// imagescript dep
|
// imagescript dep
|
||||||
is,
|
is,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../deps.ts';
|
} from '../deps.ts';
|
||||||
import { PastCommandCount } from './mod.d.ts';
|
import { PastCommandCount } from './mod.d.ts';
|
||||||
import { dbClient, weekDays } from './db.ts';
|
import dbClient from './db/client.ts';
|
||||||
|
import { weekDays } from './db/common.ts';
|
||||||
import utils from './utils.ts';
|
import utils from './utils.ts';
|
||||||
import config from '../config.ts';
|
import config from '../config.ts';
|
||||||
|
|
||||||
// getRandomStatus() returns status as string
|
// getRandomStatus() returns status as string
|
||||||
// Gets a new random status for the bot
|
// Gets a new random status for the bot
|
||||||
const getRandomStatus = async (): Promise<string> => {
|
const getRandomStatus = async (): Promise<string> => {
|
||||||
let status = '';
|
let status = '';
|
||||||
switch (Math.floor((Math.random() * 4) + 1)) {
|
switch (Math.floor(Math.random() * 4 + 1)) {
|
||||||
case 1:
|
case 1:
|
||||||
status = `${config.prefix}help for commands`;
|
status = `${config.prefix}help for commands`;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
status = `Running V${config.version}`;
|
status = `Running V${config.version}`;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
status = `${config.prefix}info to learn more`;
|
status = `${config.prefix}info to learn more`;
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
const cachedCount = await cacheHandlers.size('guilds');
|
const cachedCount = await cacheHandlers.size('guilds');
|
||||||
status = `Rolling dice for ${cachedCount + cache.dispatchedGuildIds.size} servers`;
|
status = `Rolling dice for ${cachedCount + cache.dispatchedGuildIds.size} servers`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
// updateListStatistics(bot ID, current guild count) returns nothing, posts to botlists
|
// updateListStatistics(bot ID, current guild count) returns nothing, posts to botlists
|
||||||
// Sends the current server count to all bot list sites we are listed on
|
// Sends the current server count to all bot list sites we are listed on
|
||||||
const updateListStatistics = (botID: bigint, serverCount: number): void => {
|
const updateListStatistics = (botID: bigint, serverCount: number): void => {
|
||||||
config.botLists.forEach(async (e) => {
|
config.botLists.forEach(async (e) => {
|
||||||
try {
|
try {
|
||||||
log(LT.LOG, `Updating statistics for ${JSON.stringify(e)}`);
|
log(LT.LOG, `Updating statistics for ${JSON.stringify(e)}`);
|
||||||
if (e.enabled) {
|
if (e.enabled) {
|
||||||
const tempHeaders = new Headers();
|
const tempHeaders = new Headers();
|
||||||
tempHeaders.append(e.headers[0].header, e.headers[0].value);
|
tempHeaders.append(e.headers[0].header, e.headers[0].value);
|
||||||
tempHeaders.append('Content-Type', 'application/json');
|
tempHeaders.append('Content-Type', 'application/json');
|
||||||
// ?{} is a template used in config, just need to replace it with the real value
|
// ?{} is a template used in config, just need to replace it with the real value
|
||||||
const response = await fetch(e.apiUrl.replace('?{bot_id}', botID.toString()), {
|
const response = await fetch(e.apiUrl.replace('?{bot_id}', botID.toString()), {
|
||||||
'method': 'POST',
|
method: 'POST',
|
||||||
'headers': tempHeaders,
|
headers: tempHeaders,
|
||||||
'body': JSON.stringify(e.body).replace('"?{server_count}"', serverCount.toString()), // ?{server_count} needs the "" removed from around it aswell to make sure its sent as a number
|
body: JSON.stringify(e.body).replace('"?{server_count}"', serverCount.toString()), // ?{server_count} needs the "" removed from around it aswell to make sure its sent as a number
|
||||||
});
|
});
|
||||||
log(LT.INFO, `Posted server count to ${e.name}. Results: ${JSON.stringify(response)}`);
|
log(LT.INFO, `Posted server count to ${e.name}. Results: ${JSON.stringify(response)}`);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log(LT.ERROR, `Failed to update statistics for ${e.name} | Error: ${err.name} - ${err.message}`)
|
log(LT.ERROR, `Failed to update statistics for ${e.name} | Error: ${err.name} - ${err.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keep one week of data
|
// Keep one week of data
|
||||||
|
@ -73,141 +74,141 @@ const previousHours: Array<Array<PastCommandCount>> = [];
|
||||||
// updateHourlyRates() returns nothing, updates DB directly
|
// updateHourlyRates() returns nothing, updates DB directly
|
||||||
// Updates the hourlyRate for command usage
|
// Updates the hourlyRate for command usage
|
||||||
const updateHourlyRates = async () => {
|
const updateHourlyRates = async () => {
|
||||||
try {
|
try {
|
||||||
const newestHour = await dbClient.query('SELECT command, count FROM command_cnt ORDER BY command;').catch((e) => utils.commonLoggers.dbError('intervals.ts:71', 'query', e));
|
const newestHour = await dbClient
|
||||||
previousHours.push(newestHour);
|
.query('SELECT command, count FROM command_cnt ORDER BY command;')
|
||||||
if (previousHours.length > 1) {
|
.catch((e) => utils.commonLoggers.dbError('intervals.ts:71', 'query', e));
|
||||||
const oldestHour = previousHours[0];
|
previousHours.push(newestHour);
|
||||||
|
if (previousHours.length > 1) {
|
||||||
|
const oldestHour = previousHours[0];
|
||||||
|
|
||||||
const computedDiff: Array<PastCommandCount> = [];
|
const computedDiff: Array<PastCommandCount> = [];
|
||||||
for (let i = 0; i < newestHour.length; i++) {
|
for (let i = 0; i < newestHour.length; i++) {
|
||||||
computedDiff.push({
|
computedDiff.push({
|
||||||
command: newestHour[i].command,
|
command: newestHour[i].command,
|
||||||
count: (newestHour[i].count - oldestHour[i].count),
|
count: newestHour[i].count - oldestHour[i].count,
|
||||||
});
|
});
|
||||||
log(LT.LOG, `Updating hourlyRate | Computing diffs: ${JSON.stringify(computedDiff)}`);
|
log(LT.LOG, `Updating hourlyRate | Computing diffs: ${JSON.stringify(computedDiff)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update DB
|
// Update DB
|
||||||
computedDiff.forEach(async (cmd) => {
|
computedDiff.forEach(async (cmd) => {
|
||||||
log(LT.LOG, `Updating hourlyRate | Storing to DB: ${JSON.stringify(cmd)}`);
|
log(LT.LOG, `Updating hourlyRate | Storing to DB: ${JSON.stringify(cmd)}`);
|
||||||
await dbClient.execute(`UPDATE command_cnt SET hourlyRate = ? WHERE command = ?`, [cmd.count / previousHours.length, cmd.command]).catch((e) =>
|
await dbClient
|
||||||
utils.commonLoggers.dbError('intervals.ts:88', 'update', e)
|
.execute(`UPDATE command_cnt SET hourlyRate = ? WHERE command = ?`, [cmd.count / previousHours.length, cmd.command])
|
||||||
);
|
.catch((e) => utils.commonLoggers.dbError('intervals.ts:88', 'update', e));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousHours.length > hoursToKeep) {
|
if (previousHours.length > hoursToKeep) {
|
||||||
previousHours.unshift();
|
previousHours.unshift();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(LT.ERROR, `Something went wrong in previousHours interval | Error: ${e.name} - ${e.message}`);
|
log(LT.ERROR, `Something went wrong in previousHours interval | Error: ${e.name} - ${e.message}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// getPercentOfRange(min, max, val) returns number
|
// getPercentOfRange(min, max, val) returns number
|
||||||
// Gets a percent value of where val lies in the min-max range
|
// Gets a percent value of where val lies in the min-max range
|
||||||
const getPercentOfRange = (minVal: number, maxVal: number, val: number): number => {
|
const getPercentOfRange = (minVal: number, maxVal: number, val: number): number => {
|
||||||
const localMax = maxVal - minVal;
|
const localMax = maxVal - minVal;
|
||||||
const localVal = val - minVal;
|
const localVal = val - minVal;
|
||||||
|
|
||||||
return localVal / localMax;
|
return localVal / localMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pixel locations in heatmap-base.png, pixel locations are 0 based
|
// Pixel locations in heatmap-base.png, pixel locations are 0 based
|
||||||
// dayPixels holds the left and right (AKA X Coord) pixel locations for each col (ex: [leftPX, rightPX])
|
// dayPixels holds the left and right (AKA X Coord) pixel locations for each col (ex: [leftPX, rightPX])
|
||||||
const dayPixels: Array<Array<number>> = [
|
const dayPixels: Array<Array<number>> = [
|
||||||
[72, 159],
|
[72, 159],
|
||||||
[163, 260],
|
[163, 260],
|
||||||
[264, 359],
|
[264, 359],
|
||||||
[363, 497],
|
[363, 497],
|
||||||
[501, 608],
|
[501, 608],
|
||||||
[612, 686],
|
[612, 686],
|
||||||
[690, 800],
|
[690, 800],
|
||||||
];
|
];
|
||||||
// hourPixels holds the top and bottom (AKA Y Coord) pixel locations for each row (ex: [topPX, botPX])
|
// hourPixels holds the top and bottom (AKA Y Coord) pixel locations for each row (ex: [topPX, botPX])
|
||||||
const hourPixels: Array<Array<number>> = [
|
const hourPixels: Array<Array<number>> = [
|
||||||
[29, 49],
|
[29, 49],
|
||||||
[51, 72],
|
[51, 72],
|
||||||
[74, 95],
|
[74, 95],
|
||||||
[97, 118],
|
[97, 118],
|
||||||
[120, 141],
|
[120, 141],
|
||||||
[143, 164],
|
[143, 164],
|
||||||
[166, 187],
|
[166, 187],
|
||||||
[189, 209],
|
[189, 209],
|
||||||
[211, 232],
|
[211, 232],
|
||||||
[234, 254],
|
[234, 254],
|
||||||
[256, 277],
|
[256, 277],
|
||||||
[279, 299],
|
[279, 299],
|
||||||
[301, 322],
|
[301, 322],
|
||||||
[324, 345],
|
[324, 345],
|
||||||
[347, 368],
|
[347, 368],
|
||||||
[370, 391],
|
[370, 391],
|
||||||
[393, 413],
|
[393, 413],
|
||||||
[415, 436],
|
[415, 436],
|
||||||
[438, 459],
|
[438, 459],
|
||||||
[461, 482],
|
[461, 482],
|
||||||
[484, 505],
|
[484, 505],
|
||||||
[507, 528],
|
[507, 528],
|
||||||
[530, 550],
|
[530, 550],
|
||||||
[552, 572],
|
[552, 572],
|
||||||
];
|
];
|
||||||
// updateHeatmap() returns nothing, creates new heatmap.png
|
// updateHeatmap() returns nothing, creates new heatmap.png
|
||||||
// Updates the heatmap image with latest data from the db
|
// Updates the heatmap image with latest data from the db
|
||||||
let minRollCnt: number;
|
let minRollCnt: number;
|
||||||
let maxRollCnt: number;
|
let maxRollCnt: number;
|
||||||
const updateHeatmapPng = async () => {
|
const updateHeatmapPng = async () => {
|
||||||
const baseHeatmap = Deno.readFileSync('./src/endpoints/gets/heatmap-base.png');
|
const baseHeatmap = Deno.readFileSync('./src/endpoints/gets/heatmap-base.png');
|
||||||
const heatmap = await is.decode(baseHeatmap);
|
const heatmap = await is.decode(baseHeatmap);
|
||||||
if (!(heatmap instanceof is.Image)) {
|
if (!(heatmap instanceof is.Image)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Get latest data from DB
|
// Get latest data from DB
|
||||||
const heatmapData = await dbClient.query('SELECT * FROM roll_time_heatmap ORDER BY hour;').catch((e) => utils.commonLoggers.dbError('intervals.ts:148', 'query', e));
|
const heatmapData = await dbClient
|
||||||
|
.query('SELECT * FROM roll_time_heatmap ORDER BY hour;')
|
||||||
|
.catch((e) => utils.commonLoggers.dbError('intervals.ts:148', 'query', e));
|
||||||
|
|
||||||
minRollCnt = Infinity;
|
minRollCnt = Infinity;
|
||||||
maxRollCnt = 0;
|
maxRollCnt = 0;
|
||||||
// determine min and max values
|
// determine min and max values
|
||||||
for (const hour of heatmapData) {
|
for (const hour of heatmapData) {
|
||||||
for (const day of weekDays) {
|
for (const day of weekDays) {
|
||||||
const rollCnt = hour[day];
|
const rollCnt = hour[day];
|
||||||
log(LT.LOG, `updateHeatmapPng | finding min/max | min: ${minRollCnt} max: ${maxRollCnt} curr: ${rollCnt}`);
|
log(LT.LOG, `updateHeatmapPng | finding min/max | min: ${minRollCnt} max: ${maxRollCnt} curr: ${rollCnt}`);
|
||||||
if (rollCnt > maxRollCnt) {
|
if (rollCnt > maxRollCnt) {
|
||||||
maxRollCnt = rollCnt;
|
maxRollCnt = rollCnt;
|
||||||
}
|
}
|
||||||
if (rollCnt < minRollCnt) {
|
if (rollCnt < minRollCnt) {
|
||||||
minRollCnt = rollCnt;
|
minRollCnt = rollCnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply values to image
|
// Apply values to image
|
||||||
for (let hour = 0; hour < heatmapData.length; hour++) {
|
for (let hour = 0; hour < heatmapData.length; hour++) {
|
||||||
for (let day = 0; day < weekDays.length; day++) {
|
for (let day = 0; day < weekDays.length; day++) {
|
||||||
log(LT.LOG, `updateHeatmapPng | putting ${weekDays[day]} ${hour}:00 into image`);
|
log(LT.LOG, `updateHeatmapPng | putting ${weekDays[day]} ${hour}:00 into image`);
|
||||||
const percent = getPercentOfRange(minRollCnt, maxRollCnt, heatmapData[hour][weekDays[day]]);
|
const percent = getPercentOfRange(minRollCnt, maxRollCnt, heatmapData[hour][weekDays[day]]);
|
||||||
heatmap.drawBox(
|
heatmap.drawBox(
|
||||||
dayPixels[day][0] + 1,
|
dayPixels[day][0] + 1,
|
||||||
hourPixels[hour][0] + 1,
|
hourPixels[hour][0] + 1,
|
||||||
dayPixels[day][1] - dayPixels[day][0] + 1,
|
dayPixels[day][1] - dayPixels[day][0] + 1,
|
||||||
hourPixels[hour][1] - hourPixels[hour][0] + 1,
|
hourPixels[hour][1] - hourPixels[hour][0] + 1,
|
||||||
is.Image.rgbToColor(
|
is.Image.rgbToColor(255 * (1 - percent), 255 * percent, 0)
|
||||||
255 * (1 - percent),
|
);
|
||||||
255 * percent,
|
}
|
||||||
0,
|
}
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Deno.writeFileSync('./src/endpoints/gets/heatmap.png', await heatmap.encode());
|
Deno.writeFileSync('./src/endpoints/gets/heatmap.png', await heatmap.encode());
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getRandomStatus,
|
getRandomStatus,
|
||||||
updateListStatistics,
|
updateListStatistics,
|
||||||
updateHourlyRates,
|
updateHourlyRates,
|
||||||
updateHeatmapPng,
|
updateHeatmapPng,
|
||||||
getMinRollCnt: () => minRollCnt,
|
getMinRollCnt: () => minRollCnt,
|
||||||
getMaxRollCnt: () => maxRollCnt,
|
getMaxRollCnt: () => maxRollCnt,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import config from '../../config.ts';
|
import config from '../../config.ts';
|
||||||
import { DEVMODE } from '../../flags.ts';
|
import { DEVMODE } from '../../flags.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import dbClient from '../db/client.ts';
|
||||||
|
import { queries } from '../db/common.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
DiscordenoMessage,
|
DiscordenoMessage,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
sendDirectMessage,
|
sendDirectMessage,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
} from '../../deps.ts';
|
} from '../../deps.ts';
|
||||||
import { SolvedRoll } from '../solver/solver.d.ts';
|
import { SolvedRoll } from '../solver/solver.d.ts';
|
||||||
import { QueuedRoll, RollModifiers } from '../mod.d.ts';
|
import { QueuedRoll, RollModifiers } from '../mod.d.ts';
|
||||||
|
@ -22,189 +23,208 @@ const rollQueue: Array<QueuedRoll> = [];
|
||||||
|
|
||||||
// Handle setting up and calling the rollWorker
|
// Handle setting up and calling the rollWorker
|
||||||
const handleRollWorker = async (rq: QueuedRoll) => {
|
const handleRollWorker = async (rq: QueuedRoll) => {
|
||||||
currentWorkers++;
|
currentWorkers++;
|
||||||
|
|
||||||
// gmModifiers used to create gmEmbed (basically just turn off the gmRoll)
|
// gmModifiers used to create gmEmbed (basically just turn off the gmRoll)
|
||||||
const gmModifiers = JSON.parse(JSON.stringify(rq.modifiers));
|
const gmModifiers = JSON.parse(JSON.stringify(rq.modifiers));
|
||||||
gmModifiers.gmRoll = false;
|
gmModifiers.gmRoll = false;
|
||||||
|
|
||||||
const rollWorker = new Worker(new URL('../solver/rollWorker.ts', import.meta.url).href, { type: 'module' });
|
const rollWorker = new Worker(new URL('../solver/rollWorker.ts', import.meta.url).href, { type: 'module' });
|
||||||
|
|
||||||
const workerTimeout = setTimeout(async () => {
|
const workerTimeout = setTimeout(async () => {
|
||||||
rollWorker.terminate();
|
rollWorker.terminate();
|
||||||
currentWorkers--;
|
currentWorkers--;
|
||||||
if (rq.apiRoll) {
|
if (rq.apiRoll) {
|
||||||
rq.api.requestEvent.respondWith(stdResp.RequestTimeout('Roll took too long to process, try breaking roll down into simpler parts'));
|
rq.api.requestEvent.respondWith(stdResp.RequestTimeout('Roll took too long to process, try breaking roll down into simpler parts'));
|
||||||
} else {
|
} else {
|
||||||
rq.dd.m.edit({
|
rq.dd.m
|
||||||
embeds: [
|
.edit({
|
||||||
(await generateRollEmbed(
|
embeds: [
|
||||||
rq.dd.message.authorId,
|
(
|
||||||
<SolvedRoll> {
|
await generateRollEmbed(
|
||||||
error: true,
|
rq.dd.message.authorId,
|
||||||
errorCode: 'TooComplex',
|
<SolvedRoll>{
|
||||||
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
|
error: true,
|
||||||
},
|
errorCode: 'TooComplex',
|
||||||
<RollModifiers> {},
|
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
|
||||||
)).embed,
|
},
|
||||||
],
|
<RollModifiers>{}
|
||||||
}).catch((e) => utils.commonLoggers.messageEditError('rollQueue.ts:51', rq.dd.m, e));
|
)
|
||||||
}
|
).embed,
|
||||||
}, config.limits.workerTimeout);
|
],
|
||||||
|
})
|
||||||
|
.catch((e) => utils.commonLoggers.messageEditError('rollQueue.ts:51', rq.dd.m, e));
|
||||||
|
}
|
||||||
|
}, config.limits.workerTimeout);
|
||||||
|
|
||||||
rollWorker.addEventListener('message', async (workerMessage) => {
|
rollWorker.addEventListener('message', async (workerMessage) => {
|
||||||
if (workerMessage.data === 'ready') {
|
if (workerMessage.data === 'ready') {
|
||||||
rollWorker.postMessage({
|
rollWorker.postMessage({
|
||||||
rollCmd: rq.rollCmd,
|
rollCmd: rq.rollCmd,
|
||||||
modifiers: rq.modifiers,
|
modifiers: rq.modifiers,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let apiErroredOut = false;
|
let apiErroredOut = false;
|
||||||
try {
|
try {
|
||||||
currentWorkers--;
|
currentWorkers--;
|
||||||
clearTimeout(workerTimeout);
|
clearTimeout(workerTimeout);
|
||||||
const returnmsg = workerMessage.data;
|
const returnmsg = workerMessage.data;
|
||||||
const pubEmbedDetails = await generateRollEmbed(rq.apiRoll ? rq.api.userId : rq.dd.message.authorId, returnmsg, rq.modifiers);
|
const pubEmbedDetails = await generateRollEmbed(rq.apiRoll ? rq.api.userId : rq.dd.message.authorId, returnmsg, rq.modifiers);
|
||||||
const gmEmbedDetails = await generateRollEmbed(rq.apiRoll ? rq.api.userId : rq.dd.message.authorId, returnmsg, gmModifiers);
|
const gmEmbedDetails = await generateRollEmbed(rq.apiRoll ? rq.api.userId : rq.dd.message.authorId, returnmsg, gmModifiers);
|
||||||
const countEmbed = generateCountDetailsEmbed(returnmsg.counts);
|
const countEmbed = generateCountDetailsEmbed(returnmsg.counts);
|
||||||
|
|
||||||
// If there was an error, report it to the user in hopes that they can determine what they did wrong
|
// If there was an error, report it to the user in hopes that they can determine what they did wrong
|
||||||
if (returnmsg.error) {
|
if (returnmsg.error) {
|
||||||
if (rq.apiRoll) {
|
if (rq.apiRoll) {
|
||||||
rq.api.requestEvent.respondWith(stdResp.InternalServerError(returnmsg.errorMsg));
|
rq.api.requestEvent.respondWith(stdResp.InternalServerError(returnmsg.errorMsg));
|
||||||
} else {
|
} else {
|
||||||
rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
|
rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rq.apiRoll || DEVMODE && config.logRolls) {
|
if (rq.apiRoll || (DEVMODE && config.logRolls)) {
|
||||||
// If enabled, log rolls so we can see what went wrong
|
// If enabled, log rolls so we can see what went wrong
|
||||||
dbClient.execute(queries.insertRollLogCmd(rq.apiRoll ? 1 : 0, 1), [rq.originalCommand, returnmsg.errorCode, rq.apiRoll ? null : rq.dd.m.id]).catch((e) =>
|
dbClient
|
||||||
utils.commonLoggers.dbError('rollQueue.ts:82', 'insert into', e)
|
.execute(queries.insertRollLogCmd(rq.apiRoll ? 1 : 0, 1), [rq.originalCommand, returnmsg.errorCode, rq.apiRoll ? null : rq.dd.m.id])
|
||||||
);
|
.catch((e) => utils.commonLoggers.dbError('rollQueue.ts:82', 'insert into', e));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let n: DiscordenoMessage | void;
|
let n: DiscordenoMessage | void;
|
||||||
// Determine if we are to send a GM roll or a normal roll
|
// Determine if we are to send a GM roll or a normal roll
|
||||||
if (rq.modifiers.gmRoll) {
|
if (rq.modifiers.gmRoll) {
|
||||||
if (rq.apiRoll) {
|
if (rq.apiRoll) {
|
||||||
n = await sendMessage(rq.api.channelId, {
|
n = await sendMessage(rq.api.channelId, {
|
||||||
content: rq.modifiers.apiWarn,
|
content: rq.modifiers.apiWarn,
|
||||||
embeds: [pubEmbedDetails.embed],
|
embeds: [pubEmbedDetails.embed],
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
apiErroredOut = true;
|
apiErroredOut = true;
|
||||||
rq.api.requestEvent.respondWith(stdResp.InternalServerError('Message failed to send - location 0.'));
|
rq.api.requestEvent.respondWith(stdResp.InternalServerError('Message failed to send - location 0.'));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Send the public embed to correct channel
|
// Send the public embed to correct channel
|
||||||
rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
|
rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!apiErroredOut) {
|
if (!apiErroredOut) {
|
||||||
// And message the full details to each of the GMs, alerting roller of every GM that could not be messaged
|
// And message the full details to each of the GMs, alerting roller of every GM that could not be messaged
|
||||||
rq.modifiers.gms.forEach(async (gm) => {
|
rq.modifiers.gms.forEach(async (gm) => {
|
||||||
log(LT.LOG, `Messaging GM ${gm}`);
|
log(LT.LOG, `Messaging GM ${gm}`);
|
||||||
// Attempt to DM the GM and send a warning if it could not DM a GM
|
// Attempt to DM the GM and send a warning if it could not DM a GM
|
||||||
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
|
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
|
||||||
embeds: rq.modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed],
|
embeds: rq.modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed],
|
||||||
}).then(async () => {
|
})
|
||||||
// Check if we need to attach a file and send it after the initial details sent
|
.then(async () => {
|
||||||
if (gmEmbedDetails.hasAttachment) {
|
// Check if we need to attach a file and send it after the initial details sent
|
||||||
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
|
if (gmEmbedDetails.hasAttachment) {
|
||||||
file: gmEmbedDetails.attachment,
|
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
|
||||||
}).catch(() => {
|
file: gmEmbedDetails.attachment,
|
||||||
if (n && rq.apiRoll) {
|
}).catch(() => {
|
||||||
n.reply(generateDMFailed(gm));
|
if (n && rq.apiRoll) {
|
||||||
} else {
|
n.reply(generateDMFailed(gm));
|
||||||
rq.dd.message.reply(generateDMFailed(gm));
|
} else {
|
||||||
}
|
rq.dd.message.reply(generateDMFailed(gm));
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
}).catch(() => {
|
}
|
||||||
if (rq.apiRoll && n) {
|
})
|
||||||
n.reply(generateDMFailed(gm));
|
.catch(() => {
|
||||||
} else {
|
if (rq.apiRoll && n) {
|
||||||
rq.dd.message.reply(generateDMFailed(gm));
|
n.reply(generateDMFailed(gm));
|
||||||
}
|
} else {
|
||||||
});
|
rq.dd.message.reply(generateDMFailed(gm));
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
} else {
|
});
|
||||||
// Not a gm roll, so just send normal embed to correct channel
|
}
|
||||||
if (rq.apiRoll) {
|
} else {
|
||||||
n = await sendMessage(rq.api.channelId, {
|
// Not a gm roll, so just send normal embed to correct channel
|
||||||
content: rq.modifiers.apiWarn,
|
if (rq.apiRoll) {
|
||||||
embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
|
n = await sendMessage(rq.api.channelId, {
|
||||||
}).catch(() => {
|
content: rq.modifiers.apiWarn,
|
||||||
apiErroredOut = true;
|
embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
|
||||||
rq.api.requestEvent.respondWith(stdResp.InternalServerError('Message failed to send - location 1.'));
|
}).catch(() => {
|
||||||
});
|
apiErroredOut = true;
|
||||||
} else {
|
rq.api.requestEvent.respondWith(stdResp.InternalServerError('Message failed to send - location 1.'));
|
||||||
n = await rq.dd.m.edit({
|
});
|
||||||
embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
|
} else {
|
||||||
});
|
n = await rq.dd.m.edit({
|
||||||
}
|
embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (pubEmbedDetails.hasAttachment && n) {
|
if (pubEmbedDetails.hasAttachment && n) {
|
||||||
// Attachment requires you to send a new message
|
// Attachment requires you to send a new message
|
||||||
n.reply({
|
n.reply({
|
||||||
file: pubEmbedDetails.attachment,
|
file: pubEmbedDetails.attachment,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rq.apiRoll && !apiErroredOut) {
|
if (rq.apiRoll && !apiErroredOut) {
|
||||||
dbClient.execute(queries.insertRollLogCmd(1, 0), [rq.originalCommand, returnmsg.errorCode, n ? n.id : null]).catch((e) => utils.commonLoggers.dbError('rollQueue.ts:155', 'insert into', e));
|
dbClient
|
||||||
|
.execute(queries.insertRollLogCmd(1, 0), [rq.originalCommand, returnmsg.errorCode, n ? n.id : null])
|
||||||
|
.catch((e) => utils.commonLoggers.dbError('rollQueue.ts:155', 'insert into', e));
|
||||||
|
|
||||||
rq.api.requestEvent.respondWith(stdResp.OK(JSON.stringify(
|
rq.api.requestEvent.respondWith(
|
||||||
rq.modifiers.count
|
stdResp.OK(
|
||||||
? {
|
JSON.stringify(
|
||||||
counts: countEmbed,
|
rq.modifiers.count
|
||||||
details: pubEmbedDetails,
|
? {
|
||||||
}
|
counts: countEmbed,
|
||||||
: {
|
details: pubEmbedDetails,
|
||||||
details: pubEmbedDetails,
|
}
|
||||||
},
|
: {
|
||||||
)));
|
details: pubEmbedDetails,
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
} catch (e) {
|
)
|
||||||
log(LT.ERROR, `Unddandled Error: ${JSON.stringify(e)}`);
|
);
|
||||||
if (rq.apiRoll && !apiErroredOut) {
|
}
|
||||||
rq.api.requestEvent.respondWith(stdResp.InternalServerError(JSON.stringify(e)));
|
}
|
||||||
}
|
} catch (e) {
|
||||||
}
|
log(LT.ERROR, `Unddandled Error: ${JSON.stringify(e)}`);
|
||||||
});
|
if (rq.apiRoll && !apiErroredOut) {
|
||||||
|
rq.api.requestEvent.respondWith(stdResp.InternalServerError(JSON.stringify(e)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Runs the roll or queues it depending on how many workers are currently running
|
// Runs the roll or queues it depending on how many workers are currently running
|
||||||
export const queueRoll = async (rq: QueuedRoll) => {
|
export const queueRoll = async (rq: QueuedRoll) => {
|
||||||
if (rq.apiRoll) {
|
if (rq.apiRoll) {
|
||||||
handleRollWorker(rq);
|
handleRollWorker(rq);
|
||||||
} else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
|
} else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
|
||||||
handleRollWorker(rq);
|
handleRollWorker(rq);
|
||||||
} else {
|
} else {
|
||||||
rq.dd.m.edit({
|
rq.dd.m
|
||||||
embeds: [{
|
.edit({
|
||||||
color: infoColor2,
|
embeds: [
|
||||||
title: `${config.name} currently has its hands full and has queued your roll.`,
|
{
|
||||||
description: `There are currently ${currentWorkers + rollQueue.length} rolls ahead of this roll.
|
color: infoColor2,
|
||||||
|
title: `${config.name} currently has its hands full and has queued your roll.`,
|
||||||
|
description: `There are currently ${currentWorkers + rollQueue.length} rolls ahead of this roll.
|
||||||
|
|
||||||
The results for this roll will replace this message when it is done.`,
|
The results for this roll will replace this message when it is done.`,
|
||||||
}],
|
},
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:197', rq.dd.m, e));
|
],
|
||||||
rollQueue.push(rq);
|
})
|
||||||
}
|
.catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:197', rq.dd.m, e));
|
||||||
|
rollQueue.push(rq);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks the queue constantly to make sure the queue stays empty
|
// Checks the queue constantly to make sure the queue stays empty
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
log(LT.LOG, `Checking rollQueue for items, rollQueue length: ${rollQueue.length}, currentWorkers: ${currentWorkers}, config.limits.maxWorkers: ${config.limits.maxWorkers}`);
|
log(
|
||||||
if (rollQueue.length && currentWorkers < config.limits.maxWorkers) {
|
LT.LOG,
|
||||||
const temp = rollQueue.shift();
|
`Checking rollQueue for items, rollQueue length: ${rollQueue.length}, currentWorkers: ${currentWorkers}, config.limits.maxWorkers: ${config.limits.maxWorkers}`
|
||||||
if (temp) {
|
);
|
||||||
temp.dd.m.edit(rollingEmbed).catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:208', temp.dd.m, e));
|
if (rollQueue.length && currentWorkers < config.limits.maxWorkers) {
|
||||||
handleRollWorker(temp);
|
const temp = rollQueue.shift();
|
||||||
}
|
if (temp) {
|
||||||
}
|
temp.dd.m.edit(rollingEmbed).catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:208', temp.dd.m, e));
|
||||||
|
handleRollWorker(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
Loading…
Reference in New Issue