🔖 Version 3.0.0 released

This commit is contained in:
Axel Olausson Holtenäs 2022-03-09 21:12:57 +01:00
parent c93e090ed5
commit 99565f78a3
No known key found for this signature in database
GPG key ID: E3AE7E194AE017ED
43 changed files with 1451 additions and 466 deletions

View file

@ -1,6 +1,6 @@
{
"name": "xyter",
"version": "2.4.0",
"version": "3.0.0",
"description": "Earn credits while chatting! And more",
"main": "src/index.js",
"scripts": {
@ -31,6 +31,7 @@
"discord-api-types": "^0.27.3",
"discord.js": "^13.6.0",
"dotenv": "^16.0.0",
"i18next": "^21.6.13",
"mongoose": "^6.2.3",
"pino": "^7.0.0-rc.9",
"quick.db": "^7.1.3",

View file

@ -0,0 +1,90 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { credits } = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Admin',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
// Stop if given amount is zero or below
if (amount <= 0) {
const embed = {
title: 'Give',
description: "You can't give zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get toUser object
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
// Stop if user has zero or below credits
if (!toUser) {
const embed = {
title: 'Give',
description: 'That user has no credits, I can not give credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Increase toUser with amount
toUser.balance += amount;
// Save toUser
await toUser.save().then(async () => {
const embed = {
title: 'Give',
description: `Gave ${creditNoun(amount)} to ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} gave ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} to ${user.username}`,
);
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} gave ${user.id} ${creditNoun(amount)}.`);
});
};

View file

@ -0,0 +1,8 @@
const give = require('./give');
const set = require('./set');
const take = require('./take');
const transfer = require('./transfer');
module.exports = {
give, set, take, transfer,
};

View file

@ -0,0 +1,90 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { credits } = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Admin',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
// Stop if given amount is zero or below
if (amount <= 0) {
const embed = {
title: 'Give',
description: "You can't give zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get toUser object
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
// Stop if user has zero or below credits
if (!toUser) {
const embed = {
title: 'Set',
description: 'That user has no credits, I can not set credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Set toUser with amount
toUser.balance = amount;
// Save toUser
await toUser.save().then(async () => {
const embed = {
title: 'Set',
description: `You set ${creditNoun(amount)} on ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} set ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} on ${user.username}`,
);
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} set ${user.id} to ${creditNoun(amount)}.`);
});
};

View file

@ -0,0 +1,90 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { credits } = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Admin',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
// Stop if given amount is zero or below
if (amount <= 0) {
const embed = {
title: 'Take',
description: "You can't take zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get toUser object
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
// Stop if user has zero or below credits
if (!toUser) {
const embed = {
title: 'Take',
description: 'That user has no credits, I can not take credits from the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Decrease toUser with amount
toUser.balance -= amount;
// Save toUser
await toUser.save().then(async () => {
const embed = {
title: 'Take',
description: `You took ${creditNoun(amount)} to ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} took ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} from ${user.username}`,
);
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} took ${creditNoun(amount)} from ${user.id}.`);
});
};

View file

@ -0,0 +1,122 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { credits } = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
const saveUser = require('../../../../helpers/saveUser');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Admin',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const from = await interaction.options.getUser('from');
const to = await interaction.options.getUser('to');
const amount = await interaction.options.getInteger('amount');
// Get fromUser object
const fromUser = await credits.findOne({
userId: from.id,
guildId: interaction.member.guild.id,
});
// Get toUser object
const toUser = await credits.findOne({ userId: to.id, guildId: interaction.member.guild.id });
// Stop if fromUser has zero credits or below
if (!fromUser) {
const embed = {
title: 'Transfer',
description: 'That user has no credits, I can not transfer credits from the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Stop if toUser has zero credits or below
if (!toUser) {
const embed = {
title: 'Transfer',
description: 'That user has no credits, I can not transfer credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Stop if amount is zero or below
if (amount <= 0) {
const embed = {
title: 'Transfer failed',
description: "You can't transfer zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Decrease fromUser with amount
fromUser.balance -= amount;
// Increase toUser with amount
toUser.balance += amount;
await saveUser(fromUser, toUser).then(async () => {
const embed = {
title: 'Transfer',
description: `You sent ${creditNoun(amount)} from ${from} to ${to}.`,
color: 0x22bb33,
fields: [
{
name: `${from.username} Balance`,
value: `${fromUser.balance}`,
inline: true,
},
{
name: `${to.username} Balance`,
value: `${toUser.balance}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} transferred ${creditNoun(amount)} from ${from.id} to ${to.id}.`);
});
};

View file

@ -0,0 +1,50 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const {
give, take, set, transfer,
} = require('./addons');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Admin',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Command handler
if (interaction.options.getSubcommand() === 'give') {
// Execute give addon
await give(interaction);
} else if (interaction.options.getSubcommand() === 'take') {
// Execute take addon
await take(interaction);
} else if (interaction.options.getSubcommand() === 'set') {
// Execute set addon
await set(interaction);
} else if (interaction.options.getSubcommand() === 'transfer') {
// Execute transfer addon
await transfer(interaction);
}
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} executed /${interaction.commandName} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`);
};

View file

@ -0,0 +1,55 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { Permissions } = require('discord.js');
const credits = require('./credits');
module.exports = {
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)))),
async execute(interaction) {
if (interaction.options.getSubcommandGroup() === 'credits') {
await credits(interaction);
}
return true;
},
};

