Compare commits
65 commits
master
...
new-gatewa
Author | SHA1 | Date | |
---|---|---|---|
0068cde234 | |||
2347762ecc | |||
75b9d712af | |||
d97c5fa569 | |||
3ca0b4cb5c | |||
0eb76aac2b | |||
9e77c291cb | |||
fa0be297ba | |||
2b8c67b16c | |||
fd29ec5137 | |||
bec72ade6a | |||
6f4545de4c | |||
be8c4f35d7 | |||
83a9a1f65c | |||
f2aadf4953 | |||
9a8c889234 | |||
816e39df5c | |||
7acf3301ad | |||
84036ecbb5 | |||
df8e98a796 | |||
b561580c68 | |||
a477928374 | |||
e40cf2b0a7 | |||
ac811afc44 | |||
548ae6fab2 | |||
e60b506308 | |||
4025bc2aa2 | |||
5c97a6dc6a | |||
1001bc697b | |||
823c1d4de8 | |||
bd38870c44 | |||
d93d42a131 | |||
1a24f5b819 | |||
1036a253eb | |||
063fa844ab | |||
3159c72439 | |||
a51246ab16 | |||
c3490af9d0 | |||
c33e02e06d | |||
f812359b42 | |||
c7b87dc4bf | |||
56ce10d420 | |||
133625c0f6 | |||
abca96068d | |||
3b8fdb61b8 | |||
c929e8b949 | |||
fb5d8cf7b1 | |||
79cfe4c57d | |||
7038dc1c6f | |||
a2fe5d4dca | |||
a4618d9e63 | |||
1102f0f4e5 | |||
7683e56bb6 | |||
03692a6f7b | |||
a8660cfb96 | |||
9e47046c7b | |||
d1a4b2cf5c | |||
003712fe7f | |||
1f2fd34ac5 | |||
b561f80835 | |||
dfc1674bad | |||
7e623c36fd | |||
b94fc32f46 | |||
dfc1978368 | |||
acba68a2d1 |
59 changed files with 2456 additions and 3237 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,4 +3,5 @@ botconfig.json
|
|||
Lavalink.jar
|
||||
logs
|
||||
*.log
|
||||
node_modules
|
||||
node_modules
|
||||
.vscode
|
|
@ -5,15 +5,25 @@
|
|||
},
|
||||
|
||||
"Annaki": {
|
||||
"common": "Main Power Up",
|
||||
"common": "Ink Saver (Sub)",
|
||||
"uncommon": "Special Saver"
|
||||
},
|
||||
|
||||
"Barazushi": {
|
||||
"common": "Intensify Action",
|
||||
"uncommon": "Sub Power Up"
|
||||
},
|
||||
|
||||
"Cuttlegear": {
|
||||
"common": "N/A",
|
||||
"uncommon": "N/A"
|
||||
},
|
||||
|
||||
"Emberz": {
|
||||
"common": "Intensify Action",
|
||||
"uncommon": "Special Charge Up"
|
||||
},
|
||||
|
||||
"Enperry": {
|
||||
"common": "Sub Power Up",
|
||||
"uncommon": "Ink Resistance Up"
|
||||
|
@ -36,7 +46,7 @@
|
|||
|
||||
"Inkline": {
|
||||
"common": "Bomb Defence Up DX",
|
||||
"uncommon": "Main Power Up"
|
||||
"uncommon": "Intensify Action"
|
||||
},
|
||||
|
||||
"Krak-On": {
|
||||
|
@ -54,7 +64,7 @@
|
|||
"uncommon": "Special Saver"
|
||||
},
|
||||
|
||||
"Splash Mob": {
|
||||
"SplashMob": {
|
||||
"common": "Ink Saver (Main)",
|
||||
"uncommon": "Run Speed Up"
|
||||
},
|
||||
|
@ -75,7 +85,7 @@
|
|||
},
|
||||
|
||||
"ToniKensa": {
|
||||
"common": "Main Power Up",
|
||||
"common": "Ink Saver (Main)",
|
||||
"uncommon": "Sub Power Up"
|
||||
},
|
||||
|
23
bot/base/Command.js
Normal file
23
bot/base/Command.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
module.exports = class Command {
|
||||
constructor (name, category) {
|
||||
// Gateway stuff
|
||||
this.name = name,
|
||||
this.description = 'No description provided.',
|
||||
this.options = [],
|
||||
this.permissions = {
|
||||
DEFAULT_MEMBER_PERMISSIONS: 'SendMessages'
|
||||
};
|
||||
this.dm_permission = false,
|
||||
// Extra stuff Woomy uses internally
|
||||
this.category = category,
|
||||
this.usage = 'No usage information provided.',
|
||||
this.friendlyOptions = 'No options provided.',
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.cooldown = 2000;
|
||||
}
|
||||
|
||||
run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
9
bot/base/Event.js
Normal file
9
bot/base/Event.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
module.exports = class Event {
|
||||
constructor (wsEvent) {
|
||||
this.wsEvent = wsEvent;
|
||||
}
|
||||
|
||||
run (client) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,22 +1,57 @@
|
|||
module.exports = class {
|
||||
const Command = require('../../base/Command.js');
|
||||
const { version, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
|
||||
const moment = require('moment');
|
||||
require('moment-duration-format');
|
||||
|
||||
|
||||
module.exports = class About extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
this.description = 'Bot information and statistics',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const uptime = moment.duration(client.uptime).format(' D [days], H [hrs], m [mins], s [secs]');
|
||||
const bot = await interaction.guild.members.fetch(client.user.id, {force: true});
|
||||
const userCount = await client.db.countUsers();
|
||||
|
||||
let build = 'prod';
|
||||
if (client.config.developmentMode === true) {
|
||||
build = 'dev';
|
||||
}
|
||||
|
||||
const links = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setURL('https://discord.gg/HCF8mdv')
|
||||
.setLabel('Support')
|
||||
.setStyle(ButtonStyle.Link),
|
||||
new ButtonBuilder()
|
||||
.setURL('https://gitdab.com/embee/woomy')
|
||||
.setLabel('Source')
|
||||
.setStyle(ButtonStyle.Link),
|
||||
);
|
||||
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle('About me')
|
||||
.setThumbnail(client.user.avatarURL({format: 'png'}))
|
||||
.setColor(bot.displayHexColor)
|
||||
.addFields(
|
||||
{
|
||||
name: 'General',
|
||||
value: `» Users: \`${userCount}\`\n» Servers: \`${client.guilds.cache.size}\`\n» Commands: \`${client.commands.size}\`\n» Uptime: \`${uptime}\``,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Technical',
|
||||
value: `» RAM Usage: \`${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB\`\n» Woomy version: \`v${client.version} ${build}\`\n» discord.js version: \`v${version}\`\n» node.js version: \`${process.version}\``,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: 'Made in Australia'});
|
||||
|
||||
return interaction.reply({ embeds: [embed], components: [links] });
|
||||
}
|
||||
};
|
|
@ -1,95 +1,87 @@
|
|||
const prettified = require ('../../assets/categories.json');
|
||||
const Command = require('../../base/Command.js');
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Help extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'meta :P',
|
||||
arguments: '[command/category]',
|
||||
details: 'details',
|
||||
examples: 'examples'
|
||||
};
|
||||
this.description = 'Lists all the commands you can use',
|
||||
this.options = [
|
||||
{
|
||||
type: 3,
|
||||
name: 'command',
|
||||
description: 'The command to get information on'
|
||||
},
|
||||
],
|
||||
this.usage = '/help [command]',
|
||||
this.friendlyOptions = '`command` - The command to get information on',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
const commands = client.commands;
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const input = await interaction.options.get('command');
|
||||
const bot = await interaction.guild.members.fetch(client.user.id, {force: true});
|
||||
const categories = [];
|
||||
|
||||
commands.forEach(cmd => {
|
||||
client.commands.forEach(cmd => {
|
||||
if (!categories.includes(cmd.category)) {
|
||||
if (cmd.category === 'Developer' && !client.config.ownerIDs.includes(message.author.id)) return;
|
||||
if (cmd.category === 'Developer' && !client.config.devIds.includes(interaction.user.id)) return;
|
||||
categories.push(cmd.category);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!args[0]) {
|
||||
const embed = new client.MessageEmbed();
|
||||
embed.setTitle('Help & Commands');
|
||||
embed.setColor(client.functions.embedColor(message.guild));
|
||||
embed.setDescription(
|
||||
`
|
||||
» Use \`${message.prefix}help [category]\` to get basic information on all commands in the category.
|
||||
» Use \`${message.prefix}help [command]\` to get full information on a specific command.
|
||||
» [Click here](https://discord.gg/HCF8mdv) to join my Discord server if you need help, or just want to hang out!
|
||||
» [Click here](https://discord.com/oauth2/authorize?client_id=${client.user.id}&permissions=2134240503&scope=bot) to invite me to your server!
|
||||
\n**News:**
|
||||
A massive update has just been released! Lots of commands and features have been added or redone and my code has been rewritten to use lots of cool new stuff. To view the full changelog, run \`changelog\`
|
||||
`
|
||||
);
|
||||
categories.forEach(category => {
|
||||
embed.addField(`${prettified[category].emoji} ${category}`, `*${prettified[category].description}*\n${client.commands.filter(cmd => cmd.category === category).length} commands`, true);
|
||||
});
|
||||
embed.setFooter('<> = required, / = either/or, [] = optional');
|
||||
|
||||
|
||||
if (!input) {
|
||||
const fields = [];
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle('Command list')
|
||||
.setColor(bot.displayHexColor)
|
||||
.setDescription(
|
||||
`
|
||||
» Use \`/help [command]\` to get full information on a specific command.
|
||||
» [Click here](https://discord.gg/HCF8mdv) to join my support server if you need help!
|
||||
» [Click here](https://discord.com/oauth2/authorize?client_id=${client.user.id}&permissions=2134240503&scope=bot) to invite me to your server!
|
||||
`
|
||||
)
|
||||
.setFooter({text: 'Thank you for using Woomy! 🦑'});
|
||||
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
categories.forEach(cat => {
|
||||
let cmds = '`';
|
||||
const filteredCmds = client.commands.filter(cmd => cmd.category === cat);
|
||||
filteredCmds.forEach(cmd => {
|
||||
cmds += (cmd.name + '`, `');
|
||||
});
|
||||
|
||||
const cat = args[0].toProperCase();
|
||||
const cmd = args[0].toLowerCase();
|
||||
cmds = cmds.substr(0, cmds.length - 3);
|
||||
|
||||
if (categories.includes(cat)) {
|
||||
let cmds = '';
|
||||
const filteredCmds = client.commands.filter(cmd => cmd.category === cat);
|
||||
|
||||
filteredCmds.forEach(cmd => {
|
||||
let params = '';
|
||||
if (cmd.help.arguments.length > 0) params = '`' + cmd.help.arguments + '`';
|
||||
cmds += `**${message.prefix + cmd.name}** ${params} ✦ ${cmd.help.description}\n`;
|
||||
fields.push({name: cat.toProperCase() + ':', value: cmds});
|
||||
});
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(prettified[cat].emoji + ' ' + cat)
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setDescription(cmds)
|
||||
.setFooter('<> = required, / = either/or, [] = optional');
|
||||
embed.addFields(fields);
|
||||
|
||||
return interaction.reply({ embeds: [embed] });
|
||||
} else if (client.commands.has(input.value)) {
|
||||
const command = await client.commands.get(input.value);
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle(`${command.category} -> ${command.name.toProperCase()}`)
|
||||
.setColor(bot.displayHexColor)
|
||||
.setDescription(command.description)
|
||||
.setFooter({ text: '<> = required, / = either/or, [] = optional'});
|
||||
|
||||
const fields = [];
|
||||
|
||||
if (command.usage !== 'No usage information provided.') {
|
||||
fields.push({name: 'Usage:', value: command.usage});
|
||||
}
|
||||
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
if (command.friendlyOptions !== 'No options provided.') {
|
||||
fields.push({name: 'Options', value: command.friendlyOptions});
|
||||
}
|
||||
|
||||
if (client.commands.has(cmd) || client.aliases.has(cmd)) {
|
||||
const command = client.commands.get(cmd) || client.commands.get(client.aliases.get(cmd));
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(prettified[command.category].emoji + ' ' + command.category + ' -> ' + command.name.toProperCase())
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setDescription(command.help.description)
|
||||
.addField('Format:', `\`${message.prefix + command.name} ${command.help.arguments}`.trim() + '`');
|
||||
if (command.help.details.length > 0) embed.addField('Parameters:', command.help.details);
|
||||
if (command.help.examples.length > 0) embed.addField('Examples', command.help.examples);
|
||||
if (command.aliases.length > 0) embed.addField('Aliases:', '`' + command.aliases.join('`, `') + '`');
|
||||
if (command.userPerms.length > 0) embed.addField('User permissions:', command.userPerms.join(', '), true);
|
||||
if (command.botPerms.length > 0) embed.addField('Bot permissions:', command.botPerms.join(', '), true);
|
||||
embed.addField('Cooldown:', `${command.cooldown / 1000} seconds`, true);
|
||||
embed.setFooter('<> = required, / = either/or, [] = optional');
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
if (fields.length > 0) embed.addFields(fields);
|
||||
|
||||
return message.channel.send(`${client.config.emojis.userError} ${cmd} doesn't appear to be a command, alias, or category. Are you sure you spelt it right?`);
|
||||
}
|
||||
return interaction.reply({ embeds: [embed] });
|
||||
}
|
||||
return interaction.reply(`${client.config.emojis.userError} A command of that name could not be found.`);
|
||||
}
|
||||
};
|
|
@ -1,27 +1,16 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const replies = require('../../assets/replies.json');
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Ping extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Test response time between Woomy and Discord.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
this.description = 'Check response time between Woomy and Discord',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
message.channel.send(replies.ping.random())
|
||||
.then(m => {
|
||||
m.edit(`${m.content} \`roundtrip: ${m.timestamp - message.timestamp}ms | websocket: ${message.guild.shard.latency}ms\``);
|
||||
});
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const msg = await interaction.reply({ content: replies.ping.random(), fetchReply: true });
|
||||
interaction.editReply(`${msg.content} Roundtrip: \`${msg.createdTimestamp - interaction.createdTimestamp}ms\` Heartbeat: \`${client.ws.ping}ms\``);
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) {
|
||||
|
||||
}
|
||||
};
|
|
@ -1,119 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = ['administrator'],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Add, remove or list users on the blocklist for this server. User\'s on the blocklist cannot use my commands.',
|
||||
arguments: '<add | remove | list> <user>',
|
||||
details: '',
|
||||
examples: 'blocklist list\nblocklist add @Veemo\nblocklist remove emily'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, [action, ...user], data) {
|
||||
if (!action || action.toLowerCase() === 'list') {
|
||||
const list = [];
|
||||
for (const userID of data.guild.blocklist) {
|
||||
const user = await client.users.fetch(userID);
|
||||
list.push(`${user.username}#${user.discriminator}`);
|
||||
}
|
||||
|
||||
if (list.length === 0) return message.channel.send('The server blocklist is currently empty. Use `blocklist add <user>` to add people to the blocklist!');
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle('Users on blocklist: ' + data.guild.blocklist.length)
|
||||
.setDescription('```' + list.join(', ') + '```')
|
||||
.setColor(client.functions.embedColor(message.guild));
|
||||
|
||||
message.channel.send({ embeds: [embed] });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
action = action.toLowerCase();
|
||||
|
||||
if (action !== 'add' & action !== 'remove') {
|
||||
return message.channel.send(`${client.config.emojis.userError} You didn't specify a valid action. Usage: \`${this.help.usage}\``);
|
||||
}
|
||||
|
||||
if (!user) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't specify a user. Usage: \`${message.prefix + this.help.usage}\``
|
||||
);
|
||||
|
||||
let member;
|
||||
|
||||
if (message.mentions.length > 0) {
|
||||
member = await message.guild.members.fetch(message.mentions[0].id);
|
||||
} else {
|
||||
member = await client.functions.validateUserID(message.guild, user[0]);
|
||||
|
||||
if (!member) {
|
||||
member = await message.guild.searchMembers(user.join(' '), 2);
|
||||
|
||||
if (member.length === 0) return message.channel.send(
|
||||
`${client.config.emojis.userError} No users found. Check for mispellings, or ping the user instead.`
|
||||
);
|
||||
|
||||
if (member.length > 1) return message.channel.send(
|
||||
`${client.config.emojis.userError} Found more than one user, try refining your search or pinging the user instead.`
|
||||
);
|
||||
|
||||
member = member[0];
|
||||
}
|
||||
}
|
||||
|
||||
const blocklist = data.guild.blocklist;
|
||||
|
||||
if (action === 'add') {
|
||||
if (member.id === message.guild.ownerID) return message.channel.send(
|
||||
`${client.config.emojis.userError} You can't block the owner, silly!`
|
||||
);
|
||||
|
||||
if (client.functions.highestRole(member).position >= client.functions.highestRole(message.member).position && message.member.id !== message.guild.ownerID) {
|
||||
return message.channel.send(`${client.config.emojis.userError} This user has a higher role than you, you can't add them to the blocklist!`);
|
||||
}
|
||||
|
||||
if (blocklist.includes(member.id)) return message.channel.send(
|
||||
`${client.config.emojis.userError} This user is already on the blocklist, you can't add them twice!`
|
||||
);
|
||||
|
||||
blocklist.push(member.id);
|
||||
|
||||
client.db.updateGuild(message.guild.id, 'blocklist', blocklist).then(() => {
|
||||
message.channel.send(`${client.config.emojis.success} Added \`${member.username}#${member.discriminator}\` to the blocklist.`);
|
||||
}).catch(error => {
|
||||
client.logger.error('GUILD_UPDATE_ERROR', error);
|
||||
message.channel.send(`${client.config.emojis.botError} An error occured while adding this user to the blocklist, please try again! **Error:** ${error}`);
|
||||
}) ;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'remove') {
|
||||
if (client.functions.highestRole(member).position >= client.functions.highestRole(message.member).position && message.member.id !== message.guild.ownerID) {
|
||||
return message.channel.send(`${client.config.emojis.userError} This user has a higher role than you, you can't remove them to the blocklist!`);
|
||||
}
|
||||
|
||||
if (!blocklist.includes(member.id)) return message.channel.send(
|
||||
`${client.config.emojis.userError} This user isn't on the blocklist.`
|
||||
);
|
||||
|
||||
blocklist.remove(member.id);
|
||||
|
||||
client.db.updateGuild(message.guild.id, 'blocklist', blocklist).then(() => {
|
||||
message.channel.send(`${client.config.emojis.success} Removed \`${member.username}#${member.discriminator}\` from the blocklist.`);
|
||||
}).catch(error => {
|
||||
client.logger.error('GUILD_UPDATE_ERROR', error);
|
||||
message.channel.send(`${client.config.emojis.botError} An error occured while removing this user from the blocklist, please try again! **Error:** ${error}`);
|
||||
}) ;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,95 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['disabled'],
|
||||
this.userPerms = ['administrator'],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'description',
|
||||
arguments: '[command/category]',
|
||||
details: '`command/category` - choose whether to disable a command or a category.',
|
||||
examples: 'examples'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) {
|
||||
const essential = {
|
||||
categories: ['Configuration', 'Developer'],
|
||||
commands: ['help']
|
||||
};
|
||||
|
||||
if (!args[0] || args[0].toLowerCase() === 'list') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[1]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't specify what command/category to disable. Usage: \`${this.help.usage}\``
|
||||
);
|
||||
|
||||
if (args[0].toLowerCase() === 'command' || args[0].toLowerCase() === 'cmd') {
|
||||
const disabled = data.guild.disabledcommands;
|
||||
|
||||
let command;
|
||||
|
||||
if (client.commands.has(args[1])) {
|
||||
command = client.commands.get(args[1]);
|
||||
} else if (client.aliases.has(args[1])) {
|
||||
command = client.commands.get(client.aliases.get(args[1]));
|
||||
}
|
||||
|
||||
if (!command) return message.channel.send(
|
||||
`${client.config.emojis.userError} ${args[1]} isn't a command or an alias, are you sure you spelt it correctly?`
|
||||
);
|
||||
|
||||
if (essential.commands.includes(command.name) || essential.categories.includes(command.category)) {
|
||||
return message.channel.send(
|
||||
`${client.config.emojis.userError} This command is essential and cannot be disabled. Sorry!`
|
||||
);
|
||||
}
|
||||
|
||||
if (disabled.includes(command.name)) return message.channel.send(
|
||||
`${client.config.emojis.userError} This command is already disabled.`
|
||||
);
|
||||
|
||||
disabled.push(command.name);
|
||||
|
||||
await client.db.updateGuild(message.guild.id, 'disabledcommands', disabled);
|
||||
|
||||
return message.channel.send(
|
||||
`${client.config.emojis.success} Added **${args[1]}** to the list of disabled commands for this server.`
|
||||
);
|
||||
}
|
||||
|
||||
if (args[0].toLowerCase() === 'category' || args[0].toLowerCase() === 'cat') {
|
||||
const disabled = data.guild.disabledcommands;
|
||||
|
||||
let command;
|
||||
|
||||
if (client.commands.has(args[1])) {
|
||||
command = client.commands.get(args[1]);
|
||||
} else if (client.aliases.has(args[1])) {
|
||||
command = client.commands.get(client.aliases.get(args[1]));
|
||||
}
|
||||
|
||||
if (!command) return message.channel.send(
|
||||
`${client.config.emojis.userError} ${args[1]} isn't a category, are you sure you spelt it correctly?`
|
||||
);
|
||||
|
||||
if (!disabled.includes(command.name)) return message.channel.send(
|
||||
`${client.config.emojis.userError} This category isn't disabled.`
|
||||
);
|
||||
|
||||
disabled.remove(command.name);
|
||||
|
||||
await client.db.updateGuild(message.guild.id, 'disabledcommands', disabled);
|
||||
|
||||
return message.channel.send(
|
||||
`${client.config.emojis.success} Added **${args[1]}** to the list of disabled category for this server!`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 5000,
|
||||
this.help = {
|
||||
description: 'Sets your own personal prefix for woomy, that works across all the servers you\'re in!',
|
||||
arguments: '[new prefix]',
|
||||
details: '',
|
||||
examples: 'userprefix w! - sets your personal prefix to woomy'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) {
|
||||
if (!args[0]) {
|
||||
return message.channel.send(
|
||||
`Your prefix for Woomy is currently: \`${data.user.prefix}\``
|
||||
);
|
||||
}
|
||||
|
||||
await client.db.updateUser(message.author.id, 'prefix', args[0]);
|
||||
|
||||
message.channel.send(
|
||||
`${client.config.emojis.success} Your personal prefix has been set to: \`${args[0]}\``
|
||||
);
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,39 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = true,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 0,
|
||||
this.help = {
|
||||
description: 'Evalutes and executes JavaScript code.',
|
||||
arguments: '<code>',
|
||||
details: '',
|
||||
examples: 'eval this.client.deleteCapitalism()'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
const code = args.join(' ');
|
||||
try {
|
||||
const evaled = eval(code);
|
||||
const clean = await client.functions.clean(evaled);
|
||||
const MAX_CHARS = 3 + 2 + clean.length + 3;
|
||||
if (MAX_CHARS > 2000) {
|
||||
return message.channel.send(undefined, { file: Buffer.from(clean), name: 'EVAL_SUCCESS.js' });
|
||||
}
|
||||
message.channel.send(`\`\`\`js\n${clean}\n\`\`\``);
|
||||
} catch (err) {
|
||||
const e = await client.functions.clean(err);
|
||||
const MAX_CHARS = 3 + 2 + e.length + 3;
|
||||
if (MAX_CHARS > 2000) {
|
||||
return message.channel.send(undefined, { file: Buffer.from(e), name: 'EVAL_ERROR.txt' });
|
||||
}
|
||||
|
||||
message.channel.send(`\`\`\`xl\n${e}\n\`\`\``);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,24 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = true,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 0,
|
||||
this.help = {
|
||||
description: 'Reloads all commands and event modules.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: '',
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
client.commandLoader.reloadCommands();
|
||||
client.eventLoader.reloadEventModules();
|
||||
message.channel.send('All commands and event modules have been reloaded!');
|
||||
}
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
const exitQuotes = require('../../assets/exitQuotes.json');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = true,
|
||||
this.aliases = ['reboot'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 0,
|
||||
this.help = {
|
||||
description: 'Restarts Woomy.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
client.logger.success('RESTART', 'Restart command recieved. ' + exitQuotes.random());
|
||||
client.disconnect();
|
||||
client.functions.wait();
|
||||
|
||||
fetch('https://gamecp.apex.to/api/client/servers/1fc76afa-9a4d-497b-983a-a898795ab5b5/power', {
|
||||
method: 'post',
|
||||
body: JSON.stringify({ 'signal': 'restart' }),
|
||||
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${client.config.server}`, 'User-Agent': client.config.userAgent }
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,46 +1,47 @@
|
|||
module.exports = class {
|
||||
const Command = require('../../base/Command.js');
|
||||
|
||||
module.exports = class Colour extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['color'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Shows you colours that can be random, a hex code or generated from the words you type into the command.',
|
||||
arguments: '[hexcode/text]',
|
||||
details: '',
|
||||
examples: '`colour` - generates a random colour\n`colour #ee79ff` - Displays the colour of this hexcode\n`colour alpaca` - Generates a colour from the word alpaca'
|
||||
};
|
||||
this.description = 'Shows you a random colour, or a colour generated from a hex code or text.',
|
||||
this.category = category;
|
||||
this.options = [
|
||||
{
|
||||
type: 3,
|
||||
name: 'input',
|
||||
description: 'hex code/text',
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
let colour;
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const input = await interaction.options.get('input');
|
||||
let color = null;
|
||||
|
||||
if (!args[0]) {
|
||||
colour = client.functions.randomColour();
|
||||
} else if (args[0].match(/#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)) {
|
||||
colour = args[0];
|
||||
if (!input) {
|
||||
color = client.functions.randomColor();
|
||||
} else if (input.value.match(/#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)) {
|
||||
color = input.value;
|
||||
} else {
|
||||
let hash = 0;
|
||||
const string = args.join(' ');
|
||||
const string = input.value;
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
hash = string.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
colour = '#';
|
||||
color = '#';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const value = (hash >> (i * 8)) & 0xFF;
|
||||
colour += ('00' + value.toString(16)).substr(-2);
|
||||
color += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
}
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(colour)
|
||||
.setColor(colour)
|
||||
.setImage(`https://fakeimg.pl/256x256/${colour.replace('#', '')}/?text=%20`);
|
||||
|
||||
message.channel.send({ embeds: [embed] });
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle(color)
|
||||
.setColor(color)
|
||||
.setImage(`https://fakeimg.pl/256x256/${color.replace('#', '')}/?text=%20`)
|
||||
.setFooter({ text: 'Wow, thats a pretty one!'});
|
||||
|
||||
interaction.reply({embeds: [embed]});
|
||||
}
|
||||
};
|
|
@ -1,39 +1,81 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const fetch = require('node-fetch');
|
||||
const moment = require('moment');
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Garfield extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'John I require lasagna',
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Sends you a strip from the best comic ever',
|
||||
arguments: '[daily]',
|
||||
details: '',
|
||||
examples: '`garfield` - sends a random garfield comic strip\n`garfield daily` - sends the daily strip'
|
||||
};
|
||||
this.cooldown = 20000,
|
||||
this.options = [
|
||||
{
|
||||
type: 1,
|
||||
name: 'daily',
|
||||
description: 'Get the comic for the current day.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'random',
|
||||
description: 'Get a random comic.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'from',
|
||||
description: 'Get the comic for a specific date.',
|
||||
options: [
|
||||
{
|
||||
type: 3,
|
||||
name: 'date',
|
||||
description: 'The date the comic you wish to view was published, formatted like so: YYYY-MM-DD',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
let date = 'xxxx';
|
||||
if (args[0] && args[0].toLowerCase() === 'daily') date = new Date();
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
fetch('`https://garfield-comics.glitch.me/`~SRoMG/?date=' + date, { headers: { 'User-Agent': client.config.userAgent }})
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
// set to get todays comic
|
||||
let url = 'https://garfield-comics.glitch.me/~SRoMG/?date=' + new Date();
|
||||
const subCmd = interaction.options.getSubcommand();
|
||||
const bot = await interaction.guild.members.fetch(client.user.id, {force: true});
|
||||
|
||||
if (subCmd === 'from') {
|
||||
let unverifiedDate = await interaction.options.get('date').value;
|
||||
|
||||
unverifiedDate = unverifiedDate.replaceAll('.', '-');
|
||||
unverifiedDate = unverifiedDate.replaceAll('/', '-');
|
||||
|
||||
const verifiedDate = moment(unverifiedDate, 'YYYY-MM-DD', true);
|
||||
|
||||
if (verifiedDate.isValid() === false) {
|
||||
return interaction.reply({
|
||||
content: `${client.config.emojis.userError} The date you provided is not valid. Please format the date as follows: \`YYYY-MM-DD\``,
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
url = 'https://garfield-comics.glitch.me/~SRoMG/?date=' + verifiedDate;
|
||||
|
||||
} else if (subCmd === 'random') {
|
||||
url = 'https://garfield-comics.glitch.me/~SRoMG/?date=xxxx';
|
||||
}
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
fetch(url, { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(`${json.data.name} (No. ${json.data.number})`)
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setURL('https://www.mezzacotta.net/garfield/?comic=' + json.data.number)
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle(`#${json.data.number}: ${json.data.name}`)
|
||||
.setColor(bot.displayHexColor)
|
||||
.setImage(json.data.image.src);
|
||||
editMessage.edit({ embeds: [embed] });
|
||||
interaction.editReply({ embeds: [embed] });
|
||||
})
|
||||
.catch(err => {
|
||||
editMessage.edit(`${client.config.emojis.botError} An error has occurred: ${err}`);
|
||||
client.logger.error('GARFIELD_COMMAND_ERROR', `API err or err replying: ${err}`);
|
||||
return interaction.editReply(`${client.config.emojis.botError} An API error occurred, sorry! I've reported this to my developers.`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,31 +1,23 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Inspire extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'Generates a (likely terrible) inspirational quote.',
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Generates a random (and likely terrible) inspirational quote.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: null
|
||||
};
|
||||
this.cooldown = 10000;
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
try {
|
||||
fetch('http://inspirobot.me/api?generate=true', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.text())
|
||||
.then(body => editMessage.edit(body));
|
||||
} catch (err) {
|
||||
editMessage.edit(`${client.config.emojis.botError} An error has occurred: ${err}`);
|
||||
}
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
await interaction.deferReply();
|
||||
fetch('http://inspirobot.me/api?generate=true', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.text())
|
||||
.then(body => interaction.editReply(body))
|
||||
.catch(err => {
|
||||
client.logger.error('INSPIRE_COMMAND_ERROR', `API err or err replying: ${err}`);
|
||||
return interaction.editReply(`${client.config.emojis.botError} An API error occurred, sorry! I've reported this to my developers.`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,85 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Get data on a Pokemon ability.',
|
||||
arguments: '<ability>',
|
||||
details: '',
|
||||
examples: '`ability intimidate`\n`ability moxie`'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't give me an ability to look up!`
|
||||
);
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
|
||||
const query = args.join(' ').toLowerCase();
|
||||
|
||||
fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': client.config.userAgent
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getAbilityDetailsByFuzzy(ability: "${query}") {
|
||||
name
|
||||
desc
|
||||
shortDesc
|
||||
bulbapediaPage
|
||||
serebiiPage
|
||||
smogonPage
|
||||
isFieldAbility
|
||||
}
|
||||
}
|
||||
`})
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.startsWith('Failed to get data for ability')) {
|
||||
editMessage.edit(
|
||||
`${client.config.emojis.userError} I couldn't find any abilities with names similar to ${query}. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('POKEMON_API_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const ability = json.data.getAbilityDetailsByFuzzy;
|
||||
|
||||
let fieldEffects = '';
|
||||
if (ability.isFieldAbility) {
|
||||
fieldEffects = ` Outside of battle, ${ability.isFieldAbility}`;
|
||||
}
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setTitle(ability.name.toProperCase());
|
||||
if (ability.desc) {
|
||||
embed.setDescription(ability.desc + fieldEffects);
|
||||
} else {
|
||||
embed.setDescription(ability.shortDesc + fieldEffects);
|
||||
}
|
||||
embed.addField('External Resources:', `[Bulbapedia](${ability.bulbapediaPage}) • [Serebii](${ability.serebiiPage}) • [Smogon](${ability.smogonPage})`);
|
||||
editMessage.edit({ content: null, embeds: [embed] });
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,140 +0,0 @@
|
|||
const { typeArray, colours } = require('../../assets/pokemon.json');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['type', 'typematchup'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 5000,
|
||||
this.help = {
|
||||
description: 'Get the strengths and weaknesses of a pokemon type/type combination',
|
||||
arguments: '<pokemon/type> [type2]',
|
||||
details: 'The type2 argument is only needed if you are submitting two types, not a pokemon or singular type.',
|
||||
examples: '`effective ghost dragon`\n`effective ribombee`'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't give me a pokemon or type combination to look up! Usage: \`${message.prefix + this.name + ' ' + this.help.arguments}\``
|
||||
);
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
|
||||
let types;
|
||||
|
||||
if (!typeArray.includes(args[0].toProperCase())) {
|
||||
const res = await fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': client.config.userAgent
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getPokemonDetailsByFuzzy(pokemon: "${args.join(' ').toLowerCase()}") {
|
||||
types
|
||||
}
|
||||
}
|
||||
`})
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.startsWith('No Pokémon found')) {
|
||||
message.channel.send(
|
||||
`${client.config.emojis.userError} I couldn't find any Pokemon with names similar to ${args.join(' ').toLowerCase()}. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('MATCHUP_API_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
types = json.data.getPokemonDetailsByFuzzy.types.map(type => type.toLowerCase());
|
||||
} else {
|
||||
types = args.map(type => type.toLowerCase());
|
||||
}
|
||||
|
||||
fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getTypeMatchup(types: [${types.join(', ')}]) {
|
||||
attacking { doubleEffectiveTypes effectiveTypes normalTypes resistedTypes doubleResistedTypes effectlessTypes }
|
||||
defending { doubleEffectiveTypes effectiveTypes normalTypes resistedTypes doubleResistedTypes effectlessTypes }
|
||||
}
|
||||
}
|
||||
`})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.includes('does not exist in "Types')) {
|
||||
message.channel.send(
|
||||
`${client.config.emojis.userError} One or more of the types you gave me are invalid. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('MATCHUP_FETCH_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const typeMatchup = json.data.getTypeMatchup;
|
||||
|
||||
let effectless = '';
|
||||
if (typeMatchup.attacking.effectlessTypes.length > 0) effectless = `
|
||||
**Doesn't effect:**
|
||||
${typeMatchup.attacking.effectlessTypes.map(type => `\`${type.toProperCase()}\``).join(' ')}
|
||||
`;
|
||||
|
||||
let immune = '';
|
||||
if (typeMatchup.defending.effectlessTypes.length > 0) immune = `
|
||||
**Immunities:**
|
||||
${typeMatchup.defending.effectlessTypes.map(type => `\`${type.toProperCase()}\``).join(' ')}
|
||||
`;
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(colours[types[0].toProperCase()])
|
||||
.setTitle('Type effectiveness of ' + types.map(type => type.toProperCase()).join(' and '))
|
||||
.addField('Offensive:', `
|
||||
**Super-effective:**
|
||||
${this.parseEffectiveTypes(typeMatchup.attacking.effectiveTypes, typeMatchup.attacking.doubleEffectiveTypes)}
|
||||
**Not very effective:**
|
||||
${this.parseResistedTypes(typeMatchup.attacking.resistedTypes, typeMatchup.attacking.doubleResistedTypes)}${effectless}
|
||||
`)
|
||||
.addField('Defensive:', `
|
||||
**Weaknesses:**
|
||||
${this.parseEffectiveTypes(typeMatchup.defending.effectiveTypes, typeMatchup.defending.doubleEffectiveTypes)}
|
||||
**Resistances:**
|
||||
${this.parseResistedTypes(typeMatchup.defending.resistedTypes, typeMatchup.defending.doubleResistedTypes)}${immune}
|
||||
`);
|
||||
editMessage.edit({ content: null, embeds: [embed] });
|
||||
});
|
||||
}
|
||||
|
||||
parseEffectiveTypes (effective, doubleEffective) {
|
||||
return doubleEffective
|
||||
.map(type => `\`${type.toProperCase()} (x4)\``)
|
||||
.concat(effective.map(type => `\`${type.toProperCase()} (x2)\``))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
parseResistedTypes (resisted, doubleResisted) {
|
||||
return doubleResisted
|
||||
.map(type => `\`${type.toProperCase()} (x0.25)\``)
|
||||
.concat(resisted.map(type => `\`${type.toProperCase()} (x0.5)\``))
|
||||
.join(' ');
|
||||
}
|
||||
};
|
|
@ -1,82 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Gets information on a held item.',
|
||||
arguments: '<item>',
|
||||
details: '',
|
||||
examples: 'item life orb\nitem griseous orb'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't give me an item to look up!`
|
||||
);
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
|
||||
const query = args.join(' ').toLowerCase();
|
||||
|
||||
fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': client.config.userAgent
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getItemDetailsByFuzzy(item: "${query}") {
|
||||
name
|
||||
desc
|
||||
shortDesc
|
||||
sprite
|
||||
generationIntroduced
|
||||
bulbapediaPage
|
||||
serebiiPage
|
||||
smogonPage
|
||||
}
|
||||
}
|
||||
`})
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.startsWith('Failed to get data for item')) {
|
||||
message.channel.send(
|
||||
`${client.config.emojis.userError} I couldn't find any items with names similar to ${query}. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('POKEMON_API_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const item = json.data.getItemDetailsByFuzzy;
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setTitle(item.name)
|
||||
.setThumbnail(item.sprite)
|
||||
.addField('External Resources:', `[Bulbapedia](${item.bulbapediaPage}) • [Serebii](${item.serebiiPage}) • [Smogon](${item.smogonPage})`);
|
||||
if (item.desc) {
|
||||
embed.setDescription(`${item.desc} Added in Generation ${item.generationIntroduced}.`);
|
||||
} else {
|
||||
embed.setDescription(`${item.shortDesc} Added in Generation ${item.generationIntroduced}.`);
|
||||
}
|
||||
editMessage.edit({ content: null, embeds: [embed] });
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,119 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
const { colours } = require('../../assets/pokemon.json');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Gets information on a pokemon move.',
|
||||
arguments: '<move>',
|
||||
details: '',
|
||||
examples: `${this.name} roar of time\n${this.name} shadow ball`
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't give me a pokemon move to look up!`
|
||||
);
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
|
||||
const query = args.join(' ').toLowerCase();
|
||||
|
||||
fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': client.config.userAgent
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getMoveDetailsByFuzzy(move: "${query}") {
|
||||
name
|
||||
desc
|
||||
shortDesc
|
||||
type
|
||||
basePower
|
||||
zMovePower
|
||||
maxMovePower
|
||||
pp
|
||||
category
|
||||
accuracy
|
||||
priority
|
||||
target
|
||||
isZ
|
||||
isGMax
|
||||
contestType
|
||||
bulbapediaPage
|
||||
serebiiPage
|
||||
smogonPage
|
||||
isFieldMove
|
||||
}
|
||||
}
|
||||
`})
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.startsWith('Failed to get data for move')) {
|
||||
message.channel.send(
|
||||
`${client.config.emojis.userError} I couldn't find any moves with names similar to ${query}. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('POKEMON_API_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const move = json.data.getMoveDetailsByFuzzy;
|
||||
|
||||
let suffix = '';
|
||||
|
||||
if (move.isZ) {
|
||||
suffix = ' (Z-Move)';
|
||||
} else if (!move.maxMovePower && move.basePower > 0) {
|
||||
suffix = ' (Max Move)';
|
||||
} else if (move.isGMax) {
|
||||
suffix = ' (G-Max Move)';
|
||||
}
|
||||
|
||||
let fieldEffects = '';
|
||||
if (move.isFieldMove) fieldEffects = ' Outside of battle, ' + move.isFieldMove;
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(colours[move.type])
|
||||
.setTitle(move.name.toProperCase() + suffix);
|
||||
if (move.desc) {
|
||||
embed.setDescription(move.desc + fieldEffects);
|
||||
} else {
|
||||
embed.setDescription(move.shortDesc + fieldEffects);
|
||||
}
|
||||
|
||||
embed.addField('Type:', move.type, true);
|
||||
embed.addField('Category:', move.category, true);
|
||||
embed.addField('Target:', move.target, true);
|
||||
if (!move.isZ || move.maxMovePower) embed.addField('Base Power:', move.basePower.toString(), true);
|
||||
if (!move.isZ || move.maxMovePower) embed.addField('Z Power:', move.zMovePower.toString(), true);
|
||||
if (move.maxMovePower) embed.addField('Max Power:', move.maxMovePower.toString(), true);
|
||||
if (!move.isZ) embed.addField('Base PP:', move.pp.toString(), true);
|
||||
embed.addField('Accuracy:', move.accuracy.toString(), true);
|
||||
embed.addField('Priority:', move.priority.toString(), true);
|
||||
if (move.isZ) embed.addField('Z-Crystal:', move.isZ, true);
|
||||
if (move.isGMax) embed.addField('G-Max Pokemon:', move.isGMax, true);
|
||||
if (move.contestType !== null) embed.addField('Contest Type', move.contestType, true);
|
||||
embed.addField('External Resources:', `[Bulbapedia](${move.bulbapediaPage}) • [Serebii](${move.serebiiPage}) • [Smogon](${move.smogonPage})`);
|
||||
editMessage.edit({ content: null, embeds: [embed] });
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,180 +0,0 @@
|
|||
const { colours } = require('../../assets/pokemon.json');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['pokedex', 'dex'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 5000,
|
||||
this.help = {
|
||||
description: 'Get useful data on any pokemon you ask me to!',
|
||||
arguments: '<pokemon>',
|
||||
details: '',
|
||||
examples: '`pokemon mudkip`\n`pokemon alolan ninetales`'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return message.channel.send(
|
||||
`${client.config.emojis.userError} You didn't give me a pokemon to look up!`
|
||||
);
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
|
||||
const query = args.join(' ').toLowerCase();
|
||||
|
||||
fetch('https://graphqlpokemon.favware.tech/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': client.config.userAgent
|
||||
},
|
||||
body: JSON.stringify({ query: `
|
||||
{
|
||||
getPokemonDetailsByFuzzy(pokemon: "${query}" reverse: true) {
|
||||
num
|
||||
species
|
||||
types
|
||||
abilities { first second hidden special }
|
||||
baseStats { hp attack defense specialattack specialdefense speed }
|
||||
eggGroups
|
||||
evolutionLevel
|
||||
evolutions { species evolutionLevel evolutions { species evolutionLevel } }
|
||||
preevolutions { species evolutionLevel preevolutions { species evolutionLevel } }
|
||||
gender { male female }
|
||||
height
|
||||
weight
|
||||
otherFormes
|
||||
cosmeticFormes
|
||||
baseStatsTotal
|
||||
flavorTexts { game flavor }
|
||||
sprite
|
||||
shinySprite
|
||||
smogonTier
|
||||
bulbapediaPage
|
||||
serebiiPage
|
||||
smogonPage
|
||||
}
|
||||
}
|
||||
`})
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
if (json.errors) {
|
||||
json.errors.forEach(error => {
|
||||
if (error.message.startsWith('No Pokémon found')) {
|
||||
message.channel.send(
|
||||
`${client.config.emojis.userError} I couldn't find any Pokemon with names similar to ${query}. Check your spelling, maybe?`
|
||||
);
|
||||
} else {
|
||||
client.logger.error('POKEMON_API_ERROR', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const pokemon = json.data.getPokemonDetailsByFuzzy;
|
||||
const evoChain = this.parseEvoChain(pokemon);
|
||||
const genderRatio = this.parseGenderRatio(pokemon.gender);
|
||||
const abilities = this.parseAbilities(pokemon.abilities);
|
||||
let sprite = pokemon.sprite;
|
||||
if (Math.floor((Math.random() * 100) + 1) === 69) sprite = pokemon.shinySprite;
|
||||
let formes;
|
||||
if (pokemon.otherFormes) {
|
||||
formes = pokemon.otherFormes.join(', ');
|
||||
if (pokemon.cosmeticFormes) {
|
||||
formes = formes.split().concat(pokemon.cosmeticFormes);
|
||||
}
|
||||
}
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(colours[pokemon.types[0]])
|
||||
.setTitle(`${pokemon.species.toProperCase()} (No. ${pokemon.num})`)
|
||||
.setDescription(pokemon.flavorTexts[0].flavor)
|
||||
.setThumbnail(sprite)
|
||||
.addField('Types:', pokemon.types.join(', '), true)
|
||||
.addField('Abilities:', abilities.join(', '), true)
|
||||
.addField('Gender Ratio:', genderRatio, true)
|
||||
.addField('Base Stats:', `HP: ${pokemon.baseStats.hp} Atk: ${pokemon.baseStats.attack} Def: ${pokemon.baseStats.defense} SpA: ${pokemon.baseStats.specialattack} SpD: ${pokemon.baseStats.specialdefense} Spe: ${pokemon.baseStats.speed} BST: ${pokemon.baseStatsTotal}`);
|
||||
if (evoChain) embed.addField('Evolution Chain:', evoChain);
|
||||
if (formes) embed.addField('Other Formes:', formes);
|
||||
embed.addField('Height:', `${pokemon.height}m`, true);
|
||||
embed.addField('Weight:', `${pokemon.weight}kg`, true);
|
||||
embed.addField('Egg Groups:', pokemon.eggGroups.join(', '), true);
|
||||
embed.addField('Smogon Tier:', pokemon.smogonTier, true);
|
||||
embed.addField('External Resources:', `[Bulbapedia](${pokemon.bulbapediaPage}) • [Serebii](${pokemon.serebiiPage}) • [Smogon](${pokemon.smogonPage})`);
|
||||
editMessage.edit({ content: null, embeds: [embed] });
|
||||
});
|
||||
}
|
||||
|
||||
constructEvoLink (species, level, evoChain, isEvo = true) {
|
||||
if (isEvo) {
|
||||
return `${evoChain} → \`${species.toProperCase()}\` ${level ? `(${level})` : ''}`;
|
||||
}
|
||||
return `\`${species.toProperCase()}\` ${level ? `(${level})` : ''} → ${evoChain}`;
|
||||
}
|
||||
|
||||
parseEvoChain (pokeDetails) {
|
||||
// Set evochain if there are no evolutions
|
||||
let evoChain = `**${pokeDetails.species.toProperCase()} ${pokeDetails.evolutionLevel ? `(${pokeDetails.evolutionLevel})` : ''}**`;
|
||||
if (!pokeDetails.evolutions && !pokeDetails.preevolutions) {
|
||||
evoChain = null;
|
||||
}
|
||||
|
||||
// Parse pre-evolutions and add to evochain
|
||||
if (pokeDetails.preevolutions) {
|
||||
const { evolutionLevel } = pokeDetails.preevolutions[0];
|
||||
evoChain = this.constructEvoLink(pokeDetails.preevolutions[0].species, evolutionLevel, evoChain, false);
|
||||
|
||||
// If the direct pre-evolution has another pre-evolution (charizard -> charmeleon -> charmander)
|
||||
if (pokeDetails.preevolutions[0].preevolutions) {
|
||||
evoChain = this.constructEvoLink(pokeDetails.preevolutions[0].preevolutions[0].species, null, evoChain, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse evolution chain and add to evochain
|
||||
if (pokeDetails.evolutions) {
|
||||
evoChain = this.constructEvoLink(pokeDetails.evolutions[0].species, pokeDetails.evolutions[0].evolutionLevel, evoChain);
|
||||
|
||||
// In case there are multiple evolutionary paths
|
||||
const otherFormeEvos = pokeDetails.evolutions.slice(1);
|
||||
if (otherFormeEvos) {
|
||||
evoChain = `${evoChain}, ${otherFormeEvos.map((oevo) => `\`${oevo.species}\` (${oevo.evolutionLevel})`).join(', ')}`;
|
||||
}
|
||||
|
||||
// If the direct evolution has another evolution (charmander -> charmeleon -> charizard)
|
||||
if (pokeDetails.evolutions[0].evolutions) {
|
||||
evoChain = this.constructEvoLink(
|
||||
pokeDetails.evolutions[0].evolutions[0].species,
|
||||
pokeDetails.evolutions[0].evolutions[0].evolutionLevel,
|
||||
evoChain
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return evoChain;
|
||||
}
|
||||
|
||||
parseGenderRatio (genderRatio) {
|
||||
if (genderRatio.male === '0%' && genderRatio.female === '0%') {
|
||||
return 'Genderless';
|
||||
}
|
||||
|
||||
return `${genderRatio.male} ♂ | ${genderRatio.female} ♀`;
|
||||
}
|
||||
|
||||
parseAbilities (abilitiesData) {
|
||||
const abilities = [];
|
||||
for (const [type, ability] of Object.entries(abilitiesData)) {
|
||||
if (!ability) continue;
|
||||
abilities.push(type === 'hidden' ? `*${ability}*` : ability);
|
||||
}
|
||||
|
||||
return abilities;
|
||||
}
|
||||
};
|
|
@ -1,74 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
const prettifyMiliseconds = require('pretty-ms');
|
||||
const { createPaginationEmbed } = require('eris-pagination');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 30000,
|
||||
this.help = {
|
||||
description: 'Get current map, weapons and gear for salmon run.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
message.channel.sendTyping();
|
||||
fetch('https://splatoon2.ink/data/coop-schedules.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
fetch('https://splatoon2.ink/data/timeline.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(timelineRes => timelineRes.json())
|
||||
.then(timelineJson => {
|
||||
|
||||
const embeds = [];
|
||||
|
||||
if ((json.details[0].start_time * 1000) > Date.now() === true) {
|
||||
embeds.push(
|
||||
new client.MessageEmbed()
|
||||
.setTitle('Upcoming Salmon Run')
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[0].stage.image)
|
||||
.addField('Map', json.details[0].stage.name, true)
|
||||
.setFooter(`Starting in ${prettifyMiliseconds(json.details[0].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
|
||||
);
|
||||
} else {
|
||||
embeds.push(
|
||||
new client.MessageEmbed()
|
||||
.setTitle('Current Salmon Run')
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setThumbnail('https://splatoon2.ink/assets/splatnet'+timelineJson.coop.reward_gear.gear.image)
|
||||
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[0].stage.image)
|
||||
.addField('Map', json.details[0].stage.name, true)
|
||||
.addField('Reward Gear', timelineJson.coop.reward_gear.gear.name, true)
|
||||
.addField('Weapons', json.details[0].weapons[0].weapon.name+', '+json.details[0].weapons[1].weapon.name+', '+json.details[0].weapons[2].weapon.name+', '+json.details[0].weapons[3].weapon.name)
|
||||
.setFooter(`Ending in ${prettifyMiliseconds((json.details[0].end_time * 1000) - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
|
||||
);
|
||||
}
|
||||
|
||||
embeds.push(
|
||||
new client.MessageEmbed()
|
||||
.setTitle('Upcoming Salmon Run')
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[1].stage.image)
|
||||
.addField('Map', json.details[1].stage.name, true)
|
||||
.addField('Weapons', json.details[1].weapons[1].weapon.name+', '+json.details[1].weapons[1].weapon.name+', '+json.details[1].weapons[2].weapon.name+', '+json.details[1].weapons[3].weapon.name)
|
||||
.setFooter(`Starting in ${prettifyMiliseconds(json.details[1].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
|
||||
);
|
||||
|
||||
createPaginationEmbed(message, embeds);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
message.channel.send(`${client.config.emojis.botError} An error has occurred: ${err}`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,50 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
const prettifyMiliseconds = require('pretty-ms');
|
||||
const { createPaginationEmbed } = require('eris-pagination');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 30000,
|
||||
this.help = {
|
||||
description: 'See what is currently on offer in the splatnet shop',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
message.channel.sendTyping();
|
||||
fetch('https://splatoon2.ink//data/merchandises.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
const embeds = [];
|
||||
|
||||
for ( let i = 0; i < json.merchandises.length; i++ ) {
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(json.merchandises[i].gear.name)
|
||||
.setThumbnail('https://splatoon2.ink/assets/splatnet' + json.merchandises[i].gear.image)
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.addField('Price', (json.merchandises[i].price).toString(), true)
|
||||
.addField('Brand', json.merchandises[i].gear.brand.name, true)
|
||||
.addField('Ability Slots', (json.merchandises[i].gear.rarity + 1).toString(), true)
|
||||
.addField('Main Ability', json.merchandises[i].skill.name, true)
|
||||
.addField('Common Ability', json.merchandises[i].gear.brand.frequent_skill.name, true)
|
||||
.setFooter('Out of stock in ' + prettifyMiliseconds(json.merchandises[i].end_time * 1000 - Date.now()) + ' | Data provided by splatoon2.ink');
|
||||
embeds.push(embed);
|
||||
}
|
||||
|
||||
createPaginationEmbed(message, embeds);
|
||||
})
|
||||
.catch(err => {
|
||||
message.channel.send(`${client.config.emojis.botError} An error has occurred: ${err}`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,56 +0,0 @@
|
|||
const fetch = require('node-fetch');
|
||||
const prettifyMiliseconds = require('pretty-ms');
|
||||
const { createPaginationEmbed } = require('eris-pagination');
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['splatoonmodes'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 30000,
|
||||
this.help = {
|
||||
description: 'Get current and upcoming maps and modes for regular, ranked and league battles.',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
message.channel.sendTyping();
|
||||
fetch('https://splatoon2.ink/data/schedules.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
|
||||
const embeds = [
|
||||
new client.MessageEmbed()
|
||||
.setTitle('Current Splatoon 2 Maps')
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.addField('<:turf_war:814651383911153692> Turf War', `${json.regular[0].stage_a.name}\n${json.regular[0].stage_b.name}`, true)
|
||||
.addField(`<:ranked:814651402479468544> Ranked: ${json.gachi[0].rule.name}`, `${json.gachi[0].stage_a.name}\n${json.gachi[0].stage_b.name}`, true)
|
||||
.addField(`<:league:814651415409590363> League: ${json.league[0].rule.name}`, `${json.league[0].stage_a.name}\n${json.league[0].stage_b.name}`, true)
|
||||
.setFooter(`Maps changing in ${prettifyMiliseconds(json.league[0].end_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
|
||||
];
|
||||
|
||||
for ( let i = 1; i < json.regular.length; i++ ) {
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle('Upcoming Splatoon 2 Maps')
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.addField('<:turf_war:814651383911153692> Turf War', `${json.regular[i].stage_a.name}\n${json.regular[i].stage_b.name}`, true)
|
||||
.addField(`<:ranked:814651402479468544> Ranked: ${json.gachi[i].rule.name}`, `${json.gachi[i].stage_a.name}\n${json.gachi[i].stage_b.name}`, true)
|
||||
.addField(`<:league:814651415409590363> League: ${json.league[i].rule.name}`, `${json.league[i].stage_a.name}\n${json.league[i].stage_b.name}`, true)
|
||||
.setFooter(`Available in ${prettifyMiliseconds(json.league[i].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`);
|
||||
embeds.push(embed);
|
||||
}
|
||||
|
||||
createPaginationEmbed(message, embeds);
|
||||
})
|
||||
.catch(err => {
|
||||
message.channel.send(`${client.config.emojis.botError} An error has occurred: ${err}`);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,52 +1,33 @@
|
|||
module.exports = class {
|
||||
const Command = require('../../base/Command.js');
|
||||
|
||||
module.exports = class Avatar extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['pfp'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'View a full-sized version of someone\'s avatar.',
|
||||
arguments: '<user>',
|
||||
details: '',
|
||||
examples: 'avatar\navatar @May\navatar emily'
|
||||
};
|
||||
this.description = 'View a full-sized version of someone\'s avatar.',
|
||||
this.options = [
|
||||
{
|
||||
type: 6,
|
||||
name: 'user',
|
||||
description: 'The user to get the avatar of.'
|
||||
},
|
||||
],
|
||||
this.usage = '/avatar [user]',
|
||||
this.friendlyOptions = '`user` - The user to get the avatar of (optional)',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const target = await interaction.options.getUser('user') ?? interaction.user;
|
||||
const user = await client.users.fetch(target.id, {force: true});
|
||||
const member = await interaction.guild.members.fetch(target.id, {force: true});
|
||||
|
||||
let member = message.member;
|
||||
|
||||
if (args[0]) {
|
||||
if (message.mentions.length > 0) {
|
||||
member = await message.guild.members.fetch(message.mentions[0].id)
|
||||
} else {
|
||||
member = await client.functions.validateUserID(message.guild, args[0]);
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle(user.username + '#' + user.discriminator + '\'s avatar')
|
||||
.setColor(user.hexAccentColor ?? member.displayHexColor)
|
||||
.setDescription(`[Global avatar](${user.avatarURL({extension: 'png', 'size': 4096})})`)
|
||||
.setImage(member.displayAvatarURL({extension: 'png', 'size': 4096}));
|
||||
|
||||
if (!member) {
|
||||
member = await message.guild.searchMembers(args.join(' '), 2);
|
||||
|
||||
if (member.length === 0) return message.channel.send(
|
||||
`${client.config.emojis.userError} No users found. Check for mispellings, or ping the user instead.`
|
||||
);
|
||||
|
||||
if (member.length > 1) return message.channel.send(
|
||||
`${client.config.emojis.userError} Found more than one user, try refining your search or pinging the user instead.`
|
||||
);
|
||||
|
||||
member = member[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(member.user.username + '#' + member.user.discriminator)
|
||||
.setColor(client.functions.embedColor(message.guild, member))
|
||||
.setImage(member.user.avatarURL);
|
||||
|
||||
message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
interaction.reply({embeds: [embed]});
|
||||
}
|
||||
};
|
90
bot/commands/Utility/server.js
Normal file
90
bot/commands/Utility/server.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const { time } = require('discord.js');
|
||||
|
||||
module.exports = class Avatar extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'View information on this server.',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const guild = await client.guilds.fetch(interaction.guild.id, {force: true});
|
||||
const members = await guild.members.fetch();
|
||||
const roles = await interaction.guild.roles.cache;
|
||||
const channels = await interaction.guild.channels.cache;
|
||||
|
||||
let verificationLevel = 'None';
|
||||
|
||||
/* eslint-disable indent */
|
||||
switch (guild.verificationLevel) {
|
||||
case 1: {
|
||||
verificationLevel = 'Low';
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
verificationLevel = 'Medium';
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
verificationLevel = 'High';
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
verificationLevel = 'Very high';
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* eslint-disable indent */
|
||||
|
||||
let mfaLevel = 'None';
|
||||
if (guild.mfaLevel === 1) {
|
||||
mfaLevel = '2FA required';
|
||||
}
|
||||
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setColor(client.functions.embedColor(guild))
|
||||
.setTitle(guild.name)
|
||||
.setThumbnail(guild.iconURL({extension: 'png', 'size': 4096}))
|
||||
.addFields(
|
||||
{
|
||||
name: 'ID', value: guild.id, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Owner', value: `<@${guild.ownerId}>`, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Locale', value: guild.preferredLocale, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Verification level', value: verificationLevel, inline: true
|
||||
},
|
||||
{
|
||||
name: 'MFA level', value: mfaLevel, inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Boosts', value: `${guild.premiumSubscriptionCount} (Level ${guild.premiumTier})`, inline: true
|
||||
|
||||
},
|
||||
{
|
||||
name: `Members (${members.size})`,
|
||||
value: `${members.size - members.filter(member => member.user.bot).size} Humans, ${members.filter(member => member.user.bot).size} Bots`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Channels', value: `${channels.filter(channel => channel.type === 0 || channel.type === 5).size} Text, ${channels.filter(channel => channel.type === 2 || channel.type === 13).size} Voice`, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Roles', value: roles.size.toString(), inline: true
|
||||
},
|
||||
{
|
||||
name: 'Created', value: time(guild.createdAt, 'D') + time(guild.createdAt, 'R'), inline: true
|
||||
},
|
||||
{
|
||||
name: 'Features', value: guild.features.join(', ')
|
||||
}
|
||||
);
|
||||
interaction.reply({ embeds: [embed] });
|
||||
}
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
const guild = message.guild;
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setColor(client.functions.embedColor(message.guild))
|
||||
.setTitle(guild.name)
|
||||
.setThumbnail(guild.iconURL)
|
||||
.addField('ID', guild.id, true)
|
||||
.addField('Owner', `<@${guild.ownerID}>`, true)
|
||||
.addField('Region', guild.region.toProperCase(), true)
|
||||
.addField('Boosts', `${guild.premiumSubscriptionCount} (Level ${guild.premiumTier})`, true)
|
||||
.addField('Member Count (Approximate)', `${guild.memberCount} (${guild.memberCount - guild.members.filter(member => member.user.bot).length} humans, ${guild.members.filter(member => member.user.bot).length} bots)`, true)
|
||||
.addField('Channels', `${guild.channels.size} ()`)
|
||||
message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
};
|
426
bot/commands/Utility/splatnet.js
Normal file
426
bot/commands/Utility/splatnet.js
Normal file
|
@ -0,0 +1,426 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const fetch = require('node-fetch');
|
||||
const { pagination } = require('@devraelfreeze/discordjs-pagination');
|
||||
const prettifyMiliseconds = require('pretty-ms');
|
||||
const brandAbilities = require('../../assets/s3BrandAbilities.json');
|
||||
|
||||
module.exports = class Splatnet extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'View the current map rotation, salmon run gear and SplatNet gear for Splatoon 3',
|
||||
this.category = category,
|
||||
this.options = [
|
||||
{
|
||||
type: 1,
|
||||
name: 'maps',
|
||||
description: 'Get current and upcoming map rotations for turf war, anarchy and X-rank battles.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'salmonrun',
|
||||
description: 'Get current and upcoming map rotations for salmon run, as well as the monthly gear reward.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'gear',
|
||||
description: 'View the gear currently available on the SplatNet mobile app.'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const subCmd = interaction.options.getSubcommand();
|
||||
const embeds = [];
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
if (subCmd === 'maps') {
|
||||
if (client.cache.has('SPLATNET_MAPS') && Date.now() > client.cache.get('SPLATNET_MAPS').expiry) {
|
||||
client.cache.delete('SPLATNET_MAPS');
|
||||
}
|
||||
|
||||
if (!client.cache.has('SPLATNET_MAPS')) {
|
||||
fetch('https://splatoon3.ink/data/schedules.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(async json => {
|
||||
// cache data so we dont spam API
|
||||
client.cache.set('SPLATNET_MAPS', {data: json, expiry: new Date(json.data.xSchedules.nodes[0].endTime)});
|
||||
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle('Current Splatoon 3 Maps')
|
||||
.setColor(interaction.guild.members.me.displayHexColor)
|
||||
.addFields(
|
||||
{
|
||||
name: '<:turf_war:814651383911153692> Turf War',
|
||||
value: `${json.data.regularSchedules.nodes[0].regularMatchSetting.vsStages[0].name}\n${json.data.regularSchedules.nodes[0].regularMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Series: ${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Open: ${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:xRank:1056806341575970898> X rank: ${json.data.xSchedules.nodes[0].xMatchSetting.vsRule.name}`,
|
||||
value: `${json.data.xSchedules.nodes[0].xMatchSetting.vsStages[0].name}\n${json.data.xSchedules.nodes[0].xMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Maps changing in ${prettifyMiliseconds(new Date(json.data.xSchedules.nodes[0].endTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
for (let i = 1; i < json.data.regularSchedules.nodes.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle('Upcoming Splatoon 3 Maps')
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: '<:turf_war:814651383911153692> Turf War',
|
||||
value: `${json.data.regularSchedules.nodes[i].regularMatchSetting.vsStages[0].name}\n${json.data.regularSchedules.nodes[i].regularMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Series: ${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Open: ${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `X rank: ${json.data.xSchedules.nodes[i].xMatchSetting.vsRule.name}`,
|
||||
value: `${json.data.xSchedules.nodes[i].xMatchSetting.vsStages[0].name}\n${json.data.xSchedules.nodes[i].xMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Starting in ${prettifyMiliseconds(new Date(json.data.xSchedules.nodes[i].startTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
await pagination({
|
||||
embeds: embeds,
|
||||
author: interaction.member.user,
|
||||
interaction: interaction,
|
||||
time: 60000,
|
||||
disableButtons: false,
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
client.logger.error('SPLATNET_COMMAND_ERROR', `API err or err replying: ${err.stack}`);
|
||||
return interaction.editReply(`${client.config.emojis.botError} An error occurred, sorry! I've reported this to my developers.`);
|
||||
});
|
||||
} else {
|
||||
let json = client.cache.get('SPLATNET_MAPS');
|
||||
json = json.data;
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle('Current Splatoon 3 Maps')
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: '<:turf_war:814651383911153692> Turf War',
|
||||
value: `${json.data.regularSchedules.nodes[0].regularMatchSetting.vsStages[0].name}\n${json.data.regularSchedules.nodes[0].regularMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Series: ${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[0].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Open: ${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[0].bankaraMatchSettings[1].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `X rank: ${json.data.xSchedules.nodes[0].xMatchSetting.vsRule.name}`,
|
||||
value: `${json.data.xSchedules.nodes[0].xMatchSetting.vsStages[0].name}\n${json.data.xSchedules.nodes[0].xMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Maps changing in ${prettifyMiliseconds(new Date(json.data.xSchedules.nodes[0].endTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
|
||||
for (let i = 1; i < json.data.regularSchedules.nodes.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle('Upcoming Splatoon 3 Maps')
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: '<:turf_war:814651383911153692> Turf War',
|
||||
value: `${json.data.regularSchedules.nodes[i].regularMatchSetting.vsStages[0].name}\n${json.data.regularSchedules.nodes[i].regularMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Series: ${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[0].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `<:ranked:814651402479468544> Anarchy Open: ${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsRule.name}`,
|
||||
value: `${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsStages[0].name}\n${json.data.bankaraSchedules.nodes[i].bankaraMatchSettings[1].vsStages[1].name}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: `X rank: ${json.data.xSchedules.nodes[i].xMatchSetting.vsRule.name}`,
|
||||
value: `${json.data.xSchedules.nodes[i].xMatchSetting.vsStages[0].name}\n${json.data.xSchedules.nodes[i].xMatchSetting.vsStages[1].name}`,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Starting in ${prettifyMiliseconds(new Date(json.data.xSchedules.nodes[i].startTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
await pagination({
|
||||
embeds: embeds,
|
||||
author: interaction.member.user,
|
||||
interaction: interaction,
|
||||
time: 60000,
|
||||
disableButtons: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (subCmd === 'salmonrun') {
|
||||
if (client.cache.has('SPLATNET_SR') && Date.now() > client.cache.get('SPLATNET_SR').expiry) {
|
||||
client.cache.delete('SPLATNET_SR');
|
||||
}
|
||||
|
||||
if (!client.cache.has('SPLATNET_SR')) {
|
||||
fetch('https://splatoon3.ink/data/schedules.json', { headers: { 'User-Agent': client.config.userAgent} })
|
||||
.then(res => res.json())
|
||||
.then(tlJson => {
|
||||
fetch('https://splatoon3.ink/data/coop.json', { headers: { 'User-Agent': client.config.userAgent} })
|
||||
.then(rewardRes => rewardRes.json())
|
||||
.then(async rewardJson => {
|
||||
const embeds = [];
|
||||
const json = {
|
||||
tl: tlJson.data.coopGroupingSchedule,
|
||||
rw: rewardJson.data.coopResult.monthlyGear
|
||||
};
|
||||
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle('Current Salmon Run')
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.setThumbnail(json.rw.image.url)
|
||||
.setImage(json.tl.regularSchedules.nodes[0].setting.coopStage.image.url)
|
||||
.addFields(
|
||||
{
|
||||
name: 'Stage',
|
||||
value: json.tl.regularSchedules.nodes[0].setting.coopStage.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Monthly Gear',
|
||||
value: json.rw.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Weapons',
|
||||
value: json.tl.regularSchedules.nodes[0].setting.weapons[0]
|
||||
}
|
||||
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (subCmd === 'gear') {
|
||||
if (client.cache.has('SPLATNET_GEAR') && Date.now() > client.cache.get('SPLATNET_GEAR').expiry) {
|
||||
client.cache.delete('SPLATNET_GEAR');
|
||||
}
|
||||
|
||||
if (!client.cache.has('SPLATNET_GEAR')) {
|
||||
fetch('https://splatoon3.ink/data/gear.json', { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(async json => {
|
||||
client.cache.set('SPLATNET_GEAR', {data: json, expiry: new Date(json.data.gesotown.limitedGears[0].saleEndTime)});
|
||||
|
||||
// splatnet daily drop
|
||||
for (let i = 0; i < json.data.gesotown.pickupBrand.brandGears.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle(`${json.data.gesotown.pickupBrand.brandGears[i].gear.name} (${this.starPower(json.data.gesotown.pickupBrand.brandGears[i].gear.additionalGearPowers.length)})`)
|
||||
.setDescription(`This piece of gear is apart of the ${json.data.gesotown.pickupBrand.brand.name} daily drop. The next drop will be for ${json.data.gesotown.pickupBrand.nextBrand.name}.`)
|
||||
.setThumbnail(json.data.gesotown.pickupBrand.brandGears[i].gear.image.url)
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: 'Brand',
|
||||
value: json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Price',
|
||||
value: `${json.data.gesotown.pickupBrand.brandGears[i].price}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Main Ability',
|
||||
value: json.data.gesotown.pickupBrand.brandGears[i].gear.primaryGearPower.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Common Ability',
|
||||
value: brandAbilities[json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name.trim()].common,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Uncommon Ability',
|
||||
value: brandAbilities[json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name.trim()].uncommon,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Off sale in ${prettifyMiliseconds(new Date(json.data.gesotown.pickupBrand.brandGears[i].saleEndTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
|
||||
// general splatnet items
|
||||
for (let i = 0; i < json.data.gesotown.limitedGears.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle(`${json.data.gesotown.limitedGears[i].gear.name} (${this.starPower(json.data.gesotown.limitedGears[i].gear.additionalGearPowers.length)})`)
|
||||
.setThumbnail(json.data.gesotown.limitedGears[i].gear.image.url)
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: 'Brand',
|
||||
value: json.data.gesotown.limitedGears[i].gear.brand.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Price',
|
||||
value: `${json.data.gesotown.limitedGears[i].price}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Main Ability',
|
||||
value: json.data.gesotown.limitedGears[i].gear.primaryGearPower.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Common Ability',
|
||||
value: brandAbilities[json.data.gesotown.limitedGears[i].gear.brand.name.trim()].common,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Uncommon Ability',
|
||||
value: brandAbilities[json.data.gesotown.limitedGears[i].gear.brand.name.trim()].uncommon,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Off sale in ${prettifyMiliseconds(new Date(json.data.gesotown.limitedGears[i].saleEndTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
await pagination({
|
||||
embeds: embeds,
|
||||
author: interaction.member.user,
|
||||
interaction: interaction,
|
||||
time: 60000,
|
||||
disableButtons: false,
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
client.logger.error('SPLATNET_COMMAND_ERROR', `API err or err replying: ${err.stack}`);
|
||||
return interaction.editReply(`${client.config.emojis.botError} An error occurred, sorry! I've reported this to my developers.`);
|
||||
});
|
||||
} else {
|
||||
let json = client.cache.get('SPLATNET_GEAR');
|
||||
json = json.data;
|
||||
|
||||
// splatnet daily drop
|
||||
for (let i = 0; i < json.data.gesotown.pickupBrand.brandGears.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle(`${json.data.gesotown.pickupBrand.brandGears[i].gear.name} (${this.starPower(json.data.gesotown.pickupBrand.brandGears[i].gear.additionalGearPowers.length)})`)
|
||||
.setDescription(`This piece of gear is apart of the ${json.data.gesotown.pickupBrand.brand.name} daily drop. The next drop will be for ${json.data.gesotown.pickupBrand.nextBrand.name}.`)
|
||||
.setThumbnail(json.data.gesotown.pickupBrand.brandGears[i].gear.image.url)
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: 'Brand',
|
||||
value: json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Price',
|
||||
value: `${json.data.gesotown.pickupBrand.brandGears[i].price}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Main Ability',
|
||||
value: json.data.gesotown.pickupBrand.brandGears[i].gear.primaryGearPower.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Common Ability',
|
||||
value: brandAbilities[json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name.trim()].common,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Uncommon Ability',
|
||||
value: brandAbilities[json.data.gesotown.pickupBrand.brandGears[i].gear.brand.name.trim()].uncommon,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Off sale in ${prettifyMiliseconds(new Date(json.data.gesotown.pickupBrand.brandGears[i].saleEndTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
|
||||
// general splatnet items
|
||||
for (let i = 0; i < json.data.gesotown.limitedGears.length; i++) {
|
||||
embeds.push(new client.EmbedBuilder()
|
||||
.setTitle(`${json.data.gesotown.limitedGears[i].gear.name} (${this.starPower(json.data.gesotown.limitedGears[i].gear.additionalGearPowers.length)})`)
|
||||
.setThumbnail(json.data.gesotown.limitedGears[i].gear.image.url)
|
||||
.setColor(interaction.guild.members.me.displayColor)
|
||||
.addFields(
|
||||
{
|
||||
name: 'Brand',
|
||||
value: json.data.gesotown.limitedGears[i].gear.brand.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Price',
|
||||
value: `${json.data.gesotown.limitedGears[i].price}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: 'Main Ability',
|
||||
value: json.data.gesotown.limitedGears[i].gear.primaryGearPower.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Common Ability',
|
||||
value: brandAbilities[json.data.gesotown.limitedGears[i].gear.brand.name.trim()].common,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Uncommon Ability',
|
||||
value: brandAbilities[json.data.gesotown.limitedGears[i].gear.brand.name.trim()].uncommon,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({ text: `Off sale in ${prettifyMiliseconds(new Date(json.data.gesotown.limitedGears[i].saleEndTime).getTime() - Date.now(), { secondsDecimalDigits: 0 })} - Data provided by splatoon3.ink`})
|
||||
);
|
||||
}
|
||||
await pagination({
|
||||
embeds: embeds,
|
||||
author: interaction.member.user,
|
||||
interaction: interaction,
|
||||
time: 60000,
|
||||
disableButtons: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
starPower (slots) {
|
||||
if (slots === 1) return '0*';
|
||||
if (slots === 2) return '1*';
|
||||
if (slots === 3) return '2*';
|
||||
return 'err';
|
||||
}
|
||||
};
|
72
bot/commands/Utility/user.js
Normal file
72
bot/commands/Utility/user.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const { time } = require('discord.js');
|
||||
module.exports = class Avatar extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'View someone\'s public account information',
|
||||
this.options = [
|
||||
{
|
||||
type: 6,
|
||||
name: 'user',
|
||||
description: 'The user to get information on'
|
||||
},
|
||||
],
|
||||
this.usage = '/user [user]',
|
||||
this.friendlyOptions = '`user` - The user to get information on (optional)',
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
const target = await interaction.options.getUser('user') ?? interaction.user;
|
||||
const user = await client.users.fetch(target.id, {force: true});
|
||||
const member = await interaction.guild.members.fetch(target.id, {force: true});
|
||||
|
||||
const badges = [];
|
||||
if (client.config.devIds.includes(user.id)) badges.push('<:Woomy_Developer:816822318289518622> ');
|
||||
if (user.id === member.guild.ownerId) badges.push('<:owner:685703193694306331>');
|
||||
|
||||
user.flags?.toArray().forEach(flag => {
|
||||
badges.push(`${client.config.emojis[flag] ?? flag}`);
|
||||
});
|
||||
|
||||
const roles = [];
|
||||
for (const roleId of member._roles) {
|
||||
if (roles.length === 45) {
|
||||
roles.push(`and ${member.roles.length - 45} more`);
|
||||
break;
|
||||
}
|
||||
|
||||
roles.push(`<@&${roleId}>`);
|
||||
}
|
||||
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle(member.user.username + '#' + member.user.discriminator)
|
||||
.setColor(user.hexAccentColor ?? member.displayHexColor)
|
||||
.setThumbnail(member.displayAvatarURL({extension: 'png', 'size': 4096}))
|
||||
.addFields(
|
||||
{
|
||||
name: 'Display Name', value: member.nick || user.username, inline: true
|
||||
},
|
||||
{
|
||||
name: 'User ID', value: user.id, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Highest Role', value: `<@&${member.roles.highest.id}>`, inline: true
|
||||
},
|
||||
{
|
||||
name: 'Roles:', value: roles.join(' ')
|
||||
},
|
||||
{
|
||||
name: 'Joined Server', value: time(member.joinedAt, 'D') + time(member.joinedAt, 'R'), inline: true
|
||||
},
|
||||
{
|
||||
name: 'Joined Discord', value: time(user.createdAt, 'D') + time(user.createdAt, 'R'), inline: true
|
||||
}
|
||||
);
|
||||
if (badges.length > 0) {
|
||||
embed.setDescription(badges.join(' '));
|
||||
}
|
||||
return interaction.reply({embeds: [embed]});
|
||||
}
|
||||
};
|
|
@ -1,78 +0,0 @@
|
|||
const dayjs = require('dayjs');
|
||||
dayjs.extend(require('dayjs/plugin/relativeTime'));
|
||||
|
||||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = ['user'],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Get information on a user.',
|
||||
arguments: '[user]',
|
||||
details: '',
|
||||
examples: 'userinfo\nuserinfo Octavia\nuserinfo @Animals'
|
||||
};
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
let member = message.member;
|
||||
|
||||
if (args[0]) {
|
||||
if (message.mentions.length > 0) {
|
||||
member = await message.guild.members.fetch(message.mentions[0].id)
|
||||
} else {
|
||||
member = await client.functions.validateUserID(message.guild, args[0]);
|
||||
|
||||
if (!member) {
|
||||
member = await message.guild.searchMembers(args.join(' '), 2);
|
||||
|
||||
if (member.length === 0) return message.channel.send(
|
||||
`${client.config.emojis.userError} No users found. Check for mispellings, or ping the user instead.`
|
||||
);
|
||||
|
||||
if (member.length > 1) return message.channel.send(
|
||||
`${client.config.emojis.userError} Found more than one user, try refining your search or pinging the user instead.`
|
||||
);
|
||||
|
||||
member = member[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const badges = [];
|
||||
|
||||
if (client.config.ownerIDs.includes(member.id)) badges.push('<:Woomy_Developer:816822318289518622> ');
|
||||
if (member.id === member.guild.ownerID) badges.push('<:owner:685703193694306331>');
|
||||
if (member.bot) badges.push('<:bot:686489601678114859>');
|
||||
|
||||
const roles = [];
|
||||
|
||||
for (const roleID of member.roles) {
|
||||
if (roles.length === 45) {
|
||||
roles.push(`and ${member.roles.length - 45} more`);
|
||||
break;
|
||||
}
|
||||
|
||||
roles.push(`<@&${roleID}>`);
|
||||
}
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(member.user.username + '#' + member.user.discriminator)
|
||||
.setColor(client.functions.embedColor(message.guild, member))
|
||||
.setThumbnail(member.user.avatarURL || member.user.defaultAvatarURL)
|
||||
.addField('Display Name', member.nick || member.user.username, true)
|
||||
.addField('User ID', member.id, true)
|
||||
.addField('Highest Role', `<@&${client.functions.highestRole(member).id}>`, true)
|
||||
.addField('Roles:', roles.join(' '))
|
||||
.addField('Joined Server', `${dayjs(member.joinedAt).format('D/M/YYYY HH:mm (UTCZ)')}\n*${dayjs().to(member.joinedAt)}*`, true)
|
||||
.addField('Joined Discord', `${dayjs(member.user.createdAt).format('D/M/YYYY HH:mm (UTCZ)')}\n*${dayjs().to(member.user.createdAt)}*`, true);
|
||||
if (badges.length > 0) embed.setDescription(badges.join(' '));
|
||||
|
||||
message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
};
|
|
@ -1,85 +1,97 @@
|
|||
const Command = require('../../base/Command.js');
|
||||
const fetch = require('node-fetch');
|
||||
const windrose = require('windrose');
|
||||
const ISO2 = require('../../assets/ISO2.json');
|
||||
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Weather extends Command {
|
||||
constructor (name, category) {
|
||||
super (name, category);
|
||||
this.name = name,
|
||||
this.description = 'View the weather in a place ',
|
||||
this.options = [
|
||||
{
|
||||
type: 3,
|
||||
name: 'city',
|
||||
description: 'The city to check the weather at',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 3,
|
||||
name: 'country',
|
||||
description: 'The country the city is in',
|
||||
}
|
||||
],
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: 'Gives you the weather for the specified city. You can also specify a country code with a comma.',
|
||||
arguments: '<city>, [code]',
|
||||
details: '`<city>` - name of a city\n`[code]` - country code (USA = US, Australia = AU, etc.)',
|
||||
examples: 'w!weather Minneapolis\nw!weather Melbourne, AU'
|
||||
};
|
||||
this.cooldown = 10000;
|
||||
}
|
||||
|
||||
async run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
if (!args[0]) return;
|
||||
|
||||
let city = args.join(' ').toProperCase();
|
||||
let countryCode = ',';
|
||||
async run (client, interaction, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
if (args.join(' ').indexOf(',') > -1) {
|
||||
const params = city.split(',');
|
||||
city = params[0].trim().toProperCase();
|
||||
if (ISO2.country[params[1].toProperCase().trim()]) {
|
||||
countryCode += ISO2.country[params[1].toProperCase().trim()];
|
||||
const city = await interaction.options.get('city').value;
|
||||
let country = await interaction.options.get('country');
|
||||
let countryCode = '';
|
||||
|
||||
if (country) {
|
||||
country = country.value;
|
||||
countryCode += ',';
|
||||
if (ISO2.country[country.toProperCase().trim()]) {
|
||||
countryCode += ISO2.country[country.toProperCase().trim()];
|
||||
} else {
|
||||
countryCode += params[1].trim();
|
||||
countryCode += country.trim();
|
||||
}
|
||||
}
|
||||
|
||||
const editMessage = await message.channel.send(`${client.config.emojis.loading} Please wait...`);
|
||||
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city + countryCode}&appid=${client.config.keys.weather}`, { headers: { 'User-Agent': client.config.userAgent }})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
if (json.cod >= 200 && json.cod <= 299) {
|
||||
const tempCelcius = Math.round(json.main.temp - 273.15);
|
||||
let embedColour;
|
||||
if (tempCelcius < 0) {
|
||||
embedColour = '#addeff';
|
||||
} else if (tempCelcius < 20) {
|
||||
embedColour = '#4fb8ff';
|
||||
} else if (tempCelcius < 26) {
|
||||
embedColour = '#ffea4f';
|
||||
} else if (tempCelcius < 31) {
|
||||
embedColour = '#ffa14f';
|
||||
const tempCelsius = Math.round(json.main.temp - 273.15);
|
||||
let embedColor;
|
||||
if (tempCelsius < 0) {
|
||||
embedColor = '#addeff';
|
||||
} else if (tempCelsius < 20) {
|
||||
embedColor = '#4fb8ff';
|
||||
} else if (tempCelsius < 26) {
|
||||
embedColor = '#ffea4f';
|
||||
} else if (tempCelsius < 31) {
|
||||
embedColor = '#ffa14f';
|
||||
} else {
|
||||
embedColour = '#ff614f';
|
||||
embedColor = '#ff614f';
|
||||
}
|
||||
|
||||
const embed = new client.MessageEmbed()
|
||||
.setTitle(`Weather for ${city + ', ' + ISO2.code[json.sys.country]}`)
|
||||
|
||||
const embed = new client.EmbedBuilder()
|
||||
.setTitle('Current conditions in ' + city.toProperCase() + ', ' + ISO2.code[json.sys.country])
|
||||
.setThumbnail(`https://openweathermap.org/img/wn/${json.weather[0].icon}@4x.png`)
|
||||
.setColor(embedColour)
|
||||
.addField('Condition:', json.weather[0].main, true)
|
||||
.addField('Temperature:', `${tempCelcius}°C | ${Math.round(json.main.temp * 9/5 - 459.67)}°F`, true)
|
||||
.addField('Min/Max:', `
|
||||
${Math.round(json.main.temp_min - 273.15)}°C - ${Math.round(json.main.temp_max - 273.15)}°C
|
||||
${Math.round(json.main.temp_min * 9/5 - 459.67)}°F - ${Math.round(json.main.temp_max * 9/5 - 459.67)}°F
|
||||
`, true)
|
||||
.addField('Humidity:', `${json.main.humidity}%`, true)
|
||||
.addField('Wind Speed:', `${Math.round(json.wind.speed * 10) / 10}km/h | ${Math.round(json.wind.speed * 10 / 1.609344)}mi/h`, true)
|
||||
.addField('Wind Direction:', windrose.getPoint(json.wind.deg).name, true)
|
||||
.setFooter('Powered by openweathermap.org');
|
||||
return editMessage.edit({ content: null, embeds: [embed] });
|
||||
.setColor(embedColor)
|
||||
.addFields(
|
||||
{ name: 'Condition:', value: json.weather[0].main, inline: true },
|
||||
{ name: 'Temperature:', value: `${tempCelsius}°C ・ ${Math.round(json.main.temp * 9/5 - 459.67)}°F`, inline: true },
|
||||
{ name: 'Min/Max:', value:`
|
||||
${Math.round(json.main.temp_min - 273.15)}°C ・ ${Math.round(json.main.temp_max - 273.15)}°C
|
||||
${Math.round(json.main.temp_min * 9/5 - 459.67)}°F ・ ${Math.round(json.main.temp_max * 9/5 - 459.67)}°F
|
||||
`, inline: true},
|
||||
{ name: 'Humidity:', value: `${json.main.humidity}%`, inline: true },
|
||||
{ name: 'Wind Speed:', value: `${Math.round(json.wind.speed * 10) / 10}km/h ・ ${Math.round(json.wind.speed * 10 / 1.609344)}mi/h`, inline: true },
|
||||
{ name: 'Wind Direction:', value: windrose.getPoint(json.wind.deg).name, inline: true}
|
||||
)
|
||||
.setFooter({ text: 'Powered by openweathermap.org'});
|
||||
|
||||
return interaction.reply({embeds: [embed]});
|
||||
} else {
|
||||
if (json.message && json.message === 'city not found') {
|
||||
return message.channel.send(`${client.config.emojis.userError} You provided an invalid city name. Maybe check your spelling?`);
|
||||
return interaction.reply({
|
||||
content: `${client.config.emojis.userError} ${city.toProperCase()} is not listed in my sources.`,
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
return message.channel.send(`${client.config.emojis.botError} API error occured: \`code ${json.cod}: ${json.message}\``);
|
||||
client.logger.error('WEATHER_COMMAND_ERROR', `API Error: ${json}`);
|
||||
return interaction.reply({
|
||||
content: `${client.config.emojis.botError} API error occurred: \`code ${json.cod}\``,
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
return message.channel.send(`${client.config.emojis.botError} An error has occured: \`${err.stack}\``);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
42
bot/deploy.js
Normal file
42
bot/deploy.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
// taken from https://discordjs.guide/
|
||||
|
||||
const { REST, Routes } = require('discord.js');
|
||||
const { clientId, token } = require('../botconfig.json');
|
||||
const read = require('fs-readdir-recursive');
|
||||
const commands = [];
|
||||
const commandFiles = read('./commands').filter(file => file.endsWith('.js'));
|
||||
|
||||
if (process.argv.length === 2) {
|
||||
console.log('No guild ID provided, deployment failed.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const guildId = process.argv[2];
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const command = new (require(__dirname + '/commands/' + file))(file.substr(file.indexOf('/') + 1).slice(0, -3), file.substr(0, file.indexOf('/')));
|
||||
commands.push({
|
||||
name: command.name,
|
||||
description: command.description,
|
||||
options: command.options,
|
||||
permissions: command.permissions,
|
||||
dm_permission: command.dm_permission
|
||||
});
|
||||
}
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(token);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
const data = await rest.put(
|
||||
Routes.applicationGuildCommands(clientId, guildId),
|
||||
{ body: commands },
|
||||
);
|
||||
|
||||
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable indent */
|
||||
|
||||
class EventHandler {
|
||||
|
||||
constructor (client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
@ -13,52 +13,51 @@ class EventHandler {
|
|||
break;
|
||||
}
|
||||
|
||||
// param_1 - error message
|
||||
case 'error': {
|
||||
const errorModules = this.client.eventModules.filter(module => module.wsEvent === 'error');
|
||||
errorModules.forEach(module => module.run(this.client, param_1));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - message object
|
||||
case 'messageCreate': {
|
||||
const mCreateModules = this.client.eventModules.filter(module => module.wsEvent === 'messageCreate');
|
||||
mCreateModules.forEach(module => module.run(this.client, param_1));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - guild object
|
||||
case 'interactionCreate': {
|
||||
const iCreateModules = this.client.eventModules.filter(module => module.wsEvent === 'interactionCreate');
|
||||
iCreateModules.forEach(module => module.run(this.client, param_1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'guildCreate': {
|
||||
const gCreateModules = this.client.eventModules.filter(module => module.wsEvent === 'guildCreate');
|
||||
gCreateModules.forEach(module => module.run(this.client, param_1));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - guild object
|
||||
case 'guildDelete': {
|
||||
const gDeleteModules = this.client.eventModules.filter(module => module.wsEvent === 'guildDelete');
|
||||
gDeleteModules.forEach(module => module.run(this.client, param_1));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - guild object | param_2 - member object
|
||||
case 'guildMemberAdd': {
|
||||
const gMemberAddModules = this.client.eventModules.filter(module => module.wsEvent === 'guildMemberAdd');
|
||||
gMemberAddModules.forEach(module => module.run(this.client, param_1, param_2));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - guild object | param_2 - member object
|
||||
case 'guildMemberRemove': {
|
||||
const gMemberRemoveModules = this.client.eventModules.filter(module => module.wsEvent === 'guildMemberRemove');
|
||||
gMemberRemoveModules.forEach(module => module.run(this.client, param_1, param_2));
|
||||
break;
|
||||
}
|
||||
|
||||
// param_1 - old voice state | param_2 - new voice state
|
||||
case 'voiceStateUpdate': {
|
||||
const vStateUpdateModules = this.client.eventModules.filter(module => module.wsEvent === 'voiceStateUpdate');
|
||||
vStateUpdateModules.forEach(module => module.run(this.client));
|
||||
vStateUpdateModules.forEach(module => module.run(this.client, param_1, param_2));
|
||||
break;
|
||||
}
|
||||
}
|
62
bot/event_modules/interactionCreate/interactionHandler.js
Normal file
62
bot/event_modules/interactionCreate/interactionHandler.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
const Event = require('../../base/Event.js');
|
||||
module.exports = class InteractionHandler extends Event {
|
||||
constructor (wsEvent) {
|
||||
super (wsEvent);
|
||||
this.wsEvent = wsEvent;
|
||||
}
|
||||
|
||||
async run (client, interaction) {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
// Request all the data we need from the database
|
||||
const data = {};
|
||||
data.user = await client.db.getUser(interaction.user.id);
|
||||
data.guild = await client.db.getGuild(interaction.guild.id);
|
||||
data.member = await client.db.getMember(interaction.guild.id, interaction.user.id);
|
||||
|
||||
const command = client.commands.get(interaction.commandName);
|
||||
|
||||
// Return if the command is disabled globally
|
||||
if (command.enabled === false) interaction.reply({
|
||||
content: client.config.emojis.permError + ' This command has been disabled by my developers.',
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
// Return if the command is restricted to developers (and the user is not a developer)
|
||||
if (command.devOnly === true && client.config.devIds.includes(interaction.user.id) !== true) {
|
||||
return interaction.reply({
|
||||
content: `${client.config.emojis.permError} ${interaction.user.username} is not in the sudoers file. This incident will be reported.`,
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
// Cooldown
|
||||
if (client.cooldowns.get(command.name).has(interaction.user.id)) {
|
||||
const timestamp = client.cooldowns.get(command.name).get(interaction.user.id);
|
||||
const currentTime = Date.now();
|
||||
const cooldown = command.cooldown / 1000;
|
||||
const timePassed = Math.floor((currentTime - timestamp) / 1000);
|
||||
return interaction.reply({
|
||||
content: `${client.config.emojis.wait} You need to wait ${cooldown - timePassed} seconds before using this command again.`,
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
client.cooldowns.get(command.name).set(interaction.user.id, new Date());
|
||||
setTimeout(() => {
|
||||
client.cooldowns.get(command.name).delete(interaction.user.id);
|
||||
}, client.commands.get(command.name).cooldown);
|
||||
}
|
||||
|
||||
// Try to execute the command, if it fails return error stack and inform the user
|
||||
try {
|
||||
command.run(client, interaction, data);
|
||||
client.logger.command(`Ran ${command.name}`);
|
||||
} catch (error) {
|
||||
client.logger.error('COMMAND_EXECUTION_ERROR', `${command.name}: ${error.stack}`);
|
||||
interaction.reply({
|
||||
content: `${client.config.emojis.botError} An error occurred when I was trying to run this command. I've sent through the details of the error to my developers.`,
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,7 +1,8 @@
|
|||
const Event = require('../../base/Event.js');
|
||||
const activities = require('../../assets/activities.json');
|
||||
|
||||
module.exports = class {
|
||||
module.exports = class Activity extends Event {
|
||||
constructor (wsEvent) {
|
||||
super (wsEvent);
|
||||
this.wsEvent = wsEvent;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module.exports = class {
|
||||
const Event = require('../../base/Event.js');
|
||||
module.exports = class Ready extends Event {
|
||||
constructor (wsEvent) {
|
||||
super (wsEvent);
|
||||
this.wsEvent = wsEvent;
|
||||
}
|
||||
|
||||
|
|
43
bot/index.js
43
bot/index.js
|
@ -3,15 +3,13 @@
|
|||
const Discord = require('discord.js');
|
||||
const CommandLoader = require('./util/commandLoader');
|
||||
const EventLoader = require('./util/eventLoader');
|
||||
const EventHandler = require('./util/handlers/eventHandler');
|
||||
const MessageHandler = require('./util/handlers/messageHandler');
|
||||
const EventHandler = require('./event_modules/eventHandler');
|
||||
const Functions = require('./util/functions');
|
||||
const Database = require('./util/database');
|
||||
const Logger = require('./util/logger');
|
||||
const sentry = require('@sentry/node');
|
||||
const config = require('../botconfig.json');
|
||||
const version = require('../package.json').version;
|
||||
|
||||
class WoomyClient extends Discord.Client {
|
||||
constructor (options) {
|
||||
super(options);
|
||||
|
@ -23,26 +21,28 @@ class WoomyClient extends Discord.Client {
|
|||
|
||||
// Essential modules
|
||||
this.logger = Logger;
|
||||
this.MessageEmbed = Discord.MessageEmbed;
|
||||
this.EmbedBuilder = Discord.EmbedBuilder;
|
||||
this.db = new Database(this);
|
||||
this.functions = new Functions(this);
|
||||
this.commandLoader = new CommandLoader(this);
|
||||
this.eventLoader = new EventLoader(this);
|
||||
this.eventHandler = new EventHandler(this);
|
||||
this.messageHandler = new MessageHandler(this);
|
||||
|
||||
// Collections to store our successfully loaded events and commands in, as well as cooldowns.
|
||||
this.commands = new Discord.Collection();
|
||||
this.aliases = new Discord.Collection();
|
||||
this.eventModules = new Discord.Collection();
|
||||
this.cooldowns = new Discord.Collection();
|
||||
|
||||
// Cache we can store stuff in
|
||||
this.cache = new Discord.Collection();
|
||||
}
|
||||
|
||||
// Listen for Discord events and pass needed information to the event handler so we can respond to them.
|
||||
createEventListeners () {
|
||||
this.on('ready', this.runReadyModules);
|
||||
this.on('error', this.runErrorModules);
|
||||
this.on('messageCreate', this.runMessageCreateModules);
|
||||
this.on('interactionCreate', this.runInteractionCreateModules);
|
||||
this.on('guildCreate', this.runGuildCreateModules);
|
||||
this.on('guildDelete', this.runGuildDeleteModules);
|
||||
this.on('guildMemberAdd', this.runGuildMemberAddModules);
|
||||
|
@ -50,7 +50,7 @@ class WoomyClient extends Discord.Client {
|
|||
this.on('voiceStateUpdate', this.runVoiceStateUpdateModules);
|
||||
}
|
||||
|
||||
// Recieves information from the per-event listeners, and passes on needed information to the handler
|
||||
// Receives information from the per-event listeners, and passes on needed information to the handler
|
||||
mainEventListener (wsEvent, param_1, param_2) {
|
||||
try {
|
||||
this.eventHandler.handle(wsEvent, param_1, param_2);
|
||||
|
@ -68,9 +68,8 @@ class WoomyClient extends Discord.Client {
|
|||
this.mainEventListener('error', error);
|
||||
}
|
||||
|
||||
runMessageCreateModules (message) {
|
||||
this.messageHandler.handle(message);
|
||||
this.mainEventListener('messageCreate', message);
|
||||
runInteractionCreateModules (interaction) {
|
||||
this.mainEventListener('interactionCreate', interaction);
|
||||
}
|
||||
|
||||
runGuildCreateModules (guild) {
|
||||
|
@ -98,15 +97,19 @@ class WoomyClient extends Discord.Client {
|
|||
const client = new WoomyClient({
|
||||
shards: 'auto',
|
||||
intents: [
|
||||
'GUILDS',
|
||||
'GUILD_MEMBERS',
|
||||
'GUILD_EMOJIS',
|
||||
'GUILD_VOICE_STATES',
|
||||
'GUILD_MESSAGES',
|
||||
'DIRECT_MESSAGES',
|
||||
'GUILD_MESSAGE_REACTIONS',
|
||||
]
|
||||
Discord.GatewayIntentBits.Guilds,
|
||||
Discord.GatewayIntentBits.GuildMembers,
|
||||
Discord.GatewayIntentBits.GuildEmojisAndStickers,
|
||||
Discord.GatewayIntentBits.GuildVoiceStates,
|
||||
],
|
||||
allowedMentions: {
|
||||
parse: [
|
||||
'users',
|
||||
'roles'
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// Extensions of native javascript types, *not good practice* but they're useful
|
||||
require('./util/prototypes');
|
||||
|
||||
|
@ -115,7 +118,7 @@ client.commandLoader.loadCommands();
|
|||
client.eventLoader.loadEventModules();
|
||||
client.createEventListeners();
|
||||
|
||||
// Development mode is set in botconfig.yml, and disables some stuff if enabled. Imagine how messy Sentry would be without this!
|
||||
// Development mode is set in botconfig.json
|
||||
if (client.config.developmentMode === false) {
|
||||
try {
|
||||
sentry.init({ dsn: client.config.keys.sentry });
|
||||
|
@ -139,7 +142,7 @@ process.on('unhandledRejection', err => {
|
|||
client.logger.error('UNHANDLED_PROMISE_ERROR', err.stack);
|
||||
});
|
||||
|
||||
// Shut down gracefully when SIGINT is recieved
|
||||
// Shut down gracefully when SIGINT is received
|
||||
process.on('SIGINT', () => {
|
||||
client.functions.shutdown();
|
||||
});
|
|
@ -13,12 +13,8 @@ class CommandLoader {
|
|||
const name = file.substr(file.indexOf('/') + 1).slice(0, -3);
|
||||
const category = file.substr(0, file.indexOf('/'));
|
||||
const command = new (require(this.client.path + '/commands/' + file))(name, category);
|
||||
|
||||
this.client.commands.set(command.name, command);
|
||||
this.client.cooldowns.set(command.name, new Map());
|
||||
command.aliases.forEach(alias => {
|
||||
this.client.aliases.set(alias, command.name);
|
||||
});
|
||||
} catch (error) {
|
||||
this.client.logger.error('COMMAND_LOADER_ERROR', `Failed to load ${file}: ${error}`);
|
||||
}
|
||||
|
|
|
@ -161,6 +161,21 @@ class Database {
|
|||
const res = await this.pool.query('INSERT INTO users (user_id) VALUES ($1) RETURNING *;', [id]);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async countGuilds () {
|
||||
const res = await this.pool.query('SELECT COUNT(*) FROM guilds;');
|
||||
return res.rows[0].count;
|
||||
}
|
||||
|
||||
async countMembers () {
|
||||
const res = await this.pool.query('SELECT COUNT(*) FROM members;');
|
||||
return res.rows[0].count;
|
||||
}
|
||||
|
||||
async countUsers () {
|
||||
const res = await this.pool.query('SELECT COUNT(*) FROM users;');
|
||||
return res.rows[0].count;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Database;
|
|
@ -32,7 +32,7 @@ class Functions {
|
|||
return Math.round((Math.random() * (max - min) + min));
|
||||
}
|
||||
|
||||
randomColour () {
|
||||
randomColor () {
|
||||
const n = (Math.random() * 0xfffff * 1000000).toString(16);
|
||||
return '#' + n.slice(0, 6);
|
||||
}
|
||||
|
@ -51,10 +51,6 @@ class Functions {
|
|||
return role;
|
||||
}
|
||||
|
||||
searchMembers (guild, input) {
|
||||
|
||||
}
|
||||
|
||||
embedColor (guild, member) {
|
||||
if (!member) {
|
||||
return guild.members.cache.get(this.client.user.id).displayHexColor;
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
class MessageHandler {
|
||||
constructor (client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
async handle (message) {
|
||||
// Ignore messages from bots, and messages in DM's
|
||||
if (message.author.bot) return;
|
||||
if (!message.guild) return;
|
||||
|
||||
// Request all the data we need from the database
|
||||
const data = {};
|
||||
data.user = await this.client.db.getUser(message.author.id);
|
||||
data.guild = await this.client.db.getGuild(message.guild.id);
|
||||
data.member = await this.client.db.getMember(message.guild.id, message.author.id);
|
||||
|
||||
// Ignore users on the guild blocklist
|
||||
if (data.guild.blocklist.includes(message.author.id)) return;
|
||||
|
||||
// If a user pings Woomy, respond to them with the prefixes they can use
|
||||
if (message.content === `<@${this.client.user.id}>` || message.content === `<@!${this.client.user.id}>`) {
|
||||
return message.channel.send(
|
||||
`Hi! The prefix for this server is \`${data.guild.prefix}\`, and your personal prefix is \`${data.user.prefix}\`. You can also ping me ^-^`
|
||||
);
|
||||
}
|
||||
|
||||
// All the prefixes Woomy will respond to
|
||||
const prefixes = [
|
||||
data.user.prefix,
|
||||
data.guild.prefix,
|
||||
`<@${this.client.user.id}> `,
|
||||
`<@!${this.client.user.id}> `
|
||||
];
|
||||
|
||||
let prefix;
|
||||
|
||||
// Check the message content to see if it starts with one of our prefixes
|
||||
for (const thisPrefix of prefixes) {
|
||||
if (message.content.startsWith(thisPrefix)) {
|
||||
prefix = thisPrefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore the message if it doesn't start with a valid prefix
|
||||
if (!prefix) return;
|
||||
|
||||
// Save prefix so we can use it later (mostly for help command)
|
||||
if (prefix === `<@${this.client.user.id}> ` || prefix === `<@!${this.client.user.id}> `) {
|
||||
message.prefix = '@Woomy ';
|
||||
} else (message.prefix = prefix);
|
||||
|
||||
// Turn the message content into an array (excluding the prefix)
|
||||
const args = message.content.slice(prefix.length).trim().split(/ +/g);
|
||||
|
||||
// Find the command
|
||||
const commandName = args.shift().toLowerCase();
|
||||
const command = this.client.commands.get(commandName) || this.client.commands.get(this.client.aliases.get(commandName));
|
||||
|
||||
// Return if a command (or its aliases) are not found
|
||||
if (!command) return;
|
||||
|
||||
// Both of these blocks check if the command is disabled/in a disabled category
|
||||
if (data.guild.disabledcommands.includes(command.name)) return message.channel.send(
|
||||
this.client.config.emojis.permError + ' This command has been disabled by a server administrator.'
|
||||
);
|
||||
|
||||
if (data.guild.disabledcategories.includes(command.category)) return message.channel.send(
|
||||
this.client.config.emojis.permError + ' The category this command is apart of has been disabled by a server administrator.'
|
||||
);
|
||||
|
||||
// Both of these blocks check the permissions of the user, and reply with missing perms if any are found
|
||||
const missingUserPerms = this.client.functions.checkPermissions(message.channel, message.author.id, command.userPerms);
|
||||
if (missingUserPerms) return message.channel.send(
|
||||
`${this.client.config.emojis.permError} You can't use this command because you lack these permissions: \`${missingUserPerms.join('`, `')}\``
|
||||
);
|
||||
|
||||
const missingBotPerms = this.client.functions.checkPermissions(message.channel, this.client.user.id, command.botPerms);
|
||||
if (missingBotPerms) return message.channel.send(
|
||||
`${this.client.config.emojis.permError} I can't run this command because I lack these permissions: \`${missingBotPerms.join('`, `')}\``
|
||||
);
|
||||
|
||||
// Return if the command is disabled globally
|
||||
if (command.enabled === false) return message.channel.send(
|
||||
this.client.config.emojis.permError + ' This command has been disabled by my developers.'
|
||||
);
|
||||
|
||||
// Return if the command is restricted to developers (and the user is not a developer)
|
||||
if (command.devOnly === true && this.client.config.ownerIDs.includes(message.author.id) !== true) {
|
||||
return message.channel.send(
|
||||
`${this.client.config.emojis.permError} ${message.author.username} is not in the sudoers file. This incident will be reported.`
|
||||
);
|
||||
}
|
||||
|
||||
// Cooldown
|
||||
if (this.client.cooldowns.get(command.name).has(message.author.id)) {
|
||||
const timestamp = this.client.cooldowns.get(command.name).get(message.author.id);
|
||||
const currentTime = Date.now();
|
||||
const cooldown = command.cooldown / 1000;
|
||||
const timePassed = Math.floor((currentTime - timestamp) / 1000);
|
||||
return message.channel.send(
|
||||
`${this.client.config.emojis.wait} ${message.author.mention}, you need to wait ${cooldown - timePassed} seconds before using this command again.`
|
||||
);
|
||||
} else {
|
||||
this.client.cooldowns.get(command.name).set(message.author.id, new Date());
|
||||
setTimeout(() => {
|
||||
this.client.cooldowns.get(command.name).delete(message.author.id);
|
||||
}, this.client.commands.get(command.name).cooldown);
|
||||
}
|
||||
|
||||
try {
|
||||
command.run(this.client, message, args, data);
|
||||
this.client.logger.command(`Ran ${command.name}`);
|
||||
} catch (error) {
|
||||
this.client.logger.error('COMMAND_EXECUTION_ERROR', `${command.name}: ${error.stack}`);
|
||||
message.channel.send(`${this.client.config.emojis.botError} An error occured when I was trying to run this command. I've sent through the details of the error to my developers.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageHandler;
|
|
@ -34,7 +34,7 @@ class Logger {
|
|||
|
||||
/**
|
||||
* Log something related to being successful
|
||||
* @param {string} title The title of the log enty
|
||||
* @param {string} title The title of the log entry
|
||||
* @param {string} body The body of the log entry
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -44,7 +44,7 @@ class Logger {
|
|||
|
||||
/**
|
||||
* Log something related to a warning
|
||||
* @param {string} title The title of the log enty
|
||||
* @param {string} title The title of the log entry
|
||||
* @param {string} body The body of the log entry
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -54,7 +54,7 @@ class Logger {
|
|||
|
||||
/**
|
||||
* Log something related to an error
|
||||
* @param {string} title The title of the log enty
|
||||
* @param {string} title The title of the log entry
|
||||
* @param {string} body The body of the log entry
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -64,7 +64,7 @@ class Logger {
|
|||
|
||||
/**
|
||||
* Log something related to debugging
|
||||
* @param {string} title The title of the log enty
|
||||
* @param {string} title The title of the log entry
|
||||
* @param {string} body The body of the log entry
|
||||
* @returns {void}
|
||||
*/
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
"userAgent": "",
|
||||
|
||||
"ownerIDs": [""],
|
||||
"devIds": [""],
|
||||
|
||||
"clientId": "",
|
||||
|
||||
"keys": {
|
||||
"sentry": "",
|
||||
|
@ -18,13 +20,25 @@
|
|||
"database": "",
|
||||
"password": "",
|
||||
"port": 0000
|
||||
}
|
||||
},
|
||||
|
||||
"emojis": {
|
||||
"success": "<:success:466995111885144095>",
|
||||
"botError": "<:warning:701681841190600704>",
|
||||
"userError": "<:error:466995152976871434>",
|
||||
"permError": "<:denied:466995195150336020>",
|
||||
"wait": "<:wait:467115775849922570>"
|
||||
"wait": "<:wait:467115775849922570>",
|
||||
"ActiveDeveloper": "<:ActiveDeveloper:1053643399477084261>",
|
||||
"VerifiedDeveloper": "<:VerifiedDeveloper:1053643383631003709>",
|
||||
"BugHunterLevel1": "<:BugHunterLevel1:1053643390853595186>",
|
||||
"BugHunterLevel2": "<:BugHunterLevel2:1053643388836130826>",
|
||||
"CertifiedModerator": "<:CertifiedModerator:1053643397103104070>",
|
||||
"HypeSquadOnlineHouse1": "<:HypeSquadOnlineHouse1:1053643379948400730>",
|
||||
"HypeSquadOnlineHouse2": "<:HypeSquadOnlineHouse2:1053643378253897758>",
|
||||
"HypeSquadOnlineHouse3": "<:HypeSquadOnlineHouse3:1053643381823246388>",
|
||||
"Hypesquad": "<:Hypesquad:1053643395215663144>",
|
||||
"Partner": "<:Partner:1053643375921860618>",
|
||||
"PremiumEarlySupporter": "<:PremiumEarlySupporter:1053643386550243338>",
|
||||
"Staff": "<:Staff:1053643393248534652>"
|
||||
}
|
||||
}
|
2644
package-lock.json
generated
2644
package-lock.json
generated
File diff suppressed because it is too large
Load diff
20
package.json
20
package.json
|
@ -4,15 +4,17 @@
|
|||
"description": "Made with <3 by mudkipscience",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@sentry/node": "^6.9.0",
|
||||
"@devraelfreeze/discordjs-pagination": "^2.6.8",
|
||||
"@sentry/node": "^7.28.1",
|
||||
"bufferutil": "^4.0.3",
|
||||
"chalk": "^4.1.0",
|
||||
"dayjs": "^1.10.6",
|
||||
"discord.js": "^13.0.0-dev.1dcad05.1626134620",
|
||||
"chalk": "^4.1.2",
|
||||
"discord.js": "^14.7.1",
|
||||
"erlpack": "^0.1.3",
|
||||
"eslint": "^7.30.0",
|
||||
"eslint": "^8.30.0",
|
||||
"fs-readdir-recursive": "^1.1.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"moment": "^2.29.4",
|
||||
"moment-duration-format": "^2.3.2",
|
||||
"node-fetch": "^2.6.7",
|
||||
"pg": "^8.5.1",
|
||||
"pg-format": "^1.0.4",
|
||||
"pretty-ms": "^7.0.1",
|
||||
|
@ -25,12 +27,12 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/woomyware/v2.git"
|
||||
"url": "git+https://gitdab.com/embee/woomy-v2.git"
|
||||
},
|
||||
"author": "Emily J. (mudkipscience)",
|
||||
"license": "AGPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/woomyware/v2/issues"
|
||||
"url": "https://gitdab.com/embee/woomy-v2/issues"
|
||||
},
|
||||
"homepage": "https://github.com/woomyware/v2#readme"
|
||||
"homepage": "https://gitdab.com/embee/woomy-v2"
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (name, category) {
|
||||
this.name = name,
|
||||
this.category = category,
|
||||
this.enabled = true,
|
||||
this.devOnly = false,
|
||||
this.aliases = [],
|
||||
this.userPerms = [],
|
||||
this.botPerms = [],
|
||||
this.cooldown = 2000,
|
||||
this.help = {
|
||||
description: '',
|
||||
arguments: '',
|
||||
details: '',
|
||||
examples: ''
|
||||
};
|
||||
}
|
||||
|
||||
run (client, message, args, data) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
module.exports = class {
|
||||
constructor (wsEvent) {
|
||||
this.wsEvent = wsEvent;
|
||||
}
|
||||
|
||||
async run (client) { //eslint-disable-line no-unused-vars
|
||||
|
||||
}
|
||||
};
|
Loading…
Reference in a new issue