Merge branch 'dev' into 'main'

Added new commain (development)

See merge request illegitimate/illegitimate-bot!135
This commit is contained in:
2023-12-28 12:20:00 +00:00
122 changed files with 14278 additions and 1720 deletions

View File

@@ -12,4 +12,4 @@ docker-compose.yml
Dockerfile Dockerfile
Dockerfile.cache Dockerfile.cache
nodemon.json nodemon.json
README.old README.old

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
node_modules/* node_modules/*
.env .env
dist/

View File

@@ -3,12 +3,11 @@ FROM node-cache as cache
FROM node:20.9.0-alpine3.18 FROM node:20.9.0-alpine3.18
COPY --from=cache /node_modules /app/node_modules COPY --from=cache /node_modules /app/node_modules
COPY package.json /app
COPY yarn.lock /app
COPY . /app COPY . /app
WORKDIR /app WORKDIR /app
RUN yarn install RUN yarn global add typescript
RUN yarn build
CMD ["node", "src/index.js"] CMD [ "yarn", "start" ]

View File

@@ -3,4 +3,4 @@ FROM node:20.9.0-alpine3.18
COPY package.json ./ COPY package.json ./
COPY yarn.lock ./ COPY yarn.lock ./
RUN yarn install RUN yarn install

View File

@@ -7,5 +7,6 @@
"staffOtherChannel": "1082036748558803104", "staffOtherChannel": "1082036748558803104",
"hypixelGuildID": "5a353a170cf2e529044f2935", "hypixelGuildID": "5a353a170cf2e529044f2935",
"onlineLogChannel": "1101144489306886226", "onlineLogChannel": "1101144489306886226",
"botLogChannel": "1174403585149243472" "botLogChannel": "1174403585149243472",
"instructionsgif": "https://cdn.discordapp.com/attachments/838716950723952640/1188211176300089384/4DMu513uNxbM.gif?ex=6599b2e4&is=65873de4&hm=e727c7a39aacbc47d6a5453f4b5f792a45679983c30d662cd258a311381b6df0&"
} }

View File

@@ -2,11 +2,13 @@
"restartable": "rs", "restartable": "rs",
"ignore": [ "ignore": [
".git", ".git",
"node_modules/**/node_modules" "node_modules/**/node_modules",
"dist/config",
"src"
], ],
"verbose": true, "verbose": true,
"env": { "env": {
"NODE_ENV": "dev" "NODE_ENV": "dev"
}, },
"ext": "js,json" "ext": "js, json"
} }

View File

@@ -2,15 +2,17 @@
"name": "illegitimate-bot", "name": "illegitimate-bot",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "src/index.js", "main": "src/index.ts",
"scripts": { "scripts": {
"dev": "nodemon", "start": "node dist/src/index.js",
"dev:build": "node scripts/dev-deploy.js", "build": "tsc",
"dev:delete": "node scripts/delete-commands.js", "watch": "tsc -w",
"dev": "nodemon dist/src/index.js",
"dev:build": "ts-node scripts/dev-deploy.ts",
"dev:delete": "ts-node scripts/delete-commands.ts",
"lint": "eslint_d src", "lint": "eslint_d src",
"lint:fix": "eslint_d --fix src", "lint:fix": "eslint_d --fix src",
"prod:build:global": "node scripts/deploy-commands.js --prod", "prod:build": "ts-node scripts/deploy-commands.ts"
"prod:build:user": "node scripts/deploy-commands.js --dev"
}, },
"author": "Taken", "author": "Taken",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
@@ -23,5 +25,11 @@
"mongoose": "^7.0.1", "mongoose": "^7.0.1",
"ms": "^2.1.3", "ms": "^2.1.3",
"pretty-ms": "^8.0.0" "pretty-ms": "^8.0.0"
},
"devDependencies": {
"@types/ms": "^0.7.34",
"@types/node": "^20.10.5",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
} }
} }

View File

@@ -1,20 +0,0 @@
const { REST, Routes } = require("discord.js")
require("dotenv").config()
const token = process.env.DEVTOKEN
const clientId = process.env.DEVID
const guildId = process.env.GUILDID
const rest = new REST({ version: "10" }).setToken(token)
async function deleteCommands() {
try {
console.log("Started deleting application (/) commands.")
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: [] },
)
console.log("Successfully deleted application (/) commands.")
} catch (error) {
console.error(error)
}
}
deleteCommands()

View File

@@ -0,0 +1,18 @@
import { REST, Routes } from "discord.js"
import config from "../src/utils/Config"
const rest = new REST({ version: "10" }).setToken(config.dev.devtoken)
async function deleteCommands() {
try {
console.log("Started deleting application (/) commands.")
await rest.put(
Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
{ body: [] },
)
console.log("Successfully deleted application (/) commands.")
} catch (error) {
console.error(error)
}
}
deleteCommands()

View File

@@ -1,69 +0,0 @@
const { REST, Routes } = require("discord.js")
require("dotenv").config()
const token = process.env.TOKEN
const clientId = process.env.CLIENTID
const guildId = process.env.GUILDID
const rest = new REST({ version: "10" }).setToken(token)
const fs = require("node:fs")
const args = process.argv.slice(2)
const arg = args[0]
if (!arg) {
console.log("Please specify a command to run!")
}
else if (arg === "--prod") {
const commands = []
const commandFiles = fs.readdirSync("./src/commands").filter(file => file.endsWith(".js"))
const contentMenuCommands = fs.readdirSync("./src/commands-contextmenu").filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command = require(`../src/commands/${file}`)
commands.push(command.data.toJSON())
}
for (const file of contentMenuCommands) {
const command = require(`../src/commands-contextmenu/${file}`)
commands.push(command.data.toJSON())
}
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationCommands(clientId),
{ body: commands },
)
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) {
console.error(error)
}
})()
}
else if (arg === "--dev") {
const commands = []
const commandFiles = fs.readdirSync("./commands-testing").filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command = require(`../commands-testing/${file}`)
commands.push(command.data.toJSON())
}
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
)
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) {
console.error(error)
}
})()
}
else if (arg && arg !== "--prod" && arg !== "--dev") {
console.log("Invalid argument!")
}

View File

@@ -0,0 +1,33 @@
import { REST, RESTGetAPIApplicationGuildCommandResult, RESTPutAPIApplicationCommandsJSONBody, Routes } from "discord.js"
import fs from "node:fs"
import { Command } from "../src/interfaces"
import config from "../src/utils/Config"
const rest = new REST({ version: "10" }).setToken(config.prod.token)
const commands: RESTPutAPIApplicationCommandsJSONBody = []
const commandFiles = fs.readdirSync("./dist/src/commands").filter(file => file.endsWith(".js"))
const contentMenuCommands = fs.readdirSync("./dist/src/commands-contextmenu").filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command: Command = require(`../dist/src/commands/${file}`)
commands.push(command.data.toJSON())
}
for (const file of contentMenuCommands) {
const command: Command = require(`../dist/src/commands-contextmenu/${file}`)
commands.push(command.data.toJSON())
}
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationCommands(config.dev.clientid),
{ body: commands },
) as RESTGetAPIApplicationGuildCommandResult[]
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) {
console.error(error)
}
})()

View File

@@ -1,46 +0,0 @@
const { REST, Routes } = require("discord.js")
require("dotenv").config()
const token = process.env.DEVTOKEN
const clientId = process.env.DEVID
const guildId = process.env.GUILDID
const fs = require("fs")
const rest = new REST({ version: "10" }).setToken(token)
const commands = []
const commandFiles = fs.readdirSync("./src/commands/").filter(file => file.endsWith(".js"))
const contentMenuCommands = fs.readdirSync("./src/commands-contextmenu/").filter(file => file.endsWith(".js"))
const commandsTesting = fs.readdirSync("./src/commands-testing/").filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command = require(`../src/commands/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
for (const file of contentMenuCommands) {
const command = require(`../src/commands-contextmenu/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
for (const file of commandsTesting) {
const command = require(`../src/commands-testing/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
)
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) {
console.error(error)
}
})()

37
scripts/dev-deploy.ts Normal file
View File

@@ -0,0 +1,37 @@
import { REST, RESTGetAPIApplicationGuildCommandResult, RESTPutAPIApplicationCommandsJSONBody, Routes } from "discord.js"
import fs from "fs"
import config from "../src/utils/Config"
import { Command } from "../src/interfaces"
const rest = new REST({ version: "10" }).setToken(config.dev.devtoken)
const commands: RESTPutAPIApplicationCommandsJSONBody = []
const commandFiles = fs.readdirSync("./dist/src/commands/").filter(file => file.endsWith(".js"))
const contentMenuCommands = fs.readdirSync("./dist/src/commands-contextmenu/").filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command: Command = require(`../dist/src/commands/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
for (const file of contentMenuCommands) {
const command: Command = require(`../dist/src/commands-contextmenu/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
{ body: commands },
) as RESTGetAPIApplicationGuildCommandResult[]
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) {
console.error(error)
}
})()

View File

@@ -1,21 +1,21 @@
const { ContextMenuCommandBuilder, ApplicationCommandType, PermissionFlagsBits, userMention } = require("discord.js") import { ContextMenuCommandBuilder, ApplicationCommandType, PermissionFlagsBits, userMention } from "discord.js"
import { ContextMenu } from "../interfaces"
module.exports = { export = {
name: "congratsmessage", name: "congratsmessage",
description: "Congratulate a user.", description: "Congratulate a user.",
type: "contextmenu", type: "contextmenu",
dev: false,
data: new ContextMenuCommandBuilder() data: new ContextMenuCommandBuilder()
.setName("Congratulate") .setName("Congratulate")
.setType(ApplicationCommandType.Message) .setType(ApplicationCommandType.Message)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages), .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
/** @param { import('discord.js').ContextMenuCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const { targetId } = interaction const { targetId } = interaction
const message = await interaction.channel.messages.fetch(targetId) const message = await interaction.channel!.messages.fetch(targetId)
if (!message) { if (!message) {
return interaction.reply({ content: "That user does not exist.", ephemeral: true }) return interaction.reply({ content: "That user does not exist.", ephemeral: true })
@@ -33,4 +33,4 @@ module.exports = {
await interaction.reply({ content: "Sent a congrats message", ephemeral: true }) await interaction.reply({ content: "Sent a congrats message", ephemeral: true })
} }
} } as ContextMenu

View File

@@ -1,36 +0,0 @@
const { ContextMenuCommandBuilder, ApplicationCommandType, PermissionFlagsBits } = require("discord.js")
module.exports = {
name: "resetnick",
description: "Reset your nickname.",
type: "contextmenu",
data: new ContextMenuCommandBuilder()
.setName("Reset Nickname")
.setType(ApplicationCommandType.User)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageNicknames),
/** @param { import('discord.js').ContextMenuCommandInteraction } interaction */
async execute(interaction) {
const { targetId } = interaction
const target = await interaction.guild.members.fetch(targetId)
if (!target) {
return interaction.reply({ content: "That user does not exist.", ephemeral: true })
}
if (target.id === interaction.user.id) {
return interaction.reply({ content: "You can't reset your own nickname.", ephemeral: true })
}
if (!target.manageable) {
return interaction.reply({ content: "I cannot reset that user's nickname.", ephemeral: true })
}
await target.setNickname(target.user.username, "Reset by " + interaction.user.username + "#" + interaction.user.discriminator)
return interaction.reply({ content: `Reset ${target.user.username}'s nickname.`, ephemeral: true })
}
}

View File

@@ -0,0 +1,38 @@
import { ContextMenuCommandBuilder, ApplicationCommandType, PermissionFlagsBits } from "discord.js"
import { ContextMenu } from "../interfaces"
export = {
name: "resetnick",
description: "Reset your nickname.",
type: "contextmenu",
dev: false,
data: new ContextMenuCommandBuilder()
.setName("Reset Nickname")
.setType(ApplicationCommandType.User)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageNicknames),
async execute(interaction) {
const { targetId } = interaction
const target = await interaction.guild!.members.fetch(targetId)
if (!target) {
interaction.reply({ content: "That user does not exist.", ephemeral: true })
return
}
if (target.id === interaction.user.id) {
interaction.reply({ content: "You can't reset your own nickname.", ephemeral: true })
return
}
if (!target.manageable) {
interaction.reply({ content: "I cannot reset that user's nickname.", ephemeral: true })
return
}
await target.setNickname(target.user.username, "Reset by " + interaction.user.username + "#" + interaction.user.discriminator)
interaction.reply({ content: `Reset ${target.user.username}'s nickname.`, ephemeral: true })
}
} as ContextMenu

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
const { admin, helper } = require("../../config/roles.json") import { admin, helper } from "../../config/roles.json"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "ban", name: "ban",
description: "Ban a user", description: "Ban a user",
type: "slash", type: "slash",
@@ -38,32 +39,38 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const member = interaction.options.getMember("user") const member = interaction.options.getMember("user") as GuildMember | null
const reason = interaction.options.getString("reason") ?? "No reason provided." const reason = interaction.options.getString("reason") ?? "No reason provided."
const messageDeletionDays = interaction.options.getNumber("messagedeletiondays") ?? 0 const messageDeletionDays = interaction.options.getNumber("messagedeletiondays") ?? 0
const mod = await interaction.guild.members.fetch(interaction.user.id) const embedColor = Number(color.replace("#", "0x"))
if (!member) {
await interaction.editReply("You must specify a user.")
return
}
const mod = await interaction.guild!.members.fetch(interaction.user.id)
const memberRoles = member.roles.cache.map(role => role.id) const memberRoles = member.roles.cache.map(role => role.id)
const modRoles = mod.roles.cache.map(role => role.id) const modRoles = mod.roles.cache.map(role => role.id)
const embedColor = Number(color.replace("#", "0x"))
if (!modRoles.includes(admin)) { if (!modRoles.includes(admin)) {
await interaction.editReply("You do not have permission to use this command.") await interaction.editReply("You do not have permission to use this command.")
return return
} }
if (interaction.guild.members.me.roles.highest.position <= member.roles.highest.position) { if (interaction.guild!.members.me!.roles.highest.position <= member.roles.highest.position) {
await interaction.editReply("I cannot ban this member.") await interaction.editReply("I cannot ban this member.")
return return
} }
if (member.id === mod.id) { if (member.id === mod.id) {
return interaction.editReply("You cannot ban yourself.") await interaction.editReply("You cannot ban yourself.")
return
} }
if (member.id === interaction.applicationId) { if (member.id === interaction.applicationId) {
@@ -71,7 +78,7 @@ module.exports = {
return return
} }
if (member.id === interaction.guild.ownerId) { if (member.id === interaction.guild!.ownerId) {
await interaction.editReply("I ban kick the server owner.") await interaction.editReply("I ban kick the server owner.")
return return
} }
@@ -87,8 +94,8 @@ module.exports = {
} }
await member.ban({ await member.ban({
deleteMessageSeconds: messageDeletionDays * 86400, reason: reason,
reason: reason + ` - ${mod.user.username}` deleteMessageDays: messageDeletionDays
}) })
await interaction.editReply({ await interaction.editReply({
@@ -101,11 +108,11 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + member.user.id, text: "ID: " + member.user.id,
icon_url: member.user.avatarURL({ dynamic: true }) icon_url: member.user.avatarURL({ forceStatic: false }) || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} } as Command

View File

@@ -1,9 +1,10 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } = require("../../config/reqs.json") import { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } from "../../config/reqs.json"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } = require("../utils/utils.js") import { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } from "../utils/Hypixel"
import { Command } from "../interfaces"
module.exports = { export = {
name: "check", name: "check",
description: "Check a player's stats.", description: "Check a player's stats.",
type: "slash", type: "slash",
@@ -17,8 +18,6 @@ module.exports = {
.setDescription("The player's IGN.") .setDescription("The player's IGN.")
.setRequired(true)), .setRequired(true)),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({}) await interaction.deferReply({})
@@ -111,7 +110,7 @@ module.exports = {
if (!guild) { if (!guild) {
guildRank = "N/A" guildRank = "N/A"
} else { } else {
guildRank = guild.members.find((m) => m.uuid === uuid).rank guildRank = guild.members.find((m) => m.uuid === uuid)!.rank
} }
const statsFields = [] const statsFields = []
@@ -235,7 +234,7 @@ module.exports = {
const level = hypixelLevel(hypixelExp) const level = hypixelLevel(hypixelExp)
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -246,14 +245,14 @@ module.exports = {
"**Guild Rank:** `" + guildRank + "`", "**Guild Rank:** `" + guildRank + "`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
}, },
fields: statsFields fields: statsFields
}] }]
}) })
} }
} } as Command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, ChannelType, GuildTextBasedChannel } from "discord.js"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "clear", name: "clear",
description: "Clears messages", description: "Clears messages",
type: "slash", type: "slash",
@@ -19,14 +20,12 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
const amount = interaction.options.getInteger("amount") const amount = interaction.options.getInteger("amount")!
const channel = interaction.channel const channel2 = interaction.channel!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
if (!amount || amount < 1 || amount > 100) { if (!amount || amount < 1 || amount > 100) {
@@ -38,6 +37,17 @@ module.exports = {
}) })
} }
if (channel2.type !== ChannelType.GuildText) {
await interaction.editReply({
embeds: [{
description: "You can only clear messages in a text channel",
color: embedColor
}],
})
}
const channel = channel2 as GuildTextBasedChannel
channel.messages.fetch({ limit: amount }).then(async messages => { channel.messages.fetch({ limit: amount }).then(async messages => {
const messagesToDelete = messages.map(m => m) const messagesToDelete = messages.map(m => m)
.filter(m => .filter(m =>
@@ -56,4 +66,4 @@ module.exports = {
}) })
}) })
} }
} } as Command

View File

@@ -1,9 +1,10 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
const settings = require("../schemas/settingsSchema.js") import settings = require("../schemas/settingsSchema")
const mongoose = require("mongoose") import mongoose = require("mongoose")
import { Command } from "../interfaces"
module.exports = { export = {
name: "config", name: "config",
description: "Configure the bot", description: "Configure the bot",
type: "slash", type: "slash",
@@ -30,8 +31,6 @@ module.exports = {
.setDMPermission(false) .setDMPermission(false)
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
@@ -70,6 +69,5 @@ module.exports = {
}] }]
}) })
} }
} }
} } as Command

View File

