Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/interactions stored temporary into database #399

Merged
merged 73 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
3cd9bf1
fix: config
JustDams Oct 13, 2023
1f64c86
Merge branch 'main' of github.com:faceitFinder/faceitfinder-discordbo…
JustDams Oct 13, 2023
2bf0f7b
Merge branch 'main' of github.com:faceitFinder/faceitfinder-discordbo…
JustDams Oct 15, 2023
1ddc349
Merge branch 'main' of github.com:faceitFinder/faceitfinder-discordbo…
JustDams Oct 15, 2023
66ac3ba
Merge branch 'main' of github.com:faceitFinder/faceitfinder-discordbo…
JustDams Oct 18, 2023
ef1d342
udpate: packages
JustDams Oct 18, 2023
f6eaf03
Merge branch 'main' of github.com:faceitFinder/faceitfinder-discordbo…
JustDams Oct 18, 2023
1518e8d
update: mongoose
JustDams Oct 19, 2023
23b2c61
feature: new model
JustDams Oct 19, 2023
fb5ac5c
update: command handling
JustDams Oct 19, 2023
8e044a2
update: graph params
JustDams Oct 19, 2023
8037777
fix: lint
JustDams Oct 19, 2023
d1ec500
update: error return
JustDams Oct 19, 2023
3b960d8
update: new user button interaction handling
JustDams Oct 19, 2023
a214690
feat: new stats command
JustDams Oct 19, 2023
6c8629a
update: loading card
JustDams Oct 19, 2023
90212e1
update: set expire time on interactions
JustDams Oct 19, 2023
29624e0
feat: interaction expired message
JustDams Oct 19, 2023
5fa13b7
update: stats
JustDams Oct 25, 2023
bef89cb
refacto: stats
JustDams Oct 25, 2023
2c8d50f
update: loading cards, refacto: compare
JustDams Oct 25, 2023
c1cc952
update: expiration message
JustDams Oct 26, 2023
f7a642f
ufeat: player color as a parameter
JustDams Oct 26, 2023
c2f1833
update: daily/weekly/monthly/yearly stats
JustDams Oct 26, 2023
9b200d7
feat: interaction generation for options
JustDams Oct 26, 2023
4913dd3
update: pagination build
JustDams Oct 26, 2023
b9afb9e
fix: linter
JustDams Oct 26, 2023
2f5d89a
update: graph
JustDams Oct 26, 2023
a0543ec
feat: stringselectmenu disabled
JustDams Oct 26, 2023
473737b
fix: button generation
JustDams Oct 26, 2023
8ab6498
update: interaction user update handler, datestats pagination
JustDams Oct 26, 2023
e25e77a
update: datestats pagination handling
JustDams Oct 26, 2023
71fb425
feat: readable json options
JustDams Oct 26, 2023
a9d5bda
feat: readable json options
JustDams Oct 26, 2023
9d97e37
feat: readable json options
JustDams Oct 26, 2023
3b7b3dc
feat: readable json options
JustDams Oct 26, 2023
a8ba190
feat: keep selected graph when changing day/week/month/yeah, and read…
JustDams Oct 27, 2023
9dc4d9a
feat: pagination management
JustDams Oct 27, 2023
fd94712
fix: error
JustDams Oct 27, 2023
8702ac4
feat: new user
JustDams Oct 27, 2023
4293a08
feat: new functions params/names
JustDams Oct 27, 2023
31d7e24
update: datestats and pagination, fix: placeholder null
JustDams Oct 29, 2023
cf31773
fix: datestats history null
JustDams Oct 29, 2023
a624ea9
feat: last
JustDams Oct 29, 2023
816716f
feat: laststats
JustDams Oct 29, 2023
36d9f0c
update: datestats
JustDams Oct 29, 2023
8e21cf5
remove: console log
JustDams Oct 29, 2023
d612fc4
feat: interaction deletion
JustDams Oct 29, 2023
e168272
update: loading interactions
JustDams Oct 29, 2023
2748be1
feat: find, some update on the last methods
JustDams Oct 29, 2023
ee6d06d
update: all the options are being updated
JustDams Oct 29, 2023
0f81524
feat: axios retry, and packages update
JustDams Oct 29, 2023
dd03f04
remove: unused method
JustDams Oct 29, 2023
bd6315f
remove: unused method
JustDams Oct 29, 2023
5c93512
remove: unused method
JustDams Oct 29, 2023
535d5d3
using custom api
JustDams Oct 29, 2023
739ce18
fix
JustDams Oct 29, 2023
3d4fd0a
feat: catch errors from old interactions
JustDams Oct 30, 2023
0059e3d
update: link
JustDams Oct 30, 2023
afd53e3
fix
JustDams Oct 30, 2023
44f2607
remove: old code
JustDams Nov 1, 2023
290bcf5
update: show the selected last match before fetching datas
JustDams Nov 1, 2023
45e020c
Merge branch 'feature/interactions-stored-temporary-into-database' of…
JustDams Nov 1, 2023
d92a2cc
refacto: map command
JustDams Nov 1, 2023
54e4d02
update: methods files
JustDams Nov 1, 2023
a47c4bc
fix: missing import
JustDams Nov 1, 2023
2c96349
fix: missing import
JustDams Nov 1, 2023
e730127
update: teams
JustDams Nov 1, 2023
f832119
update: compare
JustDams Nov 1, 2023
31e954e
fix: missing import
JustDams Nov 1, 2023
384a4fa
update: show the selected last match before disabling
JustDams Nov 1, 2023
1fd9484
fix
JustDams Nov 1, 2023
e307828
fix: conflicts
JustDams Nov 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 138 additions & 105 deletions commands/compare.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Discord = require('discord.js')
const { color, emojis } = require('../config.json')
const { getUsers, getInteractionOption, getGameOption } = require('../functions/commands')
const { color, emojis, defaultGame } = require('../config.json')
const { getUsers } = require('../functions/commands')
const CustomTypeFunc = require('../functions/customType')
const CustomType = require('../templates/customType')
const Graph = require('../functions/graph')
Expand All @@ -9,6 +9,7 @@ const { getTranslations, getTranslation } = require('../languages/setup')
const { getMapOption } = require('../functions/map')
const { getStats } = require('../functions/apiHandler')
const { gameOption } = require('../templates/options')
const { getInteractionOption, getGameOption } = require('../functions/utility')

