mirror of
https://github.com/ION606/selmerBot.git
synced 2026-05-14 21:26:54 +00:00
Compare commits
22 Commits
v1.0.1-preslash
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| df4d21f487 | |||
| 697b1c0c76 | |||
| 914dc7ece4 | |||
| ebb34c9f89 | |||
| 5292bd8a09 | |||
| 9f5f94d49e | |||
| a41e602036 | |||
| 7b247e462f | |||
| 6ae725d211 | |||
| 1b1932015e | |||
| 1324c3db8f | |||
| b75cb7b495 | |||
| df7d79e69a | |||
| 2ff7a84bee | |||
| 8a47943764 | |||
| 47dc8e37cd | |||
| c85bb3ef45 | |||
| 4043038162 | |||
| 18894961bd | |||
| d69e7e0479 | |||
| b30fdc9e7f | |||
| e1002d748d |
@@ -1,8 +1,12 @@
|
||||
node_modules
|
||||
config.json
|
||||
backup.json
|
||||
*.env
|
||||
*.sqlite
|
||||
*.txt
|
||||
!spec/LevelsXP.txt
|
||||
*.sqlite
|
||||
temp.js
|
||||
|
||||
easySetup.js
|
||||
meme.js
|
||||
@@ -1,3 +1,5 @@
|
||||
# THIS REPOSITORY HAS BEEN MIRRORED TO THE SELMER BOT ORGANIZATION AND IS NOW READ-ONLY
|
||||
|
||||
# selmerBot
|
||||
|
||||
Authors: ION606, MajorDrools
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
name: 'extracredit',
|
||||
description: "Selmer Bot Dm's you for some *AHEM* extra credit",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
let dm;
|
||||
let num = Math.floor(Math.random() * 10);
|
||||
|
||||
@@ -41,7 +41,10 @@ module.exports = {
|
||||
break;
|
||||
}
|
||||
|
||||
let ID = message.member.id;
|
||||
message.client.users.fetch(ID).then(user => user.send(dm));
|
||||
}
|
||||
// let ID = interaction.user.id;
|
||||
// message.client.users.fetch(ID).then(user => user.send(dm));
|
||||
interaction.user.send(dm);
|
||||
interaction.reply({content: "Extra Credit sent 😉", ephemeral: true});
|
||||
},
|
||||
options: []
|
||||
}
|
||||
@@ -1,24 +1,15 @@
|
||||
module.exports = {
|
||||
name: 'arrow',
|
||||
description: 'Engage in a trademarked activity and throw an arrow at a trash can',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
let counter = 0;
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
arrow = '>';
|
||||
while (true) {
|
||||
arrow = '-' + arrow;
|
||||
message.channel.send(arrow);
|
||||
await message.channel.messages.fetch({limit: 1}).then(messages => {
|
||||
message.channel.bulkDelete(messages);
|
||||
});
|
||||
counter ++;
|
||||
if (counter >= 5) {
|
||||
message.channel.messages.fetch({limit: 1}).then(messages => {
|
||||
message.channel.bulkDelete(messages);
|
||||
});
|
||||
await interaction.reply(arrow);
|
||||
for (let i = 0; i < 5; i++) {
|
||||
arrow = '-' + arrow
|
||||
await interaction.editReply(arrow);
|
||||
}
|
||||
|
||||
arrow = arrow + '🗑️';
|
||||
message.channel.send(arrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
await interaction.editReply(arrow);
|
||||
}, options: []
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
const { addxp, BASE } = require('../db/econ.js');
|
||||
|
||||
|
||||
async function setCard(bot, interaction) {
|
||||
bot.mongoconnection.then(async (client) => {
|
||||
const dbo = client.db(interaction.guildId).collection('SETUP');
|
||||
dbo.findOne({_id: "LEVELING"}).then((doc) => {
|
||||
const bkBuffer = Buffer.from(doc.card, 'base64');
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function textToLevels(bot, message, xp_list) {
|
||||
if (!bot.inDebugMode && message.guild.id == bot.home_server) { return; }
|
||||
|
||||
const author = message.author;
|
||||
// doc.xp + (BASE.XP * doc.rank)
|
||||
bot.mongoconnection.then((client) => {
|
||||
const serverOpts = client.db(message.guild.id).collection('SETUP');
|
||||
serverOpts.findOne({_id: "LEVELING"}).then((doc) => {
|
||||
if (!doc) {
|
||||
serverOpts.insertOne({_id: "LEVELING", enabled: false, card: undefined, text: undefined, col: "#FFFFFF"});
|
||||
const server = bot.guilds.cache.get(message.guild.id);
|
||||
server.members.fetch(message.guild.ownerId).then(function(owner) {
|
||||
// Implement `setup leveling enable`
|
||||
owner.send("Interactive Leveling has been added to your server!\nTo enable it, use `/setup leveling enable`");
|
||||
});
|
||||
} else if (doc.enabled) {
|
||||
const dbo = client.db(message.guild.id).collection(author.id);
|
||||
dbo.findOne({"balance": {$exists: true}}).then((doc) => {
|
||||
const newXp = doc.xp + Math.ceil((BASE.XP * doc.rank) / 4);
|
||||
addxp(bot, message, dbo, newXp, xp_list, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {textToLevels};
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
name: "profile",
|
||||
description: "Posts a description of Monsieur Sleemer himself",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor('#002eff')
|
||||
.setTitle('My professional resume')
|
||||
@@ -14,6 +14,6 @@ module.exports = {
|
||||
{name: '\t__Epithet 2__', value: "_There is no god, only logic_"}
|
||||
);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
}
|
||||
interaction.reply({ embeds: [newEmbed] });
|
||||
}, options: []
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
name: 'quotes',
|
||||
description: "A public version of Extra Credit",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
let dm;
|
||||
let num = Math.floor(Math.random() * 10);
|
||||
|
||||
@@ -41,6 +41,7 @@ module.exports = {
|
||||
break;
|
||||
}
|
||||
|
||||
message.channel.send(dm);
|
||||
}
|
||||
interaction.reply(dm);
|
||||
},
|
||||
options: []
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
const Discord = require('discord.js');
|
||||
|
||||
/**
|
||||
* @description a fun little easter egg mention function
|
||||
* @param {Discord.Message} message
|
||||
*/
|
||||
function replies(bot, message) {
|
||||
const c = message.content.replace(`<@${bot.user.id}>`, "").toLowerCase().trim();
|
||||
var s = "";
|
||||
|
||||
switch (c) {
|
||||
case "hi":
|
||||
case "hello":
|
||||
case "hya":
|
||||
s = "Hi there! :wave:";
|
||||
break;
|
||||
|
||||
case "i love you":
|
||||
s = "seek help :smile:";
|
||||
break;
|
||||
|
||||
case "chicken nuggets":
|
||||
s = "nom nom nom";
|
||||
break;
|
||||
|
||||
case "chimkin nungits":
|
||||
s = "marry me :heart_eyes:";
|
||||
break;
|
||||
|
||||
case "😉":
|
||||
s = ":wink:";
|
||||
break;
|
||||
|
||||
case "😜":
|
||||
s = "😜";
|
||||
break;
|
||||
|
||||
case "🍆":
|
||||
case "🍑":
|
||||
case "🍌":
|
||||
s = "❌";
|
||||
break;
|
||||
|
||||
case "💩":
|
||||
s = "🤮";
|
||||
break;
|
||||
|
||||
default: s = "I'm not sure what that means! Please use `/help` for a comprehensive list of commands!\n\n_PS - If you want to make full use of the bot's AI capabilities, consider Selmer Bot Premium. See more at https://selmerbot.com/premium _";
|
||||
}
|
||||
|
||||
message.reply(s).catch(() => { message.channel.send(s); });
|
||||
}
|
||||
|
||||
module.exports = replies;
|
||||
@@ -1,11 +1,11 @@
|
||||
const { MessageEmbed, MessageActionRow, MessageButton, Interaction } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: 'code',
|
||||
description: 'See where Selmer bot\'s code is stored! (you can also use _!repo_)',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
name: 'repo',
|
||||
description: 'See where Selmer bot\'s code is stored!',
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const embd = new MessageEmbed()
|
||||
.setAuthor({ name: "Selmer Bot", url: bot.inviteLink, iconURL: bot.user.displayAvatarURL() })
|
||||
.setAuthor({ name: "Selmer Bot", url: bot.user.inviteLink, iconURL: bot.user.displayAvatarURL() })
|
||||
.setThumbnail("https://github.com/ION606/selmer-bot-website/blob/main/assets/Selmer-icon.png?raw=true") // .setThumbnail('https://repository-images.githubusercontent.com/460670550/43932b23-d795-4334-838f-f33ee8f795c4')
|
||||
.setDescription("Selmer Bot was created by ION606");
|
||||
|
||||
@@ -18,7 +18,7 @@ module.exports = {
|
||||
|
||||
new MessageButton()
|
||||
.setStyle("LINK")
|
||||
.setURL("https://www.selmerbot.com/")
|
||||
.setURL("https://selmerbot.com/")
|
||||
.setLabel("Website"),
|
||||
|
||||
new MessageButton()
|
||||
@@ -27,6 +27,7 @@ module.exports = {
|
||||
.setCustomId("sbtutorial")
|
||||
]);
|
||||
|
||||
message.reply({ embeds: [embd], components: [row] })
|
||||
}
|
||||
interaction.reply({ embeds: [embd], components: [row] });
|
||||
}, options: [],
|
||||
isDm: true
|
||||
}
|
||||
@@ -3,17 +3,17 @@ const { MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('
|
||||
|
||||
//Intro, setup/logging, Econ, Moderation, anime/manga, games, Selmer Specific, Misc, DMS/Premium
|
||||
const tutoText = [
|
||||
"__**Hello, and welcome to the Selmer Bot tutorial!**__\nIn this tutorial, I will walk you through the various commands and features of Selmer Bot!\n\nTo progress to the next page, click the right arrow at the bottom of this message.\nTo go back to the previous page, click the left arrow",
|
||||
"__**SETUP AND LOGGING**__\nSet up your server to take full advantage of Selmer Bot's features, this includes moderation logging, custom welcome messages, calendar event pings and more!\n_Note: Most of these commands are only available to the server owner_\n\n__***COMMANDS***__\n!setup help welcome, !setup help logs, !setup help announcement, !setup welcome_channel, !setup welcome_message, !setup keep_logs, !setup log_channel, !setup log_severity, !setup announcement_channel, !setup announcement_role",
|
||||
"__**ECONOMY**__\nThese commands have to do with the inventory and currency system Selmer Bot uses, although I should note that as of now Selmer Coin holds no IRL value ;-;\n\n__***COMMANDS***__\n!inventory, !buy, !sell, !shop, !work, !rank, !balance",
|
||||
"__**MODERATION**__\nI mean....\n\n***__COMMANDS__***\n!help admin, !warn, !mute, !unmute, !kick, !ban, !unban, !lock, !unlock, !serverlock",
|
||||
"__**AMIME AND MANGA**__\nGet info on your favorite Anime or Manga as a stat-sheet, a fancy embed, or have Selmer Bot describe it to you!\n\n__***COMMANDS***__\n!asearch, !msearch",
|
||||
"__**GAMES**__\nAt the moment Selmer Bot only offers two games: Trivia and Tic Tac Toe. Both games can be played with other people, but only Trivia can be played solo. Selmer Bot also has a battle game where you can use weapons, potions, attack and defend, but this is still in beta\n\n__***COMMANDS***__\n!help game, !game battle !game tictactoe, !game trivia, !game equip, !game status, !game hp, !game classes, !game quit",
|
||||
"__**SELMER SPECIFIC**__\nThese commands will probably be found nowhere else!\nThese include quotes (For legal reasons I have to state they aren't real quotes, mostly), as well as varius other things I based on good old Selmer\n\n__***COMMANDS***__\n!arrow, !extracredit, !tuto, !profile, !quotes",
|
||||
"__**MISCELLANEOUS**__\nThese are the commands that are not really in any of the other categories. Don't be fooled, these are actually some of the most useful commands Selmer Bot has to offer. From playing music to web scraping to memes, I'm sure Selmer Bot has what you're looking for!\n\n__***COMMANDS***__\n!help, !kareoke, !link, !meme, !pickupline, !audio, !react, !scrape, !stocks, !crypto",
|
||||
"__**DM COMMANDS**__\nThese commands will only work in DM's. All these commands will only work with Selmer Bot Premium (it's on the next page).\nThese features include Reminders (AKA a calendar) and Selmer Bot's own chat AI!\n\n__***COMMANDS***__\n!chat, !startconvo, !endconvo, !premium",
|
||||
"__**SELMER BOT PREMIUM**__\nUse an AI chat, complete with semi-accurate IRL data, have Selmer Bot remind you of events with an easy-to-use interface and even a clickable calendar on the Selmer Bot website (_www.selmerbot.com_)\n\n__***COMMANDS***__\n!premium, !premium buy, !premium manage, !reminders",
|
||||
"__**Thank you for completing the Selmer Bot Tutorial!**__\n\nTry out Selmer Bot's features, play the games and most importantly, have fun!\n\n-The Selmer Bot Team AKA ION606"
|
||||
"__**Hello, and welcome to the Selmer Bot tutorial**__\nIn this tutorial, I will walk you through the various commands and features of Selmer Bot\n\nTo progress to the next page, click the right arrow at the bottom of this message.\nTo go back to the previous page, click the left arrow",
|
||||
"__**SETUP AND LOGGING**__\nSet up your server to take full advantage of Selmer Bot's features, this includes moderation logging, custom welcome messages, calendar event pings and more\n_Note: Most of these commands are only available to the server owner_\n\n__***COMMANDS***__\nsetup",
|
||||
"__**ECONOMY**__\nThese commands have to do with the inventory and currency system Selmer Bot uses, although I should note that as of now Selmer Coin holds no IRL value ;-;\n\n__***COMMANDS***__\ninventory, buy, sell, shop, work, rank, balance",
|
||||
"__**MODERATION**__\nI mean....\n\n***__COMMANDS__***\nhelp admin, warn, mute, unmute, kick, ban, unban, lock, unlock, serverlock\n\n__***NOTE:***__\nThe user needs to have either _kick_ or _ban_ permissions to use these",
|
||||
"__**AMIME AND MANGA**__\nGet info on your favorite Anime or Manga as a stat-sheet, a fancy embed, or have Selmer Bot describe it to you\n\n__***COMMANDS***__\nasearch, msearch",
|
||||
"__**GAMES**__\nAt the moment Selmer Bot offers three games: Trivia, Tic Tac Toe, and Minesweeper. Both Trivia and Tic Tac Toe can be played with other people. Trivia and Minesweeper can also be played solo. Selmer Bot also has a battle game where you can use weapons, potions, attack and defend, but this is still in beta\n\n__***COMMANDS***__\nhelp game, game battle game tictactoe, game trivia, game equip, game status, game hp, game classes, game quit\n\n__**NOTE**__\nDue to how complicated this feature is, it will not be migrated to slash commands for now",
|
||||
"__**SELMER SPECIFIC**__\nThese commands will probably be found nowhere else\nThese include quotes (For legal reasons I have to state they aren't real quotes, mostly), as well as varius other things I based on good old Selmer\n\n__***COMMANDS***__\narrow, extracredit, tuto, profile, quotes",
|
||||
"__**MISCELLANEOUS**__\nThese are the commands that are not really in any of the other categories. Don't be fooled, these are actually some of the most useful commands Selmer Bot has to offer. From playing music to web scraping to memes, I'm sure Selmer Bot has what you're looking for\n\n__***COMMANDS***__\nhelp, kareoke, link, meme, pickupline, audio, react, scrape, stocks, crypto",
|
||||
"__**DM COMMANDS**__\nThese commands will only work in DM's. All these commands will only work with Selmer Bot Premium (it's on the next page).\nThese features include Reminders (AKA a calendar) and Selmer Bot's own chat AI\n\n__***COMMANDS***__\nchat, startconvo, endconvo, premium",
|
||||
"__**SELMER BOT PREMIUM**__\nUse an AI chat, complete with semi-accurate IRL data, have Selmer Bot remind you of events with an easy-to-use interface and even a clickable calendar on the Selmer Bot website (_ https://selmerbot.com _)\n\n__***COMMANDS***__\npremium, premium buy, premium manage, reminders",
|
||||
"__**Thank you for completing the Selmer Bot Tutorial**__\n\nTry out Selmer Bot's features, play the games and most importantly, have fun\n\n-The Selmer Bot Team AKA ION606"
|
||||
];
|
||||
|
||||
//If the page number == 0 and refered == false, then interaction will be a Message
|
||||
@@ -29,7 +29,7 @@ function postEmbd(bot, interaction, page, refered) {
|
||||
te.setAuthor(author)
|
||||
.setTitle("Selmer Bot Tutorial")
|
||||
.setDescription(tutoText[page])
|
||||
.setURL('https://www.selmerbot.com/')
|
||||
.setURL('https://selmerbot.com/')
|
||||
.setFooter({ text: `Page ${page + 1}` });
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ function postEmbd(bot, interaction, page, refered) {
|
||||
row.addComponents(prevbtn, nextbtn);
|
||||
|
||||
if (page > 0 || refered) {
|
||||
interaction.update({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [te], components: [row] });
|
||||
interaction.update({ content: '_Note: To see a full list of reminder stats visit selmerbot.com _', embeds: [te], components: [row] });
|
||||
} else {
|
||||
interaction.reply({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [te], components: [row] });
|
||||
interaction.channel.send({ content: '_Note: To see a full list of reminder stats visit selmerbot.com _', embeds: [te], components: [row] });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ function postEmbd(bot, interaction, page, refered) {
|
||||
module.exports = {
|
||||
name: 'tuto',
|
||||
description: 'An introduction command to Selmer Bot',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
postEmbd(bot, message, 0, false);
|
||||
}, postEmbd
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
postEmbd(bot, interaction, 0, false);
|
||||
}, postEmbd,
|
||||
options: []
|
||||
}
|
||||
@@ -1,28 +1,33 @@
|
||||
const { checkRole } = require('./verify.js');
|
||||
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: 'lock',
|
||||
description: 'Lock a channel',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
const guild = bot.guilds.cache.get(message.guild.id);
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const arg = interaction.options.data[0];
|
||||
const guild = bot.guilds.cache.get(interaction.guildId);
|
||||
|
||||
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||
checkRole(bot, guild, interaction.user.id).then((isAllowed) => {
|
||||
if (isAllowed) { return interaction.reply('Insufficient Permissions!'); }
|
||||
|
||||
var channel;
|
||||
if (args[0]) {
|
||||
channel = guild.channels.cache.find(channel => channel.name.toLowerCase() === args[0]);
|
||||
if (arg) {
|
||||
channel = arg.channel;
|
||||
} else {
|
||||
channel = message.channel;
|
||||
channel = interaction.channel;
|
||||
}
|
||||
|
||||
if (!channel) { return message.reply("This channel does not exist!"); }
|
||||
|
||||
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||
let role = interaction.guild.roles.cache.find(r => r.name === "@everyone");
|
||||
channel.permissionOverwrites.edit(role.id, {
|
||||
VIEW_CHANNEL: true,
|
||||
SEND_MESSAGES: false,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
ATTACH_FILES: false
|
||||
});
|
||||
}
|
||||
|
||||
interaction.reply(`${channel} has been locked!`);
|
||||
});
|
||||
},
|
||||
options: [{name: 'channel', description: 'The channel to lock (defaults to current channel)', type: Constants.ApplicationCommandOptionTypes.CHANNEL, required: false}]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//@ts-check
|
||||
const { log, SEVCODES } = require('../log.js');
|
||||
const { checkRole } = require('./verify.js');
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
|
||||
function modHelp() {
|
||||
@@ -15,7 +16,7 @@ function kick(guild, user) {
|
||||
}
|
||||
|
||||
|
||||
async function toggle_ban(guild, message, args, ban, reason) {
|
||||
async function toggle_ban(guild, interaction, args, ban, reason) {
|
||||
|
||||
if (ban) {
|
||||
guild.members.ban(args);
|
||||
@@ -27,7 +28,7 @@ async function toggle_ban(guild, message, args, ban, reason) {
|
||||
i++
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
message.guild.bans.fetch().then((users) => {
|
||||
interaction.guild.bans.fetch().then((users) => {
|
||||
const userObj = users.filter((u) => {
|
||||
return (`${u.user.username}#${u.user.discriminator}` == user);
|
||||
}).first();
|
||||
@@ -51,22 +52,22 @@ async function toggle_ban(guild, message, args, ban, reason) {
|
||||
}
|
||||
|
||||
|
||||
function toggle_mute(bot, guild, command, message, user, reason, mute) {
|
||||
function toggle_mute(bot, guild, command, interaction, user, reason, mute) {
|
||||
const mutedRole = guild.roles.cache.find((role) => role.name.toLowerCase() === 'muted');
|
||||
const guser = guild.members.cache.get(user.id);
|
||||
// if there is no `Muted` role, send an error
|
||||
if (!mutedRole) { return message.channel.send('There is no "muted" role on this server. Please create one then try again'); }
|
||||
if (!mutedRole) { return interaction.reply('There is no "muted" role on this server. Please create one then try again'); }
|
||||
|
||||
if (mute) {
|
||||
if (guser.roles.cache.get(mutedRole.id) == undefined) {
|
||||
guser.roles.add(mutedRole);
|
||||
log(bot, message, command, user, reason, SEVCODES.low);
|
||||
} else { message.reply("This user is already muted!"); }
|
||||
log(bot, interaction, command, user, reason, SEVCODES.low);
|
||||
} else { interaction.reply("This user is already muted!"); }
|
||||
} else {
|
||||
if (guser.roles.cache.get(mutedRole.id) != undefined) {
|
||||
guser.roles.remove(mutedRole);
|
||||
log(bot, message, command, user, reason, SEVCODES.none);
|
||||
} else { message.reply("This user is not muted!"); }
|
||||
log(bot, interaction, command, user, reason, SEVCODES.none);
|
||||
} else { interaction.reply("This user is not muted!"); }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -94,43 +95,48 @@ function timeOut(bot, user, message, args, command, reason) {
|
||||
}
|
||||
|
||||
|
||||
function moderation_handler(bot, message, args, command) {
|
||||
const guild = message.guild;
|
||||
function moderation_handler(bot, interaction, command) {
|
||||
const guild = interaction.guild;
|
||||
|
||||
//Verify
|
||||
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permission!'); }
|
||||
checkRole(bot, guild, interaction.user.id).then((isAllowed) => {
|
||||
if (!isAllowed) { return interaction.reply('Insufficient Permission!'); }
|
||||
|
||||
let mentioned = message.mentions.users.first();
|
||||
if (mentioned && mentioned.id == message.author.id) { return message.reply(`You can't ${command} yourself!`); }
|
||||
const mentioned = interaction.options.data.filter((arg) => { return (arg.name == 'user'); })[0].user;
|
||||
if (mentioned && mentioned.id == interaction.user.id) { return interaction.reply(`You can't ${command} yourself!`); }
|
||||
|
||||
const reason = args.slice(1).join(' ');
|
||||
const reasonInit = interaction.options.data.filter((arg) => { return (arg.name == 'reason'); })[0];
|
||||
const reason = (reasonInit) ? reasonInit.value : "None";
|
||||
|
||||
if (message.mentions.members.first() && (message.mentions.members.first().roles.highest.position > message.guild.members.resolve(bot.user).roles.highest.position)) {
|
||||
return message.reply("I'm not high enough in the role hierarchy to do that!\n_To raise my place, go to **Server Settings -> Roles** then drag me up!_");
|
||||
const user = guild.members.resolve(mentioned.id);
|
||||
|
||||
if (user && (user.roles.highest.position > guild.members.resolve(bot.user).roles.highest.position)) {
|
||||
return interaction.reply("I'm not high enough in the role hierarchy to do that!\n_To raise my place, go to **Server Settings -> Roles** then drag me up!_");
|
||||
}
|
||||
|
||||
if (command != 'unban' && !mentioned || !reason) { return message.channel.send(`Please use the following format: _!<command> <user> <reason>`); }
|
||||
if (command == 'unban' && !args[0] && !reason) { return message.channel.send("Please use the following format: _!unban <user_tag>#<user_discriminator> <reason>\nExample: _!unban John#1122_"); }
|
||||
|
||||
// if (command != 'unban' && !mentioned || !reason) { return message.channel.send(`Please use the following format: _!<command> <user> <reason>`); }
|
||||
// if (command == 'unban' && !args[0] && !reason) { return message.channel.send("Please use the following format: _!unban <user_tag>#<user_discriminator> <reason>\nExample: _!unban John#1122_"); }
|
||||
// if (command == 'ban' && guild.members.cache.get(mentioned.id).bannable) { message.reply("This user is not bannable!"); } //Broken
|
||||
// if (command == 'ban' && !message.guild.members.cache.get(mentioned.id)) { message.reply("This user is not in the server"); }
|
||||
|
||||
switch (command) {
|
||||
case 'kick': kick(guild, mentioned);
|
||||
log(bot, message, command, mentioned, reason, SEVCODES.medium);
|
||||
log(bot, interaction, command, mentioned, reason, SEVCODES.medium);
|
||||
break;
|
||||
|
||||
case 'ban': toggle_ban(guild, message, mentioned, true, reason);
|
||||
log(bot, message, command, mentioned, reason, SEVCODES.high);
|
||||
case 'ban': toggle_ban(guild, interaction, mentioned, true, reason);
|
||||
log(bot, interaction, command, mentioned, reason, SEVCODES.high);
|
||||
break;
|
||||
|
||||
//Leave the then() catch() thing, it needs to be async
|
||||
case 'unban': toggle_ban(guild, message, args, false, reason).then((user) => { log(bot, message, command, user, reason, SEVCODES.none)}).catch((note) => { message.reply(note); });
|
||||
case 'unban': toggle_ban(guild, interaction, false, reason).then((user) => { log(bot, interaction, command, user, reason, SEVCODES.none)}).catch((note) => { interaction.reply(note); });
|
||||
break;
|
||||
|
||||
case 'mute': toggle_mute(bot, guild, command, message, mentioned, reason, true);
|
||||
case 'mute': toggle_mute(bot, guild, command, interaction, mentioned, reason, true);
|
||||
break;
|
||||
|
||||
case 'unmute': toggle_mute(bot, guild, command, message, mentioned, reason, true);
|
||||
case 'unmute': toggle_mute(bot, guild, command, interaction, mentioned, reason, true);
|
||||
break;
|
||||
|
||||
// case 'timeout': timeOut(bot, mentioned, message, args, command, reason);
|
||||
@@ -139,9 +145,10 @@ function moderation_handler(bot, message, args, command) {
|
||||
|
||||
default: console.log(`ERROR! Moderation Command "${command}" has somehow been used!`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: 'moderation',
|
||||
moderation_handler, modHelp
|
||||
moderation_handler, modHelp,
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
const {Interaction, Constants, Modal, TextInputComponent, MessageActionRow, MessageEmbed, MessageButton, Message} = require('discord.js');
|
||||
const { checkRole } = require('./verify.js');
|
||||
const { isValidUrl } = require('../dev only/setPresence.js');
|
||||
const embdList = [{name: 'Title'}, {name: 'Image', desc: 'The image url'}, {name: 'Thumbnail', desc: 'The thumbnail url'}, {name: 'URL'}, {name: 'Description', desc: 'Use {ROLE} to insert the role'}];
|
||||
|
||||
|
||||
async function postForm(interaction, role, useEmoji, txt) {
|
||||
// Create the modal
|
||||
const modal = new Modal();
|
||||
|
||||
modal.setTitle('Create a new reaction role!')
|
||||
.setCustomId(`reactionModal|${role.id}|${useEmoji}|${txt}`);
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const tempInp = new TextInputComponent()
|
||||
.setCustomId(embdList[i].name.toLowerCase())
|
||||
.setLabel(embdList[i].name);
|
||||
|
||||
if (embdList[i].name != 'Description') {
|
||||
tempInp.setStyle('SHORT');
|
||||
} else {
|
||||
tempInp.setStyle('PARAGRAPH');
|
||||
}
|
||||
|
||||
if (embdList[i].desc) {
|
||||
tempInp.setPlaceholder(embdList[i].desc);
|
||||
}
|
||||
|
||||
modal.addComponents(new MessageActionRow().addComponents(tempInp));
|
||||
}
|
||||
|
||||
// Show the modal to the user
|
||||
interaction.showModal(modal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
function postNotif(interaction, roleId, guild, user) {
|
||||
const role = guild.roles.cache.get(roleId);
|
||||
|
||||
const embd = new MessageEmbed()
|
||||
.setTitle("You got a new role!")
|
||||
.setDescription(`You were given the *${role.name}* role in **${guild}**\n_You did this by reacting to [this message](${interaction.message.url})_`)
|
||||
.setTimestamp()
|
||||
.setThumbnail(guild.iconURL());
|
||||
user.send({embeds: [embd]});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
function processForm(interaction, bot) {
|
||||
const roleId = interaction.customId.split('|')[1];
|
||||
const title = interaction.fields.getTextInputValue('title');
|
||||
const img = interaction.fields.getTextInputValue('image');
|
||||
const thumb = interaction.fields.getTextInputValue('thumbnail');
|
||||
const url = interaction.fields.getTextInputValue('url');
|
||||
var desc = interaction.fields.getTextInputValue('description');
|
||||
|
||||
const useEmoji = (interaction.customId.split('|')[2] == 'true');
|
||||
var txt = interaction.customId.split('|')[3];
|
||||
var emoji = undefined;
|
||||
|
||||
//Emoji?
|
||||
|
||||
if (Number.isInteger(Number(txt))) {
|
||||
emoji = interaction.guild.emojis.cache.get(txt);
|
||||
}
|
||||
|
||||
if (desc.indexOf("{ROLE}") != -1) {
|
||||
desc = desc.replaceAll("{ROLE}", `<@&${roleId}>`);
|
||||
}
|
||||
|
||||
const embd = new MessageEmbed()
|
||||
.setTitle(title)
|
||||
.setDescription(desc || "");
|
||||
|
||||
if (img && isValidUrl(img)) embd.setImage(img);
|
||||
if (thumb && isValidUrl(thumb)) embd.setThumbnail(thumb);
|
||||
if (url && isValidUrl(url)) embd.setURL(url);
|
||||
|
||||
if (useEmoji) {
|
||||
interaction.channel.send({embeds: [embd]}).then((msg) => {
|
||||
try {
|
||||
msg.react(emoji || txt);
|
||||
|
||||
const filter = (reaction, user) => {
|
||||
return (!user.bot && (reaction.emoji.id == txt || reaction.emoji.name == txt));
|
||||
};
|
||||
|
||||
const collector = msg.createReactionCollector({ filter });
|
||||
|
||||
collector.on('collect', (reaction, user) => {
|
||||
const guildUser = reaction.message.guild.members.cache.get(user.id);
|
||||
|
||||
if (guildUser.roles.cache.has(roleId)) {
|
||||
return guildUser.send("You already have this role!");
|
||||
}
|
||||
|
||||
guildUser.roles.add(roleId);
|
||||
postNotif(reaction, roleId, reaction.message.guild, guildUser);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const btn = new MessageButton()
|
||||
.setCustomId(`addRole|${roleId}`)
|
||||
.setStyle('PRIMARY');
|
||||
|
||||
if (emoji) btn.setEmoji(emoji);
|
||||
else btn.setLabel(txt);
|
||||
|
||||
const row = new MessageActionRow()
|
||||
.addComponents([btn]);
|
||||
|
||||
interaction.channel.send({embeds: [embd], components: [row]})
|
||||
}
|
||||
|
||||
interaction.reply({content: "Reaction role added!", ephemeral: true});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
* @returns
|
||||
*/
|
||||
function handleBtn(interaction) {
|
||||
const roleId = interaction.customId.split('|')[1];
|
||||
const user = interaction.guild.members.cache.get(interaction.user.id);
|
||||
if (user.roles.cache.has(roleId)) {
|
||||
return interaction.reply({content: "You already have this role!", ephemeral: true});
|
||||
}
|
||||
|
||||
user.roles.add(roleId);
|
||||
const role = interaction.guild.roles.cache.get(roleId);
|
||||
postNotif(interaction, role.id, interaction.guild, interaction.user);
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: "reactionrole",
|
||||
description: "Give someone a role when they react to a message",
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const user = interaction.user;
|
||||
|
||||
checkRole(bot, interaction.guild, user.id).then((isAdmin) => {
|
||||
if (isAdmin) {
|
||||
const role = interaction.options.data.filter((opt) => { return(opt.name == "role"); })[0].role;
|
||||
const useEmoji = interaction.options.data.filter((opt) => { return(opt.name == "useemoji"); })[0].value;
|
||||
var txt = interaction.options.data.filter((opt) => { return(opt.name == "text"); })[0].value;
|
||||
|
||||
if (txt.startsWith('<:') && txt.endsWith(">")) {
|
||||
const emoji = interaction.guild.emojis.cache.get(txt.split(":")[2].split(">")[0]);
|
||||
|
||||
if (!emoji) { return interaction.reply("Please use a valid emoji"); }
|
||||
|
||||
txt = txt.split(":")[2].split(">")[0];
|
||||
}
|
||||
|
||||
if (role.position >= interaction.guild.me.roles.highest.position ||!interaction.guild.me.permissions.has("MANAGE_ROLES")) {
|
||||
return interaction.reply({
|
||||
content: "I'm not high enough in the role hierarchy to do that!\n_To raise my place, go to **Server Settings -> Roles** then drag me up!_",
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
postForm(interaction, role, useEmoji, txt);
|
||||
}
|
||||
});
|
||||
}, processForm, handleBtn,
|
||||
options: [
|
||||
{name: "role", description: "The role to assign", type: Constants.ApplicationCommandOptionTypes.ROLE, required: true},
|
||||
{name: "useemoji", description: 'React using a button or emoji', type: Constants.ApplicationCommandOptionTypes.BOOLEAN, required: true},
|
||||
{name: 'text', description: 'The reaction emoji or button text', type: Constants.ApplicationCommandOptionTypes.STRING, required: true}
|
||||
]
|
||||
}
|
||||
@@ -1,18 +1,36 @@
|
||||
module.exports = {
|
||||
name: 'serverLock',
|
||||
description: 'Lock ***ALL CHANNELS*** for everyone with the "everyone" role - ***SERVER OWNER ONLY. FOR EMERGENCY USE ONLY***',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
const guild = bot.guilds.cache.get(message.guild.id);
|
||||
name: 'serverlock',
|
||||
description: 'Lock ALL CHANNELS for everyone with the "everyone" role - SERVER OWNER ONLY!',
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
if (interaction.guild.ownerId != interaction.user.id) { return interaction.reply('Insufficient Permissions!'); }
|
||||
|
||||
if (guild.ownerId != message.author.id) { return message.reply('Insufficient Permissions!'); }
|
||||
const role = interaction.guild.roles.cache.find(r => r.name === "@everyone");
|
||||
const arr = [];
|
||||
|
||||
message.guild.channels.cache.forEach(ch => {
|
||||
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||
VIEW_CHANNEL: false,
|
||||
interaction.guild.channels.cache.forEach(channel => {
|
||||
if (channel.permissionsFor(role).has("SEND_MESSAGES")) {
|
||||
channel.permissionOverwrites.edit(role.id, {
|
||||
VIEW_CHANNEL: true,
|
||||
SEND_MESSAGES: false,
|
||||
READ_MESSAGE_HISTORY: false,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
ATTACH_FILES: false
|
||||
});
|
||||
});
|
||||
|
||||
//Maybe add the message to the array to be edited/deleted after unlock
|
||||
if (channel.type == 'GUILD_TEXT') {
|
||||
channel.send(`***CHANNEL LOCKED BY ${interaction.user}***`);
|
||||
}
|
||||
|
||||
arr.push(channel.id);
|
||||
}
|
||||
});
|
||||
|
||||
bot.lockedChannels.set(interaction.guildId, arr);
|
||||
|
||||
interaction.reply(`***SERVER LOCKED BY ${interaction.user}***`);
|
||||
}, options: []
|
||||
}
|
||||
|
||||
// interaction.reply(```diff
|
||||
// - SERVER LOCKED
|
||||
// ```);
|
||||
@@ -1,21 +1,32 @@
|
||||
// const { checkRole } = require('./verify.js');
|
||||
//Maybe add a list to selmer Bot that adds the channels when locking
|
||||
|
||||
module.exports = {
|
||||
name: 'serverunlock',
|
||||
description: 'unlocks the channels locked using /serverlock',
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const guild = bot.guilds.cache.get(interaction.guildId);
|
||||
const role = interaction.guild.roles.cache.find(r => r.name === "@everyone");
|
||||
|
||||
// module.exports = {
|
||||
// name: 'serverUnlock',
|
||||
// description: 'unlocks ***ALL CHANNELS*** for everyone except the those with the "Selmer Bot Commands" role',
|
||||
// execute(message, args, Discord, Client, bot) {
|
||||
// const guild = bot.guilds.cache.get(message.guild.id);
|
||||
// if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||
if (interaction.guild.ownerId != interaction.user.id) { return interaction.reply('Insufficient Permissions!'); }
|
||||
|
||||
// if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||
const channelIds = bot.lockedChannels.get(interaction.guildId);
|
||||
|
||||
// message.guild.channels.cache.forEach(ch => {
|
||||
// channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||
// VIEW_CHANNEL: true,
|
||||
// SEND_MESSAGES: false,
|
||||
// READ_MESSAGE_HISTORY: false,
|
||||
// ATTACH_FILES: false
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
if (!channelIds) { return interaction.reply("No channels to unlock..."); }
|
||||
|
||||
channelIds.forEach(id => {
|
||||
const channel = guild.channels.cache.get(id);
|
||||
channel.permissionOverwrites.edit(role.id, {
|
||||
VIEW_CHANNEL: true,
|
||||
SEND_MESSAGES: true,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
ATTACH_FILES: true
|
||||
});
|
||||
});
|
||||
|
||||
bot.lockedChannels.set(interaction.guildId, []);
|
||||
interaction.reply(`Channels unlocked by ${interaction.user}`);
|
||||
},
|
||||
options: []
|
||||
}
|
||||
+149
-74
@@ -1,127 +1,202 @@
|
||||
//@ts-check
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const { Constants } = require('discord.js');
|
||||
const { CreateNewCollection } = require("../db/econ");
|
||||
const { checkRole } = require('./verify.js');
|
||||
const fetch = require('node-fetch');
|
||||
const help = require('../misc/help.js');
|
||||
|
||||
|
||||
async function setWelcomeChannel(dbo, message, channelname) {
|
||||
const channel = message.guild.channels.cache.find(ch => ch.name === channelname);
|
||||
dbo.insertOne({welcomechannel: channel});
|
||||
}
|
||||
async function execute(interaction, Discord, Client, bot) {
|
||||
const server = interaction.guildId;
|
||||
const owner = interaction.guild.members.cache.get(interaction.guild.ownerId);
|
||||
const args = interaction.options.data;
|
||||
|
||||
|
||||
|
||||
async function execute(bot, message, args, command, Discord, mongouri, items, xp_collection) {
|
||||
const server = message.guild.id;
|
||||
const owner = message.guild.members.cache.get(message.guild.ownerId);
|
||||
|
||||
if (message.author.id != message.guild.ownerId) {
|
||||
return message.reply('Only the server owner can do this!');
|
||||
if (interaction.user.id != interaction.guild.ownerId) {
|
||||
return interaction.reply({content: 'Only the server owner can do this!', ephemeral: true});
|
||||
}
|
||||
|
||||
// // @ts-ignore
|
||||
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||
// if (client.writeConcern || client.writeConcern) {
|
||||
// client.close();
|
||||
// return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
||||
// }
|
||||
|
||||
bot.mongoconnection.then(async (client) => {
|
||||
// if (err) { return console.log(err); }
|
||||
try {
|
||||
//Initialize
|
||||
CreateNewCollection(message, client, server, owner.user.id);
|
||||
CreateNewCollection(interaction, client, server, owner.user.id);
|
||||
|
||||
const db = client.db(server);
|
||||
const dbo = db.collection('SETUP');
|
||||
|
||||
//Chose the appropriate command
|
||||
command = args[0];
|
||||
if (args.length < 1) { return interaction.reply({content: "Please chose a valid option", ephemeral: true}); }
|
||||
|
||||
if (!command) {
|
||||
message.channel.send('Please use the following format _!setup help <welcome, logs>_');
|
||||
} else if (command == 'welcome_channel') {
|
||||
if (args.length != 2) { return message.reply('The command format is _!setup welcome_channel <channel name>_'); }
|
||||
// setWelcomeChannel(dbo, message, args[1]);
|
||||
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
try {
|
||||
const command = args[i].name;
|
||||
|
||||
if (command == 'welcome_channel') {
|
||||
const channel = args[i].channel;
|
||||
|
||||
dbo.updateOne({welcomechannel: {$exists: true}}, {$set: {welcomechannel: `${channel.id}`}});
|
||||
message.reply(`Set ${channel} as the new welcome channel`)
|
||||
} else if (command == 'welcome_message') {
|
||||
if (args.length < 2) { return message.reply('The command format is _!setup welcome\\_message_\nUse _{sn}_ to insert the server name, _{un}_ to insert the user name, and _{ut}_ to insert the user tag\nExample: _!setup welcome\\_message Welcome to {sn} Sir {un}#{ut}_'); }
|
||||
let msg = "";
|
||||
for (let i = 1; i < args.length; i ++ ) {
|
||||
msg += args[i] + ' ';
|
||||
interaction.reply({content: `Set ${channel} as the new welcome channel`, ephemeral: true})
|
||||
}
|
||||
else if (command == 'welcome_message') {
|
||||
const msg = args[i].value;
|
||||
|
||||
if (msg.length > 30) { return message.reply('Please specify a welcome message under 30 characters!'); }
|
||||
if (msg.length > 30 || msg.length < 1) { return interaction.reply({content: 'Please specify a welcome message between 0 and 30 characters!', ephemeral: true}); }
|
||||
dbo.updateOne({welcomemessage: {$exists: true}}, {$set: {welcomemessage: msg}})
|
||||
} else if (command == 'keep_logs') {
|
||||
if (args.length != 2) { return message.reply('Please specify a parameter\nExample: _!setup keep\\_logs true'); }
|
||||
|
||||
let keeplogs = false;
|
||||
if (args[1] == 'true') { keeplogs = true; }
|
||||
}
|
||||
else if (command == 'keep_logs') {
|
||||
let keeplogs = args[i].value;
|
||||
|
||||
dbo.updateOne({ _id: 'LOG'}, {$set: {keepLogs: keeplogs}});
|
||||
|
||||
message.reply(`Toggled log keeping to ${keeplogs}. Please use _!setup log_channel_ to choose the log channel`);
|
||||
} else if (command == 'log_channel') {
|
||||
if (args.length != 2) { return message.reply('Please specify a parameter\nExample: _!setup log\\_channel true_'); }
|
||||
|
||||
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||
interaction.reply({content: `Toggled log keeping to ${keeplogs}. Please use _!setup log_channel_ to choose the log channel`, ephemeral: true});
|
||||
}
|
||||
else if (command == 'log_channel') {
|
||||
const channel = args[i].channel;
|
||||
if (!channel) { return interaction.reply({content: 'The specified channel does not exist!', ephemeral: true}); }
|
||||
|
||||
dbo.updateOne({_id: 'LOG'}, {$set: {logchannel: `${channel.id}`}});
|
||||
message.reply(`Made ${channel} the new Selmer Bot Logs channel!`);
|
||||
} else if (command == 'log_severity') {
|
||||
const tier = args[1];
|
||||
interaction.reply({content: `Made ${channel} the new Selmer Bot Logs channel!`, ephemeral: true});
|
||||
}
|
||||
else if (command == 'log_severity') {
|
||||
const tier = args[i].value;
|
||||
const l = ['none', 'low', 'medium', 'high'];
|
||||
if (!l.includes(tier)) { return message.reply("Please select an existing tier ('none', 'low', 'medium', 'high')"); }
|
||||
if (!l.includes(tier)) { return interaction.reply({content: "Please select an existing tier ('none', 'low', 'medium', 'high')", ephemeral: true}); }
|
||||
|
||||
dbo.updateOne({_id: 'LOG'}, {$set: {severity: tier}})
|
||||
|
||||
message.reply("Severity updated!");
|
||||
} else if (command == 'announcement_role') {
|
||||
if (message.mentions.roles.first() == undefined) {
|
||||
return message.reply("Please mention a role (_!setup announcement\\_role **@role**_)\n_Note: Selmer Bot does NOT ping the @everyone role_");
|
||||
interaction.reply({content: `Severity updated to ${tier}`, ephemeral: true});
|
||||
}
|
||||
const role = message.mentions.roles.first().id;
|
||||
dbo.updateOne({_id: 'announcement'}, { $set: { 'role': role } });
|
||||
else if (command == 'ping_role') {
|
||||
const role = args[i].value;
|
||||
// if (message.mentions.roles.first() == undefined) {
|
||||
// return message.reply("Please mention a role (_!setup announcement\\_role **@role**_)\n_Note: Selmer Bot does NOT ping the @everyone role_");
|
||||
// }
|
||||
// const role = message.mentions.roles.first().id;
|
||||
dbo.updateOne({_id: 'announcement'}, { $set: { 'role': role.id } });
|
||||
|
||||
message.reply("Role updated!");
|
||||
} else if (command == "announcement_channel") {
|
||||
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||
interaction.reply({content: `Role updated to ${role}`, ephemeral: true});
|
||||
}
|
||||
else if (command == "ping_channel") {
|
||||
const channel = args[i].channel;
|
||||
if (!channel) { return interaction.reply({content: 'The specified channel does not exist!', ephemeral: true}); }
|
||||
|
||||
dbo.updateOne({_id: 'announcement'}, { $set: { 'channel': channel.id } });
|
||||
interaction.reply({content: `Channel set to ${channel}`, ephemeral: true});
|
||||
}
|
||||
else if (command == "add_mod_role") {
|
||||
dbo.findOne({_id: "roles"}).then((doc) => {
|
||||
const role = args[i].value;
|
||||
if (!doc.commands.includes(role)) {
|
||||
dbo.updateOne({_id: "roles"}, { $push: { commands: role } });
|
||||
interaction.reply({ content: "Role added!", ephemeral: true });
|
||||
} else {
|
||||
interaction.reply({ content: "This role is already a command role!", ephemeral: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (command == "remove_mod_role") {
|
||||
dbo.updateOne({_id: "roles"}, { $pull: { commands: { $in: [ args[i].value ] }} });
|
||||
interaction.reply({ content: "Role removed!", ephemeral: true });
|
||||
}
|
||||
else if (command == "welcome_banner") {
|
||||
const attachement_url = interaction.options.data[0].attachment.attachment;
|
||||
const response = await fetch(attachement_url);
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
const imgbfr = Buffer.from(arrayBuffer);
|
||||
dbo.updateOne({_id: 'WELCOME'}, {$set: {welcomebanner: imgbfr.toString('base64')}});
|
||||
interaction.reply({ content: `Banner updated to ${attachement_url}`, ephemeral: true});
|
||||
}
|
||||
else if (command == "welcome_text_color") {
|
||||
const reg = /^#[0-9A-F]{6}$/i;
|
||||
const newCol = interaction.options.data[0].value;
|
||||
if (reg.test(newCol)) {
|
||||
dbo.updateOne({_id: 'WELCOME'}, {$set: {welcometextcolor: newCol}});
|
||||
interaction.reply({content: `Color updated to ${newCol} (https://www.color-hex.com/color/${newCol.substring(1)})`, ephemeral: true});
|
||||
} else {
|
||||
interaction.reply("Please chose a valid hex color\nYou can find colors here: https://www.color-hex.com/");
|
||||
}
|
||||
}
|
||||
else if (command == "toggle_leveling") {
|
||||
const tog = interaction.options.data[0].value;
|
||||
dbo.updateOne({_id: 'LEVELING'}, {$set: {enabled: tog}});
|
||||
interaction.reply({content: "Turned leveling " + (tog) ? "ON" : "OFF", ephemeral: true});
|
||||
}
|
||||
else if (command == "leveling_banner") {
|
||||
const level_banner = interaction.options.data[0].attachment.attachment;
|
||||
const response = await fetch(level_banner);
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
const imgbfr = Buffer.from(arrayBuffer);
|
||||
dbo.updateOne({_id: 'LEVELING'}, {$set: {card: imgbfr.toString('base64')}});
|
||||
interaction.reply({content: `Updated leveling banner to ${level_banner}`, ephemeral: true});
|
||||
}
|
||||
else if (command == "leveling_text") {
|
||||
dbo.updateOne({_id: 'LEVELING'}, {$set: {text: interaction.options.data[0].value}});
|
||||
interaction.reply({content: `Updated leveling text to ${interaction.options.data[0].value}`, ephemeral: true});
|
||||
}
|
||||
else if (command == "leveling_color") {
|
||||
const reg = /^#[0-9A-F]{6}$/i;
|
||||
const newCol = interaction.options.data[0].value;
|
||||
if (reg.test(newCol)) {
|
||||
dbo.updateOne({_id: 'LEVELING'}, {$set: {col: newCol}});
|
||||
interaction.reply({content: `Color updated to ${newCol} (https://www.color-hex.com/color/${newCol.substring(1)})`, ephemeral: true});
|
||||
} else {
|
||||
interaction.reply("Please chose a valid hex color\nYou can find colors here: https://www.color-hex.com/");
|
||||
}
|
||||
}
|
||||
else if (command == "help") {
|
||||
if (interaction.options.data[0].value) {
|
||||
help.execute(interaction, Discord, Client, bot);
|
||||
} else {
|
||||
interaction.reply({content: 'https://docs.selmerbot.com/setup', ephemeral: true});
|
||||
}
|
||||
}
|
||||
else {
|
||||
interaction.reply({content: "Please chose a valid option", ephemeral: true});
|
||||
}
|
||||
/* Made obsolete by the change to Slash Commands
|
||||
|
||||
else if (command == 'help') {
|
||||
let temp;
|
||||
const subcat = args[i].value;
|
||||
if (args[1] == 'welcome') {
|
||||
temp = 'Use _!setup welcome\\_channel [channel name]_ to set the welcome channel and _!setup welcome\\_message [message]_ to set a welcome message!\n';
|
||||
temp = 'Use _/setup welcome\\_channel [channel name]_ to set the welcome channel and _/setup welcome\\_message [message]_ to set a welcome message/\n';
|
||||
} else if (args[1] == 'logs') {
|
||||
temp = 'To enable logging, use the command _!setup keep\\_logs true_ and _!setup log\\_channel_ [channel name] to set the logging channel!\n';
|
||||
temp += 'Use _!setup keep\\_logs false_ to disable logging and _!setup log\\_severity [none, low, medium, high]_ to set the threshold\n';
|
||||
temp += '__Severities:__\n*none* - unmute, unban\n*low* - mute\n*medium* - kick\n*high* - ban\nEvery tier also includes all notifs for ***higher*** tiers (AKA _!setup log\\_severity none_ will log everything from every severity)\n';
|
||||
temp = 'To enable logging, use the command _/setup keep\\_logs true_ and _/setup log\\_channel_ [channel name] to set the logging channel/\n';
|
||||
temp += 'Use _/setup keep\\_logs false_ to disable logging and _/setup log\\_severity [none, low, medium, high]_ to set the threshold\n';
|
||||
temp += '__Severities:__\n*none* - unmute, unban\n*low* - mute\n*medium* - kick\n*high* - ban\nEvery tier also includes all notifs for ***higher*** tiers (AKA _/setup log\\_severity none_ will log everything from every severity)\n';
|
||||
} else if (args[1] == 'announcement') {
|
||||
temp = "To pick the announcement channel, use _!setup announcement\\_channel_\nTo pick the announcement role, use _!setup announcement\\_role_";
|
||||
} else { temp = 'Use _!setup Please use the following format: _!setup help [welcome, logs, announcement]_\nExample: _!setup help welcome_'; }
|
||||
temp = "To pick the announcement channel, use _/setup announcement\\_channel_\nTo pick the announcement role, use _/setup announcement\\_role_";
|
||||
} else { temp = 'Use _/setup Please use the following format: _/setup help [welcome, logs, announcement]_\nExample: _/setup help welcome_'; }
|
||||
|
||||
message.reply(temp);
|
||||
}
|
||||
interaction.reply({content: temp, ephemeral: true});
|
||||
}*/
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'setup',
|
||||
description: 'Set up server features',
|
||||
execute
|
||||
execute,
|
||||
options: [
|
||||
{name: 'welcome_channel', description: 'Sets the channel for welcome messages', type: Constants.ApplicationCommandOptionTypes.CHANNEL },
|
||||
{name: 'welcome_message', description: 'Use {un}, {ud}, {ut}, and {sn} for username, user descriminator, user tag, and server name', type: Constants.ApplicationCommandOptionTypes.STRING },
|
||||
{name: 'welcome_banner', description: 'Sets the welcome banner', type: Constants.ApplicationCommandOptionTypes.ATTACHMENT},
|
||||
{name: 'welcome_text_color', description: 'Sets the welcome banner text color', type: Constants.ApplicationCommandOptionTypes.STRING},
|
||||
{name: 'keep_logs', description: 'Toggles logging', type: Constants.ApplicationCommandOptionTypes.BOOLEAN },
|
||||
{name: 'log_channel', description: 'Sets the logging channel', type: Constants.ApplicationCommandOptionTypes.CHANNEL },
|
||||
{name: 'log_severity', description: 'Sets the logging Severity (logs this/lower tiers)', type: Constants.ApplicationCommandOptionTypes.STRING, choices: [{name: 'none', value: 'none'}, {name: 'low', value: 'low'}, {name: 'medium', value: 'medium'}, {name: 'high', value: 'high'}] },
|
||||
{name: 'ping_role', description: 'Sets the role to be pinged for reminders', type: Constants.ApplicationCommandOptionTypes.ROLE},
|
||||
{name: 'ping_channel', description: 'Sets the channel for reminders', type: Constants.ApplicationCommandOptionTypes.CHANNEL},
|
||||
{name: 'add_mod_role', description: 'Make a role into an admin role for Selmer Bot, able to execute ALL Selmer Bot commands', type: Constants.ApplicationCommandOptionTypes.ROLE},
|
||||
{name: 'remove_mod_role', description: 'Remove a Selmer Bot moderation role', type: Constants.ApplicationCommandOptionTypes.ROLE},
|
||||
{name: 'toggle_leveling', description: 'Enable or Disable the leveling system', type: Constants.ApplicationCommandOptionTypes.BOOLEAN},
|
||||
{name: 'leveling_banner', description: 'Set the card background for the leveling system', type: Constants.ApplicationCommandOptionTypes.ATTACHMENT},
|
||||
{name: 'leveling_text', description: 'Use {un}, {ud}, {ut}, {sn}, and {r} for username, descriminator, user tag, server name, and rank', type: Constants.ApplicationCommandOptionTypes.STRING},
|
||||
{name: 'leveling_color', description: 'Set the card text color for the leveling system', type: Constants.ApplicationCommandOptionTypes.STRING},
|
||||
{name: 'help', description: 'in-app?', type: Constants.ApplicationCommandOptionTypes.BOOLEAN}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
const { checkRole } = require('./verify.js');
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'unlock',
|
||||
description: 'Unlock a channel',
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const arg = interaction.options.data[0];
|
||||
const guild = bot.guilds.cache.get(interaction.guildId);
|
||||
|
||||
checkRole(bot, guild, interaction.user.id).then((isAllowed) => {
|
||||
if (!isAllowed) { return message.reply('Insufficient Permissions!'); }
|
||||
|
||||
var channel;
|
||||
if (arg) {
|
||||
channel = arg.channel;
|
||||
} else {
|
||||
channel = interaction.channel;
|
||||
}
|
||||
|
||||
let role = interaction.guild.roles.cache.find(r => r.name === "@everyone");
|
||||
|
||||
channel.permissionOverwrites.edit(role.id, {
|
||||
VIEW_CHANNEL: true,
|
||||
SEND_MESSAGES: true,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
ATTACH_FILES: true
|
||||
});
|
||||
|
||||
interaction.reply(`${channel} has been unlocked!`);
|
||||
});
|
||||
},
|
||||
options: [{name: 'channel', description: 'The channel to unlock (defaults to current channel)', type: Constants.ApplicationCommandOptionTypes.CHANNEL, required: false}]
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
const { checkRole } = require('./verify.js');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'unlock',
|
||||
description: 'Unlock a channel',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
const guild = bot.guilds.cache.get(message.guild.id);
|
||||
|
||||
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||
|
||||
var channel;
|
||||
if (args[0]) {
|
||||
channel = guild.channels.cache.find(channel => channel.name.toLowerCase() === args[0]);
|
||||
} else {
|
||||
channel = message.channel;
|
||||
}
|
||||
|
||||
if (!channel) { return message.reply("This channel does not exist!"); }
|
||||
|
||||
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||
VIEW_CHANNEL: true,
|
||||
SEND_MESSAGES: true,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
ATTACH_FILES: true
|
||||
});
|
||||
}
|
||||
}
|
||||
+30
-23
@@ -1,32 +1,39 @@
|
||||
function checkRole(bot, guild, userId, cal = false) {
|
||||
var roleName;
|
||||
const Discord = require('discord.js');
|
||||
|
||||
if (cal) {
|
||||
roleName = "Selmer Bot Calendar";
|
||||
} else {
|
||||
roleName = "Selmer Bot Commands";
|
||||
}
|
||||
|
||||
const role = guild.roles.cache.find((role) => { return (role.name == roleName); })
|
||||
/**
|
||||
* @param {Discord.Guild} guild
|
||||
* @returns {Promise<Boolean>}
|
||||
*/
|
||||
function checkRole(bot, guild, userId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const user = guild.members.cache.get(userId);
|
||||
|
||||
return (role != undefined && user.roles.cache.has(role.id)); // || user.id == guild.ownerId || bot.inDebugMode
|
||||
// return (role != undefined && user.roles.cache.has(role.id)); // || user.id == guild.ownerId || bot.inDebugMode
|
||||
|
||||
// Maybe implement this later, useless for now
|
||||
bot.mongoconnection.then((client) => {
|
||||
// const role = client.db(message.guild.id).collection("admin-roles");
|
||||
const a = new Array();
|
||||
client.db(guild.id).collection("SETUP").findOne({_id: "roles"}).then((doc) => {
|
||||
const comRoles = doc.commands;
|
||||
const role = guild.roles.cache.find((role) => { return (role.name == "Selmer Bot Commands"); });
|
||||
const hasPreAdminRole = (role != undefined && user.roles.cache.has(role.id) || user.id == guild.ownerId);
|
||||
|
||||
/*Maybe implement this later, useless for now
|
||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||
client.connect(err => {
|
||||
|
||||
|
||||
const role = client.db(message.guild.id).collection("admin-roles");
|
||||
shop.find().toArray(function(err, itemstemp) {
|
||||
if (err) throw err;
|
||||
|
||||
items = [...itemstemp];
|
||||
|
||||
client.close();
|
||||
if (!comRoles) {
|
||||
resolve(hasPreAdminRole);
|
||||
} else {
|
||||
const hasRoles = [];
|
||||
Promise.all(comRoles.map((val) => {
|
||||
if (user.roles.cache.has(val)) {
|
||||
hasRoles.push(true);
|
||||
}
|
||||
})).then(() => {
|
||||
resolve(hasRoles.length > 0 || hasPreAdminRole);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
+105
-85
@@ -1,105 +1,125 @@
|
||||
const { MessageAttachment } = require('discord.js');
|
||||
// const { readFile } = require('fs/promises');
|
||||
const fs = require("fs");
|
||||
const sharp = require('sharp');
|
||||
const fetch = require('node-fetch');
|
||||
const arrayBufferToBuffer = require('arraybuffer-to-buffer');
|
||||
|
||||
const { request } = require('undici');
|
||||
const CanvasImport = require('@napi-rs/canvas');
|
||||
const canvas = CanvasImport.createCanvas(700, 250)
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
//https://some-random-api.ml/welcome
|
||||
async function welcome(member, welcomechannel, welcomemessage = null, welcomebanner = null) {
|
||||
|
||||
//Draw Stuff
|
||||
const context = canvas.getContext('2d');
|
||||
var bkimgsrc;
|
||||
|
||||
let bkurl = 'https://github.com/ION606/selmerBot/blob/main/commands/admin/wallpaper.jpg';
|
||||
const response = await fetch(bkurl);
|
||||
response.arrayBuffer().then(async (data) => {
|
||||
|
||||
// const background = new CanvasImport.Image();
|
||||
// background.src = arrayBufferToBuffer(data);
|
||||
const { GuildMember } = require('discord.js');
|
||||
|
||||
|
||||
// This uses the canvas dimensions to stretch the image onto the entire canvas
|
||||
// context.drawImage(background, 0, 0, canvas.width, canvas.height);
|
||||
context.fillStyle = 'rgba(0,0,0,1)';
|
||||
context.fillRect(0,0, canvas.width, canvas.height);
|
||||
|
||||
//Draw the Border
|
||||
context.strokeStyle = '#0099ff';
|
||||
context.strokeRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
|
||||
//Add Text
|
||||
|
||||
//have the function here, because returns are whack
|
||||
const applyText = (canvas, text) => {
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
// Declare a base size of the font
|
||||
let fontSize = 70;
|
||||
let i = 0;
|
||||
|
||||
do {
|
||||
// Assign the font to the context and decrement it so it can be measured again
|
||||
context.font = `italic ${fontSize -= 10}px sans-serif`;
|
||||
// Compare pixel width of the text to the canvas minus the approximate avatar size
|
||||
|
||||
i ++;
|
||||
} while (context.measureText(text).width > canvas.width - 100);
|
||||
|
||||
// Return the result to use in the actual canvas
|
||||
return context.font;
|
||||
};
|
||||
|
||||
//message.author.username == interaction.member.displayName
|
||||
//message.guild.name == interaction.member.guild.name
|
||||
let text = `Welcome to ${member.guild.name} ${member.user.username}#${member.user.discriminator}!`;
|
||||
if(welcomemessage != null) {
|
||||
function formatMessage(member, welcomemessage, isLvl, rank = null) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let text;
|
||||
if (!isLvl) {
|
||||
text = `Welcome to ${member.guild.name} ${member.user.tag}!`;
|
||||
if (welcomemessage != null) {
|
||||
text = welcomemessage;
|
||||
text = text.replace('{sn}', member.guild.name);
|
||||
text = text.replace('{un}', member.user.username);
|
||||
text = text.replace('{ut}', member.user.discriminator);
|
||||
text = text.replace('{ud}', member.user.discriminator);
|
||||
text = text.replace('{ut}', member.user.tag);
|
||||
}
|
||||
} else {
|
||||
text = `Congradulations ${member.user.tag} for reaching rank ${rank}!`;
|
||||
|
||||
if (welcomemessage != null) {
|
||||
text = welcomemessage;
|
||||
text = text.replace('{sn}', member.guild.name);
|
||||
text = text.replace('{un}', member.user.username);
|
||||
text = text.replace('{ud}', member.user.discriminator);
|
||||
text = text.replace('{ut}', member.user.tag);
|
||||
text = text.replace('{r}', rank);
|
||||
}
|
||||
}
|
||||
|
||||
context.font= applyText(canvas, text);
|
||||
context.fillStyle = '#ffffff';
|
||||
context.fillText(text, (canvas.width/2) - (context.measureText(text).width)/2, canvas.height - 15);
|
||||
resolve(text);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//Draw a white circle
|
||||
context.beginPath();
|
||||
context.arc((canvas.width/2), 90, 85, 0, 2 * Math.PI, false);
|
||||
context.fillStyle = 'white';
|
||||
context.fill();
|
||||
context.closePath();
|
||||
/**
|
||||
* @param {GuildMember} member
|
||||
* @param {*} welcomeChannel
|
||||
*/
|
||||
async function welcome(member, welcomeChannel, welcomemessage, welcomebanner, welcomeTextCol, isLvl = false, rank = null) {
|
||||
formatMessage(member, welcomemessage, isLvl, rank).then(async (wmsg) => {
|
||||
const width = 1024;
|
||||
const height = 500;
|
||||
const usernameText = `${wmsg}`;
|
||||
const memberCountText = (!isLvl) ? `You are member ${member.guild.memberCount}` : "";
|
||||
|
||||
//ANYTHING DRAWN AFTER THIS WILL BE CLIPPED!!!
|
||||
//Make whatever image will be draw (the user's avatar) into a circular format
|
||||
context.beginPath();
|
||||
context.arc((canvas.width/2), 90, 80, 0, Math.PI * 2, true);
|
||||
context.closePath();
|
||||
var uSize = 55 - Math.round(wmsg.length/2);
|
||||
|
||||
// Clip off the region you just drew (enforce template?)
|
||||
context.clip();
|
||||
if (uSize < 5) { uSize = 5; }
|
||||
|
||||
const username = `
|
||||
<svg width="${width}" height="${height}">
|
||||
<style>
|
||||
.username { fill: ${welcomeTextCol}; font-size: ${uSize}px; font-weight: bold;}
|
||||
</style>
|
||||
<text x="50%" y="50%" text-anchor="middle" class="username" font-family='Didot'>${usernameText}</text>
|
||||
</svg>
|
||||
`;
|
||||
const memberCount = `
|
||||
<svg width="${width}" height="${height}">
|
||||
<style>
|
||||
.memberCount { fill: ${welcomeTextCol}; font-size: 40px; font-weight: bold;}
|
||||
</style>
|
||||
<text x="50%" y="50%" text-anchor="middle" class="memberCount" font-family='Didot'>${memberCountText}</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
//Add the user's profile pic (message.author == interaction.user)
|
||||
const { body } = await request(member.displayAvatarURL({ format: 'jpg' }));
|
||||
const avatar = new CanvasImport.Image();
|
||||
avatar.src = Buffer.from(await body.arrayBuffer());
|
||||
context.drawImage(avatar, (canvas.width/2) - 80, 10, 160, 160);
|
||||
const r = 100;
|
||||
const circleShape = Buffer.from(`<svg><circle cx="${r}" cy="${r}" r="${r}" /></svg>`);
|
||||
var response, arrayBuffer;
|
||||
const usernameBuffer = Buffer.from(username);
|
||||
const memberCountBuffer = Buffer.from(memberCount);
|
||||
response = await fetch(member.displayAvatarURL());
|
||||
arrayBuffer = await response.arrayBuffer();
|
||||
const iconBuffer = Buffer.from(arrayBuffer);
|
||||
|
||||
// Use the helpful Attachment class structure to process the file for you
|
||||
const attachment = new MessageAttachment(canvas.toBuffer('image/png'), 'profile-image.png');
|
||||
var bkBuffer;
|
||||
|
||||
welcomechannel.send({ files: [attachment] });
|
||||
if (!welcomebanner) {
|
||||
response = await fetch('https://wallpapercave.com/wp/wp3258574.png');
|
||||
arrayBuffer = await response.arrayBuffer();
|
||||
bkBuffer = Buffer.from(arrayBuffer);
|
||||
} else {
|
||||
// return console.log(welcomebanner);
|
||||
bkBuffer = Buffer.from(welcomebanner, 'base64');
|
||||
}
|
||||
|
||||
})
|
||||
sharp(iconBuffer)
|
||||
.resize(300, 300)
|
||||
.composite([{
|
||||
input: circleShape,
|
||||
blend: 'dest-in'
|
||||
}])
|
||||
.toBuffer().then((iconBufferNew) => {
|
||||
sharp(bkBuffer)
|
||||
.resize(1024, 500)
|
||||
.composite([
|
||||
{
|
||||
input: usernameBuffer,
|
||||
top: 80,
|
||||
left: -10,
|
||||
},
|
||||
{
|
||||
input: memberCountBuffer,
|
||||
top: 130,
|
||||
left: -10,
|
||||
},
|
||||
{
|
||||
input: iconBufferNew,
|
||||
top: 10,
|
||||
left: 1024/2 - 300/2,
|
||||
},
|
||||
]).toBuffer((err, buffer) => {
|
||||
if (err) { return console.error(err); }
|
||||
|
||||
// return console.log(buffer.byteLength * 0.000001);
|
||||
welcomeChannel.send({
|
||||
files: [buffer],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { welcome }
|
||||
+38
-28
@@ -1,24 +1,27 @@
|
||||
const { Constants } = require('discord.js');
|
||||
const scraper = require('mal-scraper');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'asearch',
|
||||
description: 'Selmer bot gives you info on an anime',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
if (args.length < 1) { return message.reply("Please specify an anime!"); }
|
||||
let name = "";
|
||||
if (args.length > 1) {
|
||||
let i = 0;
|
||||
while (i < args.length && args[i] != '~fancy' && args[i] != '~summary' && args[i] != '~stats') {
|
||||
name += args[i] + " ";
|
||||
i++;
|
||||
}
|
||||
} else { name = args[0]; }
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
|
||||
if (args[args.length - 1] != '~fancy' && args[args.length - 1] != '~summary' && args[args.length - 1] != '~stats') { args.push('~stats'); }
|
||||
const args = interaction.options.data;
|
||||
const name = args.filter((arg) => { return (arg.name == 'anime'); })[0].value;
|
||||
var style;
|
||||
|
||||
if (args.length > 1) {
|
||||
style = args.filter((arg) => { return (arg.name == 'style'); })[0].value;
|
||||
}
|
||||
else { style = "stats"; }
|
||||
|
||||
//Maybe change it to "this anime movie" if there is only 1 episode?
|
||||
|
||||
//When set to true, getInfoFromName.getBestMatch did not, in fact, return the best results
|
||||
scraper.getInfoFromName(name, false).then((data) => {
|
||||
try {
|
||||
if (args[args.length - 1] == '~stats') {
|
||||
try { console.log(data);
|
||||
if (style == 'stats') {
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor('#002eff')
|
||||
.setTitle(data.title)
|
||||
@@ -28,40 +31,47 @@ module.exports = {
|
||||
.addFields(
|
||||
{name: 'Genres:', value: data.genres.join(", ")},
|
||||
{name: 'Score:', value: data.score},
|
||||
{name: 'Episode:', value: data.episodes}
|
||||
{name: 'Episode:', value: data.episodes},
|
||||
{name: "Date Aired/Premiered", value: data.premiered || data.aired}
|
||||
).setURL(data.trailer);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
} else if (args[args.length - 1] == '~fancy') {
|
||||
let temp = `The ${data.genres.join(", ")} anime _${data.title}_ first aired on ${data.premiered}`;
|
||||
interaction.reply({ embeds: [newEmbed] });
|
||||
} else if (style == 'fancy') {
|
||||
let temp = `The ${data.genres.join(", ")} anime _${data.title}_ first aired on ${data.premiered || data.aired}`;
|
||||
if (data.aired) { temp += `. This anime ran for ${data.aired} for a total of ${data.episodes} episodes.`}
|
||||
else { temp += ` and is still airing with ${data.episodes} so far!`}
|
||||
|
||||
temp += ` This anime has a score of ${data.score} and is ${data.popularity} on MyAnimeList!\n`;
|
||||
temp += `You can see a trailer for ${data.title} here: ${data.trailer}`;
|
||||
temp += `\n\n(to see a summary of the anime, use '${bot.prefix}asearch <anime name> ~summary')`;
|
||||
temp += `You can see a trailer for ${data.title} ***[here](${data.trailer})***`;
|
||||
// temp += `\n\n(to see a summary of the anime, use '${bot.prefix}asearch <anime name> summary')`;
|
||||
|
||||
message.channel.send({ embeds: [new Discord.MessageEmbed().setImage(data.picture)]});
|
||||
message.channel.send(temp);
|
||||
} else if (args[args.length - 1] == '~summary') {
|
||||
interaction.reply({ embeds: [new Discord.MessageEmbed().setImage(data.picture).setDescription(temp)] });
|
||||
// message.channel.send(temp);
|
||||
} else if (style == 'summary') {
|
||||
let temp = data.synopsis;
|
||||
message.channel.send(temp);
|
||||
interaction.reply(temp);
|
||||
} else {
|
||||
message.reply(`Unknown command, try using the format '${bot.prefix}asearch <anime name> [~stats or ~fancy or ~summary]`);
|
||||
interaction.reply(`Unknown command, try using the format '/asearch <anime name> [stats or fancy or summary]`);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message.indexOf('MessageEmbed field values must be non-empty strings') != -1) {
|
||||
message.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||
interaction.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||
} else {
|
||||
message.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||
const m = interaction.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
addComplaintButton(bot, message);
|
||||
m.then((msg) => {
|
||||
addComplaintButton(bot, msg);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
options: [
|
||||
{name: 'anime', description: 'The name of the anime', type: Constants.ApplicationCommandOptionTypes.STRING, required: true},
|
||||
{name: 'style', description: 'stats or fancy or summary (defaults to stats)', type: Constants.ApplicationCommandOptionTypes.STRING, required: false, choices: [ { name: 'stats', value: 'stats' }, { name: 'fancy', value: 'fancy' }, {name: 'summary', value: 'summary'} ] }
|
||||
]
|
||||
}
|
||||
+25
-22
@@ -1,23 +1,21 @@
|
||||
const { Constants } = require('discord.js');
|
||||
const scraper = require('mal-scraper');
|
||||
const search = scraper.search;
|
||||
const type = "manga";
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'msearch',
|
||||
description: 'Selmer bot gives you info on a manga',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
if (args.length < 1) { return message.reply("Please specify a manga!"); }
|
||||
if (args[args.length - 1] != '~fancy' && args[args.length - 1] != '~summary' && args[args.length - 1] != '~stats') { args.push('~stats'); }
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
const args = interaction.options.data;
|
||||
const name = args.filter((arg) => { return (arg.name == 'manga'); })[0].value;
|
||||
var style;
|
||||
|
||||
let name = "";
|
||||
if (args.length > 1) {
|
||||
let i = 0;
|
||||
while (i < args.length && args[i] != '~fancy' && args[i] != '~summary' && args[i] != '~stats') {
|
||||
name += args[i] + " ";
|
||||
i++;
|
||||
style = args.filter((arg) => { return (arg.name == 'style'); })[0].value;
|
||||
}
|
||||
}
|
||||
|
||||
let cmd = args[args.length - 1];
|
||||
else { style = "stats"; }
|
||||
|
||||
try {
|
||||
search.search(type, {
|
||||
@@ -25,7 +23,7 @@ module.exports = {
|
||||
term: name
|
||||
}).then((data1) => {
|
||||
let data = data1[0];
|
||||
if (cmd == "~stats") {
|
||||
if (style == "stats") {
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor('#ff9900')
|
||||
.setTitle(data.title)
|
||||
@@ -38,32 +36,37 @@ module.exports = {
|
||||
{name: 'Volumes:', value: data.vols}
|
||||
);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
} else if (cmd == "~fancy") {
|
||||
interaction.reply({ embeds: [newEmbed] });
|
||||
} else if (style == "fancy") {
|
||||
let temp = `The ${data.type} _${data.title}_ currently has ${data.vols} volumes with ${data.nbChapters} chapters, `;
|
||||
temp += `running from _${data.startDate.replace(/-/g, "/")}_ to _${data.endDate.replace(/-/g, "/")}_, and has a score of ${data.score} on MyAnimeList!\n`;
|
||||
temp += `You can read more about _${data.title}_ at ${data.url}`;
|
||||
|
||||
message.channel.send(temp);
|
||||
} else if (cmd == "~summary") {
|
||||
interaction.reply(temp);
|
||||
} else if (style == "summary") {
|
||||
//Remove the "read more." at the end
|
||||
let temp = data.shortDescription.slice(0, -10);
|
||||
temp += ` _read more at_ ${data.url}`;
|
||||
return message.channel.send(temp);
|
||||
return interaction.reply(temp);
|
||||
} else {
|
||||
message.reply(`Unknown command, try using the format '${bot.prefix}msearch <manga name> [~stats or ~fancy or ~summary]`);
|
||||
interaction.reply(`Unknown command, try using the format '${bot.prefix}msearch <manga name> [stats or fancy or summary]`);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.message.indexOf('MessageEmbed field values must be non-empty strings') != -1) {
|
||||
message.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||
interaction.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||
} else {
|
||||
message.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||
const m = interaction.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
addComplaintButton(bot, message);
|
||||
m.then((msg) => {
|
||||
addComplaintButton(bot, msg);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
options: [{name: 'manga', description: 'The name of the manga', type: Constants.ApplicationCommandOptionTypes.STRING, required: true}, {name: 'style', description: 'stats or fancy or summary (defaults to stats)', type: Constants.ApplicationCommandOptionTypes.STRING, required: false, choices: [ { name: 'stats', value: 'stats' }, { name: 'fancy', value: 'fancy' }, {name: 'summary', value: 'summary'} ] }]
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
const axios = require('axios');
|
||||
|
||||
/**
|
||||
* @param {String} purl
|
||||
* @returns {Promise<Array<String>>}
|
||||
*
|
||||
* @example
|
||||
* const purls = getPlaylistUrls(url);
|
||||
* purls.then((urls) => { console.log(urls); });
|
||||
*/
|
||||
async function getPlaylistUrls(bot, purl, isPremium) {
|
||||
const gApiKey = bot.youtubeAPIKey;
|
||||
const numSongs = (isPremium) ? 20 : 10;
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const pid = (purl.split("list=")[1]).replace("&feature=share", "");
|
||||
await axios.get(`https://www.googleapis.com/youtube/v3/playlistItems`, {
|
||||
params: {
|
||||
part: 'id,snippet',
|
||||
maxResults: numSongs,
|
||||
playlistId: pid,
|
||||
key: gApiKey
|
||||
}
|
||||
})
|
||||
.then((result) => {
|
||||
const l = [];
|
||||
result.data.items.forEach((vid, ind) => {
|
||||
const vurl = `https://www.youtube.com/watch?v=${vid.snippet.resourceId.videoId}`
|
||||
const pvurl = `https://www.youtube.com/watch?v=${vid.snippet.resourceId.videoId}&list=${pid}&index=${ind+1}`
|
||||
l.push({video_url: vurl, in_playlist_url: pvurl});
|
||||
});
|
||||
|
||||
resolve(l);
|
||||
}).catch((err) => { reject(err.message); });
|
||||
} catch (err) {
|
||||
reject(err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = { getPlaylistUrls }
|
||||
@@ -0,0 +1,600 @@
|
||||
// const { joinVoiceChannel, createAudioResource } = require('@discordjs/voice');
|
||||
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType, joinVoiceChannel, createAudioResource, getVoiceConnection } = require('@discordjs/voice');
|
||||
const { MessageActionRow, MessageButton, MessageEmbed, Constants } = require('discord.js');
|
||||
const play = require('play-dl');
|
||||
const { getPlaylistUrls } = require('./addPlaylist.js');
|
||||
const { verPremium } = require('../premium/verifyPremium.js');
|
||||
|
||||
// Note: Unsure of what this does , but may be related to the play-dl lib (my notes are inconsistent)
|
||||
// play.authorization();
|
||||
|
||||
async function playMusic(bot, interaction, channelId, url, isPlaylist) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const channel = bot.channels.cache.get(channelId);
|
||||
const connection = joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: channel.guild.id,
|
||||
adapterCreator: channel.guild.voiceAdapterCreator,
|
||||
});
|
||||
|
||||
connection.on(VoiceConnectionStatus.Ready, () => {
|
||||
// console.log('Connected to the voice channel!');
|
||||
});
|
||||
|
||||
try {
|
||||
let stream;
|
||||
let yt_info;
|
||||
if (url.startsWith("https://")) {
|
||||
if (!url.startsWith("https://www.youtube.com/") &&
|
||||
!url.startsWith("https://music.youtube.com/") && !url.startsWith("https://youtu.be/")) {
|
||||
if (!isPlaylist) {
|
||||
interaction.reply("This is not a valid YouTube URL").catch((err) => {
|
||||
console.log(err.message);
|
||||
interaction.reply("Uh oh, an error has occured!");
|
||||
});
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
yt_info = await play.video_info(url);
|
||||
// let stream = await play.stream_from_info(yt_info)
|
||||
stream = await play.stream(url);
|
||||
|
||||
// console.log("Playing from a URL!");
|
||||
} else {
|
||||
yt_info = await play.search(url, {
|
||||
limit: 1
|
||||
});
|
||||
|
||||
stream = await play.stream(yt_info[0].url);
|
||||
yt_info = await play.video_info(yt_info[0].url);
|
||||
}
|
||||
|
||||
let resource = createAudioResource(stream.stream, {
|
||||
inputType: stream.type
|
||||
})
|
||||
|
||||
// let audio = "em.mp3";
|
||||
// let resource = createAudioResource(join(__dirname, audio));
|
||||
|
||||
const data = bot.audioData.get(channel.guild.id);
|
||||
|
||||
if (data && data[1]) {
|
||||
//[player, [queue Array]]
|
||||
data[1].push({yt_info: yt_info, resource: resource});
|
||||
bot.audioData.set(interaction.guildId, data);
|
||||
|
||||
if (!isPlaylist) {
|
||||
interaction.reply(`_"${yt_info.video_details.title}" added to queue!_`).catch((err) => {
|
||||
channel.send("Uh oh, there's been a Discord API error!");
|
||||
console.log(err);
|
||||
reject();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const player = createAudioPlayer();
|
||||
connection.subscribe(player);
|
||||
|
||||
bot.audioData.set(interaction.guildId, [player, new Array(), null]);
|
||||
player.play(resource);
|
||||
|
||||
|
||||
player.on(AudioPlayerStatus.Playing, () => {
|
||||
//Check maybe?
|
||||
});
|
||||
|
||||
player.on(AudioPlayerStatus.Idle, () => {
|
||||
//TODO find away to trigger the "stop" event here
|
||||
// playNext(interaction, bot);
|
||||
// pause_start_stop(interaction, bot);
|
||||
});
|
||||
|
||||
playStopEmbed(bot, interaction, yt_info, false, true);
|
||||
}
|
||||
|
||||
resolve(true);
|
||||
} catch (err) {
|
||||
if (!isPlaylist) {
|
||||
console.log(err);
|
||||
interaction.reply("Uh Oh, there's been an error!").catch((err) => { console.log(err); })
|
||||
}
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function playStopEmbed(bot, interaction, yt_info, stopped, message = null) {
|
||||
if (stopped) {
|
||||
var em = interaction.message.embeds[0];
|
||||
rows = [];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
interaction.update({embeds: [em], components: rows});
|
||||
} else {
|
||||
const author = {
|
||||
name: "Selmer Bot",
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
}
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setColor('#0F00F0')
|
||||
.setTitle(`${yt_info.video_details.title}`)
|
||||
.setAuthor(author)
|
||||
.setDescription('IS NOW PLAYING')
|
||||
.setURL(yt_info.video_details.url)
|
||||
.setThumbnail(yt_info.video_details.thumbnails[0].url);
|
||||
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('PAUSE')
|
||||
.setLabel('⏸️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
|
||||
if (message) {
|
||||
if (interaction) {
|
||||
const m = interaction.channel.send({ embeds: [newEmbed], components: [row] });
|
||||
m.then((msg) => {
|
||||
const data = bot.audioData.get(interaction.guildId);
|
||||
data[2] = msg.id;
|
||||
bot.audioData.set(interaction.guildId, data);
|
||||
});
|
||||
} else {
|
||||
const m = message.reply({ embeds: [newEmbed], components: [row] });
|
||||
m.then((msg) => {
|
||||
const data = bot.audioData.get(message.guild.id);
|
||||
data[2] = msg.id;
|
||||
bot.audioData.set(message.guild.id, data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
interaction.update({embeds: [newEmbed], components: [row]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function pause_start_stop(interaction, bot, message = null, command = null) {
|
||||
try {
|
||||
var player, em, guildId;
|
||||
if (interaction) { guildId = interaction.guildId }
|
||||
else { guildId = message.guild.id; }
|
||||
|
||||
|
||||
const data = bot.audioData.get(guildId);
|
||||
if (!data) {
|
||||
var em = interaction.message.embeds[0];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
return interaction.message.edit({ components: [], embeds: [em]});
|
||||
}
|
||||
|
||||
if (interaction) {
|
||||
player = data[0];
|
||||
command = interaction.customId.toLowerCase();
|
||||
em = interaction.message.embeds[0];
|
||||
} else {
|
||||
player = data[0];
|
||||
em = message.embeds[0];
|
||||
}
|
||||
|
||||
var rows = [new MessageActionRow()];
|
||||
|
||||
if (command == "pause") {
|
||||
rows[0].addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('RESUME')
|
||||
.setLabel('▶️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
em.description = 'IS NOW PAUSED';
|
||||
player.pause();
|
||||
|
||||
} else if (command == "resume") {
|
||||
rows[0].addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('PAUSE')
|
||||
.setLabel('⏸️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
em.description = 'IS NOW PLAYING';
|
||||
|
||||
player.unpause();
|
||||
} else if (command == "stop") {
|
||||
playStopEmbed(bot, interaction, null, true);
|
||||
|
||||
const connection = getVoiceConnection(interaction.guild.id);
|
||||
|
||||
player.stop();
|
||||
|
||||
//Remove everything from queue
|
||||
bot.audioData.delete(interaction.guildId);
|
||||
|
||||
if (connection) { connection.destroy(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (interaction) { interaction.update({embeds: [em], components: rows}); }
|
||||
else {
|
||||
const data = bot.audioData.get(guildId);
|
||||
|
||||
// var msg = message.channel.messages.cache.get(data[2]);
|
||||
const newEmbed = message.embeds[0];
|
||||
newEmbed.description = "Has been deferred";
|
||||
message.edit({ embeds: [ newEmbed ], components: []});
|
||||
|
||||
const m = message.reply({embeds: [em], components: rows});
|
||||
m.then((msg) => {
|
||||
const data = bot.audioData.get(message.guild.id);
|
||||
data[2] = msg.id;
|
||||
bot.audioData.set(message.guild.id, data);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
rows = [];
|
||||
em.description = new String('IS NOW STOPPED');
|
||||
interaction.update({embeds: [em], components: rows});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function playNext(interaction, bot, message = null) {
|
||||
// https://discordjs.guide/voice/audio-player.html#taking-action-within-the-error-handler
|
||||
|
||||
//Setup data[1] = {info: yt_info, resource: resource}
|
||||
var guildId;
|
||||
if (message != null) { guildId = message.guild.id; }
|
||||
else { guildId = interaction.guildId; }
|
||||
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return interaction.followUp("Audio queue empty!"); }
|
||||
const player = data[0];
|
||||
|
||||
//Check if the queue is empty
|
||||
if (data[1].length <= 0) {
|
||||
player.stop();
|
||||
bot.audioData.delete(guildId);
|
||||
if (message) { return true; }
|
||||
else { return playStopEmbed(bot, interaction, null, true); }
|
||||
}
|
||||
|
||||
|
||||
const resource = data[1][0].resource;
|
||||
const yt_info = data[1][0].yt_info;
|
||||
player.stop();
|
||||
|
||||
//Play the thing
|
||||
player.play(resource);
|
||||
|
||||
//remove the song from queue
|
||||
delete data[1][0];
|
||||
data[1] = data[1].filter(n => n);
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
//Add the embed
|
||||
var msg = message;
|
||||
if (!message) {
|
||||
msg = interaction.message;
|
||||
interaction.update({ embeds: [ new MessageEmbed(interaction.message.embeds[0]).setDescription("IS NOW STOPPED") ], components: []});
|
||||
}
|
||||
|
||||
playStopEmbed(bot, interaction, yt_info, false, msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function fromMessage(bot, command, interaction) {
|
||||
//Setup data[1] = {info: yt_info, resource: resource}
|
||||
const guildId = interaction.guildId;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return interaction.reply("No music is currently playing!"); }
|
||||
|
||||
const player = data[0];
|
||||
const message = interaction.channel.messages.cache.get(data[2]);
|
||||
// console.log(message);
|
||||
|
||||
var em;
|
||||
if (message.embeds) { em = message.embeds[0]; }
|
||||
var rows;
|
||||
|
||||
if (command == 'stop') {
|
||||
em = message.embeds[0];
|
||||
rows = [];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
player.stop();
|
||||
const connection = getVoiceConnection(guildId);
|
||||
if (connection) { connection.destroy(); }
|
||||
|
||||
bot.audioData.delete(guildId);
|
||||
interaction.reply("Audio stopped!");
|
||||
|
||||
} else if (command == 'skip') {
|
||||
if (playNext(null, bot, message)) {
|
||||
rows = [];
|
||||
em = message.embeds[0];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
interaction.reply("Audio stopped!");
|
||||
}
|
||||
} else if (command == 'pause' || command == 'resume') {
|
||||
interaction.deferReply();
|
||||
pause_start_stop(null, bot, message, command);
|
||||
interaction.deleteReply();
|
||||
}
|
||||
|
||||
|
||||
message.edit({embeds: [em], components: rows});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function showQueue(bot, isUpdate, interaction = null, page = 0) {
|
||||
const guild = interaction.guildId;
|
||||
const data = bot.audioData.get(guild);
|
||||
if (!data) { return interaction.reply("The audio queue is empty!"); }
|
||||
|
||||
const rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return interaction.reply("The audio queue is empty!"); }
|
||||
|
||||
const songList = [];
|
||||
var tenSongs = '';
|
||||
let i = 0;
|
||||
|
||||
rawQueue.forEach(function (rawSong) {
|
||||
const songDetails = rawSong.yt_info.video_details;
|
||||
tenSongs += `${i + 1}. ${songDetails.title}\n`;
|
||||
|
||||
i++;
|
||||
|
||||
//Split the songs into pages of 10
|
||||
if (i % 10 == 0) { songList.push(tenSongs); tenSongs = ''; }
|
||||
});
|
||||
|
||||
//If there's still some left over songs, add that
|
||||
if (i % 10 != 0) {
|
||||
songList.push(tenSongs);
|
||||
}
|
||||
|
||||
if (page >= songList.length) { page = songList.length - 1 }
|
||||
if (page < 0) { page = 0; } //LEAVE AS TWO IF's AS THE LENGTH MIGHT BE 0
|
||||
|
||||
if (songList.length == 0) { songList.push(tenSongs); }
|
||||
|
||||
//Create the embed
|
||||
const author = {
|
||||
name: "Selmer Bot",
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
}
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setTitle("SONG QUEUE")
|
||||
.setAuthor(author)
|
||||
.setDescription(songList[page])
|
||||
.setFooter({ text: `Page ${page + 1}` })
|
||||
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`audioQueue|${page - 1}`)
|
||||
.setLabel('⬅️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId(`audioQueue|${page + 1}`)
|
||||
.setLabel('➡️')
|
||||
.setStyle('SECONDARY'),
|
||||
|
||||
)
|
||||
|
||||
if (isUpdate) {
|
||||
interaction.update({embeds: [newEmbed], components: [row]});
|
||||
} else {
|
||||
interaction.reply({ embeds: [newEmbed], components: [row] }).catch((err) => {
|
||||
console.log(err);
|
||||
interaction.channel.send({ embeds: [newEmbed], components: [row] });
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeFromQueue(bot, interaction, posStr) {
|
||||
const guildId = interaction.guildId;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return interaction.reply("The audio queue is empty!"); }
|
||||
|
||||
const rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return interaction.reply("The audio queue is empty!"); }
|
||||
else if (isNaN(posStr) || Number(posStr) > rawQueue.length) { return interaction.reply("Please specify a number within queue bounds!"); }
|
||||
|
||||
const pos = Number(posStr) - 1;
|
||||
const details = rawQueue[pos].yt_info.video_details;
|
||||
|
||||
delete data[1][pos];
|
||||
data[1] = data[1].filter(n => n);
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setColor('#0F00F0')
|
||||
.setTitle(`${details.title}`)
|
||||
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||
.setDescription( `has been removed from position ${pos + 1} in queue!`)
|
||||
.setThumbnail(details.thumbnails[0].url);
|
||||
|
||||
interaction.reply({ embeds: [newEmbed] }).catch((err) => {
|
||||
interaction.channel.send({ embeds: [newEmbed] });
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
function shuffleQueue(bot, interaction) {
|
||||
const guildId = interaction.guildId;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return interaction.reply("The audio queue is empty!"); }
|
||||
|
||||
let rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return interaction.reply("The audio queue is empty!"); }
|
||||
|
||||
//Shuffle the queue
|
||||
rawQueue = rawQueue.sort(() => Math.random()-0.5);
|
||||
|
||||
data[1] = rawQueue;
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
interaction.reply("The queue has been shuffled!\nThe new queue is:").catch((err) => {
|
||||
console.log(err);
|
||||
interaction.channel.send("The queue has been shuffled!\nThe new queue is:");
|
||||
});
|
||||
|
||||
showQueue(bot, false, interaction);
|
||||
}
|
||||
|
||||
|
||||
//[ { name: 'play', type: 'SUB_COMMAND', options: [ [Object] ] } ]
|
||||
module.exports = {
|
||||
name: "audio",
|
||||
description: 'Play a song from YouTube, add free!',
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
const commandList = ['stop', 'skip', 'pause', 'resume'];
|
||||
const command = interaction.options.data[0];
|
||||
|
||||
if (!command) {
|
||||
return interaction.reply("Please specify a song or playlist!").chatch(err => {
|
||||
console.log(err);
|
||||
interaction.channel.send("Uh oh, there's been an error!");
|
||||
});
|
||||
}
|
||||
|
||||
// if (args.length < 1) {
|
||||
// message.reply("Please use the following format _!audio [song name or URL]_ **or** _!audio queue_");
|
||||
// return;
|
||||
// } else
|
||||
|
||||
if (command.name == 'queue') {
|
||||
return showQueue(bot, false, interaction);
|
||||
} else if (commandList.indexOf(command.name) != -1) {
|
||||
return fromMessage(bot, command.name, interaction);
|
||||
} else if (command.name == 'remove') {
|
||||
if (args.length < 2) { return interaction.reply("Please specify a position in queue!"); }
|
||||
return removeFromQueue(bot, interaction, args[1].value);
|
||||
} else if (command.name == 'shuffle') {
|
||||
return shuffleQueue(bot, interaction);
|
||||
}
|
||||
|
||||
/*
|
||||
Re-introduce once the issue with ydtl-core is resolved (see
|
||||
https://github.com/porridgewithraisins/jam-bot#known-bugs)
|
||||
const stream = await ytdl(url, { filter: 'audioonly' });
|
||||
*/
|
||||
const channelId = interaction.guild.members.cache.get(interaction.user.id).voice.channelId;
|
||||
|
||||
if (!channelId) {
|
||||
interaction.reply("Please join a voice channel before you try this!");
|
||||
return;
|
||||
}
|
||||
|
||||
const subCommand = command.options[0];
|
||||
if (!subCommand) { return; }
|
||||
|
||||
interaction.deferReply();
|
||||
if (subCommand.name == 'playlist') {
|
||||
|
||||
var isPremium;
|
||||
await verPremium(bot, interaction.user.id).then(() => { isPremium = true; }).catch(() => { isPremium = false; });
|
||||
|
||||
const urls_promise = getPlaylistUrls(bot, subCommand.value, isPremium);
|
||||
urls_promise.then(async (urls) => {
|
||||
|
||||
for (let i = 0; i < urls.length; i++) {
|
||||
try {
|
||||
const url = urls[i].video_url;
|
||||
await playMusic(bot, interaction, channelId, url, true);
|
||||
|
||||
const msg = (i > 0) ? `Added ${i+1}/${urls.length} songs to queue` : `Added ${i+1}/${urls.length} song to queue`;
|
||||
interaction.editReply(msg).catch((err) => { interaction.channel.send(msg); });
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
const msg = (err == "Request failed with status code 400") ? "Invalid playlist URL" : "uh oh, there's been an error";
|
||||
|
||||
console.log(err);
|
||||
interaction.reply(msg).catch((err) => {
|
||||
interaction.channel.send(msg);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const url = subCommand.value;
|
||||
playMusic(bot, interaction, channelId, url);
|
||||
interaction.deleteReply();
|
||||
}
|
||||
}, pause_start_stop, playNext, showQueue,
|
||||
options: [
|
||||
{name: 'play', description: 'play a song', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND, options: [
|
||||
{name: 'video', description: 'The song URL/search term(s)', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'playlist', description: 'The playlist URL', type: Constants.ApplicationCommandOptionTypes.STRING, required: false}
|
||||
]},
|
||||
|
||||
{name: 'pause', description: 'Pause the currently playing song', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
{name: 'queue', description: 'Show the song queue', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
{name: 'remove', description: 'Remove a song from the queue', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND, options: [
|
||||
{name: 'position', description: 'The song\'s position in queue', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: true}
|
||||
]},
|
||||
|
||||
{name: 'resume', description: 'Resume playing the current song', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
{name: 'shuffle', description: 'Shuffle the song queue', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
{name: 'skip', description: 'skip the current song', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
{name: 'stop', description: 'stop the music and clear the queue', type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND},
|
||||
|
||||
//Actions left: remove, shuffle,
|
||||
]
|
||||
}
|
||||
+140
-91
@@ -1,8 +1,9 @@
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
// const { update } = require('apt');
|
||||
const { Collection, Client, Formatters, Intents } = require('discord.js');
|
||||
const { Collection, Client, Formatters, Intents, Interaction } = require('discord.js');
|
||||
const { CLIENT_ODBC } = require('mysql/lib/protocol/constants/client');
|
||||
const { time } = require('@discordjs/builders');
|
||||
const { welcome } = require('../admin/welcome.js');
|
||||
|
||||
let currencySymbol = '$';
|
||||
|
||||
@@ -31,14 +32,14 @@ function isNum(arg) {
|
||||
};
|
||||
|
||||
|
||||
function CreateNewCollection(message, client, server, id, opponent = null, game = null) {
|
||||
function CreateNewCollection(interaction, client, server, id, opponent = null, game = null) {
|
||||
const db = client.db(String(server));
|
||||
const dbo = db.collection(id);
|
||||
|
||||
db.listCollections({name: id})
|
||||
.next(function(err, collinfo) {
|
||||
if (!collinfo) {
|
||||
message.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!")
|
||||
interaction.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!")
|
||||
let hp_mp = {maxhp: BASE.HP, hp: BASE.HP, maxmp: BASE.MP, mp: BASE.MP}
|
||||
dbo.insertOne({balance: 10, rank: 1, lastdayworked: 0, xp: 0, hpmp: hp_mp, game: game, gamesettings: {battle: {class: 'none', ultimate: true}}, opponent: opponent, state: STATE.IDLE, equipped: { weapons: {main: null, secondary: null}, items: {}}});
|
||||
}
|
||||
@@ -46,7 +47,12 @@ function CreateNewCollection(message, client, server, id, opponent = null, game
|
||||
}
|
||||
|
||||
|
||||
function addxp(message, dbo, amt, xp_list) {
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
* @returns
|
||||
*/
|
||||
function addxp(bot, interaction, dbo, amt, xp_list, noPing = false) {
|
||||
if (!isNum(amt)) { return console.log("This isn't a number...."); }
|
||||
|
||||
dbo.find({"balance": {$exists: true}}).toArray(function(err, doc) {
|
||||
@@ -55,6 +61,7 @@ function addxp(message, dbo, amt, xp_list) {
|
||||
temp = doc[0];
|
||||
let rank = temp.rank + 1; //The table starts at rank 0, the user starts at rank 1
|
||||
const txp = amt; /*temp.xp + amt; // This part was used before the xp check was made in the 'work' function */
|
||||
|
||||
//If the rank is less than 100, you can still advance
|
||||
if (rank < 101) {
|
||||
let needed = xp_list.get(rank);
|
||||
@@ -75,11 +82,38 @@ function addxp(message, dbo, amt, xp_list) {
|
||||
|
||||
let newmp = temp.mp + 5;
|
||||
|
||||
dbo.updateOne({balance: temp.balance, rank: temp.rank, lastdayworked: temp.lastdayworked}, { $set: { rank: rank, hpmp: {maxhp: newhp, maxmp: newmp} }});
|
||||
message.channel.send('Congradulations <@' + message.author.id + '> for reaching rank ' + String(rank) + '!');
|
||||
dbo.updateOne({balance: temp.balance, rank: temp.rank, lastdayworked: temp.lastdayworked}, { $set: { rank: rank, hpmp: {maxhp: newhp, maxmp: newmp}, xp: txp }});
|
||||
|
||||
var user;
|
||||
if (interaction.user) {
|
||||
user = interaction.user;
|
||||
} else {
|
||||
// This is a message
|
||||
user = interaction.author;
|
||||
}
|
||||
|
||||
if (bot) {
|
||||
bot.mongoconnection.then((client) => {
|
||||
const sbo = client.db(interaction.guildId).collection('SETUP');
|
||||
sbo.findOne({_id: 'LEVELING'}).then((doc) => {
|
||||
if (!doc || !doc.card) {
|
||||
return interaction.channel.send('Congradulations <@' + user.id + '> for reaching rank ' + String(rank) + '!');
|
||||
}
|
||||
const member = interaction.guild.members.cache.get((interaction.user) ? interaction.user.id : interaction.member.id);
|
||||
|
||||
welcome(member, interaction.channel, doc.text, doc.card, doc.col, true, String(rank));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
interaction.channel.send('Congradulations <@' + user.id + '> for reaching rank ' + String(rank) + '!');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
message.reply("You've already reached max level!");
|
||||
if (!noPing) {
|
||||
interaction.reply("You've already reached max level!").catch((err) => {
|
||||
interaction.channel.send("You've already reached max level!");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
dbo.updateOne({balance: temp.balance}, { $set: { xp: txp}});
|
||||
@@ -87,25 +121,28 @@ function addxp(message, dbo, amt, xp_list) {
|
||||
}
|
||||
|
||||
|
||||
function getBalance(dbo, message) {
|
||||
function getBalance(dbo, interaction) {
|
||||
dbo.find({"balance": {$exists: true}}).toArray(function(err, doc) {
|
||||
let bal = 0;
|
||||
if (doc[0] && doc[0].balance) {
|
||||
bal = doc[0].balance;
|
||||
}
|
||||
return message.reply(`<@${message.author.id}>, your current balance is ${currencySymbol}${bal}`);
|
||||
return interaction.reply(`<@${interaction.user.id}>, your current balance is ${currencySymbol}${bal}`)
|
||||
.catch((err) => {
|
||||
interaction.channel.send(`<@${interaction.user.id}>, your current balance is ${currencySymbol}${bal}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function rank(dbo, message, xp_list) {
|
||||
function rank(dbo, interaction, xp_list) {
|
||||
dbo.find({"balance": {$exists: true}}).toArray(function(err, doc) {
|
||||
if (!String(doc)) { return console.log("ERROR!\nThis account does not exist!"); }
|
||||
|
||||
let next = doc[0].rank + 1;
|
||||
let needed = xp_list.get(next);
|
||||
|
||||
message.channel.send('<@' + message.author.id + '> you are currently at rank ' + String(next-1) + ' and have ' + String(doc[0].xp) + 'xp. You need ' + String(needed - doc[0].xp) + ' more xp to get to rank ' + String(next));
|
||||
interaction.channel.send(`<@${interaction.user.id}'> you are currently at rank ${next-1} and have ${doc[0].xp}xp. You need ${needed - doc[0].xp} more xp to get to rank ${next}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,22 +152,27 @@ function convertCurrency(id, amt, dbo) {
|
||||
|
||||
}
|
||||
|
||||
function checkAndUpdateBal(dbo, item, message, args) {
|
||||
|
||||
function checkAndUpdateBal(dbo, item, interaction, amt) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
dbo.find({"balance": {$exists: true}}).toArray(b = function(err, doc) {
|
||||
if (!String(doc)) {
|
||||
message.reply("Your account doesn't exist, please contact the mods for support");
|
||||
interaction.reply("Your account doesn't exist, please contact the mods for support").catch(() => {
|
||||
interaction.channel.send("Your account doesn't exist, please contact the mods for support");
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
const icost = args[0] * item.cost;
|
||||
const icost = amt * item.cost;
|
||||
if (doc[0].balance < icost) {
|
||||
message.reply("Insufficient funds!");
|
||||
interaction.reply("Insufficient funds!").catch(() => { interaction.channel.send("Insufficient funds!"); });
|
||||
resolve(false);
|
||||
} else {
|
||||
let temp = doc[0];
|
||||
dbo.updateOne({balance: temp.balance, rank: temp.rank, lastdayworked: temp.lastdayworked}, { $set: { balance: doc[0].balance -= icost }});
|
||||
message.reply(`You have bought ${item.name} for ${currencySymbol}${icost}!`);
|
||||
interaction.reply(`You have bought ${item.name} for ${currencySymbol}${icost}!`).catch(() => {
|
||||
interaction.channel.send(`You have bought ${item.name} for ${currencySymbol}${icost}!`);
|
||||
});
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
@@ -138,46 +180,51 @@ function checkAndUpdateBal(dbo, item, message, args) {
|
||||
}
|
||||
|
||||
|
||||
function buy(id, message, args, dbo, shop, xp_list) {
|
||||
if (args.length < 2) { return; }
|
||||
if (!isNum(args[0])) { return message.reply("Please enter a number for query 2"); }
|
||||
function buy(id, interaction, dbo, shop, xp_list) {
|
||||
const args = interaction.options.data;
|
||||
|
||||
let query = args[1];
|
||||
//REAPPLY THIS TO OTHER FUNCTIONS
|
||||
let query = args.filter((arg) => { return (arg.name == 'item'); })[0].value;
|
||||
let amt = args.filter((arg) => { return (arg.name == 'amount'); })[0].value;
|
||||
let item = shop.filter(function (item) { return item.name.toLowerCase() == query.toLowerCase(); })[0];
|
||||
|
||||
if (!String(item)) { return message.reply("This item does not exist!"); }
|
||||
if (!String(item)) { return interaction.reply("This item does not exist!").catch(() => { interaction.channel.send("This item does not exist!"); }); }
|
||||
|
||||
// let success = Boolean(checkAndUpdateBal(dbo, item, message, args));
|
||||
checkAndUpdateBal(dbo, item, message, args).then((success) => {
|
||||
if (!success) { return } //The message is handled in the CheckAndUpdateBal() function
|
||||
checkAndUpdateBal(dbo, item, interaction, amt).then((success) => {
|
||||
//The message is handled in the CheckAndUpdateBal() function
|
||||
if (!success) { return }
|
||||
|
||||
var newObj = { name: item.name, cost: item.cost, icon: item.icon, sect: item.sect};
|
||||
|
||||
addxp(message, dbo, Math.ceil(item.cost * 1.2), xp_list);
|
||||
addxp(bot, interaction, dbo, Math.ceil(item.cost * 1.2), xp_list);
|
||||
|
||||
dbo.find(newObj, {$exists: true}).toArray(function(err, doc) {
|
||||
if(String(doc)) {
|
||||
let newnum = doc[0].num + Number(args[0]);
|
||||
let newnum = doc[0].num + amt;
|
||||
dbo.updateOne({ name: item.name }, {$set: {num: newnum}});
|
||||
} else {
|
||||
item.num = amt;
|
||||
// dbo.insertOne({ name: item.name, cost: item.cost, icon: item.icon, sect: item.sect, num: Number(args[0])}); //Causes "cyclic dependancy"
|
||||
dbo.insertOne(item);
|
||||
dbo.updateOne(item, { $set: {num: Number(args[0]) }});
|
||||
dbo.updateOne(item, { $set: {num: amt }});
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
function sell(id, message, args, dbo, shop, xp_list) {
|
||||
if (args.length < 2) { return; }
|
||||
if (!isNum(args[0])) { return message.reply("Please enter a number for query 1"); }
|
||||
|
||||
let query = args[1];
|
||||
var newObj = { name: query };
|
||||
//FIXME
|
||||
function sell(bot, id, interaction, dbo, shop, xp_list) {
|
||||
const args = interaction.options.data;
|
||||
const query = args.filter((arg) => { return (arg.name == 'item'); })[0].value;
|
||||
var num = args.filter((arg) => { return (arg.name == 'amount'); })[0].value;
|
||||
|
||||
let item = shop.filter(function (titem) { return titem.name.toLowerCase() == query.toLowerCase(); });
|
||||
if (!String(item)) { return message.reply("This item does not exist!"); }
|
||||
if (!String(item)) {
|
||||
return interaction.reply("This item does not exist!").catch((err) => {
|
||||
interaction.channel.send("This item does not exist!");
|
||||
});
|
||||
}
|
||||
|
||||
item[0] = {name: item[0].name, cost: item[0].cost, icon: item[0].icon, sect: item[0].sect};
|
||||
|
||||
@@ -187,7 +234,6 @@ function sell(id, message, args, dbo, shop, xp_list) {
|
||||
if(String(doc)) {
|
||||
|
||||
//Make sure you don't sell more than you have
|
||||
let num = Number(args[0]);
|
||||
if (num < doc[0].num) {
|
||||
let newNum = doc[0].num - num;
|
||||
dbo.updateOne({ name: item[0].name }, {$set: {num: newNum}});
|
||||
@@ -204,23 +250,34 @@ function sell(id, message, args, dbo, shop, xp_list) {
|
||||
dbo.updateOne({"balance": {$exists: true}}, { $set: { balance: currentBal + amountSoldFor }});
|
||||
});
|
||||
|
||||
addxp(message, dbo, Math.ceil(functional_item.cost * 1.2), xp_list);
|
||||
addxp(bot, interaction, dbo, Math.ceil(functional_item.cost * 1.2), xp_list);
|
||||
|
||||
message.reply(`You've sold ${num} ${String(functional_item.name)} for ${currencySymbol}${amountSoldFor}`);
|
||||
interaction.reply(`You've sold ${num} ${String(functional_item.name)} for ${currencySymbol}${amountSoldFor}`)
|
||||
.catch((err) => {
|
||||
interaction.channel.send(`You've sold ${num} ${String(functional_item.name)} for ${currencySymbol}${amountSoldFor}`);
|
||||
});
|
||||
} else {
|
||||
message.reply("You don't own this item!");
|
||||
interaction.reply("You don't own this item!").catch((err) => {
|
||||
interaction.channel.send(`You've sold ${num} ${String(functional_item.name)} for ${currencySymbol}${amountSoldFor}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function work(dbo, message, xp_list) {
|
||||
function work(bot, dbo, interaction, xp_list) {
|
||||
let fulldate = new Date();
|
||||
let date = fulldate.getDate();
|
||||
dbo.find({"lastdayworked": {$exists: true}}).toArray(function(err, doc) {
|
||||
if (!String(doc)) { return message.reply("Your account doesn't exist, please contact the mods for support"); }
|
||||
if (!String(doc)) {
|
||||
return interaction.reply("Your account doesn't exist, please contact the mods for support").catch((err) => {
|
||||
interaction.channel.send("Your account doesn't exist, please contact the mods for support");
|
||||
});
|
||||
}
|
||||
if (doc[0].lastdayworked == date) {//date
|
||||
message.reply("You've already worked today, try again tomorrow!");
|
||||
interaction.reply("You've already worked today, try again tomorrow!").catch((err) => {
|
||||
interaction.channel.send("You've already worked today, try again tomorrow!");
|
||||
});
|
||||
} else {
|
||||
//Amount to be paid
|
||||
let amt = 0;
|
||||
@@ -229,14 +286,17 @@ function work(dbo, message, xp_list) {
|
||||
|
||||
//Update the amount to the new TOTAL balance
|
||||
dbo.updateOne({"balance": {$exists: true}}, { $set: { balance: doc[0].balance + amt, lastdayworked: date }});
|
||||
addxp(message, dbo, xp_earned, xp_list);
|
||||
message.channel.send(`<@${message.author.id}> worked and earned ${currencySymbol}${amt} and ${xp_earned} xp!`);
|
||||
|
||||
addxp(bot, interaction, dbo, xp_earned, xp_list);
|
||||
interaction.reply(`<@${interaction.user.id}> worked and earned ${currencySymbol}${amt} and ${xp_earned} xp!`).catch((err) => {
|
||||
interaction.channel.send(`<@${interaction.user.id}> worked and earned ${currencySymbol}${amt} and ${xp_earned} xp!`)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function printInventory(dbo, message) {
|
||||
function printInventory(dbo, interaction) {
|
||||
let tempstring = "";
|
||||
dbo.find().toArray(function(err, docs){
|
||||
docs.forEach(val => {
|
||||
@@ -246,44 +306,50 @@ function printInventory(dbo, message) {
|
||||
});
|
||||
|
||||
if (tempstring == "") { tempstring += "You have nothing in your inventory!"; }
|
||||
message.reply(tempstring);
|
||||
interaction.reply(tempstring).catch((err) => {
|
||||
interaction.channel.send(tempstring);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function getShop(message, args, items, bot) {
|
||||
if (args.length == 0) {
|
||||
let temp = Formatters.codeBlock(items.map(i => `${i.sect}`).join(' '));
|
||||
temp = [...new Set(temp.split(' '))];
|
||||
function getShop(interaction, items, bot) {
|
||||
const args = interaction.options.data;
|
||||
const type = args.filter((arg) => { return (arg.name == 'type'); })[0].value.toLowerCase();
|
||||
|
||||
return message.reply(`Please use the format ${bot.prefix}shop [type] [page number]\nTypes are: ${temp}`);
|
||||
}
|
||||
// if (args.length == 0) {
|
||||
// let temp = Formatters.codeBlock(items.map(i => `${i.sect}`).join(' '));
|
||||
// temp = [...new Set(temp.split(' '))];
|
||||
|
||||
// return message.reply(`Please use the format ${bot.prefix}shop [type] [page number]\nTypes are: ${temp}`);
|
||||
// }
|
||||
|
||||
let ind = 1;
|
||||
let noinp = false;
|
||||
if (args.length > 1) {
|
||||
if (args[1] < (items.length / 9)) {
|
||||
ind = Number(args[1]);
|
||||
const amt = args.filter((arg) => { return (arg.name == 'page'); })[0].value;
|
||||
if (amt.value < (items.length / 9)) {
|
||||
ind = Number(amt);
|
||||
} else {
|
||||
return message.reply("That number is too large");
|
||||
return interaction.reply("That number is too large").catch(() => { interaction.channel.send("That number is too large"); });
|
||||
}
|
||||
} else {
|
||||
noinp = true;
|
||||
}
|
||||
|
||||
const items2 = items.filter(function(f) { return (f.sect.toLowerCase() == args[0].toLowerCase()) }).slice((ind - 1)*10, (ind - 1)*10+10);
|
||||
const items2 = items.filter(function(f) { return (f.sect.toLowerCase() == type) }).slice((ind - 1)*10, (ind - 1)*10+10);
|
||||
newText = Formatters.codeBlock(items2.map(i => `${i.icon} (${i.name}): $${i.cost}`).join('\n')); //${currencySymbol} doesn't owrk for some reason
|
||||
|
||||
if (noinp) {
|
||||
newText += `(Use ${bot.prefix}shop [type] [page number] to access other pages)`;
|
||||
}
|
||||
|
||||
return message.reply(newText);
|
||||
return interaction.reply(newText).catch(() => { interaction.channel.send(newtext); });
|
||||
}
|
||||
|
||||
|
||||
function econHelp() {
|
||||
let l = ["buy", 'shop', 'work', 'rank', 'inventory', 'balance', 'sell']
|
||||
let l = ["buy", 'shop', 'work', 'rank', 'inventory', 'balance', 'sell'];
|
||||
|
||||
return l.join(", ");
|
||||
}
|
||||
@@ -293,10 +359,11 @@ function econHelp() {
|
||||
module.exports = {
|
||||
name: 'econ',
|
||||
description: 'ECON',
|
||||
async execute(bot, message, args, command, Discord, mongouri, items, xp_list) {
|
||||
async execute(bot, interaction, Discord, mongouri, items, xp_list) {
|
||||
//Set Discord vars
|
||||
const id = message.author.id;
|
||||
const server = message.guild.id;
|
||||
const id = interaction.user.id;
|
||||
const server = interaction.guildId;
|
||||
const command = interaction.commandName;
|
||||
|
||||
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||
// if (client.writeConcern || client.writeConcern) {
|
||||
@@ -308,60 +375,42 @@ module.exports = {
|
||||
bot.mongoconnection.then(async (client) => {
|
||||
|
||||
//Initialize if necessary
|
||||
CreateNewCollection(message, client, server, id);
|
||||
CreateNewCollection(interaction, client, server, id);
|
||||
|
||||
const db = client.db(String(server));
|
||||
const dbo = db.collection(id);
|
||||
|
||||
currencySymbol = bot.currencysymbolmmain;
|
||||
|
||||
//test area
|
||||
if (command == 'xp' || command == 'adbal') {
|
||||
//Selmer Dev only command
|
||||
if (message.member.roles.cache.has('944048889038774302')) {
|
||||
if (command == 'xp') {
|
||||
return addxp(message, dbo, Number(args[0]), xp_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Command Area
|
||||
if(command == 'init') {
|
||||
//Add security check here
|
||||
// init.execute(bot, message, args, command, dbo, Discord, connect);
|
||||
return;
|
||||
} else if (command == 'buy') {
|
||||
buy(id, message, args, dbo, items, xp_list);
|
||||
buy(bot, id, interaction, dbo, items, xp_list);
|
||||
} else if (command == 'shop') {
|
||||
getShop(message, args, items, bot);
|
||||
getShop(interaction, items, bot);
|
||||
} else if (command == 'work') {
|
||||
work(dbo, message, xp_list);
|
||||
work(bot, dbo, interaction, xp_list);
|
||||
} else if (command == 'rank') {
|
||||
rank(dbo, message, xp_list);
|
||||
rank(dbo, interaction, xp_list);
|
||||
} else if (command == 'inventory') {
|
||||
printInventory(dbo, message);
|
||||
printInventory(dbo, interaction);
|
||||
} else if (command == 'balance') {
|
||||
getBalance(dbo, message);
|
||||
getBalance(dbo, interaction);
|
||||
} else if (command == 'sell') {
|
||||
sell(id, message, args, dbo, items, xp_list);
|
||||
sell(bot, id, interaction, dbo, items, xp_list);
|
||||
} else {
|
||||
message.channel.send("'" + message.content + "' is not a command!");
|
||||
interaction.reply(`${command} is not a command`).catch((err) => {
|
||||
interaction.channel.send(`${command} is not a command`);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
//Battle Updating stuff
|
||||
addxp, checkAndUpdateBal, CreateNewCollection, econHelp, addxp, BASE, STATE
|
||||
addxp, checkAndUpdateBal, CreateNewCollection, econHelp, BASE, STATE,
|
||||
options: []
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
?????????????? What did I need this for?
|
||||
else if (command == 'checkinv') {
|
||||
const req = dbo.findOne({ id: message.guild.id });
|
||||
if (!req) { return message.reply("Doc doesn't exist!"); }
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,31 @@
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
//Add the items on boot-up
|
||||
"buy": {
|
||||
description: 'Buy an item from the shop',
|
||||
options: [
|
||||
{name: 'item', description: 'the item you want to buy', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: []},
|
||||
{name: 'amount', description: 'item amount', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: true, choices: []},
|
||||
]},
|
||||
'shop': {
|
||||
description: 'Displays the shop',
|
||||
options: [
|
||||
{name: 'type', description: 'the type of item', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [{name: 'Food', value: 'Food'}, {name: 'Weapons', value: 'Weapons'}, {name: 'HP', value: 'HP'}, {name: 'MP', value: 'MP'}]},
|
||||
{name: 'page', description: 'the shop page you want to go to', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: false},
|
||||
]
|
||||
}, 'work': {
|
||||
description: 'Work and earn money and xp',
|
||||
options: []
|
||||
},
|
||||
'rank': { description: 'See your current rank' },
|
||||
'inventory': { description: 'Check what\'s in your inventory' },
|
||||
'balance': { description: 'Check your current balance' },
|
||||
'sell': {
|
||||
description: 'Sell an item from your inventory',
|
||||
options: [
|
||||
{name: 'item', description: 'the item you want to buy', type: Constants.ApplicationCommandOptionTypes.STRING, required: true},
|
||||
{name: 'amount', description: 'the item you want to buy', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: true}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
const fs = require('fs');
|
||||
const { Client } = require('discord.js');
|
||||
|
||||
function mapToObj(map){
|
||||
const obj = {}
|
||||
for (let [k,v] of map) {
|
||||
obj[k] = v
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
|
||||
function objToMap(obj) {
|
||||
const m = new Map();
|
||||
for (i in obj) {
|
||||
m.set(i, obj[i]);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
async function backupLists(bot, IDM) {
|
||||
try {
|
||||
var backups = {}
|
||||
backups.locked = mapToObj(bot.lockedChannels);
|
||||
const bts = JSON.stringify({ "backups": backups });
|
||||
|
||||
if (IDM) {
|
||||
fs.writeFile('commands/admin/backup.json', bts, 'utf8', (err) => {
|
||||
// error checking
|
||||
if(err) throw err;
|
||||
|
||||
console.log("New data added: " + bts);
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
process.env.backupLists = bts;
|
||||
process.exit(0);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Client} bot
|
||||
* @param {Boolean} IDM
|
||||
*/
|
||||
async function loadBotBackups(bot, IDM) {
|
||||
try {
|
||||
if (!process.env.backupLists) {
|
||||
const botBackups = require('../admin/backup.json').backups;
|
||||
bot.lockedChannels = objToMap(botBackups.locked);
|
||||
} else {
|
||||
bot.lockedChannels = objToMap(JSON.parse(process.env.backupLists.locked));
|
||||
}
|
||||
|
||||
// bot.user.setActivity("RESTARTING BOT, PLEASE STAND BY.mp3", { type: "LISTENING" }); // User is....undefined????
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
bot.lockedChannels = new Map();
|
||||
const a = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = { backupLists, loadBotBackups }
|
||||
@@ -4,7 +4,7 @@ function devCheck(message, bot) {
|
||||
const command = message.content.split(' ')[0].slice(1);
|
||||
const args = message.content.split(' ')[1];
|
||||
const member = bot.guilds.cache.get(bot.home_server).members.cache.get(message.author.id);
|
||||
console.log(command);
|
||||
|
||||
//Check if they have the "Selmer Dev" role
|
||||
if (member.roles.cache.has('944048889038774302')) {
|
||||
switch (command) {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
const Discord = require('discord.js')
|
||||
const axios = require('axios')
|
||||
const cheerio = require('cheerio');
|
||||
const { URL } = require("url");
|
||||
|
||||
function isValidUrl(s) {
|
||||
try {
|
||||
new URL(s);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function handleStreamInp(bot, url, customTitle) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!isValidUrl(url)) {
|
||||
return reject(false);
|
||||
}
|
||||
|
||||
axios.get(url).then(async response => {
|
||||
var title;
|
||||
|
||||
if (customTitle) {
|
||||
title = customTitle;
|
||||
} else {
|
||||
const html = response.data;
|
||||
const $ = cheerio.load(html);
|
||||
title = $('meta[name="description"]').attr("content");
|
||||
}
|
||||
|
||||
bot.user.setActivity({name: title, type: "STREAMING", url: url});
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//Have this only visible to you.
|
||||
/**
|
||||
* @param {Discord.Client} bot
|
||||
* @param {Discord.Interaction} interaction
|
||||
*/
|
||||
async function setPresence(bot, interaction) {
|
||||
const command = interaction.options.data[0];
|
||||
|
||||
if (command.name == "setpresence") {
|
||||
const txt = command.options.filter((arg) => { return(arg.name == 'pres_text'); })[0].value;
|
||||
const type = command.options.filter((arg) => { return(arg.name == 'type'); })[0].value;
|
||||
|
||||
var sep = " ";
|
||||
if (type == "LISTENING" || type == "WATCHING") {
|
||||
sep = " to ";
|
||||
} else if (type == "COMPETING") {
|
||||
sep = " in ";
|
||||
}
|
||||
|
||||
//Check if it's me
|
||||
if (interaction.user.id == bot.guilds.cache.get(bot.home_server).ownerId) {
|
||||
if (type == "STREAMING") {
|
||||
const t = (command.options.length > 2) ? command.options.filter((arg) => { return(arg.name == "display_name"); })[0].value : null;
|
||||
|
||||
handleStreamInp(bot, txt, t, interaction).then(() => {
|
||||
interaction.reply(`Set bot presence to _${type + sep + txt}_`);
|
||||
}).catch(() => {
|
||||
interaction.reply("Invalid URL").catch((err) => {
|
||||
interaction.channel.send("Invalid URL");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
bot.user.setActivity(txt, { type: type });
|
||||
interaction.reply(`Set bot presence to _${type + sep + txt}_`);
|
||||
}
|
||||
}
|
||||
} else if (command.name == "setactivity") {
|
||||
const stat = command.options[0];
|
||||
|
||||
bot.user.setStatus(stat.value);
|
||||
interaction.reply(`Set bot status to ${stat.value}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = { setPresence, isValidUrl }
|
||||
@@ -27,10 +27,12 @@ function handle_dm(message, bot) {
|
||||
handleInp(bot, message);
|
||||
} else if (message.content.indexOf('!reminders') != -1) {
|
||||
reminders.execute(message, null, null, null, bot);
|
||||
} else if (message.content.indexOf('!repo') != -1 || message.content.indexOf('!code') != -1) {
|
||||
repo.execute(message, null, null, null, bot);
|
||||
}
|
||||
|
||||
// else if (message.content.indexOf('!repo') != -1 || message.content.indexOf('!code') != -1) {
|
||||
// repo.execute(message, null, null, null, bot);
|
||||
// }
|
||||
|
||||
else {
|
||||
return message.reply('UNUSABLE DM COMMAND DETECTED');
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@ const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
|
||||
|
||||
//#region game lose/win
|
||||
function loseGame(user_dbo, xp_collection, message, bot = null) {
|
||||
function loseGame(user_dbo, xp_collection, interaction, bot = null) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs) {
|
||||
const doc = docs[0];
|
||||
if (doc == undefined) {
|
||||
message.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||
addComplaintButton(bot, message);
|
||||
interaction.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||
addComplaintButton(bot, interaction);
|
||||
return;
|
||||
}
|
||||
if (doc.game == null) { return message.reply("You're not even in a game and you're trying to quit! Sad..."); }
|
||||
if (doc.game == null) { return interaction.reply("You're not even in a game and you're trying to quit! Sad..."); }
|
||||
|
||||
var addbal;
|
||||
//If this function was called from "winGame", return
|
||||
@@ -25,10 +25,13 @@ function loseGame(user_dbo, xp_collection, message, bot = null) {
|
||||
if (doc.balance > 5) {
|
||||
user_dbo.updateOne(doc, { $set: { balance: doc.balance - addbal}});
|
||||
}
|
||||
} else { message.channel.delete(); }
|
||||
} else {
|
||||
//Check if the channel is a thread
|
||||
interaction.channel.delete();
|
||||
}
|
||||
|
||||
//Update the player's xp
|
||||
addxp(message, user_dbo, Math.ceil((BASE.XP * doc.rank)/2),xp_collection)
|
||||
addxp(bot, interaction, user_dbo, Math.ceil((BASE.XP * doc.rank)/2),xp_collection);
|
||||
user_dbo.updateOne({"game": {$exists: true}}, { $set: { game: null, opponent: null, state: STATE.IDLE, 'hpmp.hp': doc.hpmp.maxhp, 'hpmp.mp': doc.hpmp.maxmp }});
|
||||
|
||||
resolve(addbal);
|
||||
@@ -38,14 +41,14 @@ function loseGame(user_dbo, xp_collection, message, bot = null) {
|
||||
}
|
||||
|
||||
|
||||
function winGame(client, bot, db, user_dbo, xp_collection, message, singlePlayer = false) {
|
||||
function winGame(client, bot, db, user_dbo, xp_collection, interaction, singlePlayer = false) {
|
||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||
const doc = docs[0];
|
||||
|
||||
//Check for an opponent
|
||||
if (doc.opponent != null) {
|
||||
let other = db.collection(doc.opponent);
|
||||
let promise_temp = loseGame(other, xp_collection, message);
|
||||
let promise_temp = loseGame(other, xp_collection, interaction);
|
||||
|
||||
promise_temp.then(function(result) {
|
||||
var amt_taken = result;
|
||||
@@ -55,7 +58,7 @@ function winGame(client, bot, db, user_dbo, xp_collection, message, singlePlayer
|
||||
|
||||
//Delete the bot's record of the game
|
||||
if (!singlePlayer) {
|
||||
client.db('B|S' + bot.user.id).collection(message.guild.id).drop();
|
||||
client.db('B|S' + bot.user.id).collection(interaction.guildId).drop();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,16 +66,16 @@ function winGame(client, bot, db, user_dbo, xp_collection, message, singlePlayer
|
||||
user_dbo.updateOne({"game": {$exists: true}}, { $set: { game: null, opponent: null, state: STATE.IDLE, xp: doc.xp + (BASE.XP * doc.rank), 'hpmp.hp': doc.hpmp.maxhp, 'hpmp.mp': doc.hpmp.maxmp }});
|
||||
|
||||
if (!singlePlayer) {
|
||||
const channel = bot.channels.cache.get(message.channel.parentId);
|
||||
const channel = bot.channels.cache.get(interaction.channel.parentId);
|
||||
channel.send(`<@${user_dbo.s.namespace.collection}> just won a game of "${docs[0].game}"!`);
|
||||
}
|
||||
message.channel.delete();
|
||||
interaction.channel.delete();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function equipItem(client, bot, db, dbo, message) {
|
||||
|
||||
function equipItem(client, bot, db, dbo, interaction) {
|
||||
return interaction.reply("This command is not implemented yet!");
|
||||
if (!bot.inDebugMode) { return; }
|
||||
let items = [
|
||||
{ name: 'HP Potion', cost: 20, icon: 'CUSTOM|healing_potion', sect: 'HP', num: 2 },
|
||||
|
||||
+110
-94
@@ -1,5 +1,7 @@
|
||||
// // @ts-check //Disabled
|
||||
|
||||
// Maybe have the interaction type be "user" https://canary.discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-types
|
||||
const { MessageActionRow, MessageButton, Message } = require('discord.js');
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
let ecoimport = require("../db/econ.js");
|
||||
|
||||
@@ -20,7 +22,7 @@ const { chooseClass, presentClasses } = require('./game_classes.js');
|
||||
|
||||
//Has a list of all games (used to change player state)
|
||||
const allGames = ['battle', 'Tic Tac Toe'];
|
||||
// const { NULL } = require('mysql/lib/protocol/constants/types');
|
||||
|
||||
|
||||
|
||||
//#region functions (NOT GAME SPECIFIC)
|
||||
@@ -69,18 +71,18 @@ async function Initialize(bot, user_dbo, command, message, first, second, other_
|
||||
//#endregion
|
||||
|
||||
//replies to the message with current game specifics
|
||||
function getGame(message, args, db) {
|
||||
function getGame(interaction, args, db) {
|
||||
let id;
|
||||
var temp;
|
||||
|
||||
if (args.length == 1 && String(args[0]).startsWith('<')) { id = args[0].substr(2, args[0].length - 3)}
|
||||
else { id = message.author.id; }
|
||||
var user_dbo = db.collection(message.author.id);
|
||||
else { id = interaction.user.id; }
|
||||
var user_dbo = db.collection(interaction.user.id);
|
||||
|
||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||
const doc = docs[0];
|
||||
if (doc.game == null) {
|
||||
return message.reply(`<@${id}> is not currently playing a game!`);
|
||||
return interaction.reply(`<@${id}> is not currently playing a game!`);
|
||||
}
|
||||
|
||||
temp = `<@${id}> is currently playing "${doc.game}"`;
|
||||
@@ -89,58 +91,64 @@ function getGame(message, args, db) {
|
||||
temp += ` with <@${doc.opponent}>`
|
||||
}
|
||||
|
||||
message.reply(temp);
|
||||
interaction.reply(temp);
|
||||
});
|
||||
}
|
||||
|
||||
function acceptIsValid(bot, other_discord, message, msg, tag_len) {
|
||||
function acceptIsValid(bot, other_discord, interaction, invUserId, message) {
|
||||
|
||||
if (other_discord == undefined) {
|
||||
message.reply("This is not a valid invite!");
|
||||
interaction.reply("This is not a valid invite!");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Make sure the bot was the one creating the invite
|
||||
let check0 = msg.author.bot;
|
||||
let check0 = message.author.bot;
|
||||
|
||||
//Author
|
||||
let tag = msg.content.substr(2, tag_len);
|
||||
let check1 = Number(tag) == Number(message.author.id);
|
||||
let check1 = Number(other_discord.id) == Number(invUserId);
|
||||
|
||||
//Time (within the last 5 min)
|
||||
let prev = snowflake.convertSnowflakeToDate(msg.id);
|
||||
let now = snowflake.convertSnowflakeToDate(message.id);
|
||||
let prev = snowflake.convertSnowflakeToDate(message.id);
|
||||
let now = snowflake.convertSnowflakeToDate(interaction.id);
|
||||
// @ts-ignore
|
||||
let diff = now - prev;
|
||||
var minutes = Math.floor((diff/1000)/60);
|
||||
let check2 = minutes <= 5 || bot.inDebugMode;
|
||||
|
||||
if (!check0) { message.reply("really?"); }
|
||||
else if (!check1 && check2) { message.reply("_INVALID USER_"); }
|
||||
else if (check1 && !check2) { message.reply("_THIS INVITE EXPIRED!_"); }
|
||||
else if (!check1 && !check2) { message.reply("_THIS MESSAGE HAS AN INVALID USER AND HAS EXPIRED_")}
|
||||
if (!check0) { interaction.reply("really?"); }
|
||||
else if (!check1 && check2) { interaction.reply("_INVALID USER_"); }
|
||||
else if (check1 && !check2) { interaction.reply("_THIS INVITE EXPIRED!_"); }
|
||||
else if (!check1 && !check2) { interaction.reply("_THIS MESSAGE HAS AN INVALID USER AND HAS EXPIRED_")}
|
||||
|
||||
return (check0 && check1 && check2);
|
||||
}
|
||||
|
||||
|
||||
function hpmp(message, command, dbo) {
|
||||
function hpmp(interaction, command, dbo) {
|
||||
// throw 'THIS HAS NOT BEEN UPDATED WITH THE MOST RECENT VERSION OF THE MONGODB STRUCTURE!';
|
||||
|
||||
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
||||
interaction.reply(`You have ${String(doc[0].hpmp.hp)} hp and ${String(doc[0].hpmp.mp)} mp left!`);
|
||||
});
|
||||
|
||||
/*
|
||||
if (command == 'hp') {
|
||||
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
||||
return message.reply(`You have ${String(doc[0].hpmp.hp)} hp left!`);
|
||||
return interaction.reply(`You have ${String(doc[0].hpmp.hp)} hp left!`);
|
||||
});
|
||||
} else if (command == 'mp') {
|
||||
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
||||
return message.reply(`You have ${String(doc[0].hpmp.hp)} mp left!`);
|
||||
return interaction.reply(`You have ${String(doc[0].hpmp.MP)} mp left!`);
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
function equip(message, args, command, dbo, bot, shop) {
|
||||
const inp = args[1];
|
||||
if (!inp) { return message.reply("Please provide input (either a weapon for main or shield for secondary)")}
|
||||
function equip(interaction, inp, command, dbo, bot, shop) {
|
||||
// const inp = args[1];
|
||||
if (!inp) { return interaction.reply("Please provide input (either a weapon for main or shield for secondary)"); }
|
||||
|
||||
//Check if the user is already in a game
|
||||
dbo.find({'game': {$exists: true}}).toArray(function(err, docs) {
|
||||
@@ -149,7 +157,7 @@ function equip(message, args, command, dbo, bot, shop) {
|
||||
if (doc.game != null) {
|
||||
ret = true;
|
||||
// console.log(doc.game);
|
||||
return message.reply('You can\'t equip while in a game!');
|
||||
return interaction.reply('You can\'t equip while in a game!');
|
||||
}
|
||||
|
||||
//If the thing is a shield, add it to secondary
|
||||
@@ -158,7 +166,7 @@ function equip(message, args, command, dbo, bot, shop) {
|
||||
if (docs[0] != undefined) {
|
||||
dbo.updateOne({}, {$set: {'equipped.weapons.secondary': docs[0]}});
|
||||
} else {
|
||||
message.reply("You don't own a shield!");
|
||||
interaction.reply("You don't own a shield!");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -170,7 +178,7 @@ function equip(message, args, command, dbo, bot, shop) {
|
||||
//Equip the weapon
|
||||
dbo.updateOne({}, {$set: {'equipped.weapons.main': docs[0]}});
|
||||
} else {
|
||||
message.reply(`You don't own any ${inp}s!`);
|
||||
interaction.reply(`You don't own any ${inp}s!`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -213,12 +221,11 @@ function in_game_redirector(bot, interaction, threadname, doc, client, mongouri,
|
||||
module.exports ={
|
||||
name: "game",
|
||||
description: "Play a game using Selmer Bot!",
|
||||
async execute(bot, message, args, command, Discord, mongouri, items, xp_collection) {
|
||||
|
||||
async execute(bot, interaction, command, Discord, mongouri, items, xp_collection) {
|
||||
|
||||
//#region Setup
|
||||
const id = message.author.id;
|
||||
const server = message.guild.id;
|
||||
const id = interaction.user.id;
|
||||
const server = interaction.guildId;
|
||||
|
||||
// // @ts-ignore
|
||||
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||
@@ -235,12 +242,12 @@ module.exports ={
|
||||
const serverinbotdb = botdb.collection(server);
|
||||
|
||||
//Initialize if necessary
|
||||
ecoimport.CreateNewCollection(message, client, server, id);
|
||||
command = args[0];
|
||||
ecoimport.CreateNewCollection(interaction, client, server, id);
|
||||
var commandName = command.name;
|
||||
|
||||
//Check for a second person and create a second database entry if neccessary
|
||||
if (message.mentions.users.first() != undefined) {
|
||||
ecoimport.CreateNewCollection(message, client, server, message.mentions.users.first().id);
|
||||
if (command.options && command.options.length > 0 && command.options[0].type == "USER") {
|
||||
ecoimport.CreateNewCollection(interaction, client, server, command.options[0].value);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -258,41 +265,30 @@ module.exports ={
|
||||
|
||||
//#region non-game-specific commands
|
||||
//For TWO+ PLAYER games only!!!
|
||||
if (command == 'accept') {
|
||||
//Handle the messages
|
||||
if (message.reference == null) { return message.reply("Please reply to a valid battle request message!"); }
|
||||
let mid = message.reference.messageId;
|
||||
let msg = await message.channel.messages.fetch(mid);
|
||||
|
||||
//Check if the person actually challenged you
|
||||
//Get the length of any user tag
|
||||
let mentioned = msg.mentions.users.keys();
|
||||
|
||||
let tag_len = String(mentioned.next().value).length;
|
||||
|
||||
//<@tage_len>, <@ --2+tag_len+2+3 = 7+tag_len
|
||||
let other_tag = msg.content.substr(7+tag_len, tag_len);
|
||||
|
||||
const other_discord = msg.mentions.users.get(other_tag);
|
||||
if (commandName == 'accept') {
|
||||
const args = interaction.customId.split('|');
|
||||
// console.log(interaction.message.interaction);
|
||||
// console.log(interaction.user);
|
||||
// return console.log(args);
|
||||
|
||||
//Should also check if the player is already playing a game!!!
|
||||
if (!acceptIsValid(bot, other_discord, message, msg, tag_len)) { return; }
|
||||
if (!acceptIsValid(bot, interaction.user, interaction, args[1], interaction.message)) { return; }
|
||||
|
||||
//Get the opponent
|
||||
const other = db.collection(other_discord.id);
|
||||
let startPos = msg.content.indexOf('"') + 1;
|
||||
let newCommand = msg.content.substr(startPos, msg.content.lastIndexOf('"') - startPos);
|
||||
|
||||
const other_id = interaction.message.interaction.user.id;
|
||||
const other = db.collection(other_id);
|
||||
// return console.log(args, interaction.message.interaction);
|
||||
let newCommand = interaction.message.interaction.commandName.split(" ")[1];
|
||||
|
||||
//#region BOT SECTION
|
||||
|
||||
//Store both IDs in the database (for turns)
|
||||
let name_first = await bot.users.cache.get(id);
|
||||
let name_second = await bot.users.cache.get(other_discord.id);
|
||||
let name_second = await bot.users.cache.get(other_id);
|
||||
|
||||
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
|
||||
const threadname = `${name_first.username} VS ${name_second.username} [${newCommand.toUpperCase()}]`;
|
||||
var newObj = {0: id, 1: other_discord.id, turn: 0, thread: threadname};
|
||||
var newObj = {0: id, 1: other_id, turn: 0, thread: threadname};
|
||||
|
||||
if (newCommand.replaceAll(" ", "").toLowerCase() == 'tictactoe') { newCommand = 'Tic Tac Toe'; }
|
||||
|
||||
@@ -316,90 +312,110 @@ module.exports ={
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
const remAccptBtn = (msgToDel) => {
|
||||
try {
|
||||
msgToDel.edit({components: []});
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
//Need this for all 2 player games
|
||||
const result = Initialize(bot, dbo, newCommand, msg, id, other_discord.id, other);
|
||||
const result = Initialize(bot, dbo, newCommand, interaction.message, id, other_id, other);
|
||||
|
||||
if (newCommand == 'battle') {
|
||||
result.then(function (thread) {
|
||||
battle.handle(client, dbo, other, bot, thread, 'initalize', mongouri, items, null, xp_collection);
|
||||
remAccptBtn(interaction.message);
|
||||
});
|
||||
} else if (newCommand == 'Tic Tac Toe') {
|
||||
result.then(function (thread) {
|
||||
ttt.handle(client, db, dbo, other, bot, thread, 'initalize', mongouri, null, xp_collection);
|
||||
remAccptBtn(interaction.message);
|
||||
});
|
||||
}
|
||||
} else if (command == 'quit') {
|
||||
} else if (commandName == 'quit') {
|
||||
|
||||
const channel = bot.channels.cache.get(interaction.channel.parentId);
|
||||
|
||||
const channel = bot.channels.cache.get(message.channel.parentId);
|
||||
//Remove the turn counter from the bot's database
|
||||
serverinbotdb.deleteOne({0: id} || {1: id});
|
||||
if (doc.opponent != null) {
|
||||
// let other = message.guild.members.cache.get(doc.opponent);
|
||||
let other = db.collection(doc.opponent);
|
||||
channel.send(`<@${message.author.id}> has quit a game of "${game}" with <@${doc.opponent}>!`);
|
||||
winGame(client, bot, db, other, xp_collection, message);
|
||||
channel.send(`<@${interaction.user.id}> has quit a game of "${game}" with <@${doc.opponent}>!`);
|
||||
winGame(client, bot, db, other, xp_collection, interaction);
|
||||
} else {
|
||||
loseGame(dbo, xp_collection, message, bot);
|
||||
channel.send(`<@${message.author.id}> has quit a game of "${game}"!`);
|
||||
loseGame(dbo, xp_collection, interaction, bot);
|
||||
channel.send(`<@${interaction.user.id}> has quit a game of "${game}"!`);
|
||||
}
|
||||
}
|
||||
else if (command == 'status') {
|
||||
getGame(message, args, db);
|
||||
} else if (command == 'hp' || command == 'mp') {
|
||||
hpmp(message, command, dbo);
|
||||
else if (commandName == 'status') {
|
||||
getGame(interaction, args, db);
|
||||
} else if (commandName == 'hpmp') {
|
||||
hpmp(interaction, commandName, dbo);
|
||||
} else if (command == 'equip') {
|
||||
// equipItem(client, bot, db, dbo, message);
|
||||
equip(message, args, command, dbo, bot, items);
|
||||
// This does not work
|
||||
equip(interaction, args, command, dbo, bot, items);
|
||||
} else if (command == 'classes') {
|
||||
// This does not work
|
||||
presentClasses(message, args[1]);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region game-specific commands
|
||||
else {
|
||||
if (command == undefined) { return message.reply("Please specify a game or use _!game help_"); }
|
||||
if (commandName == undefined) { return interaction.reply("Please specify a game or use _!game help_"); }
|
||||
|
||||
//Make change to new name if necessary
|
||||
if (command.replaceAll(" ", "").toLowerCase() == 'tictactoe') { command = 'Tic Tac Toe'; }
|
||||
if (commandName.replaceAll(" ", "").toLowerCase() == 'tictactoe') { commandName = 'Tic Tac Toe'; }
|
||||
|
||||
if (game == 'battle' || command == 'battle') {
|
||||
if (!bot.inDebugMode) { return message.reply("This command is currently in development!"); }
|
||||
//RETURN TO THIS LATER
|
||||
if (game == 'battle' || commandName == 'battle') {
|
||||
if (!bot.inDebugMode) { return interaction.reply("This command is currently in development!"); }
|
||||
|
||||
//Handle sending the request and making sure the user exists here
|
||||
let other_discord = message.mentions.users.first();
|
||||
if (other_discord == undefined) {
|
||||
return message.reply(`"${args[1]}" is not a valid user (use _!game battle @user_)`);
|
||||
}
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`gameaccept|${command.options[0].value}|${interaction.user.id}`)
|
||||
.setLabel('Accept Invite')
|
||||
.setStyle('SUCCESS')
|
||||
);
|
||||
|
||||
message.channel.send(`${other_discord}, <@${message.author.id}> has invited you to play _"battle"_. To accept, please reply to this message with _!game accept_`);
|
||||
} else if (game == 'Tic Tac Toe' || command == 'Tic Tac Toe') {
|
||||
let other_discord = message.mentions.users.first();
|
||||
if (other_discord == undefined) {
|
||||
return message.reply(`"${args[1]}" is not a valid user (use _!game tictactoe @user_)`);
|
||||
}
|
||||
const content = {content: `${command.options[0].user}, ${interaction.user} has invited you to play _"Tic Tac Toe"_. Click the button to accept the invitation!`, components: [row]};
|
||||
interaction.reply(content).catch((err) => interaction.channel.send(content));
|
||||
|
||||
message.channel.send(`${other_discord}, <@${message.author.id}> has invited you to play _"Tic Tac Toe"_. To accept, please reply to this message with _!game accept_`);
|
||||
} else if (game == 'trivia' || command == 'trivia') {
|
||||
trivia.execute(message, args, Discord, client, bot);
|
||||
} else if (game == "minesweeper" || command == 'minesweeper') {
|
||||
if (game == "minesweeper" && command == 'minesweeper') {
|
||||
} else if (game == 'Tic Tac Toe' || commandName == 'Tic Tac Toe') {
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`gameaccept|${command.options[0].value}|${interaction.user.id}`)
|
||||
.setLabel('Accept Invite')
|
||||
.setStyle('SUCCESS')
|
||||
);
|
||||
|
||||
const content = {content: `${command.options[0].user}, ${interaction.user} has invited you to play _"Tic Tac Toe"_. Click the button to accept the invitation!`, components: [row]};
|
||||
interaction.reply(content).catch((err) => interaction.channel.send(content));
|
||||
} else if (game == 'trivia' || commandName == 'trivia') {
|
||||
trivia.execute(interaction, Discord, client, bot);
|
||||
} else if (game == "minesweeper" || commandName == 'minesweeper') {
|
||||
if (game == "minesweeper" && commandName == 'minesweeper') {
|
||||
return message.reply("You're already in a game!");
|
||||
}
|
||||
const threadname = `${message.author.username} has started a solo game of Minesweeper`;
|
||||
const thread = await message.channel.threads.create({
|
||||
const threadname = `${interaction.user.username} is playing Minesweeper`;
|
||||
const thread = await interaction.channel.threads.create({
|
||||
name: threadname,
|
||||
// type: 'GUILD_PRIVATE_THREAD',
|
||||
autoArchiveDuration: 60,
|
||||
reason: `N/A`,
|
||||
});
|
||||
mnswpr.handle(bot, null, thread, message, args);
|
||||
mnswpr.handle(bot, interaction, thread);
|
||||
}
|
||||
|
||||
//Catch statement (invalid command)
|
||||
else {
|
||||
message.reply(`'${bot.prefix}game ${command}' is not a command!`);
|
||||
interaction.reply(`'/game ${commandName}' is not a command!`);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
const { Constants } = require('discord.js');
|
||||
const { trivia_categories } = require('./trivia_categories.json');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: "trivia",
|
||||
description: 'Start a game of Trivia',
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: 'difficulty', description: 'The question difficulty OR "help"', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [{name: 'easy', value: 'easy'}, {name: 'medium', value: 'medium'}, {name: 'hard', value: 'hard'}]},
|
||||
{name: 'category', description: 'The trivia Category', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: false, choices: trivia_categories},
|
||||
{name: 'time', description: 'Set the round length (in seconds)', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: false},
|
||||
]},
|
||||
|
||||
{
|
||||
name: "battle",
|
||||
description: 'Start a game of Batte',
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: 'opponent', description: 'Who do you want to battle against?', type: Constants.ApplicationCommandOptionTypes.USER, required: true},
|
||||
]},
|
||||
|
||||
{
|
||||
name: "minesweeper",
|
||||
description: "Start a game of Minesweeper",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: 'difficulty', description: 'Set the diffficulty', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [{name: 'easy', value: 'easy'}, {name: 'medium', value: 'medium'}, {name: 'hard', value: 'hard'}]},
|
||||
// {name: 'opponent', description: 'Play a game against someone else', type: Constants.ApplicationCommandOptionTypes.USER, required: false}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: "tictactoe",
|
||||
description: 'Start a game of TicTacToe',
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: 'opponent', description: 'Who do you want to play against?', type: Constants.ApplicationCommandOptionTypes.USER, required: true},
|
||||
]},
|
||||
|
||||
{
|
||||
name: "quit",
|
||||
description: "Quit your current game",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: []
|
||||
},
|
||||
|
||||
{
|
||||
name: "status",
|
||||
description: "Check your current game status",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: []
|
||||
},
|
||||
|
||||
{
|
||||
name: "hpmp",
|
||||
description: "Check your current game status",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: []
|
||||
},
|
||||
]
|
||||
@@ -3,23 +3,24 @@ const { winGame, loseGame, equipItem } = require('./external_game_functions.js')
|
||||
const wait = require('node:timers/promises').setTimeout;
|
||||
const { STATE } = require('../db/econ.js')
|
||||
|
||||
function startGame(bot, channel, message, args) {
|
||||
function startGame(bot, channel, interaction) {
|
||||
const args = interaction.options.data;
|
||||
let componentlist = [];
|
||||
var diff;
|
||||
|
||||
if (args.length < 1 || args[0] == 'easy') {
|
||||
if (args.length < 1 || args[0].value == 'easy') {
|
||||
diff = 0;
|
||||
} else if (args[0] == 'medium') {
|
||||
} else if (args[0].value == 'medium') {
|
||||
diff = 0.1;
|
||||
} else if (args[0] == 'hard') {
|
||||
} else if (args[0].value == 'hard') {
|
||||
diff = 0.2;
|
||||
} else {
|
||||
diff = 0;
|
||||
}
|
||||
|
||||
let user = '';
|
||||
if (args.length < 2 || args[1] == 'solo') {
|
||||
user = message.author.id;
|
||||
if (args.length < 2) {
|
||||
user = interaction.user.id;
|
||||
}
|
||||
|
||||
for (let i = 0; i < 5; i ++) {
|
||||
@@ -45,6 +46,7 @@ function startGame(bot, channel, message, args) {
|
||||
componentlist.push(row);
|
||||
}
|
||||
|
||||
interaction.reply(`${interaction.user} has started a solo game of Minesweeper!`);
|
||||
channel.send({ content: `SCORE: \`0\`\nTILES LEFT: \`25\``, components: componentlist });
|
||||
}
|
||||
|
||||
@@ -90,7 +92,7 @@ async function changeBoard(bot, interaction, xp_collection) {
|
||||
const user = id[4];
|
||||
if (user && user != '') {
|
||||
if (interaction.user.id != user) {
|
||||
interaction.user.send(`Message from a Minesweeper game in <#${interaction.channel.id}>: ***It's not your turn!***`);
|
||||
interaction.user.send(`Message from a Minesweeper game in <#${interaction.channel.id}>: ***This is a solo game!***`);
|
||||
return; // interaction.reply({ content: "It's not your turn!", ephemeral: true }); //Can only reply once
|
||||
}
|
||||
}
|
||||
@@ -103,7 +105,7 @@ async function changeBoard(bot, interaction, xp_collection) {
|
||||
bot.mongoconnection.then((client) => { client.db(interaction.guildId).collection(interaction.user.id).updateOne({ game: {$exists: true} }, { $set: { game: null } }); });
|
||||
const channel = bot.channels.cache.get(interaction.message.channel.parentId);
|
||||
channel.send(`${interaction.user} found a bomb in Minesweeper!`);
|
||||
interaction.channel.send(`\`Thread closing\` <t:${Math.floor((new Date()).getTime()/1000) + 8}:R>`);
|
||||
interaction.channel.send(`\`Thread closing\` <t:${Math.floor((new Date()).getTime()/1000) + 10}:R>`);
|
||||
|
||||
await wait(7000);
|
||||
interaction.channel.delete();
|
||||
@@ -140,29 +142,34 @@ async function changeBoard(bot, interaction, xp_collection) {
|
||||
}
|
||||
|
||||
|
||||
function checkAndStartGame(bot, message, channel, args) {
|
||||
function checkAndStartGame(bot, interaction, channel) {
|
||||
bot.mongoconnection.then(client => {
|
||||
const db = client.db(message.guild.id);
|
||||
const dbo = db.collection(message.author.id);
|
||||
const db = client.db(interaction.guildId);
|
||||
const dbo = db.collection(interaction.user.id);
|
||||
dbo.findOne({game: {$exists: true}}).then((doc) => {
|
||||
try {
|
||||
if (doc.game != null) { return message.reply("You're already in a game!"); }
|
||||
if (doc.game != null) {
|
||||
console.log(doc);
|
||||
return interaction.reply("You're already in a game!").catch((err) => {
|
||||
interaction.channel.send("You're already in a game!");
|
||||
});
|
||||
}
|
||||
|
||||
dbo.updateOne({ "game": {$exists: true} }, { $set: { game: "minesweeper", state: STATE.FIGHTING }});
|
||||
startGame(bot, channel, message, args);
|
||||
startGame(bot, channel, interaction);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint.js');
|
||||
addComplaintButton(bot, message);
|
||||
addComplaintButton(bot, interaction.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function handle(bot, interaction, channel = null, message = null, args = null, xp_collection = null) {
|
||||
if (channel != null && args != null) {
|
||||
checkAndStartGame(bot, message, channel, args);
|
||||
function handle(bot, interaction, channel = null, isStart = true, xp_collection = null) {
|
||||
if (isStart) {
|
||||
checkAndStartGame(bot, interaction, channel);
|
||||
} else {
|
||||
//Maybe add player checking later?
|
||||
changeBoard(bot, interaction, xp_collection);
|
||||
|
||||
@@ -124,7 +124,6 @@ async function handle(client, db, dbo, other, bot, thread, command, doc, interac
|
||||
let board = ["", "", "", "", "", "", "", "", ""];
|
||||
postActionBar(thread, dbo, board, false,true);
|
||||
} else {
|
||||
|
||||
//Change the board
|
||||
let square = Number(interaction.customId.split('|')[1]);
|
||||
let symbol = doc.symbols[doc.turn];
|
||||
@@ -143,6 +142,8 @@ async function handle(client, db, dbo, other, bot, thread, command, doc, interac
|
||||
changeTurn(client, bot, interaction);
|
||||
} else {
|
||||
postActionBar(interaction, dbo, board, won);
|
||||
|
||||
//Maybe add a "close board" button instead of this
|
||||
await wait(7000);
|
||||
winGame(client, bot, db, dbo, xp_collection, interaction.message);
|
||||
}
|
||||
|
||||
+32
-21
@@ -3,11 +3,12 @@ const fetch = require('node-fetch');
|
||||
const categoriesJSON = require('./trivia_categories.json').trivia_categories;
|
||||
const { decode } = require('html-entities');
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const { Interaction } = require('discord.js');
|
||||
|
||||
|
||||
const categories = new Map();
|
||||
for (i in categoriesJSON) {
|
||||
categories.set(categoriesJSON[i].name, categoriesJSON[i].id);
|
||||
categories.set(categoriesJSON[i].name, categoriesJSON[i].value);
|
||||
}
|
||||
// const { jsonToMapRecursive, mapToTableRecursive } = require('../utils/jsonFormatters.js');
|
||||
|
||||
@@ -41,11 +42,11 @@ function changeDB(bot, message, m) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {*} message
|
||||
* @param {Interaction} interaction
|
||||
* @param {Map<string, object>} m
|
||||
* @param {int} time
|
||||
*/
|
||||
function startTrivia(message, m, time, bot) {
|
||||
function startTrivia(interaction, m, time, bot) {
|
||||
var iter = m.values().next();
|
||||
var obj = iter.value;
|
||||
|
||||
@@ -63,8 +64,10 @@ function startTrivia(message, m, time, bot) {
|
||||
return (response.content.toLowerCase() == answer.toLowerCase());
|
||||
};
|
||||
|
||||
message.reply({ content: `${question}\n(Type your answers below!)`, fetchReply: true })
|
||||
.then(() => {
|
||||
interaction.channel.send({ content: `${question}\n(Type your answers below!)`, fetchReply: true })
|
||||
.then((message) => {
|
||||
interaction.reply({content: `Trivia started by ${interaction.user}`});
|
||||
|
||||
const timeList = ['🔟', '9️⃣', '8️⃣', '7️⃣', '6️⃣', '5️⃣', '4️⃣', '3️⃣', '2️⃣', '1️⃣', '0️⃣' ];
|
||||
var i = 0;
|
||||
const intId = setInterval(() => { if (i < timeList.length) { message.react(timeList[i]); i++ } }, Math.round(time/11));
|
||||
@@ -72,9 +75,9 @@ function startTrivia(message, m, time, bot) {
|
||||
message.channel.awaitMessages({ filter, max: 10, time: time }) // , errors: ['time']
|
||||
.then((collected) => {
|
||||
if (collected.size > 0) {
|
||||
message.reply(`${collected.first().author} got the correct answer (${answer})!`);
|
||||
message.reply(`${collected.first().author} got the correct answer (||${answer}||) first!`);
|
||||
} else {
|
||||
message.reply('Tsk Tsk, looks like nobody got the answer this time.');
|
||||
message.reply(`Tsk Tsk, looks like nobody got the answer (||${answer}||) this time.`);
|
||||
}
|
||||
|
||||
// changeDB(bot, message, null);
|
||||
@@ -82,7 +85,7 @@ function startTrivia(message, m, time, bot) {
|
||||
})
|
||||
.catch((collected) => {
|
||||
console.log(collected);
|
||||
message.reply('Tsk Tsk, looks like nobody got the answer this time.');
|
||||
message.reply(`Tsk Tsk, looks like nobody got the answer (||${answer}||) this time.`);
|
||||
// changeDB(bot, message, null);
|
||||
clearInterval(intId);
|
||||
});
|
||||
@@ -94,25 +97,31 @@ function startTrivia(message, m, time, bot) {
|
||||
|
||||
module.exports = {
|
||||
name: 'trivia',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
const difficult = ['easy', 'medium', 'hard'];
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
const opts = interaction.options.data[0].options;
|
||||
const args = [];
|
||||
args[0] = opts.filter((o) => { return (o.name == 'difficulty'); })[0];
|
||||
args[1] = opts.filter((o) => { return (o.name == 'category'); })[0];
|
||||
args[2] = opts.filter((o) => { return (o.name == 'time'); })[0];
|
||||
|
||||
const difficult = ['hard', 'medium', 'easy'];
|
||||
let inputs = ['easy', ''];
|
||||
|
||||
if (args[0] && difficult.includes(args[0].toLowerCase())) {
|
||||
inputs[0] = args[0].toLowerCase();
|
||||
} else if (args[0] == 'help') {
|
||||
let temp = `Use ${bot.prefix}trivia [difficulty (easy, medium, hard)] [topic] [time]\n`;
|
||||
if (args[0] && difficult.includes(args[0].value.toLowerCase())) {
|
||||
inputs[0] = args[0].value.toLowerCase();
|
||||
} else if (args[0].value == 'help') {
|
||||
let temp = `Use /trivia [difficulty (easy, medium, hard)] [category] [time]\n`;
|
||||
temp += '**__Trivia Categories__**\n';
|
||||
categories.forEach((val, key) => {
|
||||
temp += `_${key}_\n`;
|
||||
})
|
||||
});
|
||||
temp += '_Please copy and paste the FULL NAME if you want to use a category';
|
||||
|
||||
return message.reply(temp);
|
||||
return interaction.reply(temp);
|
||||
}
|
||||
|
||||
if (args[1] && Array.from(categories.keys()).includes(args[1])) {
|
||||
inputs[1] = categories.get(args[1]);
|
||||
if (args[1] && Array.from(categories.keys()).includes(args[1].value)) {
|
||||
inputs[1] = categories.get(args[1].value);
|
||||
}
|
||||
|
||||
// Get all categories mapped to their ids
|
||||
@@ -142,9 +151,11 @@ module.exports = {
|
||||
// console.log(decode(query));
|
||||
query = decode(query);
|
||||
|
||||
if (bot.inDebugMode) {
|
||||
//Get the answer (may have "" in it)
|
||||
const question = query.substring(query.indexOf('question":') + 10, query.indexOf('","correct_answer'));
|
||||
// const question = query.substring(query.indexOf('question":') + 10, query.indexOf('","correct_answer'));
|
||||
// console.log(`Q: ${question}\n\nActual: ${query}\n---------------------------------------`);
|
||||
}
|
||||
|
||||
let q = query.split('","');
|
||||
// queries[ind] = q;
|
||||
@@ -156,11 +167,11 @@ module.exports = {
|
||||
i ++;
|
||||
});
|
||||
|
||||
const time = args[2] || (difficult.indexOf(inputs[0]) + 1) * 10000;
|
||||
const time = (args[2]) ? args[2].value : (difficult.indexOf(inputs[0]) + 1) * 10000;
|
||||
|
||||
// console.log(m, time);
|
||||
// changeDB(bot, message, m);
|
||||
startTrivia(message, m, time, bot);
|
||||
startTrivia(interaction, m, time, bot);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"trivia_categories": [
|
||||
{ "id": 9, "name": "General Knowledge" },
|
||||
{ "id": 10, "name": "Entertainment: Books" },
|
||||
{ "id": 11, "name": "Entertainment: Film" },
|
||||
{ "id": 12, "name": "Entertainment: Music" },
|
||||
{ "id": 13, "name": "Entertainment: Musicals & Theatres" },
|
||||
{ "id": 14, "name": "Entertainment: Television" },
|
||||
{ "id": 15, "name": "Entertainment: Video Games" },
|
||||
{ "id": 16, "name": "Entertainment: Board Games" },
|
||||
{ "id": 17, "name": "Science & Nature" },
|
||||
{ "id": 18, "name": "Science: Computers" },
|
||||
{ "id": 19, "name": "Science: Mathematics" },
|
||||
{ "id": 20, "name": "Mythology" },
|
||||
{ "id": 21, "name": "Sports" },
|
||||
{ "id": 22, "name": "Geography" },
|
||||
{ "id": 23, "name": "History" },
|
||||
{ "id": 24, "name": "Politics" },
|
||||
{ "id": 25, "name": "Art" },
|
||||
{ "id": 26, "name": "Celebrities" },
|
||||
{ "id": 27, "name": "Animals" },
|
||||
{ "id": 28, "name": "Vehicles" },
|
||||
{ "id": 29, "name": "Entertainment: Comics" },
|
||||
{ "id": 30, "name": "Science: Gadgets" },
|
||||
{ "id": 31, "name": "Entertainment: Japanese Anime & Manga" },
|
||||
{ "id": 32, "name": "Entertainment: Cartoon & Animations" }
|
||||
{ "value": 9, "name": "General Knowledge" },
|
||||
{ "value": 10, "name": "Entertainment: Books" },
|
||||
{ "value": 11, "name": "Entertainment: Film" },
|
||||
{ "value": 12, "name": "Entertainment: Music" },
|
||||
{ "value": 13, "name": "Entertainment: Musicals & Theatres" },
|
||||
{ "value": 14, "name": "Entertainment: Television" },
|
||||
{ "value": 15, "name": "Entertainment: Video Games" },
|
||||
{ "value": 16, "name": "Entertainment: Board Games" },
|
||||
{ "value": 17, "name": "Science & Nature" },
|
||||
{ "value": 18, "name": "Science: Computers" },
|
||||
{ "value": 19, "name": "Science: Mathematics" },
|
||||
{ "value": 20, "name": "Mythology" },
|
||||
{ "value": 21, "name": "Sports" },
|
||||
{ "value": 22, "name": "Geography" },
|
||||
{ "value": 23, "name": "History" },
|
||||
{ "value": 24, "name": "Politics" },
|
||||
{ "value": 25, "name": "Art" },
|
||||
{ "value": 26, "name": "Celebrities" },
|
||||
{ "value": 27, "name": "Animals" },
|
||||
{ "value": 28, "name": "Vehicles" },
|
||||
{ "value": 29, "name": "Entertainment: Comics" },
|
||||
{ "value": 30, "name": "Science: Gadgets" },
|
||||
{ "value": 31, "name": "Entertainment: Japanese Anime & Manga" },
|
||||
{ "value": 32, "name": "Entertainment: Cartoon & Animations" }
|
||||
]
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const { createSubscriptionManual } = require('./premium/stripe.js');
|
||||
const { pause_start_stop, playNext, showQueue } = require('./misc/playAudio.js');
|
||||
const { pause_start_stop, playNext, showQueue } = require('./audio/audioMain.js');
|
||||
const { resolveComplaint } = require('./dev only/submitcomplaint.js');
|
||||
const { RSSInteractionHandler } = require('../side projects/RSSHandlers/rssFeed.js');
|
||||
const reminders = require('./premium/reminders.js');
|
||||
const tuto = require('../commands/Selmer Specific/intro');
|
||||
const reactionrole = require('./admin/reactionrole.js');
|
||||
const tuto = require('./Selmer Specific/tuto');
|
||||
const mswpr = require('./games/minesweeper.js');
|
||||
const giveaway = require('./misc/giveaway.js');
|
||||
const setup = require('./admin/easySetup.js');
|
||||
// const { RSSInteractionHandler } = require('./premium/rssFeed.js');
|
||||
const { Interaction } = require('discord.js')
|
||||
const { Interaction, Client } = require('discord.js');
|
||||
const Discord = require('discord.js');
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -72,7 +76,7 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE
|
||||
playNext(interaction, bot);
|
||||
} else if (interaction.customId.indexOf('audioQueue|') != -1) {
|
||||
const page = Number(interaction.customId.split('|')[1]);
|
||||
showQueue(bot, interaction.message, interaction, page);
|
||||
showQueue(bot, true, interaction, page);
|
||||
} else {
|
||||
pause_start_stop(interaction, bot);
|
||||
}
|
||||
@@ -87,10 +91,16 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE
|
||||
const page = Number(interaction.customId.split('|')[1]);
|
||||
tuto.postEmbd(bot, interaction, page, true);
|
||||
} else if (interaction.customId.indexOf("mswpr|") != -1) {
|
||||
mswpr.handle(bot, interaction, interaction.channel, interaction.message, null, xp_collection);
|
||||
mswpr.handle(bot, interaction, interaction.channel, false, xp_collection);
|
||||
} else if (interaction.customId.indexOf("sbtutorial") != -1) {
|
||||
interaction.deferUpdate();
|
||||
tuto.execute(interaction.message, null, null, null, bot);
|
||||
tuto.execute(interaction, null, null, bot);
|
||||
} else if (interaction.customId.indexOf("gameaccept") != -1) {
|
||||
bot.commands.get('game').execute(bot, interaction, {name: 'accept'}, Discord, mongouri, items, xp_collection);
|
||||
} else if (interaction.customId.indexOf("setupBtn") != -1) {
|
||||
setup.handle(bot, interaction);
|
||||
} else if (interaction.customId.indexOf('addRole') != -1) {
|
||||
reactionrole.handleBtn(interaction);
|
||||
} //Button else ifs here
|
||||
});
|
||||
}
|
||||
@@ -147,19 +157,35 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE
|
||||
|
||||
//Handle the interaction here
|
||||
}
|
||||
} /*else if (interaction.customId.indexOf('RSS') != -1) {
|
||||
} else if (interaction.customId.indexOf('RSS') != -1) {
|
||||
if (bot.inDebugMode) {
|
||||
RSSInteractionHandler(bot, interaction);
|
||||
}*/ //menu else ifs here
|
||||
}
|
||||
} //menu else ifs here
|
||||
}
|
||||
|
||||
//Forms
|
||||
else if (interaction.isModalSubmit()) {
|
||||
if (interaction.customId.indexOf('newEventModal') != -1) {
|
||||
reminders.modalHandle(bot, interaction);
|
||||
} else if (interaction.customId.indexOf('giveawayModal') != -1) {
|
||||
giveaway.processForm(interaction, bot);
|
||||
} else if (interaction.customId.indexOf('reactionModal') != -1) {
|
||||
reactionrole.processForm(interaction, bot);
|
||||
}
|
||||
} //other selection types here
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Client} bot
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
async function handleContext(bot, interaction) {
|
||||
const { targetId, commandName, user } = interaction;
|
||||
console.log(interaction);
|
||||
}
|
||||
|
||||
module.exports = { handle_interaction }
|
||||
module.exports = { handle_interaction, handleContext }
|
||||
|
||||
//values: [ 'price_1LI5pzFtuywsbrwdlY1gWMkV' ]
|
||||
//values: [ 'price_1LIpROFtuywsbrwdmxOb8Baj' ]
|
||||
+7
-10
@@ -1,4 +1,3 @@
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const Discord = require('discord.js');
|
||||
const SEVCODES = {
|
||||
none: 0,
|
||||
@@ -9,18 +8,16 @@ const SEVCODES = {
|
||||
const col_list = {0: '0ed300', 1: 'f6ff00', 2: 'ffa100', 3: 'FF0000'}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} bot
|
||||
* @param {*} message the message the mod sent (AKA a DISCORD MESSAGE OBJECT)
|
||||
* @param {Discord.Client} bot
|
||||
* @param {Discord.Interaction} interaction the message the mod sent (AKA a DISCORD MESSAGE OBJECT)
|
||||
*/
|
||||
function log(bot, message, command, mentioned, reason, severity) {
|
||||
function log(bot, interaction, command, mentioned, reason, severity) {
|
||||
bot.mongoconnection.then(client => {
|
||||
// if (err) { return console.log(err); }
|
||||
|
||||
|
||||
client.db(message.guild.id).collection('SETUP').findOne({_id: 'LOG'}).then((doc) => {
|
||||
if (!doc) { return message.channel.send("Server logs not set up yet!"); }
|
||||
const channel = message.guild.channels.cache.get(doc.logchannel);
|
||||
client.db(interaction.guildId).collection('SETUP').findOne({_id: 'LOG'}).then((doc) => {
|
||||
if (!doc) { return interaction.reply("Server logs not set up yet!"); }
|
||||
const channel = interaction.guild.channels.cache.get(doc.logchannel);
|
||||
|
||||
if (!channel) { return console.log("There is no specified log channel!"); }
|
||||
//Check severity threshold
|
||||
@@ -35,7 +32,7 @@ function log(bot, message, command, mentioned, reason, severity) {
|
||||
.setColor(col_list[severity])
|
||||
.setTitle(`User ${mentioned.username}#${mentioned.discriminator} has been ${action}`)
|
||||
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
||||
.setDescription(`Reason: ${reason}\n Responsible Mod: ${message.author.username}#${message.author.discriminator}`)
|
||||
.setDescription(`Reason: ${reason}\n Responsible Mod: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user})`)
|
||||
.setThumbnail(mentioned.displayAvatarURL())
|
||||
.setTimestamp();
|
||||
|
||||
|
||||
+13
-11
@@ -1,4 +1,4 @@
|
||||
const { Formatters, MessageEmbed } = require('discord.js');
|
||||
const { Formatters, MessageEmbed, Constants } = require('discord.js');
|
||||
const CoinGecko = require('coingecko-api');
|
||||
const CoinGeckoClient = new CoinGecko();
|
||||
|
||||
@@ -18,10 +18,11 @@ getAllCoins();
|
||||
module.exports = {
|
||||
name: 'crypto',
|
||||
description: 'Get the prices for most cryptocurrencies!',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
if (args.length < 1 || args[0] == 'help') {
|
||||
return message.reply("Please specify at least one cryptocurrency (_ex: !crypto BTC_) or list all currencies (_!crypto list_)");
|
||||
} else if (args[0] == 'list') {
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
const args = interaction.options.data;
|
||||
if (args.length < 1 || args[0].value == 'help') {
|
||||
return interaction.reply("Please specify at least one cryptocurrency (_ex: !crypto BTC_) or list all currencies (_!crypto list_)");
|
||||
} else if (args[0].value == 'list') {
|
||||
try {
|
||||
return new Promise((resolve, reject) => {
|
||||
let temp = "```Name --> Symbol\n\n";
|
||||
@@ -32,11 +33,11 @@ module.exports = {
|
||||
|
||||
resolve(temp);
|
||||
}).then((temp) => {
|
||||
message.reply(temp);
|
||||
interaction.reply(temp);
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return message.reply("Uh Oh! There's been an error!");
|
||||
return interaction.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ module.exports = {
|
||||
|
||||
var datacc = data.data.tickers.filter(t => t.target == 'USD');
|
||||
|
||||
const temp = datacc.filter(t => t.base == args[0]);
|
||||
const temp = datacc.filter(t => t.base == args[0].value);
|
||||
const res = temp.length == 0 ? [] : temp[0];
|
||||
|
||||
//price: res.last, symbol: base, trust score: trust_score
|
||||
@@ -67,10 +68,11 @@ module.exports = {
|
||||
.setTimestamp()
|
||||
.setFooter({ text: 'Selmer Bot uses CoinGecko for cryptocurrency information'});
|
||||
|
||||
message.reply({ embeds: [embd] });
|
||||
interaction.reply({ embeds: [embd] });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return message.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
return interaction.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
},
|
||||
options: [{name: 'query', description: 'Name or List', type: Constants.ApplicationCommandOptionTypes.STRING, required: true}]
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
const { Interaction, MessageActionRow, MessageButton, MessageEmbed, Modal, TextInputComponent } = require('discord.js');
|
||||
const { checkRole } = require('../admin/verify.js');
|
||||
|
||||
|
||||
async function postForm(interaction) {
|
||||
// Create the modal
|
||||
const modal = new Modal();
|
||||
|
||||
modal.setTitle('Creating a new giveaway')
|
||||
.setCustomId('giveawayModal');
|
||||
|
||||
// Add components to modal
|
||||
// Create the text input components
|
||||
// The label is the prompt the user sees for this input
|
||||
// Short means only a single line of text
|
||||
// Paragraph means multiple lines of text
|
||||
|
||||
const durationInp = new TextInputComponent()
|
||||
.setCustomId('duration')
|
||||
.setLabel("How long should the givaway last?")
|
||||
.setPlaceholder('10S or 10M or 10H or 10D between 1 minute and 30 days')
|
||||
.setStyle('SHORT');
|
||||
|
||||
const titleInp = new TextInputComponent()
|
||||
.setCustomId('title')
|
||||
.setLabel("What should the giveaway be called?")
|
||||
.setStyle('SHORT');
|
||||
|
||||
const descriptionInp = new TextInputComponent()
|
||||
.setCustomId('description')
|
||||
.setLabel("Describe the giveaway")
|
||||
.setPlaceholder('A fun giveaway!')
|
||||
.setStyle('PARAGRAPH');
|
||||
|
||||
const prizeInp = new TextInputComponent()
|
||||
.setCustomId('prize')
|
||||
.setLabel("What does the winner....win?")
|
||||
.setPlaceholder('Discord Nitro')
|
||||
.setStyle('SHORT');
|
||||
|
||||
const winnersInp = new TextInputComponent()
|
||||
.setCustomId('winners')
|
||||
.setLabel("Number of winners")
|
||||
.setPlaceholder('Between 1 and 99 winners')
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2)
|
||||
.setStyle('SHORT');
|
||||
|
||||
// An action row only holds one text input,
|
||||
// so you need one action row per text input.
|
||||
const title = new MessageActionRow().addComponents(titleInp);
|
||||
const desc = new MessageActionRow().addComponents(descriptionInp);
|
||||
const dur = new MessageActionRow().addComponents(durationInp);
|
||||
const prize = new MessageActionRow().addComponents(prizeInp);
|
||||
const winners = new MessageActionRow().addComponents(winnersInp);
|
||||
|
||||
// Add inputs to the modal
|
||||
modal.addComponents(title, desc, dur, prize, winners);
|
||||
|
||||
// Show the modal to the user
|
||||
interaction.showModal(modal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
function processForm(interaction, bot) {
|
||||
const title = interaction.fields.getTextInputValue('title');
|
||||
const desc = interaction.fields.getTextInputValue('description');
|
||||
const dur = interaction.fields.getTextInputValue('duration');
|
||||
const prize = interaction.fields.getTextInputValue('prize');
|
||||
const winners = interaction.fields.getTextInputValue('winners');
|
||||
|
||||
postGiveawayMessage(bot, interaction, title, desc, dur, prize, winners);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Interaction} interaction
|
||||
*/
|
||||
function postGiveawayMessage(bot, interaction, title, desc, dur, prize, winners) {
|
||||
|
||||
const author = {
|
||||
name: "Selmer Bot",
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
};
|
||||
|
||||
var timeAdjuster = 1;
|
||||
var time;
|
||||
|
||||
if (dur.indexOf('M') != -1) {
|
||||
timeAdjuster = 60;
|
||||
time = dur.replace("M", "");
|
||||
} else if (dur.indexOf('H') != -1) {
|
||||
timeAdjuster = 3600;
|
||||
time = dur.replace("H", "");
|
||||
} else if (dur.indexOf('D') != -1) {
|
||||
timeAdjuster = 86400;
|
||||
time = dur.replace("D", "");
|
||||
}
|
||||
|
||||
if (!Number.isInteger(Number(time))) {
|
||||
return interaction.reply("Please enter a valid time in the following format: 10[S, M, H, D]");
|
||||
} else if (!Number.isInteger(Number(winners))) {
|
||||
return interaction.reply("Please enter a valid NUMBER of winners");
|
||||
}
|
||||
|
||||
const embd = new MessageEmbed()
|
||||
.setTitle(title)
|
||||
.setAuthor(author)
|
||||
.setDescription(desc)
|
||||
.addFields([
|
||||
{name: 'Prize', value: prize},
|
||||
{name: 'Ends in', value: `<t:${Math.floor((new Date()).getTime()/1000) + (Number(time) * timeAdjuster)}:R>`},
|
||||
{name: 'Host', value: `${interaction.user}`},
|
||||
{name: 'Number of Contestants', value: '0'},
|
||||
{name: 'Number of Winners', value: winners}
|
||||
]);
|
||||
|
||||
const msgPromise = interaction.channel.send({ embeds: [embd] });
|
||||
msgPromise.then((msg) => {
|
||||
msg.react('🎉');
|
||||
|
||||
var nonbots = [];
|
||||
const filter = (reaction, user) => {
|
||||
if (!user.bot) {
|
||||
nonbots.push(user);
|
||||
}
|
||||
|
||||
return (reaction.emoji.name === '🎉');
|
||||
};
|
||||
|
||||
const collector = msg.createReactionCollector({ filter, time: 5000 });
|
||||
|
||||
// collector.on('collect', (reaction, user) => {
|
||||
// console.log(`Collected ${reaction.emoji.name} from ${user.tag}`);
|
||||
// });
|
||||
|
||||
collector.on('end', collected => {
|
||||
const finalists = [];
|
||||
if (winners >= nonbots.length) {
|
||||
for (let i = 0; i < nonbots.length; i++) {
|
||||
finalists.push(`<@${nonbots[i].id}>`);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < winners; i++) {
|
||||
const ind = Math.floor(nonbots.length * Math.random());
|
||||
finalists.push(`<@${nonbots[ind].id}>`);
|
||||
delete nonbots[ind];
|
||||
nonbots = nonbots.filter((val) => { return (val != null); });
|
||||
}
|
||||
}
|
||||
|
||||
let embd = msg.embeds[0];
|
||||
|
||||
if (winners > 1) {
|
||||
msg.reply(`And the winners are:\n${finalists.join("\n")}`);
|
||||
embd.fields.push({name: 'winners:', value: `${finalists.join("\n")}`, inline: true});
|
||||
} else {
|
||||
msg.reply(`And the winner is:\n${finalists.join("\n")}`);
|
||||
embd.fields.push({name: 'winner:', value: `${finalists.join("\n")}`, inline: true});
|
||||
}
|
||||
|
||||
msg.edit({ embeds: [embd] });
|
||||
});
|
||||
|
||||
interaction.reply({ content: 'Giveaway posted!', ephemeral: true });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'giveaway',
|
||||
description: 'Create a giveaway',
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
|
||||
postForm(interaction);
|
||||
},
|
||||
processForm,
|
||||
options: []
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
module.exports = {
|
||||
name: "test",
|
||||
description: "HI SELMER",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
message.channel.send("HI SELMER!!!");
|
||||
}
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
interaction.reply("HI SELMER!!!");
|
||||
},
|
||||
options: []
|
||||
}
|
||||
+27
-17
@@ -1,28 +1,35 @@
|
||||
const { modHelp } = require('../admin/moderation.js');
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
//CHANGE THIS TO FORMS?
|
||||
module.exports ={
|
||||
name: "help",
|
||||
description: "Gets help for all of Selmer Bot's commands",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
|
||||
const groups = new Map([['SBspec', ['arrow', 'extracredit', 'profile', 'quotes', 'code']], ['adminCommands', [ 'setup', 'lock', 'unlock', 'serverlock' ]]]);
|
||||
|
||||
if (args[0] == 'econ') {
|
||||
var spec = "";
|
||||
if (interaction.options.data[0]) {
|
||||
spec = interaction.options.data[0].value;
|
||||
}
|
||||
|
||||
if (spec == 'econ') {
|
||||
let temp = "***Selmer Bot Commands (Econ):***\n";
|
||||
temp += bot.commands.get('econ').econHelp();
|
||||
temp += `\n\n(remember to use _'${bot.prefix}'_ before the command!)`;
|
||||
return message.channel.send(temp);
|
||||
temp += `\n\n(remember to use \`/\` before the command!)`;
|
||||
return interaction.reply({ content: temp, ephemeral: true });
|
||||
|
||||
}
|
||||
else if (args[0] == 'game') {
|
||||
else if (spec == 'game') {
|
||||
let temp = "***Selmer Bot Commands (Games):***\n";
|
||||
temp += bot.commands.get('game').allGames.join(", ");
|
||||
temp += `\n\n(remember to use _'${bot.prefix}game'_ before the command!)`;
|
||||
return message.channel.send(temp);
|
||||
// temp += `\n\n_Note: due to how complicated this feature is, it will not be migrated to slash commands for now_`;
|
||||
temp += `\n\n(remember to use \'/\' before the command!)`;
|
||||
return interaction.reply({ content: temp, ephemeral: true });
|
||||
|
||||
}
|
||||
else if (args[0] == 'admin') {
|
||||
else if (spec == 'admin') {
|
||||
let temp = `__**Selmer Bot Admin Commands**__\n`
|
||||
Array.from(groups.get('adminCommands')).forEach(commName => {
|
||||
let comm = bot.commands.get(commName);
|
||||
@@ -33,10 +40,10 @@ module.exports ={
|
||||
temp += modHelp();
|
||||
|
||||
//Uses a different format, only the server owner can use it
|
||||
temp += '\n_setup_ - ***SERVER OWNER ONLY*** - use _!setup help_\n';
|
||||
temp += `\n\n(remember to use _'${bot.prefix}'_ before the command!)`;
|
||||
temp += '\n_setup_ - ***SERVER OWNER ONLY*** - use \`setup help\`\n';
|
||||
temp += `\n\n(remember to use \`/\` before the command!)`;
|
||||
|
||||
return message.channel.send(temp);
|
||||
return interaction.reply({ content: temp, ephemeral: true });
|
||||
}
|
||||
|
||||
let temp = "***Selmer Bot Commands:***\n";
|
||||
@@ -49,10 +56,10 @@ module.exports ={
|
||||
bot.commands.forEach((comm) => {
|
||||
if (comm.name != 'verify') {
|
||||
if (comm.name == 'econ') {
|
||||
temp += `**econ** - use _!help econ_\n`;
|
||||
temp += `**econ** - use \`/help econ\`\n`;
|
||||
}
|
||||
else if (comm.name == 'game') {
|
||||
temp += `**games** - use _!help game_\n`;
|
||||
temp += `**games** - use \`/help game\`\n`;
|
||||
}
|
||||
else {
|
||||
if (comm.name && comm.description && !noPostList.includes(comm.name)) {
|
||||
@@ -62,17 +69,20 @@ module.exports ={
|
||||
}
|
||||
});
|
||||
|
||||
temp += '**admin/moderation commands** - use !help admin\n';
|
||||
temp += '**admin/moderation commands** - use `/help admin`\n';
|
||||
|
||||
//Selmer Specific
|
||||
temp += '\n__**Selmer\'s \\*Special\\* Commands**__\n'
|
||||
sList.forEach((commName) => {
|
||||
const comm = bot.commands.get(commName);
|
||||
if (comm && comm.name && comm.description) {
|
||||
temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`;
|
||||
}
|
||||
})
|
||||
|
||||
temp += `\n_(remember to use '${bot.prefix}' before the command!)_`;
|
||||
temp += `\n_(remember to use \`/\` before the command!)_`;
|
||||
|
||||
message.channel.send(temp);
|
||||
}
|
||||
interaction.reply({ content: temp, ephemeral: true });
|
||||
},
|
||||
options: [{name: 'command', description: 'econ, game, or admin', type: Constants.ApplicationCommandOptionTypes.STRING, required: false, choices: [ { name: 'econ', value: 'econ' }, { name: 'game', value: 'game' }, {name: 'admin', value: 'admin'} ]}]
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
module.exports ={
|
||||
name: 'kareoke',
|
||||
description: 'Sing your least-favorite song with your favorite person, me!',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const arg = interaction.options.data[0].value;
|
||||
if (arg == "help") { return interaction.reply({content: "Please pick out a song at https://www.karaoke-lyrics.net/\nThe command should look like\n/kareoke [link_here]"}); }
|
||||
|
||||
const axios = require('axios');
|
||||
const cheerio = require('cheerio')
|
||||
const url = args[0];
|
||||
if (args[0] == undefined) {
|
||||
message.channel.send("Please pick out a song at https://www.karaoke-lyrics.net/\nThe command should look like\n/kareoke [link_here]");
|
||||
} else {
|
||||
const url = interaction.options.data[0].value;
|
||||
|
||||
axios(url)
|
||||
.then(response => {
|
||||
const html = response.data;
|
||||
@@ -18,9 +21,12 @@ module.exports ={
|
||||
message.channel.send(breakbar + "\n" + lyrics + "\n" + breakbar);
|
||||
//console.log(lyrics);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
interaction.reply("Please provide a valid url from https://www.karaoke-lyrics.net/");
|
||||
});
|
||||
},
|
||||
options: [{name: 'url', description: 'the url of the song or "help"', type: Constants.ApplicationCommandOptionTypes.STRING, required: true}]
|
||||
}
|
||||
|
||||
//TEST: https://www.karaoketexty.cz/texty-pisni/zoegirl/plain-170199
|
||||
@@ -1,15 +1,15 @@
|
||||
module.exports = {
|
||||
name: "links",
|
||||
description: "A helpful list of links to all of Selmer's wonderful websites",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor('#002eff')
|
||||
.setTitle("Selmer's Links")
|
||||
.addFields(
|
||||
{name: 'HyperGrader', value: "https://rpi.logicamodernapproach.com/"},
|
||||
{name: 'Personal Website', value: "http://www.logicamodernapproach.com/rpi/intlogs22.bringsjord/#sec-3"}
|
||||
{name: 'Personal Website', value: "http://www.logicamodernapproach.com/"}
|
||||
);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
}
|
||||
interaction.reply({ embeds: [newEmbed] });
|
||||
}, options: []
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
const memes = require("random-memes");
|
||||
const { randomHexColor } = require('../admin/colorgen.js');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'meme',
|
||||
description: 'Selmer Bot will post a random meme from reddit',
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
memes.random().then(meme => {
|
||||
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor(randomHexColor())
|
||||
.setTitle(meme.caption)
|
||||
// .setURL(meme.image)
|
||||
.setDescription(`category: ${meme.category}`)
|
||||
.setImage(meme.image);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
}).catch(async err => {
|
||||
console.log(err);
|
||||
//Try a different way
|
||||
const fetch = require('node-fetch');
|
||||
const response = await fetch('https://some-random-api.ml/meme');
|
||||
const data = await response.json().catch(err => {
|
||||
console.log(err);
|
||||
return message.reply("_Uh oh, something's gone wrong!_");
|
||||
});
|
||||
|
||||
const newEmbed = new Discord.MessageEmbed()
|
||||
.setColor(randomHexColor())
|
||||
.setTitle(data.caption)
|
||||
// .setURL(data.image)
|
||||
.setDescription(`category: ${data.category}`)
|
||||
.setImage(data.image);
|
||||
|
||||
message.channel.send({ embeds: [newEmbed] });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// https://ponly.com/200-pick-up-lines/
|
||||
const { Constants } = require('discord.js');
|
||||
|
||||
const cheesy = [
|
||||
'If I said you had a good body would you hold it against me?',
|
||||
@@ -280,32 +281,33 @@ const anime = [
|
||||
module.exports = {
|
||||
name: 'pickupline',
|
||||
description: 'Get a pickup line from our selection of 200 lines!',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
const nameList = new Map([['cheesy', cheesy], ['funny', funny], ['smooth', smooth], ['best', best], ['anime', anime]]);
|
||||
const type = interaction.options.data[0].value;
|
||||
|
||||
if (args[0] == 'sources') {
|
||||
if (type == 'sources') {
|
||||
message.reply("The normal lines are from https://ponly.com/200-pick-up-lines/\nThe anime lines are from https://thoughtcatalog.com/january-nelson/2021/06/anime-pick-up-lines/")
|
||||
.then((msg) => { msg.suppressEmbeds(true); })
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length < 1 || (!nameList.get(args[0]) && args[0] != 'random')) { return message.reply("Please use the following format !pickupline <'cheesy', 'funny', 'smooth', 'best', 'anime', 'random', 'sources'>"); }
|
||||
|
||||
var key;
|
||||
if (args[0] == 'random') {
|
||||
if (type == 'random') {
|
||||
let keyInd = Math.floor(Math.random() * nameList.size);
|
||||
key = Array.from(nameList.keys())[keyInd];
|
||||
} else {
|
||||
key = args[0];
|
||||
key = type;
|
||||
}
|
||||
|
||||
|
||||
const arr = nameList.get(key);
|
||||
keyInd = Math.floor(Math.random() * arr.length);
|
||||
try {
|
||||
message.reply(arr[keyInd]);
|
||||
interaction.reply(arr[keyInd]);
|
||||
} catch {
|
||||
message.channel.send(arr[keyInd]);
|
||||
}
|
||||
interaction.channel.send(arr[keyInd]);
|
||||
}
|
||||
},
|
||||
options: [{name: 'type', description: 'Pick the genre of line or take a chance with random!', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [{name: "cheesy", value: "cheesy"}, {name: "funny", value: "funny"}, {name: "smooth", value: "smooth"}, {name: "best", value: "best"}, {name: "anime", value: "anime"}, {name: "random", value: "random"}, {name: "sources", value: "sources"} ] }]
|
||||
}
|
||||
@@ -1,459 +0,0 @@
|
||||
const pathToFfmpeg = require('ffmpeg-static');
|
||||
// const { joinVoiceChannel, createAudioResource } = require('@discordjs/voice');
|
||||
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType, joinVoiceChannel, createAudioResource, getVoiceConnection } = require('@discordjs/voice');
|
||||
const { MessageActionRow, MessageButton, MessageEmbed, MessageSelectMenu, Message } = require('discord.js');
|
||||
const play = require('play-dl');
|
||||
|
||||
|
||||
// Note: Unsure of what this does , but may be related to the play-dl lib (my notes are inconsistent)
|
||||
// play.authorization();
|
||||
|
||||
function playStopEmbed(bot, interaction, yt_info, stopped, message = null) {
|
||||
if (stopped) {
|
||||
var em = interaction.message.embeds[0];
|
||||
rows = [];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
interaction.update({embeds: [em], components: rows});
|
||||
} else {
|
||||
const author = {
|
||||
name: "Selmer Bot",
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
}
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setColor('#0F00F0')
|
||||
.setTitle(`${yt_info.video_details.title}`)
|
||||
.setAuthor(author)
|
||||
.setDescription('IS NOW PLAYING')
|
||||
.setURL(yt_info.video_details.url)
|
||||
.setThumbnail(yt_info.video_details.thumbnails[0].url);
|
||||
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('PAUSE')
|
||||
.setLabel('⏸️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
|
||||
if (message) {
|
||||
const m = message.reply({ embeds: [newEmbed], components: [row] });
|
||||
m.then((msg) => {
|
||||
const data = bot.audioData.get(message.guild.id);
|
||||
data[2] = msg.id;
|
||||
bot.audioData.set(message.guild.id, data);
|
||||
})
|
||||
} else {
|
||||
interaction.update({embeds: [newEmbed], components: [row]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function pause_start_stop(interaction, bot, message = null, command = null) {
|
||||
try {
|
||||
var player, em;
|
||||
|
||||
if (interaction) {
|
||||
player = bot.audioData.get(interaction.guildId)[0];
|
||||
command = interaction.customId.toLowerCase();
|
||||
em = interaction.message.embeds[0];
|
||||
} else {
|
||||
player = bot.audioData.get(message.guild.id)[0];
|
||||
em = message.embeds[0];
|
||||
}
|
||||
|
||||
var rows = [new MessageActionRow()];
|
||||
|
||||
if (command == "pause") {
|
||||
rows[0].addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('RESUME')
|
||||
.setLabel('▶️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
em.description = 'IS NOW PAUSED';
|
||||
player.pause();
|
||||
|
||||
} else if (command == "resume") {
|
||||
rows[0].addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId('PAUSE')
|
||||
.setLabel('⏸️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('STOP')
|
||||
.setLabel('⏹️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId('SKIP')
|
||||
.setLabel('⏭️')
|
||||
.setStyle('SECONDARY')
|
||||
);
|
||||
|
||||
em.description = 'IS NOW PLAYING';
|
||||
|
||||
player.unpause();
|
||||
} else if (command == "stop") {
|
||||
playStopEmbed(bot, interaction, null, true);
|
||||
|
||||
const connection = getVoiceConnection(interaction.guild.id);
|
||||
|
||||
player.stop();
|
||||
|
||||
//Remove everything from queue
|
||||
bot.audioData.delete(interaction.guildId);
|
||||
|
||||
if (connection) { connection.destroy(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (interaction) { interaction.update({embeds: [em], components: rows}); }
|
||||
else {
|
||||
const data = bot.audioData.get(message.guild.id);
|
||||
|
||||
// var msg = message.channel.messages.cache.get(data[2]);
|
||||
const newEmbed = message.embeds[0];
|
||||
newEmbed.description = "Has been deferred";
|
||||
message.edit({ embeds: [ newEmbed ], components: []});
|
||||
|
||||
const m = message.reply({embeds: [em], components: rows});
|
||||
m.then((msg) => {
|
||||
const data = bot.audioData.get(message.guild.id);
|
||||
data[2] = msg.id;
|
||||
bot.audioData.set(message.guild.id, data);
|
||||
})
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
rows = [];
|
||||
em.description = new String('IS NOW STOPPED');
|
||||
interaction.update({embeds: [em], components: rows});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function playNext(interaction, bot, message = null) {
|
||||
// https://discordjs.guide/voice/audio-player.html#taking-action-within-the-error-handler
|
||||
|
||||
//Setup data[1] = {info: yt_info, resource: resource}
|
||||
var guildId;
|
||||
if (message != null) { guildId = message.guild.id; }
|
||||
else { guildId = interaction.guildId; }
|
||||
|
||||
let data = bot.audioData.get(guildId);
|
||||
const player = data[0];
|
||||
|
||||
//Check if the queue is empty
|
||||
if (data[1].length <= 0) {
|
||||
player.stop();
|
||||
bot.audioData.delete(guildId);
|
||||
if (message) { return true; }
|
||||
else { return playStopEmbed(bot, interaction, null, true); }
|
||||
}
|
||||
|
||||
|
||||
const resource = data[1][0].resource;
|
||||
const yt_info = data[1][0].yt_info;
|
||||
player.stop();
|
||||
|
||||
//Play the thing
|
||||
player.play(resource);
|
||||
|
||||
//remove the song from queue
|
||||
delete data[1][0];
|
||||
data[1] = data[1].filter(n => n);
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
//Add the embed
|
||||
var msg = message;
|
||||
if (!message) {
|
||||
msg = interaction.message;
|
||||
interaction.update({ embeds: [ new MessageEmbed(interaction.message.embeds[0]).setDescription("IS NOW STOPPED") ], components: []});
|
||||
}
|
||||
|
||||
playStopEmbed(bot, interaction, yt_info, false, msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function fromMessage(bot, command, msg) {
|
||||
//Setup data[1] = {info: yt_info, resource: resource}
|
||||
const guildId = msg.guild.id;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return msg.reply("No music is currently playing!"); }
|
||||
|
||||
const player = data[0];
|
||||
const message = msg.channel.messages.cache.get(data[2]);
|
||||
// console.log(message);
|
||||
|
||||
var em;
|
||||
if (message.embeds) { em = message.embeds[0]; }
|
||||
var rows;
|
||||
|
||||
if (command == 'stop') {
|
||||
em = message.embeds[0];
|
||||
rows = [];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
player.stop();
|
||||
const connection = getVoiceConnection(guildId);
|
||||
if (connection) { connection.destroy(); }
|
||||
|
||||
bot.audioData.delete(guildId);
|
||||
msg.reply("Audio stopped!");
|
||||
|
||||
} else if (command == 'skip') {
|
||||
if (playNext(null, bot, message)) {
|
||||
rows = [];
|
||||
em = message.embeds[0];
|
||||
em.description = new String;
|
||||
em.description = 'IS NOW STOPPED';
|
||||
|
||||
msg.reply("Audio stopped!");
|
||||
}
|
||||
} else if (command == 'pause' || command == 'resume') {
|
||||
pause_start_stop(null, bot, message, command);
|
||||
}
|
||||
|
||||
|
||||
message.edit({embeds: [em], components: rows});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function showQueue(bot, message, interaction = null, page = 0) {
|
||||
const guild = message.guild.id;
|
||||
const data = bot.audioData.get(guild);
|
||||
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||
|
||||
const rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||
|
||||
const songList = [];
|
||||
var fiveSongs = '';
|
||||
let i = 0;
|
||||
|
||||
rawQueue.forEach(function (rawSong) {
|
||||
const songDetails = rawSong.yt_info.video_details;
|
||||
fiveSongs += `${i + 1}. ${songDetails.title}\n`;
|
||||
|
||||
i++;
|
||||
|
||||
//Split the songs into pages of 10
|
||||
if (i % 10 == 0) { songList.push(fiveSongs); fiveSongs = ''; }
|
||||
});
|
||||
|
||||
if (page >= songList.length) { page = songList.length - 1 }
|
||||
if (page < 0) { page = 0; } //LEAVE AS TWO IF's AS THE LENGTH MIGHT BE 0
|
||||
|
||||
if (songList.length == 0) { songList.push(fiveSongs); }
|
||||
|
||||
//Create the embed
|
||||
const author = {
|
||||
name: "Selmer Bot",
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
}
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setTitle("SONG QUEUE")
|
||||
.setAuthor(author)
|
||||
.setDescription(songList[page])
|
||||
.setFooter({ text: `Page ${page + 1}` })
|
||||
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`audioQueue|${page - 1}`)
|
||||
.setLabel('⬅️')
|
||||
.setStyle('SECONDARY'),
|
||||
new MessageButton()
|
||||
.setCustomId(`audioQueue|${page + 1}`)
|
||||
.setLabel('➡️')
|
||||
.setStyle('SECONDARY'),
|
||||
|
||||
)
|
||||
|
||||
if (interaction) {
|
||||
interaction.update({embeds: [newEmbed], components: [row]});
|
||||
} else {
|
||||
message.reply({ embeds: [newEmbed], components: [row] });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeFromQueue(bot, message, posStr) {
|
||||
const guildId = message.guild.id;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||
|
||||
const rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||
else if (isNaN(posStr) || Number(posStr) > rawQueue.length) { return message.reply("Please specify a number within queue bounds!"); }
|
||||
|
||||
const pos = Number(posStr) - 1;
|
||||
const details = rawQueue[pos].yt_info.video_details;
|
||||
|
||||
delete data[1][pos];
|
||||
data[1] = data[1].filter(n => n);
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
const newEmbed = new MessageEmbed()
|
||||
.setColor('#0F00F0')
|
||||
.setTitle(`${details.title}`)
|
||||
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||
.setDescription( `has been removed from position ${pos + 1} in queue!`)
|
||||
.setThumbnail(details.thumbnails[0].url);
|
||||
|
||||
message.reply({ embeds: [newEmbed] });
|
||||
}
|
||||
|
||||
|
||||
|
||||
function shuffleQueue(bot, message) {
|
||||
const guildId = message.guild.id;
|
||||
let data = bot.audioData.get(guildId);
|
||||
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||
|
||||
let rawQueue = data[1];
|
||||
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||
|
||||
//Shuffle the queue
|
||||
rawQueue = rawQueue.sort(() => Math.random()-0.5);
|
||||
|
||||
data[1] = rawQueue;
|
||||
|
||||
bot.audioData.set(guildId, data);
|
||||
|
||||
message.reply("The queue has been shuffled!\nThe new queue is:");
|
||||
showQueue(bot, message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: "audio",
|
||||
description: 'Play a song from YouTube, add free!',
|
||||
async execute(message, args, Discord, Client, bot, interaction = null) {
|
||||
const commandList = ['stop', 'skip', 'pause', 'resume'];
|
||||
|
||||
if (args.length < 1) {
|
||||
message.reply("Please use the following format _!audio [song name or URL]_ **or** _!audio queue_");
|
||||
return;
|
||||
} else if (args[0] == 'queue') {
|
||||
return showQueue(bot, message);
|
||||
} else if (commandList.indexOf(args[0]) != -1) {
|
||||
return fromMessage(bot, args[0], message);
|
||||
} else if (args[0] == 'remove') {
|
||||
if (args.length < 2) { return message.reply("Please specify a position in queue!"); }
|
||||
return removeFromQueue(bot, message, args[1]);
|
||||
} else if (args[0] == 'shuffle') {
|
||||
return shuffleQueue(bot, message);
|
||||
}
|
||||
|
||||
/*
|
||||
Re-introduce once the issue with ydtl-core is resolved (see
|
||||
https://github.com/porridgewithraisins/jam-bot#known-bugs)
|
||||
const stream = await ytdl(url, { filter: 'audioonly' });
|
||||
*/
|
||||
|
||||
if (!message.member.voice.channel) {
|
||||
message.reply("Please join a voice channel before you try this!");
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = bot.channels.cache.get(message.member.voice.channel.id);
|
||||
// console.log(message.member.voice.channel.id);
|
||||
|
||||
const connection = joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: channel.guild.id,
|
||||
adapterCreator: channel.guild.voiceAdapterCreator,
|
||||
});
|
||||
|
||||
connection.on(VoiceConnectionStatus.Ready, () => {
|
||||
// console.log('Connected to the voice channel!');
|
||||
});
|
||||
|
||||
let stream;
|
||||
let yt_info;
|
||||
if (args[0].startsWith("https://")) {
|
||||
if (!args[0].startsWith("https://www.youtube.com/") &&
|
||||
!args[0].startsWith("https://music.youtube.com/")) {
|
||||
message.reply("This is not a valid YouTube URL");
|
||||
return;
|
||||
}
|
||||
yt_info = await play.video_info(args[0]);
|
||||
// let stream = await play.stream_from_info(yt_info)
|
||||
stream = await play.stream(args[0]);
|
||||
|
||||
// console.log("Playing from a URL!");
|
||||
} else {
|
||||
yt_info = await play.search(args.join(' '), {
|
||||
limit: 1
|
||||
});
|
||||
|
||||
stream = await play.stream(yt_info[0].url);
|
||||
yt_info = await play.video_info(yt_info[0].url);
|
||||
}
|
||||
|
||||
let resource = createAudioResource(stream.stream, {
|
||||
inputType: stream.type
|
||||
})
|
||||
|
||||
// let audio = "em.mp3";
|
||||
// let resource = createAudioResource(join(__dirname, audio));
|
||||
|
||||
const data = bot.audioData.get(channel.guild.id);
|
||||
|
||||
if (data && data[1]) {
|
||||
//[player, [queue Array]]
|
||||
data[1].push({yt_info: yt_info, resource: resource});
|
||||
bot.audioData.set(message.guild.id, data);
|
||||
message.reply(`_"${yt_info.video_details.title}" added to queue!_`);
|
||||
} else {
|
||||
const player = createAudioPlayer();
|
||||
connection.subscribe(player);
|
||||
|
||||
bot.audioData.set(message.guild.id, [player, new Array(), null]);
|
||||
player.play(resource);
|
||||
|
||||
|
||||
player.on(AudioPlayerStatus.Playing, () => {
|
||||
//Check maybe?
|
||||
});
|
||||
|
||||
playStopEmbed(bot, interaction, yt_info, false, message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}, pause_start_stop, playNext, showQueue
|
||||
}
|
||||
+33
-16
@@ -1,13 +1,12 @@
|
||||
const { MessageEmbed } = require('discord.js');
|
||||
const { MessageEmbed, Constants } = require('discord.js');
|
||||
|
||||
|
||||
//!poll <name> <option 1, option 2> [option 3...option 10]
|
||||
module.exports = {
|
||||
name: "poll",
|
||||
description: "Create a cool poll embed (with time up to 1 hour!)",
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
if (args.length < 3) { return message.reply("Please provide a poll name, time (like 1:25 or 0 for not timed) and 1 - 10 options!"); }
|
||||
if (args.length > 12) { return message.reply("Please specify less than 10 options!"); }
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
const args = interaction.options.data;
|
||||
|
||||
const timeList = [ '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟' ];
|
||||
const author = {
|
||||
@@ -15,32 +14,36 @@ module.exports = {
|
||||
url: "",
|
||||
iconURL: bot.user.displayAvatarURL()
|
||||
}
|
||||
const name = args.filter((arg) => { return (arg.name == 'question'); })[0].value;
|
||||
|
||||
|
||||
var time = 0;
|
||||
const time = interaction.options.data.filter((arg) => { return (arg.name == 'time'); })[0].value;
|
||||
var temp;
|
||||
var isTimed = !Number.isNaN(Number(args[1].split(":")[0]));
|
||||
// var isTimed = !Number.isNaN(Number(args[1].split(":")[0]));
|
||||
|
||||
if (!isTimed) {
|
||||
temp = `This poll was created by ${message.author} and has no time limit!\n`;
|
||||
if (time != 0) {
|
||||
temp = `This poll was created by ${interaction.user} and has no time limit!\n`;
|
||||
} else {
|
||||
time += (Number(args[1].split(':')[0]) * 60) + Number(args[1].split(':')[1]);
|
||||
temp = `This poll was created by ${message.author} and ends <t:${Math.floor((new Date()).getTime()/1000) + time}:R>!\n`;
|
||||
time += time * 60; // (Number(args[1].split(':')[0]) * 60) + Number(args[1].split(':')[1]);
|
||||
temp = `This poll was created by ${interaction.user} and ends <t:${Math.floor((new Date()).getTime()/1000) + time}:R>!\n`;
|
||||
}
|
||||
|
||||
//args[0] is the poll name
|
||||
for(let i = 2; i < args.length; i ++) {
|
||||
for(let i = 0; i < args.length; i ++) {
|
||||
if (args[i].name.indexOf('option') == -1) { continue; }
|
||||
// complist.push({ name: `${timeList[i - 1]}: ${args[i]}`, value: "" });
|
||||
temp += `\n${timeList[i - 2]}: ${args[i]}\n`;
|
||||
temp += `\n${timeList[i - 2]}: ${args[i].value}\n`;
|
||||
}
|
||||
|
||||
const embd = new MessageEmbed()
|
||||
.setTimestamp()
|
||||
.setTitle(`${args[0]}`)
|
||||
.setTitle(`${name}`)
|
||||
.setDescription(temp)
|
||||
.setAuthor(author)
|
||||
|
||||
message.channel.send({ embeds: [embd] }).then((msg) => {
|
||||
const m = interaction.channel.send({ embeds: [embd] });
|
||||
m.then((msg) => {
|
||||
interaction.reply("Poll Posted!");
|
||||
|
||||
for(let i = 0; i < args.length - 2; i ++) {
|
||||
msg.react(timeList[i]);
|
||||
}
|
||||
@@ -85,5 +88,19 @@ module.exports = {
|
||||
msg.reply(temp);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
options: [
|
||||
{name: 'question', description: 'The poll question...', type: Constants.ApplicationCommandOptionTypes.STRING, required: true},
|
||||
{name: 'time', description: 'the time the poll is open for in minutes (for no limit input 0)', type: Constants.ApplicationCommandOptionTypes.INTEGER, required: true},
|
||||
{name: 'option1', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: true},
|
||||
{name: 'option2', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option3', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option4', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option5', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option6', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option7', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option8', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option9', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
{name: 'option10', description: 'A poll option', type: Constants.ApplicationCommandOptionTypes.STRING, required: false},
|
||||
]
|
||||
}
|
||||
Vendored
+7
-2
@@ -1,3 +1,5 @@
|
||||
//NOTE: THIS FUNCTION REQUIRES REPLIES, AND I CAN'T FIGURE OUT HOW TO LINK THEM TO SLASH COMMANDS
|
||||
|
||||
module.exports = {
|
||||
name: 'react',
|
||||
description: "Reacts with a phrase or single emoji",
|
||||
@@ -8,9 +10,8 @@ module.exports = {
|
||||
if (message.reference) {
|
||||
msg = await message.channel.messages.fetch(message.reference.messageId);
|
||||
} else { msg = message; }
|
||||
//Get rid of any custom emojis
|
||||
console.log("IMPLEMENT THIS");
|
||||
|
||||
try {
|
||||
let emoji = [...new Set(args[0])];
|
||||
if (emoji.length > 15 /*|| message.IndexOf(":") != -1*/) { return message.reply("Please enter less than 15 emojis"); }
|
||||
let notused = new Array(15);
|
||||
@@ -34,5 +35,9 @@ module.exports = {
|
||||
message.reply(notused.toString() + " is not a valid reaction emoji");
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return message.reply("Uh oh, there's been an error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
module.exports = {
|
||||
name: 'reactionrole',
|
||||
description: 'Creates an embed that will give a role when reacted to',
|
||||
async execute(message, args, Discord, bot) {
|
||||
if (bot.commands.get('verify').checkRole(message, args)) {
|
||||
console.log("IS ADMNIN");
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
-12
@@ -1,35 +1,51 @@
|
||||
const hastebin = require("hastebin-gen");
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
const { Constants } = require('discord.js');
|
||||
const { URL } = require("url");
|
||||
const axios = require('axios');
|
||||
const { isValidUrl } = require('../dev only/setPresence.js');
|
||||
|
||||
|
||||
module.exports ={
|
||||
name: "scrape",
|
||||
description: ".....",
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
const axios = require('axios');
|
||||
const cheerio = require('cheerio');
|
||||
const url = args[0];
|
||||
description: "Scrapes a website, then puts the result into a hastebin",
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
// const cheerio = require('cheerio');
|
||||
const url = interaction.options.data[0].value;
|
||||
|
||||
if (!isValidUrl(url)) {
|
||||
return interaction.reply("Please enter a valid url").catch((err) => {
|
||||
interaction.channel.send("Please enter a valid url");
|
||||
});
|
||||
}
|
||||
|
||||
axios(url)
|
||||
.then(async response => {
|
||||
const html = response.data;
|
||||
const $ = cheerio.load(html);
|
||||
// const $ = cheerio.load(html);
|
||||
//lyrics = $('.para_row').text();
|
||||
|
||||
const haste = await hastebin(html, { extension: "txt" });
|
||||
message.channel.send(haste);
|
||||
interaction.reply(haste);
|
||||
// console.log(lyrics);
|
||||
})
|
||||
.catch(function(err) {
|
||||
if (err.message.indexOf('The "url" argument must be of type string') != -1) {
|
||||
message.reply("The URL should be a string!");
|
||||
interaction.reply("The URL should be a string!");
|
||||
} else if (err.code == 'ERR_BAD_REQUEST') {
|
||||
message.reply("404 link not valid!")
|
||||
interaction.reply("404 link not valid!")
|
||||
} else {
|
||||
message.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||
addComplaintButton(bot, message);
|
||||
const m = interaction.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||
|
||||
m.then((msg) => {
|
||||
addComplaintButton(bot, msg);
|
||||
});
|
||||
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
options: [{name: 'url', description: 'The website URL', type: Constants.ApplicationCommandOptionTypes.STRING, required: true }]
|
||||
}
|
||||
|
||||
//TEST: https://www.karaoketexty.cz/texty-pisni/zoegirl/plain-170199
|
||||
+29
-28
@@ -1,4 +1,4 @@
|
||||
const { Modal, TextInputComponent, MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js');
|
||||
const { Constants, MessageEmbed, Interaction } = require('discord.js');
|
||||
|
||||
const dateFns = require('date-fns');
|
||||
const { formatToTimeZone } = require('date-fns-timezone');
|
||||
@@ -13,7 +13,7 @@ const alpaca = new Alpaca({
|
||||
});
|
||||
|
||||
//This is the same as making the following request: https://data.alpaca.markets/v2/stocks/snapshots?symbols={stock_symbols_here}
|
||||
async function getStockData(bot, message, args, stock) {
|
||||
async function getStockData(bot, interaction, stock, type, after) {
|
||||
try {
|
||||
const snapshotPromise = alpaca.getSnapshot(stock);
|
||||
|
||||
@@ -22,7 +22,7 @@ async function getStockData(bot, message, args, stock) {
|
||||
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||
.setFooter({ text: 'Selmer Bot uses Alpaca for stock information'})
|
||||
|
||||
if (args[1] == 'trade') {
|
||||
if (type) {
|
||||
const lt = snapshot.LatestTrade;
|
||||
embd.setTitle(`${stock} Latest Trade`)
|
||||
.setTimestamp(lt.Timestamp)
|
||||
@@ -33,9 +33,9 @@ async function getStockData(bot, message, args, stock) {
|
||||
//This will always be IEX, as it is the only exchange the free version offers
|
||||
{name: 'Exchange', value: `IEX (${lt.Exchange})`},
|
||||
)
|
||||
} else if (args[1] == 'quote') {
|
||||
if (args[2] == 'after') {
|
||||
return message.reply("Due to the markets not being open, there is no quote data available!");
|
||||
} else if (type) {
|
||||
if (after) {
|
||||
return interaction.reply("Due to the markets not being open, there is no quote data available!");
|
||||
}
|
||||
const lq = snapshot.LatestQuote;
|
||||
embd.setTitle(`${stock} Latest Quote`)
|
||||
@@ -49,7 +49,7 @@ async function getStockData(bot, message, args, stock) {
|
||||
//This will always be IEX, as it is the only exchange the free version offers
|
||||
{name: 'Exchange', value: `IEX (${lq.Exchange})`},
|
||||
)
|
||||
} else if (args[1] == 'bars') {
|
||||
} else if (type) {
|
||||
const mb = snapshot.MinuteBar;
|
||||
const db = snapshot.DailyBar;
|
||||
const pdb = snapshot.PrevDailyBar;
|
||||
@@ -61,23 +61,22 @@ async function getStockData(bot, message, args, stock) {
|
||||
{name: 'Day Bar (Yesterday)', value: `Open Price: ${pdb.OpenPrice},\nClose Price: ${pdb.ClosePrice},\nHigh Price: ${pdb.HighPrice},\nLow Price: ${pdb.LowPrice},\nVolume: ${pdb.Volume},\nCount: ${pdb.TradeCount},\nVWAP: ${pdb.VWAP}`},
|
||||
)
|
||||
} else {
|
||||
return message.reply("The command format is: _!stocks <stock_name, 'hours'> <trade, quote, bars> [after]_");
|
||||
return interaction.reply("The command format is: _/stocks <stock_name, 'hours'> <trade, quote, bars> [after]_");
|
||||
}
|
||||
|
||||
message.reply({embeds: [embd]});
|
||||
interaction.reply({embeds: [embd]});
|
||||
})
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
message.reply("Uh Oh, there's been an error!");
|
||||
interaction.reply("Uh Oh, there's been an error!");
|
||||
}
|
||||
}
|
||||
|
||||
function getData(bot, message, args) {
|
||||
var stock;
|
||||
if (args.length < 1) {
|
||||
return message.reply("Please specify a stock (ex: AAPL, GOOG, etc)")
|
||||
} else { stock = args[0];}
|
||||
|
||||
function getData(bot, interaction) {
|
||||
const args = interaction.options.data;
|
||||
const stock = args.filter((arg) => { return (arg.name == 'name')})[0].value;
|
||||
const type = args.filter((arg) => { return (arg.name == 'type')})[0].value;
|
||||
const after = (args.length > 2 && args.filter((arg) => { return (arg.name == 'after')})[0].value);
|
||||
|
||||
const format = `yyyy-MM-dd HH:mm:ss`;
|
||||
const date = dateFns.format(new Date(), format);
|
||||
@@ -90,17 +89,17 @@ function getData(bot, message, args) {
|
||||
end: date
|
||||
}).then((calendars) => {
|
||||
let temp;
|
||||
if (clock.is_open || args[2] == 'after') {
|
||||
if (args[0] == 'hours') {
|
||||
if (clock.is_open || after) {
|
||||
if (stock == 'hours') {
|
||||
temp = `The markets opened at ${calendars[0].open} and will close at ${calendars[0].close} on ${date}.`;
|
||||
return message.reply(temp);
|
||||
return interaction.reply(temp);
|
||||
}
|
||||
getStockData(bot, message, args, stock);
|
||||
getStockData(bot, interaction, stock, type, after);
|
||||
} else {
|
||||
// `The market is currently ${clock.is_open ? 'open.' : 'closed.'}`
|
||||
//May be innacurate?
|
||||
temp = `_The markets closed at \`${calendars[0].close}\` and will open again at \`${calendars[0].open}\` on \`${dateFns.format((new Date()).setDate(new Date().getDate() + 1), 'yyyy-MM-dd')}\`.\nTo get the last snapshot before market closure, add the \`after\` keyword to the end of your command (trade and bars ONLY), ex: !stocks GOOG bars after_`;
|
||||
return message.reply(temp);
|
||||
temp = `_The markets closed at \`${calendars[0].close}\` and will open again at \`${calendars[0].open}\` on \`${dateFns.format((new Date()).setDate(new Date().getDate() + 1), 'yyyy-MM-dd')}\`.\nTo get the last snapshot before market closure, add the \`after\` keyword to the end of your command (trade and bars ONLY), ex: /stocks GOOG bars after_`;
|
||||
return interaction.reply(temp);
|
||||
}
|
||||
});
|
||||
})
|
||||
@@ -111,10 +110,12 @@ function getData(bot, message, args) {
|
||||
module.exports = {
|
||||
name: 'stocks',
|
||||
description: "Have Selmer Bot give you \"current\" stock prices",
|
||||
async execute(message, args, Discord, Client, bot) {
|
||||
if (args[0] == 'help' || args.length < 1) {
|
||||
return message.reply("The command format is: _!stocks <stock_name, 'hours'> <trade, quote, bars> [after]_");
|
||||
}
|
||||
getData(bot, message, args);
|
||||
}
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
getData(bot, interaction);
|
||||
},
|
||||
options: [
|
||||
{name: 'name', description: 'the stock name or "hours" for market hours', type: Constants.ApplicationCommandOptionTypes.STRING, required: true},
|
||||
{name: 'type', description: 'The type of data to present', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [ { name: 'trade', value: 'trade' }, { name: 'quote', value: 'quote' }, {name: 'bars', value: 'bars'}]},
|
||||
{name: 'after', description: 'If the markets are closed, get the last entry', type: Constants.ApplicationCommandOptionTypes.BOOLEAN, required: false},
|
||||
]
|
||||
}
|
||||
@@ -24,6 +24,7 @@ async function messageExists(message) {
|
||||
|
||||
|
||||
async function getResponse(convo, bot) {
|
||||
try {
|
||||
const response = await bot.openai.createCompletion({
|
||||
model: "text-davinci-002",
|
||||
prompt: convo,
|
||||
@@ -36,6 +37,11 @@ async function getResponse(convo, bot) {
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function convoManager(clientinp, bot, message) {
|
||||
@@ -78,6 +84,10 @@ async function convoManager(clientinp, bot, message) {
|
||||
//Get the response
|
||||
const r = await getResponse(convo, bot);
|
||||
|
||||
if (!r) {
|
||||
return message.channel.send("Uh oh! There's been an error! Please contact support \:[");
|
||||
}
|
||||
|
||||
let response = r.data.choices[0].text;
|
||||
|
||||
convo += (response + '\n');
|
||||
@@ -103,7 +113,7 @@ module.exports = {
|
||||
name: 'chat',
|
||||
description: 'chat',
|
||||
convoManager,
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
message.reply("Please DM Selmer bot to use this command!");
|
||||
execute(interaction, args, Discord, Client, bot) {
|
||||
interaction.reply("Please DM Selmer bot to use this command!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
const { ICalParser } = require('cozy-ical');
|
||||
const { URL } = require('url');
|
||||
const { Constants } = require('discord.js');
|
||||
const request = require('request');
|
||||
const { verPremium } = require('../premium/verifyPremium.js');
|
||||
const { isValidUrl } = require('../dev only/setPresence.js');
|
||||
|
||||
|
||||
//#region SET REMINDERS
|
||||
|
||||
function addReminder(interaction, bot, obj, Id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
bot.mongoconnection.then((client) => {
|
||||
// Update the Key object first to check if the time is already there
|
||||
const kbo = client.db('main').collection('reminderKeys');
|
||||
kbo.findOne(({ 'userId': Id })).then((doc) => {
|
||||
const t = obj.time.toString();
|
||||
try {
|
||||
if (doc.times.indexOf(obj.time) == -1) {
|
||||
kbo.updateOne({ 'userId': Id }, { $push: { times: t } })
|
||||
} else {
|
||||
//Event already exists at this time
|
||||
reject("An event already exists at this time!");
|
||||
return; // interaction.channel.send("An event already exists at this time!");
|
||||
}
|
||||
|
||||
//Update the Time object
|
||||
const dbo = client.db('main').collection('reminders');
|
||||
dbo.findOne({ time: t }).then((doc) => {
|
||||
let n = 0;
|
||||
if (doc) {
|
||||
n = doc.amt;
|
||||
doc.amt ++;
|
||||
|
||||
doc[`${n}`] = obj.event;
|
||||
dbo.findOneAndReplace({ time: t }, doc);
|
||||
} else {
|
||||
const d = new Date(Number(obj.time));
|
||||
doc = { "0": obj.event, "time": t, "month": d.getMonth(), "amt": 1 }; //Month used for clearing when the calendar month begins (maybe modify the garbage collection with an `else if (day == 1? clear last month)` )
|
||||
dbo.insertOne(doc);
|
||||
}
|
||||
|
||||
//Reply with the reminder in correct format
|
||||
// interaction.reply({ content: "REMINDER SAVED!", embeds: [embd], ephemeral: true });
|
||||
resolve(true);
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
// interaction.reply("Uh Oh! An error has occured!");
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err); //interaction.reply("Uh Oh! An error has occured!");
|
||||
reject(err);
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log("ERR");
|
||||
console.error(err);
|
||||
reject(false);
|
||||
// interaction.reply("Uh Oh! An error has occured!");
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// return interaction.reply("Uh Oh! An error has occured!"); // Gets "acknowledged" too many times
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
//#region SETUP AND PARSING
|
||||
class calClass {
|
||||
constructor(vevent) {
|
||||
const model = vevent.model;
|
||||
const alarms = vevent.subComponents;
|
||||
|
||||
if (alarms && alarms[0] && alarms[0].model) {
|
||||
let temp = alarms[0].model.trigger;
|
||||
temp = temp.split('DT')[1];
|
||||
temp = temp.split("H");
|
||||
|
||||
let hours = (temp[0] && temp[0] != '0') ? Number(temp[0]) : 0;
|
||||
let minutesStr = temp[1].split('M')[0];
|
||||
let minutes = (minutesStr && !isNaN(minutesStr)) ? hours + Number(minutesStr) : hours;
|
||||
|
||||
this.offset = minutes;
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
this.name = model.summary;
|
||||
this.description = (model.description) ? model.description : "N/A";
|
||||
|
||||
const dateTime = new Date(model.startDate);
|
||||
this.time = dateTime.getTime()/1000;
|
||||
|
||||
if (isValidUrl(model.location)) {
|
||||
this.url = model.location || undefined;
|
||||
this.loc = undefined;
|
||||
} else {
|
||||
this.url = undefined;
|
||||
this.loc = model.location || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
isValidUrl(s) {
|
||||
try {
|
||||
new URL(s);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
exportAsObj(gid, uid) {
|
||||
const obj = { time: this.time, event: { guildId: gid, userId: uid, name: this.name, description: this.description, offset: this.offset, link: this.url, location: this.loc } }
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseData(calStr, gid, uid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parser = new ICalParser();
|
||||
parser.parseString(calStr, function(err, cal) {
|
||||
try {
|
||||
const arr = [];
|
||||
|
||||
for (i in cal.subComponents) {
|
||||
const a = new calClass(cal.subComponents[i]);
|
||||
arr.push(a.exportAsObj(gid, uid));
|
||||
}
|
||||
|
||||
resolve(arr);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {String} fileName
|
||||
*/
|
||||
function readFileAndParse(url, bot, interaction, gid, uid) {
|
||||
request.get(url, function (error, response, body) {
|
||||
try {
|
||||
if (!error && response.statusCode == 200) {
|
||||
const isGuild = (gid && !uid) || false;
|
||||
const notAdded = [];
|
||||
|
||||
const Id = (isGuild) ? gid : uid;
|
||||
|
||||
parseData(body, gid, uid).then((arr) => {
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
// If the key does not exist, create it
|
||||
if (arr.length > 0) {
|
||||
bot.mongoconnection.then((client) => {
|
||||
const kbo = client.db('main').collection('reminderKeys');
|
||||
kbo.findOne(({ 'userId': Id })).then((doc) => {
|
||||
if (!doc) {
|
||||
doc = { userId: Id, times: [] }
|
||||
kbo.insertOne(doc);
|
||||
|
||||
reject("New user created, please try again!");
|
||||
} else {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
reject("No data...");
|
||||
}
|
||||
|
||||
// const m = new Map(arr.map((obj, ind) => { return [ind, obj]; }));
|
||||
}).then(() => {
|
||||
Promise.all(arr.map((obj, ind) => {
|
||||
addReminder(interaction, bot, obj, Id).then(() => {})
|
||||
.catch((err) => {
|
||||
notAdded.push(err);
|
||||
});
|
||||
})).then((t) => {
|
||||
const r1 = { content: `ITEMS NOT ADDED:\n${notAdded.join("\n")}`, ephemeral: true }
|
||||
|
||||
if (r1.content != "ITEMS NOT ADDED:\n") {
|
||||
interaction.reply(r1).catch((err) => { interaction.channel.send(r1); });
|
||||
} else {
|
||||
const r2 = `All ${arr.length} items added to calendar!`;
|
||||
interaction.reply(r2).catch((err) => { interaction.channel.send(r2); });
|
||||
}
|
||||
});
|
||||
}).catch((err) => {
|
||||
interaction.reply(err);
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
interaction.reply({ content: "Uh oh, there's been an error!", ephemeral: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'import_ics',
|
||||
description: 'Import events using a calendar',
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
//Check if the user has premium
|
||||
await verPremium(bot, interaction.user.id).then(() => {
|
||||
const url = interaction.options.data[0].attachment.attachment;
|
||||
|
||||
if (!url.endsWith(".ics")) {
|
||||
return interaction.reply("Please use a valid ***.ics*** file!")
|
||||
}
|
||||
|
||||
let uid, gid;
|
||||
if (interaction.channel.type == 'DM') {
|
||||
uid = interaction.user.id;
|
||||
} else {
|
||||
gid = interaction.guildId;
|
||||
}
|
||||
readFileAndParse(url, bot, interaction, gid, uid);
|
||||
}).catch(() => {
|
||||
interaction.reply("You have to be a premium subscriber to use this feature!");
|
||||
});
|
||||
},
|
||||
options: [
|
||||
{name: 'ics_file', description: 'The ics file to input', type: Constants.ApplicationCommandOptionTypes.ATTACHMENT, required: true},
|
||||
],
|
||||
isDm: true
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
const { Modal, TextInputComponent, MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js');
|
||||
const { checkRole } = require('../admin/verify');
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,9 +50,9 @@ function postEmbd(bot, desc, interaction, page, isGuild, id, refered) {
|
||||
row.addComponents(prevbtn, nextbtn);
|
||||
|
||||
if (page > 0 || refered) {
|
||||
interaction.update({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||
interaction.update({ content: '_Note: To see a full list of reminder stats visit https://selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||
} else {
|
||||
interaction.reply({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||
interaction.reply({ content: '_Note: To see a full list of reminder stats visit https://selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
@@ -190,8 +189,11 @@ function addEvent(obj, connection, interaction, embd) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = false) {
|
||||
/**
|
||||
* @returns { Promise<[]> | Promise<[false, []] | [true, String]>} (all events) || (custom err) ? [true, err] : [false, err]
|
||||
*/
|
||||
function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = false, isExport = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var userId = false;
|
||||
var guildId = false;
|
||||
const numperpage = 5;
|
||||
@@ -209,11 +211,23 @@ function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = f
|
||||
|
||||
//ReminderKeys are all stored as userId, the reminders themselves are not
|
||||
dbo.findOne({$or: [ {userId: userId}, {userId: guildId} ]}).then((doc) => {
|
||||
if (!doc) { return interaction.reply("No events exist!"); }
|
||||
if (!doc) {
|
||||
if (isExport) {
|
||||
return reject([true, "No events exist!"]);
|
||||
}
|
||||
|
||||
return interaction.reply("No events exist!");
|
||||
}
|
||||
|
||||
times = doc.times;
|
||||
const tbo = client.db('main').collection('reminders');
|
||||
|
||||
tbo.find({time: {$in: times}}).toArray((err, docs) => {
|
||||
|
||||
if (isExport) {
|
||||
return resolve(docs);
|
||||
}
|
||||
|
||||
//There's gotta be a better way
|
||||
var temp = [""];
|
||||
var page = 0;
|
||||
@@ -234,13 +248,19 @@ function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = f
|
||||
|
||||
//Create the embed
|
||||
postEmbd(bot, temp, interaction, jpage, isGuild, id, refered);
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if (isExport) {
|
||||
return reject([false, err]);
|
||||
}
|
||||
return interaction.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -365,21 +385,21 @@ function turnPage(bot, interaction) {
|
||||
module.exports = {
|
||||
name: "reminders",
|
||||
description: "Have Selmer Bot remind you - premium feature",
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
//Check if the user has premium
|
||||
bot.mongoconnection.then(async (client) => {
|
||||
const dbo = client.db('main').collection('authorized');
|
||||
dbo.find({ discordID: message.author.id }).toArray((err, docs) => {
|
||||
dbo.find({ discordID: interaction.user.id }).toArray((err, docs) => {
|
||||
|
||||
//Only available to Selmer Bot devs, testers and "authorized" users
|
||||
if (docs[0] != undefined) {
|
||||
//Execute the command
|
||||
const row = new MessageActionRow()
|
||||
|
||||
if (message.channel.type == 'DM') {
|
||||
if (interaction.channel.type == 'DM') {
|
||||
row.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`newEvent|User|${message.author.id}`)
|
||||
.setCustomId(`newEvent|User|${interaction.user.id}`)
|
||||
.setLabel('New Personal Reminder')
|
||||
.setStyle('SUCCESS'),
|
||||
new MessageButton()
|
||||
@@ -390,7 +410,7 @@ module.exports = {
|
||||
} else {
|
||||
row.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`newEvent|User|${message.author.id}`)
|
||||
.setCustomId(`newEvent|User|${interaction.user.id}`)
|
||||
.setLabel('New Personal Reminder')
|
||||
.setStyle('SUCCESS'),
|
||||
new MessageButton()
|
||||
@@ -404,11 +424,12 @@ module.exports = {
|
||||
);
|
||||
}
|
||||
|
||||
return message.channel.send({ content: 'Please select an action\n_Notes: Adding offset to an event is only supported on the website and personal reminders can be viewed in DM\'s_', components: [row] });
|
||||
return interaction.reply({ content: 'Please select an action\n_Notes: Adding offset to an event is only supported on the website and personal reminders can be viewed in DM\'s_', components: [row], ephemeral: true });
|
||||
} else {
|
||||
message.reply("You have to be a premium subscriber to use this feature!\n_support coming soon_");
|
||||
interaction.reply("You have to be a premium subscriber to use this feature!\n_support coming soon_");
|
||||
}
|
||||
});
|
||||
});
|
||||
}, modalHandle, turnPage
|
||||
}, modalHandle, turnPage, addEvent, getEvents,
|
||||
options: []
|
||||
}
|
||||
+27
-21
@@ -3,9 +3,10 @@
|
||||
https://selmer-bot-listener.ion606.repl.co
|
||||
--------------------------------------------------
|
||||
*/
|
||||
//@ts-check
|
||||
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const { MessageActionRow, MessageSelectMenu } = require('discord.js');
|
||||
const { MessageActionRow, MessageSelectMenu, Constants } = require('discord.js');
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
|
||||
|
||||
@@ -79,10 +80,10 @@ async function createSubscriptionManual(bot, interaction, id, priceID) {
|
||||
}
|
||||
|
||||
|
||||
async function changeSubscriptionManual(bot, message) {
|
||||
async function changeSubscriptionManual(bot, interaction) {
|
||||
const stripe = bot.stripe;
|
||||
const mongouri = bot.mongouri;
|
||||
const id = message.author.id;
|
||||
const id = interaction.user.id;
|
||||
|
||||
//Just in case
|
||||
if (!id) { return console.log('....What? How?'); }
|
||||
@@ -102,7 +103,7 @@ async function changeSubscriptionManual(bot, message) {
|
||||
resolve(userID);
|
||||
} else {
|
||||
// client.close();
|
||||
reject(`No user with the ID of <@${message.author.id}>`);
|
||||
reject(`No user with the ID of <@${interaction.user.id}>`);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -112,22 +113,22 @@ async function changeSubscriptionManual(bot, message) {
|
||||
customer: userID,
|
||||
return_url: "https://linktr.ee/selmerbot",
|
||||
}).then((session) => {
|
||||
message.reply(session.url);
|
||||
interaction.reply(session.url);
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
||||
if (String(typeof(err)) == 'string') {
|
||||
message.reply(err);
|
||||
interaction.reply(err);
|
||||
} else {
|
||||
console.log(err);
|
||||
message.reply("A Stripe error occured! Please click the ✅ to report this ASAP!");
|
||||
addComplaintButton(bot, interaction.message);
|
||||
interaction.reply("A Stripe error occured! Please click the ✅ to report this ASAP!");
|
||||
addComplaintButton(bot, interaction.message); //?????????
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function createDropDown(bot, message) {
|
||||
function createDropDown(bot, interaction) {
|
||||
const stripe = bot.stripe;
|
||||
|
||||
const pl = [];
|
||||
@@ -155,24 +156,25 @@ function createDropDown(bot, message) {
|
||||
const row = new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageSelectMenu()
|
||||
.setCustomId(`${message.author.id}|premium`)
|
||||
.setCustomId(`${interaction.user.id}|premium`)
|
||||
.setPlaceholder('Nothing selected')
|
||||
.addOptions(vl)
|
||||
);
|
||||
|
||||
message.channel.send({ content: `Please choose a tier`, components: [row] });
|
||||
interaction.reply({ content: `Please choose a tier`, components: [row], ephemeral: true });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function handleInp(bot, message) {
|
||||
if (message.content == '!premium' || message.content == '!premium help') {
|
||||
message.reply('Use _!premium buy_ to get premium or use _!premium manage_ to change or cancel your subscription\n\n_Disclaimer: Selmer Bot uses Stripe to manage payments. Read more at *https://stripe.com/ *_');
|
||||
} else if (message.content == '!premium buy') {
|
||||
createDropDown(bot, message);
|
||||
} else if (message.content == '!premium manage') {
|
||||
changeSubscriptionManual(bot, message);
|
||||
function handleInp(bot, interaction) {
|
||||
const inp = interaction.options.data[0];
|
||||
if (!inp || inp.value == 'help') {
|
||||
interaction.reply({content: 'Use _!premium buy_ to get premium or use _!premium manage_ to change or cancel your subscription\n\n_Disclaimer: Selmer Bot uses Stripe to manage payments. Read more at *https://stripe.com/ *_', ephemeral: true});
|
||||
} else if (inp.value == 'buy') {
|
||||
createDropDown(bot, interaction);
|
||||
} else if (inp.value == 'manage') {
|
||||
changeSubscriptionManual(bot, interaction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +182,11 @@ function handleInp(bot, message) {
|
||||
module.exports = {
|
||||
name: 'premium',
|
||||
description: 'everything payment',
|
||||
execute(message, args, Discord, Client, bot) {
|
||||
message.reply("Please DM Selmer bot to use this command!");
|
||||
}, handleInp, createSubscriptionManual
|
||||
execute(interaction, Discord, Client, bot) {
|
||||
handleInp(bot, interaction);
|
||||
}, handleInp, createSubscriptionManual,
|
||||
options: [
|
||||
{name: 'option', description: 'What do you want to do?', type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [{name: 'help', value: 'help'}, {name: 'buy', value: 'buy'}, {name: 'manage', value: 'manage'}]}
|
||||
],
|
||||
isDm: true
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
/**
|
||||
* Check if the user has a premium subscription
|
||||
* @param {*} bot
|
||||
* @param {String} userId
|
||||
* @returns {Promise<Boolean>}
|
||||
*/
|
||||
function verPremium(bot, userId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const member = bot.guilds.cache.get(bot.home_server).members.cache.get(userId);
|
||||
bot.mongoconnection.then(async (client) => {
|
||||
const dbo = client.db('main').collection('authorized');
|
||||
dbo.findOne({ discordID: userId }).then((doc) => {
|
||||
//Only available to Selmer Bot devs, testers and "authorized" users
|
||||
if (doc != undefined || member && (member.roles.cache.has('944048889038774302') || member.roles.cache.has('946610800418762792'))) {
|
||||
resolve(true);
|
||||
} else {
|
||||
reject("You have to be a premium subscriber to use this feature!\n_support coming soon_");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = { verPremium }
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
<body>
|
||||
<div class="row">
|
||||
<div style="text-align: center;">
|
||||
<button onclick="window.open('https://www.selmerbot.com/', target='_blank')" class="webBtn">selmerbot.com</button>
|
||||
<button onclick="window.open('https://selmerbot.com/', target='_blank')" class="webBtn">selmerbot.com</button>
|
||||
<script type="text/javascript" src="https://cdnjs.buymeacoffee.com/1.0.0/button.prod.min.js" data-name="bmc-button" data-slug="ion606" data-color="#FFDD00" data-emoji="" data-font="Cookie" data-text="Buy me a coffee" data-outline-color="#000000" data-font-color="#000000" data-coffee-color="#ffffff"></script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//#region imports
|
||||
const { Client, Intents, MessageActionRow, MessageButton, MessageSelectMenu } = require('discord.js');
|
||||
const { Client, Intents } = require('discord.js');
|
||||
const Discord = require('discord.js');
|
||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||
const { MongoClient, ServerApiVersion, GridFSBucket } = require('mongodb');
|
||||
const fs = require('fs');
|
||||
// const OpenAI = require('openai-api')
|
||||
const { Configuration, OpenAIApi } = require("openai");
|
||||
@@ -9,11 +9,15 @@ const Stripe = require('stripe');
|
||||
|
||||
const turnManager = require('./commands/turnManager.js');
|
||||
const { welcome } = require('./commands/admin/welcome.js');
|
||||
const { handle_interaction } = require('./commands/interactionhandler.js');
|
||||
const { handle_interaction, handleContext } = require('./commands/interactionhandler.js');
|
||||
const { handle_dm } = require('./commands/dm_handler');
|
||||
const { devCheck } = require('./commands/dev only/devcheck.js');
|
||||
const { moderation_handler } = require('./commands/admin/moderation.js');
|
||||
const { registerCommands } = require('./registerCommands.js');
|
||||
const { backupLists, loadBotBackups } = require('./commands/dev only/backupBot.js');
|
||||
const { setPresence } = require('./commands/dev only/setPresence.js');
|
||||
const { exit } = require('process');
|
||||
const {textToLevels} = require('./commands/Selmer Specific/msgLevels.js');
|
||||
//#endregion
|
||||
|
||||
const BASE_LVL_XP = 20;
|
||||
@@ -29,6 +33,7 @@ let debug_channel;
|
||||
|
||||
let MLAIKEY;
|
||||
let StripeAPIKey;
|
||||
let youtubeAPIKey;
|
||||
|
||||
if (process.env.token != undefined) {
|
||||
//Use "setx NAME VALUE" in the local powershell terminal to set
|
||||
@@ -37,6 +42,7 @@ if (process.env.token != undefined) {
|
||||
debug_channel = process.env.debug_channel;
|
||||
MLAIKEY = process.env.MLAIKEY;
|
||||
StripeAPIKey = process.env.StripeAPIKey;
|
||||
youtubeAPIKey = process.env.youtubeAPIKey;
|
||||
} else {
|
||||
token = require('./config.json').token;
|
||||
home_server = require('./config.json').home_server;
|
||||
@@ -44,9 +50,9 @@ if (process.env.token != undefined) {
|
||||
|
||||
MLAIKEY = require('./config.json').MLAIKEY;
|
||||
StripeAPIKey = require('./config.json').StripeAPIKey;
|
||||
youtubeAPIKey = require('./config.json').youtubeAPIKey;
|
||||
|
||||
// { token, home_server, debug_channel, MLAIKEY, StripeAPIKey } = require('./config.json'); // Doesn't work
|
||||
IDM = true;
|
||||
IDM = token.startsWith("OTI2NT");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -74,6 +80,7 @@ bot.inDebugMode = IDM;
|
||||
bot.home_server = home_server;
|
||||
bot.debug_channel = debug_channel;
|
||||
bot.inviteLink = 'https://discord.com/oauth2/authorize?client_id=944046902415093760&scope=applications.commands+bot&permissions=549755289087';
|
||||
bot.youtubeAPIKey = youtubeAPIKey;
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: MLAIKEY,
|
||||
@@ -85,6 +92,7 @@ bot.stripe = Stripe(StripeAPIKey);
|
||||
//The first thing will be an audioPlayer(), the second a queue
|
||||
bot.audioData = new Map();
|
||||
|
||||
bot.lockedChannels = new Map();
|
||||
|
||||
//#region MongoDB integration
|
||||
//Development support
|
||||
@@ -99,11 +107,64 @@ bot.mongouri = mongouri;
|
||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||
bot.mongoconnection = client.connect();
|
||||
|
||||
const { connect } = require('mongoose');
|
||||
//Error stuff
|
||||
var preverr = "";
|
||||
var errmsg;
|
||||
var errTimes = 1;
|
||||
|
||||
//#endregion MongoDB Integration end
|
||||
|
||||
|
||||
//#region PROCESS STUFF
|
||||
loadBotBackups(bot, IDM);
|
||||
process.on("SIGTERM", (signal) => {
|
||||
console.log(`Process ${process.pid} received a SIGTERM signal`);
|
||||
backupLists(bot, IDM);
|
||||
// process.exit(0);
|
||||
bot.user.setStatus('invisible');
|
||||
});
|
||||
|
||||
process.on("SIGINT", (signal) => {
|
||||
console.log(`Process ${process.pid} has been interrupted`);
|
||||
backupLists(bot, IDM);
|
||||
// process.exit(0);
|
||||
bot.user.setStatus('invisible');
|
||||
});
|
||||
|
||||
process.on('uncaughtException', (signal) => {
|
||||
//Check if this was the last err and if so, ignore
|
||||
if (preverr == signal.stack.toString()) {
|
||||
var tempmsg = errmsg.content;
|
||||
tempmsg.replaceAll(`{${errTimes}}`, `{${errTimes + 1}}`);
|
||||
errTimes++;
|
||||
|
||||
errmsg.edit(tempmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(signal);
|
||||
|
||||
if (bot.inDebugMode) { return; }
|
||||
|
||||
const guild = bot.guilds.cache.get(bot.home_server);
|
||||
const owner = guild.members.cache.get(guild.ownerId);
|
||||
preverr = signal.stack.toString();
|
||||
|
||||
owner.send(`${owner} SELMER BOT IS DOWN!!!`).then(() => {
|
||||
guild.channels.cache.get("1054550753982828624").send(`<@&944048889038774302> Selmer Bot is down!\n***ERROR STACK:***\n`).then(() => {
|
||||
guild.channels.cache.get("1054550753982828624").send(`\`\`\`${preverr}\`\`\`\nTHIS ERROR HAS OCCURED {1} TIMES IN A ROW`).then((msg) => {
|
||||
errmsg = msg;
|
||||
preverr = signal.stack.toString();
|
||||
// exit(12);
|
||||
bot.user.setStatus('dnd');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region set up bot commands
|
||||
|
||||
// const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js')); // Obsolete?
|
||||
@@ -129,6 +190,7 @@ fs.readdirSync('./commands')
|
||||
//Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file)
|
||||
let temp_command = require("./commands/db/econ.js");
|
||||
const { STATE } = require('./commands/db/econ.js');
|
||||
const replies = require('./commands/Selmer Specific/replies.js');
|
||||
bot.commands.set('econ', temp_command);
|
||||
temp_command = require('./commands/games/game.js');
|
||||
bot.commands.set('game', temp_command);
|
||||
@@ -144,14 +206,18 @@ bot.commands.set('game', temp_command);
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
//#region bot.[anything] section
|
||||
|
||||
//XP Table section
|
||||
let xp_collection = new Map();
|
||||
let items;
|
||||
var botIsReady = bot.inDebugMode;
|
||||
|
||||
bot.on('ready', async () => {
|
||||
const startTime = new Date().getTime();
|
||||
bot.user.setPresence({ activities: [{ name: 'Booting up, please hold!', type: "PLAYING" }], status: 'idle' });
|
||||
|
||||
registerCommands(bot).then(() => {
|
||||
//Make then copy the shop
|
||||
bot.mongoconnection.then(client => {
|
||||
const shop = client.db("main").collection("shop");
|
||||
@@ -160,10 +226,6 @@ bot.on('ready', async () => {
|
||||
|
||||
items = [...itemstemp];
|
||||
});
|
||||
|
||||
//Srt status and Activity (idle and listening to !help)
|
||||
bot.user.setActivity(`${bot.prefix}help`, { type: "LISTENING" });
|
||||
// bot.user.setStatus('idle');
|
||||
});
|
||||
|
||||
//Note the xp numbers are a little wonky on levels 6, 8 and 13 (why though?)
|
||||
@@ -175,7 +237,7 @@ bot.on('ready', async () => {
|
||||
}
|
||||
|
||||
|
||||
//Reaction map area
|
||||
bot.user.setPresence({ activities: [{ name: '/help', type: 'PLAYING' }], status: 'online' });
|
||||
if (!bot.inDebugMode) {
|
||||
console.log('SLEEMER BOT ONLINE!!!!! OH MY GOD OH MY GOD!!!');
|
||||
} else {
|
||||
@@ -187,12 +249,60 @@ bot.on('ready', async () => {
|
||||
let srv = bot.guilds.cache.get(bot.home_server).emojis.cache;
|
||||
emj = srv.find((g) => { return g.name == 'selmer_coin' });
|
||||
bot.currencysymbolmmain = `${emj}`;
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
}).finally(() => {
|
||||
botIsReady = true;
|
||||
console.log(`Setting up Slash Commands took ${(new Date().getTime() - startTime) / 1000} seconds to complete!`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//Button Section
|
||||
bot.on('interactionCreate', async interaction => {
|
||||
const { commandName } = interaction;
|
||||
if (!botIsReady) {
|
||||
return interaction.reply("The bot is still warming up. This is process can take up to 5 minutes. Please try again in a bit! \:(");
|
||||
}
|
||||
// console.log(bot.lockedChannels);
|
||||
//Slash commands
|
||||
if (interaction.isApplicationCommand()) {
|
||||
|
||||
if (interaction.isUserContextMenu()) {
|
||||
return handleContext(bot, interaction.options.data[0]);
|
||||
}
|
||||
|
||||
const logable = ['kick', 'ban', 'unban', 'mute', 'unmute', 'timeout'];
|
||||
const econList = ["buy", 'shop', 'work', 'rank', 'inventory', 'balance', 'sell'];
|
||||
const adminList = ["setpresence", "setactivity"];
|
||||
|
||||
if (commandName == "admin" && adminList.includes(interaction.options.data[0].name)) {
|
||||
if (interaction.user.id == bot.guilds.cache.get(bot.home_server).ownerId) {
|
||||
setPresence(bot, interaction);
|
||||
} else {
|
||||
return interaction.reply({ content: "HAHAHAHAHAHAHAHAHAHAHA\n\nno.", ephemeral: true }).catch((err) => {
|
||||
interaction.channel.send({ content: "HAHAHAHAHAHAHAHAHAHAHA\n\nno.", ephemeral: true });
|
||||
});
|
||||
}
|
||||
} else if (logable.includes(commandName)) {
|
||||
moderation_handler(bot, interaction, commandName);
|
||||
} else if (econList.includes(commandName)) {
|
||||
bot.commands.get('econ').execute(bot, interaction, Discord, mongouri, items, xp_collection);
|
||||
} else if (commandName == 'game') {
|
||||
if (!bot.inDebugMode) { interaction.reply("This command is still in development, use normal text\nEx: _!game tictactoe @opponent_"); }
|
||||
const command = interaction.options.data[0];
|
||||
bot.commands.get('game').execute(bot, interaction, command, Discord, mongouri, items, xp_collection);
|
||||
} else if (commandName == 'setup_embed') {
|
||||
const {generateMsg} = require('./commands/admin/easySetup.js')
|
||||
generateMsg(bot, interaction);
|
||||
} else if (bot.commands.has(commandName)) {
|
||||
bot.commands.get(commandName).execute(interaction, Discord, Client, bot);
|
||||
} else {
|
||||
interaction.reply("Unknown command detected!");
|
||||
}
|
||||
} else {
|
||||
handle_interaction(interaction, mongouri, turnManager, bot, STATE, items, xp_collection);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -210,16 +320,17 @@ bot.on("guildCreate", guild => {
|
||||
|
||||
//const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here');
|
||||
const server = bot.guilds.cache.get(guild.id);
|
||||
const owner = server.members.fetch(guild.ownerId).then(function(owner) {
|
||||
owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Commands_" role and people you want to access set the calendar the "Selmer Bot Calendar" role');
|
||||
owner.send('To help set up Selmer Bot to work better with your server, use _!setup help_ in a channel Selmer Bot is in!');
|
||||
server.members.fetch(guild.ownerId).then(function(owner) {
|
||||
owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Commands_" role and people you want to access set the calendar the "_Selmer Bot Calendar_" role');
|
||||
owner.send('To help set up Selmer Bot to work better with your server, use _/setup help_ in a channel Selmer Bot is in!');
|
||||
});
|
||||
|
||||
//Set up the server
|
||||
bot.mongoconnection.then(client => {
|
||||
|
||||
const dbo = client.db(guild.id).collection('SETUP');
|
||||
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null}, {_id: 'LOG', 'keepLogs': false, 'logchannel': null, 'severity': 0}, {_id: 'announcement', channel: null, role: null}]);
|
||||
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null, 'col': "#FFFFFF"}, {_id: 'LOG', 'keepLogs': false, 'logchannel': null, 'severity': 0},
|
||||
{_id: 'announcement', channel: null, role: null}, {_id: 'roles', commands: ["Selmer Bot Commands"], announcements: "Selmer Bot Calendar"}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -276,29 +387,32 @@ bot.on("guildDelete", guild => {
|
||||
|
||||
//Welcome new members
|
||||
bot.on('guildMemberAdd', async (member) => {
|
||||
if (member.guild.id == bot.home_server && !bot.inDebugMode) { return; }
|
||||
|
||||
//Check for impartial data
|
||||
if(member.partial) await member.fetch();
|
||||
if (member.partial) { member = await member.fetch(); }
|
||||
|
||||
const guild = bot.guilds.cache.get(member.guild.id);
|
||||
|
||||
bot.mongoconnection.then(client => {
|
||||
const dbo = client.db(member.guild.id).collection('SETUP');
|
||||
|
||||
dbo.find({_id: 'WELCOME'}).toArray(async (err, docs) => {
|
||||
dbo.findOne({_id: 'WELCOME'}).then(async (doc) => {
|
||||
if (!doc) { return; }
|
||||
|
||||
var welcomechannel;
|
||||
if (docs[0].welcomechannel == null) {
|
||||
if (doc.welcomechannel == null) {
|
||||
welcomechannel = guild.channels.cache.find(channel => channel.name.toLowerCase() === 'welcome');
|
||||
} else {
|
||||
welcomechannel = guild.channels.cache.get(docs[0].welcomechannel)
|
||||
welcomechannel = guild.channels.cache.get(doc.welcomechannel)
|
||||
}
|
||||
|
||||
if (welcomechannel == null) {
|
||||
return console.log('No welcome channel detected');
|
||||
return; // console.log('No welcome channel detected');
|
||||
}
|
||||
|
||||
await welcome(member, welcomechannel, docs[0].welcomemessage);
|
||||
})
|
||||
await welcome(member, welcomechannel, doc.welcomemessage, doc.welcomebanner, (doc.welcometextcolor) ? doc.welcometextcolor : "#FFFFFF");
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
@@ -320,35 +434,35 @@ bot.on('messageCreate', (message) => {
|
||||
//Special case, testing server (still need the emojis and error logging)
|
||||
if (!bot.inDebugMode && message.guild.id == bot.home_server) { return; }
|
||||
|
||||
//COMMAND AREA
|
||||
//Check if the prefix exists
|
||||
if (!message.content.startsWith(prefix) || message.author.bot) return;
|
||||
if (message.mentions.has(bot.user.id)) {
|
||||
if (message.content == `<@${bot.user.id}>`) {
|
||||
return message.reply("What?");
|
||||
} else {
|
||||
return replies(bot, message);
|
||||
}
|
||||
}
|
||||
|
||||
//Check if the prefix exists
|
||||
if (message.author.bot) { return; }
|
||||
|
||||
if (message.content.startsWith(prefix)) {
|
||||
//Game section (too complicated to move to Slash Commands)
|
||||
//Note: Slash commands do not register as valid replies
|
||||
const args = message.content.slice(prefix.length).split(' ');
|
||||
const command = args.shift().toLowerCase();
|
||||
|
||||
//Log logable commands then execute them
|
||||
const logable = ['kick', 'ban', 'unban', 'mute', 'unmute', 'timeout'];
|
||||
if (logable.includes(command)) {
|
||||
moderation_handler(bot, message, args, command);
|
||||
}
|
||||
|
||||
//Performes the command
|
||||
//Admin section
|
||||
else if (command == 'reactionrole') { bot.commands.get(command).execute(message, args, Discord, bot); }
|
||||
|
||||
else if(bot.commands.has(command) && command != 'ECON') {
|
||||
//Database access is required, change the inputs
|
||||
if (command == 'game' || command == 'accept' || command == 'setup') {
|
||||
if (command == 'game' || command == 'accept') {
|
||||
bot.commands.get(command).execute(bot, message, args, command, Discord, mongouri, items, xp_collection);
|
||||
} else if (command == 'rss' && bot.inDebugMode) {
|
||||
const rss = require('./side projects/RSSHandlers/rssFeed.js');
|
||||
rss.execute(message, args, Discord, client, bot);
|
||||
} else {
|
||||
bot.commands.get(command).execute(message, args, Discord, Client, bot);
|
||||
textToLevels(bot, message, xp_collection);
|
||||
}
|
||||
} else {
|
||||
//Use for the leveling-by-interaction system
|
||||
textToLevels(bot, message, xp_collection);
|
||||
}
|
||||
|
||||
//Econ and also the catch statement
|
||||
else { bot.commands.get('econ').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); }
|
||||
})
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
Generated
+1514
-615
File diff suppressed because it is too large
Load Diff
+9
-5
@@ -2,17 +2,16 @@
|
||||
"dependencies": {
|
||||
"@alpacahq/alpaca-trade-api": "^2.16.1",
|
||||
"@discordjs/opus": "github:discordjs/opus",
|
||||
"@discordjs/rest": "^1.0.1",
|
||||
"@discordjs/rest": "^1.1.0",
|
||||
"@discordjs/voice": "^0.8.0",
|
||||
"@napi-rs/canvas": "^0.1.22",
|
||||
"apt": "^0.0.2",
|
||||
"arraybuffer-to-buffer": "^0.0.7",
|
||||
"axios": "^0.27.2",
|
||||
"body-parser": "^1.20.0",
|
||||
"canvas": "^2.9.3",
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"coingecko-api": "^1.0.10",
|
||||
"cors": "^2.8.5",
|
||||
"cozy-ical": "^1.1.22",
|
||||
"date-fns": "^2.29.2",
|
||||
"date-fns-timezone": "^0.1.4",
|
||||
"discord-reply": "^0.1.2",
|
||||
@@ -22,22 +21,24 @@
|
||||
"feedparser": "^2.2.10",
|
||||
"ffmpeg": "^0.0.4",
|
||||
"ffmpeg-static": "^5.0.0",
|
||||
"googleapis": "^107.0.0",
|
||||
"hastebin-gen": "^2.0.5",
|
||||
"html-entities": "^2.3.3",
|
||||
"libsodium-wrappers": "^0.7.10",
|
||||
"mal-scraper": "^2.11.4",
|
||||
"mongoose": "^6.3.2",
|
||||
"mysql": "^2.18.1",
|
||||
"node-fetch": "^2.6.7",
|
||||
"node.js": "^0.0.1-security",
|
||||
"npm": "^8.13.2",
|
||||
"openai": "^3.0.0",
|
||||
"play-dl": "^1.9.4",
|
||||
"pusher": "^5.1.1-beta",
|
||||
"random-memes": "^3.1.0",
|
||||
"request": "^2.88.2",
|
||||
"robinhood": "^1.8.0",
|
||||
"rss-parser": "^3.12.0",
|
||||
"sequelize": "^6.19.0",
|
||||
"sharp": "^0.31.1",
|
||||
"sqlite3": "^5.0.3",
|
||||
"stripe": "^9.11.0",
|
||||
"sudo": "^1.0.3",
|
||||
@@ -62,5 +63,8 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/ION606/selmerBot/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ION606/selmerBot#readme"
|
||||
"homepage": "https://github.com/ION606/selmerBot#readme",
|
||||
"devDependencies": {
|
||||
"@types/node-fetch": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
const {Client, Constants} = require('discord.js');
|
||||
|
||||
/**
|
||||
* Registers all slash commands
|
||||
* @param {Client} bot
|
||||
*/
|
||||
function registerCommands(bot) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const commands = bot.application.commands;
|
||||
|
||||
/*
|
||||
val: {
|
||||
name: 'code',
|
||||
description: "See where Selmer bot's code is stored! (you can also use _!repo_)",
|
||||
execute: [Function: execute]
|
||||
},
|
||||
|
||||
key: code
|
||||
*/
|
||||
|
||||
//#region Slash Commands
|
||||
bot.commands.forEach((val, key) => {
|
||||
if ((val.options && val.name != 'econ') || val.isDm) {
|
||||
if (val.isDm) {
|
||||
commands.create({
|
||||
name: val.name,
|
||||
description: val.description,
|
||||
options: val.options,
|
||||
dm_permission: true,
|
||||
});
|
||||
} else {
|
||||
commands.create({
|
||||
name: val.name,
|
||||
description: val.description,
|
||||
options: val.options,
|
||||
dm_permission: false,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// console.log(val, key);
|
||||
console.log(key);
|
||||
}
|
||||
});
|
||||
|
||||
//Create the "econ" commands
|
||||
const econList = ["buy", 'shop', 'work', 'rank', 'inventory', 'balance', 'sell'];
|
||||
const econMain = require('./commands/db/econSlashOptions.js');
|
||||
|
||||
econList.forEach((commandName) => {
|
||||
const command = econMain[`${commandName}`];
|
||||
commands.create({
|
||||
name: commandName,
|
||||
description: command.description,
|
||||
options: command.options || [],
|
||||
dm_permission: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//Create the moderation commands
|
||||
//NOTE: The user needs to have kicking or banning permissions to use these
|
||||
const modList = ['lock', 'unlock', 'kick', 'ban', 'unban', 'mute', 'unmute'];
|
||||
for (let i = 0; i < modList.length; i++) {
|
||||
const opts = [
|
||||
{name: "user", description: `The user to ${modList[i]}`, type: Constants.ApplicationCommandOptionTypes.USER, required: true},
|
||||
{name: "reason", description: "Why?", type: Constants.ApplicationCommandOptionTypes.STRING, required: false}
|
||||
];
|
||||
|
||||
commands.create({
|
||||
name: modList[i],
|
||||
description: `${modList[i]} a user`,
|
||||
options: opts,
|
||||
dm_permission: false,
|
||||
default_member_permissions: 6,
|
||||
});
|
||||
|
||||
// .then((comm) => {
|
||||
// comm.setDefaultMemberPermissions(Discord.PermissionFlagsBits.KickMembers | Discord.PermissionFlagsBits.BanMembers);
|
||||
// });
|
||||
}
|
||||
|
||||
//Admin commands (Home Server only)
|
||||
const guild = bot.guilds.cache.get(bot.home_server);
|
||||
guild.commands.create({
|
||||
name: "admin",
|
||||
description: "admin commands",
|
||||
// type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND_GROUP,
|
||||
options: [
|
||||
{
|
||||
name: "setpresence",
|
||||
description: "Change the bot's presence",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: "pres_text", description: "The new presence text", type: Constants.ApplicationCommandOptionTypes.STRING, required: true },
|
||||
{name: "type", description: "The new presence text", type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [
|
||||
{name: "LISTENING", value: "LISTENING"}, {name: "WATCHING", value: "WATCHING"}, {name: "COMPETING", value: "COMPETING"}, {name: "PLAYING", value: "PLAYING"}, { name: "STREAMING", value: "STREAMING"}
|
||||
]},
|
||||
{name: 'display_name', description: "What to display instead of the stream's title", type: Constants.ApplicationCommandOptionTypes.STRING, required: false}
|
||||
],
|
||||
dm_permission: false
|
||||
},
|
||||
{
|
||||
name: "setactivity",
|
||||
description: "Change the bot's activity",
|
||||
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
|
||||
options: [
|
||||
{name: "type", description: "The new presence text", type: Constants.ApplicationCommandOptionTypes.STRING, required: true, choices: [
|
||||
{name: "Do Not Disturb", value: "dnd"}, {name: "Idle", value: "idle"}, {name: "invisible", value: "invisible"}, {name: "online", value: "online"}
|
||||
]},
|
||||
],
|
||||
dm_permission: false
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
//Takes much longer, so it'll be the benchmark for when the Promise resolves
|
||||
//#region GAMES
|
||||
const gameOpts = require('./commands/games/gameCommandOptions.js');
|
||||
commands.create({
|
||||
name: 'game',
|
||||
description: 'Play one of Selmer Bot\'s games!', //NOT APPLICABLE USING SUB COMMAND GROUPS???
|
||||
// type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND_GROUP,
|
||||
options: gameOpts,
|
||||
dm_permission: false
|
||||
}).then(() => {
|
||||
if (!bot.inDebugMode) { return resolve(true); }
|
||||
|
||||
commands.create({
|
||||
name: 'setup_embed',
|
||||
description: 'Create a row of buttons for easier setup',
|
||||
options: []
|
||||
});
|
||||
|
||||
//#region Context Menus
|
||||
commands.create({
|
||||
name: "Temp",
|
||||
type: 'USER'
|
||||
}).then(() => { resolve(true); });
|
||||
|
||||
//#endregion
|
||||
}).catch((err) => { reject(err); });
|
||||
|
||||
//#endregion
|
||||
//#endregion
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = { registerCommands }
|
||||
@@ -5,7 +5,7 @@ var FeedParser = require('feedparser');
|
||||
const fetch = require('node-fetch');
|
||||
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType, joinVoiceChannel, createAudioResource, getVoiceConnection } = require('@discordjs/voice');
|
||||
const play = require('play-dl');
|
||||
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||
const { addComplaintButton } = require('../../commands/dev only/spam_collection.js');
|
||||
|
||||
const hastebin = require("hastebin-gen");
|
||||
const { simpleCast } = require('./simplecast.js')
|
||||
@@ -137,11 +137,12 @@ function playAudio(bot, message, user, obj) {
|
||||
|
||||
async function getAndFormatRSS(bot, message, user, inp) {
|
||||
|
||||
message.reply(inp).catch((err) => { message.channel.send(inp); console.error(err); });
|
||||
|
||||
var req = fetch(inp)
|
||||
const feedparser = new FeedParser();
|
||||
|
||||
req.then(function (res) {
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error('Bad status code');
|
||||
}
|
||||
@@ -172,14 +173,15 @@ async function getAndFormatRSS(bot, message, user, inp) {
|
||||
i ++;
|
||||
if (i >= 100) { break; }
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
feedparser.addListener('end', () => {
|
||||
const item = items[Math.round(Math.random() * items.length)];
|
||||
|
||||
// return console.log(item);
|
||||
if (inp.indexOf('simplecast') != -1) {
|
||||
var s = new simpleCast(item, inp);
|
||||
s.audioLink = 'https://download.samplelib.com/mp3/sample-15s.mp3';
|
||||
|
||||
// s.audioLink = 'https://download.samplelib.com/mp3/sample-15s.mp3';
|
||||
playAudio(bot, message, user, s);
|
||||
}
|
||||
});
|
||||
@@ -314,9 +316,7 @@ module.exports = {
|
||||
|
||||
|
||||
/*
|
||||
REMOVED
|
||||
"ABC": "https://abcnews.go.com/abcnews/topstories"
|
||||
"FBI": "https://www.fbi.gov/feeds/national-press-releases/rss.xml" (Uhhhh......maybe I should't use this one.....)
|
||||
|
||||
|
||||
REMOVED
|
||||
"ABC": "https://abcnews.go.com/abcnews/topstories"
|
||||
"FBI": "https://www.fbi.gov/feeds/national-press-releases/rss.xml" (Uhhhh......maybe I should't use this one.....)
|
||||
*/
|
||||
Reference in New Issue
Block a user