This commit is contained in:
Christopher Cookman 2024-04-10 10:44:35 -06:00
commit 26d4837e0d
Signed by: ChrisChrome
GPG key ID: A023A26E42C33A42
5 changed files with 1112 additions and 0 deletions

134
.gitignore vendored Normal file
View file

@ -0,0 +1,134 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
config*
!config.json.default
defcon.txt

60
config.json.default Normal file
View file

@ -0,0 +1,60 @@
{
"debug": false,
"discord": {
"token": "",
"status_messages": [
{
"comment": "Main status",
"channel_id": "",
"message_id": ""
},
{
"comment": "Voice Status",
"channel_id": "",
"change_name": true
}
],
"actionable_servers": [""],
"slowmodes": [
{
"comment": "main chat",
"channel_id": "",
"slowmode": 60,
"defaultSlowmode": 0
}
],
"slowmode_categories": [
{
"comment": "Main Chat rooms",
"category_id": "",
"slowmode": 60,
"defaultSlowmode": 0
}
],
"invitelog": ""
},
"DEFCON": {
"levels": {
"1": {
"color": "#ec3e40",
"message": "**DEFCON 1** - High Alert, Full Lockdown. Break all Discord Invites and lock down the SL Server if necessary."
},
"2": {
"color": "#ff9b2b",
"message": "**DEFCON 2** - High Alert, Server invite links are locked, Discord server chats are heavily monitored (i.e. slowmodes, active moderation)."
},
"3": {
"color": "#f5d800",
"message": "**DEFCON 3** - Moderate Alert, Server invites are locked."
},
"4": {
"color": "#377fc7",
"message": "**DEFCON 4** - Moderate Alert, Server invites are monitored for suspicious individuals."
},
"5": {
"color": "#01a46d",
"message": "**DEFCON 5** - Low Alert, Normal Operations."
}
}
}
}

417
index.js Normal file
View file

