Converted main codebase to typescript

Signed-off-by: Taken <taken@mairimashita.org>
This commit is contained in:
2023-12-28 13:17:57 +01:00
parent 1d9ded82a4
commit 68fde04bbb
122 changed files with 14230 additions and 1834 deletions

1
.gitignore vendored
View File

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

View File

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

View File

@@ -2,7 +2,9 @@
"restartable": "rs",
"ignore": [
".git",
"node_modules/**/node_modules"
"node_modules/**/node_modules",
"dist/config",
"src"
],
"verbose": true,
"env": {

View File

@@ -2,17 +2,17 @@
"name": "illegitimate-bot",
"version": "1.0.0",
"description": "",
"main": "dist/src/index.js",
"main": "src/index.ts",
"scripts": {
"start": "node dist/src/index.js",
"build": "tsc",
"dev": "nodemon",
"dev:ts": "nodemon --exec node_modules/.bin/tsx src/index.ts",
"dev:build": "node scripts/dev-deploy.js",
"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:fix": "eslint_d --fix src",
"prod:build:global": "node scripts/deploy-commands.js --prod",
"prod:build:user": "node scripts/deploy-commands.js --dev"
"prod:build": "ts-node scripts/deploy-commands.ts"
},
"author": "Taken",
"license": "GPL-3.0-only",
@@ -24,13 +24,12 @@
"log-beautify": "^1.2.0",
"mongoose": "^7.0.1",
"ms": "^2.1.3",
"pretty-ms": "^8.0.0",
"ts-node": "^10.9.2"
"pretty-ms": "^8.0.0"
},
"devDependencies": {
"@types/ms": "^0.7.34",
"@types/node": "^20.10.5",
"tsx": "^4.7.0",
"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",
description: "Congratulate a user.",
type: "contextmenu",
dev: false,
data: new ContextMenuCommandBuilder()
.setName("Congratulate")
.setType(ApplicationCommandType.Message)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
/** @param { import('discord.js').ContextMenuCommandInteraction } interaction */
async execute(interaction) {
const { targetId } = interaction
const message = await interaction.channel.messages.fetch(targetId)
const message = await interaction.channel!.messages.fetch(targetId)
if (!message) {
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 })
}
}
} 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")
const { admin, helper } = require("../../config/roles.json")
const { color } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
import { admin, helper } from "../../config/roles.json"
import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "ban",
description: "Ban a user",
type: "slash",
@@ -38,32 +39,38 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
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 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 modRoles = mod.roles.cache.map(role => role.id)
const embedColor = Number(color.replace("#", "0x"))
if (!modRoles.includes(admin)) {
await interaction.editReply("You do not have permission to use this command.")
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.")
return
}
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) {
@@ -71,7 +78,7 @@ module.exports = {
return
}
if (member.id === interaction.guild.ownerId) {
if (member.id === interaction.guild!.ownerId) {
await interaction.editReply("I ban kick the server owner.")
return
}
@@ -87,8 +94,8 @@ module.exports = {
}
await member.ban({
deleteMessageSeconds: messageDeletionDays * 86400,
reason: reason + ` - ${mod.user.username}`
reason: reason,
deleteMessageDays: messageDeletionDays
})
await interaction.editReply({
@@ -101,11 +108,11 @@ module.exports = {
color: embedColor,
footer: {
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")
const { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } = require("../../config/reqs.json")
const { color, devMessage } = require("../../config/options.json")
const { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } = require("../utils/utils.js")
import { SlashCommandBuilder } from "discord.js"
import { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } from "../../config/reqs.json"
import { color, devMessage } from "../../config/options.json"
import { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } from "../utils/Hypixel"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "check",
description: "Check a player's stats.",
type: "slash",
@@ -17,8 +18,6 @@ module.exports = {
.setDescription("The player's IGN.")
.setRequired(true)),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply({})
@@ -111,7 +110,7 @@ module.exports = {
if (!guild) {
guildRank = "N/A"
} else {
guildRank = guild.members.find((m) => m.uuid === uuid).rank
guildRank = guild.members.find((m) => m.uuid === uuid)!.rank
}
const statsFields = []
@@ -235,7 +234,7 @@ module.exports = {
const level = hypixelLevel(hypixelExp)
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({
embeds: [{
@@ -246,14 +245,14 @@ module.exports = {
"**Guild Rank:** `" + guildRank + "`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: footerText + " | " + devMessage,
icon_url: footerIcon
icon_url: footerIcon!
},
fields: statsFields
}]
})
}
}
} as Command

View File

@@ -1,7 +1,8 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js")
const { color } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits, ChannelType, GuildTextBasedChannel } from "discord.js"
import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "clear",
description: "Clears messages",
type: "slash",
@@ -19,14 +20,12 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
const amount = interaction.options.getInteger("amount")
const channel = interaction.channel
const amount = interaction.options.getInteger("amount")!
const channel2 = interaction.channel!
const embedColor = Number(color.replace("#", "0x"))
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 => {
const messagesToDelete = messages.map(m => m)
.filter(m =>
@@ -56,4 +66,4 @@ module.exports = {
})
})
}
}
} as Command

View File

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

View File

