Merge pull request #218 from ZynerOrg/restyled/dev
Restyle Major rewritten structure & grammar
This commit is contained in:
commit
5c5b525667
117 changed files with 3107 additions and 2851 deletions
|
@ -1,5 +1,6 @@
|
|||
# Custom Dictionary Words
|
||||
Controlpanel
|
||||
cpgg
|
||||
dagen
|
||||
discordjs
|
||||
Följande
|
||||
|
@ -11,6 +12,7 @@ inom
|
|||
inställningar
|
||||
inte
|
||||
Krediter
|
||||
multistream
|
||||
Nivå
|
||||
omdöme
|
||||
Omdöme
|
||||
|
|
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,10 +1,9 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
|
||||
title: ""
|
||||
labels: "bug"
|
||||
assignees: "VermiumSifell"
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
|
|||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
|
@ -23,16 +23,10 @@ A clear and concise description of what you expected to happen.
|
|||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
**Environment (please complete the following information):**
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
- Commit: [git rev-parse HEAD]
|
||||
- Branch: [git branch --show-current]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -4,6 +4,12 @@ node_modules
|
|||
config.json
|
||||
package-lock.json
|
||||
|
||||
|
||||
**/config/*.ts
|
||||
!**/config/index.ts
|
||||
!**/config/example.*.ts
|
||||
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
|
|
@ -39,14 +39,17 @@
|
|||
"discord.js": "^13.6.0",
|
||||
"dotenv": "^16.0.0",
|
||||
"i18next": "^21.6.13",
|
||||
"module-alias": "^2.2.2",
|
||||
"mongoose": "^6.2.3",
|
||||
"node-schedule": "^2.1.0",
|
||||
"pino": "^7.0.0-rc.9",
|
||||
"pino-pretty": "^7.6.1",
|
||||
"quick.db": "^7.1.3",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsconfig-paths": "^3.14.1",
|
||||
"typescript": "^4.6.3",
|
||||
"uuid": "^8.3.2"
|
||||
"uuid": "^8.3.2",
|
||||
"winston-daily-rotate-file": "^4.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chance": "^1.1.3",
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Modules
|
||||
import add from "./modules/add";
|
||||
import remove from "./modules/remove";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, guild, user, commandName } = interaction;
|
||||
|
||||
// Module - Add
|
||||
if (options?.getSubcommand() === "add") {
|
||||
// Execute Module - Add
|
||||
return add(interaction);
|
||||
}
|
||||
|
||||
// Module - Remove
|
||||
else if (options?.getSubcommand() === "remove") {
|
||||
// Execute Module - Remove
|
||||
return remove(interaction);
|
||||
}
|
||||
|
||||
// Log debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
};
|
|
@ -1,99 +0,0 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../helpers/database/models/counterSchema";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
// Channel option
|
||||
const optionChannel = options?.getChannel("channel");
|
||||
|
||||
// Word option
|
||||
const optionWord = options?.getString("word");
|
||||
|
||||
// Start option
|
||||
const optionStart = options?.getNumber("start");
|
||||
|
||||
if (optionChannel?.type !== "GUILD_TEXT") {
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":toolbox: Admin - Counters [Add]" as string,
|
||||
description:
|
||||
"That channel is not supported, it needs to be a text channel." as string,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const counterExist = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: optionChannel?.id,
|
||||
optionWord,
|
||||
});
|
||||
|
||||
if (!counterExist) {
|
||||
await counterSchema?.create({
|
||||
guildId: guild?.id,
|
||||
channelId: optionChannel?.id,
|
||||
optionWord,
|
||||
counter: optionStart || 0,
|
||||
});
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} added ${optionChannel?.id} as a counter using word "${optionWord}" for counting.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":toolbox: Admin - Counters [Add]" as string,
|
||||
description: `${optionChannel} is now counting when hearing word ${optionWord} and it starts at number ${
|
||||
optionStart || 0
|
||||
}.`,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":toolbox: Admin - Counters [Add]" as string,
|
||||
description: `${optionChannel} is already a counting channel.`,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../helpers/database/models/counterSchema";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const optionChannel = options?.getChannel("channel");
|
||||
|
||||
await counterSchema
|
||||
?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
channelId: optionChannel?.id,
|
||||
})
|
||||
?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Counters [Remove]" as string,
|
||||
description: `${optionChannel} is no longer an counting channel.`,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} removed ${optionChannel?.id} as a counter.`
|
||||
);
|
||||
};
|
|
@ -1,38 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import give from "./modules/give";
|
||||
import take from "./modules/take";
|
||||
import set from "./modules/set";
|
||||
import transfer from "./modules/transfer";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options } = interaction;
|
||||
|
||||
// Module - Give
|
||||
if (options?.getSubcommand() === "give") {
|
||||
// Execute Module - Give
|
||||
return give(interaction);
|
||||
}
|
||||
|
||||
// Module - Take
|
||||
else if (options?.getSubcommand() === "take") {
|
||||
// Execute Module - Take
|
||||
return take(interaction);
|
||||
}
|
||||
|
||||
// Module - Set
|
||||
else if (options?.getSubcommand() === "set") {
|
||||
// Execute Module - Set
|
||||
return set(interaction);
|
||||
}
|
||||
|
||||
// Module - Transfer
|
||||
else if (options?.getSubcommand() === "transfer") {
|
||||
// Execute Module - Transfer
|
||||
return transfer(interaction);
|
||||
}
|
||||
};
|
|
@ -1,132 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../../helpers/creditNoun";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
// User option
|
||||
const optionUser = options?.getUser("user");
|
||||
|
||||
// Amount option
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount option is null
|
||||
if (optionAmount === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Give]" as string,
|
||||
description: "We could not read your requested amount." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Give]" as string,
|
||||
description: "You can not give zero credits or below." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
if (optionUser === null) return;
|
||||
if (guild === null) return;
|
||||
|
||||
// toUser Information
|
||||
const toUser = await fetchUser(optionUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (!toUser) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Give]" as string,
|
||||
description: `We could not find ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Give]" as string,
|
||||
description: `We could not find credits for ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Deposit amount to toUser
|
||||
toUser.credits += optionAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Give]" as string,
|
||||
description: `We have given ${optionUser}, ${creditNoun(optionAmount)}.`,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} gave ${
|
||||
optionUser?.id
|
||||
} ${creditNoun(optionAmount)}.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,114 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../../helpers/creditNoun";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
// User Option
|
||||
const optionUser = options.getUser("user");
|
||||
|
||||
// Amount Option
|
||||
const optionAmount = options.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Set]" as string,
|
||||
description: "We could not read your requested amount." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
if (optionUser === null) return;
|
||||
if (guild === null) return;
|
||||
|
||||
// toUser Information
|
||||
const toUser = await fetchUser(optionUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (!toUser) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Set]" as string,
|
||||
description: `We could not find ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Set]" as string,
|
||||
description: `We could not find credits for ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Set toUser with amount
|
||||
toUser.credits = optionAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Set]" as string,
|
||||
description: `We have set ${optionUser} to ${creditNoun(optionAmount)}`,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} set ${
|
||||
optionUser?.id
|
||||
} to ${creditNoun(optionAmount)}.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,134 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../../helpers/creditNoun";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
// User option
|
||||
const optionUser = options?.getUser("user");
|
||||
|
||||
// Amount option
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Take]" as string,
|
||||
description: "We could not read your requested amount." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Take]" as string,
|
||||
description: "You can not take zero credits or below." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
if (optionUser === null) return;
|
||||
if (guild === null) return;
|
||||
|
||||
// toUser Information
|
||||
const toUser = await fetchUser(optionUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (!toUser) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Take]" as string,
|
||||
description: `We could not find ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Take]" as string,
|
||||
description: `We could not find credits for ${optionUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Withdraw amount from toUser
|
||||
toUser.credits -= optionAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Set]" as string,
|
||||
description: `We have taken ${creditNoun(
|
||||
optionAmount
|
||||
)} from ${optionUser}`,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} set ${
|
||||
optionUser?.id
|
||||
} to ${creditNoun(optionAmount)}.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,171 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../../helpers/creditNoun";
|
||||
import saveUser from "../../../../helpers/saveUser";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, options, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const optionFromUser = options?.getUser("from");
|
||||
const optionToUser = options?.getUser("to");
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: "We could not read your requested amount." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
if (guild === null) return;
|
||||
if (optionFromUser === null) return;
|
||||
if (optionToUser === null) return;
|
||||
|
||||
// Get fromUser object
|
||||
const fromUser = await fetchUser(optionFromUser, guild);
|
||||
|
||||
// Get toUser object
|
||||
const toUser = await fetchUser(optionToUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (!fromUser) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: `We could not find ${optionFromUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (!fromUser?.credits) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: `We could not find credits for ${optionFromUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser does not exist
|
||||
if (!toUser) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: `We could not find ${optionToUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: `We could not find credits for ${optionToUser} in our database.`,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Withdraw amount from fromUser
|
||||
fromUser.credits -= optionAmount;
|
||||
|
||||
// Deposit amount to toUser
|
||||
toUser.credits += optionAmount;
|
||||
|
||||
// Save users
|
||||
await saveUser(fromUser, toUser)?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin - Credits [Transfer]" as string,
|
||||
description: `You sent ${creditNoun(
|
||||
optionAmount
|
||||
)} from ${optionFromUser} to ${optionToUser}.`,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
fields: [
|
||||
{
|
||||
name: `${optionFromUser?.username} Balance`,
|
||||
value: `${fromUser?.credits}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `${optionToUser?.username} Balance`,
|
||||
value: `${toUser?.credits}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} transferred ${creditNoun(
|
||||
optionAmount
|
||||
)} from ${optionFromUser?.id} to ${optionToUser?.id}.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,177 +0,0 @@
|
|||
//Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction, ColorResolvable, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
|
||||
// Groups
|
||||
import credits from "./credits";
|
||||
import counters from "./counters";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("admin")
|
||||
.setDescription("Admin actions.")
|
||||
.addSubcommandGroup((group) =>
|
||||
group
|
||||
.setName("credits")
|
||||
.setDescription("Manage credits.")
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("give")
|
||||
.setDescription("Give credits to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("set")
|
||||
.setDescription("Set credits to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to set credits on.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will set.")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("take")
|
||||
.setDescription("Take credits from a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to take credits from.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will take.")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("transfer")
|
||||
.setDescription("Transfer credits from a user to another user.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("from")
|
||||
.setDescription("The user you want to take credits from.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("to")
|
||||
.setDescription("The user you want to give credits to.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will transfer.")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
)
|
||||
.addSubcommandGroup((group) =>
|
||||
group
|
||||
.setName("counters")
|
||||
.setDescription("Manage counters.")
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("add")
|
||||
.setDescription("Add a counter")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The counter channel.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("word")
|
||||
.setDescription("The counter word.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option.setName("start").setDescription("Start at number X.")
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("remove")
|
||||
.setDescription("Remove a counter")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The counter channel.")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
// Destructure
|
||||
const { memberPermissions, options, user, commandName, guild } =
|
||||
interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":toolbox: Admin" as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
description: "You do not have permission to manage this!" as string,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Group - Credits
|
||||
if (options?.getSubcommandGroup() === "credits") {
|
||||
// Execute Group - Credits
|
||||
return credits(interaction);
|
||||
}
|
||||
|
||||
// Group - Counters
|
||||
else if (options?.getSubcommandGroup() === "counters") {
|
||||
// Execute Group - Counters
|
||||
return counters(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
},
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Modules
|
||||
import view from "./modules/view";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("counters")
|
||||
.setDescription("Manage counters.")
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand
|
||||
.setName("view")
|
||||
.setDescription("View a counter.")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The counter channel you want to view")
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options, guild, user, commandName } = interaction;
|
||||
|
||||
// Module - View
|
||||
if (options?.getSubcommand() === "view") {
|
||||
// Execute Module - View
|
||||
return view(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
},
|
||||
};
|
|
@ -1,54 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../helpers/database/models/counterSchema";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const optionChannel = options?.getChannel("channel");
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: optionChannel?.id,
|
||||
});
|
||||
|
||||
if (!counter) {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":1234: Counters [View]" as string,
|
||||
description: `${optionChannel} is not a counting channel.` as string,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":1234: Counters [View]" as string,
|
||||
color: config.colors.success as ColorResolvable,
|
||||
description: `${optionChannel} is currently at number ${counter?.counter}.`,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
};
|
|
@ -1,90 +0,0 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
|
||||
// Modules
|
||||
import balance from "./modules/balance";
|
||||
import gift from "./modules/gift";
|
||||
import top from "./modules/top";
|
||||
import work from "./modules/work";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("credits")
|
||||
.setDescription("Manage your credits.")
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand
|
||||
.setName("balance")
|
||||
.setDescription("Check a user's balance.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user whose balance you want to check.")
|
||||
.setRequired(false)
|
||||
)
|
||||
)
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand
|
||||
.setName("gift")
|
||||
.setDescription("Gift someone credits from your credits.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("reason").setDescription("Your reason.")
|
||||
)
|
||||
)
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand.setName("top").setDescription("Check the top balance.")
|
||||
)
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand.setName("work").setDescription("Work for credits.")
|
||||
),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options, user, guild, commandName } = interaction;
|
||||
|
||||
// Module - Balance
|
||||
if (options?.getSubcommand() === "balance") {
|
||||
// Execute Module - Balance
|
||||
return balance(interaction);
|
||||
}
|
||||
|
||||
// Module - Gift
|
||||
else if (options?.getSubcommand() === "gift") {
|
||||
// Execute Module - Gift
|
||||
return gift(interaction);
|
||||
}
|
||||
|
||||
// Module - Top
|
||||
else if (options?.getSubcommand() === "top") {
|
||||
// Execute Module - Top
|
||||
return top(interaction);
|
||||
}
|
||||
|
||||
// Module - Work
|
||||
else if (options?.getSubcommand() === "work") {
|
||||
// Execute Module - Work
|
||||
return work(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
},
|
||||
};
|
|
@ -1,82 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../helpers/creditNoun";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
// User option
|
||||
const optionUser = options?.getUser("user");
|
||||
|
||||
if (guild === null) return;
|
||||
|
||||
// Get credit object
|
||||
const userDB = await fetchUser(optionUser || user, guild);
|
||||
|
||||
// If userDB does not exist
|
||||
if (userDB === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Balance]" as string,
|
||||
description: `We can not find ${
|
||||
optionUser || "you"
|
||||
} in our database.` as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If userDB.credits does not exist
|
||||
if (userDB.credits === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Balance]" as string,
|
||||
description: `We can not find credits for ${
|
||||
optionUser || "you"
|
||||
} in our database.` as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
} else {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Balance]" as string,
|
||||
description: `${
|
||||
optionUser ? `${optionUser} has` : "You have"
|
||||
} ${creditNoun(userDB.credits)}.` as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
};
|
|
@ -1,187 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Helpers
|
||||
import saveUser from "../../../helpers/saveUser";
|
||||
import creditNoun from "../../../helpers/creditNoun";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { options, user, guild, client } = interaction;
|
||||
|
||||
// User option
|
||||
const optionUser = options?.getUser("user");
|
||||
|
||||
// Amount option
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// Reason option
|
||||
const optionReason = options?.getString("reason");
|
||||
|
||||
if (guild === null) return;
|
||||
if (optionUser === null) return;
|
||||
|
||||
// Get fromUserDB object
|
||||
const fromUserDB = await fetchUser(user, guild);
|
||||
|
||||
// Get toUserDB object
|
||||
const toUserDB = await fetchUser(optionUser, guild);
|
||||
|
||||
if (fromUserDB === null) return;
|
||||
if (toUserDB === null) return;
|
||||
|
||||
// If receiver is same as sender
|
||||
if (optionUser?.id === user?.id) {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description: "You can't pay yourself." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description: "We could not read your requested amount." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description: "You can't pay zero or below." as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If user has below gifting amount
|
||||
if (fromUserDB?.credits < optionAmount) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description:
|
||||
`You have insufficient credits. Your credits is ${fromUserDB?.credits}` as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If toUserDB has no credits
|
||||
if (!toUserDB) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description:
|
||||
`That user has no credits, I can not gift credits to ${optionUser}` as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Withdraw amount from fromUserDB
|
||||
fromUserDB.credits -= optionAmount;
|
||||
|
||||
// Deposit amount to toUserDB
|
||||
toUserDB.credits += optionAmount;
|
||||
|
||||
// Save users
|
||||
await saveUser(fromUserDB, toUserDB)?.then(async () => {
|
||||
// Interaction embed object
|
||||
const interactionEmbed = {
|
||||
title: ":dollar: Credits [Gift]",
|
||||
description: `You sent ${creditNoun(optionAmount)} to ${optionUser}${
|
||||
optionReason ? ` with reason: ${optionReason}` : ""
|
||||
}. Your new credits is ${creditNoun(fromUserDB?.credits)}.`,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// DM embed object
|
||||
const dmEmbed = {
|
||||
title: ":dollar: Credits [Gift]" as string,
|
||||
description: `You received ${creditNoun(optionAmount)} from ${user}${
|
||||
optionReason ? ` with reason: ${optionReason}` : ""
|
||||
}. Your new credits is ${creditNoun(toUserDB?.credits)}.` as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Get DM user object
|
||||
const dmUser = client?.users?.cache?.get(interaction?.user?.id);
|
||||
|
||||
// Send DM to user
|
||||
await dmUser?.send({ embeds: [dmEmbed] });
|
||||
|
||||
// Send debug message
|
||||
logger.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}`
|
||||
);
|
||||
|
||||
// Send interaction reply
|
||||
return interaction.editReply({
|
||||
embeds: [interactionEmbed],
|
||||
});
|
||||
});
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Models
|
||||
import userSchema from "../../../helpers/database/models/userSchema";
|
||||
|
||||
// helpers
|
||||
import creditNoun from "../../../helpers/creditNoun";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Get all users in the guild
|
||||
|
||||
const usersDB = await userSchema.find({ guildId: interaction?.guild?.id });
|
||||
|
||||
const topTen = usersDB
|
||||
|
||||
// Sort them after credits amount (ascending)
|
||||
.sort((a, b) => (a?.credits > b?.credits ? -1 : 1))
|
||||
|
||||
// Return the top 10
|
||||
.slice(0, 10);
|
||||
|
||||
// Create entry object
|
||||
const entry = (x: any, index: number) =>
|
||||
`**Top ${index + 1}** - <@${x?.userId}> ${creditNoun(x?.credits)}`;
|
||||
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Top]" as string,
|
||||
description: `Below are the top ten.\n${topTen
|
||||
?.map((x, index) => entry(x, index))
|
||||
?.join("\n")}` as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
};
|
|
@ -1,116 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
import Chance from "chance";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import timeouts from "../../../helpers/database/models/timeoutSchema";
|
||||
|
||||
// Helpers
|
||||
import creditNoun from "../../../helpers/creditNoun";
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import fetchGuild from "../../../helpers/fetchGuild";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user } = interaction;
|
||||
|
||||
// Chance module
|
||||
const chance = new Chance();
|
||||
|
||||
// Check if user has a timeout
|
||||
const isTimeout = await timeouts?.findOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
if (guild === null) return;
|
||||
|
||||
const guildDB = await fetchGuild(guild);
|
||||
|
||||
// If user is not on timeout
|
||||
if (!isTimeout) {
|
||||
const creditsEarned = chance.integer({
|
||||
min: 0,
|
||||
max: guildDB?.credits?.workRate,
|
||||
});
|
||||
|
||||
const userDB = await fetchUser(user, guild);
|
||||
|
||||
if (userDB === null) return;
|
||||
|
||||
userDB.credits += creditsEarned;
|
||||
|
||||
await userDB?.save()?.then(async () => {
|
||||
// Send debug message
|
||||
logger?.debug(`Credits added to user: ${user?.id}`);
|
||||
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Work]" as string,
|
||||
description: `You have earned ${creditNoun(creditsEarned)}` as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
// Create a timeout for the user
|
||||
await timeouts?.create({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has not worked within the last ${
|
||||
guildDB?.credits?.workTimeout / 1000
|
||||
} seconds, work can be done`
|
||||
);
|
||||
|
||||
// When timeout is out, remove it from the database
|
||||
await timeouts?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
}, guildDB?.credits?.workTimeout);
|
||||
} else {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":dollar: Credits [Work]" as string,
|
||||
description: `You have worked within the last ${
|
||||
guildDB?.credits?.workTimeout / 1000
|
||||
} seconds, you can not work now!` as string,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has worked within last day, no work can be done`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
};
|
|
@ -1,97 +0,0 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
//Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../helpers/database/models/guildSchema";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
const workRate = options?.getNumber("work-rate");
|
||||
const workTimeout = options?.getNumber("work-timeout");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
// Modify values
|
||||
guildDB.credits.status = status !== null ? status : guildDB?.credits?.status;
|
||||
guildDB.credits.rate = rate !== null ? rate : guildDB?.credits?.rate;
|
||||
guildDB.credits.timeout =
|
||||
timeout !== null ? timeout : guildDB?.credits?.timeout;
|
||||
guildDB.credits.workRate =
|
||||
workRate !== null ? workRate : guildDB?.credits?.workRate;
|
||||
guildDB.credits.workTimeout =
|
||||
workTimeout !== null ? workTimeout : guildDB?.credits?.workTimeout;
|
||||
guildDB.credits.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.credits?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":tools: Settings - Guild [Credits]" as string,
|
||||
description: "Following settings is set!" as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status" as string,
|
||||
value: `${guildDB?.credits?.status}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate" as string,
|
||||
value: `${guildDB?.credits?.rate}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Work Rate" as string,
|
||||
value: `${guildDB?.credits?.workRate}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length" as string,
|
||||
value: `${guildDB?.credits?.minimumLength}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout" as string,
|
||||
value: `${guildDB?.credits?.timeout}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Work Timeout" as string,
|
||||
value: `${guildDB?.credits?.workTimeout}` as string,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user.id} has changed credit details.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,81 +0,0 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../helpers/database/models/guildSchema";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
// Modify values
|
||||
guildDB.points.status = status !== null ? status : guildDB?.points?.status;
|
||||
guildDB.points.rate = rate !== null ? rate : guildDB?.points?.rate;
|
||||
guildDB.points.timeout =
|
||||
timeout !== null ? timeout : guildDB?.points?.timeout;
|
||||
guildDB.points.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.points?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Settings - Guild [Points]" as string,
|
||||
description: "Following settings is set!" as string,
|
||||
color: config.colors.success as ColorResolvable,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status" as string,
|
||||
value: `${guildDB?.points?.status}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate" as string,
|
||||
value: `${guildDB?.points?.rate}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length" as string,
|
||||
value: `${guildDB?.points?.minimumLength}` as string,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout" as string,
|
||||
value: `${guildDB?.points?.timeout}` as string,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has changed credit details.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,51 +0,0 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../handlers/logger";
|
||||
|
||||
// Models
|
||||
import apiSchema from "../../../../helpers/database/models/apiSchema";
|
||||
import encryption from "../../../../handlers/encryption";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const url = options?.getString("url");
|
||||
const token = encryption.encrypt(options?.getString("token"));
|
||||
|
||||
// Update API credentials
|
||||
await apiSchema
|
||||
?.findOneAndUpdate(
|
||||
{ guildId: guild?.id },
|
||||
{ url, token },
|
||||
{ new: true, upsert: true }
|
||||
)
|
||||
.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":hammer: Settings - Guild [Pterodactyl]" as string,
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
description: "Pterodactyl settings is saved!" as string,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has changed api credentials.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
// Dependencies
|
||||
import { Permissions, ColorResolvable, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Modules
|
||||
import pterodactyl from "./addons/pterodactyl";
|
||||
import credits from "./addons/credits";
|
||||
import points from "./addons/points";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { memberPermissions, options, commandName, user, guild } = interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":tools: Settings - Guild" as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
description: "You do not have permission to manage this!" as string,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Module - Pterodactyl
|
||||
if (options?.getSubcommand() === "pterodactyl") {
|
||||
// Execute Module - Pterodactyl
|
||||
return pterodactyl(interaction);
|
||||
}
|
||||
|
||||
// Module - Credits
|
||||
else if (options?.getSubcommand() === "credits") {
|
||||
// Execute Module - Credits
|
||||
return credits(interaction);
|
||||
}
|
||||
|
||||
// Module - Points
|
||||
else if (options?.getSubcommand() === "points") {
|
||||
// Execute Module - Points
|
||||
return points(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
};
|
|
@ -1,144 +0,0 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Groups
|
||||
import guildGroup from "./guild";
|
||||
import userGroup from "./user";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("settings")
|
||||
.setDescription("Manage settings.")
|
||||
.addSubcommandGroup((group) =>
|
||||
group
|
||||
.setName("guild")
|
||||
.setDescription("Manage guild settings.")
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("pterodactyl")
|
||||
.setDescription("Controlpanel.gg")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("url")
|
||||
.setDescription("The api url")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("token")
|
||||
.setDescription("The api token")
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("credits")
|
||||
.setDescription("Credits")
|
||||
.addBooleanOption((option) =>
|
||||
option
|
||||
.setName("status")
|
||||
.setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("rate")
|
||||
.setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-rate")
|
||||
.setDescription("Maximum amount of credits on work.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-timeout")
|
||||
.setDescription(
|
||||
"Timeout between work schedules (milliseconds)."
|
||||
)
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription(
|
||||
"Timeout between earning credits (milliseconds)."
|
||||
)
|
||||
)
|
||||
)
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("points")
|
||||
.setDescription("Points")
|
||||
.addBooleanOption((option) =>
|
||||
option
|
||||
.setName("status")
|
||||
.setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("rate")
|
||||
.setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription(
|
||||
"Timeout between earning credits (milliseconds)."
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.addSubcommandGroup((group) =>
|
||||
group
|
||||
.setName("user")
|
||||
.setDescription("Manage user settings.")
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("appearance")
|
||||
.setDescription("Manage your appearance")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("language")
|
||||
.setDescription("Configure your language")
|
||||
.addChoice("English", "en")
|
||||
.addChoice("Swedish", "sv")
|
||||
)
|
||||
)
|
||||
),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
// Destructure
|
||||
const { options, commandName, user, guild } = interaction;
|
||||
|
||||
// Group - Guild
|
||||
if (options.getSubcommandGroup() === "guild") {
|
||||
// Execute Group - Guild
|
||||
await guildGroup(interaction);
|
||||
}
|
||||
// Group - User
|
||||
else if (options.getSubcommandGroup() === "user") {
|
||||
// Execute Group - User
|
||||
await userGroup(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
},
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Modules
|
||||
import appearance from "./modules/appearance";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user, options, commandName } = interaction;
|
||||
|
||||
// Module - Appearance
|
||||
if (options?.getSubcommand() === "appearance") {
|
||||
// Execute Module - Appearance
|
||||
await appearance(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
};
|
|
@ -1,112 +0,0 @@
|
|||
// Dependencies
|
||||
import axios from "axios";
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
// Get lookup query
|
||||
const query = options?.getString("query");
|
||||
|
||||
// Make API request
|
||||
await axios
|
||||
// Make a get request
|
||||
?.get(`http://ip-api.com/json/${query}`)
|
||||
|
||||
// If successful
|
||||
?.then(async (res) => {
|
||||
// If query failed
|
||||
if (res?.data?.status === "fail") {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Utilities - Lookup" as string,
|
||||
description: `${res?.data?.message}: ${res?.data?.query}` as string,
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
await interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If query is successful
|
||||
else if (res?.data?.status === "success") {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Utilities - Lookup" as string,
|
||||
fields: [
|
||||
{
|
||||
name: "AS" as string,
|
||||
value: `${res?.data?.as || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Country" as string,
|
||||
value: `${res?.data?.country || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Country Code" as string,
|
||||
value: `${res?.data?.countryCode || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Region" as string,
|
||||
value: `${res?.data?.region || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Region Name" as string,
|
||||
value: `${res?.data?.regionName || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "City" as string,
|
||||
value: `${res?.data?.city || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "ZIP Code" as string,
|
||||
value: `${res?.data?.zip || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Latitude" as string,
|
||||
value: `${res?.data?.lat || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Longitude" as string,
|
||||
value: `${res?.data?.lon || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Timezone" as string,
|
||||
value: `${res?.data?.timezone || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "ISP" as string,
|
||||
value: `${res?.data?.isp || "Not available"}` as string,
|
||||
},
|
||||
{
|
||||
name: "Organization" as string,
|
||||
value: `${res?.data?.org || "Not available"}` as string,
|
||||
},
|
||||
],
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
await interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
})
|
||||
.catch(async (e) => {
|
||||
logger?.error(e);
|
||||
});
|
||||
};
|
2
src/config/example.api.ts
Normal file
2
src/config/example.api.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Controlpanel.gg (Pterodactyl) API token
|
||||
export const cpggToken = "";
|
3
src/config/example.database.ts
Normal file
3
src/config/example.database.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
// MongoDB connection string
|
||||
export const url =
|
||||
"mongodb+srv://username:password@server/database?retryWrites=true&w=majority";
|
5
src/config/example.discord.ts
Normal file
5
src/config/example.discord.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Discord API token
|
||||
export const token = "";
|
||||
|
||||
// Discord API id
|
||||
export const clientId = "";
|
17
src/config/example.embed.ts
Normal file
17
src/config/example.embed.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Dependencies
|
||||
import { ColorResolvable } from "discord.js";
|
||||
|
||||
// Color for successfully actions
|
||||
export const successColor: ColorResolvable = "#22bb33";
|
||||
|
||||
// Color for waiting actions
|
||||
export const waitColor: ColorResolvable = "#f0ad4e";
|
||||
|
||||
// Color for error actions
|
||||
export const errorColor: ColorResolvable = "#bb2124";
|
||||
|
||||
// Footer text
|
||||
export const footerText = "https://github.com/ZynerOrg/xyter";
|
||||
|
||||
// Footer icon
|
||||
export const footerIcon = "https://github.com/ZynerOrg.png";
|
0
src/config/example.encryption.ts
Normal file
0
src/config/example.encryption.ts
Normal file
11
src/config/example.other.ts
Normal file
11
src/config/example.other.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Development features
|
||||
export const devMode = false;
|
||||
|
||||
// Development guild
|
||||
export const guildId = "";
|
||||
|
||||
// Hoster name
|
||||
export const hosterName = "someone";
|
||||
|
||||
// Hoster Url
|
||||
export const hosterUrl = "scheme://domain.tld";
|
2
src/config/example.reputation.ts
Normal file
2
src/config/example.reputation.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Timeout between repute someone (seconds)
|
||||
export const timeout = 86400; // One day
|
15
src/database/index.ts
Normal file
15
src/database/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { url } from "@config/database";
|
||||
|
||||
import mongoose from "mongoose";
|
||||
import logger from "@logger";
|
||||
|
||||
export default async () => {
|
||||
await mongoose
|
||||
.connect(url)
|
||||
?.then(async () => {
|
||||
logger.info("Successfully connected to MongoDB!");
|
||||
})
|
||||
?.catch(async () => {
|
||||
logger.error("Error whilst connecting to MongoDB!");
|
||||
});
|
||||
};
|
|
@ -1,66 +1,85 @@
|
|||
import mongoose from "mongoose";
|
||||
import { Schema, model } from "mongoose";
|
||||
|
||||
const guildSchema = new mongoose.Schema(
|
||||
interface IGuild {
|
||||
guildId: string;
|
||||
credits: {
|
||||
status: boolean;
|
||||
rate: number;
|
||||
timeout: number;
|
||||
workRate: number;
|
||||
minimumLength: number;
|
||||
workTimeout: number;
|
||||
};
|
||||
shop: { roles: { status: boolean; pricePerHour: number } };
|
||||
points: {
|
||||
status: boolean;
|
||||
rate: number;
|
||||
minimumLength: number;
|
||||
timeout: number;
|
||||
};
|
||||
}
|
||||
|
||||
const guildSchema = new Schema<IGuild>(
|
||||
{
|
||||
guildId: {
|
||||
type: mongoose.SchemaTypes.Decimal128,
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
index: true,
|
||||
},
|
||||
credits: {
|
||||
status: {
|
||||
type: mongoose.SchemaTypes.Boolean,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
rate: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
minimumLength: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
timeout: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 5000,
|
||||
},
|
||||
workRate: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 15,
|
||||
},
|
||||
workTimeout: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 900000,
|
||||
},
|
||||
},
|
||||
shop: {
|
||||
roles: {
|
||||
status: {
|
||||
type: mongoose.SchemaTypes.Boolean,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
pricePerHour: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
points: {
|
||||
status: {
|
||||
type: mongoose.SchemaTypes.Boolean,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
rate: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
minimumLength: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
timeout: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
type: Number,
|
||||
default: 5000,
|
||||
},
|
||||
},
|
||||
|
@ -68,4 +87,4 @@ const guildSchema = new mongoose.Schema(
|
|||
{ timestamps: true }
|
||||
);
|
||||
|
||||
export default mongoose.model("guild", guildSchema);
|
||||
export default model<IGuild>("guild", guildSchema);
|
3
src/database/schemas/index.ts
Normal file
3
src/database/schemas/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import counter from "./counter";
|
||||
|
||||
export default { counter };
|
|
@ -5,15 +5,12 @@ import { Guild } from "discord.js";
|
|||
import updatePresence from "../../helpers/updatePresence";
|
||||
import fetchGuild from "../../helpers/fetchGuild";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
name: "guildCreate",
|
||||
async execute(guild: Guild) {
|
||||
// Destructure
|
||||
const { client } = guild;
|
||||
|
||||
await fetchGuild(guild);
|
||||
|
||||
await updatePresence(client);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,15 +5,12 @@ import { Guild } from "discord.js";
|
|||
import updatePresence from "../../helpers/updatePresence";
|
||||
import dropGuild from "../../helpers/dropGuild";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
name: "guildDelete",
|
||||
async execute(guild: Guild) {
|
||||
// Destructure client
|
||||
const { client } = guild;
|
||||
|
||||
await dropGuild(guild);
|
||||
|
||||
await updatePresence(client);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
// Dependencies
|
||||
import { GuildMember } from "discord.js";
|
||||
|
||||
// Helpers
|
||||
import updatePresence from "../../helpers/updatePresence";
|
||||
import fetchUser from "../../helpers/fetchUser";
|
||||
|
||||
|
@ -8,7 +11,6 @@ export default {
|
|||
const { client, user, guild } = member;
|
||||
|
||||
await fetchUser(user, guild);
|
||||
|
||||
await updatePresence(client);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
// Dependencies
|
||||
import { GuildMember } from "discord.js";
|
||||
|
||||
// Helpers
|
||||
import updatePresence from "../../helpers/updatePresence";
|
||||
import dropUser from "../../helpers/dropUser";
|
||||
|
||||
|
@ -8,7 +11,6 @@ export default {
|
|||
const { client, user, guild } = member;
|
||||
|
||||
await dropUser(user, guild);
|
||||
|
||||
await updatePresence(client);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,57 +1,11 @@
|
|||
import config from "../../../config.json";
|
||||
import logger from "../../handlers/logger";
|
||||
import guilds from "../../helpers/database/models/guildSchema";
|
||||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
import { Interaction, ColorResolvable } from "discord.js";
|
||||
import isCommand from "./isCommand";
|
||||
|
||||
export default {
|
||||
name: "interactionCreate",
|
||||
async execute(interaction: Interaction) {
|
||||
// Destructure member, client
|
||||
const { client, guild } = interaction;
|
||||
|
||||
// If interaction is command
|
||||
if (interaction.isCommand()) {
|
||||
// Get command from collection
|
||||
const command = client.commands.get(interaction.commandName);
|
||||
|
||||
// If command do not exist
|
||||
if (!command) return;
|
||||
|
||||
// Create guild if it does not exist already
|
||||
await guilds.findOne({ guildId: guild?.id }, { new: true, upsert: true });
|
||||
|
||||
try {
|
||||
// Defer reply
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
// Execute command
|
||||
await command.execute(interaction);
|
||||
|
||||
// Send debug message
|
||||
logger.debug(`Executing command: ${interaction.commandName}`);
|
||||
} catch (e) {
|
||||
// Send debug message
|
||||
logger.error(e);
|
||||
|
||||
// Send interaction reply
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
{
|
||||
author: {
|
||||
name: client?.user?.username,
|
||||
icon_url: client?.user?.displayAvatarURL(),
|
||||
url: "https://bot.zyner.org/",
|
||||
},
|
||||
title: "Error",
|
||||
description: "There was an error while executing this command!",
|
||||
color: config.colors.error as ColorResolvable,
|
||||
timestamp: new Date(),
|
||||
},
|
||||
],
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
async execute(interaction: CommandInteraction) {
|
||||
await isCommand(interaction);
|
||||
},
|
||||
};
|
||||
|
|
58
src/events/interactionCreate/isCommand.ts
Normal file
58
src/events/interactionCreate/isCommand.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
import * as embed from "@config/embed";
|
||||
|
||||
import guildSchema from "@schemas/guild";
|
||||
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
|
||||
const { client, guild, commandName, user } = interaction;
|
||||
|
||||
const currentCommand = client.commands.get(commandName);
|
||||
if (!currentCommand) return;
|
||||
|
||||
// If command do not exist
|
||||
|
||||
// Create guild if it does not exist already
|
||||
await guildSchema.findOne(
|
||||
{ guildId: guild?.id },
|
||||
{ new: true, upsert: true }
|
||||
);
|
||||
|
||||
// Defer reply
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
await currentCommand
|
||||
.execute(interaction)
|
||||
.then(async () => {
|
||||
return logger.debug(
|
||||
`Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} executed ${commandName}`
|
||||
);
|
||||
})
|
||||
.catch(async (error: any) => {
|
||||
console.log(error);
|
||||
|
||||
logger.error(
|
||||
`Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} There was an error executing the command: ${commandName}`
|
||||
);
|
||||
|
||||
logger.error(error);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("Error")
|
||||
.setDescription(
|
||||
`There was an error executing the command: **${currentCommand.data.name}**.`
|
||||
)
|
||||
.setColor(embed.errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: embed.footerText, iconURL: embed.footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
};
|
|
@ -14,7 +14,6 @@ export default {
|
|||
async execute(message: Message) {
|
||||
const { author, guild } = message;
|
||||
|
||||
// If message author is bot
|
||||
if (author?.bot) return;
|
||||
|
||||
if (guild === null) return;
|
||||
|
@ -32,6 +31,6 @@ export default {
|
|||
await points(guildObj, userObj, message);
|
||||
|
||||
// Execute Module - Counters
|
||||
await counters(guildObj, userObj, message);
|
||||
await counters(message);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import counters from "../../../helpers/database/models/counterSchema";
|
||||
import counters from "../../../database/schemas/counter";
|
||||
|
||||
import { Message } from "discord.js";
|
||||
|
||||
export default async (guildDB: any, userDB: any, message: Message) => {
|
||||
export default async (message: Message) => {
|
||||
const { guild, channel, content } = message;
|
||||
|
||||
// Get counter object
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logger from "../../../handlers/logger";
|
||||
import timeouts from "../../../helpers/database/models/timeoutSchema";
|
||||
import logger from "../../../logger";
|
||||
import timeouts from "../../../database/schemas/timeout";
|
||||
import { Message } from "discord.js";
|
||||
export default async (guildDB: any, userDB: any, message: Message) => {
|
||||
const { guild, author, channel, content } = message;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logger from "../../../handlers/logger";
|
||||
import timeouts from "../../../helpers/database/models/timeoutSchema";
|
||||
import logger from "../../../logger";
|
||||
import timeouts from "../../../database/schemas/timeout";
|
||||
|
||||
import { Message } from "discord.js";
|
||||
export default async (guildDB: any, userDB: any, message: Message) => {
|
||||
|
|
|
@ -1,27 +1,19 @@
|
|||
import counters from "../../helpers/database/models/counterSchema";
|
||||
// Dependencies
|
||||
import { Message } from "discord.js";
|
||||
import logger from "../../logger";
|
||||
|
||||
// Modules
|
||||
import counter from "./modules/counter";
|
||||
|
||||
export default {
|
||||
name: "messageUpdate",
|
||||
async execute(oldMessage: Message, newMessage: Message) {
|
||||
// If message author is bot
|
||||
if (newMessage.author.bot) return;
|
||||
const { author } = newMessage;
|
||||
|
||||
// Get counter object
|
||||
const counter = await counters.findOne({
|
||||
guildId: newMessage.guild?.id,
|
||||
channelId: newMessage.channel.id,
|
||||
});
|
||||
logger.debug({ oldMessage, newMessage });
|
||||
|
||||
// If counter for the message channel
|
||||
if (counter) {
|
||||
// If message content is not strictly the same as counter word
|
||||
if (newMessage.content !== counter.word) {
|
||||
// Delete the message
|
||||
await newMessage.delete();
|
||||
await newMessage.channel.send(
|
||||
`${newMessage.author} said **${counter.word}**.`
|
||||
);
|
||||
}
|
||||
}
|
||||
if (author?.bot) return;
|
||||
|
||||
await counter(newMessage);
|
||||
},
|
||||
};
|
||||
|
|
28
src/events/messageUpdate/modules/counter.ts
Normal file
28
src/events/messageUpdate/modules/counter.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Dependencies
|
||||
import { Message } from "discord.js";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../database/schemas/counter";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export default async (message: Message) => {
|
||||
const { guild, channel, author, content } = message;
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: channel?.id,
|
||||
});
|
||||
|
||||
if (counter === null) return;
|
||||
const { word } = counter;
|
||||
if (content === word) return;
|
||||
|
||||
await message
|
||||
?.delete()
|
||||
?.then(async () => {
|
||||
await channel?.send(`${author} said **${word}**.`);
|
||||
})
|
||||
?.catch(async (error) => {
|
||||
logger.error(new Error(error));
|
||||
});
|
||||
};
|
|
@ -1,71 +1,24 @@
|
|||
import logger from "../../handlers/logger";
|
||||
import config from "../../../config.json";
|
||||
import deployCommands from "../../helpers/deployCommands";
|
||||
import dbGuildFix from "../../helpers/dbGuildFix";
|
||||
import dbMemberFix from "../../helpers/dbMemberFix";
|
||||
|
||||
import userSchema from "../../helpers/database/models/userSchema";
|
||||
|
||||
// Dependencies
|
||||
import { Client } from "discord.js";
|
||||
import logger from "../../logger";
|
||||
|
||||
// Helpers
|
||||
import deployCommands from "../../handlers/deployCommands";
|
||||
import updatePresence from "../../helpers/updatePresence";
|
||||
import devMode from "../../helpers/devMode";
|
||||
|
||||
export default {
|
||||
name: "ready",
|
||||
once: true,
|
||||
async execute(client: Client) {
|
||||
// Send info message
|
||||
await logger.info(`Ready! Logged in as ${client?.user?.tag}`);
|
||||
|
||||
logger.info(`Successfully logged into discord user: ${client?.user?.tag}!`);
|
||||
await updatePresence(client);
|
||||
|
||||
if (config.importToDB) {
|
||||
const guilds = client.guilds.cache;
|
||||
await guilds.map(async (guild) => {
|
||||
await guild?.members.fetch().then(async (members) => {
|
||||
await members.forEach(async (member) => {
|
||||
const { user } = member;
|
||||
dbMemberFix(user, guild);
|
||||
});
|
||||
});
|
||||
await dbGuildFix(guild);
|
||||
});
|
||||
}
|
||||
|
||||
if (client === null) return;
|
||||
if (client.application === null) return;
|
||||
|
||||
if (!config?.devMode) {
|
||||
client?.application?.commands
|
||||
?.set([], config.bot.guildId)
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Removed all guild based commands from ${config.bot.guildId}`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (config.clearUnused) {
|
||||
await userSchema.find().then(
|
||||
async (result) =>
|
||||
await result.map(async (user) => {
|
||||
if (
|
||||
user.credits !== 0 ||
|
||||
user.reputation !== 0 ||
|
||||
user.points !== 0
|
||||
) {
|
||||
logger.info(`Not removing user: ${user}`);
|
||||
} else {
|
||||
logger.warn(`Removing user: ${user}`);
|
||||
console.log({ userId: user.userId, guildId: user.guildId });
|
||||
await userSchema
|
||||
.deleteOne({ _id: user._id })
|
||||
.then(async (result) => {
|
||||
logger.error(`Removed user: ${user} ${result}`);
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await devMode(client);
|
||||
await deployCommands();
|
||||
|
||||
const guilds = client.guilds.cache;
|
||||
guilds.map(async (guild) => {
|
||||
logger.debug({ name: guild.name, members: guild.memberCount });
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
import fs from "fs"; // fs
|
||||
import { Collection } from "discord.js"; // discord.js
|
||||
import { Client } from "../types/common/discord";
|
||||
import logger from "../logger";
|
||||
|
||||
export default async (client: Client) => {
|
||||
client.commands = new Collection();
|
||||
const commandFiles = fs.readdirSync("./src/commands");
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const command = require(`../commands/${file}`);
|
||||
client.commands.set(command.default.data.name, command.default);
|
||||
}
|
||||
fs.readdir("./src/plugins", async (error: any, plugins: any) => {
|
||||
if (error) {
|
||||
return logger?.error(new Error(error));
|
||||
}
|
||||
|
||||
await plugins?.map(async (pluginName: any) => {
|
||||
const plugin = await import(`../plugins/${pluginName}`);
|
||||
|
||||
await client?.commands?.set(plugin?.default?.data?.name, plugin?.default);
|
||||
logger?.debug(
|
||||
`Successfully loaded plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}`
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
54
src/handlers/deployCommands.ts
Normal file
54
src/handlers/deployCommands.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Dependencies
|
||||
import { token, clientId } from "@config/discord";
|
||||
import { devMode, guildId } from "@config/other";
|
||||
|
||||
import logger from "../logger";
|
||||
import fs from "fs";
|
||||
import { REST } from "@discordjs/rest";
|
||||
import { Routes } from "discord-api-types/v9";
|
||||
|
||||
export default async () => {
|
||||
fs.readdir("./src/plugins", async (error: any, plugins: any) => {
|
||||
if (error) {
|
||||
return logger?.error(new Error(error));
|
||||
}
|
||||
|
||||
const pluginList = [] as any;
|
||||
|
||||
await plugins?.map(async (pluginName: any) => {
|
||||
const plugin = await import(`../plugins/${pluginName}`);
|
||||
|
||||
pluginList.push(plugin.default.data.toJSON());
|
||||
|
||||
logger?.debug(
|
||||
`Successfully deployed plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}`
|
||||
);
|
||||
});
|
||||
|
||||
const rest = new REST({ version: "9" }).setToken(token);
|
||||
|
||||
await rest
|
||||
.put(Routes.applicationCommands(clientId), {
|
||||
body: pluginList,
|
||||
})
|
||||
.then(async () =>
|
||||
logger.info("Successfully registered application commands.")
|
||||
)
|
||||
.catch(async (err: any) => {
|
||||
logger.error(err);
|
||||
});
|
||||
|
||||
if (devMode) {
|
||||
await rest
|
||||
.put(Routes.applicationGuildCommands(clientId, guildId), {
|
||||
body: pluginList,
|
||||
})
|
||||
.then(async () =>
|
||||
logger.info("Successfully registered guild application commands.")
|
||||
)
|
||||
.catch(async (err: any) => {
|
||||
logger.error(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
import pino from "pino";
|
||||
import * as config from "../../config.json";
|
||||
|
||||
export default pino({ level: config.debug ? "debug" : "info" });
|
|
@ -1,65 +0,0 @@
|
|||
import schedule from "node-schedule";
|
||||
import users from "../helpers/database/models/userSchema";
|
||||
import shopRolesSchema from "../helpers/database/models/shopRolesSchema";
|
||||
import guilds from "../helpers/database/models/guildSchema";
|
||||
import logger from "./logger";
|
||||
import { Client } from "discord.js";
|
||||
|
||||
export default async (client: Client) => {
|
||||
schedule.scheduleJob("*/5 * * * *", async () => {
|
||||
shopRolesSchema.find().then(async (shopRoles: any) => {
|
||||
shopRoles.map(async (shopRole: any) => {
|
||||
const payed = new Date(shopRole.lastPayed);
|
||||
|
||||
const oneHourAfterPayed = payed.setHours(payed.getHours() + 1);
|
||||
|
||||
if (new Date() > new Date(oneHourAfterPayed)) {
|
||||
logger.debug(
|
||||
`Role: ${shopRole.roleId} Expires: ${
|
||||
new Date() < new Date(oneHourAfterPayed)
|
||||
} Last Payed: ${shopRole.lastPayed}`
|
||||
);
|
||||
|
||||
// Get guild object
|
||||
const guild = await guilds.findOne({
|
||||
guildId: shopRole.guildId,
|
||||
});
|
||||
|
||||
const userDB = await users.findOne({
|
||||
userId: shopRole.userId,
|
||||
guildId: shopRole.guildId,
|
||||
});
|
||||
const { pricePerHour } = guild.shop.roles;
|
||||
|
||||
if (userDB === null) return;
|
||||
|
||||
if (userDB.credits < pricePerHour) {
|
||||
const rGuild = client?.guilds?.cache?.get(`${shopRole.guildId}`);
|
||||
const rMember = await rGuild?.members?.fetch(`${shopRole.userId}`);
|
||||
|
||||
shopRolesSchema
|
||||
.deleteOne({ _id: shopRole._id })
|
||||
.then(async () =>
|
||||
logger.debug(`Removed ${shopRole._id} from shopRoles`)
|
||||
);
|
||||
|
||||
return await rMember?.roles
|
||||
.remove(`${shopRole.roleId}`)
|
||||
.then(async (test) => console.log("4", test))
|
||||
.catch(async (test) => console.log("5", test)); // Removes all roles
|
||||
}
|
||||
|
||||
shopRole.lastPayed = new Date();
|
||||
shopRole.save();
|
||||
userDB.credits -= pricePerHour;
|
||||
userDB.save();
|
||||
await logger.debug(
|
||||
`${shopRole.roleId} was payed one hour later. BEFORE: ${payed} AFTER: ${oneHourAfterPayed} UPDATED: ${shopRole.updatedAt} CREATED: ${shopRole.createdAt}`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await logger.debug("Checking schedules! (Every 5 minutes)");
|
||||
});
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
export default (amount: number) =>
|
||||
`${amount <= 1 ? `${amount} credit` : `${amount} credits`}`;
|
|
@ -1,9 +0,0 @@
|
|||
import mongoose from "mongoose";
|
||||
|
||||
import * as config from "../../../config.json";
|
||||
import logger from "../../handlers/logger";
|
||||
|
||||
export default async () => {
|
||||
await mongoose.connect(config.mongodb.url);
|
||||
logger.info("Connected to the database");
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
// TODO This file will make sure that all guilds always has at least one entry in all collections with "guildId"
|
||||
|
||||
import apis from "./database/models/apiSchema";
|
||||
import guilds from "./database/models/guildSchema";
|
||||
import apis from "../database/schemas/api";
|
||||
import guilds from "../database/schemas/guild";
|
||||
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
import { Guild } from "discord.js";
|
||||
|
||||
export default async (guild: Guild) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import users from "./database/models/userSchema";
|
||||
import logger from "../handlers/logger";
|
||||
import users from "../database/schemas/user";
|
||||
import logger from "../logger";
|
||||
import { Guild, User } from "discord.js";
|
||||
|
||||
export default async (user: User, guild: Guild) => {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import config from "../../config.json";
|
||||
import logger from "../handlers/logger";
|
||||
import fs from "fs";
|
||||
import { REST } from "@discordjs/rest";
|
||||
import { Routes } from "discord-api-types/v9";
|
||||
|
||||
export default async () => {
|
||||
const commands = [];
|
||||
const commandFiles = fs.readdirSync("./src/commands");
|
||||
|
||||
for (const file of commandFiles) {
|
||||
// eslint-disable-next-line global-require
|
||||
const command = require(`../commands/${file}`);
|
||||
commands.push(command.default.data.toJSON());
|
||||
}
|
||||
|
||||
const rest = new REST({ version: "9" }).setToken(config.bot.token);
|
||||
|
||||
await rest.put(Routes.applicationCommands(config.bot.clientId), {
|
||||
body: commands,
|
||||
});
|
||||
|
||||
if (config?.devMode) {
|
||||
await rest
|
||||
.put(
|
||||
Routes.applicationGuildCommands(
|
||||
config.bot.clientId,
|
||||
config.bot.guildId
|
||||
),
|
||||
{
|
||||
body: commands,
|
||||
}
|
||||
)
|
||||
.then(async () =>
|
||||
logger.info("Successfully registered application commands.")
|
||||
)
|
||||
.catch(async (err) => {
|
||||
await logger.error(err);
|
||||
});
|
||||
}
|
||||
};
|
15
src/helpers/devMode.ts
Normal file
15
src/helpers/devMode.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Dependencies
|
||||
import { Client } from "discord.js";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
// Configuration
|
||||
import { devMode, guildId } from "@config/other";
|
||||
|
||||
export default async (client: Client) => {
|
||||
if (!devMode) {
|
||||
client?.application?.commands?.set([], guildId).then(async () => {
|
||||
logger.verbose(`Removed all guild based commands from ${guildId}`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,11 +1,11 @@
|
|||
import guilds from "../helpers/database/models/guildSchema";
|
||||
import users from "../helpers/database/models/userSchema";
|
||||
import apis from "../helpers/database/models/apiSchema";
|
||||
import counters from "../helpers/database/models/counterSchema";
|
||||
import shopRoles from "../helpers/database/models/shopRolesSchema";
|
||||
import timeouts from "../helpers/database/models/timeoutSchema";
|
||||
import guilds from "../database/schemas/guild";
|
||||
import users from "../database/schemas/user";
|
||||
import apis from "../database/schemas/api";
|
||||
import counters from "../database/schemas/counter";
|
||||
import shopRoles from "../database/schemas/shopRole";
|
||||
import timeouts from "../database/schemas/timeout";
|
||||
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
|
||||
import { Guild } from "discord.js";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import users from "../helpers/database/models/userSchema";
|
||||
import users from "../database/schemas/user";
|
||||
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
|
||||
import { Guild, User } from "discord.js";
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
import { Guild } from "discord.js";
|
||||
|
||||
// Models
|
||||
import guildSchema from "./database/models/guildSchema";
|
||||
import guildSchema from "../database/schemas/guild";
|
||||
|
||||
// Handlers
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
|
||||
// Function
|
||||
export default async (guild: Guild) => {
|
||||
const guildObj = await guildSchema?.findOne({ guildId: guild.id });
|
||||
if (guildObj === null) {
|
||||
const guildObj = new guildSchema({ guildId: guild.id });
|
||||
const newGuildObj = new guildSchema({ guildId: guild.id });
|
||||
|
||||
await guildObj
|
||||
await newGuildObj
|
||||
.save()
|
||||
.then(async () => {
|
||||
logger.debug(
|
||||
|
@ -24,7 +24,7 @@ export default async (guild: Guild) => {
|
|||
logger.error(err);
|
||||
});
|
||||
|
||||
return guildObj;
|
||||
return newGuildObj;
|
||||
} else {
|
||||
return guildObj;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
|
||||
// Models
|
||||
import userSchema from "./database/models/userSchema";
|
||||
import userSchema from "../database/schemas/user";
|
||||
|
||||
// Handlers
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
|
||||
// Function
|
||||
export default async (user: User, guild: Guild) => {
|
||||
|
@ -14,12 +14,12 @@ export default async (user: User, guild: Guild) => {
|
|||
guildId: guild.id,
|
||||
});
|
||||
if (userObj === null) {
|
||||
const userObj = new userSchema({
|
||||
const newUserObj = new userSchema({
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
});
|
||||
|
||||
await userObj
|
||||
await newUserObj
|
||||
.save()
|
||||
.then(async () => {
|
||||
logger.debug(
|
||||
|
@ -30,7 +30,7 @@ export default async (user: User, guild: Guild) => {
|
|||
logger.error(err);
|
||||
});
|
||||
|
||||
return userObj;
|
||||
return newUserObj;
|
||||
} else {
|
||||
return userObj;
|
||||
}
|
||||
|
|
3
src/helpers/index.ts
Normal file
3
src/helpers/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import pluralize from "./pluralize";
|
||||
|
||||
export default { pluralize };
|
2
src/helpers/pluralize.ts
Normal file
2
src/helpers/pluralize.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export default (count: number, noun: string, suffix?: string) =>
|
||||
`${count} ${noun}${count !== 1 ? suffix || "s" : ""}`;
|
|
@ -1,5 +1,5 @@
|
|||
import sleep from "./sleep";
|
||||
import logger from "../handlers/logger";
|
||||
import logger from "../logger";
|
||||
import Chance from "chance";
|
||||
|
||||
export default async function saveUser(data: any, data2: any) {
|
||||
|
|
46
src/index.ts
46
src/index.ts
|
@ -1,28 +1,30 @@
|
|||
// Dependencies
|
||||
import "tsconfig-paths/register"; // Allows using tsconfig.json paths during runtime
|
||||
import { Client, Intents } from "discord.js"; // discord.js
|
||||
|
||||
import database from "./helpers/database";
|
||||
import events from "./handlers/events";
|
||||
import commands from "./handlers/commands";
|
||||
import locale from "./handlers/locale";
|
||||
import schedules from "./handlers/schedules";
|
||||
import locale from "@locale";
|
||||
import database from "@database";
|
||||
import schedules from "@schedules";
|
||||
|
||||
import config from "../config.json"; // config.json
|
||||
import events from "@handlers/events";
|
||||
import commands from "@handlers/commands";
|
||||
|
||||
(async () => {
|
||||
// Initialize discord.js client
|
||||
const client = new Client({
|
||||
intents: [
|
||||
Intents?.FLAGS?.GUILDS,
|
||||
Intents?.FLAGS?.GUILD_MESSAGES,
|
||||
Intents?.FLAGS?.GUILD_MEMBERS,
|
||||
],
|
||||
});
|
||||
// Configurations
|
||||
import { token } from "@config/discord";
|
||||
|
||||
await database();
|
||||
await locale();
|
||||
await events(client);
|
||||
await commands(client);
|
||||
await schedules(client);
|
||||
await client?.login(config?.bot?.token);
|
||||
})();
|
||||
const client = new Client({
|
||||
intents: [
|
||||
Intents?.FLAGS?.GUILDS,
|
||||
Intents?.FLAGS?.GUILD_MESSAGES,
|
||||
Intents?.FLAGS?.GUILD_MEMBERS,
|
||||
],
|
||||
});
|
||||
|
||||
locale();
|
||||
database();
|
||||
schedules(client);
|
||||
|
||||
commands(client);
|
||||
events(client);
|
||||
|
||||
client?.login(token);
|
||||
|
|
26
src/logger/index.ts
Normal file
26
src/logger/index.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import winston from "winston";
|
||||
import "winston-daily-rotate-file";
|
||||
|
||||
const { combine, timestamp, printf, colorize, align, json } = winston.format;
|
||||
|
||||
export default winston.createLogger({
|
||||
level: process.env.LOG_LEVEL || "silly",
|
||||
transports: [
|
||||
new winston.transports.DailyRotateFile({
|
||||
filename: "logs/combined-%DATE%.log",
|
||||
datePattern: "YYYY-MM-DD",
|
||||
maxFiles: "14d",
|
||||
format: combine(timestamp(), json()),
|
||||
}),
|
||||
new winston.transports.Console({
|
||||
format: combine(
|
||||
colorize({ all: true }),
|
||||
timestamp({
|
||||
format: "YYYY-MM-DD HH:MM:ss",
|
||||
}),
|
||||
align(),
|
||||
printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`)
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
20
src/plugins/counters/index.ts
Normal file
20
src/plugins/counters/index.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
|
||||
import modules from "@root/plugins/counters/modules";
|
||||
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("counters")
|
||||
.setDescription("Manage counters.")
|
||||
.addSubcommand(modules.view.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "view") {
|
||||
return modules.view.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
3
src/plugins/counters/modules/index.ts
Normal file
3
src/plugins/counters/modules/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import view from "./view";
|
||||
|
||||
export default { view };
|
71
src/plugins/counters/modules/view/index.ts
Normal file
71
src/plugins/counters/modules/view/index.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
import counterSchema from "@schemas/counter";
|
||||
|
||||
// Configuration
|
||||
import {
|
||||
errorColor,
|
||||
successColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("view")
|
||||
.setDescription("View a counter's count.")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The counter channel you want to view.")
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
});
|
||||
|
||||
if (counter === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:1234:] Counters (View)")
|
||||
.setDescription(`${discordChannel} is not a counting channel!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:1234:] Counters (View)")
|
||||
.setDescription(
|
||||
`${discordChannel} is currently at number ${counter?.counter}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
36
src/plugins/credits/index.ts
Normal file
36
src/plugins/credits/index.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import modules from "@root/plugins/credits/modules";
|
||||
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("credits")
|
||||
.setDescription("Manage your credits.")
|
||||
.addSubcommand(modules.balance.data)
|
||||
.addSubcommand(modules.gift.data)
|
||||
.addSubcommand(modules.top.data)
|
||||
.addSubcommand(modules.work.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "balance") {
|
||||
return modules.balance.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "gift") {
|
||||
return modules.gift.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "top") {
|
||||
return modules.top.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "work") {
|
||||
return modules.work.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
100
src/plugins/credits/modules/balance/index.ts
Normal file
100
src/plugins/credits/modules/balance/index.ts
Normal file
|
@ -0,0 +1,100 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
errorColor,
|
||||
successColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return (
|
||||
command
|
||||
.setName("balance")
|
||||
.setDescription("Check a user's balance.")
|
||||
|
||||
// User
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user whose balance you want to check.")
|
||||
)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
const discordUser = options?.getUser("user");
|
||||
|
||||
if (guild === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(`We can not find your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const userObj = await fetchUser(discordUser || user, guild);
|
||||
|
||||
if (userObj === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(
|
||||
`We can not find ${discordUser || "you"} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (userObj.credits === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(
|
||||
`We can not find credits for ${
|
||||
discordUser || "you"
|
||||
} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(
|
||||
`${discordUser || "You"} have ${pluralize(
|
||||
userObj.credits,
|
||||
"credit"
|
||||
)}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
249
src/plugins/credits/modules/gift/index.ts
Normal file
249
src/plugins/credits/modules/gift/index.ts
Normal file
|
@ -0,0 +1,249 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
errorColor,
|
||||
successColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import saveUser from "../../../../helpers/saveUser";
|
||||
import pluralize from "../../../../helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("gift")
|
||||
.setDescription("Gift someone credits from your credits.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("reason").setDescription("Your reason.")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild, client } = interaction;
|
||||
|
||||
const optionUser = options?.getUser("user");
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
const optionReason = options?.getString("reason");
|
||||
|
||||
if (guild === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We can not find your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (optionUser === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We can not find your requested user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Get fromUserDB object
|
||||
const fromUserDB = await fetchUser(user, guild);
|
||||
|
||||
// Get toUserDB object
|
||||
const toUserDB = await fetchUser(optionUser, guild);
|
||||
|
||||
if (fromUserDB === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`We can not find your requested from user in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (toUserDB === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`We can not find your requested to user in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If receiver is same as sender
|
||||
if (optionUser?.id === user?.id) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`You can not pay yourself!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`You can't gift zero or below!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If user has below gifting amount
|
||||
if (fromUserDB?.credits < optionAmount) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`You have insufficient credits. Your balance is ${fromUserDB?.credits}!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUserDB has no credits
|
||||
if (toUserDB === null) {
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`We can not find your requested to user in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Withdraw amount from fromUserDB
|
||||
fromUserDB.credits -= optionAmount;
|
||||
|
||||
// Deposit amount to toUserDB
|
||||
toUserDB.credits += optionAmount;
|
||||
|
||||
// Save users
|
||||
await saveUser(fromUserDB, toUserDB)?.then(async () => {
|
||||
// Get DM user object
|
||||
const dmUser = client?.users?.cache?.get(optionUser?.id);
|
||||
|
||||
// Send DM to user
|
||||
await dmUser
|
||||
?.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`You received ${pluralize(
|
||||
optionAmount,
|
||||
"credit"
|
||||
)} from ${user}${
|
||||
optionReason ? ` with reason: ${optionReason}` : ""
|
||||
}. Your new credits is ${pluralize(
|
||||
toUserDB?.credits,
|
||||
"credit"
|
||||
)}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
})
|
||||
.catch(async () =>
|
||||
logger.debug(`Can not send DM to user ${optionUser?.id}`)
|
||||
);
|
||||
|
||||
// Send debug message
|
||||
logger.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}`
|
||||
);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(
|
||||
`You sent ${pluralize(optionAmount, "credit")} to ${optionUser}${
|
||||
optionReason ? ` with reason: ${optionReason}` : ""
|
||||
}. Your new credits is ${pluralize(
|
||||
fromUserDB?.credits,
|
||||
"credit"
|
||||
)}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
6
src/plugins/credits/modules/index.ts
Normal file
6
src/plugins/credits/modules/index.ts
Normal 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 };
|
52
src/plugins/credits/modules/top/index.ts
Normal file
52
src/plugins/credits/modules/top/index.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Dependencies
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
import userSchema from "@schemas/user";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("top").setDescription("Check the top balance.");
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Get all users in the guild
|
||||
|
||||
const usersDB = await userSchema.find({ guildId: interaction?.guild?.id });
|
||||
|
||||
const topTen = usersDB
|
||||
|
||||
// Sort them after credits amount (ascending)
|
||||
.sort((a, b) => (a?.credits > b?.credits ? -1 : 1))
|
||||
|
||||
// Return the top 10
|
||||
.slice(0, 10);
|
||||
|
||||
// Create entry object
|
||||
const entry = (x: any, index: number) =>
|
||||
`**Top ${index + 1}** - <@${x?.userId}> ${pluralize(
|
||||
x?.credits,
|
||||
"credit"
|
||||
)}`;
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Top)")
|
||||
.setDescription(
|
||||
`Below are the top ten.
|
||||
|
||||
${topTen?.map((x, index) => entry(x, index))?.join("\n")}`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
117
src/plugins/credits/modules/work/index.ts
Normal file
117
src/plugins/credits/modules/work/index.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import Chance from "chance";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import timeoutSchema from "@schemas/timeout";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import fetchGuild from "@helpers/fetchGuild";
|
||||
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("work").setDescription("Work for credits.");
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user } = interaction;
|
||||
|
||||
// Chance module
|
||||
const chance = new Chance();
|
||||
|
||||
// Check if user has a timeout
|
||||
const isTimeout = await timeoutSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
if (guild === null) return;
|
||||
|
||||
const guildDB = await fetchGuild(guild);
|
||||
|
||||
// If user is not on timeout
|
||||
if (!isTimeout) {
|
||||
const creditsEarned = chance.integer({
|
||||
min: 0,
|
||||
max: guildDB?.credits?.workRate,
|
||||
});
|
||||
|
||||
const userDB = await fetchUser(user, guild);
|
||||
|
||||
if (userDB === null) return;
|
||||
|
||||
userDB.credits += creditsEarned;
|
||||
|
||||
await userDB?.save()?.then(async () => {
|
||||
logger?.debug(`Credits added to user: ${user?.id}`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Work)")
|
||||
.setDescription(
|
||||
`You have earned ${pluralize(creditsEarned, "credit")}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// Create a timeout for the user
|
||||
await timeoutSchema?.create({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} has not worked within the last ${
|
||||
guildDB?.credits?.workTimeout / 1000
|
||||
} seconds, work can be done`
|
||||
);
|
||||
|
||||
// When timeout is out, remove it from the database
|
||||
await timeoutSchema?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
}, guildDB?.credits?.workTimeout);
|
||||
} else {
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has worked within last day, no work can be done`
|
||||
);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Work)")
|
||||
.setDescription(
|
||||
`You have worked within the last ${
|
||||
guildDB?.credits?.workTimeout / 1000
|
||||
} seconds, you can not work now!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
29
src/plugins/manage/groups/counters/index.ts
Normal file
29
src/plugins/manage/groups/counters/index.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Dependencies
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import moduleCreate from "./modules/create";
|
||||
import moduleDelete from "./modules/delete";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("counters")
|
||||
.setDescription("Manage your guild's counters.")
|
||||
.addSubcommand(moduleCreate.data)
|
||||
.addSubcommand(moduleDelete.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "create") {
|
||||
return moduleCreate.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "delete") {
|
||||
return moduleDelete.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
100
src/plugins/manage/groups/counters/modules/create/index.ts
Normal file
100
src/plugins/manage/groups/counters/modules/create/index.ts
Normal file
|
@ -0,0 +1,100 @@
|
|||
// Dependencies
|
||||
import { MessageEmbed, CommandInteraction } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../../../database/schemas/counter";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("create")
|
||||
.setDescription("Add a counter to your guild.")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The channel you want to add a counter to.")
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("word")
|
||||
.setDescription("The word you want to count.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("start")
|
||||
.setDescription("The count that the counter will start at.")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
const countingWord = options?.getString("word");
|
||||
const startValue = options?.getNumber("start");
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
});
|
||||
|
||||
if (counter) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Create)")
|
||||
.setDescription(
|
||||
`${discordChannel} is already a counting channel, currently it's counting ${counter.word}!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
await counterSchema
|
||||
?.create({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
word: countingWord,
|
||||
counter: startValue || 0,
|
||||
})
|
||||
.then(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} added ${discordChannel?.id} as a counter using word "${countingWord}" for counting.`
|
||||
);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Create)")
|
||||
.setDescription(
|
||||
`${discordChannel} is now counting when hearing word ${countingWord} and it starts at number ${
|
||||
startValue || 0
|
||||
}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
81
src/plugins/manage/groups/counters/modules/delete/index.ts
Normal file
81
src/plugins/manage/groups/counters/modules/delete/index.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../../../database/schemas/counter";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("delete")
|
||||
.setDescription("Delete a counter from your guild.")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The channel that you want to delete a counter from.")
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
});
|
||||
|
||||
if (counter === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Delete)")
|
||||
.setDescription(`${discordChannel} is not a counting channel!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
await counterSchema
|
||||
?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
})
|
||||
?.then(async () => {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Delete)")
|
||||
.setDescription(
|
||||
`${discordChannel} is no longer an counting channel.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} removed ${discordChannel?.id} as a counter.`
|
||||
);
|
||||
},
|
||||
};
|
41
src/plugins/manage/groups/credits/index.ts
Normal file
41
src/plugins/manage/groups/credits/index.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
|
||||
// Modules
|
||||
import moduleGive from "./modules/give";
|
||||
import moduleSet from "./modules/set";
|
||||
import moduleTake from "./modules/take";
|
||||
import moduleTransfer from "./modules/transfer";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("credits")
|
||||
.setDescription("Manage guild member's credits.")
|
||||
.addSubcommand(moduleGive.data)
|
||||
.addSubcommand(moduleSet.data)
|
||||
.addSubcommand(moduleTake.data)
|
||||
.addSubcommand(moduleTransfer.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "give") {
|
||||
return moduleGive.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "set") {
|
||||
return moduleSet.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "take") {
|
||||
return moduleTake.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "transfer") {
|
||||
return moduleTransfer.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
161
src/plugins/manage/groups/credits/modules/give/index.ts
Normal file
161
src/plugins/manage/groups/credits/modules/give/index.ts
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("give")
|
||||
.setDescription("Give credits to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to pay.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will pay.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
const discordReceiver = options?.getUser("user");
|
||||
const creditAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount option is null
|
||||
if (creditAmount === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (creditAmount <= 0) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(`You can not give zero credits or below!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (discordReceiver === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(`We could not read receiver user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (guild === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(`We could not read your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const toUser = await fetchUser(discordReceiver, guild);
|
||||
|
||||
if (toUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(
|
||||
`We could not read your receiver user from our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (toUser?.credits === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(
|
||||
`We could not find credits for ${discordReceiver} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Deposit amount to toUser
|
||||
toUser.credits += creditAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} gave ${
|
||||
discordReceiver?.id
|
||||
} ${pluralize(creditAmount, "credit")}.`
|
||||
);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Give)")
|
||||
.setDescription(
|
||||
`We have given ${discordReceiver}, ${pluralize(
|
||||
creditAmount,
|
||||
"credit"
|
||||
)}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
149
src/plugins/manage/groups/credits/modules/set/index.ts
Normal file
149
src/plugins/manage/groups/credits/modules/set/index.ts
Normal file
|
@ -0,0 +1,149 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("set")
|
||||
.setDescription("Set credits to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to set credits on.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will set.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
const discordUser = options.getUser("user");
|
||||
const creditAmount = options.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (creditAmount === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (discordUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`We could not read your requested user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (guild === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`We could not read your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// toUser Information
|
||||
const toUser = await fetchUser(discordUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (toUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(
|
||||
`We could not read your requested user from our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(
|
||||
`We could not find credits for ${discordUser} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Set toUser with amount
|
||||
toUser.credits = creditAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} set ${
|
||||
discordUser?.id
|
||||
} to ${pluralize(creditAmount, "credit")}.`
|
||||
);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(
|
||||
`We have set ${discordUser} to ${pluralize(
|
||||
creditAmount,
|
||||
"credit"
|
||||
)}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
167
src/plugins/manage/groups/credits/modules/take/index.ts
Normal file
167
src/plugins/manage/groups/credits/modules/take/index.ts
Normal file
|
@ -0,0 +1,167 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("take")
|
||||
.setDescription("Take credits from a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user you want to take credits from.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will take.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
// User option
|
||||
const optionUser = options?.getUser("user");
|
||||
|
||||
// Amount option
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`We could not take zero credits or below!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (optionUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`We could not read your requested user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (guild === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`We could not read your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// toUser Information
|
||||
const toUser = await fetchUser(optionUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (toUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(
|
||||
`We could not read your requested user from our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(
|
||||
`We could not find credits for ${optionUser} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Withdraw amount from toUser
|
||||
toUser.credits -= optionAmount;
|
||||
|
||||
// Save toUser
|
||||
await toUser?.save()?.then(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} set ${
|
||||
optionUser?.id
|
||||
} to ${pluralize(optionAmount, "credit")}.`
|
||||
);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(
|
||||
`We have taken ${pluralize(
|
||||
optionAmount,
|
||||
"credit"
|
||||
)} from ${optionUser}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
222
src/plugins/manage/groups/credits/modules/transfer/index.ts
Normal file
222
src/plugins/manage/groups/credits/modules/transfer/index.ts
Normal file
|
@ -0,0 +1,222 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
import saveUser from "@helpers/saveUser";
|
||||
|
||||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("transfer")
|
||||
.setDescription("Transfer credits from a user to another user.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("from")
|
||||
.setDescription("The user you want to take credits from.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("to")
|
||||
.setDescription("The user you want to give credits to.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
.setDescription("The amount you will transfer.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, options, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const optionFromUser = options?.getUser("from");
|
||||
const optionToUser = options?.getUser("to");
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (guild === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(`We could not read your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (optionFromUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(`We could not read your requested from user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (optionToUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(`We could not read your requested to user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Get fromUser object
|
||||
const fromUser = await fetchUser(optionFromUser, guild);
|
||||
|
||||
// Get toUser object
|
||||
const toUser = await fetchUser(optionToUser, guild);
|
||||
|
||||
// If toUser does not exist
|
||||
if (fromUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(
|
||||
`We could not read your requested from user from our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (!fromUser?.credits) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(
|
||||
`We could not find credits for ${optionFromUser} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUser does not exist
|
||||
if (toUser === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(
|
||||
`We could not read your requested to user from our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUser.credits does not exist
|
||||
if (toUser?.credits === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(
|
||||
`We could not find credits for ${optionToUser} in our database!`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Withdraw amount from fromUser
|
||||
fromUser.credits -= optionAmount;
|
||||
|
||||
// Deposit amount to toUser
|
||||
toUser.credits += optionAmount;
|
||||
|
||||
// Save users
|
||||
await saveUser(fromUser, toUser)?.then(async () => {
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} transferred ${pluralize(
|
||||
optionAmount,
|
||||
"credit"
|
||||
)} from ${optionFromUser?.id} to ${optionToUser?.id}.`
|
||||
);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Transfer)")
|
||||
.setDescription(
|
||||
`We have sent ${pluralize(
|
||||
optionAmount,
|
||||
"credit"
|
||||
)} from ${optionFromUser} to ${optionToUser}.`
|
||||
)
|
||||
.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 }),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
47
src/plugins/manage/index.ts
Normal file
47
src/plugins/manage/index.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
//Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction, Permissions, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Groups
|
||||
import credits from "./groups/credits";
|
||||
import counters from "./groups/counters";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("manage")
|
||||
.setDescription("Manage your guild.")
|
||||
.addSubcommandGroup(counters.data)
|
||||
.addSubcommandGroup(credits.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
// Destructure
|
||||
const { memberPermissions, options } = interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage")
|
||||
.setDescription(`You do not have permission to manage this!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (options?.getSubcommandGroup() === "credits") {
|
||||
return credits.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommandGroup() === "counters") {
|
||||
return counters.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -6,10 +6,11 @@ import { CommandInteraction } from "discord.js";
|
|||
import view from "./modules/view";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
import logger from "../../logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("profile")
|
||||
.setDescription("Check a profile.")
|
|
@ -1,11 +1,11 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
|
@ -28,41 +28,41 @@ export default async (interaction: CommandInteraction) => {
|
|||
// Embed object
|
||||
const embed = {
|
||||
author: {
|
||||
name: `${discordUser?.username}#${discordUser?.discriminator}` as string,
|
||||
icon_url: discordUser?.displayAvatarURL() as string,
|
||||
name: `${discordUser?.username}#${discordUser?.discriminator}`,
|
||||
icon_url: discordUser?.displayAvatarURL(),
|
||||
},
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: `:dollar: Credits` as string,
|
||||
value: `${userObj?.credits || "Not found"}` as string,
|
||||
name: `:dollar: Credits`,
|
||||
value: `${userObj?.credits || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Level` as string,
|
||||
value: `${userObj?.level || "Not found"}` as string,
|
||||
name: `:squeeze_bottle: Level`,
|
||||
value: `${userObj?.level || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Points` as string,
|
||||
value: `${userObj?.points || "Not found"}` as string,
|
||||
name: `:squeeze_bottle: Points`,
|
||||
value: `${userObj?.points || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:loudspeaker: Reputation` as string,
|
||||
value: `${userObj?.reputation || "Not found"}` as string,
|
||||
name: `:loudspeaker: Reputation`,
|
||||
value: `${userObj?.reputation || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:rainbow_flag: Language` as string,
|
||||
value: `${userObj?.language || "Not found"}` as string,
|
||||
name: `:rainbow_flag: Language`,
|
||||
value: `${userObj?.language || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
|
@ -6,10 +6,11 @@ import { CommandInteraction } from "discord.js";
|
|||
import give from "./modules/give";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../handlers/logger";
|
||||
import logger from "../../logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("reputation")
|
||||
.setDescription("Give reputation.")
|
|
@ -1,15 +1,22 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, ColorResolvable } from "discord.js";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import config from "../../../../config.json";
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
import { timeout } from "@config/reputation";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../handlers/logger";
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import timeoutSchema from "../../../helpers/database/models/timeoutSchema";
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import timeoutSchema from "@schemas/timeout";
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
|
@ -42,13 +49,13 @@ export default async (interaction: CommandInteraction) => {
|
|||
if (optionTarget?.id === user?.id) {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":loudspeaker: Reputation [Give]" as string,
|
||||
description: "You can not repute yourself." as string,
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: "You can not repute yourself.",
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.error as ColorResolvable,
|
||||
color: errorColor,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -70,14 +77,13 @@ export default async (interaction: CommandInteraction) => {
|
|||
await userObj?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":loudspeaker: Reputation [Give]" as string,
|
||||
description:
|
||||
`You have given ${optionTarget} a ${optionType} reputation!` as string,
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: `You have given ${optionTarget} a ${optionType} reputation!`,
|
||||
timestamp: new Date(),
|
||||
color: config?.colors?.success as ColorResolvable,
|
||||
color: successColor,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -99,9 +105,7 @@ export default async (interaction: CommandInteraction) => {
|
|||
setTimeout(async () => {
|
||||
// send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has not repute within last ${
|
||||
config?.reputation?.timeout / 1000
|
||||
} seconds, reputation can be given`
|
||||
`Guild: ${guild?.id} User: ${user?.id} has not repute within last ${timeout} seconds, reputation can be given`
|
||||
);
|
||||
|
||||
// When timeout is out, remove it from the database
|
||||
|
@ -110,27 +114,23 @@ export default async (interaction: CommandInteraction) => {
|
|||
userId: user?.id,
|
||||
timeoutId: "2022-04-10-16-42",
|
||||
});
|
||||
}, config?.reputation?.timeout);
|
||||
}, timeout);
|
||||
} else {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":loudspeaker: Reputation [Give]" as string,
|
||||
description: `You have given reputation within the last ${
|
||||
config?.reputation?.timeout / 1000
|
||||
} seconds, you can not repute now!` as string,
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: `You have given reputation within the last ${timeout} seconds, you can not repute now!`,
|
||||
timestamp: new Date(),
|
||||
color: config.colors.error as ColorResolvable,
|
||||
color: errorColor,
|
||||
footer: {
|
||||
iconURL: config?.footer?.icon as string,
|
||||
text: config?.footer?.text as string,
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
// Log debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has repute within last ${
|
||||
config?.reputation?.timeout / 1000
|
||||
} seconds, no reputation can be given`
|
||||
`Guild: ${guild?.id} User: ${user?.id} has repute within last ${timeout} seconds, no reputation can be given`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
74
src/plugins/settings/guild/index.ts
Normal file
74
src/plugins/settings/guild/index.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Dependencies
|
||||
import { Permissions, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../logger";
|
||||
|
||||
// Modules
|
||||
import pterodactyl from "./modules/pterodactyl";
|
||||
import credits from "./modules/credits";
|
||||
import points from "./modules/points";
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("guild")
|
||||
.setDescription("Manage guild settings.")
|
||||
.addSubcommand(pterodactyl.data)
|
||||
.addSubcommand(credits.data)
|
||||
.addSubcommand(points.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { memberPermissions, options, commandName, user, guild } =
|
||||
interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":tools: Settings - Guild",
|
||||
color: errorColor,
|
||||
description: "You do not have permission to manage this!",
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon as string,
|
||||
text: footerText as string,
|
||||
},
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Module - Pterodactyl
|
||||
if (options?.getSubcommand() === "pterodactyl") {
|
||||
// Execute Module - Pterodactyl
|
||||
return pterodactyl.execute(interaction);
|
||||
}
|
||||
|
||||
// Module - Credits
|
||||
else if (options?.getSubcommand() === "credits") {
|
||||
// Execute Module - Credits
|
||||
return credits.execute(interaction);
|
||||
}
|
||||
|
||||
// Module - Points
|
||||
else if (options?.getSubcommand() === "points") {
|
||||
// Execute Module - Points
|
||||
return points.execute(interaction);
|
||||
}
|
||||
|
||||
// Send debug message
|
||||
return logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${
|
||||
user?.id
|
||||
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
|
||||
);
|
||||
},
|
||||
};
|
134
src/plugins/settings/guild/modules/credits.ts
Normal file
134
src/plugins/settings/guild/modules/credits.ts
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
//Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "@schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("credits")
|
||||
.setDescription("Credits")
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option.setName("rate").setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-rate")
|
||||
.setDescription("Maximum amount of credits on work.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-timeout")
|
||||
.setDescription("Timeout between work schedules (milliseconds).")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription("Timeout between earning credits (milliseconds).")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user, options } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
const workRate = options?.getNumber("work-rate");
|
||||
const workTimeout = options?.getNumber("work-timeout");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) return;
|
||||
|
||||
// Modify values
|
||||
guildDB.credits.status =
|
||||
status !== null ? status : guildDB?.credits?.status;
|
||||
guildDB.credits.rate = rate !== null ? rate : guildDB?.credits?.rate;
|
||||
guildDB.credits.timeout =
|
||||
timeout !== null ? timeout : guildDB?.credits?.timeout;
|
||||
guildDB.credits.workRate =
|
||||
workRate !== null ? workRate : guildDB?.credits?.workRate;
|
||||
guildDB.credits.workTimeout =
|
||||
workTimeout !== null ? workTimeout : guildDB?.credits?.workTimeout;
|
||||
guildDB.credits.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.credits?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
// Embed object
|
||||
const embed = {
|
||||
title: ":tools: Settings - Guild [Credits]",
|
||||
description: "Following settings is set!",
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status",
|
||||
value: `${guildDB?.credits?.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate",
|
||||
value: `${guildDB?.credits?.rate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Work Rate",
|
||||
value: `${guildDB?.credits?.workRate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length",
|
||||
value: `${guildDB?.credits?.minimumLength}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout",
|
||||
value: `${guildDB?.credits?.timeout}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Work Timeout",
|
||||
value: `${guildDB?.credits?.workTimeout}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user.id} has changed credit details.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
},
|
||||
};
|
107
src/plugins/settings/guild/modules/points.ts
Normal file
107
src/plugins/settings/guild/modules/points.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("points")
|
||||
.setDescription("Points")
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option.setName("rate").setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription("Timeout between earning credits (milliseconds).")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options, guild, user } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) return;
|
||||
|
||||
// Modify values
|
||||
guildDB.points.status = status !== null ? status : guildDB?.points?.status;
|
||||
guildDB.points.rate = rate !== null ? rate : guildDB?.points?.rate;
|
||||
guildDB.points.timeout =
|
||||
timeout !== null ? timeout : guildDB?.points?.timeout;
|
||||
guildDB.points.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.points?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Settings - Guild [Points]",
|
||||
description: "Following settings is set!",
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status",
|
||||
value: `${guildDB?.points?.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate",
|
||||
value: `${guildDB?.points?.rate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length",
|
||||
value: `${guildDB?.points?.minimumLength}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout",
|
||||
value: `${guildDB?.points?.timeout}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
// Send debug message
|
||||
logger?.debug(
|
||||
`Guild: ${guild?.id} User: ${user?.id} has changed credit details.`
|
||||
);
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
});
|
||||
},
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue