diff --git a/.gitignore b/.gitignore index 12bb89f..3cb8b87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules config.json +backup.json *.env *.sqlite *.txt diff --git a/commands/Selmer Specific/EC.js b/commands/Selmer Specific/EC.js index 71837bf..207f060 100644 --- a/commands/Selmer Specific/EC.js +++ b/commands/Selmer Specific/EC.js @@ -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: [] } \ No newline at end of file diff --git a/commands/Selmer Specific/arrow.js b/commands/Selmer Specific/arrow.js index 67c7c07..50dd656 100644 --- a/commands/Selmer Specific/arrow.js +++ b/commands/Selmer Specific/arrow.js @@ -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); - }); - arrow = arrow + 'đŸ—‘ī¸'; - message.channel.send(arrow); - break; - } + await interaction.reply(arrow); + for (let i = 0; i < 5; i++) { + arrow = '-' + arrow + await interaction.editReply(arrow); } - } + + arrow = arrow + 'đŸ—‘ī¸'; + await interaction.editReply(arrow); + }, options: [] } \ No newline at end of file diff --git a/commands/Selmer Specific/postProfile.js b/commands/Selmer Specific/postProfile.js index 177ca53..c4f0886 100644 --- a/commands/Selmer Specific/postProfile.js +++ b/commands/Selmer Specific/postProfile.js @@ -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: [] } \ No newline at end of file diff --git a/commands/Selmer Specific/quotes.js b/commands/Selmer Specific/quotes.js index 2982c02..7a21aed 100644 --- a/commands/Selmer Specific/quotes.js +++ b/commands/Selmer Specific/quotes.js @@ -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: [] } \ No newline at end of file diff --git a/commands/Selmer Specific/repo.js b/commands/Selmer Specific/repo.js index 9504ede..6d01be0 100644 --- a/commands/Selmer Specific/repo.js +++ b/commands/Selmer Specific/repo.js @@ -1,9 +1,9 @@ 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() }) .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') @@ -27,6 +27,6 @@ module.exports = { .setCustomId("sbtutorial") ]); - message.reply({ embeds: [embd], components: [row] }) - } + interaction.reply({ embeds: [embd], components: [row] }); + }, options: [] } \ No newline at end of file diff --git a/commands/Selmer Specific/intro.js b/commands/Selmer Specific/tuto.js similarity index 59% rename from commands/Selmer Specific/intro.js rename to commands/Selmer Specific/tuto.js index 7c4c457..5367451 100644 --- a/commands/Selmer Specific/intro.js +++ b/commands/Selmer Specific/tuto.js @@ -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__***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 (_www.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 @@ -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: [] } \ No newline at end of file diff --git a/commands/admin/backupBot.js b/commands/admin/backupBot.js new file mode 100644 index 0000000..437cd95 --- /dev/null +++ b/commands/admin/backupBot.js @@ -0,0 +1,63 @@ +const fs = require('fs'); +const {Buffer} = require('buffer'); + +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); + } +} + + +async function loadBotBackups(bot, IDM) { + try { + if (IDM) { + const botBackups = require('./backup.json').backups; + bot.lockedChannels = objToMap(botBackups.locked); + } else { + bot.lockedChannels = objToMap(JSON.parse(botBackups.locked)); + } + } catch (err) { + console.error(err); + bot.lockedChannels = new Map(); + const a = new Map(); + } +} + + +module.exports = { backupLists, loadBotBackups } \ No newline at end of file diff --git a/commands/admin/lockchannel.js b/commands/admin/lockchannel.js index a4faae8..472052f 100644 --- a/commands/admin/lockchannel.js +++ b/commands/admin/lockchannel.js @@ -1,28 +1,31 @@ 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!'); } + if (!checkRole(bot, guild, interaction.user.id)) { 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}] } \ No newline at end of file diff --git a/commands/admin/moderation.js b/commands/admin/moderation.js index c6ac914..2dfad25 100644 --- a/commands/admin/moderation.js +++ b/commands/admin/moderation.js @@ -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,29 +52,29 @@ 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!"); } } /* NOTE: use the following function for a "time out" type thing? setTimeout(() => { target.roles.remove(mutedRole); // remove the role - },