@@ -1,9 +1,12 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from "discord.js"
module.exports = { import { Command } from "../interfaces"
const command: Command = {
name: "dev-info", name: "dev-info",
description: "Test command for the bot.", description: "Test command for the bot.",
type: "slash", type: "slash",
dev: true, dev: true,
public: false,
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName("dev-info") .setName("dev-info")
@@ -15,13 +18,11 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async execute(interaction: ChatInputCommandInteraction) {
async execute(interaction) { const test = interaction.options.getString("test")!
const test = interaction.options.getString("test") const message = await interaction.channel!.messages.fetch(test)
const message = await interaction.channel.messages.fetch(test)
const embed = message.embeds[0] const embed = message.embeds[0]
const fields = embed.fields const fields = embed.fields
const field1 = fields[0] const field1 = fields[0]
@@ -31,3 +32,5 @@ module.exports = {
await interaction.reply({ content: "Test command.", ephemeral: true }) await interaction.reply({ content: "Test command.", ephemeral: true })
} }
} }
export = command

View File

@@ -1,6 +1,7 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
import { Command } from "../interfaces"
module.exports = { export = {
name: "devel", name: "devel",
description: "Admin command.", description: "Admin command.",
type: "slash", type: "slash",
@@ -17,8 +18,6 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const subcommand = interaction.options.getSubcommand() const subcommand = interaction.options.getSubcommand()
@@ -28,7 +27,7 @@ module.exports = {
const { exec } = require("child_process") const { exec } = require("child_process")
await interaction.reply({ content: "Reloading...", ephemeral: true }) await interaction.reply({ content: "Reloading...", ephemeral: true })
exec("pm2 restart 0", async (err) => { exec("pm2 restart 0", async (err: Error) => {
if (err) { if (err) {
await interaction.reply({ content: "Error while reloading: " + err, ephemeral: true }) await interaction.reply({ content: "Error while reloading: " + err, ephemeral: true })
} }
@@ -36,4 +35,4 @@ module.exports = {
} }
} }
} } as Command

View File

@@ -1,10 +1,11 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const verify = require("../schemas/verifySchema.js") import verify = require("../schemas/verifySchema")
const { gm, manager, moderator, beast, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json") import { gm, manager, moderator, beast, member, guildRole, guildStaff, defaultMember } from "../../config/roles.json"
import { Command } from "../interfaces"
const removeThese = [gm, manager, moderator, beast, member, guildRole, guildStaff, defaultMember] const removeThese = [gm, manager, moderator, beast, member, guildRole, guildStaff, defaultMember]
module.exports = { export = {
name: "forceunverify", name: "forceunverify",
description: "Force unverify a user", description: "Force unverify a user",
type: "slash", type: "slash",
@@ -22,13 +23,10 @@ module.exports = {
.setDMPermission(false) .setDMPermission(false)
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const member1 = interaction.options.getUser("user") const member = interaction.options.getMember("user") as GuildMember
const member = interaction.guild.members.cache.get(member1.id)
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const verifiedUser = await verify.findOne({ userID: member1.id }) const verifiedUser = await verify.findOne({ userID: member.user.id })
if (!verifiedUser) { if (!verifiedUser) {
return interaction.reply({ return interaction.reply({
@@ -39,19 +37,19 @@ module.exports = {
}) })
} }
await verify.findOneAndDelete({ userID: member1.id }) await verify.findOneAndDelete({ userID: member.user.id })
await member.roles.remove(removeThese) await member.roles.remove(removeThese)
await interaction.reply({ await interaction.reply({
embeds: [{ embeds: [{
description: "Successfully unverified " + userMention(member1.id), description: "Successfully unverified " + userMention(member.user.id),
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,11 +1,12 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
const { getGuild, getHeadURL, getIGN } = require("../utils/utils.js") import { getGuild, getHeadURL, getIGN } from "../utils/Hypixel"
const { hypixelGuildID, color, devMessage } = require("../../config/options.json") import { hypixelGuildID, color, devMessage } from "../../config/options.json"
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json") import { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../config/roles.json"
const verify = require("../schemas/verifySchema.js") import verify = require("../schemas/verifySchema")
import { Command } from "../interfaces"
const removeThese = [gm, manager, moderator, beast, elite, member, guildRole, guildStaff] const removeThese = [gm, manager, moderator, beast, elite, member, guildRole, guildStaff]
module.exports = { export = {
name: "forceupdate", name: "forceupdate",
description: "Force update the user", description: "Force update the user",
type: "slash", type: "slash",
@@ -23,19 +24,16 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user = interaction.options.getUser("user") const user = interaction.options.getMember("user") as GuildMember
const usermentioned = userMention(user.id) const usermentioned = userMention(user.user.id)
const verifyData = await verify.findOne({ userID: user.id }) const verifyData = await verify.findOne({ userID: user.user.id })
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const user1 = interaction.guild.members.cache.get(user.id) const roleManage = user.roles
const roleManage = user1.roles
if (!verifyData) { if (!verifyData) {
await interaction.editReply({ await interaction.editReply({
@@ -43,8 +41,8 @@ module.exports = {
description: "User is not verified.", description: "User is not verified.",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -58,7 +56,7 @@ module.exports = {
}] }]
}) })
const ign = await getIGN(verifyData.uuid) const ign = await getIGN(verifyData.uuid) as string
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
await interaction.editReply({ await interaction.editReply({
@@ -70,7 +68,7 @@ module.exports = {
const guild = await getGuild(verifyData.uuid) const guild = await getGuild(verifyData.uuid)
let responseGuildID = "" let responseGuildID: string | null
if (!guild) { if (!guild) {
responseGuildID = null responseGuildID = null
} else { } else {
@@ -88,11 +86,11 @@ module.exports = {
description: usermentioned + " was given the the Default Member role.", description: usermentioned + " was given the the Default Member role.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -102,8 +100,8 @@ module.exports = {
if (responseGuildID === hypixelGuildID) { if (responseGuildID === hypixelGuildID) {
const GuildMembers = guild.members const GuildMembers = guild!.members
const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid).rank const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid)!.rank
if (guildRank === "Guild Master") { if (guildRank === "Guild Master") {
@@ -122,11 +120,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Guild Master`", description: usermentioned + "'s rank has been updated to `Guild Master`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -149,11 +147,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Manager`", description: usermentioned + "'s rank has been updated to `Manager`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -176,11 +174,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Moderator`", description: usermentioned + "'s rank has been updated to `Moderator`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -203,11 +201,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Beast`.", description: usermentioned + "'s rank has been updated to `Beast`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -230,11 +228,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Elite`.", description: usermentioned + "'s rank has been updated to `Elite`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -257,11 +255,11 @@ module.exports = {
description: usermentioned + "'s rank has been updated to `Member`.", description: usermentioned + "'s rank has been updated to `Member`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -269,4 +267,4 @@ module.exports = {
} }
} }
} }
} } as Command

View File

@@ -1,12 +1,12 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, GuildMember } from "discord.js"
const { getUUID, getPlayer, getGuild, getHeadURL } = require("../utils/utils.js") import { getUUID, getPlayer, getGuild, getHeadURL } from "../utils/Hypixel"
const { color, hypixelGuildID, devMessage } = require("../../config/options.json") import { color, hypixelGuildID, devMessage } from "../../config/options.json"
const verify = require("../schemas/verifySchema.js") import verify = require("../schemas/verifySchema")
const { mongoose } = require("mongoose") import mongoose from "mongoose"
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json") import { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../config/roles.json"
import { Command } from "../interfaces"
export = {
module.exports = {
name: "forceverify", name: "forceverify",
description: "Force verify a user.", description: "Force verify a user.",
type: "slash", type: "slash",
@@ -27,19 +27,16 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user1 = interaction.options.getUser("user") const user = interaction.member as GuildMember
const user = interaction.guild.members.cache.get(user1.id)
const ign = interaction.options.getString("ign") const ign = interaction.options.getString("ign")
const mod = interaction.user const mod = interaction.user
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const verifyData = await verify.findOne({ userID: user.id }) const verifyData = await verify.findOne({ userID: user.user.id })
if (verifyData) { if (verifyData) {
interaction.editReply("That user is already verified.") interaction.editReply("That user is already verified.")
return return
@@ -56,10 +53,10 @@ module.exports = {
} }
let username = "" let username = ""
if (user1.discriminator == "0") { if (user.user.discriminator == "0") {
username = user1.username username = user.user.username
} else { } else {
username = user1.username + "#" + user1.discriminator username = user.user.username + "#" + user.user.discriminator
} }
let modName = "" let modName = ""
@@ -113,7 +110,7 @@ module.exports = {
}) })
const guild = await getGuild(uuid) const guild = await getGuild(uuid)
let responseGuildID = "" let responseGuildID: string | null
if (!guild) { if (!guild) {
responseGuildID = null responseGuildID = null
} else { } else {
@@ -122,8 +119,8 @@ module.exports = {
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
if (responseGuildID === hypixelGuildID) { if (responseGuildID === hypixelGuildID) {
const GuildMembers = guild.members const GuildMembers = guild!.members
const guildRank = GuildMembers.find(member => member.uuid === player.uuid).rank const guildRank = GuildMembers.find(member => member.uuid === player.uuid)!.rank
if (guildRank === "Guild Master") { if (guildRank === "Guild Master") {
await user.roles.add(gm, "User was force verified by " + modName) await user.roles.add(gm, "User was force verified by " + modName)
@@ -171,18 +168,18 @@ module.exports = {
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
title: interaction.guild.name, title: interaction.guild!.name,
description: "You have successfully force verified `" + username + "` with the account `" + player.displayname + "`.", description: "You have successfully force verified `" + username + "` with the account `" + player.displayname + "`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
icon_url: interaction.guild.iconURL(), icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined,
text: interaction.guild.name + " | " + devMessage text: interaction.guild!.name + " | " + devMessage
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,10 +1,11 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const { guildMember } = require("./guild/member.js") import { Command } from "../interfaces"
const { guildInfo } = require("./guild/info.js") import guildMember = require("./guild/member")
const { guildTop } = require("./guild/top.js") import guildInfo = require("./guild/info")
import guildTop = require("./guild/top")
module.exports = { export = {
name: "guild", name: "guild",
description: "Subcommands for guilds", description: "Subcommands for guilds",
type: "slash", type: "slash",
@@ -72,8 +73,6 @@ module.exports = {
.setDescription("The amount of guild members to show. [Default: 10]")) .setDescription("The amount of guild members to show. [Default: 10]"))
), ),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const subcommand = interaction.options.getSubcommand() const subcommand = interaction.options.getSubcommand()
@@ -95,7 +94,7 @@ module.exports = {
} }
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: true })
await interaction.reply({ await interaction.reply({
embeds: [{ embeds: [{
@@ -103,9 +102,9 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,15 +1,15 @@
const { getUUID, getIGN, getPlayer, getGuild, guildLevel } = require("../../utils/utils.js") import { getUUID, getIGN, getPlayer, getGuild, guildLevel } from "../../utils/Hypixel"
const { color, devMessage } = require("../../../config/options.json") import { color, devMessage } from "../../../config/options.json"
import { ChatInputCommandInteraction } from "discord.js"
import { GuildData } from "../../interfaces/Guild"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async function guildInfo(interaction: ChatInputCommandInteraction): Promise<void> {
async function guildInfo(interaction) {
await interaction.deferReply() await interaction.deferReply()
const query = interaction.options.getString("query") const query = interaction.options.getString("query")!
const type = interaction.options.getString("type") || "ign" const type = interaction.options.getString("type") || "ign"
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
let guild let guild: GuildData | null
if (type === "ign") { if (type === "ign") {
await interaction.editReply({ await interaction.editReply({
@@ -103,14 +103,14 @@ async function guildInfo(interaction) {
} }
} }
const guildName = guild.name const guildName = guild!.name
const guildCreatedMS = guild.created const guildCreatedMS = guild!.created
const guildCreated = new Date(guildCreatedMS) const guildCreated = new Date(guildCreatedMS)
const guildTag = guild.tag const guildTag = guild!.tag
const guildExpUnformatted = guild.exp const guildExpUnformatted = guild!.exp
const guildExp = new Intl.NumberFormat("en-US").format(guildExpUnformatted) const guildExp = new Intl.NumberFormat("en-US").format(guildExpUnformatted)
const guildLvl = guildLevel(guildExpUnformatted) const guildLvl = guildLevel(guildExpUnformatted)
const guildMembers = guild.members const guildMembers = guild!.members
const guildCreatedDate = guildCreated.getDate() const guildCreatedDate = guildCreated.getDate()
const guildCreatedMonth = guildCreated.getMonth() + 1 const guildCreatedMonth = guildCreated.getMonth() + 1
@@ -126,9 +126,9 @@ async function guildInfo(interaction) {
guildCreatedMinute + ":" + guildCreatedMinute + ":" +
guildCreatedSecond guildCreatedSecond
const guildOwner = guildMembers.find((m) => m.rank === "Guild Master").uuid const guildOwner = guildMembers.find((m) => m.rank === "Guild Master")!.uuid
const guildOwnerName = await getIGN(guildOwner) const guildOwnerName = await getIGN(guildOwner)
const guildRanksUnsorted = guild.ranks.sort((a, b) => b.priority - a.priority) const guildRanksUnsorted = guild!.ranks.sort((a, b) => b.priority - a.priority)
const guildRanks = guildRanksUnsorted.map((r) => "**➺ " + r.name + "** `[" + r.tag + "]`").join("\n") const guildRanks = guildRanksUnsorted.map((r) => "**➺ " + r.name + "** `[" + r.tag + "]`").join("\n")
const allGuildMembersWeeklyXP = guildMembers.map(member => member.expHistory) const allGuildMembersWeeklyXP = guildMembers.map(member => member.expHistory)
@@ -143,7 +143,7 @@ async function guildInfo(interaction) {
const averageGuildMembersWeeklyXP = new Intl.NumberFormat("en-US").format(averageGuildMembersWeeklyXPUnformatted) const averageGuildMembersWeeklyXP = new Intl.NumberFormat("en-US").format(averageGuildMembersWeeklyXPUnformatted)
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -171,10 +171,10 @@ async function guildInfo(interaction) {
color: embedColor, color: embedColor,
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
} }
}] }]
}) })
} }
module.exports = { guildInfo } export = guildInfo

View File

@@ -1,12 +1,11 @@
const { getUUID, getPlayer, getGuild, getHeadURL } = require("../../utils/utils.js") import { getUUID, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
const { color, devMessage } = require("../../../config/options.json") import { color, devMessage } from "../../../config/options.json"
import { ChatInputCommandInteraction } from "discord.js"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async function guildMember(interaction: ChatInputCommandInteraction): Promise<void> {
async function guildMember(interaction) {
await interaction.deferReply() await interaction.deferReply()
const ign = interaction.options.getString("ign") const ign = interaction.options.getString("ign")!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
await interaction.editReply({ await interaction.editReply({
@@ -45,11 +44,11 @@ async function guildMember(interaction) {
description: "This user never logged on to hypixel", description: "This user never logged on to hypixel",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head, url: head!,
}, },
footer: { footer: {
text: interaction?.guild.name || interaction.user.username + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction?.guild.iconURL({ dynamic: true }) || interaction.user.avatarURL({ dynamic: true }), icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
}, },
], ],
@@ -88,11 +87,11 @@ async function guildMember(interaction) {
description: "This user is not in a guild", description: "This user is not in a guild",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head, url: head!,
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }), icon_url: interaction.guild!.iconURL({ forceStatic: false })!,
}, },
}], }],
}) })
@@ -104,8 +103,8 @@ async function guildMember(interaction) {
const guildMembers = guild.members const guildMembers = guild.members
const guildMember = guildMembers.find((member) => member.uuid === uuid) const guildMember = guildMembers.find((member) => member.uuid === uuid)
const guildRank = guildMember.rank const guildRank = guildMember!.rank
const memberGexp = guildMember.expHistory const memberGexp = guildMember!.expHistory
const allDaysGexp = Object.keys(memberGexp).map((key) => { const allDaysGexp = Object.keys(memberGexp).map((key) => {
return "**➺ " + key + ":** " + "`" + new Intl.NumberFormat("en-US").format(memberGexp[key]) + "`" + "\n" return "**➺ " + key + ":** " + "`" + new Intl.NumberFormat("en-US").format(memberGexp[key]) + "`" + "\n"
}) })
@@ -115,7 +114,7 @@ async function guildMember(interaction) {
const averageWeeklyGexpUnformatted = Math.round(totalWeeklyGexpUnformatted / 7) const averageWeeklyGexpUnformatted = Math.round(totalWeeklyGexpUnformatted / 7)
const averageWeeklyGexp = new Intl.NumberFormat("en-US").format(averageWeeklyGexpUnformatted) const averageWeeklyGexp = new Intl.NumberFormat("en-US").format(averageWeeklyGexpUnformatted)
const guildMemberJoinMS = guildMember.joined const guildMemberJoinMS = guildMember!.joined
const guildMemberJoinTime = new Date(guildMemberJoinMS) const guildMemberJoinTime = new Date(guildMemberJoinMS)
const guildMemberJoinDate = guildMemberJoinTime.getDate() const guildMemberJoinDate = guildMemberJoinTime.getDate()
const guildMemberJoinMonth = guildMemberJoinTime.getMonth() + 1 const guildMemberJoinMonth = guildMemberJoinTime.getMonth() + 1
@@ -133,7 +132,7 @@ async function guildMember(interaction) {
guildMemberJoinSeconds guildMemberJoinSeconds
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -142,7 +141,7 @@ async function guildMember(interaction) {
"**Guild Rank:** `" + guildRank + "`\n", "**Guild Rank:** `" + guildRank + "`\n",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head, url: head!,
}, },
fields: [ fields: [
{ {
@@ -161,10 +160,10 @@ async function guildMember(interaction) {
], ],
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
}, },
}], }],
}) })
} }
module.exports = { guildMember } export = guildMember

View File

@@ -1,20 +1,19 @@
const { getUUID, getPlayer, getGuild, getIGN } = require("../../utils/utils.js") import { getUUID, getPlayer, getGuild, getIGN } from "../../utils/Hypixel"
const { color, devMessage } = require("../../../config/options.json") import { color, devMessage } from "../../../config/options.json"
const { ChannelType } = require("discord.js") import { ChannelType, ChatInputCommandInteraction } from "discord.js"
const { redis } = require("../../utils/redis.js") import { redis } from "../../utils/Redis"
import { GuildData } from "../../interfaces/Guild"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async function guildTop(interaction: ChatInputCommandInteraction): Promise<void> {
async function guildTop(interaction) {
await interaction.deferReply() await interaction.deferReply()
const query = interaction.options.getString("query") const query = interaction.options.getString("query")!
const type = interaction.options.getString("type") || "ign" const type = interaction.options.getString("type") || "ign"
let amount = interaction.options.getNumber("amount") || 10 let amount = interaction.options.getNumber("amount") || 10
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
let guild let guild: GuildData | null
if (interaction.channel.type === ChannelType.DM) { if (interaction.channel!.type === ChannelType.DM) {
interaction.editReply({ interaction.editReply({
embeds: [{ embeds: [{
description: "You can't use this command in DMs!", description: "You can't use this command in DMs!",
@@ -116,9 +115,9 @@ async function guildTop(interaction) {
} }
} }
const guildName = guild.name const guildName = guild!.name
const guildMembers = guild.members const guildMembers = guild!.members
const guildId = guild._id const guildId = guild!._id
const cachedData = await redis.get("guildTop+" + guildId) const cachedData = await redis.get("guildTop+" + guildId)
@@ -145,9 +144,12 @@ async function guildTop(interaction) {
amount = 1 amount = 1
} }
let cacheStatus type GuildTopData = { ign: string, gexp: string }[]
let guildData = [] type NewList = { name: string, value: string, inline: boolean }[]
const fieldsValueRaw = []
let cacheStatus: boolean
let guildData: GuildTopData = []
const fieldsValueRaw: string[] = []
const allMembersSorted = allMembersDailyGEXP.sort((a, b) => b.gexp - a.gexp) const allMembersSorted = allMembersDailyGEXP.sort((a, b) => b.gexp - a.gexp)
if (!cachedData) { if (!cachedData) {
@@ -160,7 +162,7 @@ async function guildTop(interaction) {
}) })
for (let i = 0; i < allMembersSorted.length; i++) { for (let i = 0; i < allMembersSorted.length; i++) {
const ign = await getIGN(allMembersSorted[i].uuid) const ign = await getIGN(allMembersSorted[i].uuid) as string
const gexpUnformatted = allMembersSorted[i].gexp const gexpUnformatted = allMembersSorted[i].gexp
const gexp = new Intl.NumberFormat("en-US").format(gexpUnformatted) const gexp = new Intl.NumberFormat("en-US").format(gexpUnformatted)
@@ -195,7 +197,7 @@ async function guildTop(interaction) {
} }
const list = Array.from({ length: sliceSize }, (_, i) => fieldsValueRaw.slice(i * sliceSize, (i + 1) * sliceSize)) const list = Array.from({ length: sliceSize }, (_, i) => fieldsValueRaw.slice(i * sliceSize, (i + 1) * sliceSize))
const newList = [] const newList: NewList = []
list.forEach((item, index) => { list.forEach((item, index) => {
if (item.length === 0) return if (item.length === 0) return
@@ -208,7 +210,7 @@ async function guildTop(interaction) {
}) })
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
const cacheStatusText = cacheStatus ? " | [Cache]" : "" const cacheStatusText = cacheStatus ? " | [Cache]" : ""
await interaction.editReply({ await interaction.editReply({
@@ -220,10 +222,10 @@ async function guildTop(interaction) {
fields: newList, fields: newList,
footer: { footer: {
text: footerText + " | " + devMessage + cacheStatusText, text: footerText + " | " + devMessage + cacheStatusText,
icon_url: footerIcon icon_url: footerIcon!
} }
}] }]
}) })
} }
module.exports = { guildTop } export = guildTop

View File

@@ -1,73 +0,0 @@
const { SlashCommandBuilder } = require("discord.js")
const { color, devMessage } = require("../../config/options.json")
const fs = require("fs")
module.exports = {
name: "help",
description: "Help command",
type: "slash",
dev: false,
public: true,
data: new SlashCommandBuilder()
.setName("help")
.setDescription("List's all commands usable by a member")
.setDMPermission(true),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
const commands = []
const commandFiles = fs.readdirSync(__dirname).filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command = require(`./${file}`)
if (command.public && !command.subcommands) {
commands.push(command)
} else if (command.public && command.subcommands) {
const commandName = command.data.name
const subcommands = command.data.options.map((subcommand) => {
return {
name: commandName + " " + subcommand.name,
description: subcommand.description
}
})
for (const subcommand of subcommands) {
commands.push(subcommand)
}
}
}
const commandList = commands.map((command) => {
return {
name: "**/" + command.name + "**",
value: "`" + command.description + "`"
}
})
const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true })
await interaction.editReply({
embeds: [{
title: "Commands",
description: "List of commands",
fields: commandList,
color: embedColor,
thumbnail: {
url: interaction?.guild?.iconURL({ dynamic: true }) || null
},
footer: {
icon_url: footerIcon,
text: footerText + " | " + devMessage
}
}]
})
}
}

79
src/commands/help.ts Normal file
View File

@@ -0,0 +1,79 @@
import { SlashCommandBuilder } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
export = {
name: "help",
description: "Help command",
type: "slash",
dev: false,
public: true,
data: new SlashCommandBuilder()
.setName("help")
.setDescription("List's all commands usable by a member")
.setDMPermission(true),
async execute(interaction, client) {
await interaction.deferReply({ ephemeral: true })
type CommandList = {
name: string,
value: string
}
const commandList: CommandList[] = []
const commandRawList = client.commands.map((command) => {
return {
name: command.name,
command: command
}
})
for (const command of commandRawList) {
const commandName = command.name
if (!command.command.subcommands && command.command.public) {
commandList.push({
name: "**/" + commandName + "**",
value: "`" + command.command.description + "`"
})
} else if (command.command.subcommands && command.command.public) {
const subcommands = command.command.data.options.map((subcommand) => {
return {
name: commandName + " " + subcommand.toJSON().name,
description: subcommand.toJSON().description
}
})
for (const subcommand of subcommands) {
commandList.push({
name: "**/" + subcommand.name + "**",
value: "`" + subcommand.description + "`"
})
}
}
}
const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({
embeds: [{
title: "Commands",
description: "List of commands",
fields: commandList,
color: embedColor,
thumbnail: {
url: interaction?.guild?.iconURL({ forceStatic: true })!
},
footer: {
icon_url: footerIcon!,
text: footerText + " | " + devMessage
}
}]
})
}
} as Command

View File

@@ -0,0 +1,42 @@
import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
import { color, devMessage, instructionsgif } from "../../config/options.json"
import { Command } from "../interfaces"
export = {
name: "instructions",
description: "Instructions for verification",
type: "slash",
dev: false,
public: false,
data: new SlashCommandBuilder()
.setName("instructions")
.setDescription("Instructions for verification")
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction) {
const embedColor = Number(color.replace("#", "0x"))
await interaction.reply({
embeds: [{
title: "Verification",
description: "1. Log onto hypixel.\n" +
"2. Right click with the head in your hotbar.\n" +
"3. Click on the social media icon.\n" +
"4. Click on the discord icon.\n" +
"5. Type your username in the chat and press enter.\n" +
"6. Run the `/verify` command in this channel.\n",
color: embedColor,
footer: {
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
image: {
url: instructionsgif,
proxy_url: instructionsgif
}
}]
})
}
} as Command

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
const { admin, helper } = require("../../config/roles.json") import { admin, helper } from "../../config/roles.json"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "kick", name: "kick",
description: "Kick a member from the server.", description: "Kick a member from the server.",
type: "slash", type: "slash",
@@ -24,18 +25,22 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers) .setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const member = interaction.options.getMember("member") const member = interaction.options.getMember("member") as GuildMember | null
const reason = interaction.options.getString("reason") ?? "No reason provided." const reason = interaction.options.getString("reason") ?? "No reason provided."
const mod = await interaction.guild.members.fetch(interaction.user.id) const embedColor = Number(color.replace("#", "0x"))
if (!member) {
await interaction.editReply("You must specify a member.")
return
}
const mod = await interaction.guild!.members.fetch(interaction.user.id)
const memberRoles = member.roles.cache.map(role => role.id) const memberRoles = member.roles.cache.map(role => role.id)
const modRoles = mod.roles.cache.map(role => role.id) const modRoles = mod.roles.cache.map(role => role.id)
const embedColor = Number(color.replace("#", "0x"))
if (!modRoles.includes(helper) && !modRoles.includes(admin)) { if (!modRoles.includes(helper) && !modRoles.includes(admin)) {
await interaction.editReply("You do not have permission to use this command.") await interaction.editReply("You do not have permission to use this command.")
@@ -47,13 +52,14 @@ module.exports = {
return return
} }
if (member.id === interaction.guild.ownerId) { if (member.id === interaction.guild!.ownerId) {
await interaction.editReply("I cannot kick the server owner.") await interaction.editReply("I cannot kick the server owner.")
return return
} }
if (member.id === mod.id) { if (member.id === mod.id) {
return interaction.editReply("You cannot kick yourself.") await interaction.editReply("You cannot kick yourself.")
return
} }
if (memberRoles.includes(helper) || memberRoles.includes(admin)) { if (memberRoles.includes(helper) || memberRoles.includes(admin)) {
@@ -77,11 +83,11 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + member.user.id, text: "ID: " + member.user.id,
icon_url: member.user.avatarURL({ dynamic: true }) icon_url: member.user.avatarURL({ forceStatic: false }) || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} } as Command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "ping", name: "ping",
description: "Get the bot's ping.", description: "Get the bot's ping.",
type: "slash", type: "slash",
@@ -12,18 +13,13 @@ module.exports = {
.setName("ping") .setName("ping")
.setDescription("Get's the bot's ping."), .setDescription("Get's the bot's ping."),
/**
* @param { import("discord.js").ChatInputCommandInteraction } interaction
* @param { import("discord.js").Client } client}
*/
async execute(interaction, client) { async execute(interaction, client) {
await interaction.deferReply() await interaction.deferReply()
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -31,10 +27,10 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} } as Command

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention } from "discord.js"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
const { waitinglistSchema } = require("../schemas/waitinglistSchema.js") import waitinglistSchema = require("../schemas/waitinglistSchema")
import { Command } from "../interfaces"
module.exports = { export = {
name: "remove", name: "remove",
description: "Remove a person on the waiting list.", description: "Remove a person on the waiting list.",
type: "slash", type: "slash",
@@ -27,15 +28,13 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
interaction.deferReply() await interaction.deferReply()
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")!
const reason = interaction.options.getString("reason") ?? "No reason provided." const reason = interaction.options.getString("reason") ?? "No reason provided."
const mod = interaction.user const mod = interaction.user!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const waitinglist = await waitinglistSchema.findOne({ UserID: user.id }) const waitinglist = await waitinglistSchema.findOne({ UserID: user.id })
@@ -44,7 +43,7 @@ module.exports = {
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
description: userMention(user.id) + " is not on the waiting list.", description: userMention(user.id) + " is not on the waiting list.",
color: color color: embedColor
}] }]
}) })
return return
@@ -60,10 +59,10 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "User ID: " + user.id, text: "User ID: " + user.id,
icon_url: user.displayAvatarURL( { dynamic: true }) icon_url: user.displayAvatarURL({ forceStatic: false })
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} } as Command

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } = require("../../config/reqs.json") import { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } from "../../config/reqs.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "reqs", name: "reqs",
description: "Displays the requirements for the guild.", description: "Displays the requirements for the guild.",
type: "slash", type: "slash",
@@ -13,15 +14,13 @@ module.exports = {
.setName("reqs") .setName("reqs")
.setDescription("Displays the requirements for the guild."), .setDescription("Displays the requirements for the guild."),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -29,7 +28,7 @@ module.exports = {
description: "**You must make 100k-150k weekly GEXP.\nAs well as onne of the game stats below**", description: "**You must make 100k-150k weekly GEXP.\nAs well as onne of the game stats below**",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: interaction?.guild?.iconURL({ dynamic: true }) || null url: interaction?.guild?.iconURL({ forceStatic: false }) || ""
}, },
fields: [ fields: [
{ {
@@ -51,9 +50,9 @@ module.exports = {
], ],
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon || undefined
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,62 +0,0 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js")
const { color, devMessage } = require("../../config/options.json")
module.exports = {
name: "send",
description: "Send a message to a channel.",
type: "slash",
dev: false,
public: false,
data: new SlashCommandBuilder()
.setName("send")
.setDescription("Send a message to a channel.")
.addStringOption(option =>
option
.setName("message")
.setDescription("The message to send."))
.addChannelOption(option =>
option
.setName("channel")
.setDescription("The channel to send the message to."))
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
const message = interaction.options.getString("message")
const channel = interaction.options.getChannel("channel")
const embedColor = Number(color.replace("#", "0x"))
if (!message) {
interaction.editReply({ content: "Please provide a message to send.", ephemeral: true })
return
}
if (!channel) {
interaction.editReply({ content: "Please provide a channel to send the message to.", ephemeral: true })
return
}
channel.send({
embeds: [
{
title: interaction.guild.name,
description: message,
color: embedColor,
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
},
footer: {
text: interaction.guild.id + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
}
}
]
})
}
}

79
src/commands/send.ts Normal file
View File

@@ -0,0 +1,79 @@
import { SlashCommandBuilder, PermissionFlagsBits, ChannelType, GuildTextBasedChannel } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
export = {
name: "send",
description: "Send a message to a channel.",
type: "slash",
dev: false,
public: false,
data: new SlashCommandBuilder()
.setName("send")
.setDescription("Send a message to a channel.")
.addStringOption(option =>
option
.setName("message")
.setDescription("The message to send.")
.setRequired(true))
.addChannelOption(option =>
option
.setName("channel")
.setDescription("The channel to send the message to."))
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
const message = interaction.options.getString("message")!
const channel2 = interaction.options.getChannel("channel") ?? interaction.channel
const embedColor = Number(color.replace("#", "0x"))
if (channel2?.type !== ChannelType.GuildText) {
await interaction.editReply({
embeds: [{
description: "You can only send a message to a text channel.",
color: embedColor,
footer: {
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
}
}]
})
return
}
const channel = channel2 as GuildTextBasedChannel
channel.send({
embeds: [
{
title: interaction.guild!.name,
description: message,
color: embedColor,
thumbnail: {
url: interaction.guild!.iconURL({ forceStatic: false })!
},
footer: {
text: interaction.guild!.id + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: true }) || undefined
}
}
]
})
await interaction.editReply({
embeds: [{
description: "Message sent.",
color: embedColor,
footer: {
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
}
}]
})
}
} as Command

View File

@@ -1,6 +1,7 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention } from "discord.js"
import { Command } from "../interfaces"
module.exports = { export = {
name: "setnick", name: "setnick",
description: "Set your nickname", description: "Set your nickname",
type: "slash", type: "slash",
@@ -23,16 +24,15 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.ManageNicknames) .setDefaultMemberPermissions(PermissionFlagsBits.ManageNicknames)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")!
const nickname = interaction.options.getString("nickname") const nickname = interaction.options.getString("nickname")
const member = await interaction.guild.members.fetch(user.id) const member = await interaction.guild!.members.fetch(user.id)
if (!member.manageable) { if (!member.manageable) {
return interaction.reply({ content: "I cannot set the nickname for this user!", ephemeral: true }) interaction.reply({ content: "I cannot set the nickname for this user!", ephemeral: true })
return
} }
await member.setNickname(nickname, `Set by ${interaction.user.tag}`) await member.setNickname(nickname, `Set by ${interaction.user.tag}`)
@@ -40,4 +40,4 @@ module.exports = {
await interaction.reply({ content: "Set the nickname of " + userMention(member.id) + " to " + nickname, ephemeral: true }) await interaction.reply({ content: "Set the nickname of " + userMention(member.id) + " to " + nickname, ephemeral: true })
} }
} } as Command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder, PermissionFlagsBits, ButtonBuilder, ActionRowBuilder, ButtonStyle, } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, ButtonBuilder, ActionRowBuilder, ButtonStyle, ChannelType, GuildTextBasedChannel } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "setup", name: "setup",
description: "Used for setup of the bot.", description: "Used for setup of the bot.",
type: "slash", type: "slash",
@@ -61,45 +62,57 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const subcommand = interaction.options.getSubcommand() const subcommand = interaction.options.getSubcommand()
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
if (subcommand === "sendguildapplication") { if (subcommand === "sendguildapplication") {
const channel = interaction.options.getChannel("channel") const channel2 = interaction.options.getChannel("channel")!
if (channel2.type !== ChannelType.GuildText) {
await interaction.reply({ content: "That channel is not a text channel.", ephemeral: true })
return
}
const channel = channel2 as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [ embeds: [{
{ title: "Guild Application",
title: "Guild Application", description: "You can apply for the guild by clicking the button below.",
description: "You can apply for the guild by clicking the button below.", color: embedColor,
color: embedColor, footer: {
footer: { text: interaction.guild!.name + " | " + devMessage,
text: interaction.guild.name + " | " + devMessage, icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
iconURL: interaction.guild.iconURL({ dynamic: true }) },
}, thumbnail: {
thumbnail: { url: interaction.guild!.iconURL({ forceStatic: false }) || ""
url: interaction.guild.iconURL({ dynamic: true })
}
} }
], }],
components: [ components: [
new ActionRowBuilder() new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder() .addComponents(
new ButtonBuilder()
.setCustomId("guildapply") .setCustomId("guildapply")
.setLabel("Apply") .setLabel("Apply")
.setStyle(ButtonStyle.Primary) .setStyle(ButtonStyle.Primary)
.setEmoji({ name: "✅" })) .setEmoji({ name: "✅" })
)
] ]
}) })
await interaction.reply({ content: "Message sent", ephemeral: true }) await interaction.reply({ content: "Message sent", ephemeral: true })
} }
if (subcommand === "sendstaffapplication") { if (subcommand === "sendstaffapplication") {
const channel = interaction.options.getChannel("channel") const channel2 = interaction.options.getChannel("channel")!
if (channel2.type !== ChannelType.GuildText) {
await interaction.reply({ content: "That channel is not a text channel.", ephemeral: true })
return
}
const channel = channel2 as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [ embeds: [
@@ -108,16 +121,16 @@ module.exports = {
description: "You can apply for the staff team by clicking the button below.", description: "You can apply for the staff team by clicking the button below.",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
thumbnail: { thumbnail: {
url: interaction.guild.iconURL({ dynamic: true }) url: interaction.guild!.iconURL({ forceStatic: false })!
} }
} }
], ],
components: [ components: [
new ActionRowBuilder() new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setCustomId("staffapply") .setCustomId("staffapply")
.setLabel("Apply") .setLabel("Apply")
@@ -130,7 +143,14 @@ module.exports = {
} }
if (subcommand === "sendinactivityapplication") { if (subcommand === "sendinactivityapplication") {
const channel = interaction.options.getChannel("channel") const channel2 = interaction.options.getChannel("channel")!
if (channel2.type !== ChannelType.GuildText) {
await interaction.reply({ content: "That channel is not a text channel.", ephemeral: true })
return
}
const channel = channel2 as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [ embeds: [
@@ -139,16 +159,16 @@ module.exports = {
description: "You can send an inactivity log by clicking the button below.", description: "You can send an inactivity log by clicking the button below.",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
thumbnail: { thumbnail: {
url: interaction.guild.iconURL({ dynamic: true }) url: interaction.guild!.iconURL({ forceStatic: false })!
} }
} }
], ],
components: [ components: [
new ActionRowBuilder() new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setCustomId("guildinactivitylog") .setCustomId("guildinactivitylog")
.setLabel("Submit") .setLabel("Submit")
@@ -161,7 +181,14 @@ module.exports = {
} }
if (subcommand === "sendverfiymessage") { if (subcommand === "sendverfiymessage") {
const channel = interaction.options.getChannel("channel") const channel2 = interaction.options.getChannel("channel")!
if (channel2.type !== ChannelType.GuildText) {
await interaction.reply({ content: "That channel is not a text channel.", ephemeral: true })
return
}
const channel = channel2 as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [{ embeds: [{
@@ -169,15 +196,15 @@ module.exports = {
description: "You can verify by clicking the button below.", description: "You can verify by clicking the button below.",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
thumbnail: { thumbnail: {
url: interaction.guild.iconURL({ dynamic: true }) url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}], }],
components: [ components: [
new ActionRowBuilder() new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setCustomId("verify") .setCustomId("verify")
.setLabel("Verify") .setLabel("Verify")
@@ -190,7 +217,14 @@ module.exports = {
} }
if (subcommand === "sendwaitinglistmessage") { if (subcommand === "sendwaitinglistmessage") {
const channel = interaction.options.getChannel("channel") const channel2 = interaction.options.getChannel("channel")!
if (channel2.type !== ChannelType.GuildText) {
await interaction.reply({ content: "That channel is not a text channel.", ephemeral: true })
return
}
const channel = channel2 as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [{ embeds: [{
@@ -199,15 +233,15 @@ module.exports = {
"Try to invite them in order.", "Try to invite them in order.",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
thumbnail: { thumbnail: {
url: interaction.guild.iconURL({ dynamic: true }) url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}], }],
components: [ components: [
new ActionRowBuilder() new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setCustomId("waitinglistupdate") .setCustomId("waitinglistupdate")
.setLabel("Update") .setLabel("Update")
@@ -219,4 +253,4 @@ module.exports = {
} }
} }
} } as Command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, ChannelType, GuildTextBasedChannel } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "slowmode", name: "slowmode",
description: "Set the slowmode of a channel.", description: "Set the slowmode of a channel.",
type: "slash", type: "slash",
@@ -22,16 +23,30 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({ ephermeral: true }) await interaction.deferReply({ ephemeral: true })
const seconds = interaction.options.getInteger("seconds") ?? 5 const seconds = interaction.options.getInteger("seconds") ?? 5
const channel = interaction.options.getChannel("channel") ?? interaction.channel const channel2 = interaction.options.getChannel("channel") ?? interaction.channel
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
if (channel2?.type !== ChannelType.GuildText) {
await interaction.editReply({
embeds: [{
description: "You can only set the slowmode of a text channel.",
color: embedColor,
footer: {
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
}
}]
})
return
}
const channel = channel2 as GuildTextBasedChannel
if (seconds > 21600) { if (seconds > 21600) {
await channel.setRateLimitPerUser(21600) await channel.setRateLimitPerUser(21600)
await interaction.editReply({ await interaction.editReply({
@@ -39,8 +54,8 @@ module.exports = {
description: `Set the slowmode of ${channel} to 21600 seconds.`, description: `Set the slowmode of ${channel} to 21600 seconds.`,
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
} }
}] }]
}) })
@@ -52,12 +67,12 @@ module.exports = {
description: `Set the slowmode of ${channel} to ${seconds} seconds.`, description: `Set the slowmode of ${channel} to ${seconds} seconds.`,
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: true }) || undefined
} }
}] }]
}) })
await channel.setRateLimitPerUser(seconds) await channel.setRateLimitPerUser(seconds)
} }
} } as Command

