mirror of
https://github.com/Burn-E99/SweeperBot.git
synced 2026-06-04 07:53:50 -04:00
upgrade to dd13
that was a pain
This commit is contained in:
@@ -1,19 +1,32 @@
|
||||
import config from '../config.ts';
|
||||
import { CountDetails, SolvedRoll } from './solver/solver.d.ts';
|
||||
import { RollModifiers } from './mod.d.ts';
|
||||
|
||||
export const failColor = 0xe71212;
|
||||
export const warnColor = 0xe38f28;
|
||||
export const successColor = 0x0f8108;
|
||||
export const infoColor1 = 0x313bf9;
|
||||
export const infoColor2 = 0x6805e9;
|
||||
|
||||
export const rollingEmbed = {
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
title: 'Rolling . . .',
|
||||
}],
|
||||
};
|
||||
const sweeperLines = [
|
||||
'Reporting broom stolen, Broom stolen!',
|
||||
'Oh no, no, no, no, no!',
|
||||
'I have nothing!',
|
||||
'Whoever has the broom, please bring it back soon. There is so much...sweeping to do.',
|
||||
'Have you seen my broom?',
|
||||
'Is theft from a frame a crime?',
|
||||
'They celebrate lost souls, but what about lost things?',
|
||||
'Where is it? Where is it?!',
|
||||
'What does the broom say? Broom Broom.',
|
||||
'All is lost....All. is. lost!',
|
||||
'malfunctional frame...will report for recycling...',
|
||||
'I have lost, a part of me...',
|
||||
'But in that sweep of death, what dreams may come?',
|
||||
'Dust to dust to dust to dust!?',
|
||||
'Who is the thief? Who is the thief...',
|
||||
'Life...is meaningless...',
|
||||
'Somebody help me!',
|
||||
'What is my purpose?',
|
||||
'They have candy, I have nothing!',
|
||||
'Dark purple candle...',
|
||||
];
|
||||
export const getRandomSweeperLine = () => sweeperLines[Math.floor(Math.random() * sweeperLines.length)];
|
||||
|
||||
export const generatePing = (time: number) => ({
|
||||
embeds: [{
|
||||
@@ -29,288 +42,3 @@ export const generateReport = (msg: string) => ({
|
||||
description: msg || 'No message',
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateStats = (guildCount: number, channelCount: number, memberCount: number, rollCount: bigint, utilityCount: bigint, rollRate: number, utilityRate: number) => ({
|
||||
embeds: [{
|
||||
color: infoColor2,
|
||||
title: 'The Artificer\'s Statistics:',
|
||||
timestamp: new Date().toISOString(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Guilds:',
|
||||
value: `${guildCount}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Channels:',
|
||||
value: `${channelCount}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Active Members:',
|
||||
value: `${memberCount}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Roll Commands:',
|
||||
value: `${rollCount}
|
||||
(${rollRate.toFixed(2)} per hour)`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Utility Commands:',
|
||||
value: `${utilityCount}
|
||||
(${utilityRate.toFixed(2)} per hour)`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateApiFailed = (args: string) => ({
|
||||
embeds: [{
|
||||
color: failColor,
|
||||
title: `Failed to ${args} API rolls for this guild.`,
|
||||
description: 'If this issue persists, please report this to the developers.',
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateApiStatus = (banned: boolean, active: boolean) => {
|
||||
const apiStatus = active ? 'allowed' : 'blocked from being used';
|
||||
return {
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
title: `The Artificer's API is ${config.api.enable ? 'currently enabled' : 'currently disabled'}.`,
|
||||
description: banned ? 'API rolls are banned from being used in this guild.\n\nThis will not be reversed.' : `API rolls are ${apiStatus} in this guild.`,
|
||||
}],
|
||||
};
|
||||
};
|
||||
|
||||
export const generateApiSuccess = (args: string) => ({
|
||||
embeds: [{
|
||||
color: successColor,
|
||||
title: `API rolls have successfully been ${args} for this guild.`,
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateDMFailed = (user: string) => ({
|
||||
embeds: [{
|
||||
color: failColor,
|
||||
title: `WARNING: ${user} could not be messaged.`,
|
||||
description: 'If this issue persists, make sure direct messages are allowed from this server.',
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateApiKeyEmail = (email: string, key: string) => ({
|
||||
content: `<@${config.api.admin}> A USER HAS REQUESTED AN API KEY`,
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
fields: [
|
||||
{
|
||||
name: 'Send to:',
|
||||
value: email,
|
||||
},
|
||||
{
|
||||
name: 'Subject:',
|
||||
value: 'Artificer API Key',
|
||||
},
|
||||
{
|
||||
name: 'Body:',
|
||||
value: `Hello Artificer API User,
|
||||
|
||||
Welcome aboard The Artificer's API. You can find full details about the API on the GitHub: https://github.com/Burn-E99/TheArtificer
|
||||
|
||||
Your API Key is: ${key}
|
||||
|
||||
Guard this well, as there is zero tolerance for API abuse.
|
||||
|
||||
Welcome aboard,
|
||||
The Artificer Developer - Ean Milligan`,
|
||||
},
|
||||
],
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateApiDeleteEmail = (email: string, deleteCode: string) => ({
|
||||
content: `<@${config.api.admin}> A USER HAS REQUESTED A DELETE CODE`,
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
fields: [
|
||||
{
|
||||
name: 'Send to:',
|
||||
value: email,
|
||||
},
|
||||
{
|
||||
name: 'Subject:',
|
||||
value: 'Artificer API Delete Code',
|
||||
},
|
||||
{
|
||||
name: 'Body:',
|
||||
value: `Hello Artificer API User,
|
||||
|
||||
I am sorry to see you go. If you would like, please respond to this email detailing what I could have done better.
|
||||
|
||||
As requested, here is your delete code: ${deleteCode}
|
||||
|
||||
Sorry to see you go,
|
||||
The Artificer Developer - Ean Milligan`,
|
||||
},
|
||||
],
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateRollError = (errorType: string, errorMsg: string) => ({
|
||||
embeds: [{
|
||||
color: failColor,
|
||||
title: 'Roll command encountered the following error:',
|
||||
fields: [{
|
||||
name: errorType,
|
||||
value: `${errorMsg}\n\nPlease try again. If the error is repeated, please report the issue using the \`${config.prefix}report\` command.`,
|
||||
}],
|
||||
}],
|
||||
});
|
||||
|
||||
export const generateCountDetailsEmbed = (counts: CountDetails) => ({
|
||||
color: infoColor1,
|
||||
title: 'Roll Count Details:',
|
||||
fields: [
|
||||
{
|
||||
name: 'Total Rolls:',
|
||||
value: `${counts.total}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Successful Rolls:',
|
||||
value: `${counts.successful}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Failed Rolls:',
|
||||
value: `${counts.failed}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Rerolled Dice:',
|
||||
value: `${counts.rerolled}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Dropped Dice:',
|
||||
value: `${counts.dropped}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Exploded Dice:',
|
||||
value: `${counts.exploded}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const generateRollEmbed = async (authorId: bigint, returnDetails: SolvedRoll, modifiers: RollModifiers) => {
|
||||
if (returnDetails.error) {
|
||||
// Roll had an error, send error embed
|
||||
return {
|
||||
embed: {
|
||||
color: failColor,
|
||||
title: 'Roll failed:',
|
||||
description: `${returnDetails.errorMsg}`,
|
||||
footer: {
|
||||
text: `Code: ${returnDetails.errorCode}`,
|
||||
},
|
||||
},
|
||||
hasAttachment: false,
|
||||
attachment: {
|
||||
'blob': await new Blob(['' as BlobPart], { 'type': 'text' }),
|
||||
'name': 'rollDetails.txt',
|
||||
},
|
||||
};
|
||||
} else {
|
||||
if (modifiers.gmRoll) {
|
||||
// Roll is a GM Roll, send this in the pub channel (this funciton will be ran again to get details for the GMs)
|
||||
return {
|
||||
embed: {
|
||||
color: infoColor2,
|
||||
description: `<@${authorId}>${returnDetails.line1}
|
||||
|
||||
Results have been messaged to the following GMs: ${modifiers.gms.join(' ')}`,
|
||||
},
|
||||
hasAttachment: false,
|
||||
attachment: {
|
||||
'blob': await new Blob(['' as BlobPart], { 'type': 'text' }),
|
||||
'name': 'rollDetails.txt',
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// Roll is normal, make normal embed
|
||||
const line2Details = returnDetails.line2.split(': ');
|
||||
let details = '';
|
||||
|
||||
if (!modifiers.superNoDetails) {
|
||||
if (modifiers.noDetails) {
|
||||
details = `**Details:**
|
||||
Suppressed by -nd flag`;
|
||||
} else {
|
||||
details = `**Details:**
|
||||
${modifiers.spoiler}${returnDetails.line3}${modifiers.spoiler}`;
|
||||
}
|
||||
}
|
||||
|
||||
const baseDesc = `<@${authorId}>${returnDetails.line1}
|
||||
**${line2Details.shift()}:**
|
||||
${line2Details.join(': ')}`;
|
||||
|
||||
if (baseDesc.length + details.length < 4090) {
|
||||
return {
|
||||
embed: {
|
||||
color: infoColor2,
|
||||
description: `${baseDesc}
|
||||
|
||||
${details}`,
|
||||
},
|
||||
hasAttachment: false,
|
||||
attachment: {
|
||||
'blob': await new Blob(['' as BlobPart], { 'type': 'text' }),
|
||||
'name': 'rollDetails.txt',
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// If its too big, collapse it into a .txt file and send that instead.
|
||||
const b = await new Blob([`${baseDesc}\n\n${details}` as BlobPart], { 'type': 'text' });
|
||||
details = 'Details have been ommitted from this message for being over 2000 characters.';
|
||||
if (b.size > 8388290) {
|
||||
details +=
|
||||
'\n\nFull details could not be attached to this messaged as a \`.txt\` file as the file would be too large for Discord to handle. If you would like to see the details of rolls, please send the rolls in multiple messages instead of bundled into one.';
|
||||
return {
|
||||
embed: {
|
||||
color: infoColor2,
|
||||
description: `${baseDesc}
|
||||
|
||||
${details}`,
|
||||
},
|
||||
hasAttachment: false,
|
||||
attachment: {
|
||||
'blob': await new Blob(['' as BlobPart], { 'type': 'text' }),
|
||||
'name': 'rollDetails.txt',
|
||||
},
|
||||
};
|
||||
} else {
|
||||
details += '\n\nFull details have been attached to this messaged as a \`.txt\` file for verification purposes.';
|
||||
return {
|
||||
embed: {
|
||||
color: infoColor2,
|
||||
description: `${baseDesc}
|
||||
|
||||
${details}`,
|
||||
},
|
||||
hasAttachment: true,
|
||||
attachment: {
|
||||
'blob': b,
|
||||
'name': 'rollDetails.txt',
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
17
src/commands/_index.ts
Normal file
17
src/commands/_index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ping } from './ping.ts';
|
||||
import { help } from './help.ts';
|
||||
import { info } from './info.ts';
|
||||
import { version } from './version.ts';
|
||||
import { report } from './report.ts';
|
||||
import { handleMentions } from './handleMentions.ts';
|
||||
import { sendMsg } from './sendMessage.ts';
|
||||
|
||||
export default {
|
||||
ping,
|
||||
help,
|
||||
info,
|
||||
version,
|
||||
report,
|
||||
handleMentions,
|
||||
sendMessage: sendMsg,
|
||||
};
|
||||
27
src/commands/handleMentions.ts
Normal file
27
src/commands/handleMentions.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import config from '../../config.ts';
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Log4Deno deps
|
||||
log,
|
||||
LT,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
} from '../../deps.ts';
|
||||
import { getRandomSweeperLine, infoColor1 } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const handleMentions = (bot: Bot, message: Message) => {
|
||||
log(LT.LOG, `Handling @mention message: ${utils.jsonStringifyBig(message)}`);
|
||||
|
||||
// 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));
|
||||
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
title: `Hello! I am ${config.name}!`,
|
||||
description: getRandomSweeperLine(),
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('handleMentions.ts:30', message, e));
|
||||
};
|
||||
48
src/commands/help.ts
Normal file
48
src/commands/help.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import config from '../../config.ts';
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
} from '../../deps.ts';
|
||||
import { infoColor2 } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const help = (bot: Bot, message: Message) => {
|
||||
// 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));
|
||||
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: infoColor2,
|
||||
title: `${config.name}\'s Available Commands:`,
|
||||
fields: [
|
||||
{
|
||||
name: `\`${config.prefix}?\``,
|
||||
value: 'This command',
|
||||
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}version\``,
|
||||
value: 'Prints the bots version',
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}report [text]\``,
|
||||
value: 'Report a command that failed to run',
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('help.ts:82', message, e));
|
||||
};
|
||||
23
src/commands/info.ts
Normal file
23
src/commands/info.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import config from '../../config.ts';
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
} from '../../deps.ts';
|
||||
import { infoColor2 } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const info = (bot: Bot, message: Message) => {
|
||||
// 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));
|
||||
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: infoColor2,
|
||||
title: `${config.name}, a Utility bot for the Destiny 2 Clan, -Midnight Coup-`,
|
||||
description: `${config.name} is developed by Ean AKA Burn_E99.
|
||||
Want to check out my source code? Check it out [here](https://github.com/Burn-E99/SweeperBot).`,
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('info.ts:23', message, e));
|
||||
};
|
||||
21
src/commands/ping.ts
Normal file
21
src/commands/ping.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
} from '../../deps.ts';
|
||||
import { generatePing } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const ping = async (bot: Bot, message: Message) => {
|
||||
// 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));
|
||||
|
||||
// Calculates ping between sending a message and editing it, giving a nice round-trip latency.
|
||||
try {
|
||||
const m = await bot.helpers.sendMessage(message.channelId, generatePing(-1));
|
||||
bot.helpers.editMessage(m.channelId, m.id, generatePing(m.timestamp - message.timestamp));
|
||||
} catch (e) {
|
||||
utils.commonLoggers.messageSendError('ping.ts:23', message, e);
|
||||
}
|
||||
};
|
||||
35
src/commands/report.ts
Normal file
35
src/commands/report.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import config from '../../config.ts';
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
// Discordeno deps
|
||||
sendMessage,
|
||||
} from '../../deps.ts';
|
||||
import { failColor, generateReport, successColor } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const report = (bot: Bot, message: Message, args: string[]) => {
|
||||
// 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));
|
||||
|
||||
if (args.join(' ')) {
|
||||
sendMessage(bot, config.reportChannel, generateReport(args.join(' '))).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:22', message, e));
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: successColor,
|
||||
title: 'Failed command has been reported to my developer.',
|
||||
description: `For more in depth support, ping <@177974415332605953>.`,
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:29', message, e));
|
||||
} else {
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
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));
|
||||
}
|
||||
};
|
||||
36
src/commands/sendMessage.ts
Normal file
36
src/commands/sendMessage.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
// Discordeno deps
|
||||
sendMessage,
|
||||
} from '../../deps.ts';
|
||||
import { failColor, successColor } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const sendMsg = (bot: Bot, message: Message, args: string[]) => {
|
||||
// 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));
|
||||
|
||||
try {
|
||||
const channelId = BigInt(args.shift() || '0');
|
||||
|
||||
if (args.join(' ') && channelId) {
|
||||
sendMessage(bot, channelId, { content: args.join(' ') }).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:22', message, e));
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: successColor,
|
||||
title: 'Attempted to send.',
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:29', message, e));
|
||||
}
|
||||
} catch (err) {
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: failColor,
|
||||
title: 'Missing args.',
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('report.ts:37', message, e));
|
||||
}
|
||||
};
|
||||
21
src/commands/version.ts
Normal file
21
src/commands/version.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import config from '../../config.ts';
|
||||
// import { dbClient, queries } from '../db.ts';
|
||||
import {
|
||||
Bot,
|
||||
// Discordeno deps
|
||||
Message,
|
||||
} from '../../deps.ts';
|
||||
import { infoColor1 } from '../commandUtils.ts';
|
||||
import utils from '../utils.ts';
|
||||
|
||||
export const version = (bot: Bot, message: Message) => {
|
||||
// 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));
|
||||
|
||||
bot.helpers.sendMessage(message.channelId, {
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
title: `My current version is ${config.version}`,
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('version.ts:24', message, e));
|
||||
};
|
||||
191
src/eventHandlers.ts
Normal file
191
src/eventHandlers.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import config from '../config.ts';
|
||||
import { DEVMODE, LOCALMODE } from '../flags.ts';
|
||||
import {
|
||||
// Discordeno deps
|
||||
ActivityTypes,
|
||||
botId,
|
||||
editBotNickname,
|
||||
editBotStatus,
|
||||
EventHandlers,
|
||||
// Log4Deno deps
|
||||
log,
|
||||
LT,
|
||||
// Discordeno deps
|
||||
sendMessage,
|
||||
} from '../deps.ts';
|
||||
// import { dbClient, ignoreList } from './src/db.ts';
|
||||
import commands from './commands/_index.ts';
|
||||
import { getRandomSweeperLine, successColor, warnColor } from './commandUtils.ts';
|
||||
import utils from './utils.ts';
|
||||
|
||||
export const events: Partial<EventHandlers> = {};
|
||||
events.ready = (bot) => {
|
||||
log(LT.INFO, `${config.name} Logged in!`);
|
||||
editBotStatus(bot, {
|
||||
activities: [{
|
||||
name: 'Booting up . . .',
|
||||
type: ActivityTypes.Game,
|
||||
createdAt: new Date().getTime(),
|
||||
}],
|
||||
status: 'online',
|
||||
});
|
||||
|
||||
// Interval to rotate the status text every 30 seconds to show off more commands
|
||||
setInterval(async () => {
|
||||
log(LT.LOG, 'Changing bot status');
|
||||
try {
|
||||
// Wrapped in try-catch due to hard crash possible
|
||||
editBotStatus(bot, {
|
||||
activities: [{
|
||||
name: getRandomSweeperLine(),
|
||||
type: ActivityTypes.Game,
|
||||
createdAt: new Date().getTime(),
|
||||
}],
|
||||
status: 'online',
|
||||
});
|
||||
} catch (e) {
|
||||
log(LT.ERROR, `Failed to update status: ${utils.jsonStringifyBig(e)}`);
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
// setTimeout added to make sure the startup message does not error out
|
||||
setTimeout(() => {
|
||||
LOCALMODE && editBotNickname(bot, config.devServer, { nick: `LOCAL - ${config.name}` });
|
||||
editBotStatus(bot, {
|
||||
activities: [{
|
||||
name: 'Booting Complete',
|
||||
type: ActivityTypes.Game,
|
||||
createdAt: new Date().getTime(),
|
||||
}],
|
||||
status: 'online',
|
||||
});
|
||||
sendMessage(bot, config.logChannel, {
|
||||
embeds: [{
|
||||
title: `${config.name} is now Online`,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: 'Version:',
|
||||
value: `${config.version}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:88', 'Startup', e));
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
events.guildCreate = (bot, guild) => {
|
||||
log(LT.LOG, `Handling joining guild ${utils.jsonStringifyBig(guild)}`);
|
||||
sendMessage(bot, config.logChannel, {
|
||||
embeds: [{
|
||||
title: 'New Guild Joined!',
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: 'Name:',
|
||||
value: `${guild.name}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Id:',
|
||||
value: `${guild.id}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Member Count:',
|
||||
value: `${guild.memberCount}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:95', 'Join Guild', e));
|
||||
};
|
||||
|
||||
events.guildDelete = (bot, guildId) => {
|
||||
log(LT.LOG, `Handling leaving guild ${utils.jsonStringifyBig(guildId)}`);
|
||||
sendMessage(bot, config.logChannel, {
|
||||
embeds: [{
|
||||
title: 'Removed from Guild',
|
||||
color: warnColor,
|
||||
fields: [
|
||||
{
|
||||
name: 'Id:',
|
||||
value: `${guildId}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
}],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('mod.ts:99', 'Leave Guild', e));
|
||||
};
|
||||
|
||||
if (DEVMODE) {
|
||||
events.debug = (dmsg) => log(LT.LOG, `Debug Message | ${utils.jsonStringifyBig(dmsg)}`);
|
||||
}
|
||||
|
||||
events.messageCreate = (bot, message) => {
|
||||
// Ignore all other bots
|
||||
if (message.isFromBot) return;
|
||||
|
||||
// Ignore all messages that are not commands
|
||||
if (message.content.indexOf(config.prefix) !== 0) {
|
||||
// Handle @bot messages
|
||||
if (message.mentionedUserIds[0] === botId && (message.content.trim().startsWith(`<@${botId}>`) || message.content.trim().startsWith(`<@!${botId}>`))) {
|
||||
commands.handleMentions(bot, message);
|
||||
}
|
||||
|
||||
// return as we are done handling this command
|
||||
return;
|
||||
}
|
||||
|
||||
log(LT.LOG, `Handling ${config.prefix}command message: ${utils.jsonStringifyBig(message)}`);
|
||||
|
||||
// Split into standard command + args format
|
||||
const args = message.content.slice(config.prefix.length).trim().split(/[ \n]+/g);
|
||||
const command = args.shift()?.toLowerCase();
|
||||
|
||||
// All commands below here
|
||||
switch (command) {
|
||||
case 'ping':
|
||||
// s!ping
|
||||
// Its a ping test, what else do you want.
|
||||
commands.ping(bot, message);
|
||||
break;
|
||||
case 'help':
|
||||
case 'h':
|
||||
case '?':
|
||||
// s!help or s!h or s!?
|
||||
// Help command, prints from help file
|
||||
commands.help(bot, message);
|
||||
break;
|
||||
case 'info':
|
||||
case 'i':
|
||||
// s!info or s!i
|
||||
// Info command, prints short desc on bot and some links
|
||||
commands.info(bot, message);
|
||||
break;
|
||||
case 'version':
|
||||
case 'v':
|
||||
// s!version or s!v
|
||||
// Returns version of the bot
|
||||
commands.version(bot, message);
|
||||
break;
|
||||
case 'report':
|
||||
case 'r':
|
||||
// s!report or s!r (command that failed)
|
||||
// Manually report a failed roll
|
||||
commands.report(bot, message, args);
|
||||
break;
|
||||
case 'sm':
|
||||
// s!sm [channelId]
|
||||
// Manually sends a message thru the bot
|
||||
if (message.authorId === config.ownerId) {
|
||||
commands.sendMessage(bot, message, args);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Non-standard commands
|
||||
console.log(`${command} WIP`);
|
||||
break;
|
||||
}
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
// getRandomStatus() returns status as string
|
||||
// Gets a new random status for the bot
|
||||
const sweeperLines = ['Reporting broom stolen, Broom stolen!', 'Oh no, no, no, no, no!', 'I have nothing!', 'Whoever has the broom, please bring it back soon. There is so much...sweeping to do.', 'Have you seen my broom?', 'Is theft from a frame a crime?', 'They celebrate lost souls, but what about lost things?', 'Where is it? Where is it?!', 'What does the broom say? Broom Broom.', 'All is lost....All. is. lost!', 'malfunctional frame...will report for recycling...', 'I have lost, a part of me...', 'But in that sweep of death, what dreams may come?', 'Dust to dust to dust to dust!?', 'Who is the thief? Who is the thief...', 'Life...is meaningless...', 'Somebody help me!', 'What is my purpose?', 'They have candy, I have nothing!', 'Dark purple candle...'];
|
||||
|
||||
const getRandomStatus = async (): Promise<string> => {
|
||||
return sweeperLines[Math.floor((Math.random() * sweeperLines.length))];
|
||||
};
|
||||
|
||||
export default {
|
||||
getRandomStatus,
|
||||
};
|
||||
98
src/utils.ts
98
src/utils.ts
@@ -5,102 +5,24 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
// Discordeno deps
|
||||
DiscordenoMessage,
|
||||
// Log4Deno deps
|
||||
log,
|
||||
LT,
|
||||
// Discordeno deps
|
||||
sendMessage,
|
||||
Message,
|
||||
} from '../deps.ts';
|
||||
|
||||
// ask(prompt) returns string
|
||||
// ask prompts the user at command line for message
|
||||
const ask = async (question: string, stdin = Deno.stdin, stdout = Deno.stdout): Promise<string> => {
|
||||
const buf = new Uint8Array(1024);
|
||||
|
||||
// Write question to console
|
||||
await stdout.write(new TextEncoder().encode(question));
|
||||
|
||||
// Read console's input into answer
|
||||
const n = <number> await stdin.read(buf);
|
||||
const answer = new TextDecoder().decode(buf.subarray(0, n));
|
||||
|
||||
return answer.trim();
|
||||
};
|
||||
|
||||
// cmdPrompt(logChannel, botName) returns nothing
|
||||
// cmdPrompt creates an interactive CLI for the bot, commands can vary
|
||||
const cmdPrompt = async (logChannel: bigint, botName: string): Promise<void> => {
|
||||
let done = false;
|
||||
|
||||
while (!done) {
|
||||
// Get a command and its args
|
||||
const fullCmd = await ask('cmd> ');
|
||||
|
||||
// Split the args off of the command and prep the command
|
||||
const args = fullCmd.split(' ');
|
||||
const command = args.shift()?.toLowerCase();
|
||||
|
||||
// All commands below here
|
||||
|
||||
// exit or e
|
||||
// Fully closes the bot
|
||||
if (command === 'exit' || command === 'e') {
|
||||
console.log(`${botName} Shutting down.\n\nGoodbye.`);
|
||||
done = true;
|
||||
Deno.exit(0);
|
||||
} // stop
|
||||
// Closes the CLI only, leaving the bot running truly headless
|
||||
else if (command === 'stop') {
|
||||
console.log(`Closing ${botName} CLI. Bot will continue to run.\n\nGoodbye.`);
|
||||
done = true;
|
||||
} // m [channel] [message]
|
||||
// Sends [message] to specified [channel]
|
||||
else if (command === 'm') {
|
||||
try {
|
||||
const channelId = args.shift() || '';
|
||||
const message = args.join(' ');
|
||||
|
||||
sendMessage(BigInt(channelId), message).catch((reason) => {
|
||||
console.error(reason);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} // ml [message]
|
||||
// Sends a message to the specified log channel
|
||||
else if (command === 'ml') {
|
||||
const message = args.join(' ');
|
||||
|
||||
sendMessage(logChannel, message).catch((reason) => {
|
||||
console.error(reason);
|
||||
});
|
||||
} // help or h
|
||||
// Shows a basic help menu
|
||||
else if (command === 'help' || command === 'h') {
|
||||
console.log(`${botName} CLI Help:
|
||||
|
||||
Available Commands:
|
||||
exit - closes bot
|
||||
stop - closes the CLI
|
||||
m [ChannelID] [messgae] - sends message to specific ChannelID as the bot
|
||||
ml [message] sends a message to the specified botlog
|
||||
help - this message`);
|
||||
} // Unhandled commands die here
|
||||
else {
|
||||
console.log('undefined command');
|
||||
}
|
||||
}
|
||||
const jsonStringifyBig = (input: any) => {
|
||||
return JSON.stringify(input, (_key, value) => typeof value === 'bigint' ? value.toString() + 'n' : value);
|
||||
};
|
||||
|
||||
const genericLogger = (level: LT, message: string) => log(level, message);
|
||||
const messageEditError = (location: string, message: DiscordenoMessage | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to edit message: ${JSON.stringify(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const messageSendError = (location: string, message: DiscordenoMessage | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to send message: ${JSON.stringify(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const messageDeleteError = (location: string, message: DiscordenoMessage | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to delete message: ${JSON.stringify(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const messageEditError = (location: string, message: Message | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to edit message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const messageSendError = (location: string, message: Message | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to send message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const messageDeleteError = (location: string, message: Message | string, err: Error) =>
|
||||
genericLogger(LT.ERROR, `${location} | Failed to delete message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
|
||||
const dbError = (location: string, type: string, err: Error) => genericLogger(LT.ERROR, `${location} | Failed to ${type} database | Error: ${err.name} - ${err.message}`);
|
||||
|
||||
export default {
|
||||
@@ -110,5 +32,5 @@ export default {
|
||||
messageSendError,
|
||||
messageDeleteError,
|
||||
},
|
||||
cmdPrompt,
|
||||
jsonStringifyBig,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user