Compare commits

..

3 Commits

Author SHA1 Message Date
513a9d1582 added more strings 2022-02-14 14:56:47 -06:00
458d3f3d76 added embed support to lang 2022-02-14 14:37:10 -06:00
28fb9ed3c8 deleted empty files 2022-02-14 12:13:50 -06:00
9 changed files with 522 additions and 87 deletions

View File

@@ -17,6 +17,10 @@
"allowNumber" : false "allowNumber" : false
} }
], ],
/* dev */
"no-debugger": "off",
/* important */ /* important */
"prefer-const": "error", "prefer-const": "error",
"quotes": ["error", "single"], "quotes": ["error", "single"],

26
dist/api.js vendored
View File

@@ -25,9 +25,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.getPlayerInteraction = exports.getPlayer = void 0; exports.getPlayerInteraction = exports.getPlayer = void 0;
/*eslint prefer-const: "error"*/ /*eslint prefer-const: "error"*/
const cheerio = __importStar(require("cheerio")); const cheerio = __importStar(require("cheerio"));
const discord_js_1 = require("discord.js");
const https_1 = __importDefault(require("https")); const https_1 = __importDefault(require("https"));
const util_1 = require("./util"); const util_1 = require("./util");
const Lang = __importStar(require("./lang"));
const uniteApiRegex = { const uniteApiRegex = {
//$1 = name, $2 = id //$1 = name, $2 = id
ogtitle: /unite api - (.+) \((.*)\)/i, ogtitle: /unite api - (.+) \((.*)\)/i,
@@ -187,18 +187,18 @@ async function sendPlayerEmbed(interaction, data) {
eloStr = `(${data.elo})`; eloStr = `(${data.elo})`;
else else
eloStr = `Class ${data.class}`; eloStr = `Class ${data.class}`;
const embed = new discord_js_1.MessageEmbed() await interaction.editReply(Lang.getEmbed('api.player', {
.setTitle(`${data.name} (${data.id})`) name: data.name,
.setURL(`https://uniteapi.dev/p/${encodeURIComponent(data.name)}`) id: data.id,
.setTimestamp() nameEncoded: encodeURIComponent(data.name),
.setThumbnail(data.avatar) avatar: data.avatar,
.setDescription(`Level ${data.level} level: data.level,
${data.rank} ${eloStr} rank: data.rank,
elo: eloStr,
**Battles** ${data.battles} battles: data.battles,
**Wins** ${data.wins} wins: data.wins,
**Win Rate** ${data.winrate}`); winrate: data.winrate
await interaction.editReply({ embeds: [embed] }); }));
} }
/** /**
* calls getPlayer() with the name from the interaction * calls getPlayer() with the name from the interaction

186
dist/lang.js vendored
View File

@@ -1,6 +1,100 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.get = exports.setLang = void 0; exports.getEmbed = exports.get = exports.setLang = void 0;
const discord_js_1 = require("discord.js");
/* UTIL FUNCS */
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;
});
}
function bigString(str) {
if (typeof str === 'object')
return str.join('\n');
return str;
}
function resolveColor(color) {
color = color.replace(/[^0-9a-f]/gi, '');
const colorNum = [0, 0, 0];
if (color.length === 3 || color.length === 6) {
const colorSpl = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color);
if (!colorSpl)
return colorNum;
for (let i = 0; i < colorSpl.length && i < colorNum.length; i++)
colorNum[i] = parseInt(colorSpl[i], 16);
}
return colorNum;
}
function embedObjStr(embedData, fallback = '') {
if (embedData.content !== undefined)
return bigString(embedData.content);
if (embedData.description !== undefined)
return bigString(embedData.description);
return fallback;
}
function embedObjEmbed(embedObj, args = {}) {
const embed = new discord_js_1.MessageEmbed(), { author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj;
if (author !== undefined) {
let authorFix;
if (typeof author === 'string')
authorFix = {
name: template(author, args)
};
else {
const { name, icon, url } = author;
authorFix = {
name: template(name, args)
};
if (icon !== undefined)
authorFix.icon = template(icon, args);
if (url !== undefined)
authorFix.url = template(url, args);
}
embed.setAuthor(authorFix);
}
if (footer !== undefined) {
let footerFix;
if (typeof footer === 'string')
footerFix = {
text: template(footer, args)
};
else {
const { text, icon } = footer;
footerFix = {
text: template(text, args)
};
if (icon !== undefined)
footerFix.icon = template(icon, args);
}
embed.setFooter(footerFix);
}
if (color !== undefined)
embed.setColor(resolveColor(template(color, args)));
if (description !== undefined)
embed.setDescription(template(bigString(description), args));
if (image !== undefined)
embed.setImage(template(image, args));
if (thumbnail !== undefined)
embed.setThumbnail(template(thumbnail, args));
if (title !== undefined)
embed.setTitle(template(title, args));
if (url !== undefined)
embed.setURL(template(url, args));
if (timestamp === true)
embed.setTimestamp();
else if (typeof timestamp === 'string')
embed.setTimestamp(new Date(template(timestamp, args)));
else if (timestamp !== false)
embed.setTimestamp(timestamp);
fields?.forEach(field => {
embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline);
});
return embed;
}
/* LANG */
const LANG = { const LANG = {
en: { en: {
main: { main: {
@@ -11,7 +105,44 @@ const LANG = {
create: 'A queue for teams of {teamsize} has been created', create: 'A queue for teams of {teamsize} has been created',
close: 'Queue has been closed', close: 'Queue has been closed',
join: 'Joined the queue', join: 'Joined the queue',
leave: 'Left the queue' leave: 'Left the queue',
team: {
embed: true,
title: 'Team',
description: '{team}'
},
queue: {
embed: true,
title: 'Active Queue',
fields: [
{
name: 'Team Size',
value: '{teamsize}'
},
{
name: 'Players Joined',
value: '{playercount}'
}
],
footer: 'type `/join`'
}
},
api: {
player: {
embed: true,
title: '{name} ({id})',
url: 'https://uniteapi.dev/p/{nameEncoded}',
timestamp: true,
thumbnail: '{avatar}',
description: [
'Level {level}',
'{rank} {elo}',
'',
'**Battles** {battles}',
'**Wins** {wins}',
'**Win Rate** {winrate}'
]
}
}, },
error: { error: {
main: { main: {
@@ -35,6 +166,7 @@ const LANG = {
} }
} }
}; };
/* MAIN */
let LANGID = 'en'; let LANGID = 'en';
if (!(LANGID in LANG)) if (!(LANGID in LANG))
throw 'language id does not exist'; throw 'language id does not exist';
@@ -45,17 +177,10 @@ function setLang(langid) {
throw 'language id does not exist'; throw 'language id does not exist';
} }
exports.setLang = setLang; 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 * reads language json (just strings)
* @param id ex: discord.error.noActiveQueue * @param id ex: discord.error.noActiveQueue
* @param args list of key/value pairs to represent template values
* @returns language value, defaults to `id` parameter * @returns language value, defaults to `id` parameter
*/ */
function get(id, args = {}) { function get(id, args = {}) {
@@ -66,6 +191,8 @@ function get(id, args = {}) {
const found = finding[key]; const found = finding[key];
if (typeof found === 'string') if (typeof found === 'string')
return template(found, args); return template(found, args);
if (found.embed === true)
return embedObjStr(found, id);
finding = found; finding = found;
} }
else else
@@ -74,3 +201,40 @@ function get(id, args = {}) {
return id; return id;
} }
exports.get = get; exports.get = get;
/**
* reads language json as an object (could be embed or just string)
* @param id ex: discord.error.noActiveQueue
* @param args list of key/value pairs to represent template values
* @param otherOptions values to be passed through to the return value
* @returns language value, defaults to `id` parameter
*/
function getEmbed(id, args = {}, otherOptions = {}) {
const embedData = {
...otherOptions,
embeds: []
};
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') {
embedData.content = template(found, args);
break;
}
if (found.embed === true) {
const embedObj = found, { content } = embedObj, embed = embedObjEmbed(embedObj, args);
embedData.embeds.push(embed);
if (content !== undefined)
embedData.content = content;
return embedData;
}
finding = found;
}
else
break;
}
return embedData;
}
exports.getEmbed = getEmbed;
debugger;