@@ -1,9 +1,12 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js")
module.exports = {
import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from "discord.js"
import { Command } from "../interfaces"
const command: Command = {
name: "dev-info",
description: "Test command for the bot.",
type: "slash",
dev: true,
public: false,
data: new SlashCommandBuilder()
.setName("dev-info")
@@ -15,13 +18,11 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.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 fields = embed.fields
const field1 = fields[0]
@@ -31,3 +32,5 @@ module.exports = {
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",
description: "Admin command.",
type: "slash",
@@ -17,8 +18,6 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const subcommand = interaction.options.getSubcommand()
@@ -28,7 +27,7 @@ module.exports = {
const { exec } = require("child_process")
await interaction.reply({ content: "Reloading...", ephemeral: true })
exec("pm2 restart 0", async (err) => {
exec("pm2 restart 0", async (err: Error) => {
if (err) {
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")
const { color, devMessage } = require("../../config/options.json")
const verify = require("../schemas/verifySchema.js")
const { gm, manager, moderator, beast, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json")
import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import verify = require("../schemas/verifySchema")
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]
module.exports = {
export = {
name: "forceunverify",
description: "Force unverify a user",
type: "slash",
@@ -22,13 +23,10 @@ module.exports = {
.setDMPermission(false)
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const member1 = interaction.options.getUser("user")
const member = interaction.guild.members.cache.get(member1.id)
const member = interaction.options.getMember("user") as GuildMember
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) {
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 interaction.reply({
embeds: [{
description: "Successfully unverified " + userMention(member1.id),
description: "Successfully unverified " + userMention(member.user.id),
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
}
}
} as Command

View File

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

View File

@@ -1,10 +1,11 @@
const { SlashCommandBuilder } = require("discord.js")
const { color, devMessage } = require("../../config/options.json")
const { guildMember } = require("./guild/member.js")
const { guildInfo } = require("./guild/info.js")
const { guildTop } = require("./guild/top.js")
import { SlashCommandBuilder } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
import guildMember = require("./guild/member")
import guildInfo = require("./guild/info")
import guildTop = require("./guild/top")
module.exports = {
export = {
name: "guild",
description: "Subcommands for guilds",
type: "slash",
@@ -72,8 +73,6 @@ module.exports = {
.setDescription("The amount of guild members to show. [Default: 10]"))
),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const subcommand = interaction.options.getSubcommand()
@@ -95,7 +94,7 @@ module.exports = {
}
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({
embeds: [{
@@ -103,9 +102,9 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color, devMessage } = require("../../../config/options.json")
import { getUUID, getIGN, getPlayer, getGuild, guildLevel } from "../../utils/Hypixel"
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) {
async function guildInfo(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply()
const query = interaction.options.getString("query")
const query = interaction.options.getString("query")!
const type = interaction.options.getString("type") || "ign"
const embedColor = Number(color.replace("#", "0x"))
let guild
let guild: GuildData | null
if (type === "ign") {
await interaction.editReply({
@@ -103,14 +103,14 @@ async function guildInfo(interaction) {
}
}
const guildName = guild.name
const guildCreatedMS = guild.created
const guildName = guild!.name
const guildCreatedMS = guild!.created
const guildCreated = new Date(guildCreatedMS)
const guildTag = guild.tag
const guildExpUnformatted = guild.exp
const guildTag = guild!.tag
const guildExpUnformatted = guild!.exp
const guildExp = new Intl.NumberFormat("en-US").format(guildExpUnformatted)
const guildLvl = guildLevel(guildExpUnformatted)
const guildMembers = guild.members
const guildMembers = guild!.members
const guildCreatedDate = guildCreated.getDate()
const guildCreatedMonth = guildCreated.getMonth() + 1
@@ -126,9 +126,9 @@ async function guildInfo(interaction) {
guildCreatedMinute + ":" +
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 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 allGuildMembersWeeklyXP = guildMembers.map(member => member.expHistory)
@@ -143,7 +143,7 @@ async function guildInfo(interaction) {
const averageGuildMembersWeeklyXP = new Intl.NumberFormat("en-US").format(averageGuildMembersWeeklyXPUnformatted)
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({
embeds: [{
@@ -171,10 +171,10 @@ async function guildInfo(interaction) {
color: embedColor,
footer: {
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")
const { color, devMessage } = require("../../../config/options.json")
import { getUUID, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
import { color, devMessage } from "../../../config/options.json"
import { ChatInputCommandInteraction } from "discord.js"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async function guildMember(interaction) {
async function guildMember(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply()
const ign = interaction.options.getString("ign")
const ign = interaction.options.getString("ign")!
const embedColor = Number(color.replace("#", "0x"))
await interaction.editReply({
@@ -45,11 +44,11 @@ async function guildMember(interaction) {
description: "This user never logged on to hypixel",
color: embedColor,
thumbnail: {
url: head,
url: head!,
},
footer: {
text: interaction?.guild.name || interaction.user.username + " | " + devMessage,
icon_url: interaction?.guild.iconURL({ dynamic: true }) || interaction.user.avatarURL({ dynamic: true }),
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
},
],
@@ -88,11 +87,11 @@ async function guildMember(interaction) {
description: "This user is not in a guild",
color: embedColor,
thumbnail: {
url: head,
url: head!,
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true }),
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!,
},
}],
})
@@ -104,8 +103,8 @@ async function guildMember(interaction) {
const guildMembers = guild.members
const guildMember = guildMembers.find((member) => member.uuid === uuid)
const guildRank = guildMember.rank
const memberGexp = guildMember.expHistory
const guildRank = guildMember!.rank
const memberGexp = guildMember!.expHistory
const allDaysGexp = Object.keys(memberGexp).map((key) => {
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 averageWeeklyGexp = new Intl.NumberFormat("en-US").format(averageWeeklyGexpUnformatted)
const guildMemberJoinMS = guildMember.joined
const guildMemberJoinMS = guildMember!.joined
const guildMemberJoinTime = new Date(guildMemberJoinMS)
const guildMemberJoinDate = guildMemberJoinTime.getDate()
const guildMemberJoinMonth = guildMemberJoinTime.getMonth() + 1
@@ -133,7 +132,7 @@ async function guildMember(interaction) {
guildMemberJoinSeconds
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({
embeds: [{
@@ -142,7 +141,7 @@ async function guildMember(interaction) {
"**Guild Rank:** `" + guildRank + "`\n",
color: embedColor,
thumbnail: {
url: head,
url: head!,
},
fields: [
{
@@ -161,10 +160,10 @@ async function guildMember(interaction) {
],
footer: {
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")
const { color, devMessage } = require("../../../config/options.json")
const { ChannelType } = require("discord.js")
const { redis } = require("../../utils/redis.js")
import { getUUID, getPlayer, getGuild, getIGN } from "../../utils/Hypixel"
import { color, devMessage } from "../../../config/options.json"
import { ChannelType, ChatInputCommandInteraction } from "discord.js"
import { redis } from "../../utils/Redis"
import { GuildData } from "../../interfaces/Guild"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async function guildTop(interaction) {
async function guildTop(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply()
const query = interaction.options.getString("query")
const query = interaction.options.getString("query")!
const type = interaction.options.getString("type") || "ign"
let amount = interaction.options.getNumber("amount") || 10
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({
embeds: [{
description: "You can't use this command in DMs!",
@@ -116,9 +115,9 @@ async function guildTop(interaction) {
}
}
const guildName = guild.name
const guildMembers = guild.members
const guildId = guild._id
const guildName = guild!.name
const guildMembers = guild!.members
const guildId = guild!._id
const cachedData = await redis.get("guildTop+" + guildId)
@@ -145,9 +144,12 @@ async function guildTop(interaction) {
amount = 1
}
let cacheStatus
let guildData = []
const fieldsValueRaw = []
type GuildTopData = { ign: string, gexp: string }[]
type NewList = { name: string, value: string, inline: boolean }[]
let cacheStatus: boolean
let guildData: GuildTopData = []
const fieldsValueRaw: string[] = []
const allMembersSorted = allMembersDailyGEXP.sort((a, b) => b.gexp - a.gexp)
if (!cachedData) {
@@ -160,7 +162,7 @@ async function guildTop(interaction) {
})
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 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 newList = []
const newList: NewList = []
list.forEach((item, index) => {
if (item.length === 0) return
@@ -208,7 +210,7 @@ async function guildTop(interaction) {
})
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]" : ""
await interaction.editReply({
@@ -220,10 +222,10 @@ async function guildTop(interaction) {
fields: newList,
footer: {
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

@@ -1,11 +1,12 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js")
const { color, devMessage, instructionsgif } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
import { color, devMessage, instructionsgif } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "instructions",
description: "Instructions for verification",
type: "slash",
dev: true,
dev: false,
public: false,
data: new SlashCommandBuilder()
@@ -13,8 +14,6 @@ module.exports = {
.setDescription("Instructions for verification")
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const embedColor = Number(color.replace("#", "0x"))
@@ -29,14 +28,15 @@ module.exports = {
"6. Run the `/verify` command in this channel.\n",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
image: {
url: instructionsgif
url: instructionsgif,
proxy_url: instructionsgif
}
}]
})
}
}
} as Command

View File

@@ -1,8 +1,9 @@
const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js")
const { admin, helper } = require("../../config/roles.json")
const { color } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits, userMention, GuildMember } from "discord.js"
import { admin, helper } from "../../config/roles.json"
import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "kick",
description: "Kick a member from the server.",
type: "slash",
@@ -24,18 +25,22 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
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 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 modRoles = mod.roles.cache.map(role => role.id)
const embedColor = Number(color.replace("#", "0x"))
if (!modRoles.includes(helper) && !modRoles.includes(admin)) {
await interaction.editReply("You do not have permission to use this command.")
@@ -47,13 +52,14 @@ module.exports = {
return
}
if (member.id === interaction.guild.ownerId) {
if (member.id === interaction.guild!.ownerId) {
await interaction.editReply("I cannot kick the server owner.")
return
}
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)) {
@@ -77,11 +83,11 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color, devMessage } = require("../../config/options.json")
import { SlashCommandBuilder } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "ping",
description: "Get the bot's ping.",
type: "slash",
@@ -12,18 +13,13 @@ module.exports = {
.setName("ping")
.setDescription("Get's the bot's ping."),
/**
* @param { import("discord.js").ChatInputCommandInteraction } interaction
* @param { import("discord.js").Client } client}
*/
async execute(interaction, client) {
await interaction.deferReply()
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 })
const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({
embeds: [{
@@ -31,10 +27,10 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color } = require("../../config/options.json")
const { waitinglistSchema } = require("../schemas/waitinglistSchema.js")
import { SlashCommandBuilder, PermissionFlagsBits, userMention } from "discord.js"
import { color } from "../../config/options.json"
import waitinglistSchema = require("../schemas/waitinglistSchema")
import { Command } from "../interfaces"
module.exports = {
export = {
name: "remove",
description: "Remove a person on the waiting list.",
type: "slash",
@@ -27,15 +28,13 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } 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 mod = interaction.user
const mod = interaction.user!
const embedColor = Number(color.replace("#", "0x"))
const waitinglist = await waitinglistSchema.findOne({ UserID: user.id })
@@ -44,7 +43,7 @@ module.exports = {
await interaction.editReply({
embeds: [{
description: userMention(user.id) + " is not on the waiting list.",
color: color
color: embedColor
}]
})
return
@@ -60,10 +59,10 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color, devMessage } = require("../../config/options.json")
const { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } = require("../../config/reqs.json")
import { SlashCommandBuilder } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { bwfkdr, bwstars, bwwins, swstars, swkdr, duelswins, duelswlr } from "../../config/reqs.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "reqs",
description: "Displays the requirements for the guild.",
type: "slash",
@@ -13,15 +14,13 @@ module.exports = {
.setName("reqs")
.setDescription("Displays the requirements for the guild."),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
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 })
const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
await interaction.editReply({
embeds: [{
@@ -29,7 +28,7 @@ module.exports = {
description: "**You must make 100k-150k weekly GEXP.\nAs well as onne of the game stats below**",
color: embedColor,
thumbnail: {
url: interaction?.guild?.iconURL({ dynamic: true }) || null
url: interaction?.guild?.iconURL({ forceStatic: false }) || ""
},
fields: [
{
@@ -51,9 +50,9 @@ module.exports = {
],
footer: {
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",
description: "Set your nickname",
type: "slash",
@@ -23,16 +24,15 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.ManageNicknames)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const user = interaction.options.getUser("user")
const user = interaction.options.getUser("user")!
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) {
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}`)
@@ -40,4 +40,4 @@ module.exports = {
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")
const { color, devMessage } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits, ButtonBuilder, ActionRowBuilder, ButtonStyle, ChannelType, GuildTextBasedChannel } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "setup",
description: "Used for setup of the bot.",
type: "slash",
@@ -61,45 +62,57 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
const subcommand = interaction.options.getSubcommand()
const embedColor = Number(color.replace("#", "0x"))
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({
embeds: [
{
embeds: [{
title: "Guild Application",
description: "You can apply for the guild by clicking the button below.",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false }) || undefined
},
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
url: interaction.guild!.iconURL({ forceStatic: false }) || ""
}
}
],
}],
components: [
new ActionRowBuilder()
.addComponents(new ButtonBuilder()
new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("guildapply")
.setLabel("Apply")
.setStyle(ButtonStyle.Primary)
.setEmoji({ name: "✅" }))
.setEmoji({ name: "✅" })
)
]
})
await interaction.reply({ content: "Message sent", ephemeral: true })
}
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({
embeds: [
@@ -108,16 +121,16 @@ module.exports = {
description: "You can apply for the staff team by clicking the button below.",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
url: interaction.guild!.iconURL({ forceStatic: false })!
}
}
],
components: [
new ActionRowBuilder()
new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder()
.setCustomId("staffapply")
.setLabel("Apply")
@@ -130,7 +143,14 @@ module.exports = {
}
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({
embeds: [
@@ -139,16 +159,16 @@ module.exports = {
description: "You can send an inactivity log by clicking the button below.",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
url: interaction.guild!.iconURL({ forceStatic: false })!
}
}
],
components: [
new ActionRowBuilder()
new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder()
.setCustomId("guildinactivitylog")
.setLabel("Submit")
@@ -161,7 +181,14 @@ module.exports = {
}
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({
embeds: [{
@@ -169,15 +196,15 @@ module.exports = {
description: "You can verify by clicking the button below.",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
url: interaction.guild!.iconURL({ forceStatic: false })!
}
}],
components: [
new ActionRowBuilder()
new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder()
.setCustomId("verify")
.setLabel("Verify")
@@ -190,7 +217,14 @@ module.exports = {
}
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({
embeds: [{
@@ -199,15 +233,15 @@ module.exports = {
"Try to invite them in order.",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
iconURL: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
},
thumbnail: {
url: interaction.guild.iconURL({ dynamic: true })
url: interaction.guild!.iconURL({ forceStatic: false })!
}
}],
components: [
new ActionRowBuilder()
new ActionRowBuilder<ButtonBuilder>()
.addComponents(new ButtonBuilder()
.setCustomId("waitinglistupdate")
.setLabel("Update")
@@ -219,4 +253,4 @@ module.exports = {
}
}
}
} as Command

View File

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

View File

@@ -1,14 +1,15 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js")
const { color, devMessage } = require("../../config/options.json")
const { beast } = require("./staff/beast.js")
const { help } = require("./staff/help.js")
const { updateDiscordRoles } = require("./staff/updatediscordroles.js")
import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { Command } from "../interfaces"
import { help} from "./staff/help"
import { beast } from "./staff/beast"
import { updateDiscordRoles } from "./staff/updatediscordroles"
module.exports = {
export = {
name: "staff",
description: "Subcommands for staff",
type: "slash",
dev: true,
dev: false,
public: false,
subcommands: true,
@@ -38,15 +39,13 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
async execute(interaction, client) {
const subcommand = interaction.options.getSubcommand()
const embedColor = Number(color.replace("#", "0x"))
if (subcommand === "help") {
help(interaction)
help(interaction, client)
return
}
@@ -61,7 +60,7 @@ module.exports = {
}
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({
embeds: [{
@@ -69,9 +68,9 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color, devMessage } = require("../../../config/options.json")
const { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } = require("../../utils/utils.js")
import { bwwins, beastbwfkdr, beastbwstars, beastswkdr, beastswstars, beastduelswins, duelswlr } from "../../../config/reqs.json"
import { color, devMessage } from "../../../config/options.json"
import { hypixelLevel, bedwarsLevel, skywarsLevel, getUUID, getPlayer, getGuild, getHeadURL } from "../../utils/Hypixel"
import { ChatInputCommandInteraction } from "discord.js"
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async function beast(interaction) {
export async function beast(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply()
const ign = interaction.options.getString("ign")
const ign = interaction.options.getString("ign")!
const embedColor = Number(color.replace("#", "0x"))
if (!ign) {
@@ -212,7 +211,7 @@ async function beast(interaction) {
const level = hypixelLevel(hypixelExp)
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({
embeds: [{
@@ -222,15 +221,13 @@ async function beast(interaction) {
"**Current Guild:** `" + guildName + "`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: footerText + " | " + devMessage,
icon_url: footerIcon
icon_url: footerIcon!
},
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

@@ -1,99 +0,0 @@
const verify = require("../../schemas/verifySchema.js")
const { color, hypixelGuildID } = require("../../../config/options.json")
const { admin, gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../../config/roles.json")
const removeThese = [gm, manager, beast, elite, member, guildRole, guildStaff]
const { getGuild } = require("../../utils/utils.js")
/** @param { import("discord.js").ChatInputCommandInteraction } interaction */
async function updateDiscordRoles(interaction) {
interaction.deferReply()
if (!interaction.member.roles.cache.has(admin)) {
interaction.editReply({
content: "You do not have permission to use this command.",
ephemeral: true
})
}
const embedColor = Number(color.replace("#", "0x"))
const guildMembers = await interaction.guild.members.fetch()
for (let i = 0; i < guildMembers.size; i++) {
const memberData = await verify.findOne({
userID: guildMembers[i].user.id
})
if (!memberData) {
for (const role of removeThese) {
guildMembers[i].roles.remove(role)
}
}
if (memberData) {
const igGuildMember = getGuild(memberData[i].uuid)
if (!igGuildMember) {
for (const role of removeThese) {
guildMembers[i].roles.remove(role)
}
}
const guildId = igGuildMember._id
const guildRank = igGuildMember.members.find(member => member.uuid === memberData[i].uuid).rank
if (!guildId === hypixelGuildID) {
for (const role of removeThese) {
guildMembers[i].roles.remove(role)
}
} else {
if (guildRank === "Guild Master") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(guildStaff, "All users updated forcefully by staff")
guildMembers[i].add(gm, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Manager") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(guildStaff, "All users updated forcefully by staff")
guildMembers[i].add(manager, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Moderator") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(guildStaff, "All users updated forcefully by staff")
guildMembers[i].add(moderator, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Beast") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(beast, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Elite") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(elite, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
if (guildRank === "Member") {
guildMembers[i].add(guildRole, "All users updated forcefully by staff")
guildMembers[i].add(member, "All users updated forcefully by staff")
guildMembers[i].add(defaultMember, "All users updated forcefully by staff")
}
}
}
}
interaction.editReply({
embeds: [{
color: embedColor,
description: "Successfully updated all users.",
footer: {
text: interaction.guild.name,
iconURL: interaction.guild.iconURL({ dynamic: true })
}
}]
})
}
module.exports = { updateDiscordRoles }

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")
const { color } = require("../../config/options.json")
const ms = require("ms")
import { SlashCommandBuilder, PermissionFlagsBits, userMention, ChatInputCommandInteraction, GuildMember } from "discord.js"
import { color } from "../../config/options.json"
import { Command } from "../interfaces"
import ms from "ms"
module.exports = {
const command: Command = {
name: "timeout",
description: "Times out a memeber",
type: "slash",
@@ -29,23 +30,21 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
async execute(interaction: ChatInputCommandInteraction) {
await interaction.deferReply()
const { default: prettyms } = await import("pretty-ms")
const target1 = interaction.options.getUser("user")
const target = interaction.guild.members.cache.get(target1.id)
const timeString = interaction.options.getString("time")
const target = interaction.options.getMember("user")! as GuildMember
const timeString = interaction.options.getString("time")!
const reason = interaction.options.getString("reason") || "No reason provided"
const time = ms(timeString)
const prettyTime = prettyms(time, { verbose: true })
const mod = interaction.member! as GuildMember
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) {
interaction.deferReply({
if (target.user.bot) {
interaction.editReply({
embeds: [{
description: "You cannot timeout a bot.",
color: embedColor,
@@ -54,8 +53,8 @@ module.exports = {
return
}
if (target.id == interaction.guild.ownerId) {
await interaction.deferReply({
if (target.id == interaction.guild!.ownerId) {
await interaction.editReply({
embeds: [{
description: "You cannot timeout the server owner.",
color: embedColor,
@@ -64,8 +63,8 @@ module.exports = {
return
}
if (interaction.guild.members.me.roles.highest.position <= target.roles.highest.position) {
interaction.deferReply({
if (interaction.guild!.members.me!.roles.highest.position <= target.roles.highest.position) {
interaction.editReply({
embeds: [{
description: "I cannot timeout this user because their role is higher than mine.",
color: embedColor,
@@ -74,8 +73,8 @@ module.exports = {
return
}
if (interaction.member.roles.highest.position <= target.roles.highest.position) {
await interaction.deferReply({
if (mod.roles.highest.position <= target.roles.highest.position) {
await interaction.editReply({
embeds: [{
description: "You cannot timeout this user because their role is higher than yours.",
color: embedColor,
@@ -85,7 +84,7 @@ module.exports = {
}
if (target.id == interaction.user.id) {
interaction.deferReply({
interaction.editReply({
embeds: [{
description: "You cannot timeout yourself.",
color: embedColor,
@@ -103,9 +102,9 @@ module.exports = {
color: embedColor,
footer: {
text: "ID: " + target.id,
iconURL: target.avatarURL()
icon_url: target.avatarURL() || undefined
},
timestamp: new Date()
timestamp: new Date().toISOString()
}]
})
return
@@ -118,9 +117,9 @@ module.exports = {
color: embedColor,
footer: {
text: "ID: " + target.id,
iconURL: target.avatarURL()
icon_url: target.avatarURL() || undefined
},
timestamp: new Date()
timestamp: new Date().toISOString()
}]
})
return
@@ -133,10 +132,12 @@ module.exports = {
color: embedColor,
footer: {
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")
const { color } = require("../../config/options.json")
import { SlashCommandBuilder, PermissionFlagsBits, userMention, User } from "discord.js"
import { color } from "../../config/options.json"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "unban",
description: "Unban a user from the server",
type: "slash",
@@ -27,16 +28,14 @@ module.exports = {
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.setDMPermission(false),
/** @param { import("discord.js").ChatInputCommandInteraction } interaction */
async execute(interaction) {
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 mod = interaction.user
const embedColor = Number(color.replace("#", "0x"))
let user
let user: User | null
if (userid === "none") {
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({
embeds: [{
title: "User unbanned",
description: "The user " + user.username + " has been unbanned.\n" +
description: "The user " + user!.username + " has been unbanned.\n" +
"**Reason:** `" + reason + "`\n" +
"**Moderator:** " + userMention(mod.id),
color: embedColor,
thumbnail: {
url: user?.avatarURL({ dynamic: true }) || null
url: user!.avatarURL({ forceStatic: false }) || ""
},
footer: {
text: "ID: " + user.id,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: "ID: " + user!.id,
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")
const { getGuild, getIGN, getHeadURL } = require("../utils/utils.js")
const verify = require("../schemas/verifySchema.js")
const { color, hypixelGuildID, devMessage } = require("../../config/options.json")
const { gm, manager, moderator, beast, elite, member, guildRole, guildStaff, defaultMember } = require("../../config/roles.json")
import { GuildMember, SlashCommandBuilder } from "discord.js"
import { getGuild, getIGN, getHeadURL } from "../utils/Hypixel"
import verify = require("../schemas/verifySchema")
import { color, hypixelGuildID, devMessage } from "../../config/options.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]
module.exports = {
export = {
name: "update",
description: "Update your guild rank.",
type: "slash",
@@ -17,15 +18,12 @@ module.exports = {
.setDescription("Update your discord roles.")
.setDMPermission(false),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
async execute(interaction) {
await interaction.deferReply()
const user1 = interaction.user
const user = interaction.guild.members.cache.get(user1.id)
const verifyData = await verify.findOne({ userID: user.id })
const user = interaction.member as GuildMember
const verifyData = await verify.findOne({ userID: user.user.id })
const roleManage = user.roles
const embedColor = Number(color.replace("#", "0x"))
@@ -35,8 +33,8 @@ module.exports = {
description: "You are not verified. Please run `/verify` to verify yourself",
color: embedColor,
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -51,14 +49,14 @@ module.exports = {
})
const guild = await getGuild(verifyData.uuid)
let guildID = ""
let guildID: string | null
if (!guild) {
guildID = null
} else {
guildID = guild._id
}
const ign = await getIGN(verifyData.uuid)
const ign = await getIGN(verifyData.uuid) as string
const head = await getHeadURL(ign)
if (guildID !== hypixelGuildID) {
@@ -73,11 +71,11 @@ module.exports = {
description: "Updated your roles to `Default Member`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -86,8 +84,8 @@ module.exports = {
if (guildID === hypixelGuildID) {
const GuildMembers = guild.members
const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid).rank
const GuildMembers = guild!.members
const guildRank = GuildMembers.find(member => member.uuid === verifyData.uuid)!.rank
if (guildRank === "Guild Master") {
@@ -106,11 +104,11 @@ module.exports = {
description: "Your rank has been updated to `Guild Master`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -133,11 +131,11 @@ module.exports = {
description: "Your rank has been updated to `Manager`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -160,11 +158,11 @@ module.exports = {
description: "Your rank has been updated to `Moderator`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -187,11 +185,11 @@ module.exports = {
description: "Your rank has been updated to `Beast`.",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -214,11 +212,11 @@ module.exports = {
description: "Your rank has been updated to `Elite`.",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
icon_url: interaction.guild!.iconURL({ forceStatic: false })!
}
}]
})
@@ -241,11 +239,11 @@ module.exports = {
description: "Your rank has been updated to `Member`.",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: interaction.guild.name + " | " + devMessage,
icon_url: interaction.guild.iconURL({ dynamic: true })
text: interaction.guild!.name + " | " + devMessage,
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")
const { color, devMessage } = require("../../config/options.json")
const { getUUID, getIGN, getHeadURL, formatUuid } = require("../utils/utils.js")
import { SlashCommandBuilder } from "discord.js"
import { color, devMessage } from "../../config/options.json"
import { getUUID, getIGN, getHeadURL, formatUuid } from "../utils/Hypixel"
import { Command } from "../interfaces"
module.exports = {
export = {
name: "uuid",
description: "Get a player's UUID",
type: "slash",
@@ -15,28 +16,27 @@ module.exports = {
.addStringOption(option => option
.setName("ign")
.setDescription("Player's name")
.setRequired(true)
),
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
.setRequired(true)),
async execute(interaction) {
await interaction.deferReply()
const ign = interaction.options.getString("ign")
const uuid = await getUUID(ign)
const ign = interaction.options.getString("ign")!
const uuid = await getUUID(ign) as string
const formattedUuid = formatUuid(uuid)
const newIgn = await getIGN(uuid)
const newIgn = await getIGN(uuid) as string
const head = await getHeadURL(ign)
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 })
const footerIcon = interaction.guild ? interaction.guild.iconURL({ forceStatic: false }) : interaction.user.avatarURL({ forceStatic: false })
if (!uuid) {
interaction.editReply({
embeds: [{
description: "That player doesn't exist!",
color: embedColor
}]
})
return
}
@@ -48,13 +48,13 @@ module.exports = {
"**Formatted UUID:** `" + formattedUuid + "`",
color: embedColor,
thumbnail: {
url: head
url: head!
},
footer: {
text: footerText + " | " + devMessage,
icon_url: footerIcon
icon_url: footerIcon || undefined
}
}]
})
}
}
} as Command

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,8 +1,9 @@
const { ButtonBuilder, ActionRowBuilder, ButtonStyle, EmbedBuilder } = require("discord.js")
const { gm, manager, moderator, beast, member, guildStaff, guildRole } = require("../../../config/roles.json")
const { ignM, smallM, largeM } = require("../../../config/limitmessages.json")
const { ia1, ia2, ia3, ria1, ria2, ria3 } = require("../../../config/questions.json")
const { color, inactivityLogChannel } = require("../../../config/options.json")
import { ButtonBuilder, ActionRowBuilder, ButtonStyle, EmbedBuilder, GuildMember, GuildTextBasedChannel } from "discord.js"
import { gm, manager, moderator, beast, member, guildStaff, guildRole } from "../../../config/roles.json"
import { ignM, smallM, largeM } from "../../../config/limitmessages.json"
import { inactivity } from "../../../config/questions.json"
import { color, inactivityLogChannel } from "../../../config/options.json"
import { Button } from "../../interfaces"
const guildRoles = [gm, manager, moderator, beast, member, guildStaff, guildRole]
module.exports = {
@@ -10,13 +11,11 @@ module.exports = {
description: "Configure the bot.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
const guild = interaction.guild
const user = interaction.user
const guild = interaction.guild!
const user = interaction.member as GuildMember
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/"
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()
.setDescription("You took too long to respond.")
.setColor(embedColor)
@@ -53,12 +60,12 @@ module.exports = {
await interaction.reply({ content: "Please check your DMs.", ephemeral: true })
const input = await user.dmChannel.awaitMessages({
filter: (m) => m.author.id === user.id,
const input = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.user.id,
max: 1,
time: 1000 * 60
})
if (input.first().attachments.size > 0) {
if (input.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] })
return
}
@@ -66,7 +73,7 @@ module.exports = {
await user.send({ embeds: [tooLong] })
return
}
if (input.first().content.toLowerCase() !== "yes") {
if (input.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] })
return
}
@@ -74,7 +81,7 @@ module.exports = {
await user.send({
embeds: [{
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,
footer: {
text: "You have 5 minutes to respond to this message."
@@ -82,16 +89,16 @@ module.exports = {
}]
})
const answer1 = await user.dmChannel.awaitMessages({
filter: (m) => m.author.id === user.id,
const answer1 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.user.id,
max: 1,
time: 1000 * 60 * 5
})
if (answer1.first().attachments.size > 0) {
if (answer1.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] })
return
}
if (answer1.first().content > 16) {
if (answer1.first()!.content.length > 16) {
await user.send({
embeds: [{
description: "Max character limit is 16.",
@@ -101,7 +108,7 @@ module.exports = {
return
}
try {
await fetch(mojangAPI + answer1.first().content)
await fetch(mojangAPI + answer1.first()!.content)
} catch (error) {
await user.send({
embeds: [{
@@ -115,32 +122,32 @@ module.exports = {
await user.send({ embeds: [tooLong] })
return
}
if (answer1.first().content.toLowerCase() === "cancel") {
if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] })
return
}
const answer1_1 = answer1.first().content
const answer1_1 = answer1.first()!.content
await user.send({
embeds: [{
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,
footer: {
text: "You have 5 minutes to respond to this message."
}
}]
})
const answer2 = await user.dmChannel.awaitMessages({
filter: (m) => m.author.id === user.id,
const answer2 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.user.id,
max: 1,
time: 1000 * 60 * 5
})
if (answer2.first().attachments.size > 0) {
if (answer2.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] })
return
}
if (answer2.first().content > 128) {
if (answer2.first()!.content.length > 128) {
await user.send({
embeds: [{
description: "Max character limit is 128.",
@@ -153,32 +160,32 @@ module.exports = {
await user.send({ embeds: [tooLong] })
return
}
if (answer1.first().content.toLowerCase() === "cancel") {
if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] })
return
}
const answer2_1 = answer1.first().content
const answer2_1 = answer1.first()!.content
await user.send({
embeds: [{
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,
footer: {
text: "You have 15 minutes to respond to this message."
}
}]
})
const answer3 = await user.dmChannel.awaitMessages({
filter: (m) => m.author.id === user.id,
const answer3 = await user.dmChannel!.awaitMessages({
filter: (m) => m.author.id === user.user.id,
max: 1,
time: 1000 * 60 * 15
})
if (answer3.first().attachments.size > 0) {
if (answer3.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] })
return
}
if (answer3.first().content > 256) {
if (answer3.first()!.content.length > 256) {
await user.send({
embeds: [{
description: "Max character limit is 256",
@@ -191,11 +198,11 @@ module.exports = {
await user.send({ embeds: [tooLong] })
return
}
if (answer1.first().content.toLowerCase() === "cancel") {
if (answer1.first()!.content.toLowerCase() === "cancel") {
await user.send({ embeds: [cancelled] })
return
}
const answer3_1 = answer1.first().content
const answer3_1 = answer1.first()!.content
await user.send({
embeds: [{
@@ -203,12 +210,12 @@ module.exports = {
color: embedColor
}]
})
const final = await user.dmChannel.awaitMessages({
filter: m => m.author.id === user.id,
const final = await user.dmChannel!.awaitMessages({
filter: m => m.author.id === user.user.id,
max: 1,
time: 1000 * 60 * 5
})
if (final.first().attachments.size > 0) {
if (final.first()!.attachments.size > 0) {
await user.send({ embeds: [attachments] })
return
}
@@ -216,7 +223,7 @@ module.exports = {
await user.send({ embeds: [tooLong] })
return
}
if (final.first().content.toLowerCase() !== "yes") {
if (final.first()!.content.toLowerCase() !== "yes") {
await user.send({ embeds: [cancelled] })
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({
embeds: [{
title: user.username + "#" + user.discriminator + " - Inactivity Application",
title: user.user.username + "#" + user.user.discriminator + " - Inactivity Application",
color: embedColor,
thumbnail: {
url: user.displayAvatarURL({ dynamic: true })
url: user.displayAvatarURL({ forceStatic: false })
},
fields: [
{
name: ria1,
name: rq(1),
value: "`" + answer1_1 + "`"
},
{
name: ria2,
name: rq(2),
value: "`" + answer2_1 + "`"
},
{
name: ria3,
name: rq(3),
value: "`" + answer3_1 + "`"
}
],
footer: {
icon_url: user.displayAvatarURL({ dynamic: true }),
text: "ID: " + user.id
icon_url: user.displayAvatarURL({ forceStatic: false }),
text: "ID: " + user.user.id
}
}],
components: [
new ActionRowBuilder().addComponents(
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("inactiveapplicationaccept")
.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",
description: "Accept an inactivity application.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
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",
description: "Denies an inactivity application.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
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")
const { color } = require("../../../config/options.json")
const staffapp = require("../../schemas/staffAppSchema.js")
import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"
import { color } from "../../../config/options.json"
import staffapp from "../../schemas/staffAppSchema"
import { Button } from "../../interfaces"
module.exports = {
export = {
name: "staffapplicationaccept",
description: "Accept a staff application.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
await interaction.deferReply()
const user = interaction.user
const guild = interaction.guild
const guild = interaction.guild!
const embedColor = Number(color.replace("#", "0x"))
const message = interaction.message
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 applicantUsername = applicant.user.username + "#" + applicant.user.discriminator
@@ -31,7 +31,7 @@ module.exports = {
await message.edit({
components: [
new ActionRowBuilder().addComponents(
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("staffapplicationaccept")
.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: [{
title: applicantUsername + " - Staff Application.",
description: "Application accepted by <@" + user.id + ">.",
color: embedColor,
thumbnail: {
url: applicant.avatarURL()
url: applicant.avatarURL()!
},
footer: {
iconurl: guild.iconURL(),
icon_url: guild.iconURL()!,
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",
description: "Deny a guild application.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
const modal = new ModalBuilder()
.setTitle("Deny Reason")
.setCustomId("staffdenyreasonbox")
.setComponents(
new ActionRowBuilder().setComponents(
new ActionRowBuilder<TextInputBuilder>().setComponents(
new TextInputBuilder()
.setLabel("Deny Reason")
.setCustomId("staffdenyreason")
@@ -24,4 +23,4 @@ module.exports = {
)
await interaction.showModal(modal)
}
}
} as Button

View File

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

View File

@@ -1,14 +1,13 @@
const waitinglist = require("../../schemas/waitinglistSchema.js")
const { getGuild } = require("../../utils/utils.js")
const { hypixelGuildID } = require("../../../config/options.json")
import waitinglist from "../../schemas/waitinglistSchema"
import { getGuild } from "../../utils/Hypixel"
import { hypixelGuildID } from "../../../config/options.json"
import { Button } from "../../interfaces"
module.exports = {
export = {
name: "waitinglistupdate",
description: "Update the waiting list.",
type: "button",
/** @param {import('discord.js').ButtonInteraction} interaction */
async execute(interaction) {
await interaction.deferReply({ ephemeral: true })
@@ -34,8 +33,7 @@ module.exports = {
for (let i = 0; i < accepted.length; i++) {
const timestamp1 = accepted[i].timestamp / 1000
const timestamp = Math.floor(timestamp1)
const timestamp = Math.floor(accepted[i].timestamp / 1000)
fields.push({
name: `${i + 1}. ${accepted[i].IGN}`,
@@ -45,19 +43,19 @@ module.exports = {
await message.edit({
embeds: [{
title: embed.title,
description: embed.description,
color: embed.color,
title: embed.title!,
description: embed.description!,
color: embed.color!,
footer: {
text: "Last updated by " + user.username,
icon_url: user.avatarURL(),
icon_url: user.avatarURL()!,
},
thumbnail: embed.thumbnail,
thumbnail: embed.thumbnail!,
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")
const { color } = require("../../../config/options.json")
const guildapp = require("../../schemas/guildAppSchema.js")
import { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Message, GuildMember } from "discord.js"
import { color } from "../../../config/options.json"
import guildapp from "../../schemas/guildAppSchema"
import { Modal } from "../../interfaces"
module.exports = {
export = {
name: "denyreasonbox",
description: "Deny reason box.",
type: "modal",
/** @param { import('discord.js').ModalSubmitInteraction } interaction */
async execute(interaction) {
await interaction.deferReply()
const guild = interaction.guild
const message = interaction.message
const guild = interaction.guild!
const message = interaction.message as Message
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"))
await message.edit({
components: [
new ActionRowBuilder().addComponents(
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("guildapplicationaccept")
.setLabel("Accept")
@@ -42,7 +41,7 @@ module.exports = {
]
})
let applicant = ""
let applicant: GuildMember | null
try {
applicant = await guild.members.fetch(applicantId)
} catch (error) {
@@ -65,7 +64,7 @@ module.exports = {
.setColor(embedColor)
.setThumbnail(guild.iconURL())
.setFooter({
iconURL: guild.iconURL(),
iconURL: guild.iconURL()!,
text: "ID: " + applicantId
})
@@ -73,7 +72,7 @@ module.exports = {
await applicant.send({ embeds: [dmMessage] })
}
let responseEmbeds = ""
let responseEmbeds: EmbedBuilder[]
if (applicant === null) {
responseEmbeds = [responseEmbed, missingUser]
} else {
@@ -86,4 +85,4 @@ module.exports = {
embeds: responseEmbeds
})
}
}
} as Modal

View File

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

View File

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

View File

@@ -1,14 +1,14 @@
const { userMention } = require("discord.js")
const { color, botLogChannel } = require("../../../../config/options.json")
import { ChannelType, GuildMember, userMention } from "discord.js"
import { color, botLogChannel } from "../../../../config/options.json"
import { Event } from "../../../interfaces"
module.exports = {
const event: Event = {
name: "logNewJoins",
description: "Logs new joins",
type: "event",
event: "guildMemberAdd",
/** @param { import('discord.js').GuildMember } member */
execute(member) {
execute(member: GuildMember) {
const channel = member.guild.channels.cache.get(botLogChannel)
const embedColor = Number(color.replace("#", "0x"))
@@ -18,6 +18,11 @@ module.exports = {
return
}
if (channel.type !== ChannelType.GuildText) {
console.log("[ERROR] The channel used for new join logging is not a text channel.")
return
}
channel.send({
embeds: [{
title: "New Member",
@@ -27,9 +32,11 @@ module.exports = {
footer: {
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",
description: "Logs all button and command interactions",
type: "event",
event: "interactionCreate",
/** @param { import('discord.js').ChatInputCommandInteraction } interaction */
execute(interaction) {
execute(interaction: ChatInputCommandInteraction | ButtonInteraction) {
if (interaction.isCommand()) {
try {
console.log(interaction.user.username + " ran " +
@@ -18,11 +19,16 @@ module.exports = {
interaction.commandName
)
}
} else if (interaction.isButton()) {
}
if (interaction.isButton()) {
console.log(interaction.user.username + "#" +
interaction.user.discriminator + " clicked " +
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",
description: "ur moms someone",
type: "event",
event: "messageCreate",
/** @param { import('discord.js').Message } message */
async execute(message) {
async execute(message: Message) {
if (message.content.toLowerCase().includes("ur mom") && message.author.username === "taken.lua") {
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",
description: "send an online message",
type: "event",
event: "ready",
execute(client) {
execute(client: Client) {
if (process.env.NODE_ENV === "dev") return
const channel = client.channels.cache.get(onlineLogChannel)
@@ -17,6 +20,11 @@ module.exports = {
return
}
if (channel.type !== ChannelType.GuildText) {
console.log("[ERROR] Online message channel is not a text channel.")
return
}
channel.send({
embeds: [{
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",
description: "Sets the status of the bot",
type: "event",
event: "ready",
/** @param { import('discord.js').Client } client */
execute(client) {
execute(client: Client) {
// Playing 0
// Streaming 1
@@ -17,18 +17,22 @@ module.exports = {
// Custom 4
// Competing 5
client.user.setActivity(
const user = client.user!
user.setActivity(
{ name: statuses[0].name, type: statuses[0].type }
)
let i = 1
setInterval(() =>
client.user.setActivity(
statuses[i, i++ % statuses.length]
user.setActivity(
statuses[i++ % statuses.length]
),
1000 * 60 * 10
)
client.user.setStatus("dnd")
user.setStatus("dnd")
}
}
export = event

View File

@@ -1,20 +1,16 @@
const { userMention, channelMention } = require("discord.js")
const { botLogChannel, color } = require("../../../../config/options.json")
import { userMention, channelMention, VoiceState, ChannelType } from "discord.js"
import { botLogChannel, color } from "../../../../config/options.json"
import { Event } from "../../../interfaces"
module.exports = {
const event: Event = {
name: "vcJoinLeave",
description: "Logs when a user joins or leaves a voice channel.",
type: "event",
event: "voiceStateUpdate",
/**
* @param { import('discord.js').VoiceState } oldState
* @param { import('discord.js').VoiceState } newState
*/
execute(oldState: VoiceState, newState: VoiceState) {
execute(oldState, newState) {
// if (process.env.NODE_ENV === 'dev') return
if (process.env.NODE_ENV === 'dev') return
const guild = oldState.guild
const channel = guild.channels.cache.get(botLogChannel)
@@ -25,6 +21,11 @@ module.exports = {
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 newChannel = newState.channel
@@ -33,14 +34,14 @@ module.exports = {
channel.send({
embeds: [{
title: "Voice Channel Join",
description: userMention(oldState.member.id) +
description: userMention(newState.member!.id) +
" joined " +
channelMention(newChannel.id),
color: embedColor,
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({
embeds: [{
title: "Voice Channel Leave",
description: userMention(oldState.member.id) +
description: userMention(oldState.member!.id) +
" left " +
channelMention(oldChannel.id),
color: embedColor,
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({
embeds: [{
title: "Voice Channel Switch",
description: userMention(oldState.member.id) +
description: userMention(oldState.member!.id) +
" switched from " +
channelMention(oldChannel.id) +
" to " +
channelMention(newChannel.id),
color: embedColor,
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({
_id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const guildAppSchema = new Schema({
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({
_id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const settingsSchema = new Schema({
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({
_id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const staffAppSchema = new Schema({
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({
_id: Schema.Types.ObjectId,
@@ -6,4 +6,4 @@ const verifySchema = new Schema({
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({
_id: Schema.Types.ObjectId,
userID: { type: String, required: true },
uuid: { 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")
const log = require("log-beautify")
const fs = require("fs")
require("dotenv").config()
const token = process.env.DEVTOKEN
const clientId = process.env.DEVID
const guildId = process.env.GUILDID
log.useSymbols = false
log.setColors({
newCmds: "#b4befe",
currentCmds: "#f38ba8"
})
import { Command } from "../interfaces"
import config from "./Config"
import { REST, RESTGetAPIApplicationGuildCommandResult, RESTPutAPIApplicationGuildCommandsJSONBody, Routes } from "discord.js"
import fs = require("fs")
async function autoDeployCommands() {
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"))
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 = require(`../commands/${file}`)
@@ -25,23 +15,17 @@ async function autoDeployCommands() {
}
}
for (const file of contentMenuCommands) {
const command = require(`../commands-contextmenu/${file}`)
if (command.dev) {
commands.push(command.data.toJSON())
}
}
for (const file of commandsTesting) {
const command = require(`../commands-testing/${file}`)
const command: Command = require(`../commands-contextmenu/${file}`)
if (command.dev) {
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(
Routes.applicationGuildCommands(clientId, guildId),
)
Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
) as RESTGetAPIApplicationGuildCommandResult[]
const currentCommandsInfo = currentCommands.map(command => {
return {
@@ -67,23 +51,23 @@ async function autoDeployCommands() {
}).join("\n")
if (JSON.stringify(sortedNewCommandsInfo) === JSON.stringify(sortedCurrentCommandsInfo)) {
log.success("Commands are the same, skipping deploy.")
log.newCmds(newCmds)
console.log("Commands are the same, skipping deploy.")
console.log(newCmds)
return
}
(async () => {
try {
log.warning("Commands are different, starting deploy.")
log.currentCmds(currentCmds)
console.log("Commands are different, starting deploy.")
console.log(currentCmds)
console.log(`Started refreshing ${commands.length} application (/) commands.`)
const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
Routes.applicationGuildCommands(config.dev.devid, config.dev.guildid),
{ body: commands },
)
) as RESTPutAPIApplicationGuildCommandsJSONBody[]
log.newCmds(newCmds)
console.log(newCmds)
console.log(`Successfully reloaded ${data.length} application (/) commands.`)
} catch (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"

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

@@ -0,0 +1,6 @@
import { Redis } from "ioredis"
import config from "./Config"
const redis = new Redis(config.prod.redisURI)
export { redis }

View File

@@ -1,15 +0,0 @@
const { loadButtonEvents } = require("./eventHandlers/button.js")
const { loadSlashCommandsEvents } = require("./eventHandlers/command.js")
const { loadContextMenuEvents } = require("./eventHandlers/contextmenu.js")
const { loadModalEvents } = require("./eventHandlers/modal.js")
const { loadEvents } = require("./eventHandlers/events.js")
const { loadAutocompleteEvents } = require("./eventHandlers/autocomplete.js")
module.exports = {
loadSlashCommandsEvents,
loadButtonEvents,
loadContextMenuEvents,
loadModalEvents,
loadEvents,
loadAutocompleteEvents
}

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