@ -0,0 +1,417 @@
const config = require("./config");
const fs = require("fs");
const Discord = require("discord.js");
const colors = require("colors");
const {
REST,
Routes
} = require('discord.js');
const dcClient = new Discord.Client({
intents: ["Guilds", "GuildMembers"]
});
const rest = new REST({
version: '10'
}).setToken(config.discord.token);
const client = new Discord.Client({
intents: [
"Guilds",
"GuildInvites",
"AutoModerationConfiguration",
"AutoModerationExecution",
"GuildMembers",
"GuildModeration",
]
});
// First time bullshit
if (!fs.existsSync("config.json")) {
// Copy config.json.default, then process.exit(1) after telling the user to fill it out
fs.copyFileSync("config.json.default", "config.json");
console.log(`${colors.red("[ERROR]")} config.json not found. Please fill out config.json and restart the bot.`);
process.exit(1);
}
if (!fs.existsSync("defcon.txt")) {
// Just make the file, default to lvl 1
fs.writeFileSync("defcon.txt", "5");
}
/*
DEFCON Levels:
DEFCON 5 - Low Alert, Normal Operations.
DEFCON 4 - Moderate Alert, Server invites are monitored for suspicious individuals.
DEFCON 3 - Moderate Alert, Server invites are locked.
DEFCON 2 - High Alert, Server invite links are locked, Discord server chats are heavily monitored (i.e. slowmodes, active moderation).
DEFCON 1 - High Alert, Full Lockdown. Break all Discord Invites and lock down the SL Server if necessary.
*/
// get DEFCON level from file
let defcon = fs.readFileSync("defcon.txt", "utf8");
// DEFCON Functions, Set up server the way it needs to per DEFCON level
function updateDefcon(level) {
// Safety check
if (defcon > 5 || defcon < 1) {
defcon = 5;
}
// Update the file
fs.writeFileSync("defcon.txt", level);
// Update the variable
defcon = level;
// Update the bot's status
// client.user.setPresence({
// activities: [{
// name: `DEFCON ${level}`,
// type: Discord.ActivityType.Custom
// }]
// })
// Update the status messages
updateStatusMessages();
updateSlowmodes();
// if defcon 2 or lower, disable invites
if (level <= 3) {
actionable_servers.forEach((server) => {
server.disableInvites(true)
});
} else {
actionable_servers.forEach((server) => {
server.disableInvites(false)
});
}
}
// function updateSlowmodes() {
// if (defcon >= 3) {
// // Disable slowmodes
// slowmode_channels.forEach(async (channel) => {
// if (channel.channel.type == Discord.ChannelType.GuildCategory) {
// channel.channel.guild.channels.cache.forEach((chan) => {
// if (chan.parentId == channel.channel.id) {
// chan.setRateLimitPerUser(channel.defaultTime);
// }
// })
// } else {
// return channel.channel.setRateLimitPerUser(channel.defaultTime);
// }
// });
// } else if (defcon < 3) {
// // Enable slowmodes
// slowmode_channels.forEach(async (channel) => {
// if (channel.channel.type == Discord.ChannelType.GuildCategory) {
// // find all channels that have this category as a parent and set slowmode, gotta wait for the promise to resolve
// channel.channel.guild.channels.cache.forEach((chan) => {
// if (chan.parentId == channel.channel.id) {
// chan.setRateLimitPerUser(channel.time);
// }
// })
// } else {
// return channel.channel.setRateLimitPerUser(channel.time);
// }
// });
// }
// }
// Redo slowmodes, this time categories are separate, do those first. Still have to loop thru all channels in the guild and check if it has the category as a parent
function updateSlowmodes() {
if (defcon >= 3) {
// Disable slowmodes
slowmode_categories.forEach(async (category) => {
category.category.guild.channels.cache.forEach((chan) => {
if (chan.parentId == category.category.id) {
chan.setRateLimitPerUser(category.defaultTime);
}
})
});
slowmode_channels.forEach(async (channel) => {
return channel.channel.setRateLimitPerUser(channel.defaultTime);
})
} else {
// Enable slowmodes
slowmode_categories.forEach(async (category) => {
category.category.guild.channels.cache.forEach((chan) => {
if (chan.parentId == category.category.id) {
chan.setRateLimitPerUser(category.time);
}
})
});
slowmode_channels.forEach(async (channel) => {
return channel.channel.setRateLimitPerUser(channel.time);
})
}
}
function updateStatusMessages() {
let message = config.DEFCON.levels[defcon].message;
let color = config.DEFCON.levels[defcon].color;
// strip # from color and parseInt
color = parseInt(color.replace("#", ""), 16);
status_messages.forEach((msg) => {
msg.edit({
content: "",
embeds: [{
title: "DEFCON Status",
description: message,
color: color
}]
})
});
status_names.forEach((channel) => {
if (!channel.type == Discord.ChannelType.GuildVoice) return console.log(`${colors.red("[ERROR]")} Channel ${channel.name} is not a voice channel.`);
channel.setName(`[ DEFCON ${defcon} ]`).catch((err) => {
console.log(`${colors.red("[ERROR]")} Could not set channel name for ${channel.name}.`);
});
});
}
// Setup some global variables
let status_messages = [];
let status_names = [];
let actionable_servers = [];
let slowmode_channels = [];
let slowmode_categories = [];
client.on("ready", async () => {
console.log(`${colors.cyan("[INFO]")} Logged in as ${client.user.tag}`);
// Get status messages and actionable servers
config.discord.status_messages.forEach((msg) => {
// try to get the channel, then message, then push the msg to status_messages, if the channel or message doesnt exist, just return
let channel = client.channels.cache.get(msg.channel_id);
if (!channel) {
console.log(`${colors.red("[ERROR]")} Channel ${msg.channel} not found. Skipping, please use /msg to send a message to the channel.`);
return;
}
if (msg.change_name) {
// if name is set, add it to status_names, then skip the rest
console.log(`${colors.green("[INFO]")} Found channel name change for ${channel.name}.`)
return status_names.push(channel);
}
console.log(`${colors.green("[INFO]")} Found status message for ${channel.name}.`)
// fetch the message id, if it doesnt exist, throw error
channel.messages.fetch(msg.message_id).then((message) => {
status_messages.push(message);
}).catch((err) => {
console.log(`${colors.red("[ERROR]")} Message ${msg.message} not found in channel ${msg.channel}. Skipping, please use /msg to send a message to the channel.`);
return;
});
})
config.discord.actionable_servers.forEach((server) => {
let guild = client.guilds.cache.get(server);
actionable_servers.push(guild);
})
// Get slowmode channels
config.discord.slowmodes.forEach((channel) => {
let chan = client.channels.cache.get(channel.channel_id);
if (!chan) {
console.log(`${colors.red("[ERROR]")} Slowmode channel ${channel.channel_id} not found.`);
return;
}
slowmode_channels.push({ channel: chan, time: channel.slowmode, defaultTime: channel.defaultSlowmode });
});
config.discord.slowmode_categories.forEach((category) => {
let cat = client.channels.cache.get(category.category_id);
if (!cat) {
console.log(`${colors.red("[ERROR]")} Slowmode category ${category.category_id} not found.`);
return;
}
slowmode_categories.push({ category: cat, time: category.slowmode, defaultTime: category.defaultSlowmode });
});
//console.log(`Went through all guilds and channels:\nGuilds:\n${actionable_servers.map((server) => server.name).join("\n")}\nChannels:\n${slowmode_channels.map((channel.channel) => channel.name).join("\n")}`);
updateDefcon(defcon);
client.invites = [];
// Update Invites
client.guilds.cache.forEach(guild => { //on bot start, fetch all guilds and fetch all invites to store
guild.invites.fetch().then(guildInvites => {
guildInvites.each(guildInvite => {
client.invites[guildInvite.code] = guildInvite.uses
})
})
})
const commands = [
{
name: "defcon",
description: "Set the DEFCON level.",
default_member_permissions: 0,
options: [
{
name: "level",
description: "The DEFCON level to set.",
type: 3,
required: true,
choices: [
{
name: "DEFCON 5",
value: "5"
},
{
name: "DEFCON 4",
value: "4"
},
{
name: "DEFCON 3",
value: "3"
},
{
name: "DEFCON 2",
value: "2"
},
{
name: "DEFCON 1",
value: "1"
}
]
},
{
name: "confirm1",
description: "Confirm the DEFCON level change.",
type: 5,
required: true
},
{
name: "confirm2",
description: "Are you REALLY sure?",
type: 5,
required: true
}
]
},
{
name: "msg",
description: "Send a message to a channel.",
default_member_permissions: 0
}
]
// Do slash command stuff
await (async () => {
try {
console.log(`${colors.cyan("[INFO]")} Registering Commands...`)
let start = Date.now()
//Global
await rest.put(Routes.applicationCommands(client.user.id), { body: commands })
console.log(`${colors.cyan("[INFO]")} Successfully registered commands. Took ${colors.green((Date.now() - start) / 1000)} seconds.`);
} catch (error) {
console.error(error);
}
})();
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
let command = interaction.commandName;
switch (command) {
case "defcon":
// Update defcon
let level = interaction.options.getString("level");
newLevel = new Number(level);
// if number not between 1 and 5 send error
if (newLevel < 1 || newLevel > 5) {
interaction.reply({ content: "Invalid DEFCON level. Please choose a number between 1 and 5.", ephemeral: true });
return;
}
updateDefcon(level);
// Send response
interaction.reply({ content: `Successfully set DEFCON level to ${level}.`, ephemeral: true });
break;
case "msg":
// Send message to channel
interaction.channel.send("...").then((msg) => {
interaction.reply(msg.id)
})
break;
}
});
client.on('inviteCreate', (invite) => { //if someone creates an invite while bot is running, update store
client.invites[invite.code] = invite.uses
if (defcon > 4) return; // Dont need to send new invite messages if we're not monitoring invites
const channel = client.channels.cache.get(config.discord.invitelog)
channel.send({
embeds: [{
color: 0x00ffff,
title: "New Invite",
fields: [
{
name: "Invite",
// inline check, if expiry is in over 100 years, then it's never, otherwise it's the date
// ${invite.expiresTimestamp > 95617584000 ? "Never" : `<t:${invite.expiresTimestamp}>`
value: `Code: ${invite.code}\nMax Uses: ${invite.maxUses}\nExpires ${invite.expiresAt}\nCreated at: ${invite.createdAt}`
},
{
name: "Guild",
value: `${invite.guild.name}\n\`${invite.guild.id}\``
},
{
name: "Channel",
value: `${invite.channel.name}\n\`${invite.channel.id}\` <#${invite.channel.id}>`
},
{
name: "Inviter",
value: `${invite.inviter}\n\`${invite.inviter.id}\``
}
]
}]
});
});
client.on('guildMemberAdd', async (member) => { // We're just gonna always send invite logs, even if we're not monitoring them
const channel = client.channels.cache.get(config.discord.invitelog)
let guild = member.guild
member.guild.invites.fetch().then(guildInvites => { //get all guild invites
guildInvites.each(invite => { //basically a for loop over the invites
if (invite.uses != client.invites[invite.code]) { //if it doesn't match what we stored:
channel.send({
embeds: [{
color: 0x00ff00,
title: "New Member",
fields: [
{
name: "New Member",
value: `${member}\n\`${member.id}\`\nJoined at: <t:${member.joinedTimestamp}>\nAccount Created: <t:${member.user.createdTimestamp}>`
},
{
name: "Invite",
value: `Inviter: ${invite.inviter} (${invite.inviter.id})\nCode: ${invite.code}\nUses: ${invite.uses}`
},
{
name: "Guild",
value: `${guild.name}\n\`${guild.id}\``
}
]
}]
});
client.invites[invite.code] = invite.uses
}
})
})
if (defcon <= 4) {
// DM user saying Invites are disabled for security reasons, then kick them with the same reason
member.send("Invites are currently disabled for security reasons. Please contact a staff member for assistance.").then(() => {
member.kick(`DEFCON ${defcon}`);
channel.send({
embeds: [{
color: 0xff0000,
title: "Member Kicked",
description: `${member.user.username} was kicked`
}]
});
});
}
})
client.login(config.discord.token)