View File

@@ -1,9 +1,11 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const { beast } = require("./staff/beast.js") import { Command } from "../interfaces"
const { help } = require("./staff/help.js") import { help} from "./staff/help"
import { beast } from "./staff/beast"
import { updateDiscordRoles } from "./staff/updatediscordroles"
module.exports = { export = {
name: "staff", name: "staff",
description: "Subcommands for staff", description: "Subcommands for staff",
type: "slash", type: "slash",
@@ -29,18 +31,21 @@ module.exports = {
.setRequired(true) .setRequired(true)
) )
) )
.addSubcommand(subcommand =>
subcommand
.setName("updatediscordroles")
.setDescription("Update the discord roles of all guild members")
)
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async execute(interaction, client) {
async execute(interaction) {
const subcommand = interaction.options.getSubcommand() const subcommand = interaction.options.getSubcommand()
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
if (subcommand === "help") { if (subcommand === "help") {
help(interaction) help(interaction, client)
return return
} }
@@ -49,8 +54,13 @@ module.exports = {
return return
} }
if (subcommand === "updatediscordroles") {
updateDiscordRoles(interaction)
return
}
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.reply({ await interaction.reply({
embeds: [{ embeds: [{
@@ -58,9 +68,9 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,13 +1,12 @@
const { bwwins, beastbwfkdr, beastbwstars, beastswkdr, beastswstars, beastduelswins, duelswlr } = require("../../../config/reqs.json") import { bwwins, beastbwfkdr, beastbwstars, beastswkdr, beastswstars, beastduelswins, duelswlr } from "../../../config/reqs.json"
const { color, devMessage } = require("../../../config/options.json") import { color, devMessage } from "../../../config/options.json"
const { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } = require("../../utils/utils.js") import { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
import { ChatInputCommandInteraction } from "discord.js"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ export async function beast(interaction: ChatInputCommandInteraction): Promise<void> {
async function beast(interaction) {
await interaction.deferReply() await interaction.deferReply()
const ign = interaction.options.getString("ign") const ign = interaction.options.getString("ign")!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
if (!ign) { if (!ign) {
@@ -212,7 +211,7 @@ async function beast(interaction) {
const level = hypixelLevel(hypixelExp) const level = hypixelLevel(hypixelExp)
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
@@ -222,15 +221,13 @@ async function beast(interaction) {
"**Current Guild:** `" + guildName + "`", "**Current Guild:** `" + guildName + "`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon!
}, },
fields: statsFields fields: statsFields
}] }]
}) })
} }
module.exports = { beast }

View File

@@ -1,59 +0,0 @@
const { color, devMessage } = require("../../../config/options.json")
const fs = require("fs")
const path = require("path")
/** @param { import("discord.js").ChatInputCommandInteraction } interaction */
async function help(interaction) {
const commands = []
const commandFiles = fs.readdirSync(path.join(__dirname, "..")).filter(file => file.endsWith(".js"))
for (const file of commandFiles) {
const command = require(`../../commands/${file}`)
if (!command.public && !command.subcommands) {
commands.push(command)
} else if (!command.public && command.subcommands) {
const commandName = command.data.name
const subcommands = command.data.options.map((subcommand) => {
return {
name: commandName + " " + subcommand.name,
description: subcommand.description
}
})
for (const subcommand of subcommands) {
commands.push(subcommand)
}
}
}
const commandList = commands.map((command) => {
return {
name: "**/" + command.name + "**",
value: "`" + command.description + "`"
}
})
const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true })
await interaction.reply({
embeds: [{
title: "Commands",
description: "List of commands",
fields: commandList,
color: embedColor,
thumbnail: {
url: interaction?.guild?.iconURL({ dynamic: true }) || null
},
footer: {
icon_url: footerIcon,
text: footerText + " | " + devMessage
}
}],
ephemeral: true
})
}
module.exports = { help }

View File

@@ -0,0 +1,65 @@
import { ChatInputCommandInteraction } from "discord.js"
import { color, devMessage } from "../../../config/options.json"
import { ExtendedClient as Client } from "../../utils/Client"
export async function help(interaction: ChatInputCommandInteraction, client: Client): Promise<void> {
await interaction.deferReply({ ephemeral: true })
type CommandList = {
name: string,
value: string
}
const commandList: CommandList[] = []
const commandRawList = client.commands.map((command) => {
return {
name: command.name,
command: command
}
})
for (const command of commandRawList) {
const commandName = command.name
if (!command.command.subcommands && !command.command.public) {
commandList.push({
name: "**/" + commandName + "**",
value: "`" + command.command.description + "`"
})
} else if (command.command.subcommands && !command.command.public) {
const subcommands = command.command.data.options.map((subcommand) => {
return {
name: commandName + " " + subcommand.toJSON().name,
description: subcommand.toJSON().description
}
})
for (const subcommand of subcommands) {
commandList.push({
name: "**/" + subcommand.name + "**",
value: "`" + subcommand.description + "`"
})
}
}
}
const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({
embeds: [{
title: "Commands",
description: "List of commands",
fields: commandList,
color: embedColor,
thumbnail: {
url: interaction.guild!.iconURL({ forceStatic: false })!
},
footer: {
icon_url: footerIcon!,
text: footerText + " | " + devMessage
}
}],
})
}

View File

@@ -0,0 +1,108 @@
import verify = require("../../schemas/verifySchema")
import { color, hypixelGuildID } from "../../../config/options.json"
import { admin, gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../../config/roles.json"
const removeThese = [gm, manager, beast, elite, member, guildRole, guildStaff]
import { getGuild } from "../../utils/Hypixel"
import { ChatInputCommandInteraction, GuildMember } from "discord.js"
import { GuildData } from "../../interfaces/Guild"
export async function updateDiscordRoles(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply()
const user = interaction.member as GuildMember
if (!user.roles.cache.has(admin)) {
await interaction.editReply("You do not have permission to use this command.")
return
}
const embedColor = Number(color.replace("#", "0x"))
const guildMembers = await interaction.guild!.members.fetch()
const memberList = guildMembers.map(member => {
return {
id: member.user.id,
member: member
}
})
for (const guildMember of memberList) {
const memberData = await verify.findOne({
userID: guildMember.id
})
if (!memberData) {
for (const role of removeThese) {
guildMember.member.roles.remove(role)
}
return
}
if (memberData) {
const isGuildMember = getGuild(memberData.uuid)
if (!isGuildMember) {
for (const role of removeThese) {
guildMember.member.roles.remove(role)
}
return
}
const hypixelGuildMember = isGuildMember as unknown as GuildData
const guildId = hypixelGuildMember!._id
const guildRank = hypixelGuildMember!.members!.find(member => member.uuid === memberData.uuid)!.rank
if (guildId === hypixelGuildID) {
if (guildRank === "Guild Master") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(guildStaff, "All users updated forcefully by staff")
guildMember.member.roles.add(gm, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Manager") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(guildStaff, "All users updated forcefully by staff")
guildMember.member.roles.add(manager, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Moderator") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(guildStaff, "All users updated forcefully by staff")
guildMember.member.roles.add(moderator, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Beast") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(beast, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Elite") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(elite, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Member") {
guildMember.member.roles.add(guildRole, "All users updated forcefully by staff")
guildMember.member.roles.add(member, "All users updated forcefully by staff")
guildMember.member.roles.add(defaultMember, "All users updated forcefully by staff")
}
} else {
for (const role of removeThese) {
guildMember.member.roles.remove(role)
}
}
}
}
interaction.editReply({
embeds: [{
color: embedColor,
description: "Successfully updated all users.",
footer: {
text: interaction.guild!.name,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
}

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, ChatInputCommandInteraction, GuildMember } from "discord.js"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
const ms = require("ms") import { Command } from "../interfaces"
import ms from "ms"
module.exports = { const command: Command = {
name: "timeout", name: "timeout",
description: "Times out a memeber", description: "Times out a memeber",
type: "slash", type: "slash",
@@ -29,23 +30,21 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ async execute(interaction: ChatInputCommandInteraction) {
async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const { default: prettyms } = await import("pretty-ms") const target = interaction.options.getMember("user")! as GuildMember
const target1 = interaction.options.getUser("user") const timeString = interaction.options.getString("time")!
const target = interaction.guild.members.cache.get(target1.id)
const timeString = interaction.options.getString("time")
const reason = interaction.options.getString("reason") || "No reason provided" const reason = interaction.options.getString("reason") || "No reason provided"
const time = ms(timeString) const mod = interaction.member! as GuildMember
const prettyTime = prettyms(time, { verbose: true })
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const time = ms(timeString)
const { default: prettyMs } = await import("pretty-ms")
const prettyTime = prettyMs(time, { verbose: true })
if (target.bot) { if (target.user.bot) {
interaction.deferReply({ interaction.editReply({
embeds: [{ embeds: [{
description: "You cannot timeout a bot.", description: "You cannot timeout a bot.",
color: embedColor, color: embedColor,
@@ -54,8 +53,8 @@ module.exports = {
return return
} }
if (target.id == interaction.guild.ownerId) { if (target.id == interaction.guild!.ownerId) {
await interaction.deferReply({ await interaction.editReply({
embeds: [{ embeds: [{
description: "You cannot timeout the server owner.", description: "You cannot timeout the server owner.",
color: embedColor, color: embedColor,
@@ -64,8 +63,8 @@ module.exports = {
return return
} }
if (interaction.guild.members.me.roles.highest.position <= target.roles.highest.position) { if (interaction.guild!.members.me!.roles.highest.position <= target.roles.highest.position) {
interaction.deferReply({ interaction.editReply({
embeds: [{ embeds: [{
description: "I cannot timeout this user because their role is higher than mine.", description: "I cannot timeout this user because their role is higher than mine.",
color: embedColor, color: embedColor,
@@ -74,8 +73,8 @@ module.exports = {
return return
} }
if (interaction.member.roles.highest.position <= target.roles.highest.position) { if (mod.roles.highest.position <= target.roles.highest.position) {
await interaction.deferReply({ await interaction.editReply({
embeds: [{ embeds: [{
description: "You cannot timeout this user because their role is higher than yours.", description: "You cannot timeout this user because their role is higher than yours.",
color: embedColor, color: embedColor,
@@ -85,7 +84,7 @@ module.exports = {
} }
if (target.id == interaction.user.id) { if (target.id == interaction.user.id) {
interaction.deferReply({ interaction.editReply({
embeds: [{ embeds: [{
description: "You cannot timeout yourself.", description: "You cannot timeout yourself.",
color: embedColor, color: embedColor,
@@ -103,9 +102,9 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + target.id, text: "ID: " + target.id,
iconURL: target.avatarURL() icon_url: target.avatarURL() || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
return return
@@ -118,9 +117,9 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + target.id, text: "ID: " + target.id,
iconURL: target.avatarURL() icon_url: target.avatarURL() || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
return return
@@ -133,10 +132,12 @@ module.exports = {
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + target.id, text: "ID: " + target.id,
iconURL: target.avatarURL() icon_url: target.avatarURL() || undefined
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} }
export = command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention, User } from "discord.js"
const { color } = require("../../config/options.json") import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = { export = {
name: "unban", name: "unban",
description: "Unban a user from the server", description: "Unban a user from the server",
type: "slash", type: "slash",
@@ -27,16 +28,14 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers) .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.setDMPermission(false), .setDMPermission(false),
/** @param { import("discord.js").ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const userid = interaction.options.getString("user") const userid = interaction.options.getString("user")!
const reason = interaction.options.getString("reason") || "No reason provided" const reason = interaction.options.getString("reason") || "No reason provided"
const mod = interaction.user const mod = interaction.user
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
let user let user: User | null
if (userid === "none") { if (userid === "none") {
await interaction.editReply({ await interaction.editReply({
@@ -59,24 +58,24 @@ module.exports = {
}) })
} }
await interaction.guild.members.unban(user.id, reason) await interaction.guild!.members.unban(user!.id, reason)
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
title: "User unbanned", title: "User unbanned",
description: "The user " + user.username + " has been unbanned.\n" + description: "The user " + user!.username + " has been unbanned.\n" +
"**Reason:** `" + reason + "`\n" + "**Reason:** `" + reason + "`\n" +
"**Moderator:** " + userMention(mod.id), "**Moderator:** " + userMention(mod.id),
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: user?.avatarURL({ dynamic: true }) || null url: user!.avatarURL({ forceStatic: false }) || ""
}, },
footer: { footer: {
text: "ID: " + user.id, text: "ID: " + user!.id,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} } as Command

View File

@@ -1,11 +1,12 @@
const { SlashCommandBuilder } = require("discord.js") import { GuildMember, SlashCommandBuilder } from "discord.js"
const { getGuild, getIGN, getHeadURL } = require("../utils/utils.js") import { getGuild, getIGN, getHeadURL } from "../utils/Hypixel"
const verify = require("../schemas/verifySchema.js") import verify = require("../schemas/verifySchema")
const { color, hypixelGuildID, devMessage } = require("../../config/options.json") import { color, hypixelGuildID, devMessage } from "../../config/options.json"
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json") import { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../config/roles.json"
import { Command } from "../interfaces"
const removeThese = [gm, manager, moderator, beast, elite, member, guildRole, guildStaff] const removeThese = [gm, manager, moderator, beast, elite, member, guildRole, guildStaff]
module.exports = { export = {
name: "update", name: "update",
description: "Update your guild rank.", description: "Update your guild rank.",
type: "slash", type: "slash",
@@ -17,15 +18,12 @@ module.exports = {
.setDescription("Update your discord roles.") .setDescription("Update your discord roles.")
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user1 = interaction.user const user = interaction.member as GuildMember
const user = interaction.guild.members.cache.get(user1.id) const verifyData = await verify.findOne({ userID: user.user.id })
const verifyData = await verify.findOne({ userID: user.id })
const roleManage = user.roles const roleManage = user.roles
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
@@ -35,8 +33,8 @@ module.exports = {
description: "You are not verified. Please run `/verify` to verify yourself", description: "You are not verified. Please run `/verify` to verify yourself",
color: embedColor, color: embedColor,
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -51,14 +49,14 @@ module.exports = {
}) })
const guild = await getGuild(verifyData.uuid) const guild = await getGuild(verifyData.uuid)
let guildID = "" let guildID: string | null
if (!guild) { if (!guild) {
guildID = null guildID = null
} else { } else {
guildID = guild._id guildID = guild._id
} }
const ign = await getIGN(verifyData.uuid) const ign = await getIGN(verifyData.uuid) as string
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
if (guildID !== hypixelGuildID) { if (guildID !== hypixelGuildID) {
@@ -73,11 +71,11 @@ module.exports = {
description: "Updated your roles to `Default Member`", description: "Updated your roles to `Default Member`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -86,8 +84,8 @@ module.exports = {
if (guildID === hypixelGuildID) { if (guildID === hypixelGuildID) {
const GuildMembers = guild.members const GuildMembers = guild!.members
const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid).rank const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid)!.rank
if (guildRank === "Guild Master") { if (guildRank === "Guild Master") {
@@ -106,11 +104,11 @@ module.exports = {
description: "Your rank has been updated to `Guild Master`", description: "Your rank has been updated to `Guild Master`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -133,11 +131,11 @@ module.exports = {
description: "Your rank has been updated to `Manager`", description: "Your rank has been updated to `Manager`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -160,11 +158,11 @@ module.exports = {
description: "Your rank has been updated to `Moderator`", description: "Your rank has been updated to `Moderator`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -187,11 +185,11 @@ module.exports = {
description: "Your rank has been updated to `Beast`.", description: "Your rank has been updated to `Beast`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -214,11 +212,11 @@ module.exports = {
description: "Your rank has been updated to `Elite`.", description: "Your rank has been updated to `Elite`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -241,11 +239,11 @@ module.exports = {
description: "Your rank has been updated to `Member`.", description: "Your rank has been updated to `Member`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: false })!
} }
}] }]
}) })
@@ -253,4 +251,4 @@ module.exports = {
} }
} }
} }
} } as Command

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const { getUUID, getIGN, getHeadURL, formatUuid } = require("../utils/utils.js") import { getUUID, getIGN, getHeadURL, formatUuid } from "../utils/Hypixel"
import { Command } from "../interfaces"
module.exports = { export = {
name: "uuid", name: "uuid",
description: "Get a player's UUID", description: "Get a player's UUID",
type: "slash", type: "slash",
@@ -15,28 +16,27 @@ module.exports = {
.addStringOption(option => option .addStringOption(option => option
.setName("ign") .setName("ign")
.setDescription("Player's name") .setDescription("Player's name")
.setRequired(true) .setRequired(true)),
),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const ign = interaction.options.getString("ign") const ign = interaction.options.getString("ign")!
const uuid = await getUUID(ign) const uuid = await getUUID(ign) as string
const formattedUuid = formatUuid(uuid) const formattedUuid = formatUuid(uuid)
const newIgn = await getIGN(uuid) const newIgn = await getIGN(uuid) as string
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const footerText = interaction.guild ? interaction.guild.name : interaction.user.username const footerText = interaction.guild ? interaction.guild.name : interaction.user.username
const footerIcon = interaction.guild ? interaction.guild.iconURL({ dynamic: true }) : interaction.user.avatarURL({ dynamic: true }) const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
if (!uuid) { if (!uuid) {
interaction.editReply({ interaction.editReply({
description: "That player doesn't exist!", embeds: [{
color: embedColor description: "That player doesn't exist!",
color: embedColor
}]
}) })
return return
} }
@@ -48,13 +48,13 @@ module.exports = {
"**Formatted UUID:** `" + formattedUuid + "`", "**Formatted UUID:** `" + formattedUuid + "`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: footerText + " | " + devMessage, text: footerText + " | " + devMessage,
icon_url: footerIcon icon_url: footerIcon || undefined
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,11 +1,14 @@
const { SlashCommandBuilder } = require("discord.js") import { SlashCommandBuilder } from "discord.js"
const { getUUID, getPlayer, getGuild, getHeadURL } = require("../utils/utils.js") import { getUUID, getPlayer, getGuild, getHeadURL } from "../utils/Hypixel"
const { color, hypixelGuildID, devMessage } = require("../../config/options.json") import { color, hypixelGuildID, devMessage } from "../../config/options.json"
const verify = require("../schemas/verifySchema.js") import mongoose from "mongoose"
const mongoose = require("mongoose") import { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../config/roles.json"
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json") import { Command } from "../interfaces"
import verify = require("../schemas/verifySchema")
import { PlayerData } from "../interfaces/Player"
import { GuildData } from "../interfaces/Guild"
module.exports = { export = {
name: "verify", name: "verify",
description: "Verify yourself as a member of the server.", description: "Verify yourself as a member of the server.",
type: "slash", type: "slash",
@@ -22,14 +25,12 @@ module.exports = {
.setRequired(true)) .setRequired(true))
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user1 = interaction.user const user1 = interaction.user
const user = interaction.guild.members.cache.get(user1.id) const user = interaction.guild!.members.cache.get(user1.id)!
const ign = interaction.options.getString("ign") const ign = interaction.options.getString("ign")!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const verifyData = await verify.findOne({ userID: user.id }) const verifyData = await verify.findOne({ userID: user.id })
@@ -74,7 +75,7 @@ module.exports = {
}) })
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
const player = await getPlayer(uuid) const player = await getPlayer(uuid) as PlayerData
if (!player) { if (!player) {
interaction.editReply({ interaction.editReply({
embeds: [{ embeds: [{
@@ -99,7 +100,7 @@ module.exports = {
}] }]
}) })
const linkedDiscord = player?.socialMedia?.links?.DISCORD || null const linkedDiscord = player.socialMedia.links.DISCORD || null
if (!linkedDiscord) { if (!linkedDiscord) {
interaction.editReply({ interaction.editReply({
embeds: [ embeds: [
@@ -133,8 +134,8 @@ module.exports = {
}] }]
}) })
const guild = await getGuild(uuid) const guild = await getGuild(uuid) as GuildData | null
let guildID = "" let guildID: string | null
if (!guild) { if (!guild) {
guildID = null guildID = null
} else { } else {
@@ -143,8 +144,8 @@ module.exports = {
if (guildID === hypixelGuildID) { if (guildID === hypixelGuildID) {
const GuildMembers = guild.members const GuildMembers = guild!.members
const guildRank = GuildMembers.find((member) => member.uuid === player.uuid).rank const guildRank = GuildMembers.find((member) => member.uuid === player.uuid)!.rank
if (guildRank === "Guild Master" && guildID === hypixelGuildID) { if (guildRank === "Guild Master" && guildID === hypixelGuildID) {
await user.roles.add(gm, "Verification") await user.roles.add(gm, "Verification")
@@ -193,18 +194,18 @@ module.exports = {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
{ {
title: interaction.guild.name, title: interaction.guild!.name,
description: "You have successfully verified `" + username + "` with the account `" + player.displayname + "`.", description: "You have successfully verified `" + username + "` with the account `" + player.displayname + "`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head || ""
}, },
footer: { footer: {
icon_url: interaction.guild.iconURL(), icon_url: interaction.guild!.iconURL() || undefined,
text: interaction.guild.name + " | " + devMessage text: interaction.guild!.name + " | " + devMessage
} }
} }
] ]
}) })
} }
} } as Command

View File

@@ -1,9 +1,10 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") import { SlashCommandBuilder, PermissionFlagsBits, userMention } from "discord.js"
const { getIGN, getHeadURL } = require("../utils/utils.js") import { getIGN, getHeadURL } from "../utils/Hypixel"
const { color, devMessage } = require("../../config/options.json") import { color, devMessage } from "../../config/options.json"
const verify = require("../schemas/verifySchema.js") import verify = require("../schemas/verifySchema")
import { Command } from "../interfaces"
module.exports = { export = {
name: "whois", name: "whois",
description: "Get's the ign of a user.", description: "Get's the ign of a user.",
type: "slash", type: "slash",
@@ -21,13 +22,11 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false), .setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const verifiedUser = await verify.findOne({ userID: user.id }) const verifiedUser = await verify.findOne({ userID: user.id })
@@ -36,23 +35,23 @@ module.exports = {
return return
} }
const ign = await getIGN(verifiedUser.uuid) const ign = await getIGN(verifiedUser.uuid) as string
const head = await getHeadURL(ign) const head = await getHeadURL(ign)
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
title: interaction.guild.name, title: interaction.guild!.name,
description: "**User:** " + userMention(user.id) + "\n**IGN:** " + ign, description: "**User:** " + userMention(user.id) + "\n**IGN:** " + ign,
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }) icon_url: interaction.guild!.iconURL({ forceStatic: true }) || undefined
} }
}] }]
}) })
} }
} } as Command

View File

@@ -1,13 +1,15 @@
module.exports = { import { Autocomplete } from "../../interfaces"
export = {
name: "unban", name: "unban",
description: "Unban a user from the server", description: "Unban a user from the server",
type: "autocomplete", type: "autocomplete",
/** @param { import("discord.js").AutocompleteInteraction } interaction */
async execute(interaction) { async execute(interaction) {
const focusedOption = interaction.options.getFocused(true) const focusedOption = interaction.options.getFocused(true)
if (focusedOption.name !== "user") return if (focusedOption.name !== "user") {
return
}
if (focusedOption.value === "") { if (focusedOption.value === "") {
await interaction.respond([{ await interaction.respond([{
@@ -17,7 +19,7 @@ module.exports = {
return return
} }
const bannedUsers = await interaction.guild.bans.fetch() const bannedUsers = await interaction.guild!.bans.fetch()
const filteredUsers = bannedUsers.filter((user) => const filteredUsers = bannedUsers.filter((user) =>
user.user.username.toLowerCase().includes(focusedOption.value.toLowerCase()) user.user.username.toLowerCase().includes(focusedOption.value.toLowerCase())
) )
@@ -29,4 +31,4 @@ module.exports = {
await interaction.respond(results.slice(0, 25)).catch((err) => { console.log(err) }) await interaction.respond(results.slice(0, 25)).catch((err) => { console.log(err) })
} }
} } as Autocomplete

View File

@@ -1,24 +1,22 @@
const { color, devMessage } = require("../../../config/options.json") import { color, devMessage } from "../../../config/options.json"
const guildapp = require("../../schemas/guildAppSchema.js") import guildapp from "../../schemas/guildAppSchema"
const { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } = require("../../../config/reqs.json") import { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } from "../../../config/reqs.json"
const { hypixelLevel, bedwarsLevel, skywarsLevel, getPlayer, getGuild, getHeadURL } = require("../../utils/utils.js") import { hypixelLevel, bedwarsLevel, skywarsLevel, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "checkstats", name: "checkstats",
description: "Check your stats.", description: "Check your stats.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const message = interaction.message const message = interaction.message
const embed = message.embeds[0] const embed = message.embeds[0]
const applicantId = embed.footer.text.split(" ")[1] const applicantId = embed.footer!.text.split(" ")[1]
const guildappdata = await guildapp.findOne({ userID: applicantId }) const guildappdata = await guildapp.findOne({ userID: applicantId })
const uuid = guildappdata.uuid const uuid = guildappdata!.uuid
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const player = await getPlayer(uuid) const player = await getPlayer(uuid)
@@ -71,7 +69,7 @@ module.exports = {
if (!guild) { if (!guild) {
guildRank = "N/A" guildRank = "N/A"
} else { } else {
guildRank = guild.members.find((m) => m.uuid === uuid).rank guildRank = guild.members.find((m) => m.uuid === uuid)!.rank
} }
const statsFields = [] const statsFields = []
@@ -180,13 +178,15 @@ module.exports = {
"**Current Guild:** `" + guildName + "`\n" + "**Current Guild:** `" + guildName + "`\n" +
"**Guild Rank:** `" + guildRank + "`", "**Guild Rank:** `" + guildRank + "`",
color: embedColor, color: embedColor,
thumbnail: { url: head }, thumbnail: {
url: head!
},
footer: { footer: {
text: interaction.guild.name + " | " + devMessage, text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild.iconURL() icon_url: interaction.guild!.iconURL()!
}, },
fields: statsFields fields: statsFields
}] }]
}) })
} }
} } as Button

View File

@@ -1,38 +1,35 @@
const { ActionRowBuilder, ButtonStyle, ButtonBuilder } = require("discord.js") import { ActionRowBuilder, ButtonStyle, ButtonBuilder } from "discord.js"
const { color } = require("../../../config/options.json") import { color } from "../../../config/options.json"
const mongoose = require("mongoose") import mongoose from "mongoose"
const guildapp = require("../../schemas/guildAppSchema.js") import guildapp from "../../schemas/guildAppSchema"
const waitingList = require("../../schemas/waitinglistSchema.js") import waitingList from "../../schemas/waitinglistSchema"
const { waitingListRole } = require("../../../config/roles.json") import { waitingListRole } from "../../../config/roles.json"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "guildapplicationaccept", name: "guildapplicationaccept",
description: "Accept a guild application.", description: "Accept a guild application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const user = interaction.user const user = interaction.user
const guild = interaction.guild const guild = interaction.guild!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const message = interaction.message const message = interaction.message
const embed = message.embeds[0] const embed = message.embeds[0]
const applicantId = embed.footer.text.split(" ")[1] const applicantId = embed.footer!.text.split(" ")[1]
const applicantIGN = embed.fields[0].value.replaceAll("`", "")
const applicantIGN1 = embed.fields[0].value
const applicantIGN = applicantIGN1.replaceAll("`", "")
const applicant = await guild.members.fetch(applicantId) const applicant = await guild.members.fetch(applicantId)
const applicantUsername = applicant.user.username + "#" + applicant.user.discriminator const applicantUsername = applicant.user.username + "#" + applicant.user.discriminator
await message.edit({ await message.edit({
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("guildapplicationaccept") .setCustomId("guildapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -60,7 +57,7 @@ module.exports = {
}) })
const applicantEntry = await guildapp.findOne({ userID: applicantId }) const applicantEntry = await guildapp.findOne({ userID: applicantId })
const applicantUUID = applicantEntry.uuid const applicantUUID = applicantEntry!.uuid
const time = Date.now() const time = Date.now()
const waitingListAdd = new waitingList({ const waitingListAdd = new waitingList({
@@ -83,13 +80,13 @@ module.exports = {
description: "Application has been accepted by <@" + user.id + ">.", description: "Application has been accepted by <@" + user.id + ">.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: applicant.avatarURL() url: applicant.avatarURL() || guild.iconURL()!
}, },
footer: { footer: {
iconURL: guild.iconURL(), icon_url: guild.iconURL()!,
text: "ID: " + applicant.id text: "ID: " + applicant.id
} }
}] }]
}) })
} }
} } as Button

View File

@@ -1,19 +1,18 @@
const { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } = require("discord.js") import { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } from "discord.js"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "guildapplicationdeny", name: "guildapplicationdeny",
description: "Deny a guild application.", description: "Deny a guild application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const modal = new ModalBuilder() const modal = new ModalBuilder()
.setTitle("Deny Reason") .setTitle("Deny Reason")
.setCustomId("denyreasonbox") .setCustomId("denyreasonbox")
.setComponents( .setComponents(
new ActionRowBuilder().setComponents( new ActionRowBuilder<TextInputBuilder>().setComponents(
new TextInputBuilder() new TextInputBuilder()
.setLabel("Deny Reason") .setLabel("Deny Reason")
.setCustomId("denyreason") .setCustomId("denyreason")
@@ -24,4 +23,4 @@ module.exports = {
) )
await interaction.showModal(modal) await interaction.showModal(modal)
} }
} } as Button

View File

@@ -1,33 +1,32 @@
const { ButtonBuilder, ButtonStyle, ActionRowBuilder, EmbedBuilder } = require("discord.js") import { ButtonBuilder, ButtonStyle, ActionRowBuilder, EmbedBuilder, GuildMember, GuildTextBasedChannel } from "discord.js"
const { color } = require("../../../config/options.json") import { color } from "../../../config/options.json"
const { largeM, smallM, ignM } = require("../../../config/limitmessages.json") import { largeM, smallM, ignM } from "../../../config/limitmessages.json"
const { applicationsChannel } = require("../../../config/options.json") import { applicationsChannel } from "../../../config/options.json"
const questions = require("../../../config/questions.json") import questions from "../../../config/questions.json"
const { guildRole } = require("../../../config/roles.json") import { guildRole } from "../../../config/roles.json"
const { getUUID } = require("../../utils/utils.js") import { getUUID } from "../../utils/Hypixel"
const mongoose = require("mongoose") import mongoose from "mongoose"
const guildapp = require("../../schemas/guildAppSchema.js") import guildapp from "../../schemas/guildAppSchema"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "guildapply", name: "guildapply",
description: "Guild application button.", description: "Guild application button.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const user = interaction.user const user = interaction.member as GuildMember
const guild = interaction.guild const guild = interaction.guild!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const userRoles = guild.members.cache.get(user.id).roles.cache.map(role => role.id) const userRoles = user.roles.cache.map(role => role.id)
const guildQuestions = questions.guild const guildQuestions = questions.guild
function qu(n) { function qu(n: number): string {
return guildQuestions[n - 1].q return guildQuestions[n - 1].q
} }
function rq(n) { function rq(n: number): string {
return guildQuestions[n - 1].r return guildQuestions[n - 1].r
} }
@@ -36,14 +35,14 @@ module.exports = {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
if (userRoles.includes(guildRole)) { if (userRoles.includes(guildRole)) {
await interaction.editReply({ content: "You are already a member of the guild.", ephemeral: true }) await interaction.editReply("You are already a member of the guild.")
return return
} }
const application = await guildapp.findOne({ userID: user.id }) const application = await guildapp.findOne({ userID: user.user.id })
if (application) { if (application) {
await interaction.editReply({ content: "You already have an application in progress.", ephemeral: true }) await interaction.editReply("You already have an application in progress.")
return return
} }
@@ -70,15 +69,14 @@ module.exports = {
}] }]
}) })
} catch (error) { } catch (error) {
await interaction.editReply({ content: "Please enable your DMs.", ephemeral: true }) await interaction.editReply("Please enable your DMs.")
return return
} }
await interaction.editReply({ content: "Please check your DMs.", ephemeral: true }) await interaction.editReply("Please check your DMs.")
const input = await user.dmChannel!.awaitMessages({
const input = await user.dmChannel.awaitMessages({ filter: m => m.author.id === user.user.id,
filter: m => m.author.id === user.id,
max: 1, max: 1,
time: 1000 * 60 time: 1000 * 60
}) })
@@ -86,11 +84,11 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (input.first().content.toLowerCase() !== "yes") { if (input.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (input.first().attachments.size > 0) { if (input.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -106,8 +104,8 @@ module.exports = {
} }
}] }]
}) })
const answer1 = await user.dmChannel.awaitMessages({ const answer1 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5, time: 1000 * 60 * 5,
}) })
@@ -115,15 +113,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer1.first().content.toLowerCase() === "cancel") { if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer1.first().attachments.size > 0) { if (answer1.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer1.first().content > 16) { if (answer1.first()!.content.length > 16) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 16.", description: "Max character limit is 16.",
@@ -132,7 +130,7 @@ module.exports = {
}) })
return return
} }
const uuid = await getUUID(answer1.first().content) const uuid = await getUUID(answer1.first()!.content)
if (!uuid) { if (!uuid) {
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -143,7 +141,7 @@ module.exports = {
}) })
return return
} }
const answer1_1 = answer1.first().content const answer1_1 = answer1.first()!.content
// second question // second question
await user.send({ await user.send({
@@ -156,8 +154,8 @@ module.exports = {
} }
}] }]
}) })
const answer2 = await user.dmChannel.awaitMessages({ const answer2 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -165,15 +163,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer2.first().content.toLowerCase() === "cancel") { if (answer2.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer2.first().attachments.size > 0) { if (answer2.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer2.first().content.size > 8) { if (answer2.first()!.content.length > 8) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 8.", description: "Max character limit is 8.",
@@ -182,7 +180,7 @@ module.exports = {
}) })
return return
} }
const answer2_1 = answer2.first().content const answer2_1 = answer2.first()!.content
// third question // third question
await user.send({ await user.send({
@@ -195,8 +193,8 @@ module.exports = {
} }
}] }]
}) })
const answer3 = await user.dmChannel.awaitMessages({ const answer3 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -204,15 +202,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer3.first().content.toLowerCase() === "cancel") { if (answer3.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer3.first().attachments.size > 0) { if (answer3.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer3.first().content > 128) { if (answer3.first()!.content.length > 128) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 128.", description: "Max character limit is 128.",
@@ -220,7 +218,7 @@ module.exports = {
}] }]
}) })
} }
const answer3_1 = answer3.first().content const answer3_1 = answer3.first()!.content
// fourth question // fourth question
await user.send({ await user.send({
@@ -234,8 +232,8 @@ module.exports = {
} }
}] }]
}) })
const answer4 = await user.dmChannel.awaitMessages({ const answer4 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -243,15 +241,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer4.first().content.toLowerCase() === "cancel") { if (answer4.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer4.first().attachments.size > 0) { if (answer4.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer4.first().content > 256) { if (answer4.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -259,7 +257,7 @@ module.exports = {
}] }]
}) })
} }
const answer4_1 = answer4.first().content const answer4_1 = answer4.first()!.content
// fifth question // fifth question
await user.send({ await user.send({
@@ -272,8 +270,8 @@ module.exports = {
} }
}] }]
}) })
const answer5 = await user.dmChannel.awaitMessages({ const answer5 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -281,15 +279,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer5.first().content.toLowerCase() === "cancel") { if (answer5.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer5.first().attachments.size > 0) { if (answer5.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer5.first().content > 128) { if (answer5.first()!.content.length > 128) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 128.", description: "Max character limit is 128.",
@@ -297,7 +295,7 @@ module.exports = {
}] }]
}) })
} }
const answer5_1 = answer5.first().content const answer5_1 = answer5.first()!.content
// sixth question // sixth question
await user.send({ await user.send({
@@ -310,8 +308,8 @@ module.exports = {
} }
}] }]
}) })
const answer6 = await user.dmChannel.awaitMessages({ const answer6 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -319,15 +317,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer6.first().content.toLowerCase() === "cancel") { if (answer6.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer6.first().attachments.size > 0) { if (answer6.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer6.first().content > 256) { if (answer6.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -335,7 +333,7 @@ module.exports = {
}] }]
}) })
} }
const answer6_1 = answer6.first().content const answer6_1 = answer6.first()!.content
// seventh question // seventh question
await user.send({ await user.send({
@@ -348,8 +346,8 @@ module.exports = {
} }
}] }]
}) })
const answer7 = await user.dmChannel.awaitMessages({ const answer7 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -357,15 +355,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer7.first().content.toLowerCase() === "cancel") { if (answer7.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer7.first().attachments.size > 0) { if (answer7.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer7.first().content > 128) { if (answer7.first()!.content.length > 128) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 128.", description: "Max character limit is 128.",
@@ -373,7 +371,7 @@ module.exports = {
}] }]
}) })
} }
const answer7_1 = answer7.first().content const answer7_1 = answer7!.first()!.content
// eighth question // eighth question
await user.send({ await user.send({
@@ -386,8 +384,8 @@ module.exports = {
} }
}] }]
}) })
const answer8 = await user.dmChannel.awaitMessages({ const answer8 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -395,15 +393,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer8.first().content.toLowerCase() === "cancel") { if (answer8.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer8.first().attachments.size > 0) { if (answer8.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer8.first().content > 64) { if (answer8.first()!.content.length > 64) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 64.", description: "Max character limit is 64.",
@@ -411,7 +409,7 @@ module.exports = {
}] }]
}) })
} }
const answer8_1 = answer8.first().content const answer8_1 = answer8.first()!.content
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -420,8 +418,8 @@ module.exports = {
}] }]
}) })
const final = await user.dmChannel.awaitMessages({ const final = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5 time: 1000 * 60 * 5
}) })
@@ -429,11 +427,11 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (final.first().content.toLowerCase() !== "yes") { if (final.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (final.first().attachments.size > 0) { if (final.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -447,19 +445,19 @@ module.exports = {
const newGuildApp = new guildapp({ const newGuildApp = new guildapp({
_id: new mongoose.Types.ObjectId(), _id: new mongoose.Types.ObjectId(),
userID: user.id, userID: user.user.id,
uuid: uuid, uuid: uuid,
}) })
await newGuildApp.save() await newGuildApp.save()
const channel = guild.channels.cache.get(applicationsChannel) const channel = guild.channels.cache.get(applicationsChannel) as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [{ embeds: [{
title: user.username + "#" + user.discriminator + " - Guild Application", title: user.user.username + "#" + user.user.discriminator + " - Guild Application",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: user.avatarURL() url: user.avatarURL() || guild.iconURL()!
}, },
fields: [ fields: [
{ {
@@ -496,12 +494,12 @@ module.exports = {
} }
], ],
footer: { footer: {
iconURL: guild.iconURL(), icon_url: guild.iconURL()!,
text: "ID: " + user.id text: "ID: " + user.user.id
} }
}], }],
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("guildapplicationaccept") .setCustomId("guildapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -520,4 +518,4 @@ module.exports = {
} }
} }
} } as Button

