diff --git a/commands/Fun/react.js b/commands/Fun/react.js new file mode 100644 index 0000000..437f414 --- /dev/null +++ b/commands/Fun/react.js @@ -0,0 +1,160 @@ +const discordEmoji = require('discord-emoji'); +const emoji = {}; + +Object.values(discordEmoji).forEach(value => { + Object.keys(value).forEach(key => { + emoji[key] = value[key]; + }); +}); + +const mappings = { + 'a': [':regional_indicator_a:', ':a:'], + 'b': [':regional_indicator_b:', ':b:'], + 'c': [':regional_indicator_c:'], + 'd': [':regional_indicator_d:'], + 'e': [':regional_indicator_e:'], + 'f': [':regional_indicator_f:'], + 'g': [':regional_indicator_g:', ':compression:'], + 'h': [':regional_indicator_h:'], + 'i': [':regional_indicator_i:', ':information_source:'], + 'j': [':regional_indicator_j:'], + 'k': [':regional_indicator_k:'], + 'l': [':regional_indicator_l:'], + 'm': [':regional_indicator_m:', ':m:'], + 'n': [':regional_indicator_n:'], + 'o': [':regional_indicator_o:', ':o2:', ':o:'], + 'p': [':regional_indicator_p:', ':parking:'], + 'q': [':regional_indicator_q:'], + 'r': [':regional_indicator_r:'], + 's': [':regional_indicator_s:'], + 't': [':regional_indicator_t:', ':cross:'], + 'u': [':regional_indicator_u:'], + 'v': [':regional_indicator_v:'], + 'w': [':regional_indicator_w:'], + 'x': [':regional_indicator_x:', ':heavy_multiplication_x:', ':x:', ':negative_squared_cross_mark:'], + 'y': [':regional_indicator_y:'], + 'z': [':regional_indicator_z:'], + '0': [':zero:'], + '1': [':one:'], + '2': [':two:'], + '3': [':three:'], + '4': [':four:'], + '5': [':five:'], + '6': [':six:'], + '7': [':seven:'], + '8': [':eight:'], + '9': [':nine:'], + '!': [':exclamation:', ':grey_exclamation:'], + '?': [':question:', ':grey_question:'], + '*': [':asterisk:', ':eight_spoked_asterisk:'], + '#': [':hash:'], + '$': [':heavy_dollar_sign:'] +}; + +function clone(object) { + const newObject = {}; + + Object.keys(object).forEach(key => { + if (object[key] instanceof Array) { + newObject[key] = new Array(...object[key]); + } else { + newObject[key] = object[key]; + } + }); + + return newObject; +} + +function emojiToUnicode(input) { + if (/^:regional_indicator_[a-z]:$/.test(input)) { + return String.fromCharCode(55356) + String.fromCharCode(56806 + input.substr(20, 1).charCodeAt(0) - 97); + } + return emoji[input.slice(1, -1)]; +} + +function react(message, remaining, allowedMappings) { + if (remaining.length < 1) { + // We're out of stuff + return; + } + + const char = remaining.shift().toLowerCase(); + + if (!char) { + return; + } + + if (!allowedMappings[char]) { + // Not a usable char + return; + } + + const next = allowedMappings[char].shift(); + if (!next) { + // We have no more mappings available + return; + } + + message.react(emojiToUnicode(next)).then(() => { + react(message, remaining, allowedMappings); + }); +} + +exports.run = async (client, message, args, level) => { + if (args.length < 1) { + await message.reply("you should actually try to tell me what I should react with...") + message.delete(); + client.user.lastMessage.delete(5000); + } + + const fetchOptions = { limit: 1 }; + if (args[1]) { + if (!/\d{18}/.test(args[1])) { + await message.reply(`${args[1]} isn't a valid message ID!`); + message.delete(); + client.user.lastMessage.delete(5000); + } + + fetchOptions.around = args[1]; + } else { + fetchOptions.before = message.id; + } + + message.channel.fetchMessages(fetchOptions).then(messages => { + if (messages.length < 1) { + return message.reply("I couldn't find the specified message."); + } + + const target = messages.first(); + const allowedMappings = clone(mappings); + + // Remove current reactions from allowed emojis + target.reactions.forEach(reaction => { + const emoji = reaction.toString(); + for (const key in allowedMappings) { + const index = allowedMappings[key].indexOf(emoji); + if (index > -1) { + allowedMappings[key].splice(index, 1); + } + } + }); + + message.delete(); + + react(target, args[0].split(''), allowedMappings); + }).catch(message.error); +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: [], + permLevel: "User" +}; + +exports.help = { + name: "react", + category: "Fun", + description: "Reacts to the last sent message (or another message) with a given text; your response cannot contain spaces.", + usage: "react [message ID]" +}; \ No newline at end of file