Merge pull request #23 from VermiumSifell/main

Fix guild creation and added shop roles
This commit is contained in:
Axel Olausson Holtenäs 2022-03-14 17:44:48 +01:00 committed by GitHub
commit 1724b017da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 407 additions and 21 deletions

View file

@ -14,13 +14,18 @@
"cSpell.words": [
"Controlpanel",
"discordjs",
"hoster",
"pino",
"runned",
"Timout",
"upsert",
"uuidv"
"uuidv",
"Zyner"
],
"editor.fontFamily": "Cascadia Code",
"editor.fontLigatures": true,
"git.enableCommitSigning": true
"git.enableCommitSigning": true,
"files.associations": {
"*.yaml": "home-assistant"
}
}

View file

@ -19,5 +19,9 @@
"disable": {
"redeem": false
},
"hoster": {
"name": "someone",
"url": "scheme://domain.tld"
},
"debug": false
}

View file

@ -33,6 +33,7 @@
"dotenv": "^16.0.0",
"i18next": "^21.6.13",
"mongoose": "^6.2.3",
"node-schedule": "^2.1.0",
"pino": "^7.0.0-rc.9",
"quick.db": "^7.1.3",
"uuid": "^8.3.2"

View file

@ -50,7 +50,7 @@ module.exports = async (interaction) => {
await guild.save().then(async () => {
// Create embed object
const embed = {
title: 'Credits',
title: 'Settings - Guild - Credits',
description: 'Following settings is set!',
color: config.colors.success,
fields: [

View file

@ -14,7 +14,7 @@ module.exports = async (interaction) => {
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: 'Settings',
title: 'Settings - Guild - Pterodactyl',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
@ -42,7 +42,7 @@ module.exports = async (interaction) => {
// Build embed
const embed = {
title: 'Settings',
title: 'Settings - Guild - Pterodactyl',
color: config.colors.success,
description: 'Pterodactyl settings is saved!',
timestamp: new Date(),

View file

@ -12,7 +12,7 @@ module.exports = async (interaction) => {
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: 'Settings',
title: 'Settings - Guild',
color: config.colors.error,
description: 'You do not have permission to manage this!',
timestamp: new Date(),

View file

@ -21,7 +21,7 @@ module.exports = async (interaction) => {
await user.save().then(async () => {
// Create embed object
const embed = {
title: 'Appearance',
title: 'Settings - User - Appearance',
description: 'Following settings is set!',
color: config.colors.success,
fields: [

View file

@ -12,7 +12,7 @@ module.exports = async (interaction) => {
if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: 'Settings',
title: 'Settings - User',
color: config.colors.error,
description: `You don't have permission to manage this!`,
timestamp: new Date(),

View file

@ -0,0 +1,24 @@
const { v4: uuidv4 } = require('uuid');
const axios = require('axios');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const { credits, apis } = require('../../../helpers/database/models');
const creditNoun = require('../../../helpers/creditNoun');
module.exports = async (interaction) => {
const name = interaction.options.getString('name');
guild.roles
.create({
data: {
name,
color: 'BLUE',
},
reason: `${interaction.member.id} bought from shop`,
})
.then(console.log)
.catch(console.error);
interaction.editReply({ content: 'Roles' });
};

View file

@ -4,6 +4,7 @@ const { Permissions } = require('discord.js');
const guilds = require('../../helpers/database/models/guildSchema');
const pterodactyl = require('./addons/pterodactyl');
const roles = require('./roles');
module.exports = {
data: new SlashCommandBuilder()
@ -18,6 +19,31 @@ module.exports = {
.setName('amount')
.setDescription('How much credits you want to withdraw.')
)
)
.addSubcommandGroup((group) =>
group
.setName('roles')
.setDescription('Manage custom roles.')
.addSubcommand((command) =>
command
.setName('buy')
.setDescription('Buy a custom role')
.addStringOption((option) =>
option
.setName('name')
.setDescription('Name of the role you wish to purchase.')
)
)
.addSubcommand((command) =>
command
.setName('cancel')
.setDescription('Cancel a custom role')
.addStringOption((option) =>
option
.setName('name')
.setDescription('Name of the role you wish to cancel.')
)
)
),
async execute(interaction) {
// If subcommand is pterodactyl
@ -25,5 +51,11 @@ module.exports = {
// Execute pterodactyl addon
await pterodactyl(interaction);
}
// If subcommand group is roles
else if (interaction.options.getSubcommandGroup() === 'roles') {
// Execute roles addon
await roles(interaction);
}
},
};

View file

@ -0,0 +1,53 @@
const { v4: uuidv4 } = require('uuid');
const axios = require('axios');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
const {
credits,
apis,
shopRoles,
guilds,
} = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
module.exports = async (interaction) => {
const { member } = interaction;
const name = await interaction.options.getString('name');
await interaction.guild.roles
.create({
name,
color: 'RED',
reason: `${interaction.member.id} bought from shop`,
})
.then(async (data) => {
// Get guild object
const guild = await guilds.findOne({
guildId: interaction.member.guild.id,
});
const userObject = await credits.findOne({
userId: member.id,
guildId: interaction.member.guild.id,
});
const pricePerHour = guild.shop.roles.pricePerHour;
userObject.balance -= pricePerHour;
shopRoles.create({
roleId: data.id,
userId: member.id,
guildId: member.guild.id,
pricePerHour,
lastPayed: new Date(),
});
interaction.member.roles.add(data.id);
shopRoles.find().then((data) => console.log(data));
})
.catch(console.error);
await interaction.editReply({ content: 'Roles bought' });
};

View file

@ -0,0 +1,13 @@
const { v4: uuidv4 } = require('uuid');
const axios = require('axios');
const config = require('../../../../../config.json');
const logger = require('../../../../handlers/logger');
const { credits, apis } = require('../../../../helpers/database/models');
const creditNoun = require('../../../../helpers/creditNoun');
module.exports = async (interaction) => {
const name = interaction.options.getString('name');
interaction.editReply({ content: 'Roles canceled' });
};

View file

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

View file

@ -0,0 +1,29 @@
const { Permissions } = require('discord.js');
const config = require('../../../../config.json');
const logger = require('../../../handlers/logger');
const { buy, cancel } = require('./addons');
module.exports = async (interaction) => {
// Destructure member
const { member } = interaction;
// If subcommand is buy
if (interaction.options.getSubcommand() === 'buy') {
// Execute buy addon
await buy(interaction);
}
// If subcommand is cancel
if (interaction.options.getSubcommand() === 'cancel') {
// Execute cancel addon
await cancel(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,18 @@
const config = require('../../../../config.json');
module.exports = async (interaction) => {
const interactionEmbed = {
title: ':hammer: Utilities - About',
description: `This bot is hosted by ${
config.hoster.url
? `[${config.hoster.name}](${config.hoster.url})`
: `${config.hoster.name}`
}, the bot is developed by [Zyner](https://github.com/ZynerOrg)!
If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`,
color: config.colors.success,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
interaction.editReply({ embeds: [interactionEmbed], ephemeral: true });
};

View file

@ -0,0 +1,5 @@
const lookup = require('./lookup');
const about = require('./about');
const stats = require('./stats');
module.exports = { lookup, about, stats };

View file

@ -19,7 +19,7 @@ module.exports = async (interaction) => {
if (res.data.status === 'fail') {
// Create embed object
const embed = {
title: 'Lookup',
title: ':hammer: Utilities - Lookup',
description: `${res.data.message}: ${res.data.query}`,
color: config.colors.error,
timestamp: new Date(),
@ -34,7 +34,7 @@ module.exports = async (interaction) => {
else if (res.data.status === 'success') {
// Create embed object
const embed = {
title: 'Lookup',
title: ':hammer: Utilities - Lookup',
fields: [
{ name: 'AS', value: `${res.data.as || 'Not available'}` },
{

View file

@ -0,0 +1,52 @@
const config = require('../../../../config.json');
module.exports = async (interaction) => {
let totalSeconds = interaction.client.uptime / 1000;
let days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = Math.floor(totalSeconds % 60);
let uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`;
const interactionEmbed = {
title: ':hammer: Utilities - Stats',
description: 'Below you can see a list of statistics about the bot.',
fields: [
{
name: '⏰ Latency',
value: `${Date.now() - interaction.createdTimestamp} ms`,
inline: true,
},
{
name: '⏰ API Latency',
value: `${Math.round(interaction.client.ws.ping)} ms`,
inline: true,
},
{
name: '⏰ Uptime',
value: `${uptime}`,
inline: false,
},
{
name: '📈 Guilds',
value: `${interaction.client.guilds.cache.size}`,
inline: true,
},
{
name: '📈 Users (non-unique)',
value: `${interaction.client.guilds.cache.reduce(
(acc, guild) => acc + guild.memberCount,
0
)}`,
inline: true,
},
],
color: config.colors.success,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
interaction.editReply({ embeds: [interactionEmbed], ephemeral: true });
};

View file

@ -1,6 +1,6 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const lookup = require('./addons/lookup');
const { lookup, about, stats } = require('./addons');
module.exports = {
data: new SlashCommandBuilder()
@ -20,7 +20,10 @@ module.exports = {
)
)
.addSubcommand((subcommand) =>
subcommand.setName('users').setDescription('Iterate all users (ADMIN)')
subcommand.setName('about').setDescription('About this bot!)')
)
.addSubcommand((subcommand) =>
subcommand.setName('stats').setDescription('Check bot statistics!)')
),
async execute(interaction) {
// If subcommand is lookup
@ -28,5 +31,15 @@ module.exports = {
// Execute lookup addon
await lookup(interaction);
}
// If subcommand is about
else if (interaction.options.getSubcommand() === 'about') {
// Execute about addon
await about(interaction);
}
// If subcommand is stats
else if (interaction.options.getSubcommand() === 'stats') {
// Execute stats addon
await stats(interaction);
}
},
};

View file

@ -7,7 +7,10 @@ module.exports = {
const { client } = guild;
// Create guild object if not already created
await guilds.findOne({ guildId: guild.id }, { new: true, upsert: true });
const guildExist = await guilds.findOne({ guildId: guild.id });
if (!guildExist) {
await guilds.create({ guildId: guild.id });
}
// Set client status
await client.user.setPresence({

View file

@ -0,0 +1,27 @@
const { counters } = require('../helpers/database/models');
module.exports = {
name: 'messageUpdate',
async execute(oldMessage, newMessage) {
// If message author is bot
if (newMessage.author.bot) return;
// Get counter object
const counter = await counters.findOne({
guildId: newMessage.guild.id,
channelId: newMessage.channel.id,
});
// 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}**.`
);
}
}
},
};

View file

@ -1,5 +1,6 @@
const events = require('./events');
const commands = require('./commands');
const locale = require('./locale');
const schedules = require('./schedules');
module.exports = { events, commands, locale };
module.exports = { events, commands, locale, schedules };

View file

@ -24,21 +24,21 @@ module.exports = async () => {
give: {
version01: {
embed: {
title: 'Reputation',
title: ':medal: Reputation',
description:
'You have given reputation within the last day, you can not repute now!',
},
},
version02: {
embed: {
title: 'Reputation',
title: ':medal: Reputation',
description:
'You have given {{user}} a {{type}} reputation!',
},
},
version03: {
embed: {
title: 'Reputation',
title: ':medal: Reputation',
description: 'You can not repute yourself.',
},
},
@ -86,20 +86,20 @@ module.exports = async () => {
give: {
version01: {
embed: {
title: 'Omdöme',
title: ':medal: Omdöme',
description:
'Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!',
},
},
version02: {
embed: {
title: 'Omdöme',
title: ':medal: Omdöme',
description: 'Du har gett {{user}} ett {{type}} omdöme!',
},
},
version03: {
embed: {
title: 'Omdöme',
title: ':medal: Omdöme',
description: 'Du kan inte ge dig själv ett omdöme.',
},
},

52
src/handlers/schedules.js Normal file
View file

@ -0,0 +1,52 @@
const schedule = require('node-schedule');
const { shopRoles, credits, guilds } = require('../helpers/database/models');
const logger = require('./logger');
module.exports = async (client) => {
// schedule.scheduleJob('*/1 * * *', function () {
// console.log('The answer to life, the universe, and everything!');
// });
schedule.scheduleJob('*/30 * * * *', async () => {
shopRoles.find().then(async (data) => {
data.map(async (role) => {
var payed = new Date(role.lastPayed);
oneHourAfterPayed = payed.setHours(payed.getHours() + 1);
if (new Date() > oneHourAfterPayed) {
// Get guild object
const guild = await guilds.findOne({
guildId: role.guildId,
});
const userObject = await credits.findOne({
userId: role.userId,
guildId: role.guildId,
});
const pricePerHour = guild.shop.roles.pricePerHour;
if (userObject.balance < pricePerHour) {
const rGuild = await client.guilds.cache.get(`${role.guildId}`);
let rMember = await rGuild.members.fetch(`${role.userId}`);
await rMember.roles
.remove(`${role.roleId}`)
.then(console.log)
.catch(console.error); //Removes all roles
}
role.lastPayed = new Date();
role.save();
userObject.balance -= pricePerHour;
userObject.save();
await logger.debug(
`${role.roleId} was payed one hour later. BEFORE: ${payed} AFTER: ${oneHourAfterPayed} UPDATED: ${role.updatedAt} CREATED: ${role.createdAt}`
);
}
});
});
await logger.debug('Checking schedules! (Every 30 minutes)');
});
};

View file

@ -40,6 +40,14 @@ const guildSchema = new mongoose.Schema(
default: 900000,
},
},
shop: {
roles: {
pricePerHour: {
type: mongoose.SchemaTypes.Number,
default: 5,
},
},
},
points: {
status: {
type: mongoose.SchemaTypes.Boolean,

View file

@ -5,6 +5,7 @@ const guilds = require('./guildSchema');
const apis = require('./apiSchema');
const timeouts = require('./timeoutSchema');
const counters = require('./counterSchema');
const shopRoles = require('./shopRolesSchema');
module.exports = {
credits,
@ -14,4 +15,5 @@ module.exports = {
apis,
timeouts,
counters,
shopRoles,
};

View file

@ -0,0 +1,39 @@
const mongoose = require('mongoose');
const shopRoleSchema = new mongoose.Schema(
{
roleId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
userId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
guildId: {
type: mongoose.SchemaTypes.Decimal128,
required: true,
unique: false,
index: true,
},
pricePerHour: {
type: mongoose.SchemaTypes.Number,
required: true,
unique: false,
index: true,
default: 5,
},
lastPayed: {
type: mongoose.SchemaTypes.Date,
unique: false,
index: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('shopRole', shopRoleSchema);

View file

@ -2,7 +2,7 @@
const { Client, Intents } = require('discord.js'); // discord.js
const { database } = require('./helpers'); // helpers
const { events, commands, locale } = require('./handlers'); // handlers
const { events, commands, locale, schedules } = require('./handlers'); // handlers
const config = require('../config.json'); // config.json
@ -16,6 +16,7 @@ const config = require('../config.json'); // config.json
await locale();
await events(client);
await commands(client);
await schedules(client);
await client.login(config.bot.token);
})();