Skip to content

Commit

Permalink
refacto: map command
Browse files Browse the repository at this point in the history
  • Loading branch information
JustDams committed Nov 1, 2023
1 parent 45e020c commit d92a2cc
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 147 deletions.
147 changes: 125 additions & 22 deletions commands/map.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,98 @@
const { emojis } = require('../config.json')
const { emojis, itemByPage, color } = require('../config.json')
const fs = require('fs')
const Discord = require('discord.js')
const Options = require('../templates/options')
const Graph = require('../functions/graph')
const Interaction = require('../database/interaction')
const { getCardsConditions, getInteractionOption, getGameOption } = require('../functions/commands')
const mapSelector = require('../interactions/selectmenus/mapSelector')
const { getMapOption } = require('../functions/map')
const { getTranslations, getTranslation } = require('../languages/setup')
const { getStats } = require('../functions/apiHandler')
const { buildRows } = require('../functions/dateStats')
const { errorCard } = require('../templates/errorCard')

const sendCardWithInfo = async (interaction, playerParam) => {
const options = []
const map = getInteractionOption(interaction, 'map')
const game = getGameOption(interaction)
const buildEmbed = async (interaction, playerId, map, mode, game) => {
if (!map) return

const {
playerDatas,
playerStats,
steamDatas,
playerLastStats,
} = await getStats({
playerParam: {
param: playerId,
faceitId: true,
},
matchNumber: 0,
checkElo: true,
map,
game
})

const faceitLevel = playerDatas.games[game].skill_level
const faceitElo = playerDatas.games[game].faceit_elo
const size = 40
const filesAtt = []

const rankImageCanvas = await Graph.getRankImage(faceitLevel, faceitElo, size, game)
filesAtt.push(new Discord.AttachmentBuilder(rankImageCanvas, { name: 'level.png' }))

const mapThumbnail = `./images/maps/${map}.jpg`
const playerMapStats = playerStats.segments.filter(e => e.label === map && e.mode == mode)

if (playerMapStats.length === 0) return errorCard(getTranslation('error.user.mapNotPlayed', interaction.locale, {
playerName: playerDatas.nickname,
}), interaction.locale)

const cards = playerMapStats.map(m => {
if (fs.existsSync(mapThumbnail)) filesAtt.push(new Discord.AttachmentBuilder(mapThumbnail, { name: `${map}.jpg` }))

return new Discord.EmbedBuilder()
.setAuthor({ name: playerDatas.nickname, iconURL: playerDatas.avatar || null, url: `https://www.faceit.com/en/players/${playerDatas.nickname}` })
.setDescription(`[Steam](https://steamcommunity.com/profiles/${playerDatas.games[game].game_player_id}), [Faceit](https://www.faceit.com/en/players/${playerDatas.nickname})`)
.setThumbnail('attachment://level.png')
.addFields({ name: 'Map', value: map, inline: true },
{ name: 'Mode', value: mode, inline: true },
{ name: '\u200b', value: '\u200b', inline: true },
{ name: 'Games', value: m.stats.Matches.toString(), inline: true },
{ name: 'Winrate', value: `${playerLastStats.winrate.toFixed(2)}%`, inline: true },
{
name: 'Elo Gain',
value: isNaN(playerLastStats.eloGain) ?
'0'
: playerLastStats.eloGain > 0 ?
`+${playerLastStats.eloGain}`
: playerLastStats.eloGain.toString(),
inline: true
},
{ name: 'K/D', value: playerLastStats.kd.toFixed(2), inline: true },
{ name: 'Kills', value: playerLastStats.kills.toString(), inline: true },
{ name: 'Deaths', value: playerLastStats.deaths.toString(), inline: true },
{ name: 'Average K/D', value: m.stats['Average K/D Ratio'], inline: true },
{ name: 'Average HS', value: `${m.stats['Average Headshots %']}%`, inline: true },
{ name: 'Average MVPs', value: m.stats['Average MVPs'], inline: true },
{ name: 'Average Kills', value: m.stats['Average Kills'], inline: true },
{ name: 'Average Deaths', value: m.stats['Average Deaths'], inline: true },
{ name: 'Average Assists', value: m.stats['Average Assists'], inline: true })
.setColor(color.levels[game][faceitLevel].color)
.setFooter({ text: `Steam: ${steamDatas?.personaname || steamDatas}`, iconURL: 'attachment://game.png' })
.setImage(`attachment://${map}.jpg`)
})

filesAtt.push(new Discord.AttachmentBuilder(`images/${game}.png`, { name: 'game.png' }))

return {
embeds: cards,
files: filesAtt
}
}

const sendCardWithInfo = async (interaction, playerParam, map = null, mode = null, game = null) => {
map ??= getInteractionOption(interaction, 'map')
game ??= getGameOption(interaction)
mode ??= '5v5'
let embeds = []
let files = []

const {
playerDatas,
Expand All @@ -22,16 +103,24 @@ const sendCardWithInfo = async (interaction, playerParam) => {
game
})

if (!playerStats.segments.length) throw getTranslation('error.user.noMatches', interaction.locale, { playerName: playerDatas.nickname })

const playerId = playerDatas.player_id
let content = getTranslation('strings.selectMapDescription', interaction.locale, { playerName: playerDatas.nickname })

playerStats.segments.forEach(e => {
let options = []
await Promise.all(playerStats.segments.map(async (e) => {
const label = `${e.label} ${e.mode}`
const values = {
l: label,
s: playerId
playerId,
userId: interaction.user.id,
game,
map: e.label,
mode: e.mode
}

if (!options.filter(e => e.data.label === label).length > 0) {
const customId = (await Interaction.create(values)).id
const option = new Discord.StringSelectMenuOptionBuilder()
.setLabel(label)
.setDescription(
Expand All @@ -40,27 +129,38 @@ const sendCardWithInfo = async (interaction, playerParam) => {
interaction.locale, { matchNumber: `${e.stats.Matches} (${e.stats['Win Rate %']}%)` }
)
)
.setValue(JSON.stringify(values))
.setValue(customId)
.setDefault(`${map} 5v5` === label)

const emoji = emojis.maps[e.label]
if (emoji) option.setEmoji(emoji.balise)

options.push(option)
}
})
}))
options = options.slice(0, itemByPage)

const components = [
new Discord.ActionRowBuilder()
.addComponents(
new Discord.StringSelectMenuBuilder()
.setCustomId('mapSelector')
.setPlaceholder(getTranslation('strings.selectMap', interaction.locale))
.addOptions(options))
]

const row = new Discord.ActionRowBuilder()
.addComponents(
new Discord.StringSelectMenuBuilder()
.setCustomId('mapSelector')
.setPlaceholder(getTranslation('strings.selectMap', interaction.locale))
.addOptions(options.slice(0, 25)))
if (map) {
const resp = await buildEmbed(interaction, playerId, map, mode, game)
embeds = resp.embeds
files = resp.files
content = ''
}

return {
...await mapSelector.sendCardWithInfo(interaction, playerId, map, '5v5', game),
content: map ? ' ' : getTranslation('strings.selectMapDescription', interaction.locale, { playerName: playerDatas.nickname }),
components: buildRows(row, interaction, game, 'strings.selectMap')
content,
embeds,
files,
components
}
}

Expand All @@ -85,4 +185,7 @@ module.exports = {
fn: sendCardWithInfo
})
}
}
}