486
package-lock.json generated Normal file
View file

@ -0,0 +1,486 @@
{
"name": "discord-defcon",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "discord-defcon",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"dependencies": {
"colors": "^1.4.0",
"discord.js": "^14.14.1"
}
},
"node_modules/@discordjs/builders": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
"dependencies": {
"@discordjs/formatters": "^0.3.3",
"@discordjs/util": "^1.0.2",
"@sapphire/shapeshift": "^3.9.3",
"discord-api-types": "0.37.61",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.3",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/collection": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/formatters": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
"dependencies": {
"discord-api-types": "0.37.61"
},
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/rest": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
"dependencies": {
"@discordjs/collection": "^2.0.0",
"@discordjs/util": "^1.0.2",
"@sapphire/async-queue": "^1.5.0",
"@sapphire/snowflake": "^3.5.1",
"@vladfrangu/async_event_emitter": "^2.2.2",
"discord-api-types": "0.37.61",
"magic-bytes.js": "^1.5.0",
"tslib": "^2.6.2",
"undici": "5.27.2"
},
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
"engines": {
"node": ">=18"
}
},
"node_modules/@discordjs/util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==",
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/ws": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
"dependencies": {
"@discordjs/collection": "^2.0.0",
"@discordjs/rest": "^2.1.0",
"@discordjs/util": "^1.0.2",
"@sapphire/async-queue": "^1.5.0",
"@types/ws": "^8.5.9",
"@vladfrangu/async_event_emitter": "^2.2.2",
"discord-api-types": "0.37.61",
"tslib": "^2.6.2",
"ws": "^8.14.2"
},
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
"engines": {
"node": ">=18"
}
},
"node_modules/@fastify/busboy": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
"engines": {
"node": ">=14"
}
},
"node_modules/@sapphire/async-queue": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz",
"integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==",
"engines": {
"node": ">=v14.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/@sapphire/shapeshift": {
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz",
"integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"lodash": "^4.17.21"
},
"engines": {
"node": ">=v16"
}
},
"node_modules/@sapphire/snowflake": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz",
"integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==",
"engines": {
"node": ">=v14.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/@types/node": {
"version": "20.12.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/ws": {
"version": "8.5.9",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@vladfrangu/async_event_emitter": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz",
"integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==",
"engines": {
"node": ">=v14.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/discord-api-types": {
"version": "0.37.61",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw=="
},
"node_modules/discord.js": {
"version": "14.14.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
"dependencies": {
"@discordjs/builders": "^1.7.0",
"@discordjs/collection": "1.5.3",
"@discordjs/formatters": "^0.3.3",
"@discordjs/rest": "^2.1.0",
"@discordjs/util": "^1.0.2",
"@discordjs/ws": "^1.0.2",
"@sapphire/snowflake": "3.5.1",
"@types/ws": "8.5.9",
"discord-api-types": "0.37.61",
"fast-deep-equal": "3.1.3",
"lodash.snakecase": "4.1.1",
"tslib": "2.6.2",
"undici": "5.27.2",
"ws": "8.14.2"
},
"engines": {
"node": ">=16.11.0"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.snakecase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
},
"node_modules/magic-bytes.js": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
},
"node_modules/ts-mixer": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/undici": {
"version": "5.27.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
"engines": {
"node": ">=14.0"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/ws": {
"version": "8.14.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
},
"dependencies": {
"@discordjs/builders": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
"requires": {
"@discordjs/formatters": "^0.3.3",
"@discordjs/util": "^1.0.2",
"@sapphire/shapeshift": "^3.9.3",
"discord-api-types": "0.37.61",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.3",
"tslib": "^2.6.2"
}
},
"@discordjs/collection": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ=="
},
"@discordjs/formatters": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
"requires": {
"discord-api-types": "0.37.61"
}
},
"@discordjs/rest": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
"requires": {
"@discordjs/collection": "^2.0.0",
"@discordjs/util": "^1.0.2",
"@sapphire/async-queue": "^1.5.0",
"@sapphire/snowflake": "^3.5.1",
"@vladfrangu/async_event_emitter": "^2.2.2",
"discord-api-types": "0.37.61",
"magic-bytes.js": "^1.5.0",
"tslib": "^2.6.2",
"undici": "5.27.2"
},
"dependencies": {
"@discordjs/collection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w=="
}
}
},
"@discordjs/util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw=="
},
"@discordjs/ws": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
"requires": {
"@discordjs/collection": "^2.0.0",
"@discordjs/rest": "^2.1.0",
"@discordjs/util": "^1.0.2",
"@sapphire/async-queue": "^1.5.0",
"@types/ws": "^8.5.9",
"@vladfrangu/async_event_emitter": "^2.2.2",
"discord-api-types": "0.37.61",
"tslib": "^2.6.2",
"ws": "^8.14.2"
},
"dependencies": {
"@discordjs/collection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w=="
}
}
},
"@fastify/busboy": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="
},
"@sapphire/async-queue": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz",
"integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg=="
},
"@sapphire/shapeshift": {
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz",
"integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==",
"requires": {
"fast-deep-equal": "^3.1.3",
"lodash": "^4.17.21"
}
},
"@sapphire/snowflake": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz",
"integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA=="
},
"@types/node": {
"version": "20.12.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"requires": {
"undici-types": "~5.26.4"
}
},
"@types/ws": {
"version": "8.5.9",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
"requires": {
"@types/node": "*"
}
},
"@vladfrangu/async_event_emitter": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz",
"integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug=="
},
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
},
"discord-api-types": {
"version": "0.37.61",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw=="
},
"discord.js": {
"version": "14.14.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
"requires": {
"@discordjs/builders": "^1.7.0",
"@discordjs/collection": "1.5.3",
"@discordjs/formatters": "^0.3.3",
"@discordjs/rest": "^2.1.0",
"@discordjs/util": "^1.0.2",
"@discordjs/ws": "^1.0.2",
"@sapphire/snowflake": "3.5.1",
"@types/ws": "8.5.9",
"discord-api-types": "0.37.61",
"fast-deep-equal": "3.1.3",
"lodash.snakecase": "4.1.1",
"tslib": "2.6.2",
"undici": "5.27.2",
"ws": "8.14.2"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.snakecase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
},
"magic-bytes.js": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
},
"ts-mixer": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="
},
"tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"undici": {
"version": "5.27.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
},
"undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"ws": {
"version": "8.14.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"requires": {}
}
}
}

15
package.json Normal file
View file

@ -0,0 +1,15 @@
{
"name": "discord-defcon",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "GPL-3.0-or-later",
"dependencies": {
"colors": "^1.4.0",
"discord.js": "^14.14.1"
}
}