Compare commits
29 Commits
7da2c782af
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bb90ca792c | |||
| 0c84c85b62 | |||
| 0218583d24 | |||
| e2cc63e6c9 | |||
| ad32efb156 | |||
| 466b9708cf | |||
| f41f848ad5 | |||
| 2c596fe23f | |||
| 83c204670d | |||
| d8200e46df | |||
| 9d56ee5d34 | |||
| e2e764c295 | |||
| 6533510481 | |||
| 664224b14e | |||
| e59a863a8d | |||
| 2691653132 | |||
| 5e8fb7e729 | |||
| f1f9d95685 | |||
| 6d8d8402a5 | |||
| 202d0ef7bb | |||
| d26b5e5c56 | |||
| 564216ee8a | |||
| 0769a482fb | |||
| ea18387c75 | |||
| 3fc1ac1d54 | |||
| d7c3bdb5f7 | |||
| 9dac81db9b | |||
| 2925fb59dd | |||
| a74e19be5a |
@@ -0,0 +1,6 @@
|
|||||||
|
D_ID=
|
||||||
|
D_Token=
|
||||||
|
D_Prefix=
|
||||||
|
D_GuildID=
|
||||||
|
M_URI=
|
||||||
|
M_DB=
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.env
|
||||||
|
node_modules
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
MIT No Attribution
|
|
||||||
|
|
||||||
Copyright <YEAR> <COPYRIGHT HOLDER>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
||||||
software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
without restriction, including without limitation the rights to use, copy, modify,
|
|
||||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
@@ -1,2 +1,59 @@
|
|||||||
# Arthonor-Neo
|
# Arthonor-Neo
|
||||||
|
|
||||||
|
**Moderately Advanced Discord Bot for Friends**
|
||||||
|
|
||||||
|
Arthonor-Neo is a custom Discord bot designed for community interaction and fun. It offers an assortment of commands for economy, social engagement, and server utilities. Suitable for small to medium-sized friend servers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Core Interactions
|
||||||
|
- Nut Economy – Earn and spend nuts in server activities
|
||||||
|
- Honor System – Show recognition and respect to users
|
||||||
|
- Quotes – Save and retrieve memorable quotes
|
||||||
|
|
||||||
|
### Community & Events
|
||||||
|
- Automatic Welcome Messages – Greet new members
|
||||||
|
- Birthday System – Track and celebrate birthdays
|
||||||
|
- Automatic Birthday Cards – Personalized greetings on birthdays
|
||||||
|
- Wednesday Frog – Midweek server event
|
||||||
|
- Friday Reminder (Coming Soon)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Differences from Version 2.x
|
||||||
|
|
||||||
|
### Legacy Commands (Chat Messages)
|
||||||
|
These have been mostly removed with certain exceptions:
|
||||||
|
|
||||||
|
- Quoteadd has been kept due to the technicaly incompabiltity of replying using slash commands.
|
||||||
|
- Nuts has been kept due to frequent usage
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Timers
|
||||||
|
- WGE
|
||||||
|
- Weather commands
|
||||||
|
- GIF commands
|
||||||
|
- Certain developer tools
|
||||||
|
- WOKCommands Core
|
||||||
|
|
||||||
|
### Upgraded to Slash Commands
|
||||||
|
- Nuts
|
||||||
|
- Quotes
|
||||||
|
- Honor
|
||||||
|
- Birthdays
|
||||||
|
- Role Selection
|
||||||
|
- Channel Selection
|
||||||
|
- Meme Commands
|
||||||
|
|
||||||
|
### New and Improved
|
||||||
|
- Interactive Honor Menu
|
||||||
|
- Interactive Quote Menu
|
||||||
|
|
||||||
|
### Database Migration
|
||||||
|
Some structurual changes to the command schema, and removal of predefined schematics
|
||||||
|
|
||||||
|
- Tables renamed with prefixes, e.g. items_, config_, stats_, etc.
|
||||||
|
- Split tables into a relation-ish style
|
||||||
|
- made some data more machine-friendly
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
### ToDo?:
|
||||||
|
- quotes filter by channel
|
||||||
|
- event creation + reminder 1h before
|
||||||
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 914 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 411 KiB |
|
After Width: | Height: | Size: 371 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 536 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'abort',
|
||||||
|
description: 'abort it',
|
||||||
|
async execute(interaction) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Aborted')
|
||||||
|
.setDescription('Schließe Menü. . .')
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: []
|
||||||
|
})
|
||||||
|
await delay(2000).then(interaction.deleteReply())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honor_menu_dishonor',
|
||||||
|
description: 'honor menu dishonor button',
|
||||||
|
async execute(interaction) {
|
||||||
|
let description = interaction.message.embeds[0].data.description
|
||||||
|
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
const reason = `[-] Quick Menu Dishonor`
|
||||||
|
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Menu WIP -')
|
||||||
|
.setDescription(`Willst du wirklich <@${target.id}> einen **Dishonor** geben?\r\n[Grund: ${reason}]`)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level', value: `${theirHonorLevel?.honors ?? 0} (**-1**)`
|
||||||
|
})
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✔')
|
||||||
|
.setCustomId('honor_multi_confirm')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✖')
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honor_menu_history',
|
||||||
|
description: 'show selected user honor history',
|
||||||
|
async execute(interaction) {
|
||||||
|
let description = interaction.message.embeds[0].data.description
|
||||||
|
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const reasonsColl = db.collection('history_honors')
|
||||||
|
const history = await reasonsColl.findOne({ userID: target.user.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor History -')
|
||||||
|
.setDescription(`${target} - ${target.user.globalName ?? target.user.username}`)
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
.setFooter({text: 'Um zurückzukehren, wähle einen Nutzer!'})
|
||||||
|
if(history){
|
||||||
|
let temp = ''
|
||||||
|
history.reasons.forEach(reason => {
|
||||||
|
temp += reason + '\r\n'
|
||||||
|
})
|
||||||
|
embed.setDescription(temp)
|
||||||
|
}
|
||||||
|
const select = await interaction.message.components[0]
|
||||||
|
const row = await interaction.message.components[1]
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const { EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honor_menu_honor',
|
||||||
|
description: 'honor menu honor button',
|
||||||
|
async execute(interaction) {
|
||||||
|
let description = interaction.message.embeds[0].data.description
|
||||||
|
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
const reason = `[+] Quick Menu Honor`
|
||||||
|
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Up! -')
|
||||||
|
.setDescription(`Willst du wirklich <@${target.id}> einen **Honor** geben?\r\n[Grund: ${reason}]`)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level', value: `${theirHonorLevel?.honors ?? 0} (**+1**)`
|
||||||
|
})
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
//.setFooter('Honor Level updaten sich nicht automatisch!')
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✔')
|
||||||
|
.setCustomId('honor_multi_confirm')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✖')
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
const { EmbedBuilder, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honor_multi_confirm',
|
||||||
|
description: 'confirm it',
|
||||||
|
async execute(interaction) {
|
||||||
|
let temp = await interaction.message.embeds[0].description.split(' ')
|
||||||
|
var honor
|
||||||
|
if (temp[5] === '**Honor**') {
|
||||||
|
honor = 1
|
||||||
|
} else if (temp[5] === '**Dishonor**'){
|
||||||
|
honor = -1
|
||||||
|
} else {
|
||||||
|
return await interaction.reply({content: "ERROR", flags: MessageFlags.Ephemeral})
|
||||||
|
}
|
||||||
|
const target = await interaction.message.guild.members.fetch(temp[3].slice(2, -1))
|
||||||
|
temp = interaction.message.embeds[0].description.split('\r\n')
|
||||||
|
const reason = `${temp[1].slice(7, -1)}`
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
const reasonsColl = db.collection('history_honors')
|
||||||
|
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
await honorsColl.findOneAndUpdate({ userID: target.id }, { $inc: { honors: honor } }, { upsert: true })
|
||||||
|
await reasonsColl.findOneAndUpdate({ userID: target.id }, { $push: { reasons: reason } }, { upsert: true })
|
||||||
|
|
||||||
|
var description
|
||||||
|
var newTitle
|
||||||
|
var newDescription
|
||||||
|
var newThumbnail
|
||||||
|
|
||||||
|
if (honor == 1) {
|
||||||
|
description = `Willst du wirklich <@${target.id}> einen **Honor** geben?\r\n[Grund: ${reason}]`
|
||||||
|
newTitle = 'Honor Up!'
|
||||||
|
newDescription = `<@${target.id}> erhält einen Honor!\r\n[Grund: ${reason}]`
|
||||||
|
newThumbnail = "https://cdn.discordapp.com/emojis/748176295535443968.webp"
|
||||||
|
} else {
|
||||||
|
description = `Willst du wirklich <@${target.id}> einen **Dishonor** geben?\r\n[Grund: ${reason}]`
|
||||||
|
newTitle = 'Honor Down!'
|
||||||
|
newDescription = `<@${target.id}> erhält einen Dishonor!\r\n[Grund: ${reason}]`
|
||||||
|
newThumbnail = "https://cdn.discordapp.com/emojis/748176295132790786.webp"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Menu -')
|
||||||
|
.setDescription(description)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level', value: `${theirHonorLevel?.honors ?? 0} ${honor == 1 ? '(**+1**)' : '(**-1**)'}`
|
||||||
|
})
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed]
|
||||||
|
})
|
||||||
|
|
||||||
|
const newEmbed = new EmbedBuilder()
|
||||||
|
.setTitle(newTitle)
|
||||||
|
.setDescription(newDescription)
|
||||||
|
.setThumbnail(newThumbnail)
|
||||||
|
await interaction.followUp({
|
||||||
|
embeds: [newEmbed],
|
||||||
|
components: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honors_leaderboard_left',
|
||||||
|
description: 'navigate a page up',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
const min = 0
|
||||||
|
let skip = interaction.message.embeds[0].data.description.split('.')
|
||||||
|
skip = Number(skip[0]) - 6
|
||||||
|
skip = skip - ( skip % 5)
|
||||||
|
if ( skip < 4){
|
||||||
|
skip = 0
|
||||||
|
}
|
||||||
|
const honorsData = await honorsColl.find().sort({ honors: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
honorsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.honors} Honors\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Honors Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'honors_leaderboard_right',
|
||||||
|
description: 'navigate a page down',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
const max = await honorsColl.countDocuments()
|
||||||
|
let skip = interaction.message.embeds[0].data.description.split('.')
|
||||||
|
skip = Number(skip[0]) +4
|
||||||
|
if (skip >= (max - (max % 5))) {
|
||||||
|
skip = max - (max % 5)
|
||||||
|
}
|
||||||
|
const honorsData = await honorsColl.find().sort({ honors: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
honorsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.honors} Honors\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Honors Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'honors_leaderboard_self',
|
||||||
|
description: 'navigate to your own placement',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
|
||||||
|
const self = await honorsColl.find({ userID: interaction.user.id }).toArray()
|
||||||
|
const all = await honorsColl.find().sort({ honors: -1 }).toArray()
|
||||||
|
|
||||||
|
function findIndex(){
|
||||||
|
let index = 0
|
||||||
|
for (let i = 0; i < all.length; i++) {
|
||||||
|
index++
|
||||||
|
if (all[i].honors === self[0].honors) {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let selfIndex = findIndex()
|
||||||
|
let skip = selfIndex - ( selfIndex % 5)
|
||||||
|
|
||||||
|
const honorsData = await honorsColl.find().sort({ honors: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
honorsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.honors} Honors\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Honors Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts_give_confirm',
|
||||||
|
description: 'confirm it',
|
||||||
|
async execute(interaction) {
|
||||||
|
const from = interaction.user
|
||||||
|
let temp = await interaction.message.embeds[0].description.split(' ')
|
||||||
|
const amount = Number(temp[3].split('**')[1])
|
||||||
|
const to = await interaction.message.guild.members.fetch(temp[6].slice(2,-1))
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
await nutsColl.findOneAndUpdate({ userID: from.id }, { $inc: { nuts: -amount } }, { upsert: true })
|
||||||
|
await nutsColl.findOneAndUpdate({ userID: to.id }, { $inc: { nuts: +amount } }, { upsert: true })
|
||||||
|
|
||||||
|
const yourBalance = await nutsColl.findOne({ userID: from.id })
|
||||||
|
const theirBalance = await nutsColl.findOne({ userID: to.id })
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Gib Nuss!')
|
||||||
|
.setDescription(`Willst du wirklich **${amount}** Nüsse an <@${to.id}> senden?`)
|
||||||
|
.addFields(
|
||||||
|
{ name: `Your Current Balance`, value: `${yourBalance.nuts} (**-${amount}**)`, inline: true },
|
||||||
|
{ name: `Your New Balance`, value: `${yourBalance.nuts - amount}`, inline: true },
|
||||||
|
{ name: '\u200B', value: '\u200B' },
|
||||||
|
{ name: `Their Current Balance`, value: `${theirBalance.nuts} (**+${amount}**)`, inline: true },
|
||||||
|
{ name: `Their New Balance`, value: `${theirBalance.nuts + amount}`, inline: true }
|
||||||
|
)
|
||||||
|
.setThumbnail(to.displayAvatarURL())
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed ]
|
||||||
|
})
|
||||||
|
|
||||||
|
const newEmbed = new EmbedBuilder()
|
||||||
|
.setTitle('Gib Nuss!')
|
||||||
|
.setDescription(`Du hast **${amount}** Nuts an <@${to.id}> gesendet!`)
|
||||||
|
.setFooter({ text: 'Um den gleichen Wert zu senden, klick einfach nochmal auf ✔' })
|
||||||
|
.setThumbnail(to.user.displayAvatarURL())
|
||||||
|
await interaction.followUp({
|
||||||
|
embeds: [ newEmbed ],
|
||||||
|
components: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts_give_fake',
|
||||||
|
description: 'fake it',
|
||||||
|
async execute(interaction) {
|
||||||
|
const from = interaction.user
|
||||||
|
let temp = await interaction.message.embeds[0].description.split(' ')
|
||||||
|
const amount = Number(temp[3].split('**')[1])
|
||||||
|
const to = await interaction.message.guild.members.fetch(temp[6].slice(2,-1))
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
|
||||||
|
const yourBalance = await nutsColl.findOne({ userID: from.id })
|
||||||
|
const theirBalance = await nutsColl.findOne({ userID: to.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Gib Nuss!')
|
||||||
|
.setDescription(`Willst du wirklich **${amount}** Nüsse an <@${to.id}> senden?`)
|
||||||
|
.addFields(
|
||||||
|
{ name: `Your Current Balance`, value: `${yourBalance.nuts} (**-${amount}**)`, inline: true },
|
||||||
|
{ name: `Your New Balance`, value: `${yourBalance.nuts - amount}`, inline: true },
|
||||||
|
{ name: '\u200B', value: '\u200B' },
|
||||||
|
{ name: `Their Current Balance`, value: `${theirBalance.nuts} (**+${amount}**)`, inline: true },
|
||||||
|
{ name: `Their New Balance`, value: `${theirBalance.nuts + amount}`, inline: true }
|
||||||
|
)
|
||||||
|
.setThumbnail(to.displayAvatarURL())
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed ]
|
||||||
|
})
|
||||||
|
|
||||||
|
const newEmbed = new EmbedBuilder()
|
||||||
|
.setTitle('Du Fieser Gauner!')
|
||||||
|
.setDescription(`Yee Haw! Was tust du hier?!`)
|
||||||
|
.setThumbnail(interaction.client.user.displayAvatarURL())
|
||||||
|
await interaction.followUp({
|
||||||
|
embeds: [ newEmbed ],
|
||||||
|
components: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts_leaderboard_left',
|
||||||
|
description: 'navigate a page up',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const min = 0
|
||||||
|
let skip = interaction.message.embeds[0].data.description.split('.')
|
||||||
|
skip = Number(skip[0]) - 6
|
||||||
|
skip = skip - ( skip % 5)
|
||||||
|
if ( skip < 4){
|
||||||
|
skip = 0
|
||||||
|
}
|
||||||
|
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
nutsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Nuts Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts_leaderboard_right',
|
||||||
|
description: 'navigate a page down',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const max = await nutsColl.countDocuments({ nuts: { $gt: 0 } })
|
||||||
|
let skip = interaction.message.embeds[0].data.description.split('.')
|
||||||
|
skip = Number(skip[0]) +4
|
||||||
|
if (skip >= (max - (max % 5))) {
|
||||||
|
skip = max - (max % 5)
|
||||||
|
}
|
||||||
|
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
nutsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Nuts Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts_leaderboard_self',
|
||||||
|
description: 'navigate to your own placement',
|
||||||
|
async execute(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
|
||||||
|
const self = await nutsColl.find({ userID: interaction.user.id }).toArray()
|
||||||
|
const all = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).toArray()
|
||||||
|
|
||||||
|
function findIndex(){
|
||||||
|
let index = 0
|
||||||
|
for (let i = 0; i < all.length; i++) {
|
||||||
|
index++
|
||||||
|
if (all[i].nuts === self[0].nuts) {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let selfIndex = findIndex()
|
||||||
|
let skip = selfIndex - ( selfIndex % 5)
|
||||||
|
|
||||||
|
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
nutsData.forEach((data) => {
|
||||||
|
skip++
|
||||||
|
fields = (fields ? fields : '') + (`${skip}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Nuts Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [interaction.message.components[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const { quotesLeaderboard } = require("../../commands/slash/applications/quotes");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotes_leaderboard_left',
|
||||||
|
description: 'Navigate left through the quotes leaderboard',
|
||||||
|
async execute(interaction) {
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
// Parse current page from footer
|
||||||
|
let page = 1;
|
||||||
|
const footerText = interaction.message.embeds[0]?.footer?.text || '';
|
||||||
|
const match = footerText.match(/Page (\d+) of (\d+)/);
|
||||||
|
if (match) page = Number(match[1]);
|
||||||
|
|
||||||
|
page--; // move to previous page
|
||||||
|
|
||||||
|
await quotesLeaderboard(interaction, page);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const { quotesLeaderboard } = require("../../commands/slash/applications/quotes");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotes_leaderboard_right',
|
||||||
|
description: 'Navigate right through the quotes leaderboard',
|
||||||
|
async execute(interaction) {
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
// Parse current page from footer
|
||||||
|
let page = 1;
|
||||||
|
const footerText = interaction.message.embeds[0]?.footer?.text || '';
|
||||||
|
const match = footerText.match(/Page (\d+) of (\d+)/);
|
||||||
|
if (match) page = Number(match[1]);
|
||||||
|
|
||||||
|
page++; // move to next page
|
||||||
|
|
||||||
|
await quotesLeaderboard(interaction, page);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotes_list_left',
|
||||||
|
description: 'navigate left',
|
||||||
|
async execute(interaction) {
|
||||||
|
let oldEmbed = interaction.message.embeds[0].data
|
||||||
|
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
|
||||||
|
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1)
|
||||||
|
const target = await interaction.guild.members.fetch(userID)
|
||||||
|
if (!target) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const quotes = await quotesColl.find({ userID: target.id }).toArray()
|
||||||
|
|
||||||
|
var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1))
|
||||||
|
if (!index) { index = 0 }
|
||||||
|
index = index - 2
|
||||||
|
if (index < 1) { index = 0 }
|
||||||
|
|
||||||
|
|
||||||
|
const found = quotes[index]
|
||||||
|
|
||||||
|
const guild = await interaction.client.guilds.fetch(found.guildID)
|
||||||
|
const channel = await guild.channels.fetch(found.channelID)
|
||||||
|
const message = await channel.messages.fetch(found.messageID)
|
||||||
|
|
||||||
|
var msgData = {
|
||||||
|
content: message.content,
|
||||||
|
author: await message.author,
|
||||||
|
reference: await message.reference,
|
||||||
|
embed: await message.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
if (msgData.reference) {
|
||||||
|
let refMessage = await channel.messages.fetch(msgData.reference.messageId)
|
||||||
|
var refData = {
|
||||||
|
content: refMessage.content,
|
||||||
|
author: await refMessage.author,
|
||||||
|
embed: await refMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}`
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote #${index + 1} -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (`${footer} #${found.messageID} <@${found.userID}>`) })
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('quotes_list_mentionable')
|
||||||
|
.setPlaceholder('Filter By User')
|
||||||
|
)
|
||||||
|
|
||||||
|
const row = interaction.message.components[1]
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row]
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder, MessageFlags } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotes_list_right',
|
||||||
|
description: 'navigate right',
|
||||||
|
async execute(interaction) {
|
||||||
|
let oldEmbed = interaction.message.embeds[0].data
|
||||||
|
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
|
||||||
|
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1)
|
||||||
|
const target = await interaction.guild.members.fetch(userID)
|
||||||
|
if (!target) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const quotes = await quotesColl.find({ userID: target.id }).toArray()
|
||||||
|
|
||||||
|
var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1))
|
||||||
|
if (!index) { index = 0 }
|
||||||
|
//if (index >= quotes.length){ return interaction.reply({content: 'Max Quotes Reached', flags: MessageFlags.Ephemeral})}
|
||||||
|
if (index >= quotes.length) { index-- }
|
||||||
|
|
||||||
|
// will automatically reflect the next index due to how arrays think
|
||||||
|
|
||||||
|
const found = quotes[index]
|
||||||
|
const guild = await interaction.client.guilds.fetch(found.guildID)
|
||||||
|
const channel = await guild.channels.fetch(found.channelID)
|
||||||
|
const message = await channel.messages.fetch(found.messageID)
|
||||||
|
|
||||||
|
var msgData = {
|
||||||
|
content: message.content,
|
||||||
|
author: await message.author,
|
||||||
|
reference: await message.reference,
|
||||||
|
embed: await message.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
if (msgData.reference) {
|
||||||
|
let refMessage = await channel.messages.fetch(msgData.reference.messageId)
|
||||||
|
var refData = {
|
||||||
|
content: refMessage.content,
|
||||||
|
author: await refMessage.author,
|
||||||
|
embed: await refMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}`
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote #${index + 1} -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (`${footer} #${found.messageID} <@${found.userID}>`) })
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('quotes_list_mentionable')
|
||||||
|
.setPlaceholder('Filter By User')
|
||||||
|
)
|
||||||
|
|
||||||
|
const row = interaction.message.components[1]
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row]
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const ping = require("../../../src/ping")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'ping',
|
||||||
|
description: 'dev tool',
|
||||||
|
aliases: ['p'],
|
||||||
|
async execute(message, args) {
|
||||||
|
return ping(message, args, 'legacy')
|
||||||
|
}}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
const { EmbedBuilder } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'checknuts',
|
||||||
|
description: 'get nuts',
|
||||||
|
aliases: ['chn'],
|
||||||
|
async execute(message, args) {
|
||||||
|
var target = message.author
|
||||||
|
var addressing = `Du hast`
|
||||||
|
if (args[0]) {
|
||||||
|
if (!args[0].startsWith('<@' || !args[0].endsWith('>'))) { return message.reply('Invalid User Specification') }
|
||||||
|
try {
|
||||||
|
target = await message.guild.members.fetch(args[0].slice(2, -1))
|
||||||
|
} catch (error) {
|
||||||
|
return message.reply({
|
||||||
|
content: `User: ${args[0]} nicht gefunden!`
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await delay(4000)
|
||||||
|
message.delete()
|
||||||
|
msg.delete()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.user.id !== message.author.id) {
|
||||||
|
if (!target.user.globalName) {
|
||||||
|
addressing = `${target.user.username} hat`
|
||||||
|
} else {
|
||||||
|
addressing = `${target.user.globalName} hat`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
var nutsData = await nutsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
let content
|
||||||
|
if (!nutsData) {
|
||||||
|
content = `${addressing} noch keine Nüsse gesammelt :(`
|
||||||
|
} else {
|
||||||
|
content = `${addressing} bereits **${nutsData.nuts}** Nüsse gesammelt!`
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Checknuts!')
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
.setDescription(content)
|
||||||
|
|
||||||
|
return message.reply({
|
||||||
|
embeds: [embed]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
const { EmbedBuilder } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'nutsCooldown',
|
||||||
|
description: 'shows nut cooldown',
|
||||||
|
aliases: ['ncd'],
|
||||||
|
async execute(message, args) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_cooldowns')
|
||||||
|
const cooldown = await nutsColl.findOne({ userID: message.author.id })
|
||||||
|
|
||||||
|
let content = `Du kannst wieder nussen! :)`
|
||||||
|
let thumbnail = 'https://cdn-icons-png.flaticon.com/512/7451/7451659.png'
|
||||||
|
let title = 'Go Nuts!'
|
||||||
|
if (cooldown) {
|
||||||
|
content = `<t:${cooldown.cooldown}:R> kannst du wieder nussen! ;)`
|
||||||
|
thumbnail = 'https://cdn.discordapp.com/attachments/1152723542836772914/1152987472788193361/No-nuts-PhotoRoom.png-PhotoRoom.png'
|
||||||
|
title = 'To Nut or Not to Nut...'
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(thumbnail)
|
||||||
|
.setTitle(title)
|
||||||
|
.setDescription(content)
|
||||||
|
|
||||||
|
await message.reply({
|
||||||
|
embeds: [embed]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'nuts',
|
||||||
|
description: 'get nuts',
|
||||||
|
aliases: ['n', 'nget', 'nutsget'],
|
||||||
|
async execute(message, args) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const nutsStatsColl = db.collection('stats_nuts')
|
||||||
|
const cdColl = db.collection('items_cooldowns')
|
||||||
|
const cdData = await cdColl.findOne({ userID: message.author.id })
|
||||||
|
|
||||||
|
if (cdData?.cooldown > (Date.now() / 1000)) {
|
||||||
|
return await message.reply({
|
||||||
|
content: `Du kannst erst <t:${Math.floor(cdData?.cooldown)}:R> wieder nussen :(`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let cd = Math.floor((Date.now() + 3600000) / 1000)
|
||||||
|
await cdColl.findOneAndUpdate({
|
||||||
|
userID: message.author.id
|
||||||
|
}, {
|
||||||
|
$set: {
|
||||||
|
cooldown: cd,
|
||||||
|
application: 'nuts'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const amount = Math.floor(Math.random() * 10)
|
||||||
|
|
||||||
|
await nutsColl.findOneAndUpdate({
|
||||||
|
userID: message.author.id
|
||||||
|
}, {
|
||||||
|
$inc: { nuts: amount }
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
await nutsStatsColl.findOneAndUpdate(
|
||||||
|
{ userID: message.author.id },
|
||||||
|
{ $inc: { [`stat.${amount}`]: 1 } },
|
||||||
|
{ upsert: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
await nutsStatsColl.findOneAndUpdate(
|
||||||
|
{ userID: "__global" },
|
||||||
|
{ $inc: { [`stat.${amount}`]: 1 } },
|
||||||
|
{ upsert: true }
|
||||||
|
)
|
||||||
|
let content = `Du hast ${amount} Nüsse bekommen! :chestnut:`
|
||||||
|
if (!amount) {
|
||||||
|
content = `Du hast leider keine Nüsse bekommen :(`
|
||||||
|
}
|
||||||
|
return await message.reply({
|
||||||
|
content: content
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
const { EmbedBuilder } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'givenuts',
|
||||||
|
description: 'give nuts',
|
||||||
|
aliases: ['gn'],
|
||||||
|
async execute(message, args) {
|
||||||
|
const from = message.author
|
||||||
|
if (args[0] == `<@${message.author.id}>` || !args[0]) {
|
||||||
|
return message.reply({
|
||||||
|
content: "Du musst einen anderen User erwähnen"
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await delay(4000)
|
||||||
|
message.delete()
|
||||||
|
msg.delete()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (!args[0].startsWith('<@' || !args[0].endsWith('>'))) { return message.reply('Invalid User Specification') }
|
||||||
|
try {
|
||||||
|
target = await message.guild.members.fetch(args[0].slice(2, -1))
|
||||||
|
} catch (error) {
|
||||||
|
return message.reply({
|
||||||
|
content: `User: ${args[0]} nicht gefunden!`
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await delay(4000)
|
||||||
|
message.delete()
|
||||||
|
msg.delete()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const to = target
|
||||||
|
|
||||||
|
try {
|
||||||
|
var amount = Number(args[1])
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
return message.reply({
|
||||||
|
content: 'Du musst eine Menge angeben!'
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await delay(4000)
|
||||||
|
message.delete()
|
||||||
|
msg.delete()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (!amount) {
|
||||||
|
return message.reply({content : 'Danke für nichts, du Hu-'})
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const yourBalance = await nutsColl.findOne({ userID: from.id })
|
||||||
|
if (amount <= 0) {
|
||||||
|
return await message.reply({
|
||||||
|
content: `Hier wird nicht geklaut >:(\r\nDas gibt **${yourBalance.nuts}** Abzug!`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (yourBalance.nuts < amount) {
|
||||||
|
return await message.reply({
|
||||||
|
content: 'Du kannst nicht mehr geben als du hast!',
|
||||||
|
ephemeral: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var content = `Du sendest **${amount}** Nüsse an <@${target.id}>`
|
||||||
|
|
||||||
|
if (amount == 1) {
|
||||||
|
content = `Du sendest **eine** Nuss an <@${target.id}>`
|
||||||
|
}
|
||||||
|
await nutsColl.findOneAndUpdate({ userID: from.id }, { $inc: { nuts: -amount } }, { upsert: true })
|
||||||
|
await nutsColl.findOneAndUpdate({ userID: to.id }, { $inc: { nuts: +amount } }, { upsert: true })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Gib Nuss!')
|
||||||
|
.setDescription(content)
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
return message.reply({ embeds: [embed] })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
require('dotenv').config()
|
||||||
|
module.exports = {
|
||||||
|
name: 'nutsleaderboard',
|
||||||
|
description: 'show nuts leaderboard',
|
||||||
|
aliases: ['nl', 'tn', 'topnuts'],
|
||||||
|
async execute(message, args) {
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('◄')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_left')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('🧑')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_self')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('►')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_right')
|
||||||
|
)
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
let skip = 0
|
||||||
|
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
let placements = skip + 1
|
||||||
|
nutsData.forEach((data) => {
|
||||||
|
fields = (fields ? fields : '') + (`${placements}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Nuts Leaderboard')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await message.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
const { EmbedBuilder, MessageFlags } = require("discord.js")
|
||||||
|
const { client, mClient } = require("../../../index")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotesadd',
|
||||||
|
description: 'adds a quote to the database by replying to the message',
|
||||||
|
category: 'Quotes',
|
||||||
|
aliases: ['qadd', 'qa'],
|
||||||
|
async execute(message, args) {
|
||||||
|
const refMessage = message.reference // message to be quoted has been replied to
|
||||||
|
const refMessageId = refMessage.messageId
|
||||||
|
const refChannelId = refMessage.channelId
|
||||||
|
const refGuildId = refMessage.guildId
|
||||||
|
var msgData = {}
|
||||||
|
var refData = {}
|
||||||
|
const quoteGuild = await client.guilds.fetch(refGuildId)
|
||||||
|
const quoteChannel = await quoteGuild.channels.fetch(refChannelId)
|
||||||
|
const quoteMessage = await quoteChannel.messages.fetch(refMessageId)
|
||||||
|
|
||||||
|
msgData = {
|
||||||
|
content: quoteMessage.content,
|
||||||
|
author: await quoteMessage.author,
|
||||||
|
reference: await quoteMessage.reference,
|
||||||
|
embed: await quoteMessage.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
if (msgData.reference) {
|
||||||
|
const quoteRefGuild = await client.guilds.fetch(msgData.reference.guildId)
|
||||||
|
const quoteRefChannel = await quoteRefGuild.channels.fetch(msgData.reference.channelId)
|
||||||
|
const quoteRefMessage = await quoteRefChannel.messages.fetch(msgData.reference.messageId)
|
||||||
|
|
||||||
|
|
||||||
|
refData = {
|
||||||
|
content: quoteRefMessage.content,
|
||||||
|
author: await quoteRefMessage.author,
|
||||||
|
embed: await quoteRefMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const found = await quotesColl.findOne({ messageID: quoteMessage.id })
|
||||||
|
if (found) { return await message.reply({ content: 'Quote Already in Database', flags: MessageFlags.Ephemeral }) }
|
||||||
|
await quotesColl.findOneAndUpdate({ messageID: quoteMessage.id }, {
|
||||||
|
$set: {
|
||||||
|
messageID: quoteMessage.id,
|
||||||
|
channelID: quoteChannel.id,
|
||||||
|
guildID: quoteGuild.id,
|
||||||
|
userID: msgData.author.id,
|
||||||
|
count: 0
|
||||||
|
}
|
||||||
|
}, { upsert: true })
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
const messageLink = `https://discord.com/channels/${quoteGuild.id}/${quoteChannel.id}/${quoteMessage.id}/`
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote Added! -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (footer + ' #' + quoteMessage.id) })
|
||||||
|
await message.reply({ embeds: [embed] })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder, MessageFlags } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
const { configDotenv } = require('dotenv')
|
||||||
|
configDotenv()
|
||||||
|
|
||||||
|
function isValidDate(day, month) {
|
||||||
|
// Define the number of days in each month
|
||||||
|
const daysInMonth = {
|
||||||
|
1: 31, // January
|
||||||
|
2: 28, // February (fuck leap years, me an' the homies hate that)
|
||||||
|
3: 31, // March
|
||||||
|
4: 30, // April
|
||||||
|
5: 31, // May
|
||||||
|
6: 30, // June
|
||||||
|
7: 31, // July
|
||||||
|
8: 31, // August
|
||||||
|
9: 30, // September
|
||||||
|
10: 31, // October
|
||||||
|
11: 30, // November
|
||||||
|
12: 31 // December
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if month is valid
|
||||||
|
if (month < 1 || month > 12) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if day is valid for the given month
|
||||||
|
if (day < 1 || day > daysInMonth[month]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function getNextBirthdayTimestamp(day, month) {
|
||||||
|
const now = new Date();
|
||||||
|
now.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const currentYear = now.getFullYear();
|
||||||
|
|
||||||
|
let nextBirthday = new Date(currentYear, month - 1, day);
|
||||||
|
|
||||||
|
// If birthday already passed this year → next year
|
||||||
|
if (nextBirthday < now) {
|
||||||
|
nextBirthday.setFullYear(currentYear + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.floor(nextBirthday.getTime() / 1000); // Unix timestamp
|
||||||
|
}
|
||||||
|
async function birthdaySet(interaction) {
|
||||||
|
let target = await interaction.options.getUser('user')
|
||||||
|
let day = await interaction.options.getNumber('day')
|
||||||
|
let month = await interaction.options.getNumber('month')
|
||||||
|
|
||||||
|
|
||||||
|
if (!isValidDate(day, month)) {
|
||||||
|
return interaction.reply({ content: "Invalid Date", flags: MessageFlags.Ephemeral })
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const bdayColl = db.collection('items_birthdays')
|
||||||
|
|
||||||
|
const found = await bdayColl.findOne({ userID: target.id })
|
||||||
|
if (found) {
|
||||||
|
return interaction.reply({ content: "Already in Database", flags: MessageFlags.Ephemeral })
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
guildID: interaction.guild.id,
|
||||||
|
userID: target.id,
|
||||||
|
day: day,
|
||||||
|
month: month
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await bdayColl.insertOne(data)
|
||||||
|
if (res.acknowledged) {
|
||||||
|
return interaction.reply({ content: "Birthday added successfully!" })
|
||||||
|
} else {
|
||||||
|
return interaction.reply({ content: "There was an issue!" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function birthdayDelete(interaction) {
|
||||||
|
var target = await interaction.options.getUser('user')
|
||||||
|
const guild = await interaction.client.guilds.cache.get(interaction.guild.id)
|
||||||
|
if (!target) {
|
||||||
|
target = await guild.members.cache.get(await interaction.options.getString('id'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
return interaction.reply({ content: "Invalid or No User specified!" })
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const bdayColl = db.collection('items_birthdays')
|
||||||
|
|
||||||
|
const found = await bdayColl.findOne({ userID: target.id })
|
||||||
|
if (!found) {
|
||||||
|
return interaction.reply({ content: "Not yet in Database", flags: MessageFlags.Ephemeral })
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await bdayColl.deleteOne({ userID: target.id })
|
||||||
|
if (res.acknowledged) {
|
||||||
|
return interaction.reply({ content: "Birthday removed successfully!" })
|
||||||
|
} else {
|
||||||
|
return interaction.reply({ content: "There was an issue!" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function birthdayGet(interaction) {
|
||||||
|
const target = await interaction.options.getUser('user');
|
||||||
|
const db = mClient.db(process.env.M_DB);
|
||||||
|
const bdayColl = db.collection('items_birthdays');
|
||||||
|
|
||||||
|
const found = await bdayColl.findOne({ userID: target.id });
|
||||||
|
if (!found) {
|
||||||
|
return interaction.reply({
|
||||||
|
content: "Date not in Database!",
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const isToday =
|
||||||
|
now.getDate() === found.day &&
|
||||||
|
now.getMonth() === (found.month - 1);
|
||||||
|
|
||||||
|
let description;
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
description = `IS TODAY! 🥳🎉`;
|
||||||
|
} else {
|
||||||
|
const unix = getNextBirthdayTimestamp(found.day, found.month);
|
||||||
|
description = `is on the <t:${unix}:d>\n<t:${unix}:R>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
.setTitle(`${target.globalName ?? target.username}'s Birthday...`)
|
||||||
|
.setDescription(description);
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('birthday')
|
||||||
|
.setDescription('manage birthdays')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('set')
|
||||||
|
.setDescription('set date to birthday')
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('user')
|
||||||
|
.setDescription('user')
|
||||||
|
.setRequired(true))
|
||||||
|
.addNumberOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('day')
|
||||||
|
.setDescription('day')
|
||||||
|
.setMinValue(1)
|
||||||
|
.setMaxValue(31)
|
||||||
|
.setRequired(true))
|
||||||
|
.addNumberOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('month')
|
||||||
|
.setDescription('month')
|
||||||
|
.setMinValue(1)
|
||||||
|
.setMaxValue(12)
|
||||||
|
.setRequired(true))
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('delete')
|
||||||
|
.setDescription('deletes a birthday')
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option.setName('user').setDescription('user'))
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName('id').setDescription('ID')))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('get')
|
||||||
|
.setDescription('gets a birthday')
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option.setName('user').setDescription('user').setRequired(true))),
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'set':
|
||||||
|
if (!interaction.member.permissions.has("ADMINISTRATOR")) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: "Unprivileged Access!",
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
birthdaySet(interaction)
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
if (!interaction.member.permissions.has("ADMINISTRATOR")) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: "Unprivileged Access!",
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
birthdayDelete(interaction)
|
||||||
|
break;
|
||||||
|
case 'get':
|
||||||
|
birthdayGet(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
const { SlashCommandBuilder, Events, MessageFlags } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
async function channelSet(interaction) {
|
||||||
|
const channel = interaction.options.getChannel('channel')
|
||||||
|
const purpose = interaction.options.getString('purpose')
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const channelColl = db.collection('config_channels')
|
||||||
|
|
||||||
|
await channelColl.findOneAndUpdate({
|
||||||
|
$and: [{ guildID: channel.guild.id }, { purpose: purpose }]
|
||||||
|
}, {
|
||||||
|
$set: {
|
||||||
|
guildID: channel.guild.id,
|
||||||
|
purpose: purpose,
|
||||||
|
channelID: channel.id
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
return await interaction.editReply({
|
||||||
|
content: `Set <#${channel.id}> as ${purpose} channel!`, flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function channelSimulate(interaction) {
|
||||||
|
const purpose = interaction.options.getString('purpose')
|
||||||
|
switch (purpose) {
|
||||||
|
case 'birthday':
|
||||||
|
await interaction.client.emit('Birthday', interaction.member)
|
||||||
|
break;
|
||||||
|
case 'wge':
|
||||||
|
// For Future WGE Use
|
||||||
|
break;
|
||||||
|
case 'welcome':
|
||||||
|
await interaction.client.emit(Events.GuildMemberAdd, interaction.member)
|
||||||
|
break;
|
||||||
|
case 'logs':
|
||||||
|
// For Future Log Use
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return interaction.reply({ content: 'Done.', flags: MessageFlags.Ephemeral })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function roleSet(interaction) {
|
||||||
|
const guild = interaction.guild
|
||||||
|
const purpose = interaction.options.getString('purpose')
|
||||||
|
const role = interaction.options.getRole('role')
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const roleColl = db.collection('config_roles')
|
||||||
|
|
||||||
|
switch (purpose) {
|
||||||
|
case 'birthday':
|
||||||
|
await roleColl.findOneAndUpdate({
|
||||||
|
$and: [{ guildID: guild.id }, { purpose: purpose }]
|
||||||
|
}, {
|
||||||
|
$set: {
|
||||||
|
guildID: guild.id,
|
||||||
|
purpose: purpose,
|
||||||
|
roleID: role.id
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await interaction.editReply({
|
||||||
|
content: `Set ${role} as default role for ${purpose} in ${guild} `
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('config')
|
||||||
|
.setDescription('configurations for admins')
|
||||||
|
.addSubcommandGroup(sg =>
|
||||||
|
sg
|
||||||
|
.setName('channels')
|
||||||
|
.setDescription('configure channels for certain events')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('set')
|
||||||
|
.setDescription('sets channel')
|
||||||
|
.addStringOption(o =>
|
||||||
|
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
|
||||||
|
name: 'birthday',
|
||||||
|
value: 'birthday'
|
||||||
|
}, {
|
||||||
|
name: 'welcome',
|
||||||
|
value: 'welcome'
|
||||||
|
}, {
|
||||||
|
name: 'logs',
|
||||||
|
value: 'logs'
|
||||||
|
}, {
|
||||||
|
name: 'wge',
|
||||||
|
value: 'wge'
|
||||||
|
}))
|
||||||
|
.addChannelOption(c =>
|
||||||
|
c.setName('channel').setDescription('choose a channel').setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('simulate')
|
||||||
|
.setDescription('simulate a specific channel event')
|
||||||
|
.addStringOption(o =>
|
||||||
|
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
|
||||||
|
name: 'birthday',
|
||||||
|
value: 'birthday'
|
||||||
|
}, {
|
||||||
|
name: 'welcome',
|
||||||
|
value: 'welcome'
|
||||||
|
}, {
|
||||||
|
name: 'logs',
|
||||||
|
value: 'logs'
|
||||||
|
}, {
|
||||||
|
name: 'wge',
|
||||||
|
value: 'wge'
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommandGroup(sg =>
|
||||||
|
sg.setName('roles')
|
||||||
|
.setDescription('configure roles for certain events')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('set')
|
||||||
|
.setDescription('sets roles')
|
||||||
|
.addStringOption(o =>
|
||||||
|
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
|
||||||
|
name: 'birthday',
|
||||||
|
value: 'birthday'
|
||||||
|
}))
|
||||||
|
.addRoleOption(c =>
|
||||||
|
c.setName('role').setDescription('choose a role').setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options._group) {
|
||||||
|
case 'channels':
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'set':
|
||||||
|
await interaction.deferReply()
|
||||||
|
channelSet(interaction)
|
||||||
|
break;
|
||||||
|
case 'simulate':
|
||||||
|
channelSimulate(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'roles':
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'set':
|
||||||
|
await interaction.deferReply()
|
||||||
|
roleSet(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
const { SlashCommandBuilder } = require("discord.js");
|
||||||
|
const ping = require("../../../src/ping");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('ping')
|
||||||
|
.setDescription('dev tool'),
|
||||||
|
async execute(interaction) {
|
||||||
|
return ping(interaction, null, 'slash')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder, MessageFlags } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
|
||||||
|
async function honorHoner(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
|
||||||
|
const target = await interaction.options.getUser('target')
|
||||||
|
const reason = `[+] ${await interaction.options.getString('reason') ?? 'No reason provided'}`
|
||||||
|
|
||||||
|
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Up! -')
|
||||||
|
.setDescription(`Willst du wirklich <@${target.id}> einen **Honor** geben?\r\n[Grund: ${reason}]`)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level', value: `${theirHonorLevel?.honors ?? 0} (**+1**)`
|
||||||
|
})
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✔')
|
||||||
|
.setCustomId('honor_multi_confirm')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✖')
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function honerDishonor(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
|
||||||
|
const target = await interaction.options.getUser('target')
|
||||||
|
const reason = `[-] ${await interaction.options.getString('reason') ?? 'No reason provided'}`
|
||||||
|
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Down! -')
|
||||||
|
.setDescription(`Willst du wirklich <@${target.id}> einen **Dishonor** geben?\r\n[Grund: ${reason}]`)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level', value: `${theirHonorLevel?.honors ?? 0} (**-1**)`
|
||||||
|
})
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✔')
|
||||||
|
.setCustomId('honor_multi_confirm')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✖')
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function honorLeaderboard(interaction) {
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('◄')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('honors_leaderboard_left')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('🧑')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('honors_leaderboard_self')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('►')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('honors_leaderboard_right')
|
||||||
|
)
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
let skip = 0
|
||||||
|
const honorsData = await honorsColl.find({}).sort({ honors: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
let fields
|
||||||
|
let placements = skip + 1
|
||||||
|
honorsData.forEach((data) => {
|
||||||
|
fields = (fields ? fields : '') + (`${placements}. <@${data.userID}> : ${data.honors} Honors\r\n`)
|
||||||
|
})
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honors Leaderboard -')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true}))
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2') // Discord's blurple color
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' });
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function honorHistory(interaction) {
|
||||||
|
var target = interaction.options.getUser('target')
|
||||||
|
if (!target) { target = interaction.user }
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const reasonsColl = db.collection('history_honors')
|
||||||
|
var history = await reasonsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor History -')
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
|
||||||
|
if (history) {
|
||||||
|
let temp = ''
|
||||||
|
history.reasons.forEach(reason => {
|
||||||
|
temp += reason + '\r\n'
|
||||||
|
})
|
||||||
|
embed.setDescription(temp)
|
||||||
|
}
|
||||||
|
await interaction.editReply({ embeds: [embed] })
|
||||||
|
}
|
||||||
|
async function honorCheck(interaction) {
|
||||||
|
var target = interaction.options.getUser('target')
|
||||||
|
if (!target) { target = interaction.user }
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const honorsColl = db.collection('items_honors')
|
||||||
|
var honors = await honorsColl.findOne({ userID: target.id })
|
||||||
|
honors = honors?.honors ?? 0
|
||||||
|
|
||||||
|
if (!honors) {
|
||||||
|
content = 'Choose a goddamn side!'
|
||||||
|
} else {
|
||||||
|
if (honors === -20) {
|
||||||
|
content = 'They are is at max Dishonor Level! <:lowhonor:748176295132790786> <:lowhonor:748176295132790786> <:lowhonor:748176295132790786>\n```' + `You don't get to live a bad life and have good things happen to you. - Arthur M.` + '```'
|
||||||
|
} else if (honors === 20) {
|
||||||
|
content = 'They are at max Honor Level! <:highhonor:748176295535443968> <:highhonor:748176295535443968> <:highhonor:748176295535443968>'
|
||||||
|
} else if (honors > 0) {
|
||||||
|
content = 'real good, boah, REAL GOOD! <:highhonor:748176295535443968>'
|
||||||
|
} else if (honors < 0) {
|
||||||
|
content = 'What happened to Loyalty?! <:lowhonor:748176295132790786>'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Check -')
|
||||||
|
.setDescription(`${target} has an Honor Level of **${honors}**!`)
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
.addFields({ name: '\u200B', value: `*${content}*` })
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function honorMenu(interaction) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Honor Menu! -')
|
||||||
|
.setDescription('- Choose someone from the Select Menu below\r\n- Choose Honor Dishonor, or History\r\n- Confirm your Selection')
|
||||||
|
.setThumbnail(interaction.guild.iconURL())
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`<:honorhigh:748176295535443968>`)
|
||||||
|
.setCustomId('honor_menu_honor')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`<:honorlow:748176295132790786>`)
|
||||||
|
.setCustomId('honor_menu_dishonor')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`❌`)
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji('📜')
|
||||||
|
.setCustomId('honor_menu_history')
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
)
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('honor_menu_mentionable')
|
||||||
|
.setPlaceholder('Select a User')
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('honors')
|
||||||
|
.setDescription('rund um den honor')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('honor')
|
||||||
|
.setDescription('honor someone')
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('wer wird gehonored?').setRequired(true))
|
||||||
|
.addStringOption(o => o.setName('reason').setDescription('reason?'))
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('dishonor')
|
||||||
|
.setDescription('dishonor someone')
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('wer wird gehonored?').setRequired(true))
|
||||||
|
.addStringOption(o => o.setName('reason').setDescription('reason?'))
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('check')
|
||||||
|
.setDescription("check someone's honor level")
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('wer wird gehonored?'))
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('history')
|
||||||
|
.setDescription("check someone's honor history")
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('von wem?'))
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('leaderboard')
|
||||||
|
.setDescription("check who's got the most honor")
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('menu')
|
||||||
|
.setDescription('WIP universal honor menu'))
|
||||||
|
,
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'honor':
|
||||||
|
honorHoner(interaction)
|
||||||
|
break;
|
||||||
|
case 'dishonor':
|
||||||
|
honerDishonor(interaction)
|
||||||
|
break;
|
||||||
|
case 'leaderboard':
|
||||||
|
await interaction.deferReply()
|
||||||
|
honorLeaderboard(interaction)
|
||||||
|
break;
|
||||||
|
case 'history':
|
||||||
|
await interaction.deferReply()
|
||||||
|
honorHistory(interaction)
|
||||||
|
break;
|
||||||
|
case 'check':
|
||||||
|
await interaction.deferReply()
|
||||||
|
honorCheck(interaction)
|
||||||
|
break;
|
||||||
|
case 'menu':
|
||||||
|
honorMenu(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags, AttachmentBuilder } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
|
||||||
|
const asset_path = './assets/Command_Nuts/'
|
||||||
|
|
||||||
|
async function nutsGive(interaction) {
|
||||||
|
async function tradeWindow(buttonID1, buttonID2) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Gib Nuss!')
|
||||||
|
.setDescription(`Willst du wirklich **${amount}** Nüsse an <@${to.id}> senden?`)
|
||||||
|
.addFields(
|
||||||
|
{ name: `Your Current Balance`, value: `${yourBalance.nuts} (**-${amount}**)`, inline: true },
|
||||||
|
{ name: `Your New Balance`, value: `${yourBalance.nuts - amount}`, inline: true },
|
||||||
|
{ name: '\u200B', value: '\u200B' },
|
||||||
|
{ name: `Their Current Balance`, value: `${theirBalance.nuts} (**+${amount}**)`, inline: true },
|
||||||
|
{ name: `Their New Balance`, value: `${theirBalance.nuts + amount}`, inline: true }
|
||||||
|
)
|
||||||
|
.setThumbnail('attachment://nuts_main.png')
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✔')
|
||||||
|
.setCustomId(buttonID1)
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('✖')
|
||||||
|
.setCustomId(buttonID2)
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
)
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const from = interaction.user
|
||||||
|
const to = await interaction.options.getUser('target')
|
||||||
|
var amount = await interaction.options.getNumber('amount')
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const yourBalance = await nutsColl.findOne({ userID: from.id })
|
||||||
|
const theirBalance = await nutsColl.findOne({ userID: to.id })
|
||||||
|
|
||||||
|
if (amount <= 0) {
|
||||||
|
amount = yourBalance.nuts
|
||||||
|
return tradeWindow('nuts_give_fake', 'abort')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yourBalance.nuts < amount) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: 'Du kannst nicht mehr geben als du hast!',
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return tradeWindow('nuts_give_confirm', 'abort')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nutsCheck(interaction) {
|
||||||
|
let target = interaction.options.getUser('target')
|
||||||
|
let addressing
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
target = interaction.user
|
||||||
|
addressing = `Du hast`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.globalName) {
|
||||||
|
addressing = `${target.username} hat`
|
||||||
|
} else {
|
||||||
|
addressing = `${target.globalName} hat`
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const nutsData = await nutsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
let content
|
||||||
|
if (!nutsData) {
|
||||||
|
content = `${addressing} noch keine Nüsse gesammelt :(`
|
||||||
|
} else {
|
||||||
|
content = `${addressing} bereits **${nutsData.nuts}** Nüsse gesammelt!`
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = 'Zähle Nüsse'
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
embed.setTitle(title)
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed]
|
||||||
|
})
|
||||||
|
title = title + ' .'
|
||||||
|
await delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
embed
|
||||||
|
.setTitle(content)
|
||||||
|
.setThumbnail('attachment://nuts_main.png')
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}nuts_main.png`]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nutsLeaderboard(interaction) {
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('◄')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_left')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('🧑')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_self')
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('►')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('nuts_leaderboard_right')
|
||||||
|
)
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
let skip = 0
|
||||||
|
|
||||||
|
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
|
||||||
|
|
||||||
|
let fields
|
||||||
|
let placements = skip + 1
|
||||||
|
|
||||||
|
nutsData.forEach((data) => {
|
||||||
|
fields = (fields ? fields : '') + (`${placements}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
|
||||||
|
placements++
|
||||||
|
})
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Nuts Leaderboard')
|
||||||
|
.setThumbnail('attachment://nuts_main.png')
|
||||||
|
.setDescription(fields.toString())
|
||||||
|
.setColor('#5865F2')
|
||||||
|
.setFooter({ text: 'Use ◄ ► to navigate' })
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [row],
|
||||||
|
files: [`${asset_path}nuts_main.png`]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nutsStats(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB);
|
||||||
|
const nStatsColl = db.collection('stats_nuts');
|
||||||
|
var type = interaction?.options?.getString('type') || 'lookup'
|
||||||
|
var target = interaction?.options?.getUser('lookup') || {}
|
||||||
|
|
||||||
|
if (type == 'global') {
|
||||||
|
target.id = '__global'
|
||||||
|
} else if (!target?.id) {
|
||||||
|
target = interaction.user
|
||||||
|
}
|
||||||
|
|
||||||
|
const statsDoc = await nStatsColl.findOne({ userID: target.id });
|
||||||
|
const stat = statsDoc?.stat || {};
|
||||||
|
|
||||||
|
const totalCount = Object.values(stat).reduce((a, b) => a + b, 0);
|
||||||
|
const totalNuts = Object.entries(stat).reduce(
|
||||||
|
(sum, [num, count]) => sum + Number(num) * count,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
const rolledNumbers = Object.entries(stat).filter(([_, count]) => count > 0);
|
||||||
|
|
||||||
|
let nutMin = { number: 0, count: 0 };
|
||||||
|
let nutMax = { number: 0, count: 0 };
|
||||||
|
|
||||||
|
if (rolledNumbers.length > 0) {
|
||||||
|
nutMin = nutMax = { number: Number(rolledNumbers[0][0]), count: rolledNumbers[0][1] };
|
||||||
|
|
||||||
|
for (const [numStr, count] of rolledNumbers) {
|
||||||
|
const num = Number(numStr);
|
||||||
|
|
||||||
|
if (count > nutMax.count || (count === nutMax.count && num > nutMax.number)) {
|
||||||
|
nutMax = { number: num, count };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < nutMin.count || (count === nutMin.count && num < nutMin.number)) {
|
||||||
|
nutMin = { number: num, count };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nutAvg = totalCount ? totalNuts / totalCount : 0;
|
||||||
|
|
||||||
|
const fields = Array.from({ length: 11 }, (_, i) => ({
|
||||||
|
name: `[${i}]`,
|
||||||
|
value: `x${stat[i] ?? 0}`,
|
||||||
|
inline: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("Nut Statistic")
|
||||||
|
.setDescription(
|
||||||
|
`Total Nut Actions: **${totalCount}**\r\n` +
|
||||||
|
`Total Nuts nutted: **${totalNuts}**\r\n` +
|
||||||
|
`Nut Average: **${nutAvg.toFixed(3)}**\r\n` +
|
||||||
|
`Most Common Nut: **${nutMax.number} (x${nutMax.count})**\r\n` +
|
||||||
|
`Least Common Nut: **${nutMin.number} (x${nutMin.count})**`
|
||||||
|
)
|
||||||
|
.addFields(fields)
|
||||||
|
.setColor(0x51267)
|
||||||
|
.setTimestamp()
|
||||||
|
.setThumbnail('attachment://nuts_main.png')
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}nuts_main.png`]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nutsCooldown(interaction) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_cooldowns')
|
||||||
|
const cooldown = await nutsColl.findOne({ userID: interaction.user.id })
|
||||||
|
|
||||||
|
let content = `Du kannst wieder nussen! :)`
|
||||||
|
let thumbnail = 'attachment://nuts_main.png'
|
||||||
|
let file = `${asset_path}nuts_main.png`
|
||||||
|
let title = 'Go Nuts!'
|
||||||
|
|
||||||
|
let date = (Date.now() / 1000)
|
||||||
|
if (cooldown.cooldown > date) {
|
||||||
|
content = `<t:${cooldown.cooldown}:R> kannst du wieder nussen! ;)`
|
||||||
|
thumbnail = 'attachment://nuts_onCD.avif'
|
||||||
|
file = `${asset_path}nuts_onCD.avif`
|
||||||
|
title = 'To Nut or Not to Nut...'
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(thumbnail)
|
||||||
|
.setTitle(title)
|
||||||
|
.setDescription(content)
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [file]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nutsNut(interaction, quickMode) {
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const nutsColl = db.collection('items_nuts')
|
||||||
|
const cdColl = db.collection('items_cooldowns')
|
||||||
|
const nutsStatsColl = db.collection('stats_nuts')
|
||||||
|
|
||||||
|
const cdData = await cdColl.findOne({ userID: interaction.user.id })
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
|
||||||
|
const assets = {
|
||||||
|
high: 'attachment://nuts_high.jpg',
|
||||||
|
normal: 'attachment://nuts_normal.jpg',
|
||||||
|
low: 'attachment://nuts_low.jpg',
|
||||||
|
none: 'attachment://nuts_none.avif',
|
||||||
|
onCD: 'attachment://nuts_onCD.avif',
|
||||||
|
box: 'attachment://nuts_box.png',
|
||||||
|
explosion: 'attachment://nuts_explosion.gif'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for singular/plural
|
||||||
|
const formatNut = (amount) => `${amount} ${amount === 1 ? 'Nuss' : 'Nüsse'}`
|
||||||
|
|
||||||
|
// check cooldown
|
||||||
|
if (cdData?.cooldown > Date.now() / 1000) {
|
||||||
|
// on cooldown
|
||||||
|
embed.setTitle('To Nut or Not to Nut...')
|
||||||
|
embed.setDescription(`<t:${Math.floor(cdData.cooldown)}:R> kannst du wieder nussen! ;)`)
|
||||||
|
embed.setThumbnail(assets.onCD)
|
||||||
|
|
||||||
|
return interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}nuts_onCD.avif`]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// set 1 hour cooldown
|
||||||
|
const cd = Math.floor((Date.now() + 3600000) / 1000)
|
||||||
|
await cdColl.findOneAndUpdate({
|
||||||
|
userID: interaction.user.id
|
||||||
|
}, {
|
||||||
|
$set: {
|
||||||
|
cooldown: cd,
|
||||||
|
application: 'nuts'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// generate nut amount
|
||||||
|
const amount = Math.floor(Math.random() * 10)
|
||||||
|
|
||||||
|
// update nuts and stats
|
||||||
|
await nutsColl.findOneAndUpdate(
|
||||||
|
{ userID: interaction.user.id },
|
||||||
|
{ $inc: { nuts: amount } },
|
||||||
|
{ upsert: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
await nutsStatsColl.findOneAndUpdate(
|
||||||
|
{ userID: interaction.user.id },
|
||||||
|
{ $inc: { [`stat.${amount}`]: 1 } },
|
||||||
|
{ upsert: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
await nutsStatsColl.findOneAndUpdate(
|
||||||
|
{ userID: "__global" },
|
||||||
|
{ $inc: { [`stat.${amount}`]: 1 } },
|
||||||
|
{ upsert: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if (quickMode) {
|
||||||
|
return interaction.editReply({ content: `Du hast ${formatNut(amount)} bekommen! :chestnut:` })
|
||||||
|
}
|
||||||
|
|
||||||
|
// pseudo animation
|
||||||
|
embed.setImage(assets.box)
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}nuts_box.png`]
|
||||||
|
})
|
||||||
|
await delay(1337)
|
||||||
|
embed.setImage(assets.explosion)
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}nuts_explosion.gif`]
|
||||||
|
})
|
||||||
|
await delay(1337)
|
||||||
|
|
||||||
|
let assetFile
|
||||||
|
if (amount === 0) assetFile = assets.none
|
||||||
|
else if (amount > 8) assetFile = assets.high
|
||||||
|
else if (amount > 4) assetFile = assets.normal
|
||||||
|
else assetFile = assets.low
|
||||||
|
|
||||||
|
embed.setTitle(`Du hast ${formatNut(amount)} bekommen!`)
|
||||||
|
embed.setThumbnail(assetFile)
|
||||||
|
embed.setImage(null)
|
||||||
|
|
||||||
|
return interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [`${asset_path}${assetFile.split('://')[1]}`]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('nuts')
|
||||||
|
.setDescription('rund um die nuss')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('give')
|
||||||
|
.setDescription('gib nuss!!')
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('wer bekommt da nuts?').setRequired(true))
|
||||||
|
.addNumberOption(o => o.setName('amount').setDescription('wie viele?').setRequired(true)))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('check')
|
||||||
|
.setDescription('check out deez nuts')
|
||||||
|
.addUserOption(o => o.setName('target').setDescription('check out those nuts!')))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('leaderboard')
|
||||||
|
.setDescription('wer hat die dicksten Nüsse?'))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('stats')
|
||||||
|
.setDescription('wie viele Nüsse wurden genusst, Genosse?')
|
||||||
|
.addStringOption(o =>
|
||||||
|
o.setName('type')
|
||||||
|
.setDescription('set type to global or user')
|
||||||
|
.addChoices(
|
||||||
|
{ name: 'global', value: 'global' },
|
||||||
|
{ name: 'user', value: 'user' }
|
||||||
|
),)
|
||||||
|
.addUserOption(o =>
|
||||||
|
o.setName('lookup')
|
||||||
|
.setDescription('look up specific user nut statistic')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('cooldown')
|
||||||
|
.setDescription('wie lange bis ich nussen kann?'))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('nut')
|
||||||
|
.setDescription('willst du nuss?'))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('quick')
|
||||||
|
.setDescription('A quick nut, mlord?')
|
||||||
|
|
||||||
|
),
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'give':
|
||||||
|
nutsGive(interaction)
|
||||||
|
break;
|
||||||
|
case 'check':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsCheck(interaction)
|
||||||
|
break;
|
||||||
|
case 'leaderboard':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsLeaderboard(interaction)
|
||||||
|
break;
|
||||||
|
case 'stats':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsStats(interaction)
|
||||||
|
break;
|
||||||
|
case 'cooldown':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsCooldown(interaction)
|
||||||
|
break;
|
||||||
|
case 'nut':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsNut(interaction, false)
|
||||||
|
break;
|
||||||
|
case 'quick':
|
||||||
|
await interaction.deferReply()
|
||||||
|
nutsNut(interaction, true)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
/*
|
||||||
|
Random By Year?
|
||||||
|
Counter (Leaderboard)
|
||||||
|
*/
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder, MessageFlags } = require('discord.js')
|
||||||
|
const { mClient } = require('../../../index')
|
||||||
|
require('dotenv').config()
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
|
||||||
|
async function quotesAdd(interaction) {
|
||||||
|
|
||||||
|
const messageLink = await interaction.options.getString('link')
|
||||||
|
//regex for message link
|
||||||
|
const regex = /^https:\/\/discord\.com\/channels\/\d+\/\d+\/\d+$/
|
||||||
|
|
||||||
|
if (!messageLink.match(regex)) {
|
||||||
|
return await interaction.editReply({
|
||||||
|
content: `Invalid URL`,
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let temp = messageLink.split('/')
|
||||||
|
let messageID = temp[temp.length - 1]
|
||||||
|
let channelID = temp[temp.length - 2]
|
||||||
|
let guildID = temp[temp.length - 3]
|
||||||
|
|
||||||
|
const guild = await interaction.client.guilds.fetch(guildID)
|
||||||
|
const channel = await guild.channels.fetch(channelID)
|
||||||
|
const message = await channel.messages.fetch(messageID)
|
||||||
|
|
||||||
|
var msgData = {
|
||||||
|
content: message.content,
|
||||||
|
author: await message.author,
|
||||||
|
reference: await message.reference,
|
||||||
|
embed: await message.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
if (msgData.reference) {
|
||||||
|
let refGuild = await interaction.client.guilds.fetch(msgData.reference.guildId)
|
||||||
|
let refChannel = await refGuild.channels.fetch(msgData.reference.channelId)
|
||||||
|
let refMessage = await refChannel.messages.fetch(msgData.reference.messageId)
|
||||||
|
|
||||||
|
|
||||||
|
var refData = {
|
||||||
|
content: refMessage.content,
|
||||||
|
author: await refMessage.author,
|
||||||
|
embed: await refMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const found = await quotesColl.findOne({ messageID: messageID })
|
||||||
|
if (found) { return await interaction.editReply({ content: 'Quote Already in Database', flags: MessageFlags.Ephemeral }) }
|
||||||
|
await quotesColl.findOneAndUpdate({ messageID: messageID }, {
|
||||||
|
$set: {
|
||||||
|
messageID: messageID,
|
||||||
|
channelID: channelID,
|
||||||
|
guildID: guildID,
|
||||||
|
userID: msgData.author.id,
|
||||||
|
count: 0
|
||||||
|
}
|
||||||
|
}, { upsert: true })
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote Added! -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (footer + ' #' + messageID) })
|
||||||
|
await interaction.editReply({ embeds: [embed] })
|
||||||
|
}
|
||||||
|
async function quotesRemove(interaction) {
|
||||||
|
const id = await interaction.options.getString('id')
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const found = await quotesColl.findOne({ messageID: id })
|
||||||
|
if (!found) { return await interaction.reply({ content: 'ID not found!', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
await quotesColl.deleteOne({ messageID: id })
|
||||||
|
|
||||||
|
return interaction.reply({ content: 'Quote successfully removed!', flags: MessageFlags.Ephemeral })
|
||||||
|
}
|
||||||
|
async function quotesSearch(interaction) {
|
||||||
|
const id = interaction.options.getString("id")
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const found = await quotesColl.findOne({ messageID: id })
|
||||||
|
if (!found) { return await interaction.reply({ content: 'ID not found!', flags: MessageFlags.Ephemeral }) }
|
||||||
|
|
||||||
|
|
||||||
|
const guild = await interaction.client.guilds.fetch(found.guildID)
|
||||||
|
const channel = await guild.channels.fetch(found.channelID)
|
||||||
|
const message = await channel.messages.fetch(found.messageID)
|
||||||
|
|
||||||
|
var msgData = {
|
||||||
|
content: message.content,
|
||||||
|
author: await message.author,
|
||||||
|
reference: await message.reference,
|
||||||
|
embed: await message.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
|
||||||
|
quotesColl.findOneAndUpdate({
|
||||||
|
messageID: found.messageID
|
||||||
|
}, {
|
||||||
|
$inc: { count: 1 }
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (msgData.reference) {
|
||||||
|
let refMessage = await channel.messages.fetch(msgData.reference.messageId)
|
||||||
|
var refData = {
|
||||||
|
content: refMessage.content,
|
||||||
|
author: await refMessage.author,
|
||||||
|
embed: await refMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}`
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote Found! -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (footer + ' #' + found.messageID) })
|
||||||
|
await interaction.reply({ embeds: [embed] })
|
||||||
|
|
||||||
|
}
|
||||||
|
async function quotesRandom(interaction) {
|
||||||
|
var user = interaction.options.getUser("by")
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
var rdm
|
||||||
|
if (user) {
|
||||||
|
rdm = await quotesColl.aggregate([
|
||||||
|
{
|
||||||
|
$match: { userID: user.id },
|
||||||
|
}, {
|
||||||
|
$sample: { size: 1 }
|
||||||
|
}
|
||||||
|
]).toArray()
|
||||||
|
} else {
|
||||||
|
rdm = await quotesColl.aggregate([
|
||||||
|
{
|
||||||
|
$sample: { size: 1 }
|
||||||
|
}
|
||||||
|
]).toArray()
|
||||||
|
}
|
||||||
|
const found = rdm[0]
|
||||||
|
if (!found) { return await interaction.reply({ content: 'No Entry Found.', flags: MessageFlags.Ephemeral }) }
|
||||||
|
const guild = await interaction.client.guilds.fetch(found.guildID)
|
||||||
|
const channel = await guild.channels.fetch(found.channelID)
|
||||||
|
const message = await channel.messages.fetch(found.messageID)
|
||||||
|
|
||||||
|
var msgData = {
|
||||||
|
content: message.content,
|
||||||
|
author: await message.author,
|
||||||
|
reference: await message.reference,
|
||||||
|
embed: await message.embeds ? 'embed' : null
|
||||||
|
} // debug
|
||||||
|
|
||||||
|
quotesColl.findOneAndUpdate({
|
||||||
|
messageID: found.messageID
|
||||||
|
}, {
|
||||||
|
$inc: { count: 1 }
|
||||||
|
}, {
|
||||||
|
upsert: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (msgData.reference) {
|
||||||
|
let refMessage = await channel.messages.fetch(msgData.reference.messageId)
|
||||||
|
var refData = {
|
||||||
|
content: refMessage.content,
|
||||||
|
author: await refMessage.author,
|
||||||
|
embed: await refMessage.embeds.length > 0 ? 'embed' : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description = ''
|
||||||
|
if (refData) {
|
||||||
|
description += `> ${refData.author}`
|
||||||
|
if (refData.embed) {
|
||||||
|
description += '*an embed / a command* '
|
||||||
|
} else {
|
||||||
|
description += refData.content
|
||||||
|
}
|
||||||
|
description += `\r\n↳`
|
||||||
|
}
|
||||||
|
let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}`
|
||||||
|
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
|
||||||
|
let timestamp = new Date(message.createdTimestamp)
|
||||||
|
let footer = timestamp.toDateString().toString()
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setThumbnail(msgData.author.displayAvatarURL())
|
||||||
|
.setURL(messageLink)
|
||||||
|
.setTitle(`- Quote Found! -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: (footer + ' #' + found.messageID) })
|
||||||
|
await interaction.reply({ embeds: [embed] })
|
||||||
|
}
|
||||||
|
async function quotesList(interaction) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Quotes List! -')
|
||||||
|
.setDescription('- Choose someone below to filter by User')
|
||||||
|
.setThumbnail(interaction.guild.iconURL())
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`◀`)
|
||||||
|
.setCustomId('quotes_list_left')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`❌`)
|
||||||
|
.setCustomId('abort')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji(`▶`)
|
||||||
|
.setCustomId('quotes_list_right')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('quotes_list_mentionable')
|
||||||
|
.setPlaceholder('Filter by User')
|
||||||
|
)
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
async function quotesLeaderboard(interaction, page = 1, limit = 5) {
|
||||||
|
const db = mClient.db(process.env.M_DB);
|
||||||
|
const quotesColl = db.collection('items_quotes');
|
||||||
|
|
||||||
|
// Total quotes in the guild
|
||||||
|
const totalQuotes = await quotesColl.countDocuments({ guildID: interaction.guild.id, count: { $gte: 0 } });
|
||||||
|
const totalPages = Math.ceil(totalQuotes / limit);
|
||||||
|
|
||||||
|
// Clamp page
|
||||||
|
if (page < 1) page = 1;
|
||||||
|
if (page > totalPages) page = totalPages;
|
||||||
|
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Fetch quotes for this page
|
||||||
|
const quotesData = await quotesColl
|
||||||
|
.find({ guildID: interaction.guild.id, count: { $gte: 0 } })
|
||||||
|
.sort({ count: -1, messageID: -1 })
|
||||||
|
.skip(skip)
|
||||||
|
.limit(limit)
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
// Fallback if no quotes exist
|
||||||
|
if (!quotesData.length) {
|
||||||
|
return interaction.editReply({ content: 'No quotes found for this server yet!', components: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
const guild = await interaction.client.guilds.fetch(interaction.guild.id);
|
||||||
|
|
||||||
|
// Fetch all messages concurrently
|
||||||
|
const fields = await Promise.all(
|
||||||
|
quotesData.map(async (data, index) => {
|
||||||
|
try {
|
||||||
|
const channel = await guild.channels.fetch(data.channelID);
|
||||||
|
const message = await channel.messages.fetch(data.messageID);
|
||||||
|
const timestamp = new Date(message.createdTimestamp).toLocaleString('en-US', {
|
||||||
|
dateStyle: 'medium',
|
||||||
|
timeStyle: 'short'
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: `${skip + index + 1}.`,
|
||||||
|
value: `[#${data.messageID}](https://discord.com/channels/${data.guildID}/${data.channelID}/${data.messageID})\n**by** <@${data.userID}> • ⭐ ${data.count}\n_Posted on **${timestamp}**_\n${message.content}`
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
name: `${skip + index + 1}.`,
|
||||||
|
value: 'Message unavailable.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build embed
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('- Quotes Leaderboard -')
|
||||||
|
.setThumbnail(guild.iconURL({ dynamic: true }))
|
||||||
|
.setFields(fields)
|
||||||
|
.setColor('#5865F2')
|
||||||
|
.setFooter({ text: `Use ◄ ► to navigate • Page ${page} of ${totalPages}` });
|
||||||
|
|
||||||
|
// Build buttons
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('◄')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('quotes_leaderboard_left')
|
||||||
|
.setDisabled(page === 1),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('X')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
.setCustomId('abort'),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setLabel('►')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setCustomId('quotes_leaderboard_right')
|
||||||
|
.setDisabled(page === totalPages)
|
||||||
|
);
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed], components: [row] });
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('quotes')
|
||||||
|
.setDescription('quoten pfoten')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('add')
|
||||||
|
.setDescription('add a new quote either by replying to a message or inserting the message link')
|
||||||
|
.addStringOption(o => o.setName('link').setDescription('insert message link').setRequired(true)))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('remove')
|
||||||
|
.setDescription('remove a quote')
|
||||||
|
.addStringOption(o => o.setName('id').setDescription('insert message ID').setRequired(true)))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('search')
|
||||||
|
.setDescription('search by ID')
|
||||||
|
.addStringOption(o => o.setName('id').setDescription('insert message ID').setRequired(true)))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('random')
|
||||||
|
.setDescription('get a random quote')
|
||||||
|
.addUserOption(o => o.setName('by').setDescription('by user')))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('leaderboard')
|
||||||
|
.setDescription('see the most used quotes'))
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s
|
||||||
|
.setName('list')
|
||||||
|
.setDescription('[ADMIN] list all quotes')),
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'add':
|
||||||
|
await interaction.deferReply()
|
||||||
|
quotesAdd(interaction)
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
quotesRemove(interaction)
|
||||||
|
break;
|
||||||
|
case 'search':
|
||||||
|
quotesSearch(interaction)
|
||||||
|
break;
|
||||||
|
case 'random':
|
||||||
|
quotesRandom(interaction)
|
||||||
|
break;
|
||||||
|
case 'leaderboard':
|
||||||
|
await interaction.deferReply()
|
||||||
|
quotesLeaderboard(interaction)
|
||||||
|
break;
|
||||||
|
case 'list':
|
||||||
|
quotesList(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
module.exports.quotesLeaderboard = quotesLeaderboard
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
const { SlashCommandBuilder } = require("discord.js");
|
||||||
|
|
||||||
|
function askMyBalls() {
|
||||||
|
var answers = [
|
||||||
|
'Absolut, so wie die Authorität unserer Göttin!',
|
||||||
|
'Unterschätze es nicht, genauso wie Roberts sexual frustration',
|
||||||
|
'Ich zedaz so',
|
||||||
|
'Ohne Zweifel',
|
||||||
|
'Definitiv, Alter',
|
||||||
|
'Microsoft Outlook gut',
|
||||||
|
'Das Sternzeichen von Yeesh leuchtet heute stark dafür',
|
||||||
|
'Mit "Support-Desk am Freitagabend" - Wahrscheinlichkeit',
|
||||||
|
'Ist die Nase von Julius wunderschön und lang?',
|
||||||
|
'So wahr wie Laviis Zeichnkünste',
|
||||||
|
'nein...ja... vielleicht?',
|
||||||
|
'Frag mich nachher nochmal',
|
||||||
|
'Die Kalkulationen sind leicht off, ich aber nicht ;)',
|
||||||
|
'Ich sag es dir ein ander Mal',
|
||||||
|
'Ohne schwere Zeiten, würden wir die guten Zeiten nie schätzen',
|
||||||
|
'Genauso schlecht wie eine Ketzerei gegen den Olymp',
|
||||||
|
'Hat der Fuchs uns jemals verraten?...**hust**',
|
||||||
|
'Mein Outlook ist abgeschmiert, mist',
|
||||||
|
'Ich bezweifle es. A propos, zweifel nicht an den Götter und ihren Priester!',
|
||||||
|
'Meine Quellen sagen.... WARNUNG! Artikel 17: Die betroffene Person hat das Recht, von dem Verantwortlichen zu verlangen, dass sie betreffende personenbezogene Daten unverzüglich gelöscht werden, und der Verantwortliche ist verpflichtet, personenbezogene Daten unverzüglich zu löschen, sofern einer der folgenden Gründe zutrifft **ERROR ERROR ERROR**?'
|
||||||
|
]
|
||||||
|
const r = Math.floor(Math.random() * answers.length)
|
||||||
|
|
||||||
|
return answers[r]
|
||||||
|
}
|
||||||
|
|
||||||
|
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('8ball')
|
||||||
|
.setDescription('dont ask me anything')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('ask')
|
||||||
|
.setDescription('what do you want to know?')
|
||||||
|
.addStringOption(
|
||||||
|
o => o.setName('question').setDescription('ask away!').setRequired(true))
|
||||||
|
),
|
||||||
|
async execute(interaction) {
|
||||||
|
await interaction.deferReply()
|
||||||
|
await delay(2000)
|
||||||
|
await interaction.editReply(askMyBalls())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder } = require("discord.js");
|
||||||
|
|
||||||
|
async function doggoPet(interaction) {
|
||||||
|
|
||||||
|
const responses = [
|
||||||
|
'*loving growl*',
|
||||||
|
'Danke, das habe ich gebraucht.',
|
||||||
|
'Ein bisschen tiefer.',
|
||||||
|
'Ja, genau dort!'
|
||||||
|
]
|
||||||
|
var r = Math.floor(Math.random() * responses.length)
|
||||||
|
|
||||||
|
const filePath = `assets/Command_Doggo/doggo.jpg`;
|
||||||
|
|
||||||
|
const attachment = new AttachmentBuilder(filePath);
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setDescription(responses[r])
|
||||||
|
.setColor(0x51267)
|
||||||
|
.setTimestamp()
|
||||||
|
.setImage(`attachment://doggo.jpg`);
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [attachment]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function doggoFeed(interaction) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'WIP placeholder'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function doggoWalk(interaction) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'WIP placeholder'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function doggoPlay(interaction) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'WIP placeholder'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('doggo')
|
||||||
|
.setDescription('who is a good boi?')
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('pet')
|
||||||
|
.setDescription('beeg scratch')
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('feed')
|
||||||
|
.setDescription('tastge')
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('walk')
|
||||||
|
.setDescription('walkies')
|
||||||
|
)
|
||||||
|
.addSubcommand(s =>
|
||||||
|
s.setName('play')
|
||||||
|
.setDescription('fun time')
|
||||||
|
),
|
||||||
|
async execute(interaction) {
|
||||||
|
await interaction.deferReply()
|
||||||
|
switch (interaction.options._subcommand) {
|
||||||
|
case 'pet':
|
||||||
|
doggoPet(interaction)
|
||||||
|
break;
|
||||||
|
case 'feed':
|
||||||
|
doggoFeed(interaction)
|
||||||
|
break;
|
||||||
|
case 'walk':
|
||||||
|
doggoWalk(interaction)
|
||||||
|
break;
|
||||||
|
case 'play':
|
||||||
|
doggoPlay(interaction)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
const { SlashCommandBuilder, AttachmentBuilder, EmbedBuilder } = require('discord.js');
|
||||||
|
const fs = require('fs/promises');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function makeDay() {
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
const tage = [
|
||||||
|
'sonntag',
|
||||||
|
'montag',
|
||||||
|
'dienstag',
|
||||||
|
'mittwoch',
|
||||||
|
'donnerstag',
|
||||||
|
'freitag',
|
||||||
|
'samstag'
|
||||||
|
];
|
||||||
|
|
||||||
|
const text = {
|
||||||
|
montag: 'Es ist Montag meine Münmler!',
|
||||||
|
mittwoch: 'Es ist Mittwoch meine Kerle!',
|
||||||
|
donnerstag: 'Es ist nicht mehr Mittwoch meine Kerle!',
|
||||||
|
freitag: 'Es ist Freitag meine Kerl*innen!',
|
||||||
|
default: 'Es ist nicht Mittwoch, meine Kerle...'
|
||||||
|
};
|
||||||
|
|
||||||
|
const today = tage[date.getDay()];
|
||||||
|
|
||||||
|
let files;
|
||||||
|
try {
|
||||||
|
files = await fs.readdir('assets/Command_Mittwoch');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return { filename: 'nicht_mittwoch', content: text.default };
|
||||||
|
}
|
||||||
|
|
||||||
|
const available = files.map(f => path.parse(f).name);
|
||||||
|
|
||||||
|
if (available.includes(today)) {
|
||||||
|
return {
|
||||||
|
filename: today,
|
||||||
|
content: text[today] || text.default
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
filename: 'nicht_mittwoch',
|
||||||
|
content: text.default
|
||||||
|
};
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('mittwoch')
|
||||||
|
.setDescription('mittwoch vibes'),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { filename, content } = await makeDay();
|
||||||
|
|
||||||
|
const filePath = `assets/Command_Mittwoch/${filename}.jpg`;
|
||||||
|
|
||||||
|
const attachment = new AttachmentBuilder(filePath);
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(content)
|
||||||
|
.setColor(0x51267)
|
||||||
|
.setTimestamp()
|
||||||
|
.setImage(`attachment://${filename}.jpg`);
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
files: [attachment]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
const { createCanvas, loadImage } = require('canvas');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { mClient } = require('..');
|
||||||
|
require('dotenv').configDotenv();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: "Birthday",
|
||||||
|
once: false,
|
||||||
|
async execute(member, client) {
|
||||||
|
console.log(`${member.user.username} hat Geburtstag!`)
|
||||||
|
let found = null
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const channelsColl = db.collection('config_channels')
|
||||||
|
found = await channelsColl.find(
|
||||||
|
{
|
||||||
|
$and: [
|
||||||
|
{ guildID: member.guild.id },
|
||||||
|
{ purpose: 'birthday' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
).toArray()
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return console.log('Channel not yet set for birthday!')
|
||||||
|
}
|
||||||
|
|
||||||
|
const guild = client.guilds.cache.get(found[0].guildID);
|
||||||
|
const channel = guild.channels.cache.get(found[0].channelID);
|
||||||
|
const roleColl = db.collection('config_roles')
|
||||||
|
|
||||||
|
// Bot Role MUST BE above birthday Role, Birthday Role MUST BE above user roles
|
||||||
|
found = await roleColl.findOne({guildID: member.guild.id})
|
||||||
|
const role = guild.roles.cache.get(found.roleID)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await member.roles.add(role)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
// Create Canvas
|
||||||
|
let canvasWidth = 600;
|
||||||
|
let canvasHeight = 250;
|
||||||
|
const canvas = new createCanvas(canvasWidth, canvasHeight);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Draw Initial Image
|
||||||
|
const background = await loadImage(
|
||||||
|
path.join(__dirname, '../assets/Event_Birthday/bdbanner.png')
|
||||||
|
);
|
||||||
|
let x = 0;
|
||||||
|
let y = 0;
|
||||||
|
ctx.drawImage(background, x, y);
|
||||||
|
|
||||||
|
// Create Profile Picture
|
||||||
|
const pfp = await loadImage(
|
||||||
|
member.user.displayAvatarURL({
|
||||||
|
extension: 'jpg',
|
||||||
|
size: 64,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Draw Profile Picture on Top of Background
|
||||||
|
x = canvas.width / 2 - pfp.width / 2;
|
||||||
|
y = 20;
|
||||||
|
ctx.drawImage(pfp, x, y);
|
||||||
|
|
||||||
|
// Set styles for text
|
||||||
|
ctx.font = '35px sans-serif';
|
||||||
|
ctx.fillStyle = '#FFC0CB'; // Pink text
|
||||||
|
ctx.strokeStyle = '#000000'; // Black outline
|
||||||
|
ctx.lineWidth = 3; // Thickness of the outline
|
||||||
|
|
||||||
|
let text = `Alles Gute zum Geburtstag! `;
|
||||||
|
let textWidth = ctx.measureText(text).width;
|
||||||
|
let textX = canvas.width / 2 - textWidth / 2;
|
||||||
|
let textHeight = 35; // Approximate height of the text
|
||||||
|
|
||||||
|
// Draw the text with black outline
|
||||||
|
ctx.strokeText(text, textX, 60 + pfp.height);
|
||||||
|
ctx.fillText(text, textX, 60 + pfp.height);
|
||||||
|
|
||||||
|
// requires apt-get install ttf-ancient-fonts
|
||||||
|
ctx.font = '30px "Noto Emoji", "Segoe UI Emoji", "Apple Color Emoji", sans-serif';
|
||||||
|
text = `🎉 ${member.user.globalName ? member.user.globalName : member.user.username} 🎉`;
|
||||||
|
textWidth = ctx.measureText(text).width;
|
||||||
|
textX = canvas.width / 2 - textWidth / 2;
|
||||||
|
textHeight = 30; // Approximate height of the text
|
||||||
|
|
||||||
|
// Draw the second line of text with black outline
|
||||||
|
ctx.strokeText(text, textX, 100 + pfp.height);
|
||||||
|
ctx.fillText(text, textX, 100 + pfp.height);
|
||||||
|
|
||||||
|
const banner = canvas.toBuffer();
|
||||||
|
|
||||||
|
channel.send({
|
||||||
|
content: `@here`,
|
||||||
|
files: [{
|
||||||
|
attachment: banner,
|
||||||
|
name: 'banner.png',
|
||||||
|
description: 'a birthday banner'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
const { Events, ActivityType } = require('discord.js');
|
||||||
|
const { mClient } = require('..');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: Events.ClientReady,
|
||||||
|
once: true,
|
||||||
|
async execute(client) {
|
||||||
|
console.log(`Ready! Logged in as ${client.user.tag}`);
|
||||||
|
|
||||||
|
// Set presence
|
||||||
|
client.user.setPresence({
|
||||||
|
activities: [{
|
||||||
|
name: 'Red Dead Depression',
|
||||||
|
type: ActivityType.Streaming,
|
||||||
|
url: 'https://twitch.tv/desq_blocki'
|
||||||
|
}],
|
||||||
|
status: 'online'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if a date matches today
|
||||||
|
const isToday = (day, month) => {
|
||||||
|
const today = new Date();
|
||||||
|
return today.getDate() === day && today.getMonth() === month - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle birthdays
|
||||||
|
const handleBirthdays = async () => {
|
||||||
|
const guild = await client.guilds.fetch(process.env.D_GuildID);
|
||||||
|
const db = mClient.db(process.env.M_DB);
|
||||||
|
|
||||||
|
const bdayColl = db.collection('items_birthdays');
|
||||||
|
const allBirthdays = await bdayColl.find().toArray();
|
||||||
|
const bdayMap = new Map(allBirthdays.map(b => [b.userID, b]));
|
||||||
|
|
||||||
|
// Fetch birthday role
|
||||||
|
const bdayRoleColl = db.collection('config_roles');
|
||||||
|
const bdayRoleEntry = await bdayRoleColl.findOne({ guildID: guild.id });
|
||||||
|
const birthdayRoleID = bdayRoleEntry?.roleID;
|
||||||
|
|
||||||
|
if (!birthdayRoleID) {
|
||||||
|
console.warn("No birthday role configured in DB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch all guild members
|
||||||
|
const members = await guild.members.fetch();
|
||||||
|
|
||||||
|
for (const member of members.values()) {
|
||||||
|
const dbEntry = bdayMap.get(member.id);
|
||||||
|
|
||||||
|
if (dbEntry && isToday(dbEntry.day, dbEntry.month)) {
|
||||||
|
// Today is their birthday
|
||||||
|
await member.roles.add(birthdayRoleID).catch(err =>
|
||||||
|
console.error(`Failed to add birthday role to ${member.user.tag}:`, err)
|
||||||
|
);
|
||||||
|
console.log(`Added birthday role to ${member.user.tag}`);
|
||||||
|
//client.emit('Birthday', member);
|
||||||
|
} else {
|
||||||
|
// Default fallback: remove birthday role if present
|
||||||
|
if (member.roles.cache.has(birthdayRoleID)) {
|
||||||
|
await member.roles.remove(birthdayRoleID).catch(err =>
|
||||||
|
console.error(`Failed to remove birthday role from ${member.user.tag}:`, err)
|
||||||
|
);
|
||||||
|
console.log(`Removed birthday role from ${member.user.tag} (not today or not in DB)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await handleBirthdays();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
const { Events } = require('discord.js');
|
||||||
|
const { createCanvas, loadImage } = require('canvas');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { mClient } = require('..');
|
||||||
|
require('dotenv').configDotenv();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: Events.GuildMemberAdd,
|
||||||
|
once: false,
|
||||||
|
async execute(member, client) {
|
||||||
|
console.log(`${member.user.username} joined the Server`);
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const channelsColl = db.collection('config_channels')
|
||||||
|
const found = await channelsColl.find(
|
||||||
|
{
|
||||||
|
$and: [
|
||||||
|
{ guildID: member.guild.id },
|
||||||
|
{ purpose: 'welcome' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
).toArray()
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return console.log('Channel not yet set for welcome!')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const guild = client.guilds.cache.get(found[0].guildID);
|
||||||
|
const channel = guild.channels.cache.get(found[0].channelID);
|
||||||
|
|
||||||
|
// Create Canvas
|
||||||
|
let canvasWidth = 600;
|
||||||
|
let canvasHeight = 250;
|
||||||
|
const canvas = new createCanvas(canvasWidth, canvasHeight);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Draw Initial Image
|
||||||
|
const background = await loadImage(
|
||||||
|
path.join(__dirname, '../assets/Event_MemberJoin/background.png')
|
||||||
|
);
|
||||||
|
let x = 0;
|
||||||
|
let y = 0;
|
||||||
|
ctx.drawImage(background, x, y);
|
||||||
|
|
||||||
|
// Create Profile Picture
|
||||||
|
const pfp = await loadImage(
|
||||||
|
member.user.displayAvatarURL({
|
||||||
|
extension: 'jpg',
|
||||||
|
size: 64,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Draw Profile Picture on Top of Background
|
||||||
|
x = canvas.width / 2 - pfp.width / 2;
|
||||||
|
y = 20;
|
||||||
|
ctx.drawImage(pfp, x, y);
|
||||||
|
|
||||||
|
// Set styles for text
|
||||||
|
ctx.font = '35px sans-serif';
|
||||||
|
ctx.fillStyle = '#ffffff'; // White text
|
||||||
|
ctx.strokeStyle = '#000000'; // Black outline
|
||||||
|
ctx.lineWidth = 3; // Thickness of the outline
|
||||||
|
|
||||||
|
let text = `Willkommen, ${member.user.globalName?member.user.globalName:member.user.username}!`;
|
||||||
|
let textWidth = ctx.measureText(text).width;
|
||||||
|
let textX = canvas.width / 2 - textWidth / 2;
|
||||||
|
let textHeight = 35; // Approximate height of the text
|
||||||
|
|
||||||
|
// Draw the text with black outline
|
||||||
|
ctx.strokeText(text, textX, 60 + pfp.height);
|
||||||
|
ctx.fillText(text, textX, 60 + pfp.height);
|
||||||
|
|
||||||
|
ctx.font = '30px sans-serif';
|
||||||
|
text = `auf dem ✨Olymp✨`;
|
||||||
|
textWidth = ctx.measureText(text).width;
|
||||||
|
textX = canvas.width / 2 - textWidth / 2;
|
||||||
|
textHeight = 30; // Approximate height of the text
|
||||||
|
|
||||||
|
// Draw the second line of text with black outline
|
||||||
|
ctx.strokeText(text, textX, 100 + pfp.height);
|
||||||
|
ctx.fillText(text, textX, 100 + pfp.height);
|
||||||
|
const banner = canvas.toBuffer();
|
||||||
|
|
||||||
|
channel.send({
|
||||||
|
content: `Bitte guck einmal in die <#455023824791011338> ${member}`,
|
||||||
|
files: [{
|
||||||
|
attachment: banner,
|
||||||
|
name: 'banner.png',
|
||||||
|
description: 'a welcome banner'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
const { Events, MessageFlags } = require('discord.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: Events.InteractionCreate,
|
||||||
|
once: false,
|
||||||
|
async execute(interaction) {
|
||||||
|
if (interaction.isChatInputCommand()) { commandHandler(interaction) };
|
||||||
|
if (interaction.isButton()) { buttonHandler(interaction) }
|
||||||
|
if (interaction.isMentionableSelectMenu()) { selectMenuHandler(interaction)}
|
||||||
|
if (interaction.isUserSelectMenu()) { selectMenuHandler(interaction) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function commandHandler(interaction) {
|
||||||
|
const command = interaction.client.commands.get(interaction.commandName);
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await command.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
if (interaction.replied || interaction.deferred) {
|
||||||
|
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
} else {
|
||||||
|
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function buttonHandler(interaction) {
|
||||||
|
const button = interaction.client.buttons.get(interaction.customId)
|
||||||
|
if (!button) { return console.error(`No button registered matching ${interaction.customId}.`) }
|
||||||
|
try {
|
||||||
|
await button.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
if (interaction.replied || interaction.deferred) {
|
||||||
|
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
} else {
|
||||||
|
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function selectMenuHandler(interaction) {
|
||||||
|
const selectMenu = interaction.client.selectMenus.get(interaction.customId)
|
||||||
|
if (!selectMenu) { return console.error(`No Select Menu registered matching ${interaction.customId}.`) }
|
||||||
|
try {
|
||||||
|
await selectMenu.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
if (interaction.replied || interaction.deferred) {
|
||||||
|
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
} else {
|
||||||
|
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const { Events } = require('discord.js')
|
||||||
|
require('dotenv').config()
|
||||||
|
const { client } = require('../index')
|
||||||
|
const prefix = process.env.D_Prefix
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: Events.MessageCreate,
|
||||||
|
once: false,
|
||||||
|
async execute(message) {
|
||||||
|
if (!message.content.startsWith(prefix) || message.author.bot) return;
|
||||||
|
|
||||||
|
const args = message.content.slice(prefix.length).trim().split(/ +/);
|
||||||
|
const cmd = args.shift().toLowerCase();
|
||||||
|
let command = client.legacyCommands.get(cmd)
|
||||||
|
if(!command) command = client.legacyCommands.get(client.aliases.get(cmd))
|
||||||
|
if(!command) return
|
||||||
|
try {
|
||||||
|
client.legacyCommands.get(command.name).execute(message, args)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// const { Events, ClientVoiceManager } = require("discord.js");
|
||||||
|
// const { getVoiceConnection } = require('@discordjs/voice')
|
||||||
|
// require('dotenv').config()
|
||||||
|
// const { client } = require('../index');
|
||||||
|
// const users_in_afk = new Set();
|
||||||
|
// const delay = ms => new Promise(res => setTimeout(res, ms));
|
||||||
|
// var connected = false;
|
||||||
|
// const url = `https://www.youtube.com/watch?v=Y4ySxP_IptE`
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
// name: Events.VoiceStateUpdate,
|
||||||
|
// once: false,
|
||||||
|
// async execute(oldState, newState) {
|
||||||
|
// const guild = client.guilds.cache.get(process.env.D_GuildID)
|
||||||
|
// const afk_channel = await guild.channels.fetch(guild.afkChannelId)
|
||||||
|
// const real_afk_channel = await guild.channels.fetch(process.env.D_RealTartarosID)
|
||||||
|
// const user = await guild.members.fetch(newState.id)
|
||||||
|
|
||||||
|
// if(user.id === process.env.D_ID) return;
|
||||||
|
|
||||||
|
// // if someone enters the official AFK channel, move them to one where we can play music
|
||||||
|
// if (newState.channelId === afk_channel.id) {
|
||||||
|
// await delay(1000)
|
||||||
|
|
||||||
|
// await user.voice.setChannel(real_afk_channel)
|
||||||
|
|
||||||
|
// users_in_afk.add(newState.id)
|
||||||
|
// console.log(`${users_in_afk.size} User(s) in Channel`)
|
||||||
|
|
||||||
|
// if (!connected) {
|
||||||
|
// connected = true;
|
||||||
|
// await client.distube.voices.join(real_afk_channel)
|
||||||
|
// await user.voice.setSuppressed(true) // mute user?
|
||||||
|
// await guild.members.me.voice.setSuppressed(false); //unmute self
|
||||||
|
// await client.distube.play(real_afk_channel, url, {
|
||||||
|
// member: newState.member,
|
||||||
|
// })
|
||||||
|
// //const queue = client.distube.getQueue(guild)
|
||||||
|
// //await queue.setRepeatMode(2)
|
||||||
|
// //await queue.setVolume(40)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // if someone leaves the real AFK channel, remove them from cache but wait for rejoiners, then leave if none are here
|
||||||
|
// if (oldState.channelId === real_afk_channel.id && oldState.channelId != newState.channelId) {
|
||||||
|
// users_in_afk.delete(oldState.id)
|
||||||
|
// const user = await guild.members.fetch(oldState.id)
|
||||||
|
// //await user.voice.setMute(false) //kann nicht unmuten wenn disconnected ist
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (users_in_afk.size === 0) {
|
||||||
|
// //leave if empty
|
||||||
|
// await client.distube.voices.leave(real_afk_channel)
|
||||||
|
// connected = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
module.exports = (client) => {
|
||||||
|
const buttonsFoldersPath = path.join(__dirname, '../buttons');
|
||||||
|
const buttonsFolders = fs.readdirSync(buttonsFoldersPath);
|
||||||
|
let buttonCount = 0
|
||||||
|
for (const folder of buttonsFolders) {
|
||||||
|
const buttonsPath = path.join(buttonsFoldersPath, folder);
|
||||||
|
const buttonsFiles = fs.readdirSync(buttonsPath).filter(file => file.endsWith('.js'));
|
||||||
|
for (const file of buttonsFiles) {
|
||||||
|
buttonCount++
|
||||||
|
const filePath = path.join(buttonsPath, file);
|
||||||
|
const button = require(filePath);
|
||||||
|
if ('execute' in button) {
|
||||||
|
client.buttons.set(button.name, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`[${buttonCount}] Button(s) initialized`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
module.exports = (client) => {
|
||||||
|
const legacyFoldersPath = path.join(__dirname, '../commands/legacy');
|
||||||
|
const legacyCommandFolders = fs.readdirSync(legacyFoldersPath);
|
||||||
|
let legacyCount = 0
|
||||||
|
let aliasCount = 0
|
||||||
|
for (const folder of legacyCommandFolders) {
|
||||||
|
const commandsPath = path.join(legacyFoldersPath, folder);
|
||||||
|
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
legacyCount++
|
||||||
|
const filePath = path.join(commandsPath, file);
|
||||||
|
const command = require(filePath);
|
||||||
|
if ('execute' in command) {
|
||||||
|
client.legacyCommands.set(command.name, command);
|
||||||
|
}
|
||||||
|
if (command.aliases && Array.isArray(command.aliases)) {
|
||||||
|
command.aliases.forEach(alias => {
|
||||||
|
aliasCount++
|
||||||
|
client.aliases.set(alias, command.name)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`[${aliasCount}] Aliase(s) initialized`)
|
||||||
|
console.log(`[${legacyCount}] Legacy Command(s) initialized`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// ich hab das einfach _commands genannt, damit es beim Startup als erstes initialisiert wird.
|
||||||
|
const { REST, Routes } = require('discord.js')
|
||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
|
||||||
|
module.exports = (client) => {
|
||||||
|
let commands = [] // only used for REST API
|
||||||
|
const foldersPath = path.join(__dirname, '../commands/slash');
|
||||||
|
const commandFolders = fs.readdirSync(foldersPath);
|
||||||
|
for (const folder of commandFolders) {
|
||||||
|
// Grab all the command files from the commands directory you created earlier
|
||||||
|
const commandsPath = path.join(foldersPath, folder);
|
||||||
|
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||||
|
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
const filePath = path.join(commandsPath, file);
|
||||||
|
const command = require(filePath);
|
||||||
|
if ('data' in command && 'execute' in command) {
|
||||||
|
commands.push(command.data.toJSON());
|
||||||
|
client.commands.set(command.data.name, command);
|
||||||
|
} else {
|
||||||
|
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const rest = new REST().setToken(process.env.D_Token);
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||||
|
// The put method is used to fully refresh all commands in the guild with the current set
|
||||||
|
const data = await rest.put(
|
||||||
|
Routes.applicationGuildCommands(process.env.D_ID, process.env.D_GuildID),
|
||||||
|
{ body: commands },
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||||
|
} catch (error) {
|
||||||
|
// And of course, make sure you catch and log any errors!
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
module.exports = (client) => {
|
||||||
|
const eventsPath = path.join(__dirname, '../events')
|
||||||
|
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'))
|
||||||
|
|
||||||
|
for (const file of eventFiles) {
|
||||||
|
const filePath = path.join(eventsPath, file)
|
||||||
|
const event = require(filePath)
|
||||||
|
if (event.once) {
|
||||||
|
client.once(event.name, (...args) => event.execute(...args, client))
|
||||||
|
// added client to commomerate global usage
|
||||||
|
} else {
|
||||||
|
client.on(event.name, (...args) => event.execute(...args, client))
|
||||||
|
// added client to commomerate global usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
module.exports = (client) => {
|
||||||
|
const selectMenusFoldersPath = path.join(__dirname, '../selectMenus');
|
||||||
|
const selectMenusFolders = fs.readdirSync(selectMenusFoldersPath);
|
||||||
|
let selectMenuCount = 0
|
||||||
|
for (const folder of selectMenusFolders) {
|
||||||
|
const Path = path.join(selectMenusFoldersPath, folder);
|
||||||
|
const Files = fs.readdirSync(Path).filter(file => file.endsWith('.js'));
|
||||||
|
for (const file of Files) {
|
||||||
|
selectMenuCount++
|
||||||
|
const filePath = path.join(Path, file);
|
||||||
|
const button = require(filePath);
|
||||||
|
if ('execute' in button) {
|
||||||
|
client.selectMenus.set(button.name, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`[${selectMenuCount}] Select Menu(s) initialized`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
const { Client, GatewayIntentBits, Collection, Partials } = require('discord.js')
|
||||||
|
const { MongoClient } = require('mongodb')
|
||||||
|
require('dotenv').config()
|
||||||
|
const mClient = new MongoClient(process.env.M_URI)
|
||||||
|
exports.mClient = mClient;
|
||||||
|
const fs = require('node:fs')
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
intents: [
|
||||||
|
GatewayIntentBits.Guilds,
|
||||||
|
GatewayIntentBits.GuildMembers,
|
||||||
|
GatewayIntentBits.GuildMessages,
|
||||||
|
GatewayIntentBits.GuildPresences,
|
||||||
|
GatewayIntentBits.GuildMessageReactions,
|
||||||
|
GatewayIntentBits.GuildVoiceStates,
|
||||||
|
GatewayIntentBits.DirectMessages,
|
||||||
|
GatewayIntentBits.MessageContent,
|
||||||
|
],
|
||||||
|
partials: [Partials.Channel, Partials.Message, Partials.User, Partials.GuildMember, Partials.Reaction]
|
||||||
|
});
|
||||||
|
exports.client = client
|
||||||
|
|
||||||
|
client.commands = new Collection() // slash commands collection
|
||||||
|
client.legacyCommands = new Collection() // legacy commands collection
|
||||||
|
client.aliases = new Collection() // list of command aliases
|
||||||
|
client.buttons = new Collection() // list of buttons
|
||||||
|
client.selectMenus = new Collection() // list of selectMenus
|
||||||
|
|
||||||
|
fs.readdirSync('./handlers').forEach((handler) => {
|
||||||
|
require(`./handlers/${handler}`)(client)
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(process.env.D_Token)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "arthonor-3",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "discord companion",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/DeSqBlocki/Arthonor-3.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"discord"
|
||||||
|
],
|
||||||
|
"author": "DeSqBlocki",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/DeSqBlocki/Arthonor-3/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/DeSqBlocki/Arthonor-3#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"canvas": "^2.11.2",
|
||||||
|
"discord.js": "^14.15.3",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"mongodb": "^6.8.0",
|
||||||
|
"nodemon": "^3.1.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, UserSelectMenuBuilder, PermissionFlagsBits } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'honor_menu_mentionable',
|
||||||
|
description: 'handles honor menu mentionables',
|
||||||
|
async execute(interaction) {
|
||||||
|
const embedData = await interaction.message.embeds[0].data
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
if (!interaction.members) {
|
||||||
|
embed.setTitle(embedData.title)
|
||||||
|
.setThumbnail(embedData.thumbnail.url)
|
||||||
|
.setDescription(embedData.description);
|
||||||
|
} else {
|
||||||
|
var target = await interaction.guild.members.fetch(interaction.members.keys().next().value)
|
||||||
|
var db = mClient.db(process.env.M_DB)
|
||||||
|
var honorsColl = db.collection('items_honors')
|
||||||
|
var theirHonorLevel = await honorsColl.findOne({ userID: target.id })
|
||||||
|
|
||||||
|
const member = interaction.message.guild.members.cache.get(target.user.id)
|
||||||
|
const memberRoles = member.roles.cache
|
||||||
|
.filter((roles) => roles.id !== interaction.message.guild.id)
|
||||||
|
.map((role) => role.toString())
|
||||||
|
|
||||||
|
const description = String(`${target} - ${target.user.globalName ?? target.user.username} - ${target.user.id}\r\n\r\n${memberRoles}`).replaceAll(',', ' ')
|
||||||
|
embed.setTitle(`- User Stats -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.addFields({
|
||||||
|
name: 'Current Honor Level:', value: `${theirHonorLevel?.honors ?? 0}`, inline: true
|
||||||
|
})
|
||||||
|
.setFooter({ text: 'Honor Level updaten sich nicht automatisch!' })
|
||||||
|
}
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('honor_menu_mentionable')
|
||||||
|
.setPlaceholder('Select a User')
|
||||||
|
)
|
||||||
|
|
||||||
|
const row = interaction.message.components[1]
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, UserSelectMenuBuilder, PermissionFlagsBits, RoleSelectMenuComponent, UserSelectMenuComponent } = require("discord.js")
|
||||||
|
const { mClient } = require("../..")
|
||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'quotes_list_mentionable',
|
||||||
|
description: 'handles quotes list mentionables',
|
||||||
|
async execute(interaction) {
|
||||||
|
const embedData = await interaction.message.embeds[0].data
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
if (!interaction.members) {
|
||||||
|
embed.setTitle(embedData.title)
|
||||||
|
.setThumbnail(embedData.thumbnail.url)
|
||||||
|
.setDescription(embedData.description);
|
||||||
|
} else {
|
||||||
|
const target = await interaction.guild.members.fetch(interaction.members.keys().next().value)
|
||||||
|
const db = mClient.db(process.env.M_DB)
|
||||||
|
const quotesColl = db.collection('items_quotes')
|
||||||
|
const quotes = await quotesColl.find({ userID: target.id }).toArray()
|
||||||
|
const member = interaction.message.guild.members.cache.get(target.user.id)
|
||||||
|
const memberRoles = member.roles.cache
|
||||||
|
.filter((roles) => roles.id !== interaction.message.guild.id)
|
||||||
|
.map((role) => role.toString())
|
||||||
|
|
||||||
|
const description = String(`${target}\r\n\r\n${memberRoles}`).replaceAll(',', ' ')
|
||||||
|
embed.setTitle(`- User Stats -`)
|
||||||
|
.setDescription(description)
|
||||||
|
.setThumbnail(target.displayAvatarURL())
|
||||||
|
.addFields({
|
||||||
|
name: 'Number of Quotes:', value: `${quotes.length}`, inline: true
|
||||||
|
})
|
||||||
|
.setFooter({ text: (`${new Date().toLocaleDateString('en-US', { weekday: 'short' })} ${new Date().toLocaleDateString('en-US', { month: 'short' })} ${new Date().getDate()} ${new Date().getFullYear()} UserID <@${member.id}>`) })
|
||||||
|
}
|
||||||
|
const select = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new UserSelectMenuBuilder()
|
||||||
|
.setCustomId('quotes_list_mentionable')
|
||||||
|
.setPlaceholder('Filter By User')
|
||||||
|
)
|
||||||
|
|
||||||
|
const row = interaction.message.components[1]
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [select, row]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
module.exports =
|
||||||
|
function ping(interface, args, type){
|
||||||
|
if (type = 'legacy'){
|
||||||
|
// type = legacy
|
||||||
|
interface.reply('pang!')
|
||||||
|
} else {
|
||||||
|
interface.reply('pong!')
|
||||||
|
}
|
||||||
|
}
|
||||||