module.exports.sendCardWithInfo = sendCardWithInfo
module.exports.buildEmbed = buildEmbed
155 changes: 30 additions & 125 deletions interactions/selectmenus/mapSelector.js
Original file line number Diff line number Diff line change
@@ -1,137 +1,42 @@
const { color } = require('../../config.json')
const Discord = require('discord.js')
const fs = require('fs')
const Graph = require('../../functions/graph')
const DateStats = require('../../functions/dateStats')
const loadingCard = require('../../templates/loadingCard')
const errorCard = require('../../templates/errorCard')
const { getTranslation } = require('../../languages/setup')
const { getStats } = require('../../functions/apiHandler')
const { getOptionsValues } = require('../../functions/commands')

const sendCardWithInfo = async (interaction, playerId, map, mode, game) => {
if (!map) return

const {
playerDatas,
playerStats,
steamDatas,
playerLastStats,
} = await getStats({
playerParam: {
param: playerId,
faceitId: true,
},
matchNumber: 0,
checkElo: true,
map,
game
})

const faceitLevel = playerDatas.games[game].skill_level
const faceitElo = playerDatas.games[game].faceit_elo
const size = 40
const filesAtt = []

const rankImageCanvas = await Graph.getRankImage(faceitLevel, faceitElo, size, game)
filesAtt.push(new Discord.AttachmentBuilder(rankImageCanvas, { name: 'level.png' }))

const mapThumbnail = `./images/maps/${map}.jpg`
const playerMapStats = playerStats.segments.filter(e => e.label === map && e.mode == mode)

if (playerMapStats.length === 0) return errorCard(getTranslation('error.user.mapNotPlayed', interaction.locale, {
playerName: playerDatas.nickname,
}), interaction.locale)

const cards = playerMapStats.map(m => {
if (fs.existsSync(mapThumbnail)) filesAtt.push(new Discord.AttachmentBuilder(mapThumbnail, { name: `${map}.jpg` }))

return new Discord.EmbedBuilder()
.setAuthor({ name: playerDatas.nickname, iconURL: playerDatas.avatar || null, url: `https://www.faceit.com/en/players/${playerDatas.nickname}` })
.setDescription(`[Steam](https://steamcommunity.com/profiles/${playerDatas.games[game].game_player_id}), [Faceit](https://www.faceit.com/en/players/${playerDatas.nickname})`)
.setThumbnail('attachment://level.png')
.addFields({ name: 'Map', value: map, inline: true },
{ name: 'Mode', value: mode, inline: true },
{ name: '\u200b', value: '\u200b', inline: true },
{ name: 'Games', value: m.stats.Matches.toString(), inline: true },
{ name: 'Winrate', value: `${playerLastStats.winrate.toFixed(2)}%`, inline: true },
{
name: 'Elo Gain',
value: isNaN(playerLastStats.eloGain) ?
'0'
: playerLastStats.eloGain > 0 ?
`+${playerLastStats.eloGain}`
: playerLastStats.eloGain.toString(),
inline: true
},
{ name: 'K/D', value: playerLastStats.kd.toFixed(2), inline: true },
{ name: 'Kills', value: playerLastStats.kills.toString(), inline: true },
{ name: 'Deaths', value: playerLastStats.deaths.toString(), inline: true },
{ name: 'Average K/D', value: m.stats['Average K/D Ratio'], inline: true },
{ name: 'Average HS', value: `${m.stats['Average Headshots %']}%`, inline: true },
{ name: 'Average MVPs', value: m.stats['Average MVPs'], inline: true },
{ name: 'Average Kills', value: m.stats['Average Kills'], inline: true },
{ name: 'Average Deaths', value: m.stats['Average Deaths'], inline: true },
{ name: 'Average Assists', value: m.stats['Average Assists'], inline: true })
.setColor(color.levels[game][faceitLevel].color)
.setFooter({ text: `Steam: ${steamDatas?.personaname || steamDatas}`, iconURL: 'attachment://game.png' })
.setImage(`attachment://${map}.jpg`)
})

filesAtt.push(new Discord.AttachmentBuilder(`images/${game}.png`, { name: 'game.png' }))

return {
embeds: cards,
files: filesAtt
}
}
const { getCardByUserType } = require('../../templates/loadingCard')
const { buildEmbed, sendCardWithInfo } = require('../../commands/map')