20
dist/queue.js vendored
View File

@@ -55,11 +55,7 @@ async function checkQueue(channel) {
return; return;
if (info.players.length >= info.teamsize) { if (info.players.length >= info.teamsize) {
const 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 await channel.send(Lang.getEmbed('discord.team', { team: team.join('\n') }));
const embed = new discord_js_1.MessageEmbed()
.setTitle('Team')
.setDescription(team.join('\n'));
await channel.send({ embeds: [embed] });
} }
} }
function queueCreate(channelId, teamsize) { function queueCreate(channelId, teamsize) {
@@ -80,7 +76,7 @@ SaveQueue();
async function discordInit(client) { async function discordInit(client) {
for (const channelId of QUEUE.keys()) { for (const channelId of QUEUE.keys()) {
const info = QUEUE.get(channelId), channel = await client.channels.fetch(channelId); const info = QUEUE.get(channelId), channel = await client.channels.fetch(channelId);
if (!info) { //no idea what could cause this but TS complains if (!info) {
queueRemove(channelId); queueRemove(channelId);
continue; continue;
} }
@@ -166,12 +162,12 @@ async function close(interaction) {
*/ */
async function queue(interaction) { async function queue(interaction) {
const info = getInfo(interaction); const info = getInfo(interaction);
const embed = new discord_js_1.MessageEmbed() await interaction.reply(Lang.getEmbed('discord.queue', {
.setTitle('Active Queue') teamsize: info.teamsize.toString(),
.addField('Team Size', info.teamsize.toString(), true) playercount: info.players.length.toString(),
.addField('Players Joined', info.players.length.toString(), true) }, {
.setFooter({ text: 'type /join' }); //TODO ephemeral: true
await interaction.reply({ embeds: [embed], ephemeral: true }); }));
} }
/** /**
* joins a queue * joins a queue

View File

@@ -1 +0,0 @@
"use strict";

View File

@@ -1,9 +1,10 @@
/*eslint prefer-const: "error"*/ /*eslint prefer-const: "error"*/
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
import { CommandInteraction, MessageEmbed } from 'discord.js'; import { CommandInteraction } from 'discord.js';
import { IncomingMessage } from 'http'; import { IncomingMessage } from 'http';
import http from 'https'; import http from 'https';
import { emsg } from './util'; import { emsg } from './util';
import * as Lang from './lang';
const uniteApiRegex = { const uniteApiRegex = {
//$1 = name, $2 = id //$1 = name, $2 = id
@@ -91,6 +92,7 @@ function readHTML(html: string): uniteApiData {
wins: '', wins: '',
winrate: '' winrate: ''
}; };
let metaElems = $('meta').toArray(); let metaElems = $('meta').toArray();
//filter down to just ones named "og:..." //filter down to just ones named "og:..."
@@ -227,19 +229,18 @@ async function sendPlayerEmbed(interaction: CommandInteraction, data: uniteApiDa
else else
eloStr = `Class ${data.class}`; eloStr = `Class ${data.class}`;
const embed = new MessageEmbed() await interaction.editReply(Lang.getEmbed('api.player', {
.setTitle(`${data.name} (${data.id})`) name: data.name,
.setURL(`https://uniteapi.dev/p/${encodeURIComponent(data.name)}`) id: data.id,
.setTimestamp() nameEncoded: encodeURIComponent(data.name),
.setThumbnail(data.avatar) avatar: data.avatar,
.setDescription(`Level ${data.level} level: data.level,
${data.rank} ${eloStr} rank: data.rank,
elo: eloStr,
**Battles** ${data.battles} battles: data.battles,
**Wins** ${data.wins} wins: data.wins,
**Win Rate** ${data.winrate}`); winrate: data.winrate
}));
await interaction.editReply({embeds: [embed]});
} }
/** /**

View File

@@ -1,6 +1,200 @@
type LangObj = { [keys:string]: LangObj | string } import { MessageEmbed } from 'discord.js';
/* TYPES */
//this is a generic type, and needs 'any'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type basicObject = {[keys: string]: any};
type basicObjectStr = {[keys: string]: string};
type URL = string;
type bigString = string | string[];
interface embedData {
content?: string,
embeds: MessageEmbed[]
}
interface embedField {
name: string,
value: bigString,
inline?: boolean
}
interface authorData {
name: string,
url?: string,
icon?: string
}
interface footerData {
text: string,
icon?: string
}
interface embedObj {
embed: true,
content?: string,
title?: string,
description?: bigString,
url?: URL,
color?: string,
footer?: string | footerData,
thumbnail?: URL,
image?: URL,
author?: string | authorData,
fields?: embedField[],
timestamp?: boolean | string | number
}
type LangObj = { [keys:string]: LangObj | embedObj | string }
type LangObjWhole = { [langid:string]: LangObj } type LangObjWhole = { [langid:string]: LangObj }
/* UTIL FUNCS */
function template(str: string, args: basicObject): string {
return str.replace(/{\w+}/g, str => {
const key = str.substring(1, str.length-1);
if (key in args)
return args[key];
return key;
});
}
function bigString(str: bigString): string {
if (typeof str === 'object')
return str.join('\n');
return str;
}
function resolveColor(color: string): [number, number, number] {
color = color.replace(/[^0-9a-f]/gi, '');
const colorNum: [number, number, number] = [0, 0, 0];
if (color.length === 3 || color.length === 6) {
const colorSpl = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color);
if (!colorSpl)
return colorNum;
for (let i = 0; i < colorSpl.length && i < colorNum.length; i++)
colorNum[i] = parseInt(colorSpl[i], 16);
}
return colorNum;
}
function embedObjStr(embedData: embedObj, fallback = ''): string {
if (embedData.content !== undefined)
return bigString(embedData.content);
if (embedData.description !== undefined)
return bigString(embedData.description);
return fallback;
}
function embedObjEmbed(embedObj: embedObj, args: basicObjectStr = {}): MessageEmbed {
const embed = new MessageEmbed(),
{ author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj;
if (author !== undefined) {
let authorFix: authorData;
if (typeof author === 'string')
authorFix = {
name: template(author, args)
};
else {
const {name, icon, url} = author;
authorFix = {
name: template(name, args)
};
if (icon !== undefined)
authorFix.icon = template(icon, args);
if (url !== undefined)
authorFix.url = template(url, args);
}
embed.setAuthor(authorFix);
}
if (footer !== undefined) {
let footerFix: footerData;
if (typeof footer === 'string')
footerFix = {
text: template(footer, args)
};
else {
const {text, icon} = footer;
footerFix = {
text: template(text, args)
};
if (icon !== undefined)
footerFix.icon = template(icon, args);
}
embed.setFooter(footerFix);
}
if (color !== undefined)
embed.setColor(resolveColor(template(color, args)));
if (description !== undefined)
embed.setDescription(template(bigString(description), args));
if (image !== undefined)
embed.setImage(template(image, args));
if (thumbnail !== undefined)
embed.setThumbnail(template(thumbnail, args));
if (title !== undefined)
embed.setTitle(template(title, args));
if (url !== undefined)
embed.setURL(template(url, args));
if (timestamp === true)
embed.setTimestamp();
else if (typeof timestamp === 'string')
embed.setTimestamp(new Date(template(timestamp, args)));
else if (timestamp !== false)
embed.setTimestamp(timestamp);
fields?.forEach(field => {
embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline);
});
return embed;
}
/* LANG */
const LANG: LangObjWhole = { const LANG: LangObjWhole = {
en: { en: {
@@ -14,7 +208,46 @@ const LANG: LangObjWhole = {
create: 'A queue for teams of {teamsize} has been created', create: 'A queue for teams of {teamsize} has been created',
close: 'Queue has been closed', close: 'Queue has been closed',
join: 'Joined the queue', join: 'Joined the queue',
leave: 'Left the queue' leave: 'Left the queue',
team: {
embed: true,
title: 'Team',
description: '{team}'
},
queue: {
embed: true,
title: 'Active Queue',
fields: [
{
name: 'Team Size',
value: '{teamsize}'
},
{
name: 'Players Joined',
value: '{playercount}'
}
],
footer: 'type `/join`'
}
},
api: {
player: {
embed: true,
title: '{name} ({id})',
url: 'https://uniteapi.dev/p/{nameEncoded}',
timestamp: true,
thumbnail: '{avatar}',
description: [
'Level {level}',
'{rank} {elo}',
'',
'**Battles** {battles}',
'**Wins** {wins}',
'**Win Rate** {winrate}'
]
}
}, },
error: { error: {
@@ -47,6 +280,7 @@ const LANG: LangObjWhole = {
}; };
/* MAIN */
let LANGID = 'en'; let LANGID = 'en';
if (!(LANGID in LANG)) if (!(LANGID in LANG))
@@ -59,27 +293,13 @@ export function setLang(langid: string) {
throw 'language id does not exist'; throw 'language id does not exist';
} }
function template(str: string, args: {[keys: string]: string}): string {
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 * reads language json (just strings)
* @param id ex: discord.error.noActiveQueue * @param id ex: discord.error.noActiveQueue
* @param args list of key/value pairs to represent template values
* @returns language value, defaults to `id` parameter * @returns language value, defaults to `id` parameter
*/ */
export function get(id: string, args: {[keys: string]: string} = {}): string {//discord.error.noActiveQueue export function get(id: string, args: basicObjectStr = {}): string {
const keySpl = id.split('.').map(k => k.trim()).filter(k => k); const keySpl = id.split('.').map(k => k.trim()).filter(k => k);
@@ -94,7 +314,10 @@ export function get(id: string, args: {[keys: string]: string} = {}): string {//
if (typeof found === 'string') if (typeof found === 'string')
return template(found, args); return template(found, args);
finding = found; if (found.embed === true)
return embedObjStr(found as embedObj, id);
finding = found as LangObj;
} else } else
break; break;
@@ -102,4 +325,58 @@ export function get(id: string, args: {[keys: string]: string} = {}): string {//
} }
return id; return id;
} }
/**
* reads language json as an object (could be embed or just string)
* @param id ex: discord.error.noActiveQueue
* @param args list of key/value pairs to represent template values
* @param otherOptions values to be passed through to the return value
* @returns language value, defaults to `id` parameter
*/
export function getEmbed(id: string, args: basicObjectStr = {}, otherOptions: basicObject = {}): embedData {
const embedData: embedData = {
...otherOptions,
embeds: []
};
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') {
embedData.content = template(found, args);
break;
}
if (found.embed === true) {
const embedObj = found as embedObj,
{content} = embedObj,
embed = embedObjEmbed(embedObj, args);
embedData.embeds.push(embed);
if (content !== undefined)
embedData.content = content;
return embedData;
}
finding = found as LangObj;
} else
break;
}
return embedData;
}
debugger;

View File

@@ -3,7 +3,7 @@
join message should contain your current position in the queue, editing it to keep it current join message should contain your current position in the queue, editing it to keep it current
*/ */
import { Client, CommandInteraction, MessageEmbed, TextChannel } from 'discord.js'; import { Client, CommandInteraction, TextChannel } from 'discord.js';
import * as fs from 'fs'; import * as fs from 'fs';
import { emsg, getChannel, getMember, memberIsModThrow, queueInfo, queueInfoBase } from './util'; import { emsg, getChannel, getMember, memberIsModThrow, queueInfo, queueInfoBase } from './util';
import * as Lang from './lang'; import * as Lang from './lang';
@@ -51,12 +51,7 @@ async function checkQueue(channel: TextChannel) {
const 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 await channel.send(Lang.getEmbed('discord.team', { team: team.join('\n') }));
const embed = new MessageEmbed()
.setTitle('Team')
.setDescription(team.join('\n'));
await channel.send({embeds: [embed]});
} }
@@ -86,7 +81,7 @@ export async function discordInit(client: Client) {
const info = QUEUE.get(channelId), const info = QUEUE.get(channelId),
channel = await client.channels.fetch(channelId); channel = await client.channels.fetch(channelId);
if (!info) { //no idea what could cause this but TS complains if (!info) {
queueRemove(channelId); queueRemove(channelId);
continue; continue;
} }
@@ -198,13 +193,12 @@ async function queue(interaction: CommandInteraction) {
const info = getInfo(interaction); const info = getInfo(interaction);
const embed = new MessageEmbed() await interaction.reply(Lang.getEmbed('discord.queue', {
.setTitle('Active Queue') teamsize: info.teamsize.toString(),
.addField('Team Size', info.teamsize.toString(), true) playercount: info.players.length.toString(),
.addField('Players Joined', info.players.length.toString(), true) }, {
.setFooter({text: 'type /join'}); //TODO ephemeral: true
}));
await interaction.reply({embeds: [embed], ephemeral: true});
} }

View File