View File

@@ -1,8 +1,9 @@
const { ButtonBuilder, ActionRowBuilder, ButtonStyle, EmbedBuilder } = require("discord.js") import { ButtonBuilder, ActionRowBuilder, ButtonStyle, EmbedBuilder, GuildMember, GuildTextBasedChannel } from "discord.js"
const { gm, manager, moderator, beast, member, guildStaff, guildRole } = require("../../../config/roles.json") import { gm, manager, moderator, beast, member, guildStaff, guildRole } from "../../../config/roles.json"
const { ignM, smallM, largeM } = require("../../../config/limitmessages.json") import { ignM, smallM, largeM } from "../../../config/limitmessages.json"
const { ia1, ia2, ia3, ria1, ria2, ria3 } = require("../../../config/questions.json") import { inactivity } from "../../../config/questions.json"
const { color, inactivityLogChannel } = require("../../../config/options.json") import { color, inactivityLogChannel } from "../../../config/options.json"
import { Button } from "../../interfaces"
const guildRoles = [gm, manager, moderator, beast, member, guildStaff, guildRole] const guildRoles = [gm, manager, moderator, beast, member, guildStaff, guildRole]
module.exports = { module.exports = {
@@ -10,13 +11,11 @@ module.exports = {
description: "Configure the bot.", description: "Configure the bot.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const guild = interaction.guild const guild = interaction.guild!
const user = interaction.user const user = interaction.member as GuildMember
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const userRoles = guild.members.cache.get(user.id).roles.cache const userRoles = user.roles.cache
const mojangAPI = "https://api.mojang.com/users/profiles/minecraft/" const mojangAPI = "https://api.mojang.com/users/profiles/minecraft/"
if (!userRoles.some((role) => guildRoles.includes(role.id))) { if (!userRoles.some((role) => guildRoles.includes(role.id))) {
@@ -26,6 +25,14 @@ module.exports = {
}) })
} }
function sq(n: number): string {
return inactivity[n - 1].q
}
function rq(n: number): string {
return inactivity[n - 1].r
}
const tooLong = new EmbedBuilder() const tooLong = new EmbedBuilder()
.setDescription("You took too long to respond.") .setDescription("You took too long to respond.")
.setColor(embedColor) .setColor(embedColor)
@@ -53,12 +60,12 @@ module.exports = {
await interaction.reply({ content: "Please check your DMs.", ephemeral: true }) await interaction.reply({ content: "Please check your DMs.", ephemeral: true })
const input = await user.dmChannel.awaitMessages({ const input = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.id, filter: (m) => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 time: 1000 * 60
}) })
if (input.first().attachments.size > 0) { if (input.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -66,7 +73,7 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (input.first().content.toLowerCase() !== "yes") { if (input.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
@@ -74,7 +81,7 @@ module.exports = {
await user.send({ await user.send({
embeds: [{ embeds: [{
title: "**Question 1**", title: "**Question 1**",
description: ia1 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + ignM + "`", description: sq(1) + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + ignM + "`",
color: embedColor, color: embedColor,
footer: { footer: {
text: "You have 5 minutes to respond to this message." text: "You have 5 minutes to respond to this message."
@@ -82,16 +89,16 @@ module.exports = {
}] }]
}) })
const answer1 = await user.dmChannel.awaitMessages({ const answer1 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.id, filter: (m) => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5 time: 1000 * 60 * 5
}) })
if (answer1.first().attachments.size > 0) { if (answer1.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer1.first().content > 16) { if (answer1.first()!.content.length > 16) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 16.", description: "Max character limit is 16.",
@@ -101,7 +108,7 @@ module.exports = {
return return
} }
try { try {
await fetch(mojangAPI + answer1.first().content) await fetch(mojangAPI + answer1.first()!.content)
} catch (error) { } catch (error) {
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -115,32 +122,32 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer1.first().content.toLowerCase() === "cancel") { if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
const answer1_1 = answer1.first().content const answer1_1 = answer1.first()!.content
await user.send({ await user.send({
embeds: [{ embeds: [{
title: "**Question 2**", title: "**Question 2**",
description: ia2 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + smallM + "`", description: sq(2) + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + smallM + "`",
color: embedColor, color: embedColor,
footer: { footer: {
text: "You have 5 minutes to respond to this message." text: "You have 5 minutes to respond to this message."
} }
}] }]
}) })
const answer2 = await user.dmChannel.awaitMessages({ const answer2 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.id, filter: (m) => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5 time: 1000 * 60 * 5
}) })
if (answer2.first().attachments.size > 0) { if (answer2.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer2.first().content > 128) { if (answer2.first()!.content.length > 128) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 128.", description: "Max character limit is 128.",
@@ -153,32 +160,32 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer1.first().content.toLowerCase() === "cancel") { if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
const answer2_1 = answer1.first().content const answer2_1 = answer1.first()!.content
await user.send({ await user.send({
embeds: [{ embeds: [{
title: "**Question 3**", title: "**Question 3**",
description: ia3 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + largeM + "`", description: sq(3) + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + largeM + "`",
color: embedColor, color: embedColor,
footer: { footer: {
text: "You have 15 minutes to respond to this message." text: "You have 15 minutes to respond to this message."
} }
}] }]
}) })
const answer3 = await user.dmChannel.awaitMessages({ const answer3 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.id, filter: (m) => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
if (answer3.first().attachments.size > 0) { if (answer3.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer3.first().content > 256) { if (answer3.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256", description: "Max character limit is 256",
@@ -191,11 +198,11 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer1.first().content.toLowerCase() === "cancel") { if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
const answer3_1 = answer1.first().content const answer3_1 = answer1.first()!.content
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -203,12 +210,12 @@ module.exports = {
color: embedColor color: embedColor
}] }]
}) })
const final = await user.dmChannel.awaitMessages({ const final = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5 time: 1000 * 60 * 5
}) })
if (final.first().attachments.size > 0) { if (final.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -216,7 +223,7 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (final.first().content.toLowerCase() !== "yes") { if (final.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
@@ -228,36 +235,36 @@ module.exports = {
}] }]
}) })
const appChannel = await guild.channels.cache.get(inactivityLogChannel) const appChannel = guild.channels.cache.get(inactivityLogChannel) as GuildTextBasedChannel
await appChannel.send({ await appChannel.send({
embeds: [{ embeds: [{
title: user.username + "#" + user.discriminator + " - Inactivity Application", title: user.user.username + "#" + user.user.discriminator + " - Inactivity Application",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: user.displayAvatarURL({ dynamic: true }) url: user.displayAvatarURL({ forceStatic: false })
}, },
fields: [ fields: [
{ {
name: ria1, name: rq(1),
value: "`" + answer1_1 + "`" value: "`" + answer1_1 + "`"
}, },
{ {
name: ria2, name: rq(2),
value: "`" + answer2_1 + "`" value: "`" + answer2_1 + "`"
}, },
{ {
name: ria3, name: rq(3),
value: "`" + answer3_1 + "`" value: "`" + answer3_1 + "`"
} }
], ],
footer: { footer: {
icon_url: user.displayAvatarURL({ dynamic: true }), icon_url: user.displayAvatarURL({ forceStatic: false }),
text: "ID: " + user.id text: "ID: " + user.user.id
} }
}], }],
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("inactiveapplicationaccept") .setCustomId("inactiveapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -270,4 +277,4 @@ module.exports = {
] ]
}) })
} }
} } as Button