module.exports = {
name: 'mapSelector',
async execute(interaction, values) {
[values.m, values.v] = values.l.split(' ')

const options = interaction.message.components.at(1).components
.filter(e => e instanceof Discord.StringSelectMenuComponent)
.map(msm => msm.options.map(o => {
const active = o.value === interaction.values.at(0)
o.default = active

DateStats.setOptionValues(o, values)
async execute(interaction, values, newUser = false) {
const {
playerId,
game,
map,
mode
} = values
const optionsComponent = interaction.message.components.at(0)
let components

DateStats.updateDefaultOption(optionsComponent.components, interaction.values[0], false)

getCardByUserType(newUser, interaction)

if (newUser) {
return sendCardWithInfo(interaction, { param: playerId, faceitId: true }, map, mode, game)
}

return o
})).at(0)
const {
embeds,
files
} = await buildEmbed(interaction, playerId, map, mode, game)

const components = [
values.dataRow,
new Discord.ActionRowBuilder()
.addComponents(
new Discord.StringSelectMenuBuilder()
.setCustomId('mapSelector')
.addOptions(options))
optionsComponent.components.at(0).data.disabled = false
components = [
optionsComponent,
]

loadingCard(interaction)

return {
...await sendCardWithInfo(interaction, values.s, values.m, values.v, values.g),
content: null,
components: components
content: '',
embeds,
files,
components
}
},
sendCardWithInfo,
getJSON(interaction, json) {
const values = getOptionsValues(interaction)
const dataRow = interaction.message.components.at(0)

return Object.assign({}, JSON.parse(interaction.values), values, { dataRow })
},
updateUser(interaction) {
const values = this.getJSON(interaction)
const dataRowValues = JSON.parse(values.dataRow.components.at(0).options.at(0).value)
dataRowValues.u = interaction.user.id
values.dataRow.components.at(0).options.at(0).value = JSON.stringify(dataRowValues)

return values
}
}

0 comments on commit d92a2cc

Please sign in to comment.