Merge pull request #344 from VermiumSifell/dev

Optimizations & New features
This commit is contained in:
Axel Olausson Holtenäs 2022-05-29 22:04:23 +02:00 committed by GitHub
commit 9ee3108d5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
139 changed files with 1415 additions and 1285 deletions

3
.gitignore vendored
View file

@ -9,6 +9,9 @@ package-lock.json
!**/config/index.ts
!**/config/example.*.ts
# Build
build/
# Logs
logs

View file

@ -0,0 +1,43 @@
// Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Modules
import modules from "./modules";
// Handlers
import logger from "../../logger";
export const builder = new SlashCommandBuilder()
.setName("config")
.setDescription("Manage guild configurations.")
.addSubcommand(modules.pterodactyl.builder)
.addSubcommand(modules.credits.builder)
.addSubcommand(modules.points.builder)
.addSubcommand(modules.welcome.builder)
.addSubcommand(modules.audits.builder)
.addSubcommand(modules.shop.builder)
.addSubcommand(modules.embeds.builder);
export const moduleData = modules;
// Function
export const execute = async (interaction: CommandInteraction) => {
switch (interaction.options?.getSubcommand()) {
case "pterodactyl":
return modules.pterodactyl.execute(interaction);
case "credits":
return modules.credits.execute(interaction);
case "points":
return modules.points.execute(interaction);
case "welcome":
return modules.welcome.execute(interaction);
case "audits":
return modules.audits.execute(interaction);
case "shop":
return modules.shop.execute(interaction);
case "embeds":
return modules.embeds.execute(interaction);
}
};

View file

@ -2,13 +2,13 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v10";

View file

@ -2,13 +2,13 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
//Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -0,0 +1,38 @@
import { ColorResolvable, CommandInteraction } from "discord.js";
import guildSchema from "../../../../../../database/schemas/guild";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
export default async (interaction: CommandInteraction) => {
const { options, guild } = interaction;
if (!guild) throw new Error("Guild not found");
const embedConfig = await getEmbedConfig(guild);
if (!embedConfig) throw new Error("Embed config not found");
// Get new values
const newSuccessColor = options.getString("success-color") as ColorResolvable;
const newWaitColor = options.getString("wait-color") as ColorResolvable;
const newErrorColor = options.getString("error-color") as ColorResolvable;
const newFooterIcon = options.getString("footer-icon");
const newFooterText = options.getString("footer-text");
// Get guild values
const guildData = await guildSchema.findOne({
guildId: guild.id,
});
if (!guildData) throw new Error("Guild data not found");
if (!guildData?.embeds)
throw new Error("Guild embed configuration not found");
let { successColor, waitColor, errorColor, footerText, footerIcon } =
guildData.embeds;
// Set new values
successColor = newSuccessColor || successColor;
waitColor = newWaitColor || waitColor;
errorColor = newErrorColor || errorColor;
footerIcon = newFooterIcon || footerIcon;
footerText = newFooterText || footerText;
return { successColor, waitColor, errorColor, footerText, footerIcon };
};

View file

@ -0,0 +1,104 @@
// Dependencies
import {
ColorResolvable,
CommandInteraction,
MessageEmbed,
Permissions,
} from "discord.js";
//Handlers
import logger from "../../../../logger";
// Models
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
import getValues from "./components/getValues";
// Function
export default {
metadata: {
guildOnly: true,
ephemeral: true,
permissions: [Permissions.FLAGS.MANAGE_GUILD],
},
builder: (command: SlashCommandSubcommandBuilder) => {
return command
.setName("embeds")
.setDescription(`Embeds`)
.addStringOption((option) =>
option
.setName("success-color")
.setDescription("No provided description")
)
.addStringOption((option) =>
option.setName("wait-color").setDescription("No provided description")
)
.addStringOption((option) =>
option.setName("error-color").setDescription("No provided description")
)
.addStringOption((option) =>
option.setName("footer-icon").setDescription("No provided description")
)
.addStringOption((option) =>
option.setName("footer-text").setDescription("No provided description")
);
},
execute: async (interaction: CommandInteraction) => {
const { guild } = interaction;
if (!guild) throw new Error("Guild not found");
const { successColor, waitColor, errorColor, footerText, footerIcon } =
await getValues(interaction);
// Initialize embed object
const embed = new MessageEmbed()
.setTitle("[:tools:] Embeds")
.setFooter({ text: footerText, iconURL: footerIcon })
.setTimestamp(new Date());
// Get guild values
const guildData = await guildSchema.findOne({
guildId: guild.id,
});
if (!guildData) throw new Error("Guild data not found");
await guildData.save().then(async () => {
embed
.setDescription("Following embed configuration will be used.")
.setColor(successColor)
.addFields([
{
name: "🟢 Success Color",
value: `${successColor}`,
inline: true,
},
{
name: "🟡 Wait Color",
value: `${waitColor}`,
inline: true,
},
{
name: "🔴 Error Color",
value: `${errorColor}`,
inline: true,
},
{
name: "🖼️ Footer Icon",
value: `${footerIcon}`,
inline: true,
},
{
name: "📄 Footer Text",
value: `${footerText}`,
inline: true,
},
]);
return interaction.editReply({
embeds: [embed],
});
});
},
};

View file

@ -0,0 +1,9 @@
import audits from "./audits";
import credits from "./credits";
import points from "./points";
import pterodactyl from "./pterodactyl";
import shop from "./shop";
import welcome from "./welcome";
import embeds from "./embeds";
export default { audits, credits, points, pterodactyl, shop, welcome, embeds };

View file