View File

@@ -1,13 +1,13 @@
module.exports = { import { Button } from "../../interfaces"
export = {
name: "inactiveapplicationaccept", name: "inactiveapplicationaccept",
description: "Accept an inactivity application.", description: "Accept an inactivity application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.reply({ content: "This button is currently disabled.", ephemeral: true }) await interaction.reply({ content: "This button is currently disabled.", ephemeral: true })
} }
} } as Button

View File

@@ -1,13 +1,13 @@
module.exports = { import { Button } from "../../interfaces"
export = {
name: "inactiveapplicationdeny", name: "inactiveapplicationdeny",
description: "Denies an inactivity application.", description: "Denies an inactivity application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.reply({ content: "This button is currently disabled.", ephemeral: true }) await interaction.reply({ content: "This button is currently disabled.", ephemeral: true })
} }
} } as Button

View File

@@ -1,23 +1,23 @@
const { ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"
const { color } = require("../../../config/options.json") import { color } from "../../../config/options.json"
const staffapp = require("../../schemas/staffAppSchema.js") import staffapp from "../../schemas/staffAppSchema"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "staffapplicationaccept", name: "staffapplicationaccept",
description: "Accept a staff application.", description: "Accept a staff application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply()
const user = interaction.user const user = interaction.user
const guild = interaction.guild const guild = interaction.guild!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const message = interaction.message const message = interaction.message
const embed = message.embeds[0] const embed = message.embeds[0]
const applicantId = embed.footer.text.split(" ")[1] const applicantId = embed.footer!.text.split(" ")[1]
const applicant = await guild.members.fetch(applicantId) const applicant = await guild.members.fetch(applicantId)
const applicantUsername = applicant.user.username + "#" + applicant.user.discriminator const applicantUsername = applicant.user.username + "#" + applicant.user.discriminator
@@ -31,7 +31,7 @@ module.exports = {
await message.edit({ await message.edit({
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("staffapplicationaccept") .setCustomId("staffapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -46,22 +46,21 @@ module.exports = {
] ]
}) })
await staffapp.findOneAndDelete({ userId: applicantId }) await staffapp.findOneAndDelete({ userID: applicantId })
await interaction.reply({ await interaction.editReply({
embeds: [{ embeds: [{
title: applicantUsername + " - Staff Application.", title: applicantUsername + " - Staff Application.",
description: "Application accepted by <@" + user.id + ">.", description: "Application accepted by <@" + user.id + ">.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: applicant.avatarURL() url: applicant.avatarURL()!
}, },
footer: { footer: {
iconurl: guild.iconURL(), icon_url: guild.iconURL()!,
text: "ID: " + applicantId text: "ID: " + applicantId
} }
}] }]
}) })
} }
} } as Button

