diff --git a/dist/api.js b/dist/api.js index fec131a..24d257d 100644 --- a/dist/api.js +++ b/dist/api.js @@ -23,6 +23,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlayerInteraction = exports.getPlayer = void 0; +/*eslint prefer-const: "error"*/ const cheerio = __importStar(require("cheerio")); const discord_js_1 = require("discord.js"); const https_1 = __importDefault(require("https")); @@ -73,25 +74,25 @@ function getHTML(name) { * @throws errorMessage class if the request fails */ function readHTML(html) { - let $ = cheerio.load(html); - let metaElems = $('meta').toArray(), foundData = { - name: "", - id: "", - avatar: "", - level: "", - rank: "", + const $ = cheerio.load(html), foundData = { + name: '', + id: '', + avatar: '', + level: '', + rank: '', elo: null, class: null, - battles: "", - wins: "", - winrate: "" + battles: '', + wins: '', + winrate: '' }; + let metaElems = $('meta').toArray(); //filter down to just ones named "og:..." metaElems = metaElems.filter(el => el.attribs.property?.startsWith('og:')); metaElems.forEach(el => { - let attr = el.attribs; + const attr = el.attribs; if (attr.property === 'og:title') { - let data = uniteApiRegex.ogtitle.exec(attr.content); + const data = uniteApiRegex.ogtitle.exec(attr.content); if (data !== null && data.length >= 3) { foundData.name = data[1]; foundData.id = data[2]; @@ -99,14 +100,15 @@ function readHTML(html) { } else if (attr.property === 'og:description') { //all lines - let lines = attr.content.split('\n').map(l => l.trim()), extraLines = []; + let lines = attr.content.split('\n').map(l => l.trim()); + const extraLines = []; //ensure first line is correct - while (lines.length && !/pok.mon unite/i.test(lines[0])) { - let line = lines.shift(); - if (line) + while ((lines.length > 0) && !/pok.mon unite/i.test(lines[0])) { + const line = lines.shift(); + if (line !== undefined) extraLines.push(line); } - if (!lines.length) + if (lines.length === 0) throw (0, util_1.emsg)('Unable to read data, please try again'); //bring the first lines removed back into the data lines = [ @@ -116,10 +118,9 @@ function readHTML(html) { //first line { //will be only text after "pokemon unite:" - let line = lines[0].split(':').slice(1).join(':').trim(); - let regex = uniteApiRegex.ogdescription; + const line = lines[0].split(':').slice(1).join(':').trim(), regex = uniteApiRegex.ogdescription; if (regex[0].test(line)) { //is master/has elo - let regexData = line.match(regex[0]); + const regexData = line.match(regex[0]); if (!regexData || regexData.length < 4) throw (0, util_1.emsg)('Unable to read data, please try again'); foundData.level = regexData[1]; @@ -127,7 +128,7 @@ function readHTML(html) { foundData.elo = regexData[3]; } else { //is not master/has a class - let regexData = line.match(regex[1]); + const regexData = line.match(regex[1]); if (!regexData || regexData.length < 4) throw (0, util_1.emsg)('Unable to read data, please try again'); foundData.level = regexData[1]; @@ -138,7 +139,7 @@ function readHTML(html) { lines.shift(); //rest of lines lines.forEach(line => { - let split = line.split(':').map(l => l.trim()), key = split[0].toLowerCase().replace(/[^\w]/g, ''), value = split[1]; + const split = line.split(':').map(l => l.trim()), key = split[0].toLowerCase().replace(/[^\w]/g, ''), value = split[1]; switch (key) { case 'battles': foundData.battles = value; @@ -153,7 +154,8 @@ function readHTML(html) { }); } }); - foundData.avatar = $('.player-card-image img').attr('src') || ""; + const imgSrc = $('.player-card-image img').attr('src'); + foundData.avatar = imgSrc !== undefined ? imgSrc : ''; foundData.avatar = foundData.avatar.replace('../', 'https://uniteapi.dev/'); return foundData; } @@ -163,7 +165,7 @@ function readHTML(html) { * @returns boolean, valid or invalid */ function verifyData(data) { - if (data.id.length) + if (data.id.length > 0) return true; return false; } @@ -173,21 +175,25 @@ function verifyData(data) { * @returns player data */ async function getPlayer(name) { - let html = await getHTML(name); - let data = readHTML(html); + const html = await getHTML(name), data = readHTML(html); if (verifyData(data)) return data; return null; } exports.getPlayer = getPlayer; async function sendPlayerEmbed(interaction, data) { - let embed = new discord_js_1.MessageEmbed() + let eloStr; + if (data.elo !== null) + eloStr = `(${data.elo})`; + else + eloStr = `Class ${data.class}`; + const embed = new discord_js_1.MessageEmbed() .setTitle(`${data.name} (${data.id})`) .setURL(`https://uniteapi.dev/p/${encodeURIComponent(data.name)}`) .setTimestamp() .setThumbnail(data.avatar) .setDescription(`Level ${data.level} -${data.rank} ${data.elo ? `(${data.elo})` : `Class ${data.class}`} +${data.rank} ${eloStr} **Battles** ${data.battles} **Wins** ${data.wins} @@ -200,9 +206,9 @@ ${data.rank} ${data.elo ? `(${data.elo})` : `Class ${data.class}`} * @throws errorMessage class if the user cannot be found */ async function getPlayerInteraction(interaction) { - let username = interaction.options.getString('username', true); + const username = interaction.options.getString('username', true); await interaction.deferReply(); - let data = await getPlayer(username); + const data = await getPlayer(username); if (data === null) throw (0, util_1.emsg)('api.noUser'); else diff --git a/dist/discord.js b/dist/discord.js index 1480287..0081670 100644 --- a/dist/discord.js +++ b/dist/discord.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerCommands = void 0; +/* eslint-disable camelcase */ const rest_1 = require("@discordjs/rest"); const v9_1 = require("discord-api-types/v9"); // list of commands to register with discord @@ -46,7 +47,8 @@ const commands = [ } ] } -], commandNames = commands.map(c => c.name); +]; +/*commandNames = commands.map(c => c.name);*/ /** * register/reload commands on guild(s) * @param token discord bot token diff --git a/dist/index.js b/dist/index.js index ac6f00e..21d8c53 100644 --- a/dist/index.js +++ b/dist/index.js @@ -23,7 +23,7 @@ const discord_js_1 = require("discord.js"); const fs = __importStar(require("fs")); const api_1 = require("./api"); const discord_1 = require("./discord"); -const lang_1 = require("./lang"); +const Lang = __importStar(require("./lang")); const queue_1 = require("./queue"); const util_1 = require("./util"); const CLIENT = new discord_js_1.Client({ intents: [discord_js_1.Intents.FLAGS.GUILDS] }); @@ -32,13 +32,13 @@ console.log(new Date().toISOString() + '\n\n'); //get token if (!fs.existsSync('./token.txt')) { fs.writeFileSync('./token.txt', ''); - console.error(lang_1.Lang.get('error.main.missingToken')); + console.error(Lang.get('error.main.missingToken')); process.exit(1); } const TOKEN = fs.readFileSync('./token.txt').toString(); //discord connections CLIENT.on('ready', client => { - console.log(lang_1.Lang.get('main.login', { + console.log(Lang.get('main.login', { user: client.user.tag })); client.guilds.fetch().then(guilds => (0, discord_1.registerCommands)(TOKEN, client.user.id, guilds.map(g => g.id))); diff --git a/dist/lang.js b/dist/lang.js index 007adbf..e783d70 100644 --- a/dist/lang.js +++ b/dist/lang.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Lang = void 0; +exports.get = exports.setLang = void 0; const LANG = { en: { main: { @@ -20,7 +20,7 @@ const LANG = { discord: { noQueue: 'There is not an active queue in this channel, type `/open` to create one', noChannel: 'Unable to find channel {channelId} for teams of {teamsize}', - noCreate: 'There is already an active queue in this channel for teams of ${teamsize}', + noCreate: 'There is already an active queue in this channel for teams of {teamsize}', inQueue: 'You are already in the queue', notInQueue: 'You aren\'t in the queue', notMod: 'Member is not a moderator' @@ -35,45 +35,42 @@ const LANG = { } } }; -var Lang; -(function (Lang) { - var LANGID = 'en'; - if (!(LANGID in LANG)) +let LANGID = 'en'; +if (!(LANGID in LANG)) + throw 'language id does not exist'; +function setLang(langid) { + if (langid in LANG) + LANGID = langid; + else throw 'language id does not exist'; - function setLang(langid) { - if (langid in LANG) - LANGID = langid; - else - throw 'language id does not exist'; - } - Lang.setLang = setLang; - function template(str, args) { - return str.replace(/{\w+}/g, str => { - let key = str.substring(1, str.length - 1); - if (key in args) - return args[key]; - return key; - }); - } - /** - * reads language json - * @param id ex: discord.error.noActiveQueue - * @returns language value, defaults to `id` parameter - */ - function get(id, args = {}) { - let keySpl = id.split('.').map(k => k.trim()).filter(k => k); - let finding = LANG[LANGID]; - for (let key of keySpl) { - if (key in finding) { - let found = finding[key]; - if (typeof found === 'string') - return template(found, args); - finding = found; - } - else - break; +} +exports.setLang = setLang; +function template(str, args) { + return str.replace(/{\w+}/g, str => { + const key = str.substring(1, str.length - 1); + if (key in args) + return args[key]; + return key; + }); +} +/** + * reads language json + * @param id ex: discord.error.noActiveQueue + * @returns language value, defaults to `id` parameter + */ +function get(id, args = {}) { + const keySpl = id.split('.').map(k => k.trim()).filter(k => k); + let finding = LANG[LANGID]; + for (const key of keySpl) { + if (key in finding) { + const found = finding[key]; + if (typeof found === 'string') + return template(found, args); + finding = found; } - return id; + else + break; } - Lang.get = get; -})(Lang = exports.Lang || (exports.Lang = {})); + return id; +} +exports.get = get; diff --git a/dist/queue.js b/dist/queue.js index 7e482e8..c390640 100644 --- a/dist/queue.js +++ b/dist/queue.js @@ -23,210 +23,187 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.QueueCommands = exports.discordInit = void 0; +exports.QueueCommands = exports.queueContains = exports.discordInit = exports.queueRemove = exports.queueCreate = void 0; const discord_js_1 = require("discord.js"); const fs = __importStar(require("fs")); const util_1 = require("./util"); -const lang_1 = require("./lang"); +const Lang = __importStar(require("./lang")); //load queues from file if (!fs.existsSync('./queues.json')) fs.writeFileSync('./queues.json', '{}'); const _QUEUE = fs.readFileSync('./queues.json').toString(), QUEUE = new Map(); try { - let queueJson = JSON.parse(_QUEUE); - for (let channelId in queueJson) { - let { teamsize } = queueJson[channelId]; - if (teamsize) + const queueJson = JSON.parse(_QUEUE); + for (const channelId in queueJson) { + const { teamsize } = queueJson[channelId]; + if (teamsize !== 0) QUEUE.set(channelId, { teamsize, players: [] }); } } -catch (e) { } +catch (e) { + //do nothing +} function SaveQueue() { - let queueJson = Object.fromEntries(QUEUE), queueFileJson = {}; - for (let channelId of QUEUE.keys()) + const queueJson = Object.fromEntries(QUEUE), queueFileJson = {}; + for (const channelId of QUEUE.keys()) queueFileJson[channelId] = { teamsize: queueJson[channelId].teamsize }; fs.writeFileSync('./queues.json', JSON.stringify(queueFileJson, null, 2)); } async function checkQueue(channel) { - let info = QUEUE.get(channel.id); + const info = QUEUE.get(channel.id); if (!info) return; if (info.players.length >= info.teamsize) { - let team = info.players.splice(0, info.teamsize).map(m => m.toString()); + const team = info.players.splice(0, info.teamsize).map(m => m.toString()); //TODO add embeds to lang.ts - let embed = new discord_js_1.MessageEmbed() + const embed = new discord_js_1.MessageEmbed() .setTitle('Team') .setDescription(team.join('\n')); await channel.send({ embeds: [embed] }); } } -var Queue; -(function (Queue) { - function create(channelId, teamsize) { - if (!QUEUE.has(channelId)) { - QUEUE.set(channelId, { teamsize, players: [] }); - SaveQueue(); - } +function queueCreate(channelId, teamsize) { + if (!QUEUE.has(channelId)) { + QUEUE.set(channelId, { teamsize, players: [] }); + SaveQueue(); } - Queue.create = create; - function remove(channelId) { - if (QUEUE.has(channelId)) { - QUEUE.delete(channelId); - SaveQueue(); - } +} +exports.queueCreate = queueCreate; +function queueRemove(channelId) { + if (QUEUE.has(channelId)) { + QUEUE.delete(channelId); + SaveQueue(); } - Queue.remove = remove; - function addPlayer(channelId, member) { - if (QUEUE.has(channelId)) { - QUEUE.delete(channelId); - } - } - Queue.addPlayer = addPlayer; - function removePlayer(channelId, member) { - if (QUEUE.has(channelId)) { - QUEUE.delete(channelId); - } - } - Queue.removePlayer = removePlayer; -})(Queue || (Queue = {})); +} +exports.queueRemove = queueRemove; SaveQueue(); async function discordInit(client) { - for (let channelId of QUEUE.keys()) { - let info = QUEUE.get(channelId), channel = await client.channels.fetch(channelId); + for (const channelId of QUEUE.keys()) { + const info = QUEUE.get(channelId), channel = await client.channels.fetch(channelId); if (!info) { //no idea what could cause this but TS complains - Queue.remove(channelId); + queueRemove(channelId); continue; } if (!channel || !(channel instanceof discord_js_1.TextChannel)) { - console.error(lang_1.Lang.get('error.discord.noChannel'), { + console.error(Lang.get('error.discord.noChannel'), { channelId, teamsize: info.teamsize }); - Queue.remove(channelId); + queueRemove(channelId); continue; } - channel.send(lang_1.Lang.get('discord.botRestart')); + channel.send(Lang.get('discord.botRestart')); } } exports.discordInit = discordInit; -var QueueCommands; -(function (QueueCommands) { - /** - * get the queueInfo of an interaction - * @param interaction - * @throws errorMessage class if it does not exist - * @returns queue info - */ - function getInfo(interaction) { - let info = QUEUE.get(interaction.channelId); - if (!info) - throw (0, util_1.emsg)('discord.noQueue'); - return info; - } - /** - * compiles all the get functions above - * @param interaction - * @throws if another get function throws - * @returns object containing each - */ - const getAll = (interaction) => ({ - member: (0, util_1.getMember)(interaction), - channel: (0, util_1.getChannel)(interaction), - info: getInfo(interaction) - }); - /** - * checks if the interaction data is already in the queue - * @param interaction - * @returns boolean - */ - function queueContains(interaction) { - let { member, info } = getAll(interaction); - if (info.players.map(m => m.id).includes(member.id)) - return true; - return false; - } - QueueCommands.queueContains = queueContains; - /** - * creates a queue from an interaction - * @param interaction - * @throws errorMessage class if it cannot be left - */ - function queueCreate(interaction) { - (0, util_1.memberIsModThrow)(interaction); - let { channelId } = interaction, teamsize = interaction.options.getInteger('teamsize', true); - let existing = QUEUE.get(channelId); - if (existing) - throw (0, util_1.emsg)(lang_1.Lang.get('error.discord.noCreate', { - teamsize: existing.teamsize.toString() - })); - Queue.create(channelId, teamsize); - interaction.reply(lang_1.Lang.get('discord.create', { - teamsize: teamsize.toString() +/** + * get the queueInfo of an interaction + * @param interaction + * @throws errorMessage class if it does not exist + * @returns queue info + */ +function getInfo(interaction) { + const info = QUEUE.get(interaction.channelId); + if (!info) + throw (0, util_1.emsg)('discord.noQueue'); + return info; +} +/** + * compiles all the get functions above + * @param interaction + * @throws if another get function throws + * @returns object containing each + */ +const getAll = (interaction) => ({ + member: (0, util_1.getMember)(interaction), + channel: (0, util_1.getChannel)(interaction), + info: getInfo(interaction) +}); +/** + * checks if the interaction data is already in the queue + * @param interaction + * @returns boolean + */ +function queueContains(interaction) { + const { member, info } = getAll(interaction); + if (info.players.map(m => m.id).includes(member.id)) + return true; + return false; +} +exports.queueContains = queueContains; +/** + * opens a queue + * @param interaction + * @throws errorMessage class if it cannot be left + */ +function open(interaction) { + (0, util_1.memberIsModThrow)(interaction); + const { channelId } = interaction, teamsize = interaction.options.getInteger('teamsize', true); + const existing = QUEUE.get(channelId); + if (existing) + throw (0, util_1.emsg)(Lang.get('error.discord.noCreate', { + teamsize: existing.teamsize.toString() })); - } - QueueCommands.queueCreate = queueCreate; - /** - * opens a queue - * @param interaction - * @throws errorMessage class if it cannot be left - */ - async function open(interaction) { - queueCreate(interaction); - } - QueueCommands.open = open; - /** - * closes a queue - * @param interaction - * @throws errorMessage class if it cannot be joined - */ - async function close(interaction) { - (0, util_1.memberIsModThrow)(interaction); - QUEUE.delete(interaction.channelId); - await interaction.reply(lang_1.Lang.get('discord.close')); - } - QueueCommands.close = close; - /** - * gives info about the queue - * @param interaction - * @throws errorMessage class if it cannot be left - */ - async function queue(interaction) { - let info = getInfo(interaction); - let embed = new discord_js_1.MessageEmbed() - .setTitle('Active Queue') - .addField('Team Size', info.teamsize.toString(), true) - .addField('Players Joined', info.players.length.toString(), true) - .setFooter({ text: 'type /join' }); //TODO - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - QueueCommands.queue = queue; - /** - * joins a queue - * @param interaction - * @throws errorMessage class if it cannot be readied - */ - async function join(interaction) { - let { member, info, channel } = getAll(interaction); - if (queueContains(interaction)) - throw (0, util_1.emsg)('discord.inQueue'); - info.players.push(member); - QUEUE.set(interaction.channelId, info); - await interaction.reply(lang_1.Lang.get('discord.join')); - checkQueue(channel); - } - QueueCommands.join = join; - /** - * leaves a queue - * @param interaction - * @throws errorMessage class if it cannot be reset - */ - async function leave(interaction) { - let { member, info } = getAll(interaction); - if (!queueContains(interaction)) - throw (0, util_1.emsg)('discord.notInQueue'); - info.players.splice(info.players.indexOf(member), 1); - QUEUE.set(interaction.channelId, info); - await interaction.reply(lang_1.Lang.get('discord.leave')); - } - QueueCommands.leave = leave; -})(QueueCommands = exports.QueueCommands || (exports.QueueCommands = {})); + queueCreate(channelId, teamsize); + interaction.reply(Lang.get('discord.create', { + teamsize: teamsize.toString() + })); +} +/** + * closes a queue + * @param interaction + * @throws errorMessage class if it cannot be joined + */ +async function close(interaction) { + (0, util_1.memberIsModThrow)(interaction); + QUEUE.delete(interaction.channelId); + await interaction.reply(Lang.get('discord.close')); +} +/** + * gives info about the queue + * @param interaction + * @throws errorMessage class if it cannot be left + */ +async function queue(interaction) { + const info = getInfo(interaction); + const embed = new discord_js_1.MessageEmbed() + .setTitle('Active Queue') + .addField('Team Size', info.teamsize.toString(), true) + .addField('Players Joined', info.players.length.toString(), true) + .setFooter({ text: 'type /join' }); //TODO + await interaction.reply({ embeds: [embed], ephemeral: true }); +} +/** + * joins a queue + * @param interaction + * @throws errorMessage class if it cannot be readied + */ +async function join(interaction) { + const { member, info, channel } = getAll(interaction); + if (queueContains(interaction)) + throw (0, util_1.emsg)('discord.inQueue'); + info.players.push(member); + QUEUE.set(interaction.channelId, info); + await interaction.reply(Lang.get('discord.join')); + checkQueue(channel); +} +/** + * leaves a queue + * @param interaction + * @throws errorMessage class if it cannot be reset + */ +async function leave(interaction) { + const { member, info } = getAll(interaction); + if (!queueContains(interaction)) + throw (0, util_1.emsg)('discord.notInQueue'); + info.players.splice(info.players.indexOf(member), 1); + QUEUE.set(interaction.channelId, info); + await interaction.reply(Lang.get('discord.leave')); +} +exports.QueueCommands = { + open, + close, + queue, + join, + leave +}; diff --git a/dist/queueCommands.js b/dist/queueCommands.js new file mode 100644 index 0000000..3918c74 --- /dev/null +++ b/dist/queueCommands.js @@ -0,0 +1 @@ +"use strict"; diff --git a/dist/util.js b/dist/util.js index 929aa42..8c8f9e8 100644 --- a/dist/util.js +++ b/dist/util.js @@ -1,14 +1,34 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; Object.defineProperty(exports, "__esModule", { value: true }); exports.memberIsModThrow = exports.memberIsMod = exports.getChannel = exports.getMember = exports.emsg = exports.errorMessage = exports.shuffle = void 0; const discord_js_1 = require("discord.js"); -const lang_1 = require("./lang"); +const Lang = __importStar(require("./lang")); /** * shuffles an array * https://stackoverflow.com/a/2450976/2856416 * @param array an array * @returns an array but shuffled */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function shuffle(array) { let currentIndex = array.length, randomIndex; // While there remain elements to shuffle... @@ -37,7 +57,7 @@ exports.errorMessage = errorMessage; * @param ephemeral (default=true) * @returns new errorMessage */ -const emsg = (msg, ephemeral = true) => new errorMessage(lang_1.Lang.get(`error.${msg}`), ephemeral); +const emsg = (msg, ephemeral = true) => new errorMessage(Lang.get(`error.${msg}`), ephemeral); exports.emsg = emsg; /** * get the GuildMember of an interaction @@ -46,7 +66,7 @@ exports.emsg = emsg; * @returns member */ function getMember(interaction) { - let member = interaction.member; + const member = interaction.member; if (!(member instanceof discord_js_1.GuildMember)) throw (0, exports.emsg)('general.noMember'); return member; @@ -59,14 +79,14 @@ exports.getMember = getMember; * @returns member */ function getChannel(interaction) { - let channel = interaction.channel; + const channel = interaction.channel; if (!(channel instanceof discord_js_1.TextChannel)) throw (0, exports.emsg)('general.noChannel'); return channel; } exports.getChannel = getChannel; function memberIsMod(interaction) { - let member = getMember(interaction); + const member = getMember(interaction); return member.permissionsIn(interaction.channelId).has('MANAGE_MESSAGES'); } exports.memberIsMod = memberIsMod;