View file

@ -1,3 +1,4 @@
const i18next = require('i18next');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
@ -8,6 +9,8 @@ module.exports = async (interaction) => {
try {
const user = await interaction.options.getUser('user');
logger.debug(i18next.t('commands:credits:general:key', { count: 1 }));
await credits
// eslint-disable-next-line max-len
.findOne({
@ -17,7 +20,7 @@ module.exports = async (interaction) => {
.then(async (data) => {
if (!data) {
const embed = {
title: 'Balance',
title: `${i18next.t('commands:credits:addons:balance:embed:title')}`,
description: `${user} has no credits.`,
color: config.colors.success,
timestamp: new Date(),
@ -29,8 +32,8 @@ module.exports = async (interaction) => {
const { balance } = data;
const embed = {
title: 'Balance',
description: `${user ? `${user} has` : 'You have'} ${creditNoun(balance)}.`,
title: `${i18next.t('commands:credits:addons:balance:embed:title')}`,
description: `${user ? `${user} has` : 'You have'} ${i18next.t('commands:credits:general:credits', { count: balance })}.`,
color: config.colors.success,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },

View file

@ -1,3 +1,4 @@
const i18next = require('i18next');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
@ -18,7 +19,7 @@ module.exports = async (interaction) => {
if (user.id === interaction.user.id) {
const embed = {
title: 'Gift failed',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: "You can't pay yourself.",
color: 0xbb2124,
timestamp: new Date(),
@ -28,7 +29,7 @@ module.exports = async (interaction) => {
}
if (amount <= 0) {
const embed = {
title: 'Gift failed',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: "You can't pay zero or below.",
color: 0xbb2124,
timestamp: new Date(),
@ -38,7 +39,7 @@ module.exports = async (interaction) => {
}
if (data.balance < amount) {
const embed = {
title: 'Gift',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: `You have insufficient credits. Your balance is ${data.balance}`,
color: 0xbb2124,
timestamp: new Date(),
@ -55,7 +56,7 @@ module.exports = async (interaction) => {
if (!toUser) {
const embed = {
title: 'Gift',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: 'That user has no credits, I can not gift credits to the user',
color: config.colors.error,
timestamp: new Date(),
@ -69,7 +70,7 @@ module.exports = async (interaction) => {
await saveUser(fromUser, toUser);
const interactionEmbed = {
title: 'Gift',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: `You sent ${creditNoun(amount)} to ${user}${
reason ? ` with reason: ${reason}` : ''
}. Your new balance is ${creditNoun(fromUser.balance)}.`,
@ -78,7 +79,7 @@ module.exports = async (interaction) => {
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
const dmEmbed = {
title: 'Gift',
title: `${i18next.t('commands:credits:addons:gift:embed:title')}`,
description: `You received ${creditNoun(amount)} from ${interaction.user}${
reason ? ` with reason: ${reason}` : ''
}. Your new balance is ${creditNoun(toUser.balance)}.`,

View file

@ -1,62 +0,0 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const credits = require('../../../helpers/database/models/creditSchema');
const creditNoun = require('../../../helpers/creditNoun');
module.exports = async (interaction) => {
try {
if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Give failed',
description: 'You need to have permission to manage this guild (MANAGE_GUILD)',
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
if (amount <= 0) {
const embed = {
title: 'Give',
description: "You can't give zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
if (!toUser) {
const embed = {
title: 'Give',
description: 'That user has no credits, I can not give credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
toUser.balance += amount;
await toUser.save();
const embed = {
title: 'Give',
description: `Gave ${creditNoun(amount)} to ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} gave ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} to ${user.username}`
);
return await interaction.editReply({ embeds: [embed], ephemeral: true });
} catch (e) {
await logger.error(e);
}
return true;
};

View file

@ -1,51 +0,0 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const credits = require('../../../helpers/database/models/creditSchema');
const creditNoun = require('../../../helpers/creditNoun');
module.exports = async (interaction) => {
if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Set',
description: 'You need to have permission to manage this guild (MANAGE_GUILD)',
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
if (!toUser) {
const embed = {
title: 'Set',
description: 'That user has no credits, I can not set credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
toUser.balance = amount;
await toUser.save();
const embed = {
title: 'Set',
description: `You set ${creditNoun(amount)} on ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} set ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} on ${user.username}`,
);
return interaction.editReply({ embeds: [embed], ephemeral: true });
};

View file

@ -1,65 +0,0 @@
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const guilds = require('../../../helpers/database/models/guildSchema');
// eslint-disable-next-line consistent-return
module.exports = async (interaction) => {
try {
const status = await interaction.options.getBoolean('status');
const url = await interaction.options.getString('url');
const token = await interaction.options.getString('token');
const rate = await interaction.options.getNumber('rate');
const timeout = await interaction.options.getNumber('timeout');
const minimumLength = await interaction.options.getNumber('minimum-length');
const workRate = await interaction.options.getNumber('work-rate');
const workTimeout = await interaction.options.getNumber('work-timeout');
const guild = await guilds.findOne({ guildId: interaction.member.guild.id });
guild.credits.status = status !== null ? status : guild.credits.status;
guild.credits.url = url !== null ? url : guild.credits.url;
guild.credits.token = token !== null ? token : guild.credits.token;
guild.credits.rate = rate !== null ? rate : guild.credits.rate;
guild.credits.timeout = timeout !== null ? timeout : guild.credits.timeout;
guild.credits.workRate = workRate !== null ? workRate : guild.credits.workRate;
// eslint-disable-next-line max-len
guild.credits.workTimeout = workTimeout !== null ? workTimeout : guild.credits.workTimeout;
// eslint-disable-next-line max-len
guild.credits.minimumLength = minimumLength !== null ? minimumLength : guild.credits.minimumLength;
await guild.save();
const embed = {
title: 'Credits',
description: 'Following settings is set',
color: config.colors.success,
fields: [
{ name: 'Status', value: `${guild.credits.status}`, inline: true },
{ name: 'URL', value: `${guild.credits.url}`, inline: true },
{ name: 'Token', value: `${guild.credits.token}` },
{ name: 'Rate', value: `${guild.credits.rate}`, inline: true },
{
name: 'Minimum Length',
value: `${guild.credits.minimumLength}`,
inline: true,
},
{ name: 'Timeout', value: `${guild.credits.timeout}`, inline: true },
{
name: 'Work Rate',
value: `${guild.credits.workRate}`,
inline: true,
},
{
name: 'Work Timeout',
value: `${guild.credits.workTimeout}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
} catch (e) {
logger.error(e);
}
};

View file

@ -1,60 +0,0 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const credits = require('../../../helpers/database/models/creditSchema');
const logger = require('../../../handlers/logger');
const creditNoun = require('../../../helpers/creditNoun');
module.exports = async (interaction) => {
if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Take',
description: 'You need to have permission to manage this guild (MANAGE_GUILD)',
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
if (amount <= 0) {
const embed = {
title: 'Take',
description: "You can't take zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
const toUser = await credits.findOne({ userId: user.id, guildId: interaction.member.guild.id });
if (!toUser) {
const embed = {
title: 'Take',
description: 'That user has no credits, I can not take credits from the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
toUser.balance -= amount;
await toUser.save();
const embed = {
title: 'Take',
description: `You took ${creditNoun(amount)} to ${user}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(
`Administrator: ${interaction.user.username} took ${
amount <= 1 ? `${amount} credit` : `${amount} credits`
} from ${user.username}`,
);
return interaction.editReply({ embeds: [embed], ephemeral: true });
};

View file

@ -1,104 +0,0 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const credits = require('../../../helpers/database/models/creditSchema');
const saveUser = require('../../../helpers/saveUser');
const creditNoun = require('../../../helpers/creditNoun');
module.exports = async (interaction) => {
try {
if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Transfer failed',
description: 'You need to have permission to manage this guild (MANAGE_GUILD)',
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
const from = await interaction.options.getUser('from');
const to = await interaction.options.getUser('to');
const amount = await interaction.options.getInteger('amount');
// eslint-disable-next-line max-len
const fromUser = await credits.findOne({
userId: from.id,
guildId: interaction.member.guild.id,
});
const toUser = await credits.findOne({ userId: to.id, guildId: interaction.member.guild.id });
if (!fromUser) {
const embed = {
title: 'Transfer',
description: 'That user has no credits, I can not transfer credits from the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
if (!toUser) {
const embed = {
title: 'Transfer',
description: 'That user has no credits, I can not transfer credits to the user',
color: config.colors.error,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
if (amount <= 0) {
const embed = {
title: 'Transfer failed',
description: "You can't transfer zero or below.",
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
if (fromUser.balance < amount) {
const embed = {
title: 'Transfer',
description: `${from.username} has insufficient credits. ${from.username} balance is ${fromUser.balance}`,
color: 0xbb2124,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
fromUser.balance -= amount;
toUser.balance += amount;
await saveUser(fromUser, toUser);
const embed = {
title: 'Transfer',
description: `You sent ${creditNoun(amount)} from ${from} to ${to}.`,
color: 0x22bb33,
fields: [
{
name: `${from.username} Balance`,
value: `${fromUser.balance}`,
inline: true,
},
{
name: `${to.username} Balance`,
value: `${toUser.balance}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await logger.debug(`Gift sent from: ${interaction.user.username} to: ${to.username}`);
return await interaction.editReply({ embeds: [embed], ephemeral: true });
} catch (e) {
logger.error(e);
}
return true;
};

View file

@ -6,13 +6,8 @@ const guilds = require('../../helpers/database/models/guildSchema');
const balance = require('./addons/balance');
const gift = require('./addons/gift');
const give = require('./addons/give');
const redeem = require('./addons/redeem');
const take = require('./addons/take');
const top = require('./addons/top');
const transfer = require('./addons/transfer');
const set = require('./addons/set');
const settings = require('./addons/settings');
const work = require('./addons/work');
module.exports = {
@ -25,19 +20,6 @@ module.exports = {
data: new SlashCommandBuilder()
.setName('credits')
.setDescription('Manage your credits.')
.addSubcommand((subcommand) => subcommand
.setName('give')
.setDescription('Give credits to a user. (ADMIN)')
.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((subcommand) => subcommand
.setName('take')
.setDescription('Take credits from a user. (ADMIN)')
.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((subcommand) => subcommand
.setName('balance')
.setDescription("Check a user's balance.")
@ -56,47 +38,10 @@ module.exports = {
.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('transfer')
.setDescription('Transfer credits from a user to another user. (ADMIN)')
.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)))
.addSubcommand((subcommand) => subcommand
.setName('set')
.setDescription('Set credits on a user. (ADMIN)')
.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((subcommand) => subcommand
.setName('settings')
.setDescription('Manage credit settings. (ADMIN)')
.addBooleanOption((option) => option.setName('status').setDescription('Toggle credits.'))
.addStringOption((option) => option.setName('url').setDescription('Controlpanel.gg URL.'))
.addStringOption((option) => option.setName('token').setDescription('Controlpanel.gg token.'))
.addNumberOption((option) => option.setName('rate').setDescription('Credits rate.'))
.addNumberOption((option) => option.setName('minimum-length').setDescription('Minimum length for credits.'))
.addNumberOption((option) => option.setName('work-rate').setDescription('Work rate (rate).'))
.addNumberOption((option) => option
.setName('work-timeout')
.setDescription('Timeout between working for credits (milliseconds).'))
.addNumberOption((option) => option.setName('timeout').setDescription('Timeout between credits (milliseconds).')))
.addSubcommand((subcommand) => subcommand.setName('work').setDescription('Work for credits.')),
async execute(interaction) {
const guild = await guilds.findOne({ guildId: interaction.member.guild.id });
if (interaction.options.getSubcommand() === 'settings') {
await settings(interaction);
}
if (guild.credits.status === false && interaction.options.getSubcommand() !== 'settings') {
const embed = {
title: 'Credits',
@ -112,18 +57,10 @@ module.exports = {
await balance(interaction);
} else if (interaction.options.getSubcommand() === 'gift') {
await gift(interaction);
} else if (interaction.options.getSubcommand() === 'give') {
await give(interaction);
} else if (interaction.options.getSubcommand() === 'redeem') {
await redeem(interaction);
} else if (interaction.options.getSubcommand() === 'take') {
await take(interaction);
} else if (interaction.options.getSubcommand() === 'top') {
await top(interaction);
} else if (interaction.options.getSubcommand() === 'transfer') {
await transfer(interaction);
} else if (interaction.options.getSubcommand() === 'set') {
await set(interaction);
} else if (interaction.options.getSubcommand() === 'work') {
await work(interaction);
}

View file

@ -0,0 +1,70 @@
const i18next = require('i18next');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const { users, credits, experiences } = require('../../../helpers/database/models');
module.exports = async (interaction) => {
try {
const { member } = await interaction;
// Options
const target = await interaction.options.getUser('target');
const discordUser = await interaction.client.users.fetch(`${target ? target.id : member.id}`);
// Databases
// Fetch user from user
const user = await users.findOne(
{ userId: await discordUser.id },
);
// Fetch credit from user and guild
const experience = await experiences.findOne(
{
userId: await discordUser.id,
guildId: await member.guild.id,
},
);
// Fetch credit from user and guild
const credit = await credits.findOne(
{
userId: await discordUser.id,
guildId: await member.guild.id,
},
);
// Language variables
const notAvailableText = i18next.t('general:not_available', { lng: await user.language });
const reputationText = i18next.t('commands:profile:addons:view:embed:reputation', { lng: await user.language });
const levelText = i18next.t('commands:profile:addons:view:embed:level', { lng: await user.language });
const pointsText = i18next.t('commands:profile:addons:view:embed:points', { lng: await user.language });
const creditsText = i18next.t('commands:profile:addons:view:embed:credits', { lng: await user.language });
const languageCodeText = i18next.t('commands:profile:addons:view:embed:language_code', { lng: await user.language });
// Create embed
const embed = {
author: {
name: `${await discordUser.username}#${await discordUser.discriminator}`,
icon_url: await discordUser.displayAvatarURL(),
},
color: config.colors.success,
fields: [
{ name: `:loudspeaker: ${reputationText}`, value: `${await user.reputation || `${notAvailableText}`}`, inline: true },
{ name: `:squeeze_bottle: ${levelText}`, value: `${await experience.level || `${notAvailableText}`}`, inline: true },
{ name: `:squeeze_bottle: ${pointsText}`, value: `${await experience.points || `${notAvailableText}`}`, inline: true },
{ name: `:money_with_wings: ${creditsText}`, value: `${await credit.balance || `${notAvailableText}`}`, inline: true },
{ name: `:rainbow_flag: ${languageCodeText}`, value: `${await user.language || `${notAvailableText}`}`, inline: true },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
return await interaction.editReply({ embeds: [embed], ephemeral: true });
} catch (e) {
await logger.error(e);
}
return true;
};

View file

@ -0,0 +1,17 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const view = require('./addons/view');
module.exports = {
data: new SlashCommandBuilder()
.setName('profile')
.setDescription('Your profile.')
.addSubcommand((subcommand) => subcommand.setName('view').setDescription('View a profile.').addUserOption((option) => option.setName('target')
.setDescription('The profile you wish to view'))),
async execute(interaction) {
if (interaction.options.getSubcommand() === 'view') {
await view(interaction);
}
return true;
},
};

View file

@ -0,0 +1,59 @@
const i18next = require('i18next');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const users = require('../../../helpers/database/models/userSchema');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Get options
const target = await interaction.options.getUser('target');
const type = await interaction.options.getString('type');
// Do not allow self reputation
if (target.id === interaction.member.id) {
// Build embed
const embed = { title: 'Reputation', description: 'You can not repute yourself' };
// Send reply
return interaction.editReply({ embeds: [embed] });
}
// Get user object
const user = await users.findOne({ userId: interaction.member.id });
// Math operators depending on type of reputation
if (type === 'positive') { user.reputation += 1; }
if (type === 'negative') { user.reputation -= 1; }
// Save user
await user.save();
// Build embed
const embed = {
title: 'Reputation',
description: `You have given ${target} a ${type} reputation!`,
timestamp: new Date(),
color: config.colors.success,
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} has given ${target.id} a ${type} reputation.`);
};

View file

@ -0,0 +1,35 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { Permissions } = require('discord.js');
const logger = require('../../handlers/logger');
const give = require('./addons/give');
module.exports = {
data: new SlashCommandBuilder()
.setName('reputation')
.setDescription('Manage reputation.')
.addSubcommand((subcommand) => subcommand
.setName('give')
.setDescription('Give reputation for a user')
.addUserOption((option) => option.setName('target').setDescription('The user you want to repute.').setRequired(true))
.addStringOption((option) => option.setName('type')
.setDescription('What type of reputation you want to repute').setRequired(true)
.addChoice('Positive', 'positive')
.addChoice('Negative', 'negative'))),
async execute(interaction) {
// Destructure member
const { member } = interaction;
// Command handler
if (interaction.options.getSubcommand() === 'give') {
// Execute give addon
await give(interaction);
}
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} executed /${interaction.commandName} ${interaction.options.getSubcommand()}`);
},
};

View file

@ -0,0 +1,102 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { guilds } = require('../../../../helpers/database/models');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Settings',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const status = await interaction.options.getBoolean('status');
const rate = await interaction.options.getNumber('rate');
const timeout = await interaction.options.getNumber('timeout');
const minimumLength = await interaction.options.getNumber('minimum-length');
const workRate = await interaction.options.getNumber('work-rate');
const workTimeout = await interaction.options.getNumber('work-timeout');
// Get guild object
const guild = await guilds.findOne({ guildId: interaction.member.guild.id });
// Modify values
guild.credits.status = status !== null
? status
: guild.credits.status;
guild.credits.rate = rate !== null
? rate
: guild.credits.rate;
guild.credits.timeout = timeout !== null
? timeout
: guild.credits.timeout;
guild.credits.workRate = workRate !== null
? workRate
: guild.credits.workRate;
guild.credits.workTimeout = workTimeout !== null
? workTimeout
: guild.credits.workTimeout;
guild.credits.minimumLength = minimumLength !== null
? minimumLength
: guild.credits.minimumLength;
// Save guild
await guild.save().then(async () => {
// Build embed
const embed = {
title: 'Credits',
description: 'Following settings is set!',
color: config.colors.success,
fields: [
{ name: '🤖 Status', value: `${guild.credits.status}`, inline: true },
{ name: '📈 Rate', value: `${guild.credits.rate}`, inline: true },
{
name: '📈 Work Rate',
value: `${guild.credits.workRate}`,
inline: true,
},
{
name: '🔨 Minimum Length',
value: `${guild.credits.minimumLength}`,
inline: true,
},
{ name: '⏰ Timeout', value: `${guild.credits.timeout}`, inline: true },
{
name: '⏰ Work Timeout',
value: `${guild.credits.workTimeout}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} has changed credit details.`);
});
};

View file

@ -0,0 +1,4 @@
const pterodactyl = require('./pterodactyl');
const credits = require('./credits');
module.exports = { pterodactyl, credits };

View file

@ -0,0 +1,57 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { apis } = require('../../../../helpers/database/models');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Settings',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Get options
const url = await interaction.options.getString('url');
const token = await interaction.options.getString('token');
// Update API credentials
await apis.findOneAndUpdate(
{ guildId: member.guild.id },
{ url, token },
{ new: true, upsert: true },
).then(async () => {
// Build embed
const embed = {
title: 'Settings',
color: config.colors.success,
description: 'Pterodactyl settings is saved!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} has changed api credentials.`);
});
};

View file

@ -0,0 +1,40 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const { pterodactyl, credits } = require('./addons');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Settings',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Command handler
if (interaction.options.getSubcommand() === 'pterodactyl') {
// Execute pterodactyl addon
await pterodactyl(interaction);
} else if (interaction.options.getSubcommand() === 'credits') {
// Execute credits addon
await credits(interaction);
}
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} executed /${interaction.commandName} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`);
};

View file

@ -0,0 +1,53 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { Permissions } = require('discord.js');
const guild = require('./guild');
const user = require('./user');
module.exports = {
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).'))))
.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', 'se')))),
async execute(interaction) {
if (interaction.options.getSubcommandGroup() === 'guild') {
await guild(interaction);
} else if (interaction.options.getSubcommandGroup() === 'user') {
await user(interaction);
}
return true;
},
};

View file

@ -0,0 +1,54 @@
const { Permissions } = require('discord.js');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
// Database models
const { users } = require('../../../../helpers/database/models');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Get options
const language = await interaction.options.getString('language');
// Get user object
const user = await users.findOne({ userId: interaction.member.id });
// Modify values
user.language = language !== null ? language : user.language;
// Save guild
await user.save().then(async () => {
// Build embed
const embed = {
title: 'Appearance',
description: 'Following settings is set!',
color: config.colors.success,
fields: [
{
name: '🏳️‍🌈 Language',
value: `${user.language}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send reply
await interaction.editReply({ embeds: [embed], ephemeral: true });
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} has changed appearance settings.`);
});
};

View file

@ -0,0 +1,3 @@
const appearance = require('./appearance');
module.exports = { appearance };

View file

@ -0,0 +1,36 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const { appearance } = require('./addons');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Settings',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
await interaction.editReply({ embeds: [embed], ephemeral: true });
}
// Command handler
if (interaction.options.getSubcommand() === 'appearance') {
// Execute appearance addon
await appearance(interaction);
}
// Send debug message
await logger.debug(`Guild: ${member.guild.id} User: ${member.id} executed /${interaction.commandName} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`);
};

View file

@ -0,0 +1,30 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
module.exports = async (interaction) => {
try {
if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
const embed = {
title: 'Users failed',
description: 'You need to have permission to manage this guild (MANAGE_GUILD)',
};
return await interaction.editReply({ embeds: [embed], ephemeral: true });
}
// eslint-disable-next-line max-len
const userList = await interaction.client.users.cache.filter((user) => !user.bot);
userList.map((user) => { logger.info(user); });
// await interaction.client.guilds.cache.get(interaction.member.guild.id).then((user) => logger.info(user));
// await interaction.client.users.fetch().then(async (user) => await logger.info(`${user}`));
// // interaction.client.users.fetch().then((user) => {
// // console.log(user);
// // }).catch(console.error);
} catch {
await logger.error();
}
};

View file

@ -2,6 +2,7 @@ const { SlashCommandBuilder } = require('@discordjs/builders');
const { Permissions } = require('discord.js');
const lookup = require('./addons/lookup');
const users = require('./addons/users');
module.exports = {
permissions: new Permissions([
@ -19,10 +20,15 @@ module.exports = {
.addStringOption((option) => option
.setName('target')
.setDescription('The target you want to look up.')
.setRequired(true))),
.setRequired(true)))
.addSubcommand((subcommand) => subcommand
.setName('users')
.setDescription('Iterate all users (ADMIN)')),
async execute(interaction) {
if (interaction.options.getSubcommand() === 'lookup') {
await lookup(interaction);
} else if (interaction.options.getSubcommand() === 'users') {
await users(interaction);
}
},
};

View file

@ -3,7 +3,7 @@ const logger = require('../handlers/logger');
const guilds = require('../helpers/database/models/guildSchema');
module.exports = {
name: 'interactionCreate',
name: 'guildCreate',
async execute(guild) {
const guildExist = await guilds
.findOne({ guildId: guild.id })

View file

@ -6,53 +6,83 @@ const guilds = require('../helpers/database/models/guildSchema');
module.exports = {
name: 'interactionCreate',
async execute(interaction) {
if (!interaction.isCommand()) return;
if (interaction.isCommand()) {
const command = interaction.client.commands.get(interaction.commandName);
const command = interaction.client.commands.get(interaction.commandName);
if (!command) return;
if (!command) return;
const guildExist = await guilds.findOne({ guildId: interaction.member.guild.id });
const guildExist = await guilds.findOne({ guildId: interaction.member.guild.id });
if (!guildExist) {
await guilds.create({ guildId: interaction.member.guild.id });
}
if (!guildExist) { await guilds.create({ guildId: interaction.member.guild.id }); }
try {
await interaction.deferReply({
embeds: [
{
author: {
name: interaction.client.user.username,
icon_url: interaction.client.user.displayAvatarURL(),
url: 'https://bot.zyner.org/',
try {
await interaction.deferReply({
embeds: [
{
author: {
name: interaction.client.user.username,
icon_url: interaction.client.user.displayAvatarURL(),
url: 'https://bot.zyner.org/',
},
title: 'Check',
description: 'Please wait...',
color: config.colors.wait,
timestamp: new Date(),
},
title: 'Check',
description: 'Please wait...',
color: config.colors.wait,
timestamp: new Date(),
},
],
ephemeral: true,
});
await command.execute(interaction);
await logger.debug(`Executing command: ${interaction.commandName}`);
} catch (err) {
await logger.error(err);
await interaction.reply({
embeds: [
{
author: {
name: interaction.client.user.username,
icon_url: interaction.client.user.displayAvatarURL(),
url: 'https://bot.zyner.org/',
],
ephemeral: true,
});
await command.execute(interaction);
await logger.debug(`Executing command: ${interaction.commandName}`);
} catch (err) {
await logger.error(err);
await interaction.reply({
embeds: [
{
author: {
name: interaction.client.user.username,
icon_url: interaction.client.user.displayAvatarURL(),
url: 'https://bot.zyner.org/',
},
title: 'Error',
description: 'There was an error while executing this command!',
color: config.colors.error,
timestamp: new Date(),
},
title: 'Error',
description: 'There was an error while executing this command!',
color: config.colors.error,
timestamp: new Date(),
},
],
ephemeral: true,
});
],
ephemeral: true,
});
}
} else if (interaction.isButton()) {
const button = interaction.client.buttons.get(interaction.customId);
try {
if (!button) {
await interaction.deferReply();
await interaction.editReply({ content: `Button not exist: ${interaction.customId}` });
}
await button.execute(interaction);
await logger.debug(`Button pressed: ${interaction.customId}`);
} catch (err) {
await logger.error(err);
}
} else if (interaction.isSelectMenu()) {
const menu = interaction.client.menus.get(interaction.customId);
try {
if (!menu) {
await interaction.deferReply();
await interaction.editReply({ content: `Menu not exist: ${interaction.customId}` });
}
await menu.execute(interaction);
await logger.debug(`Menu pressed: ${interaction.customId}`);
} catch (err) {
await logger.error(err);
}
}
},
};

View file

@ -0,0 +1,20 @@
const logger = require('../handlers/logger');
const users = require('../helpers/database/models/userSchema');
module.exports = {
name: 'interactionCreate',
async execute(user) {
// const guildExist = await guilds
// .findOne({ guildId: guild.id })
// .then(logger.debug(`Found guild: ${guild.id}`))
// .catch(logger.error);
// if (!guildExist) {
// await guilds
// .create({ guildId: guild.id })
// .then(() => logger.debug(`Create guild: ${guild.id} was success`))
// .catch((e) => logger.error(e));
// }
},
};

View file

@ -1,8 +1,11 @@
const config = require('../../config.json');
const logger = require('../handlers/logger');
const users = require('../helpers/database/models/userSchema');
const guilds = require('../helpers/database/models/guildSchema');
const experiences = require('../helpers/database/models/experienceSchema');
const credits = require('../helpers/database/models/creditSchema');
const timeouts = require('../helpers/database/models/timeoutSchema');
const talkedRecently = new Set();
@ -12,9 +15,23 @@ module.exports = {
const guild = await guilds.findOne({ guildId: message.guild.id });
if (message.author.bot) return;
const userExist = await users.findOne({ userId: message.author.id });
if (!userExist) { await users.create({ userId: message.author.id }); }
if (message.content.length < guild.credits.minimumLength) return;
if (config.credits.excludedChannels.includes(message.channel.id)) return;
if (!talkedRecently.has(message.author.id)) {
const isTimeout = await timeouts.findOne(
{
guildId: message.guild.id,
userId: message.author.id,
timeoutId: 1,
},
);
if (!isTimeout) {
await credits
.findOneAndUpdate(
{ userId: message.author.id, guildId: message.guild.id },
@ -25,17 +42,43 @@ module.exports = {
.catch(async (err) => {
await logger.error(err);
});
talkedRecently.add(message.author.id);
setTimeout(() => {
logger.debug(
// Experience System
await experiences
.findOneAndUpdate(
{ userId: message.author.id, guildId: message.guild.id },
{ $inc: { points: guild.points.rate } },
{ new: true, upsert: true },
)
.then(async () => logger.debug(`Credits added to user: ${message.author.id}`))
.catch(async (err) => {
await logger.error(err);
});
await timeouts.create(
{
guildId: message.guild.id,
userId: message.author.id,
timeoutId: 1,
},
);
// talkedRecently.add(message.author.id);
setTimeout(async () => {
await logger.debug(
`User: ${message.author.id} has not talked within last ${
guild.credits.timeout / 1000
} seconds, credits can be given`,
);
talkedRecently.delete(message.author.id);
await timeouts.deleteOne({
guildId: message.guild.id,
userId: message.author.id,
timeoutId: 1,
});
// talkedRecently.delete(message.author.id);
}, guild.credits.timeout);
} else {
logger.debug(
await logger.debug(
`User: ${message.author.id} has talked within last ${
guild.credits.timeout / 1000
} seconds, no credits given`,

55
src/handlers/locale.js Normal file
View file

@ -0,0 +1,55 @@
const i18next = require('i18next');
module.exports = async () => {
await i18next.init({
lng: 'en', // if you're using a language detector, do not define the lng option
// debug: true,
fallbackLng: 'en',
resources: {
en: {
general: { not_available: 'Not Available' },
commands: {
credits: {
general: {
credits_one: '{{count}} credit',
credits_other: '{{count}} credits',
},
addons: { balance: { embed: { title: 'Credits' } }, gift: { embed: { title: 'Gift' } } },
},
profile: {
addons: {
view: {
embed: {
title: 'Profile', reputation: 'Reputation (Global)', level: 'Level (Global)', points: 'Points (Global)', credits: 'Credits (Guild)', language_code: 'Language Code (Global)',
},
},
settings: { embed: { title: 'Profile', description: 'Following settings is set', fields: { language: 'Language' } } },
},
},
},
},
sv: {
general: { not_available: 'Ej tillgängligt' },
commands: {
credits: {
general: {
credits_one: '{{count}} krona',
credits_other: '{{count}} kronor',
},
addons: { balance: { embed: { title: 'Krediter' } }, gift: { embed: { title: 'Gåva' } } },
},
profile: {
addons: {
view: {
embed: {
title: 'Profil', reputation: 'Omdöme (Globalt)', level: 'Nivå (Globalt)', points: 'Poäng (Globalt)', credits: 'Krediter (Server)', language_code: 'Språkkod (Globalt)',
},
},
settings: { embed: { title: 'Profil', description: 'Följande inställningar är satta', fields: { language: 'Språk' } } },
},
},
},
},
},
});
};

View file

@ -0,0 +1,28 @@
const mongoose = require('mongoose');
const apiSchema = new mongoose.Schema(
{
guildId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
url: {
type: mongoose.SchemaTypes.String,
required: true,
unique: false,
index: true,
},
token: {
type: mongoose.SchemaTypes.String,
required: true,
unique: false,
index: true,
},
},
{ timestamps: true },
);
module.exports = mongoose.model('api', apiSchema);

View file

@ -11,7 +11,7 @@ const creditSchema = new mongoose.Schema(
guildId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: true,
unique: false,
index: true,
},
balance: {

View file

@ -0,0 +1,35 @@
const mongoose = require('mongoose');
const experienceSchema = new mongoose.Schema(
{
userId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
guildId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
level: {
type: mongoose.SchemaTypes.Number,
required: true,
unique: false,
default: 0,
index: false,
},
points: {
type: mongoose.SchemaTypes.Number,
required: true,
unique: false,
default: 0,
index: false,
},
},
{ timestamps: true },
);
module.exports = mongoose.model('experience', experienceSchema);

View file

@ -40,8 +40,40 @@ const guildSchema = new mongoose.Schema(
default: 900000,
},
},
points: {
status: {
type: mongoose.SchemaTypes.Boolean,
default: false,
},
url: {
type: mongoose.SchemaTypes.String,
},
token: {
type: mongoose.SchemaTypes.String,
},
rate: {
type: mongoose.SchemaTypes.Number,
default: 1,
},
minimumLength: {
type: mongoose.SchemaTypes.Number,
default: 5,
},
timeout: {
type: mongoose.SchemaTypes.Number,
default: 5000,
},
workRate: {
type: mongoose.SchemaTypes.Number,
default: 15,
},
workTimeout: {
type: mongoose.SchemaTypes.Number,
default: 900000,
},
},
},
{ timestamps: true }
{ timestamps: true },
);
module.exports = mongoose.model('guild', guildSchema);

View file

@ -0,0 +1,10 @@
const credits = require('./creditSchema');
const experiences = require('./experienceSchema');
const users = require('./userSchema');
const guilds = require('./guildSchema');
const apis = require('./apiSchema');
const timeouts = require('./timeoutSchema');
module.exports = {
credits, experiences, users, guilds, apis, timeouts,
};

View file

@ -0,0 +1,22 @@
const mongoose = require('mongoose');
const timeoutSchema = new mongoose.Schema(
{
userId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
guildId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
timeoutId: { type: mongoose.SchemaTypes.Number },
},
{ timestamps: true },
);
module.exports = mongoose.model('timeout', timeoutSchema);

View file

@ -0,0 +1,20 @@
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema(
{
userId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: true,
index: true,
},
language: {
type: mongoose.SchemaTypes.String,
default: 'en',
},
reputation: { type: mongoose.SchemaTypes.Number, default: 0 },
},
{ timestamps: true },
);
module.exports = mongoose.model('user', userSchema);

View file

@ -1,6 +1,7 @@
/* eslint-disable no-restricted-syntax */
require('./deploy-commands')();
require('./helpers/database')();
require('./handlers/locale')();
const fs = require('fs');
const { Client, Collection, Intents } = require('discord.js');
@ -20,6 +21,24 @@ for (const file of commandFiles) {
client.commands.set(command.data.name, command);
}
client.buttons = new Collection();
const buttonFiles = fs.readdirSync('./src/buttons');
for (const file of buttonFiles) {
// eslint-disable-next-line import/no-dynamic-require, global-require
const button = require(`./buttons/${file}`);
client.buttons.set(button.customId, button);
}
client.menus = new Collection();
const menuFiles = fs.readdirSync('./src/menus');
for (const file of menuFiles) {
// eslint-disable-next-line import/no-dynamic-require, global-require
const menu = require(`./menus/${file}`);
client.menus.set(menu.customId, menu);
}
for (const file of eventFiles) {
// eslint-disable-next-line import/no-dynamic-require, global-require
const event = require(`./events/${file}`);