@ -2,13 +2,13 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -2,14 +2,14 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import apiSchema from "@schemas/api";
import encryption from "@handlers/encryption";
import apiSchema from "../../../../database/schemas/api";
import encryption from "../../../../handlers/encryption";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -2,13 +2,13 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -2,13 +2,13 @@
import { CommandInteraction, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../../../database/schemas/guild";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v10";
@ -96,39 +96,39 @@ export default {
await guildDB?.save()?.then(async () => {
logger?.silly(`Guild welcome updated.`);
if (!guildDB?.welcome?.status) {
return interaction?.editReply({
embeds: [
{
title: "[:tools:] Welcome",
description: `This module is currently disabled, please enable it to continue.`,
color: successColor,
timestamp: new Date(),
footer: {
iconURL: footerIcon,
text: footerText,
},
},
],
});
}
return interaction?.editReply({
embeds: [
{
title: ":hammer: Settings - Guild [Welcome]",
description: `Welcome settings updated.`,
title: "[:tools:] Welcome",
description: `The following configuration will be used.
[👋] **Welcome**
**Channel**: <#${guildDB?.welcome?.joinChannel}>
**Message**: ${guildDB?.welcome?.joinChannelMessage}
[🚪] **Leave**
**Channel**: <#${guildDB?.welcome?.leaveChannel}>
**Message**: ${guildDB?.welcome?.leaveChannelMessage}`,
color: successColor,
fields: [
{
name: "🤖 Status",
value: `${guildDB?.welcome?.status}`,
inline: true,
},
{
name: "🌊 Join Channel",
value: `${guildDB?.welcome?.joinChannel}`,
inline: true,
},
{
name: "🌊 Leave Channel",
value: `${guildDB?.welcome?.leaveChannel}`,
inline: true,
},
{
name: "📄 Join Channel Message",
value: `${guildDB?.welcome?.joinChannelMessage}`,
inline: true,
},
{
name: "📄 Leave Channel Message",
value: `${guildDB?.welcome?.leaveChannelMessage}`,
inline: true,
},
],
timestamp: new Date(),
footer: {
iconURL: footerIcon,

View file

@ -0,0 +1,19 @@
import { CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
import logger from "../../logger";
import modules from "../../commands/counters/modules";
export const builder = new SlashCommandBuilder()
.setName("counters")
.setDescription("View guild counters")
.addSubcommand(modules.view.builder);
export const moduleData = modules;
export const execute = async (interaction: CommandInteraction) => {
if (interaction.options.getSubcommand() === "view") {
await modules.view.execute(interaction);
}
};

View file

@ -0,0 +1,3 @@
import view from "./view";
export default { view };

View file

@ -1,10 +1,10 @@
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v10";
import counterSchema from "@schemas/counter";
import counterSchema from "../../../../database/schemas/counter";
export default {
metadata: { guildOnly: true, ephemeral: false },

View file

@ -0,0 +1,37 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import logger from "../../logger";
import modules from "./modules";
export const builder = new SlashCommandBuilder()
.setName("credits")
.setDescription("Manage your credits.")
.addSubcommand(modules.balance.builder)
.addSubcommand(modules.gift.builder)
.addSubcommand(modules.top.builder)
.addSubcommand(modules.work.builder);
export const moduleData = modules;
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
switch (options.getSubcommand()) {
case "balance":
await modules.balance.execute(interaction);
break;
case "gift":
await modules.gift.execute(interaction);
break;
case "top":
await modules.top.execute(interaction);
break;
case "work":
await modules.work.execute(interaction);
break;
default:
logger.silly(`Unknown subcommand ${options.getSubcommand()}`);
}
};

View file

@ -1,10 +1,10 @@
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import logger from "@logger";
import logger from "../../../../logger";
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../helpers/fetchUser";
export default {
metadata: { guildOnly: true, ephemeral: true },

View file

@ -2,16 +2,15 @@
import { CommandInteraction, MessageEmbed } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Helpers
import saveUser from "@helpers/saveUser";
import mongoose from "mongoose";
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function
@ -184,53 +183,69 @@ export default {
});
}
// Withdraw amount from fromUserDB
fromUserDB.credits -= optionAmount;
const session = await mongoose.startSession();
// Deposit amount to toUserDB
toUserDB.credits += optionAmount;
session.startTransaction();
// Save users
await saveUser(fromUserDB, toUserDB).then(async () => {
// Get DM user object
const dmUser = client.users.cache.get(optionUser.id);
try {
// Withdraw amount from fromUserDB
fromUserDB.credits -= optionAmount;
if (dmUser == null) return;
// Deposit amount to toUserDB
toUserDB.credits += optionAmount;
// Send DM to user
await dmUser
.send({
embeds: [
embed
.setDescription(
`${
user.tag
} has gifted you ${optionAmount} credits with reason: ${
optionReason || "unspecified"
}`
)
.setColor(successColor),
],
})
.catch(async (error) =>
logger.error(`[Gift] Error sending DM to user: ${error}`)
);
await fromUserDB.save();
logger.silly(
`[Gift] Successfully gifted ${optionAmount} credits to ${optionUser.tag}`
);
await toUserDB.save();
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
session.endSession();
logger.error(`${error}`);
return interaction.editReply({
embeds: [
embed
.setDescription(
`Successfully gifted ${optionAmount} credits to ${
optionUser.tag
} with reason: ${optionReason || "unspecified"}`
"An error occurred while trying to gift credits. Please try again."
)
.setColor(successColor),
.setColor(errorColor),
],
});
} finally {
// ending the session
session.endSession();
}
// Get DM user object
const dmUser = client.users.cache.get(optionUser.id);
if (!dmUser) throw new Error("User not found");
// Send DM to user
await dmUser.send({
embeds: [
embed
.setDescription(
`${user.tag} has gifted you ${optionAmount} credits with reason: ${
optionReason || "unspecified"
}`
)
.setColor(successColor),
],
});
return interaction.editReply({
embeds: [
embed
.setDescription(
`Successfully gifted ${optionAmount} credits to ${
optionUser.tag
} with reason: ${optionReason || "unspecified"}`
)
.setColor(successColor),
],
});
},
};

View file

@ -0,0 +1,6 @@
import balance from "./balance";
import gift from "./gift";
import top from "./top";
import work from "./work";
export default { balance, gift, top, work };

View file

@ -1,10 +1,10 @@
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import logger from "@logger";
import logger from "../../../../logger";
import userSchema, { IUser } from "@schemas/user";
import userSchema, { IUser } from "../../../../database/schemas/user";
export default {
metadata: { guildOnly: true, ephemeral: false },

View file

@ -4,17 +4,17 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import Chance from "chance";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../logger";
// Models
import timeoutSchema from "@schemas/timeout";
import timeoutSchema from "../../../../database/schemas/timeout";
// Helpers
import fetchUser from "@helpers/fetchUser";
import fetchGuild from "@helpers/fetchGuild";
import fetchUser from "../../../../helpers/fetchUser";
import fetchGuild from "../../../../helpers/fetchGuild";
export default {
metadata: { guildOnly: true, ephemeral: true },

23
src/commands/fun/index.ts Normal file
View file

@ -0,0 +1,23 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import logger from "../../logger";
import modules from "../../commands/fun/modules";
export const builder = new SlashCommandBuilder()
.setName("fun")
.setDescription("Fun commands.")
.addSubcommand(modules.meme.builder);
export const moduleData = modules;
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
if (options.getSubcommand() === "meme") {
await modules.meme.execute(interaction);
} else {
logger.silly(`Unknown subcommand ${options.getSubcommand()}`);
}
};

View file

@ -0,0 +1,5 @@
import meme from "./meme";
export default {
meme,
};

View file

@ -0,0 +1,59 @@
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
import axios from "axios";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
export default {
metadata: { guildOnly: false, ephemeral: false },
builder: (command: SlashCommandSubcommandBuilder) => {
return command.setName("meme").setDescription("Get a meme from r/memes)");
},
execute: async (interaction: CommandInteraction) => {
const { guild } = interaction;
const embedConfig = await getEmbedConfig(guild);
await axios
.get("https://www.reddit.com/r/memes/random/.json")
.then(async (res) => {
const response = res.data[0].data.children;
const content = response[0].data;
const embed = new MessageEmbed()
.setAuthor({
name: content.title,
iconURL:
"https://www.redditinc.com/assets/images/site/reddit-logo.png",
url: `https://reddit.com${content.permalink}`,
})
.setTitle("[:sweat_smile:] Meme")
.addFields([
{
name: "Author",
value: `[${content.author}](https://reddit.com/user/${content.author})`,
inline: true,
},
{
name: "Votes",
value: `${content.ups}/${content.downs}`,
inline: true,
},
])
.setTimestamp(new Date())
.setImage(content.url)
.setFooter({
text: embedConfig.footerText,
iconURL: embedConfig.footerIcon,
})
.setColor(embedConfig.successColor);
return interaction.editReply({ embeds: [embed] });
})
.catch((error) => {
throw new Error(error.message);
});
},
};

View file

@ -0,0 +1,29 @@
//Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Groups
import modules from "../../commands/manage/modules";
import logger from "../../logger";
export const moduleData = modules;
// Function
export const builder = new SlashCommandBuilder()
.setName("manage")
.setDescription("Manage the bot.")
.addSubcommandGroup(modules.counters.builder)
.addSubcommandGroup(modules.credits.builder);
export const execute = async (interaction: CommandInteraction) => {
// Destructure
const { options } = interaction;
if (options?.getSubcommandGroup() === "credits") {
return modules.credits.execute(interaction);
}
if (options?.getSubcommandGroup() === "counters") {
return modules.counters.execute(interaction);
}
};

View file

@ -0,0 +1,37 @@
// Dependencies
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import logger from "../../../../logger";
// Modules
import modules from "./modules";
// Function
export const moduleData = modules;
export const builder = (group: SlashCommandSubcommandGroupBuilder) => {
return group
.setName("counters")
.setDescription("Manage guild counters.")
.addSubcommand(modules.add.builder)
.addSubcommand(modules.remove.builder);
};
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
if (options?.getSubcommand() === "add") {
logger?.silly(`Executing create subcommand`);
return modules.add.execute(interaction);
}
if (options?.getSubcommand() === "remove") {
logger?.silly(`Executing delete subcommand`);
return modules.remove.execute(interaction);
}
logger?.silly(`Unknown subcommand ${options?.getSubcommand()}`);
};

View file

@ -4,12 +4,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v10";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
import logger from "@logger";
import logger from "../../../../../../logger";
// Models
import counterSchema from "@schemas/counter";
import counterSchema from "../../../../../../database/schemas/counter";
// Function
export default {

View file

@ -0,0 +1,4 @@
import add from "./add";
import remove from "./remove";
export default { add, remove };

View file

@ -2,13 +2,13 @@
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../../../logger";
// Models
import counterSchema from "@schemas/counter";
import counterSchema from "../../../../../../database/schemas/counter";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v10";

View file

@ -0,0 +1,33 @@
import { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
import logger from "../../../../logger";
import modules from "./modules";
export const moduleData = modules;
export const builder = (group: SlashCommandSubcommandGroupBuilder) => {
return group
.setName("credits")
.setDescription("Manage the credits of a user.")
.addSubcommand(modules.give.builder)
.addSubcommand(modules.set.builder)
.addSubcommand(modules.take.builder)
.addSubcommand(modules.transfer.builder)
.addSubcommand(modules.drop.builder);
};
export const execute = async (interaction: CommandInteraction) => {
switch (interaction.options.getSubcommand()) {
case "give":
return modules.give.execute(interaction);
case "set":
return modules.set.execute(interaction);
case "take":
return modules.take.execute(interaction);
case "transfer":
return modules.transfer.execute(interaction);
case "drop":
return modules.drop.execute(interaction);
}
};

View file

@ -0,0 +1,126 @@
// Dependencies
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
import apiSchema from "../../../../../../database/schemas/api";
import encryption from "../../../../../../handlers/encryption";
// Configurations
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "../../../../../../logger";
// Helpers
import pluralize from "../../../../../../helpers/pluralize";
// Models
import fetchUser from "../../../../../../helpers/fetchUser";
// Function
export default {
metadata: {
guildOnly: true,
ephemeral: true,
permissions: [Permissions.FLAGS.MANAGE_GUILD],
},
builder: (command: SlashCommandSubcommandBuilder) => {
return command
.setName("drop")
.setDescription("Drop some credits for specified amount of users.")
.addIntegerOption((option) =>
option
.setName("uses")
.setDescription("How many users should be able to use this.")
.setRequired(true)
)
.addIntegerOption((option) =>
option
.setName("credit")
.setDescription(`How much credits provided per use.`)
.setRequired(true)
)
.addChannelOption((option) =>
option
.setName("channel")
.setDescription("The channel to send the message to.")
.setRequired(true)
);
},
execute: async (interaction: CommandInteraction) => {
if (interaction.guild == null) return;
const { errorColor, successColor, footerText, footerIcon } =
await getEmbedConfig(interaction.guild); // Destructure
const { guild, options } = interaction;
const uses = options?.getInteger("uses");
const creditAmount = options?.getInteger("credit");
const channel = options?.getChannel("channel");
if (!uses) throw new Error("Amount of uses is required.");
if (!creditAmount) throw new Error("Amount of credits is required.");
if (!channel) throw new Error("Channel is required.");
const embed = new MessageEmbed()
.setTitle("[:toolbox:] Drop")
.setFooter({ text: footerText, iconURL: footerIcon });
const code = uuidv4();
const apiCredentials = await apiSchema?.findOne({
guildId: guild?.id,
});
if (!apiCredentials) return;
const api = axios?.create({
baseURL: apiCredentials.url,
headers: {
Authorization: `Bearer ${encryption.decrypt(apiCredentials.token)}`,
},
});
const shopUrl = apiCredentials?.url?.replace("/api", "/store");
await api
.post("vouchers", {
uses,
code,
credits: creditAmount,
memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`,
})
.then(async () => {
await interaction.editReply({
embeds: [
embed
.setColor(successColor)
.setDescription(`Successfully crated code: ${code}`),
],
});
const discordChannel = guild.channels.cache.get(channel.id);
if (!discordChannel) return;
if (discordChannel.type !== "GUILD_TEXT") return;
discordChannel.send({
embeds: [
new MessageEmbed()
.setTitle("[:parachute:] Code Drop!")
.addFields([
{ name: "Code", value: `${code}`, inline: true },
{ name: "Amount", value: `${creditAmount}`, inline: true },
{ name: "Uses", value: `${uses}`, inline: true },
])
.setDescription(
`${interaction.user} dropped a voucher! You can use the code [here](${shopUrl})!`
)
.setColor(successColor),
],
});
});
},
};

View file

@ -3,16 +3,16 @@ import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../../../logger";
// Helpers
import pluralize from "@helpers/pluralize";
import pluralize from "../../../../../../helpers/pluralize";
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../../../helpers/fetchUser";
// Function
export default {

View file

@ -0,0 +1,7 @@
import give from "./give";
import set from "./set";
import take from "./take";
import transfer from "./transfer";
import drop from "./drop";
export default { give, set, take, transfer, drop };

View file

@ -2,15 +2,15 @@
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../../../logger";
// Helpers
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -2,16 +2,16 @@
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
import logger from "../../../../../../logger";
// Helpers
import pluralize from "@helpers/pluralize";
import pluralize from "../../../../../../helpers/pluralize";
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -1,17 +1,16 @@
// Dependencies
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
import mongoose from "mongoose";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
// Handlers
import logger from "@logger";
// Helpers
import saveUser from "@helpers/saveUser";
import logger from "../../../../../../logger";
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function
@ -193,38 +192,66 @@ export default {
});
}
// Withdraw amount from fromUser
fromUser.credits -= optionAmount;
const session = await mongoose.startSession();
// Deposit amount to toUser
toUser.credits += optionAmount;
session.startTransaction();
// Save users
await saveUser(fromUser, toUser)?.then(async () => {
logger?.silly(`Saved users`);
try {
// Withdraw amount from fromUserDB
fromUser.credits -= optionAmount;
return interaction?.editReply({
// Deposit amount to toUserDB
toUser.credits += optionAmount;
await fromUser.save();
await toUser.save();
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
session.endSession();
logger.error(`${error}`);
return interaction.editReply({
embeds: [
new MessageEmbed()
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
.setDescription(`Transferred ${optionAmount} credits.`)
.addFields(
{
name: `${optionFromUser?.username} Balance`,
value: `${fromUser?.credits}`,
inline: true,
},
{
name: `${optionToUser?.username} Balance`,
value: `${toUser?.credits}`,
inline: true,
}
.setDescription(
"An error occurred while trying to gift credits. Please try again."
)
.setColor(errorColor)
.setTimestamp(new Date())
.setColor(successColor)
.setFooter({ text: footerText, iconURL: footerIcon }),
],
});
} finally {
// ending the session
session.endSession();
}
return interaction?.editReply({
embeds: [
new MessageEmbed()
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
.setDescription(`Transferred ${optionAmount} credits.`)
.addFields(
{
name: `${optionFromUser?.username} Balance`,
value: `${fromUser?.credits}`,
inline: true,
},
{
name: `${optionToUser?.username} Balance`,
value: `${toUser?.credits}`,
inline: true,
}
)
.setTimestamp(new Date())
.setColor(successColor)
.setFooter({ text: footerText, iconURL: footerIcon }),
],
});
},
};

View file

@ -0,0 +1,4 @@
import * as counters from "./counters";
import * as credits from "./credits";
export default { counters, credits };

View file

@ -0,0 +1,29 @@
// Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Modules
import modules from "../../commands/profile/modules";
// Handlers
import logger from "../../logger";
export const moduleData = modules;
// Function
export const builder = new SlashCommandBuilder()
.setName("profile")
.setDescription("Check a profile.")
.addSubcommand(modules.view.builder);
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
if (options?.getSubcommand() === "view") {
logger?.silly(`Executing view subcommand`);
return modules.view.execute(interaction);
}
logger?.silly(`No subcommand found`);
};

View file

@ -0,0 +1,3 @@
import view from "./view";
export default { view };

View file

@ -2,12 +2,12 @@
import { CommandInteraction } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
// Models
import fetchUser from "@helpers/fetchUser";
import fetchUser from "../../../helpers/fetchUser";
import logger from "@logger";
import logger from "../../../logger";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -0,0 +1,29 @@
// Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Modules
import modules from "./modules";
// Handlers
import logger from "../../logger";
export const moduleData = modules;
// Function
export const builder = new SlashCommandBuilder()
.setName("reputation")
.setDescription("Manage reputation.")
.addSubcommand(modules.give.builder);
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
if (options?.getSubcommand() === "give") {
logger?.silly(`Executing give subcommand`);
await modules.give.execute(interaction);
}
logger?.silly(`No subcommand found`);
};

View file

@ -2,16 +2,16 @@
import { CommandInteraction } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import { timeout } from "@config/reputation";
import { timeout } from "../../../config/reputation";
// Handlers
import logger from "@logger";
import logger from "../../../logger";
// Models
import timeoutSchema from "@schemas/timeout";
import fetchUser from "@helpers/fetchUser";
import timeoutSchema from "../../../database/schemas/timeout";
import fetchUser from "../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -0,0 +1,3 @@
import give from "./give";
export default { give };

View file

@ -0,0 +1,36 @@
// Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Modules
import modules from "./modules";
// Handlers
import logger from "../../logger";
export const moduleData = modules;
// Function
export const builder = new SlashCommandBuilder()
.setName("shop")
.setDescription("Shop for credits and custom roles.")
.addSubcommand(modules.pterodactyl.builder)
.addSubcommandGroup(modules.roles.builder);
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
if (options?.getSubcommand() === "pterodactyl") {
logger.silly(`Executing pterodactyl subcommand`);
return modules.pterodactyl.execute(interaction);
}
if (options?.getSubcommandGroup() === "roles") {
logger?.silly(`Subcommand group is roles`);
return modules.roles.execute(interaction);
}
logger?.silly(`No subcommand found.`);
};

View file

@ -0,0 +1,4 @@
import pterodactyl from "./pterodactyl";
import * as roles from "./roles";
export default { pterodactyl, roles };

View file

@ -2,15 +2,15 @@ import { CommandInteraction } from "discord.js";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import logger from "@logger";
import encryption from "@handlers/encryption";
import logger from "../../../logger";
import encryption from "../../../handlers/encryption";
import pluralize from "@helpers/pluralize";
import pluralize from "../../../helpers/pluralize";
import apiSchema from "@schemas/api";
import fetchUser from "@helpers/fetchUser";
import apiSchema from "../../../database/schemas/api";
import fetchUser from "../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
export default {

View file

@ -0,0 +1,65 @@
// Dependencies
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Handlers
import logger from "../../../../logger";
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
// Modules
import modules from "./modules";
import guildSchema from "../../../../database/schemas/guild";
export const moduleData = modules;
// Function
export const builder = (group: SlashCommandSubcommandGroupBuilder) => {
return group
.setName("roles")
.setDescription("Shop for custom roles.")
.addSubcommand(modules.buy.builder)
.addSubcommand(modules.cancel.builder);
};
export const execute = async (interaction: CommandInteraction) => {
if (interaction.guild == null) return;
const { errorColor, footerText, footerIcon } = await getEmbedConfig(
interaction.guild
);
const { options, guild } = interaction;
const guildDB = await guildSchema?.findOne({
guildId: guild?.id,
});
if (guildDB === null) return;
if (!guildDB.shop.roles.status) {
logger.silly(`Shop roles disabled.`);
return interaction?.editReply({
embeds: [
{
title: ":dollar: Shop - Roles",
description: "This server has disabled shop roles.",
color: errorColor,
timestamp: new Date(),
footer: {
iconURL: footerIcon,
text: footerText,
},
},
],
});
}
if (options?.getSubcommand() === "buy") {
await modules.buy.execute(interaction);
}
if (options?.getSubcommand() === "cancel") {
await modules.cancel.execute(interaction);
}
};

View file

@ -6,17 +6,17 @@ import {
} from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
// Models
import shopRolesSchema from "@schemas/shopRole";
import guildSchema from "@schemas/guild";
import shopRolesSchema from "../../../../../database/schemas/shopRole";
import guildSchema from "../../../../../database/schemas/guild";
import logger from "@logger";
import logger from "../../../../../logger";
// Helpers
import pluralize from "@helpers/pluralize";
import fetchUser from "@helpers/fetchUser";
import pluralize from "../../../../../helpers/pluralize";
import fetchUser from "../../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -2,16 +2,16 @@
import { CommandInteraction, GuildMemberRoleManager } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
// Models
import shopRolesSchema from "@schemas/shopRole";
import shopRolesSchema from "../../../../../database/schemas/shopRole";
import logger from "@logger";
import logger from "../../../../../logger";
// Helpers
import pluralize from "@helpers/pluralize";
import fetchUser from "@helpers/fetchUser";
import pluralize from "../../../../../helpers/pluralize";
import fetchUser from "../../../../../helpers/fetchUser";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -0,0 +1,38 @@
// Dependencies
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
// Modules
import modules from "../../commands/utility/modules";
// Handlers
import logger from "../../logger";
export const moduleData = modules;
// Function
export const builder = new SlashCommandBuilder()
.setName("utility")
.setDescription("Common utility.")
.addSubcommand(modules.lookup.builder)
.addSubcommand(modules.about.builder)
.addSubcommand(modules.stats.builder)
.addSubcommand(modules.avatar.builder);
export const execute = async (interaction: CommandInteraction) => {
const { options } = interaction;
switch (options.getSubcommand()) {
case "lookup":
return modules.lookup.execute(interaction);
case "about":
return modules.about.execute(interaction);
case "stats":
return modules.stats.execute(interaction);
case "avatar":
return modules.avatar.execute(interaction);
default:
logger.error(`Unknown subcommand ${options.getSubcommand()}`);
}
};

View file

@ -2,9 +2,9 @@
import { CommandInteraction } from "discord.js";
// Configurations
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import { hosterName, hosterUrl } from "@config/other";
import { hosterName, hosterUrl } from "../../../config/other";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// Function

View file

@ -1,4 +1,4 @@
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";

View file

@ -0,0 +1,11 @@
import avatar from "./avatar";
import about from "./about";
import lookup from "./lookup";
import stats from "./stats";
export default {
avatar,
about,
lookup,
stats,
};

View file

@ -1,11 +1,11 @@
import axios from "axios";
import { CommandInteraction } from "discord.js";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import embedBuilder from "@root/helpers/embedBuilder";
import embedBuilder from "../../../helpers/embedBuilder";
export default {
metadata: { guildOnly: false, ephemeral: false },

View file

@ -1,4 +1,4 @@
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";

View file

@ -9,3 +9,6 @@ export const hosterName = "someone";
// Hoster Url
export const hosterUrl = "scheme://domain.tld";
// Winston log level
export const logLevel = "info";

View file

@ -2,10 +2,10 @@
import mongoose from "mongoose";
// Dependencies
import logger from "@logger";
import logger from "../logger";
// Configuration
import { url } from "@config/database";
import { url } from "../config/database";
export default async () => {
await mongoose.connect(url).then(async (connection) => {

View file

@ -1,10 +1,11 @@
import { Snowflake } from "discord.js";
import { model, Schema } from "mongoose";
import { IEncryptionData } from "../../interfaces/EncryptionData";
export interface IApi {
guildId: Snowflake;
url: string;
token: { iv: string; content: string };
token: IEncryptionData;
}
const apiSchema = new Schema<IApi>(

View file

@ -1,20 +1,20 @@
// 3rd party dependencies
import { Guild } from "discord.js";
import updatePresence from "../../helpers/updatePresence";
import fetchGuild from "../../helpers/fetchGuild";
import logger from "../../logger";
import { IEventOptions } from "../../interfaces/EventOptions";
// Dependencies
import updatePresence from "@helpers/updatePresence";
import fetchGuild from "@helpers/fetchGuild";
import logger from "@logger";
export default {
async execute(guild: Guild) {
const { client } = guild;
logger?.silly(`Added to guild: ${guild.name} (${guild.id})`);
await fetchGuild(guild);
await updatePresence(client);
logger.silly(`guildCreate: ${guild}`);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (guild: Guild) => {
const { client } = guild;
logger?.silly(`Added to guild: ${guild.name} (${guild.id})`);
await fetchGuild(guild);
await updatePresence(client);
logger.silly(`guildCreate: ${guild}`);
};

View file

@ -2,19 +2,22 @@
import { Guild } from "discord.js";
// Dependencies
import updatePresence from "@helpers/updatePresence";
import dropGuild from "@helpers/dropGuild";
import logger from "@logger";
import updatePresence from "../../helpers/updatePresence";
import dropGuild from "../../helpers/dropGuild";
import logger from "../../logger";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(guild: Guild) {
const { client } = guild;
logger?.silly(`Deleted from guild: ${guild.name} (${guild.id})`);
await dropGuild(guild);
await updatePresence(client);
logger.silly(`guildDelete: ${guild}`);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (guild: Guild) => {
const { client } = guild;
logger?.silly(`Deleted from guild: ${guild.name} (${guild.id})`);
await dropGuild(guild);
await updatePresence(client);
logger.silly(`guildDelete: ${guild}`);
};

View file

@ -1,9 +1,9 @@
import logger from "@logger";
import logger from "../../logger";
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (member: GuildMember) => {

View file

@ -2,23 +2,26 @@
import { GuildMember } from "discord.js";
// Dependencies
import updatePresence from "@helpers/updatePresence";
import fetchUser from "@helpers/fetchUser";
import logger from "@logger";
import updatePresence from "../../helpers/updatePresence";
import fetchUser from "../../helpers/fetchUser";
import logger from "../../logger";
import joinMessage from "../guildMemberAdd/joinMessage";
import audits from "../guildMemberAdd/audits";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(member: GuildMember) {
const { client, user, guild } = member;
logger?.silly(
`New member: ${user.tag} (${user.id}) added to guild: ${guild.name} (${guild.id})`
);
await audits.execute(member);
await joinMessage.execute(member);
await fetchUser(user, guild);
await updatePresence(client);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (member: GuildMember) => {
const { client, user, guild } = member;
logger?.silly(
`New member: ${user.tag} (${user.id}) added to guild: ${guild.name} (${guild.id})`
);
await audits.execute(member);
await joinMessage.execute(member);
await fetchUser(user, guild);
await updatePresence(client);
};

View file

@ -1,8 +1,8 @@
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (member: GuildMember) => {

View file

@ -1,9 +1,9 @@
import logger from "@logger";
import logger from "../../logger";
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (member: GuildMember) => {

View file

@ -2,23 +2,26 @@
import { GuildMember } from "discord.js";
// Dependencies
import updatePresence from "@helpers/updatePresence";
import dropUser from "@helpers/dropUser";
import logger from "@logger";
import updatePresence from "../../helpers/updatePresence";
import dropUser from "../../helpers/dropUser";
import logger from "../../logger";
import leaveMessage from "./leaveMessage";
import audits from "./audits";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(member: GuildMember) {
const { client, user, guild } = member;
logger?.silly(
`Removed member: ${user.tag} (${user.id}) from guild: ${guild.name} (${guild.id})`
);
await audits.execute(member);
await leaveMessage.execute(member);
await dropUser(user, guild);
await updatePresence(client);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (member: GuildMember) => {
const { client, user, guild } = member;
logger?.silly(
`Removed member: ${user.tag} (${user.id}) from guild: ${guild.name} (${guild.id})`
);
await audits.execute(member);
await leaveMessage.execute(member);
await dropUser(user, guild);
await updatePresence(client);
};

View file

@ -1,8 +1,8 @@
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (member: GuildMember) => {

View file

@ -1,9 +1,9 @@
import logger from "@logger";
import logger from "../../logger";
import { Interaction, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (interaction: Interaction) => {

View file

@ -1,11 +1,12 @@
// Dependencies
import { CommandInteraction, MessageEmbed } from "discord.js";
import logger from "@logger";
import logger from "../../../logger";
import deferReply from "@root/helpers/deferReply";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getCommandMetadata from "@helpers/getCommandMetadata";
import deferReply from "../../../helpers/deferReply";
import getEmbedConfig from "../../../helpers/getEmbedConfig";
import getCommandMetadata from "../../../helpers/getCommandMetadata";
import capitalizeFirstLetter from "../../../helpers/capitalizeFirstLetter";
export default async (interaction: CommandInteraction) => {
if (!interaction.isCommand()) return;
@ -89,10 +90,12 @@ export default async (interaction: CommandInteraction) => {
return interaction.editReply({
embeds: [
new MessageEmbed()
.setTitle("Error")
.setDescription(
`There was an error executing the command: **${currentCommand?.data?.name}**.`
.setTitle(
`[:x:] ${capitalizeFirstLetter(
interaction.options.getSubcommand()
)}`
)
.setDescription(`${"``"}${error}${"``"}`)
.setColor(errorColor)
.setTimestamp(new Date())
.setFooter({ text: footerText, iconURL: footerIcon }),

View file

@ -2,19 +2,22 @@
import { CommandInteraction } from "discord.js";
// Dependencies
import isCommand from "@root/events/interactionCreate/components/isCommand";
import logger from "@logger";
import isCommand from "../../events/interactionCreate/components/isCommand";
import logger from "../../logger";
import audits from "./audits";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(interaction: CommandInteraction) {
const { guild, id } = interaction;
logger?.silly(
`New interaction: ${id} in guild: ${guild?.name} (${guild?.id})`
);
await audits.execute(interaction);
await isCommand(interaction);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (interaction: CommandInteraction) => {
const { guild, id } = interaction;
logger?.silly(
`New interaction: ${id} in guild: ${guild?.name} (${guild?.id})`
);
await audits.execute(interaction);
await isCommand(interaction);
};

View file

@ -1,10 +1,14 @@
import { Message } from "discord.js";
import modules from "@events/messageCreate/modules";
import modules from "../../events/messageCreate/modules";
export default {
async execute(message: Message) {
await modules.credits.execute(message);
await modules.points.execute(message);
await modules.counters.execute(message);
},
import { IEventOptions } from "../../interfaces/EventOptions";
export const options: IEventOptions = {
type: "on",
};
export const execute = async (message: Message) => {
await modules.credits.execute(message);
await modules.points.execute(message);
await modules.counters.execute(message);
};

View file

@ -1,7 +1,7 @@
import { Message } from "discord.js";
import logger from "@logger";
import counterSchema from "@schemas/counter";
import logger from "../../../../logger";
import counterSchema from "../../../../database/schemas/counter";
export default {
execute: async (message: Message) => {

View file

@ -1,9 +1,9 @@
import logger from "@logger";
import timeouts from "@schemas/timeout";
import logger from "../../../../logger";
import timeouts from "../../../../database/schemas/timeout";
import { Message } from "discord.js";
import fetchUser from "@helpers/fetchUser";
import fetchGuild from "@helpers/fetchGuild";
import fetchUser from "../../../../helpers/fetchUser";
import fetchGuild from "../../../../helpers/fetchGuild";
export default {
execute: async (message: Message) => {

View file

@ -1,6 +1,6 @@
import counters from "@events/messageCreate/modules/counters";
import credits from "@events/messageCreate/modules/credits";
import points from "@events/messageCreate/modules/points";
import counters from "./counters";
import credits from "./credits";
import points from "./points";
export default {
counters,

View file

@ -1,8 +1,8 @@
import logger from "@logger";
import timeouts from "@schemas/timeout";
import logger from "../../../../logger";
import timeouts from "../../../../database/schemas/timeout";
import fetchUser from "@helpers/fetchUser";
import fetchGuild from "@helpers/fetchGuild";
import fetchUser from "../../../../helpers/fetchUser";
import fetchGuild from "../../../../helpers/fetchGuild";
import { Message } from "discord.js";
export default {

View file

@ -1,9 +1,9 @@
import logger from "@logger";
import logger from "../../logger";
import { Message, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (message: Message) => {

View file

@ -1,10 +1,13 @@
import { Message } from "discord.js";
import audits from "@events/messageDelete/audits";
import audits from "../../events/messageDelete/audits";
import counter from "./modules/counter";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(message: Message) {
await audits.execute(message);
await counter(message);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (message: Message) => {
await audits.execute(message);
await counter(message);
};

View file

@ -2,8 +2,8 @@
import { Message } from "discord.js";
// Models
import counterSchema from "@schemas/counter";
import logger from "@logger";
import counterSchema from "../../../database/schemas/counter";
import logger from "../../../logger";
export default async (message: Message) => {
const { guild, channel, author, content } = message;

View file

@ -1,10 +1,10 @@
/* eslint-disable no-loops/no-loops */
import logger from "@logger";
import logger from "../../logger";
import { Message, MessageEmbed, TextChannel } from "discord.js";
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default {
execute: async (oldMessage: Message, newMessage: Message) => {

View file

@ -1,24 +1,27 @@
// Dependencies
import { Message } from "discord.js";
import logger from "@logger";
import logger from "../../logger";
// Modules
import counter from "./modules/counter";
import audits from "./audits";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
async execute(oldMessage: Message, newMessage: Message) {
const { author, guild } = newMessage;
await audits.execute(oldMessage, newMessage);
logger?.silly(
`Message update event fired by ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`
);
if (author?.bot) return logger?.silly(`Message update event fired by bot`);
await counter(newMessage);
},
export const options: IEventOptions = {
type: "on",
};
export const execute = async (oldMessage: Message, newMessage: Message) => {
const { author, guild } = newMessage;
await audits.execute(oldMessage, newMessage);
logger?.silly(
`Message update event fired by ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`
);
if (author?.bot) return logger?.silly(`Message update event fired by bot`);
await counter(newMessage);
};

View file

@ -2,8 +2,8 @@
import { Message } from "discord.js";
// Models
import counterSchema from "@schemas/counter";
import logger from "@logger";
import counterSchema from "../../../database/schemas/counter";
import logger from "../../../logger";
export default async (message: Message) => {
const { guild, channel, author, content } = message;

View file

@ -1,25 +1,21 @@
// Dependencies
import { Client } from "discord.js";
import logger from "@logger";
import logger from "../../logger";
// Helpers
import updatePresence from "@helpers/updatePresence";
import deployCommands from "@handlers/deployCommands";
import devMode from "@handlers/devMode";
import updatePresence from "../../helpers/updatePresence";
import deployCommands from "../../handlers/deployCommands";
import devMode from "../../handlers/devMode";
import { IEventOptions } from "../../interfaces/EventOptions";
export default {
once: true,
async execute(client: Client) {
logger.info("Ready!");
await updatePresence(client);
await devMode(client);
await deployCommands(client);
client.guilds?.cache.forEach((guild) => {
logger.silly(
`${client.user?.tag} (${client.user?.id}) is in guild: ${guild.name} (${guild.id}) with member count of ${guild.memberCount}`
);
});
},
export const options: IEventOptions = {
type: "once",
};
export const execute = async (client: Client) => {
logger.info("Discord's API client is ready!");
await updatePresence(client);
await devMode(client);
await deployCommands(client);
};

View file

@ -1,36 +0,0 @@
import fs from "fs"; // fs
import { Collection } from "discord.js"; // discord.js
import { Client } from "@root/types/common/discord";
import logger from "@logger";
export default async (client: Client) => {
client.commands = new Collection();
fs.readdir("./src/plugins", async (error, plugins) => {
if (error) {
return logger.error(`Error reading plugins: ${error}`);
}
await Promise.all(
plugins.map(async (pluginName, index) => {
const plugin = await import(`../plugins/${pluginName}`);
await client.commands.set(
plugin.default.builder.name,
plugin.default,
plugin.default.metadata
);
logger.verbose(
`Loaded plugin ${index + 1}/${plugins.length}: ${pluginName}`
);
})
)
.then(async () => {
logger.info(`Started all ${plugins.length} plugins.`);
})
.catch(async (err) => {
logger.error(`${err}`);
});
});
};

View file

@ -1,32 +1,28 @@
// @ts-ignore
import { token, clientId } from "@config/discord";
// @ts-ignore
import { devMode, guildId } from "@config/other";
import { token, clientId } from "../config/discord";
import { devMode, guildId } from "../config/other";
import logger from "../logger";
import { Client } from "@root/types/common/discord";
import { Client } from "discord.js";
import { REST } from "@discordjs/rest";
import { Routes } from "discord-api-types/v9";
import { SlashCommandBuilder } from "@discordjs/builders";
import { RESTPostAPIApplicationCommandsJSONBody } from "discord-api-types/v10";
export default async (client: Client) => {
const pluginList: Array<RESTPostAPIApplicationCommandsJSONBody> = [];
import { ICommand } from "../interfaces/Command";
interface IPluginData {
builder: SlashCommandBuilder;
}
export default async (client: Client) => {
const commandList: Array<RESTPostAPIApplicationCommandsJSONBody> = [];
logger.info("Gathering command list");
await Promise.all(
client.commands.map(async (pluginData: IPluginData) => {
pluginList.push(pluginData.builder.toJSON());
logger.verbose(
`Plugin is ready for deployment: ${pluginData.builder.name}`
);
client.commands.map(async (commandData: ICommand) => {
commandList.push(commandData.builder.toJSON());
logger.verbose(`${commandData.builder.name} pushed to list`);
})
)
.then(async () => {
logger.info("All plugins are ready to be deployed.");
logger.info(`Finished gathering command list.`);
})
.catch(async (error) => {
logger.error(`${error}`);
@ -36,10 +32,10 @@ export default async (client: Client) => {
await rest
.put(Routes.applicationCommands(clientId), {
body: pluginList,
body: commandList,
})
.then(async () => {
logger.info(`Successfully deployed plugins to Discord's API`);
logger.info(`Finished updating command list.`);
})
.catch(async (error) => {
logger.error(`${error}`);
@ -48,11 +44,9 @@ export default async (client: Client) => {
if (devMode) {
await rest
.put(Routes.applicationGuildCommands(clientId, guildId), {
body: pluginList,
body: commandList,
})
.then(async () =>
logger.info(`Successfully deployed guild plugins to Discord's API`)
)
.then(async () => logger.info(`Finished updating guild command list.`))
.catch(async (error) => {
logger.error(`${error}`);
});

View file

@ -1,10 +1,10 @@
// Dependencies
import { Client } from "discord.js";
import logger from "@logger";
import logger from "../logger";
// Configuration
import { devMode, guildId } from "@config/other";
import { devMode, guildId } from "../config/other";
export default async (client: Client) => {
if (!devMode) {

View file

@ -1,16 +1,12 @@
import crypto from "crypto";
// @ts-ignore
import { secretKey, algorithm } from "@config/encryption";
import { secretKey, algorithm } from "../config/encryption";
import { IEncryptionData } from "../interfaces/EncryptionData";
const iv = crypto.randomBytes(16);
interface IEncrypt {
iv: string;
content: string;
}
const encrypt = (text: crypto.BinaryLike): IEncrypt => {
const encrypt = (text: crypto.BinaryLike): IEncryptionData => {
const cipher = crypto.createCipheriv(algorithm, secretKey, iv);
const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
@ -20,7 +16,7 @@ const encrypt = (text: crypto.BinaryLike): IEncrypt => {
};
};
const decrypt = (hash: IEncrypt) => {
const decrypt = (hash: IEncryptionData) => {
const decipher = crypto.createDecipheriv(
algorithm,
secretKey,

View file

@ -1,37 +0,0 @@
import fs from "fs"; // fs
import { Client } from "discord.js"; // discord.js
import logger from "@logger";
export default async (client: Client) => {
fs.readdir("./src/events", async (error, events) => {
if (error) {
return logger.error(`Error reading plugins: ${error}`);
}
await Promise.all(
events.map(async (eventName, index) => {
const event = await import(`../events/${eventName}`);
logger.verbose(
`Loaded event ${index + 1}/${events.length}: ${eventName}`
);
if (event.once) {
return client.once(eventName, async (...args) =>
event.default.execute(...args)
);
}
return client.on(eventName, async (...args) =>
event.default.execute(...args)
);
})
)
.then(async () => {
logger.info(`Started all ${events.length} events.`);
})
.catch(async (err) => {
logger.error(`${err}`);
});
});
};

View file

@ -2,10 +2,10 @@
import { Client } from "discord.js";
import schedule from "node-schedule";
import logger from "@logger";
import logger from "../../logger";
// Jobs
import shopRoles from "@jobs/shopRoles";
import shopRoles from "../../jobs/shopRoles";
export default async (client: Client) => {
const expression = "*/5 * * * *";

View file

@ -0,0 +1,3 @@
export default (text: string): string => {
return text.charAt(0).toUpperCase() + text.slice(1);
};

View file

@ -1,5 +1,5 @@
import { CommandInteraction, MessageEmbed } from "discord.js";
import getEmbedConfig from "@helpers/getEmbedConfig";
import getEmbedConfig from "../../helpers/getEmbedConfig";
export default async (interaction: CommandInteraction, ephemeral: boolean) => {
if (interaction.guild == null) return;

View file

@ -1,11 +1,11 @@
import guildSchema from "@schemas/guild";
import userSchema from "@schemas/user";
import apiSchema from "@schemas/api";
import counterSchema from "@schemas/counter";
import shopRoleSchema from "@schemas/shopRole";
import timeoutSchema from "@schemas/timeout";
import guildSchema from "../../database/schemas/guild";
import userSchema from "../../database/schemas/user";
import apiSchema from "../../database/schemas/api";
import counterSchema from "../../database/schemas/counter";
import shopRoleSchema from "../../database/schemas/shopRole";
import timeoutSchema from "../../database/schemas/timeout";
import logger from "@logger";
import logger from "../../logger";
import { Guild } from "discord.js";

View file

@ -1,6 +1,6 @@
import userSchema from "@schemas/user";
import userSchema from "../../database/schemas/user";
import logger from "@logger";
import logger from "../../logger";
import { Guild, User } from "discord.js";

View file

@ -1,4 +1,4 @@
import { footerText, footerIcon } from "@config/embed";
import { footerText, footerIcon } from "../../config/embed";
import { MessageEmbed } from "discord.js";
export default new MessageEmbed()

View file

@ -2,10 +2,10 @@
import { Guild } from "discord.js";
// Models
import guildSchema from "@schemas/guild";
import guildSchema from "../../database/schemas/guild";
// Handlers
import logger from "@logger";
import logger from "../../logger";
// Function
export default async (guild: Guild) => {

View file

@ -2,10 +2,10 @@
import { Guild, User } from "discord.js";
// Models
import userSchema from "@schemas/user";
import userSchema from "../../database/schemas/user";
// Handlers
import logger from "@logger";
import logger from "../../logger";
// Function
export default async (user: User, guild: Guild) => {

View file

@ -1,12 +0,0 @@
import { CommandInteraction } from "discord.js";
export default async (interaction: CommandInteraction, currentCommand: any) => {
const subcommand = interaction.options.getSubcommand();
const subcommandGroup = interaction.options.getSubcommandGroup(false);
if (!subcommandGroup) {
return currentCommand.modules[subcommand].metadata;
}
return currentCommand.modules[subcommandGroup].modules[subcommand].metadata;
};

View file

@ -0,0 +1,14 @@
import { CommandInteraction } from "discord.js";
import { ICommand } from "../../interfaces/Command";
export default async (
interaction: CommandInteraction,
currentCommand: ICommand
) => {
const subcommand = interaction.options.getSubcommand();
const subcommandGroup = interaction.options.getSubcommandGroup(false);
return subcommandGroup
? currentCommand.moduleData[subcommandGroup].moduleData[subcommand].metadata
: currentCommand.moduleData[subcommand].metadata;
};

View file

@ -1,18 +0,0 @@
import guildSchema from "@schemas/guild";
import { ColorResolvable, Guild } from "discord.js";
export default async (guild: Guild) => {
const guildConfig = await guildSchema.findOne({ guildId: guild.id });
if (guildConfig == null)
return {
successColor: "#22bb33" as ColorResolvable,
waitColor: "#f0ad4e" as ColorResolvable,
errorColor: "#bb2124" as ColorResolvable,
footerIcon: "https://github.com/ZynerOrg.png",
footerText: "https://github.com/ZynerOrg/xyter",
};
return guildConfig.embeds;
};

View file

@ -0,0 +1,20 @@
import guildSchema from "../../database/schemas/guild";
import * as embedConfig from "../../config/embed";
import { Guild } from "discord.js";
export default async (guild: Guild | null) => {
if (guild == null)
return {
...embedConfig,
};
const guildConfig = await guildSchema.findOne({ guildId: guild.id });
if (guildConfig == null)
return {
...embedConfig,
};
return guildConfig.embeds;
};

View file

@ -0,0 +1,10 @@
import fs from "fs";
const fsPromises = fs.promises;
export default async (path: string) => {
try {
return await fsPromises.readdir(path);
} catch (err) {
console.error("Error occurred while reading directory!", err);
}
};

View file

@ -1,4 +1,4 @@
import logger from "@root/logger";
import logger from "../../logger";
export default (count: number, noun: string, suffix?: string): string => {
const result = `${count} ${noun}${count !== 1 ? suffix || "s" : ""}`;

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