View File

@@ -1,19 +1,18 @@
const { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } = require("discord.js") import { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } from "discord.js"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "staffapplicationdeny", name: "staffapplicationdeny",
description: "Deny a guild application.", description: "Deny a guild application.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const modal = new ModalBuilder() const modal = new ModalBuilder()
.setTitle("Deny Reason") .setTitle("Deny Reason")
.setCustomId("staffdenyreasonbox") .setCustomId("staffdenyreasonbox")
.setComponents( .setComponents(
new ActionRowBuilder().setComponents( new ActionRowBuilder<TextInputBuilder>().setComponents(
new TextInputBuilder() new TextInputBuilder()
.setLabel("Deny Reason") .setLabel("Deny Reason")
.setCustomId("staffdenyreason") .setCustomId("staffdenyreason")
@@ -24,4 +23,4 @@ module.exports = {
) )
await interaction.showModal(modal) await interaction.showModal(modal)
} }
} } as Button

View File

@@ -1,36 +1,35 @@
const { ButtonBuilder, ButtonStyle, ActionRowBuilder, EmbedBuilder } = require("discord.js") import { ButtonBuilder, ButtonStyle, ActionRowBuilder, EmbedBuilder, GuildMember, GuildTextBasedChannel } from "discord.js"
const { color, staffApplicationsChannel } = require("../../../config/options.json") import { color, staffApplicationsChannel } from "../../../config/options.json"
const { largeM, ignM } = require("../../../config/limitmessages.json") import { largeM, ignM } from "../../../config/limitmessages.json"
const questions = require("../../../config/questions.json") import questions from "../../../config/questions.json"
const { guildRole, guildStaff } = require("../../../config/roles.json") import { guildRole, guildStaff } from "../../../config/roles.json"
const mongoose = require("mongoose") import mongoose from "mongoose"
const staffapp = require("../../schemas/staffAppSchema.js") import staffapp from "../../schemas/staffAppSchema"
const settings = require("../../schemas/settingsSchema.js") import settings from "../../schemas/settingsSchema"
const { getUUID } = require("../../utils/utils.js") import { getUUID } from "../../utils/Hypixel"
const dev = process.env.DEV import { Button } from "../../interfaces"
import config from "../../utils/Config"
module.exports = { export = {
name: "staffapply", name: "staffapply",
description: "Apply for the staff team.", description: "Apply for the staff team.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const user = interaction.user const user = interaction.member as GuildMember
const guild = interaction.guild const guild = interaction.guild!
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const userRoles = interaction.member.roles.cache const userRoles = user.roles.cache
const setting = await settings.findOne({ name: "staffAppStatus" }) const setting = await settings.findOne({ name: "staffAppStatus" })
const status = setting.value const status = setting!.value || "0"
const staffQuestions = questions.staff const staffQuestions = questions.staff
function sq(n) { function sq(n: number): string {
return staffQuestions[n - 1].q return staffQuestions[n - 1].q
} }
function rq(n) { function rq(n: number): string {
return staffQuestions[n - 1].r return staffQuestions[n - 1].r
} }
@@ -38,27 +37,27 @@ module.exports = {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
if (user.id !== dev) { if (user.user.id !== config.prod.dev) {
if (status === "0") { if (status === "0") {
await interaction.editReply({ content: "Staff applications are currently closed.", ephemeral: true }) await interaction.editReply("Staff applications are currently closed.")
return return
} }
} }
if (!userRoles.has(guildRole)) { // if (!userRoles.has(guildRole)) {
await interaction.editReply({ content: "You must be a member of the guild to apply for staff.", ephemeral: true }) // await interaction.editReply("You must be a member of the guild to apply for staff.")
return // return
} // }
if (userRoles.has(guildStaff)) { // if (userRoles.has(guildStaff)) {
await interaction.editReply({ content: "You are already a staff member.", ephemeral: true }) // await interaction.editReply("You are already a staff member.")
return // return
} // }
const application = await staffapp.findOne({ userID: user.id }) const application = await staffapp.findOne({ userID: user.user.id })
if (application) { if (application) {
await interaction.editReply({ content: "You already have an application in progress.", ephemeral: true }) await interaction.editReply("You already have an application in progress.")
return return
} }
@@ -85,14 +84,14 @@ module.exports = {
}] }]
}) })
} catch (error) { } catch (error) {
await interaction.editReply({ content: "Please enable your DMs.", ephemeral: true }) await interaction.editReply("Please enable your DMs.")
return return
} }
await interaction.editReply({ content: "Please check your DMs.", ephemeral: true }) await interaction.editReply("Please check your DMs.")
const input = await user.dmChannel.awaitMessages({ const input = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 time: 1000 * 60
}) })
@@ -100,11 +99,11 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (input.first().content.toLowerCase() !== "yes") { if (input.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (input.first().attachments.size > 0) { if (input.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -120,8 +119,8 @@ module.exports = {
} }
}] }]
}) })
const answer1 = await user.dmChannel.awaitMessages({ const answer1 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5, time: 1000 * 60 * 5,
}) })
@@ -129,15 +128,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer1.first().content.toLowerCase() === "cancel") { if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer1.first().attachments.size > 0) { if (answer1.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer1.first().content > 16) { if (answer1.first()!.content.length > 16) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 16.", description: "Max character limit is 16.",
@@ -146,7 +145,7 @@ module.exports = {
}) })
return return
} }
const uuid = await getUUID(answer1.first().content) const uuid = await getUUID(answer1.first()!.content)
if (!uuid) { if (!uuid) {
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -157,7 +156,7 @@ module.exports = {
}) })
return return
} }
const answer1_1 = answer1.first().content const answer1_1 = answer1.first()!.content
// second question // second question
await user.send({ await user.send({
@@ -170,8 +169,8 @@ module.exports = {
} }
}] }]
}) })
const answer2 = await user.dmChannel.awaitMessages({ const answer2 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -179,15 +178,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer2.first().content.toLowerCase() === "cancel") { if (answer2.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer2.first().attachments.size > 0) { if (answer2.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer2.first().content > 64) { if (answer2.first()!.content.length > 64) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 64.", description: "Max character limit is 64.",
@@ -196,7 +195,7 @@ module.exports = {
}) })
return return
} }
const answer2_1 = answer2.first().content const answer2_1 = answer2.first()!.content
// third question // third question
await user.send({ await user.send({
@@ -209,8 +208,8 @@ module.exports = {
} }
}] }]
}) })
const answer3 = await user.dmChannel.awaitMessages({ const answer3 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -218,15 +217,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer3.first().content.toLowerCase() === "cancel") { if (answer3.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer3.first().attachments.size > 0) { if (answer3.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer3.first().content > 256) { if (answer3.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -234,7 +233,7 @@ module.exports = {
}] }]
}) })
} }
const answer3_1 = answer3.first().content const answer3_1 = answer3.first()!.content
// fourth question // fourth question
await user.send({ await user.send({
@@ -247,8 +246,8 @@ module.exports = {
} }
}] }]
}) })
const answer4 = await user.dmChannel.awaitMessages({ const answer4 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -256,15 +255,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer4.first().content.toLowerCase() === "cancel") { if (answer4.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer4.first().attachments.size > 0) { if (answer4.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer4.first().content > 256) { if (answer4.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -272,7 +271,7 @@ module.exports = {
}] }]
}) })
} }
const answer4_1 = answer4.first().content const answer4_1 = answer4.first()!.content
// fifth question // fifth question
await user.send({ await user.send({
@@ -285,8 +284,8 @@ module.exports = {
} }
}] }]
}) })
const answer5 = await user.dmChannel.awaitMessages({ const answer5 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -294,15 +293,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer5.first().content.toLowerCase() === "cancel") { if (answer5.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer5.first().attachments.size > 0) { if (answer5.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer5.first().content > 256) { if (answer5.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -310,7 +309,7 @@ module.exports = {
}] }]
}) })
} }
const answer5_1 = answer5.first().content const answer5_1 = answer5.first()!.content
// sixth question // sixth question
await user.send({ await user.send({
@@ -324,8 +323,8 @@ module.exports = {
} }
}] }]
}) })
const answer6 = await user.dmChannel.awaitMessages({ const answer6 = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 15 time: 1000 * 60 * 15
}) })
@@ -333,15 +332,15 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (answer6.first().content.toLowerCase() === "cancel") { if (answer6.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (answer6.first().attachments.size > 0) { if (answer6.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
if (answer6.first().content > 256) { if (answer6.first()!.content.length > 256) {
await user.send({ await user.send({
embeds: [{ embeds: [{
description: "Max character limit is 256.", description: "Max character limit is 256.",
@@ -349,7 +348,7 @@ module.exports = {
}] }]
}) })
} }
const answer6_1 = answer6.first().content const answer6_1 = answer6.first()!.content
await user.send({ await user.send({
embeds: [{ embeds: [{
@@ -358,8 +357,8 @@ module.exports = {
}] }]
}) })
const final = await user.dmChannel.awaitMessages({ const final = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.id, filter: m => m.author.id === user.user.id,
max: 1, max: 1,
time: 1000 * 60 * 5 time: 1000 * 60 * 5
}) })
@@ -367,11 +366,11 @@ module.exports = {
await user.send({ embeds: [tooLong] }) await user.send({ embeds: [tooLong] })
return return
} }
if (final.first().content.toLowerCase() !== "yes") { if (final.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] }) await user.send({ embeds: [cancelled] })
return return
} }
if (final.first().attachments.size > 0) { if (final.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] }) await user.send({ embeds: [attachments] })
return return
} }
@@ -385,21 +384,21 @@ module.exports = {
const newStaffApp = new staffapp({ const newStaffApp = new staffapp({
_id: new mongoose.Types.ObjectId(), _id: new mongoose.Types.ObjectId(),
userID: user.id, userID: user.user.id,
uuid: uuid, uuid: uuid,
}) })
await newStaffApp.save() await newStaffApp.save()
await user.deleteDM() await user.deleteDM()
const channel = guild.channels.cache.get(staffApplicationsChannel) const channel = guild.channels.cache.get(staffApplicationsChannel) as GuildTextBasedChannel
await channel.send({ await channel.send({
embeds: [{ embeds: [{
title: user.username + "#" + user.discriminator + " - Staff Application", title: user.user.username + "#" + user.user.discriminator + " - Staff Application",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: user.avatarURL() url: user.avatarURL() || guild.iconURL()!
}, },
fields: [ fields: [
{ {
@@ -429,12 +428,12 @@ module.exports = {
], ],
footer: { footer: {
iconURL: guild.iconURL(), icon_url: guild.iconURL()!,
text: "ID: " + user.id text: "ID: " + user.user.id
} }
}], }],
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("staffapplicationaccept") .setCustomId("staffapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -448,4 +447,4 @@ module.exports = {
}) })
} }
} }
} } as Button

