From c221df5f0235c1cfeb25ac01b34c332c54bd4180 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Mon, 8 Jan 2024 18:34:18 +0100 Subject: [PATCH] added "remove" command --- src/bot.ts | 36 +++++++++++++++++++++------- src/commands/add.ts | 3 ++- src/commands/list.ts | 53 ++++++++++++++++++++++++++++++++++++++++++ src/commands/remove.ts | 30 ++++++++++++++++++++++++ src/player.ts | 8 ++++++- 5 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 src/commands/list.ts create mode 100644 src/commands/remove.ts diff --git a/src/bot.ts b/src/bot.ts index 9ca87a1..052128e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -18,10 +18,8 @@ export class UEMEloBot extends Client { this.commands = commands; const token = await this.login(); console.log(`Discord Token: ${token}`); - setInterval(this.updatePlayers.bind(this), 30 * 60 * 1000); - await this.addPlayer("benjo", "tgm"); - await this.addPlayer("unclebenss", "euw"); - await this.addPlayer("moché", "EUw"); + setInterval(this.updatePlayers.bind(this), 5 * 60 * 1000); + await this.updatePlayers(); }); } @@ -54,21 +52,23 @@ export class UEMEloBot extends Client { } async updatePlayers(){ + console.log("Started full update..."); for (let p of this.players){ await p.updateFullName(); await p.updateCurrentElo(); - if (!p.startElo){ + if (!p.startElo && p.currentElo){ p.startElo = p.currentElo; console.log(`Updated start elo for ${p}`); } } + console.log("Finished full update!"); this.savePlayersToFile(); } - async addPlayer(gameName: string, tag: string){ - let player = await Player.TryCreateFrom(gameName, tag) as Player; + async addPlayer(gameName: string, tagLine: string){ + let player = await Player.TryCreateFrom(gameName, tagLine) as Player; - if (player === undefined) + if (!player) return; if (this.players.find(p => p.puuid === player.puuid)){ @@ -82,6 +82,26 @@ export class UEMEloBot extends Client { return player; } + async removePlayer(gameName: string, tagLine: string){ + let playerCopy = await Player.TryCreateFrom(gameName, tagLine); + + if (!playerCopy){ + console.error(`Tried to remove non-existent Riot ID ${gameName}#${tagLine}`) + return; + } + + let player = this.players.find(p => p.puuid === playerCopy?.puuid); + if (!player){ + console.error(`Tried to remove non-added player ${playerCopy}!`); + return; + } + + this.players.splice(this.players.indexOf(player), 1); + console.log(`Removed ${player}!`); + this.savePlayersToFile(); + return player; + } + async onReady(readyClient: Client){ console.log(`Logged in as ${readyClient.user.tag}`); } diff --git a/src/commands/add.ts b/src/commands/add.ts index fb8b3b7..16498eb 100644 --- a/src/commands/add.ts +++ b/src/commands/add.ts @@ -9,6 +9,7 @@ class Add extends Command { return option.setName("riot-id").setDescription("Riot ID: 'Name#Tag'").setRequired(true) }); } + async execute(interaction: Interaction) { if (!interaction.isChatInputCommand()) return; @@ -20,7 +21,7 @@ class Add extends Command { const player = await client.addPlayer(gameName, tagLine); if (player) - await interaction.reply({content: `${player} Hinzugefügt!`, ephemeral: true}); + await interaction.reply({content: `${player} hinzugefügt!`, ephemeral: true}); else await interaction.reply({content: "Fehler!", ephemeral: true}); } diff --git a/src/commands/list.ts b/src/commands/list.ts new file mode 100644 index 0000000..05b7770 --- /dev/null +++ b/src/commands/list.ts @@ -0,0 +1,53 @@ +import {Interaction, EmbedBuilder, APIEmbedField, codeBlock} from "discord.js"; +import {Command} from "../command"; +import {UEMEloBot} from "../bot"; +import {eloToNumber, Player} from "../player"; + +class List extends Command { + constructor() { + super("list", "Spieler auflisten"); + } + async execute(interaction: Interaction) { + if (!interaction.isChatInputCommand()) + return; + + let players = (interaction.client as UEMEloBot).players; + const maxNameLength = players.reduce((max: number, next: Player) => Math.max(max, next.toString().length), 0); + const maxProgressDigits = players.reduce((max, next) => Math.max(max, Math.abs(next.getProgress()).toString().length), 0); + + // sort by progress, then current elo, descending + players.sort((a, b) => { + const diff = b.getProgress() - a.getProgress(); + if (diff != 0) + return diff; + return eloToNumber(b.currentElo) - eloToNumber(a.currentElo); + }); + + let ranking = players.reduce((before, player, index) => { + const placement = `${index + 1})`.padStart(3, '0'); + const fill = "-".repeat(maxNameLength - `${player}`.length + 2); + const progress = Intl.NumberFormat(undefined, { + signDisplay: "always", + useGrouping: false, + }).format(player.getProgress()).padStart(maxProgressDigits + 1, " "); + return `${before}${placement} ${player} ${fill} ${progress} LP\n`; + }, ""); + ranking = ranking.trimEnd(); + + const baseURL = "https://raw.communitydragon.org/latest/plugins/rcp-fe-lol-shared-components/global/default/"; + const fileName = (players[0].currentElo?.tier.toLowerCase() ?? "unranked") + ".png"; + const iconURL = `${baseURL}${fileName}`; + + const embed = new EmbedBuilder() + .setTitle("UEM-Elo-Challenge Ranking") + .setFields([ + {name: "Leader:", value: players[0].toString()}, + {name: " ", value: codeBlock(ranking)} + ]) + .setThumbnail(iconURL); + + await interaction.reply({embeds: [embed]}); + } +} + +export default new List(); \ No newline at end of file diff --git a/src/commands/remove.ts b/src/commands/remove.ts new file mode 100644 index 0000000..60867d0 --- /dev/null +++ b/src/commands/remove.ts @@ -0,0 +1,30 @@ +import {Interaction, PermissionsBitField} from "discord.js"; +import {Command} from "../command"; +import {UEMEloBot} from "../bot"; + +class Remove extends Command { + constructor() { + super("remove", "Spieler entfernen"); + this.data.addStringOption(option => { + return option.setName("riot-id").setDescription("Riot ID: 'Name#Tag'").setRequired(true) + }).setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); + } + + async execute(interaction: Interaction) { + if (!interaction.isChatInputCommand()) + return; + + let client = interaction.client as UEMEloBot; + + const riotId = interaction.options.getString("riot-id", true); + const [gameName, tagLine] = riotId.split("#"); + + const player = await client.removePlayer(gameName, tagLine); + if (player) + await interaction.reply({content: `${player} entfernt!`, ephemeral: true}); + else + await interaction.reply({content: "Fehler!", ephemeral: true}); + } +} + +export default new Remove(); \ No newline at end of file diff --git a/src/player.ts b/src/player.ts index 2fb8c14..88247f5 100644 --- a/src/player.ts +++ b/src/player.ts @@ -78,6 +78,10 @@ export class Player { } } + getProgress(){ + return eloToNumber(this.currentElo) - eloToNumber(this.startElo); + } + toString() { return `${this.gameName}#${this.tagLine}`; } @@ -99,7 +103,9 @@ interface Elo { points: number } -function eloToNumber(elo: Elo){ +export function eloToNumber(elo: Elo | undefined){ + if (!elo) + return 0; let tiers: Record = { "CHALLENGER": 2800, "GRANDMASTER": 2800,