const compareStats = (stats1, stats2, positive = true) => {
if (positive) {
Expand All @@ -35,85 +36,89 @@ const getMaxMatchLimit = (player1, player2, fn) => {
const playerMaxMatches = [player1, player2]
.map(p => fn(p))
const maxMatchLimit = structuredClone(playerMaxMatches).sort((a, b) => a - b)[0]

return {
maxMatchLimit,
playerWithLessMatch: [player1, player2][playerMaxMatches.indexOf(maxMatchLimit)]
}
return maxMatchLimit
}

const sendCardWithInfo = async (interaction, player1Param, player2Param, type = CustomType.TYPES.ELO, maxMatch = 20, map = null, game) => {
game ??= getGameOption(interaction)
maxMatch = getInteractionOption(interaction, 'match_number') ?? maxMatch
map = getInteractionOption(interaction, 'map') || map

const buttonValues = { id: 'uCSG', u: interaction.user.id, g: game }
if (map) buttonValues.c = map

// Get player datas
let player1 = await getStats({
playerParam: player1Param,
matchNumber: 1,
game
})

let player2 = await getStats({
playerParam: player2Param,
matchNumber: 1,
game
})

let playerWithLessMatch
let maxMatchLimit
let limits

const buildButtons = (interaction, buttonsValues) => Promise.all([
CustomType.TYPES.KD,
CustomType.TYPES.ELO
].map((t) => CustomTypeFunc.generateButtons(interaction, buttonsValues, t, CustomType.TYPES.ELO)))

const getPlayersStats = ({
players,
matchNumber,
game,
map = ''
}) => Promise.all(players.map((player) => getStats({
playerParam: player,
matchNumber,
map,
game
})))

const getInitPlayersDatas = ({
player1Param,
player2Param,
game,
map
}) => getPlayersStats({
players: [player1Param, player2Param],
matchNumber: 1,
game,
map
})

const buildEmbed = async ({
player1,
player2,
maxMatch = 20,
map,
type,
game = defaultGame,
locale,
playerColor = getRandomColors(2)
}) => {
// Check if players have played at least one match
[player1, player2].filter(p => !p.playerHistory.length).map(p => {
throw getTranslation('error.user.noMatches', interaction.locale, {
throw getTranslation('error.user.noMatches', locale, {
playerName: p.playerDatas.nickname,
})
})

if (map) {
// Check if players have played the map
[player1, player2].map(p => {
mapStats = p.playerStats.segments.filter(segment => segment.label === map && segment.mode === '5v5')

if (!mapStats?.at(0)?.stats) throw getTranslation('error.user.mapNotPlayed', interaction.locale, {
if (!mapStats?.at(0)?.stats) throw getTranslation('error.user.mapNotPlayed', locale, {
playerName: p.playerDatas.nickname,
})
})

limits = getMaxMatchLimit(
filter = (p) => parseInt(p.playerStats.segments.find(segment => segment.label === map && segment.mode === '5v5').stats.Matches)

maxMatch = getMaxMatchLimit(
player1,
player2,
(p) => parseInt(p.playerStats.segments.find(segment => segment.label === map && segment.mode === '5v5').stats.Matches)
(p) => filter(p)
)
} else limits = getMaxMatchLimit(
player1,
player2,
(p) => parseInt(p.playerStats.lifetime.Matches)
)

maxMatchLimit = limits.maxMatchLimit
playerWithLessMatch = limits.playerWithLessMatch

maxMatch = maxMatch > maxMatchLimit || maxMatch <= 0 ? maxMatchLimit : maxMatch
}

// Get player stats
player1 = await getStats({
playerParam: player1Param,
[player1, player2] = await getPlayersStats({
players: [{ faceitId: true, param: player1.playerDatas.player_id }, { faceitId: true, param: player2.playerDatas.player_id }],
matchNumber: maxMatch,
map: map || '',
map,
game
})

player2 = await getStats({
playerParam: player2Param,
matchNumber: maxMatch,
map: map || '',
game
})
const maxMatchLimit = getMaxMatchLimit(
player1,
player2,
(p) => p.playerHistory.length
)

playerWithLessMatch = [player1, player2].filter(p => p.playerDatas.player_id === playerWithLessMatch.playerDatas.player_id).find(e => e)
if (maxMatch > maxMatchLimit || maxMatch < 1) maxMatch = maxMatchLimit

const fields = [{
name: 'Matches Compared',
Expand Down Expand Up @@ -225,84 +230,109 @@ const sendCardWithInfo = async (interaction, player1Param, player2Param, type =
${player2.playerLastStats['Green K/D']} \
${compareStats(player1.playerLastStats['Green K/D'], player2.playerLastStats['Green K/D'])}`,
inline: true
})
}
)

const card = new Discord.EmbedBuilder()
.setAuthor({
name: player1.playerDatas.nickname,
iconURL: player1.playerDatas.avatar || null
})
.setDescription(getTranslation('strings.compare', interaction.locale, {
.setDescription(getTranslation('strings.compare', locale, {
playerName1: `[${player1.playerDatas.nickname}](https://www.faceit.com/en/players/${player1.playerDatas.nickname})`,
playerName2: `[${player2.playerDatas.nickname}](https://www.faceit.com/en/players/${player2.playerDatas.nickname})`
}))
.setColor(color.primary)
.addFields(...fields)
.setImage('attachment://graph.png')
.setFooter({ text: new Date().toLocaleDateString(interaction.locale), iconURL: 'attachment://game.png' })

const options = [{
label: getTranslation('strings.compare', interaction.locale, {
playerName1: player1.playerDatas.nickname,
playerName2: player2.playerDatas.nickname
}),
value: JSON.stringify({
p1: player1.playerDatas.player_id,
p2: player2.playerDatas.player_id,
}),
default: true
},
{
label: 'Datas',
value: JSON.stringify({
m: maxMatch,
c: map,
g: game,
})
}]

const playerColor = getRandomColors(2)
.setFooter({ text: '\u200b', iconURL: 'attachment://game.png' })

const datasets = [player1, player2]
.map((user, i) => [
user.playerDatas.nickname,
type,
playerColor[i],
Graph.getGraph(interaction, user.playerDatas.nickname, type, user.playerHistory, user.playerDatas.games[game].faceit_elo, maxMatch, true).reverse()
Graph.getGraph(
locale,
user.playerDatas.nickname,
type,
user.playerHistory,
maxMatch
).reverse()
])

const graphBuffer = Graph.getChart(
datasets,
new Array(maxMatch).fill(''),
Graph.getCompareDatasets,
false
false,
game
)

const files = [
new Discord.AttachmentBuilder(graphBuffer, { name: 'graph.png' }),
new Discord.AttachmentBuilder(`images/${game}.png`, { name: 'game.png' })
]

const buttonValues = {
id: 'uCSG',
maxMatch,
game,
map,
p1: player1.playerDatas.player_id,
p2: player2.playerDatas.player_id,
playerColor,
}

return {
card,
files,
buttonValues
}
}

const sendCardWithInfo = async (
interaction,
player1Param,
player2Param,
type = CustomType.TYPES.ELO,
maxMatch = null,
map = null,
game = null
) => {
const defaultMaxMatch = 20

game ??= getGameOption(interaction)
maxMatch ??= getInteractionOption(interaction, 'match_number') ?? defaultMaxMatch
map ??= getInteractionOption(interaction, 'map') ?? ''

const [player1, player2] = await getInitPlayersDatas({
player1Param,
player2Param,
game,
map
})

const {
card,
files,
buttonValues
} = await buildEmbed({
player1,
player2,
maxMatch,
map,
type,
game,
locale: interaction.locale
})

return {
embeds: [card],
files: [
new Discord.AttachmentBuilder(graphBuffer, { name: 'graph.png' }),
new Discord.AttachmentBuilder(`images/${game}.png`, { name: 'game.png' })
],
files,
components: [
new Discord.ActionRowBuilder()
.addComponents(new Discord.StringSelectMenuBuilder()
.setCustomId('compareStatsSelector')
.addOptions(options)
.setDisabled(true)),
new Discord.ActionRowBuilder()
.addComponents([
CustomTypeFunc.generateButtons(
interaction,
{ ...buttonValues, n: 1 },
CustomType.TYPES.KD,
type === CustomType.TYPES.KD),
CustomTypeFunc.generateButtons(
interaction,
{ ...buttonValues, n: 2 },
CustomType.TYPES.ELO,
type === CustomType.TYPES.ELO)
])
.addComponents(await buildButtons(interaction, buttonValues))
]
}
}
Expand Down Expand Up @@ -366,10 +396,13 @@ module.exports = {
const player2 = (await getUsers(interaction, 1, 'second_user_steam', 'second_user_faceit'))?.at(0)

if (!player1 || !player2) return errorCard('error.user.missing', interaction.locale)
else if (player1 === player2) return errorCard('error.user.compareSame', interaction.locale)
else if (player1.param === player2.param) return errorCard('error.user.compareSame', interaction.locale)

return sendCardWithInfo(interaction, player1, player2)
}
}

module.exports.sendCardWithInfo = sendCardWithInfo
module.exports.buildEmbed = buildEmbed
module.exports.buildButtons = buildButtons
module.exports.getInitPlayersDatas = getInitPlayersDatas
Loading
Loading