View File

@@ -1,19 +1,18 @@
const { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } = require("discord.js") import { ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } from "discord.js"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "verify", name: "verify",
description: "Configure the bot.", description: "Configure the bot.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
const modal = new ModalBuilder() const modal = new ModalBuilder()
.setTitle("Verification") .setTitle("Verification")
.setCustomId("verifybox") .setCustomId("verifybox")
.setComponents( .setComponents(
new ActionRowBuilder().setComponents( new ActionRowBuilder<TextInputBuilder>().setComponents(
new TextInputBuilder() new TextInputBuilder()
.setLabel("IGN") .setLabel("IGN")
.setCustomId("verifyign") .setCustomId("verifyign")
@@ -26,4 +25,4 @@ module.exports = {
) )
await interaction.showModal(modal) await interaction.showModal(modal)
} }
} } as Button

View File

@@ -1,14 +1,13 @@
const waitinglist = require("../../schemas/waitinglistSchema.js") import waitinglist from "../../schemas/waitinglistSchema"
const { getGuild } = require("../../utils/utils.js") import { getGuild } from "../../utils/Hypixel"
const { hypixelGuildID } = require("../../../config/options.json") import { hypixelGuildID } from "../../../config/options.json"
import { Button } from "../../interfaces"
module.exports = { export = {
name: "waitinglistupdate", name: "waitinglistupdate",
description: "Update the waiting list.", description: "Update the waiting list.",
type: "button", type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
@@ -34,8 +33,7 @@ module.exports = {
for (let i = 0; i < accepted.length; i++) { for (let i = 0; i < accepted.length; i++) {
const timestamp1 = accepted[i].timestamp / 1000 const timestamp = Math.floor(accepted[i].timestamp / 1000)
const timestamp = Math.floor(timestamp1)
fields.push({ fields.push({
name: `${i + 1}. ${accepted[i].IGN}`, name: `${i + 1}. ${accepted[i].IGN}`,
@@ -45,19 +43,19 @@ module.exports = {
await message.edit({ await message.edit({
embeds: [{ embeds: [{
title: embed.title, title: embed.title!,
description: embed.description, description: embed.description!,
color: embed.color, color: embed.color!,
footer: { footer: {
text: "Last updated by " + user.username, text: "Last updated by " + user.username,
icon_url: user.avatarURL(), icon_url: user.avatarURL()!,
}, },
thumbnail: embed.thumbnail, thumbnail: embed.thumbnail!,
fields: fields, fields: fields,
timestamp: new Date(), timestamp: new Date().toISOString(),
}], }],
}) })
await interaction.editReply({ content: "Updated the waiting list", ephemeral: true }) await interaction.editReply("Updated the waiting list")
} }
} } as Button

View File

@@ -1,28 +1,27 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") import { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Message, GuildMember } from "discord.js"
const { color } = require("../../../config/options.json") import { color } from "../../../config/options.json"
const guildapp = require("../../schemas/guildAppSchema.js") import guildapp from "../../schemas/guildAppSchema"
import { Modal } from "../../interfaces"
module.exports = { export = {
name: "denyreasonbox", name: "denyreasonbox",
description: "Deny reason box.", description: "Deny reason box.",
type: "modal", type: "modal",
/** @param { import('discord.js').ModalSubmitInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const guild = interaction.guild const guild = interaction.guild!
const message = interaction.message const message = interaction.message as Message
const embed = message.embeds[0] const embed = message.embeds[0]
const applicantId = embed.footer.text.split(" ")[1] const applicantId = embed.footer!.text.split(" ")[1]
const reason = interaction.fields.fields.get("denyreason").value || "No reason provided" const reason = interaction.fields.fields.get("denyreason")!.value || "No reason provided"
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
await message.edit({ await message.edit({
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("guildapplicationaccept") .setCustomId("guildapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -42,7 +41,7 @@ module.exports = {
] ]
}) })
let applicant = "" let applicant: GuildMember | null
try { try {
applicant = await guild.members.fetch(applicantId) applicant = await guild.members.fetch(applicantId)
} catch (error) { } catch (error) {
@@ -65,7 +64,7 @@ module.exports = {
.setColor(embedColor) .setColor(embedColor)
.setThumbnail(guild.iconURL()) .setThumbnail(guild.iconURL())
.setFooter({ .setFooter({
iconURL: guild.iconURL(), iconURL: guild.iconURL()!,
text: "ID: " + applicantId text: "ID: " + applicantId
}) })
@@ -73,7 +72,7 @@ module.exports = {
await applicant.send({ embeds: [dmMessage] }) await applicant.send({ embeds: [dmMessage] })
} }
let responseEmbeds = "" let responseEmbeds: EmbedBuilder[]
if (applicant === null) { if (applicant === null) {
responseEmbeds = [responseEmbed, missingUser] responseEmbeds = [responseEmbed, missingUser]
} else { } else {
@@ -86,4 +85,4 @@ module.exports = {
embeds: responseEmbeds embeds: responseEmbeds
}) })
} }
} } as Modal

View File

@@ -1,29 +1,28 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") import { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"
const { color } = require("../../../config/options.json") import { color } from "../../../config/options.json"
const staffapp = require("../../schemas/staffAppSchema.js") import staffapp from "../../schemas/staffAppSchema"
import { Modal } from "../../interfaces"
module.exports = { export = {
name: "staffdenyreasonbox", name: "staffdenyreasonbox",
description: "Deny reason box.", description: "Deny reason box.",
type: "modal", type: "modal",
/** @param { import('discord.js').ModalSubmitInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply() await interaction.deferReply()
const guild = interaction.guild const guild = interaction.guild
const reason = interaction.fields.fields.get("staffdenyreason").value || "No reason provided" const reason = interaction.fields.fields.get("staffdenyreason")!.value || "No reason provided"
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const message = interaction.message const message = interaction.message!
const embed = message.embeds[0] const embed = message.embeds[0]
const applicantId = embed.footer.text.split(" ")[1] const applicantId = embed.footer!.text.split(" ")[1]
const applicant = await guild.members.fetch(applicantId) const applicant = await guild!.members.fetch(applicantId)
await message.edit({ await message.edit({
components: [ components: [
new ActionRowBuilder().addComponents( new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("staffapplicationaccept") .setCustomId("staffapplicationaccept")
.setLabel("Accept") .setLabel("Accept")
@@ -54,13 +53,13 @@ module.exports = {
"**Reason:** `" + reason + "`", "**Reason:** `" + reason + "`",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: applicant.avatarURL() url: applicant.avatarURL() || guild!.iconURL()!
}, },
footer: { footer: {
iconURL: guild.iconURL(), icon_url: guild!.iconURL()!,
text: "ID: " + applicant.id text: "ID: " + applicant.id
} }
}], }],
}) })
} }
} } as Modal

View File

@@ -1,24 +1,24 @@
const { getUUID, getPlayer, getGuild, getHeadURL } = require("../../utils/utils.js") import { getUUID, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
const { color, hypixelGuildID, devMessage } = require("../../../config/options.json") import { color, hypixelGuildID, devMessage } from "../../../config/options.json"
const verify = require("../../schemas/verifySchema.js") import verify from "../../schemas/verifySchema"
const mongoose = require("mongoose") import mongoose from "mongoose"
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../../config/roles.json") import { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } from "../../../config/roles.json"
import { Modal } from "../../interfaces"
import { GuildMember } from "discord.js"
module.exports = { export = {
name: "verifybox", name: "verifybox",
description: "Verify box.", description: "Verify box.",
type: "modal", type: "modal",
/** @param { import('discord.js').ModalSubmitInteraction } interaction */
async execute(interaction) { async execute(interaction) {
await interaction.deferReply({ ephemeral: true }) await interaction.deferReply({ ephemeral: true })
const user1 = interaction.user const user = interaction.member as GuildMember
const user = interaction.guild.members.cache.get(user1.id) const ign = interaction.fields.fields.get("verifyign")!.value
const ign = interaction.fields.fields.get("verifyign").value
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
const verifyData = await verify.findOne({ userID: user.id }) const verifyData = await verify.findOne({ userID: user.user.id })
if (verifyData) { if (verifyData) {
interaction.editReply("You are already verified.\n" + "Try running /update to update your roles.") interaction.editReply("You are already verified.\n" + "Try running /update to update your roles.")
return return
@@ -48,10 +48,10 @@ module.exports = {
} }
let username = "" let username = ""
if (user1.discriminator === "0") { if (user.user.discriminator === "0") {
username = user1.username username = user.user.username
} else { } else {
username = user1.username + "#" + user1.discriminator username = user.user.username + "#" + user.user.discriminator
} }
const linkedDiscord = player?.socialMedia?.links?.DISCORD const linkedDiscord = player?.socialMedia?.links?.DISCORD
@@ -82,7 +82,7 @@ module.exports = {
} }
const guild = await getGuild(uuid) const guild = await getGuild(uuid)
let guildID = "" let guildID: string | null
if (!guild) { if (!guild) {
guildID = null guildID = null
} else { } else {
@@ -90,8 +90,8 @@ module.exports = {
} }
if (guildID === hypixelGuildID) { if (guildID === hypixelGuildID) {
const GuildMembers = guild.members const GuildMembers = guild!.members
const guildRank = GuildMembers.find((member) => member.uuid === player.uuid).rank const guildRank = GuildMembers.find((member) => member.uuid === player.uuid)!.rank
if (guildRank === "Guild Master" && guildID === hypixelGuildID) { if (guildRank === "Guild Master" && guildID === hypixelGuildID) {
await user.roles.add(gm, "Verification") await user.roles.add(gm, "Verification")
@@ -139,15 +139,15 @@ module.exports = {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
{ {
title: interaction.guild.name, title: interaction.guild!.name,
description: "You have successfully verified `" + username + "` with the account `" + player.displayname + "`.", description: "You have successfully verified `" + username + "` with the account `" + player.displayname + "`.",
color: embedColor, color: embedColor,
thumbnail: { thumbnail: {
url: head url: head!
}, },
footer: { footer: {
icon_url: interaction.guild.iconURL(), icon_url: interaction.guild!.iconURL()!,
text: interaction.guild.name + " | " + devMessage text: interaction.guild!.name + " | " + devMessage
} }
} }
] ]
@@ -155,4 +155,4 @@ module.exports = {
} }
} }
} } as Modal

View File

@@ -1,14 +1,14 @@
const { userMention } = require("discord.js") import { ChannelType, GuildMember, userMention } from "discord.js"
const { color, botLogChannel } = require("../../../../config/options.json") import { color, botLogChannel } from "../../../../config/options.json"
import { Event } from "../../../interfaces"
module.exports = { const event: Event = {
name: "logNewJoins", name: "logNewJoins",
description: "Logs new joins", description: "Logs new joins",
type: "event", type: "event",
event: "guildMemberAdd", event: "guildMemberAdd",
/** @param { import('discord.js').GuildMember } member */ execute(member: GuildMember) {
execute(member) {
const channel = member.guild.channels.cache.get(botLogChannel) const channel = member.guild.channels.cache.get(botLogChannel)
const embedColor = Number(color.replace("#", "0x")) const embedColor = Number(color.replace("#", "0x"))
@@ -18,6 +18,11 @@ module.exports = {
return return
} }
if (channel.type !== ChannelType.GuildText) {
console.log("[ERROR] The channel used for new join logging is not a text channel.")
return
}
channel.send({ channel.send({
embeds: [{ embeds: [{
title: "New Member", title: "New Member",
@@ -27,9 +32,11 @@ module.exports = {
footer: { footer: {
text: "ID: " + member.id text: "ID: " + member.id
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
} }
} }
export = event

View File

@@ -1,12 +1,13 @@
module.exports = { import { ChatInputCommandInteraction, ButtonInteraction } from "discord.js"
import { Event } from "../../../interfaces"
const event: Event = {
name: "logBtnsCmds", name: "logBtnsCmds",
description: "Logs all button and command interactions", description: "Logs all button and command interactions",
type: "event", type: "event",
event: "interactionCreate", event: "interactionCreate",
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */ execute(interaction: ChatInputCommandInteraction | ButtonInteraction) {
execute(interaction) {
if (interaction.isCommand()) { if (interaction.isCommand()) {
try { try {
console.log(interaction.user.username + " ran " + console.log(interaction.user.username + " ran " +
@@ -18,11 +19,16 @@ module.exports = {
interaction.commandName interaction.commandName
) )
} }
} else if (interaction.isButton()) { }
if (interaction.isButton()) {
console.log(interaction.user.username + "#" + console.log(interaction.user.username + "#" +
interaction.user.discriminator + " clicked " + interaction.user.discriminator + " clicked " +
interaction.customId interaction.customId
) )
return
} }
} }
} }
export = event

View File

@@ -1,14 +1,17 @@
module.exports = { import { Event } from "../../../interfaces"
import { Message } from "discord.js"
const event: Event = {
name: "ur mom", name: "ur mom",
description: "ur moms someone", description: "ur moms someone",
type: "event", type: "event",
event: "messageCreate", event: "messageCreate",
/** @param { import('discord.js').Message } message */ async execute(message: Message) {
async execute(message) {
if (message.content.toLowerCase().includes("ur mom") && message.author.username === "taken.lua") { if (message.content.toLowerCase().includes("ur mom") && message.author.username === "taken.lua") {
message.react("Woot:734345936347725885") message.react("Woot:734345936347725885")
} }
} }
} }
export = event

View File

@@ -1,11 +0,0 @@
module.exports = {
name: "conolelog",
description: "console log",
type: "event",
event: "ready",
/** @param { import('discord.js').Client } client */
execute(client) {
console.log("Logged in as " + client.user.tag + "!")
}
}

View File

@@ -0,0 +1,15 @@
import { Event } from "../../../interfaces"
import { ExtendedClient as Client } from "../../../utils/Client"
const event: Event = {
name: "conolelog",
description: "console log",
type: "event",
event: "ready",
execute(client: Client) {
console.log("Logged in as " + client.user!.tag + "!")
}
}
export = event

View File

@@ -1,12 +1,15 @@
const { onlineLogChannel, color } = require("../../../../config/options.json") import { onlineLogChannel, color } from "../../../../config/options.json"
import { Event } from "../../../interfaces"
import { ExtendedClient as Client } from "../../../utils/Client"
import { ChannelType } from "discord.js"
module.exports = { const event: Event = {
name: "sendonlinemessage", name: "sendonlinemessage",
description: "send an online message", description: "send an online message",
type: "event", type: "event",
event: "ready", event: "ready",
execute(client) { execute(client: Client) {
if (process.env.NODE_ENV === "dev") return if (process.env.NODE_ENV === "dev") return
const channel = client.channels.cache.get(onlineLogChannel) const channel = client.channels.cache.get(onlineLogChannel)
@@ -17,6 +20,11 @@ module.exports = {
return return
} }
if (channel.type !== ChannelType.GuildText) {
console.log("[ERROR] Online message channel is not a text channel.")
return
}
channel.send({ channel.send({
embeds: [{ embeds: [{
description: "Bot is online!", description: "Bot is online!",
@@ -25,3 +33,5 @@ module.exports = {
}) })
} }
} }
export = event

View File

@@ -1,14 +1,14 @@
const statuses = require("../../../../config/statuses.json") import statuses = require("../../../../config/statuses.json")
import { Event } from "../../../interfaces"
import { ExtendedClient as Client } from "../../../utils/Client"
module.exports = { const event: Event = {
name: "status", name: "status",
description: "Sets the status of the bot", description: "Sets the status of the bot",
type: "event", type: "event",
event: "ready", event: "ready",
/** @param { import('discord.js').Client } client */ execute(client: Client) {
execute(client) {
// Playing 0 // Playing 0
// Streaming 1 // Streaming 1
@@ -17,18 +17,22 @@ module.exports = {
// Custom 4 // Custom 4
// Competing 5 // Competing 5
client.user.setActivity( const user = client.user!
user.setActivity(
{ name: statuses[0].name, type: statuses[0].type } { name: statuses[0].name, type: statuses[0].type }
) )
let i = 1 let i = 1
setInterval(() => setInterval(() =>
client.user.setActivity( user.setActivity(
statuses[i, i++ % statuses.length] statuses[i++ % statuses.length]
), ),
1000 * 60 * 10 1000 * 60 * 10
) )
client.user.setStatus("dnd") user.setStatus("dnd")
} }
} }
export = event

View File

@@ -1,20 +1,16 @@
const { userMention, channelMention } = require("discord.js") import { userMention, channelMention, VoiceState, ChannelType } from "discord.js"
const { botLogChannel, color } = require("../../../../config/options.json") import { botLogChannel, color } from "../../../../config/options.json"
import { Event } from "../../../interfaces"
module.exports = { const event: Event = {
name: "vcJoinLeave", name: "vcJoinLeave",
description: "Logs when a user joins or leaves a voice channel.", description: "Logs when a user joins or leaves a voice channel.",
type: "event", type: "event",
event: "voiceStateUpdate", event: "voiceStateUpdate",
/** execute(oldState: VoiceState, newState: VoiceState) {
* @param { import('discord.js').VoiceState } oldState
* @param { import('discord.js').VoiceState } newState
*/
execute(oldState, newState) { if (process.env.NODE_ENV === 'dev') return
// if (process.env.NODE_ENV === 'dev') return
const guild = oldState.guild const guild = oldState.guild
const channel = guild.channels.cache.get(botLogChannel) const channel = guild.channels.cache.get(botLogChannel)
@@ -25,6 +21,11 @@ module.exports = {
return return
} }
if (channel.type !== ChannelType.GuildText) {
console.log("[ERROR] The channel used for voice channel join/leave logging is not a text channel.")
return
}
const oldChannel = oldState.channel const oldChannel = oldState.channel
const newChannel = newState.channel const newChannel = newState.channel
@@ -33,14 +34,14 @@ module.exports = {
channel.send({ channel.send({
embeds: [{ embeds: [{
title: "Voice Channel Join", title: "Voice Channel Join",
description: userMention(oldState.member.id) + description: userMention(newState.member!.id) +
" joined " + " joined " +
channelMention(newChannel.id), channelMention(newChannel.id),
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + oldState.member.id text: "ID: " + newState.member!.id
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
@@ -49,14 +50,14 @@ module.exports = {
channel.send({ channel.send({
embeds: [{ embeds: [{
title: "Voice Channel Leave", title: "Voice Channel Leave",
description: userMention(oldState.member.id) + description: userMention(oldState.member!.id) +
" left " + " left " +
channelMention(oldChannel.id), channelMention(oldChannel.id),
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + oldState.member.id text: "ID: " + oldState.member!.id
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
@@ -67,16 +68,16 @@ module.exports = {
channel.send({ channel.send({
embeds: [{ embeds: [{
title: "Voice Channel Switch", title: "Voice Channel Switch",
description: userMention(oldState.member.id) + description: userMention(oldState.member!.id) +
" switched from " + " switched from " +
channelMention(oldChannel.id) + channelMention(oldChannel.id) +
" to " + " to " +
channelMention(newChannel.id), channelMention(newChannel.id),
color: embedColor, color: embedColor,
footer: { footer: {
text: "ID: " + oldState.member.id text: "ID: " + oldState.member!.id
}, },
timestamp: new Date() timestamp: new Date().toISOString()
}] }]
}) })
@@ -84,3 +85,5 @@ module.exports = {
} }
} }
export = event

View File

@@ -1,49 +0,0 @@
const { Client, GatewayIntentBits, Partials } = require("discord.js")
const { autoDeployCommands } = require("./utils/autodeploy.js")
const { loadAllEvents } = require("./utils/loadEvents.js")
const { init } = require("./utils/init.js")
require("dotenv").config()
const mongoURI = process.env.MONGOURI
const { connect } = require("mongoose")
const { redis } = require("./utils/redis.js")
init()
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildVoiceStates
],
partials: [
Partials.GuildMember,
Partials.User,
Partials.Message,
Partials.Channel
]
})
loadAllEvents(client)
let token = ""
if (process.env.NODE_ENV === "dev") {
console.log("Running in development mode.")
token = process.env.DEVTOKEN
autoDeployCommands()
} else {
console.log("Running in production mode.")
token = process.env.TOKEN
}
client.login(token)
redis.on("ready", () => {
console.log("Connected to Redis")
})
connect(mongoURI, {}).then(() => {
console.log("Connected to MongoDB")
})

46
src/index.ts Normal file
View File

@@ -0,0 +1,46 @@
import { ExtendedClient as Client} from "./utils/Client"
import { GatewayIntentBits, Partials } from "discord.js"
import config from "./utils/Config"
import { redis } from "./utils/Redis"
import { connect } from "mongoose"
import { loadAllEvents } from "./utils/Events"
import { autoDeployCommands } from "./utils/Autodeploy"
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildVoiceStates
],
partials: [
Partials.GuildMember,
Partials.User,
Partials.Message,
Partials.Channel
]
})
loadAllEvents(client)
let token: string
if (process.env.NODE_ENV === "dev") {
console.log("Running in development mode.")
token = config.dev.devtoken
autoDeployCommands()
} else {
console.log("Running in production mode.")
token = config.prod.token
}
client.login(token)
redis.on("ready", () => {
console.log("Connected to Redis")
})
connect(config.prod.mongoURI, {}).then(() => {
console.log("Connected to MongoDB")
})

View File

@@ -0,0 +1,8 @@
import { AutocompleteInteraction } from "discord.js"
export default interface Autocomplete {
name: string
description: string
type: "autocomplete"
execute: (interaction: AutocompleteInteraction) => Promise<void>
}

8
src/interfaces/Button.ts Normal file
View File

@@ -0,0 +1,8 @@
import { ButtonInteraction } from "discord.js"
export default interface Button {
name: string
description: string
type: "button"
execute: (interaction: ButtonInteraction) => Promise<void>
}

13
src/interfaces/Command.ts Normal file
View File

@@ -0,0 +1,13 @@
import { ChatInputCommandInteraction, SlashCommandBuilder} from "discord.js"
import { ExtendedClient as Client } from "../utils/Client"
export default interface Command {
name: string
description: string
type: "slash"
dev?: boolean
public: boolean
data: Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup" | "addIntegerOption">
subcommands?: boolean
execute: (interaction: ChatInputCommandInteraction, client: Client) => Promise<void>
}

19
src/interfaces/Config.ts Normal file
View File

@@ -0,0 +1,19 @@
interface ProdConfig {
token: string
mongoURI: string
dev: string
hypixelapikey: string
redisURI: string
}
interface DevConfig {
devtoken: string
clientid: string
devid: string
guildid: string
}
export default interface Config {
prod: ProdConfig
dev: DevConfig
}

View File

@@ -0,0 +1,10 @@
import { ContextMenuCommandInteraction, ContextMenuCommandBuilder } from "discord.js"
export default interface ContextMenu {
name: string
description: string
type: "contextmenu"
dev?: boolean
data: ContextMenuCommandBuilder
execute: (interaction: ContextMenuCommandInteraction) => Promise<void>
}

9
src/interfaces/Event.ts Normal file
View File

@@ -0,0 +1,9 @@
import { ClientEvents } from "discord.js"
export default interface Event {
name: string,
description: string,
type: "event",
event: keyof ClientEvents
execute(...args: any[]): void
}

96
src/interfaces/Guild.ts Normal file
View File

@@ -0,0 +1,96 @@
export interface Guild {
data: {
success: boolean
guild: GuildData
}
}
export interface GuildData {
_id: string
name: string
coins: number
coinsEver: number
created: number
members: Member[]
achievements: GuildAchievements
exp: number
legacyRanking: number
name_lower: string
tagColor: string
description: string
ranks: Rank[]
preferredGames: string[]
banner: Banner
chatMute: number
tag: string
publiclyListed: boolean
guildExpByGameType: GuildExpByGameType
}
export interface Member {
uuid: string
rank: string
joined: number
questParticipation?: number
expHistory: ExpHistory
mutedTill?: number
}
export interface ExpHistory {
[key: string]: number
}
export interface GuildAchievements {
WINNERS: number
EXPERIENCE_KINGS: number
ONLINE_PLAYERS: number
}
export interface Rank {
name: string
default: boolean
tag: string
created: number
priority: number
}
export interface Banner {
Base: string
Patterns: Pattern[]
}
export interface Pattern {
Pattern: string
Color: any
}
export interface GuildExpByGameType {
PAINTBALL: number
BUILD_BATTLE: number
SKYWARS: number
WOOL_GAMES: number
MCGO: number
GINGERBREAD: number
REPLAY: number
HOUSING: number
VAMPIREZ: number
PROTOTYPE: number
ARCADE: number
WALLS: number
UHC: number
WALLS3: number
SKYBLOCK: number
QUAKECRAFT: number
SURVIVAL_GAMES: number
SPEED_UHC: number
ARENA: number
DUELS: number
MURDER_MYSTERY: number
BEDWARS: number
SUPER_SMASH: number
PIT: number
SMP: number
BATTLEGROUND: number
LEGACY: number
TNTGAMES: number
}

8
src/interfaces/Modal.ts Normal file
View File

@@ -0,0 +1,8 @@
import { ModalSubmitInteraction } from "discord.js"
export default interface Modal {
name: string
description: string
type: "modal"
execute: (interaction: ModalSubmitInteraction) => Promise<void>
}

12045
src/interfaces/Player.ts Normal file

File diff suppressed because it is too large Load Diff

24
src/interfaces/index.ts Normal file
View File

@@ -0,0 +1,24 @@
import Autocomplete from "./Autocomplete"
import Button from "./Button"
import Command from "./Command"
import ContextMenu from "./ContextMenu"
import Event from "./Event"
import Modal from "./Modal"
import Config from "./Config"
import { Guild, GuildData } from "./Guild"
import { Player, PlayerData } from "./Player"
export {
Config,
Autocomplete,
Button,
Command,
ContextMenu,
Event,
Modal,
Guild,
GuildData,
Player,
PlayerData
}

View File

@@ -1,4 +1,4 @@
const { Schema, model } = require("mongoose") import { Schema, model } from "mongoose"
const guildAppSchema = new Schema({ const guildAppSchema = new Schema({
_id: Schema.Types.ObjectId, _id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const guildAppSchema = new Schema({
uuid: { type: String, required: true }, uuid: { type: String, required: true },
}) })
module.exports = model("guildapp", guildAppSchema, "guildapp") export = model("guildapp", guildAppSchema, "guildapp")

View File

@@ -1,4 +1,4 @@
const { Schema, model } = require("mongoose") import { Schema, model } from "mongoose"
const settingsSchema = new Schema({ const settingsSchema = new Schema({
_id: Schema.Types.ObjectId, _id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const settingsSchema = new Schema({
value: { type: String, required: true }, value: { type: String, required: true },
}) })
module.exports = model("settings", settingsSchema, "settings") export = model("settings", settingsSchema, "settings")

View File

@@ -1,4 +1,4 @@
const { Schema, model } = require("mongoose") import { Schema, model } from "mongoose"
const staffAppSchema = new Schema({ const staffAppSchema = new Schema({
_id: Schema.Types.ObjectId, _id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const staffAppSchema = new Schema({
uuid: { type: String, required: true }, uuid: { type: String, required: true },
}) })
module.exports = model("staffapp", staffAppSchema, "staffapp") export = model("staffapp", staffAppSchema, "staffapp")

View File

@@ -1,4 +1,4 @@
const { Schema, model } = require("mongoose") import { Schema, model } from "mongoose"
const verifySchema = new Schema({ const verifySchema = new Schema({
_id: Schema.Types.ObjectId, _id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const verifySchema = new Schema({
uuid: { type: String, required: true }, uuid: { type: String, required: true },
}) })
module.exports = model("verify", verifySchema, "verify") export = model("verify", verifySchema, "verify")

View File

@@ -1,11 +1,11 @@
const { Schema, model } = require("mongoose") import { Schema, model } from "mongoose"
const waitinglistSchema = new Schema({ const waitinglistSchema = new Schema({
_id: Schema.Types.ObjectId, _id: Schema.Types.ObjectId,
userID: { type: String, required: true }, userID: { type: String, required: true },
uuid: { type: String, required: true }, uuid: { type: String, required: true },
IGN: { type: String, required: true }, IGN: { type: String, required: true },
timestamp: { type: String, required: true } timestamp: { type: Number, required: true }
}) })
module.exports = model("waitinglist", waitinglistSchema, "waitinglist") export = model("waitinglist", waitinglistSchema, "waitinglist")

15
src/typings/Profile.ts Normal file
View File

@@ -0,0 +1,15 @@
export type Profile = {
data: {
id: string
name: string;
}
}
export type Profile2 = {
data: {
id: string,
name: string,
properties: { name: string, value: string }[],
profileActions: []
}
}

6
src/typings/index.ts Normal file
View File

@@ -0,0 +1,6 @@
import { Profile, Profile2 } from "./Profile"
export {
Profile,
Profile2
}

View File

@@ -1,22 +1,12 @@
const { REST, Routes } = require("discord.js") import { Command } from "../interfaces"
const log = require("log-beautify") import config from "./Config"
const fs = require("fs") import { REST, RESTGetAPIApplicationGuildCommandResult, RESTPutAPIApplicationGuildCommandsJSONBody, Routes } from "discord.js"
require("dotenv").config() import fs = require("fs")
const token = process.env.DEVTOKEN
const clientId = process.env.DEVID
const guildId = process.env.GUILDID
log.useSymbols = false
log.setColors({
newCmds: "#b4befe",
currentCmds: "#f38ba8"
})
async function autoDeployCommands() { async function autoDeployCommands() {
const commands = [] const commands = []
const commandFiles = fs.readdirSync("./src/commands/").filter(file => file.endsWith(".js")) const commandFiles = fs.readdirSync("./dist/src/commands/").filter(file => file.endsWith(".js"))
const contentMenuCommands = fs.readdirSync("./src/commands-contextmenu/").filter(file => file.endsWith(".js")) const contentMenuCommands = fs.readdirSync("./dist/src/commands-contextmenu/").filter(file => file.endsWith(".js"))
const commandsTesting = fs.readdirSync("./src/commands-testing/").filter(file => file.endsWith(".js"))
for (const file of commandFiles) { for (const file of commandFiles) {
const command = require(`../commands/${file}`) const command = require(`../commands/${file}`)
@@ -25,23 +15,17 @@ async function autoDeployCommands() {
} }
} }
for (const file of contentMenuCommands) { for (const file of contentMenuCommands) {
const command = require(`../commands-contextmenu/${file}`) const command: Command = require(`../commands-contextmenu/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
for (const file of commandsTesting) {
const command = require(`../commands-testing/${file}`)
if (command.dev) { if (command.dev) {
commands.push(command.data.toJSON()) commands.push(command.data.toJSON())
} }
} }
const rest = new REST({ version: "10" }).setToken(token) const rest = new REST({ version: "10" }).setToken(config.dev.devtoken)
const currentCommands = await rest.get( const currentCommands = await rest.get(
Routes.applicationGuildCommands(clientId, guildId), Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
) ) as RESTGetAPIApplicationGuildCommandResult[]
const currentCommandsInfo = currentCommands.map(command => { const currentCommandsInfo = currentCommands.map(command => {
return { return {
@@ -67,23 +51,23 @@ async function autoDeployCommands() {
}).join("\n") }).join("\n")
if (JSON.stringify(sortedNewCommandsInfo) === JSON.stringify(sortedCurrentCommandsInfo)) { if (JSON.stringify(sortedNewCommandsInfo) === JSON.stringify(sortedCurrentCommandsInfo)) {
log.success("Commands are the same, skipping deploy.") console.log("Commands are the same, skipping deploy.")
log.newCmds(newCmds) console.log(newCmds)
return return
} }
(async () => { (async () => {
try { try {
log.warning("Commands are different, starting deploy.") console.log("Commands are different, starting deploy.")
log.currentCmds(currentCmds) console.log(currentCmds)
console.log(`Started refreshing ${commands.length} application (/) commands.`) console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put( const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId), Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
{ body: commands }, { body: commands },
) ) as RESTPutAPIApplicationGuildCommandsJSONBody[]
log.newCmds(newCmds) console.log(newCmds)
console.log(`Successfully reloaded ${data.length} application (/) commands.`) console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
@@ -91,4 +75,4 @@ async function autoDeployCommands() {
})() })()
} }
module.exports = { autoDeployCommands } export { autoDeployCommands }

14
src/utils/Client.ts Normal file
View File

@@ -0,0 +1,14 @@
import { Client, Collection } from "discord.js"
import { Command } from "../interfaces"
import { ContextMenu } from "../interfaces"
import { Button } from "../interfaces"
import { Modal } from "../interfaces"
import { Autocomplete } from "../interfaces"
export class ExtendedClient extends Client {
commands: Collection<string, Command>= new Collection()
contextmenus: Collection<string, ContextMenu>= new Collection()
buttons: Collection<string, Button>= new Collection()
modals: Collection<string, Modal>= new Collection()
autocomplete: Collection<string, Autocomplete>= new Collection()
}

20
src/utils/Config.ts Normal file
View File

@@ -0,0 +1,20 @@
import { Config } from "../interfaces"
import "dotenv/config"
const config: Config = {
prod: {
token: process.env.TOKEN!,
mongoURI: process.env.MONGOURI!,
dev: process.env.DEV!,
hypixelapikey: process.env.HYPIXELAPIKEY!,
redisURI: process.env.REDISURI!
},
dev: {
devtoken: process.env.DEVTOKEN!,
clientid: process.env.CLIENTID!,
devid: process.env.DEVID!,
guildid: process.env.GUILDID!,
}
}
export default config

16
src/utils/Events.ts Normal file
View File

@@ -0,0 +1,16 @@
import { ExtendedClient as Client } from "./Client"
import { loadButtonEvents } from "./eventHandlers/button"
import { loadSlashCommandsEvents } from "./eventHandlers/command"
import { loadContextMenuEvents } from "./eventHandlers/contextmenu"
import { loadModalEvents } from "./eventHandlers/modal"
import { loadEvents } from "./eventHandlers/events"
import { loadAutocompleteEvents } from "./eventHandlers/autocomplete"
export function loadAllEvents(client: Client) {
loadEvents(client)
loadButtonEvents(client)
loadSlashCommandsEvents(client)
loadContextMenuEvents(client)
loadModalEvents(client)
loadAutocompleteEvents(client)
}

6
src/utils/Hypixel.ts Normal file
View File

@@ -0,0 +1,6 @@
export { skywarsLevel } from "./functions/skywars"
export { bedwarsLevel } from "./functions/bedwars"
export { hypixelLevel } from "./functions/hypixel"
export { formatUuid } from "./functions/uuid"
export { guildLevel, scaledGEXP } from "./functions/guild"
export { getUUID, getIGN, getPlayer, getGuild, getHeadURL } from "./functions/account"

Some files were not shown because too many files have changed in this diff Show More