mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: heavy usage of await
This commit is contained in:
1 parent
18360dfe8f
commit
91af52b4b8
14 files changed
+569
-666
No files matched your search
@@ -77,6 +77,7 @@ export default async function interactionCreate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await interaction.deferReply();
|
||||||
command.execute(interaction);
|
command.execute(interaction);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -86,9 +87,8 @@ export default async function interactionCreate(
|
|||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'There was an error while executing this command!',
|
content: 'There was an error while executing this command!',
|
||||||
ephemeral: true,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const executionStart = new Date().getTime();
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -22,7 +22,7 @@ export default {
|
|||||||
const currentTime = new Date().getTime();
|
const currentTime = new Date().getTime();
|
||||||
const uptime = currentTime - executionStart;
|
const uptime = currentTime - executionStart;
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
embeds: [
|
embeds: [
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setTitle(`${client.user?.username} debug information`)
|
.setTitle(`${client.user?.username} debug information`)
|
||||||
|
|||||||
+96
-95
@@ -43,106 +43,107 @@ export default {
|
|||||||
if (!extractedUser) return;
|
if (!extractedUser) return;
|
||||||
|
|
||||||
const { name, server } = extractedUser;
|
const { name, server } = extractedUser;
|
||||||
const command = `eligible ${server} ${name} ${clan}`;
|
|
||||||
|
|
||||||
getBlitzAccount(interaction, command, name, server, async (account) => {
|
const blitzAccount = await getBlitzAccount(interaction, name, server);
|
||||||
getBlitzStarsAccount(
|
if (!blitzAccount) return;
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
account.account_id,
|
|
||||||
name,
|
|
||||||
async (data) => {
|
|
||||||
const issues: string[] = [];
|
|
||||||
|
|
||||||
if (clan === 'sklld') {
|
const blitzStarsAccount = await getBlitzStarsAccount(
|
||||||
if (data.period30d.all.battles < 150) {
|
interaction,
|
||||||
issues.push(
|
blitzAccount.account_id,
|
||||||
`**Battles**: ${data.period30d.all.battles} (${
|
name,
|
||||||
data.period30d.all.battles - 150
|
);
|
||||||
})`,
|
if (!blitzStarsAccount) return;
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.period30d.avg_tier < 8) {
|
|
||||||
issues.push(
|
|
||||||
`**Tier**: ${data.period30d.avg_tier.toFixed(2)} (${(
|
|
||||||
data.period30d.avg_tier - 8
|
|
||||||
).toFixed(2)})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.period30d.special.winrate < 60) {
|
|
||||||
issues.push(
|
|
||||||
`**Winrate**: ${data.period30d.special.winrate.toFixed(2)}% (${(
|
|
||||||
data.period30d.special.winrate - 60
|
|
||||||
).toFixed(2)}%)`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.period30d.wn8 < 2100) {
|
|
||||||
issues.push(
|
|
||||||
`**WN8**: ${data.period30d.wn8.toFixed(0)} (${(
|
|
||||||
data.period30d.wn8 - 2100
|
|
||||||
).toFixed(0)})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.period30d.special.dpb < 2400) {
|
|
||||||
issues.push(
|
|
||||||
`**Damage per battle**: ${data.period30d.special.dpb.toFixed(
|
|
||||||
0,
|
|
||||||
)} (${(data.period30d.special.dpb - 2400).toFixed(0)})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (data.statistics.all.battles < 1500) {
|
|
||||||
issues.push(
|
|
||||||
`**Battles**: ${data.statistics.all.battles} (${
|
|
||||||
data.statistics.all.battles - 1500
|
|
||||||
})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.statistics.special.winrate < 53) {
|
|
||||||
issues.push(
|
|
||||||
`**Winrate**: ${data.statistics.special.winrate.toFixed(
|
|
||||||
2,
|
|
||||||
)}% (${(data.statistics.special.winrate - 53).toFixed(2)}%)`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const eligible = issues.length === 0;
|
const issues: string[] = [];
|
||||||
|
|
||||||
await interaction.editReply({
|
if (clan === 'sklld') {
|
||||||
embeds: [
|
if (blitzStarsAccount.period30d.all.battles < 150) {
|
||||||
poweredByBlitzStars(
|
issues.push(
|
||||||
new EmbedBuilder()
|
`**Battles**: ${blitzStarsAccount.period30d.all.battles} (${
|
||||||
.setTitle(
|
blitzStarsAccount.period30d.all.battles - 150
|
||||||
`${markdownEscape(data.nickname)} is ${
|
})`,
|
||||||
eligible ? '' : 'not '
|
);
|
||||||
}eligible for ${CLANS[clan].name}`,
|
}
|
||||||
)
|
if (blitzStarsAccount.period30d.avg_tier < 8) {
|
||||||
.setColor(eligible ? POSITIVE_COLOR : NEGATIVE_COLOR)
|
issues.push(
|
||||||
.setDescription(
|
`**Tier**: ${blitzStarsAccount.period30d.avg_tier.toFixed(2)} (${(
|
||||||
`${
|
blitzStarsAccount.period30d.avg_tier - 8
|
||||||
eligible
|
).toFixed(2)})`,
|
||||||
? `${markdownEscape(
|
);
|
||||||
data.nickname,
|
}
|
||||||
)} meets all the requirements set for ${
|
if (blitzStarsAccount.period30d.special.winrate < 60) {
|
||||||
CLANS[clan].name
|
issues.push(
|
||||||
}.`
|
`**Winrate**: ${blitzStarsAccount.period30d.special.winrate.toFixed(
|
||||||
: `${markdownEscape(
|
2,
|
||||||
data.nickname,
|
)}% (${(blitzStarsAccount.period30d.special.winrate - 60).toFixed(
|
||||||
)}'s shortcomings for ${CLANS[clan].name} (${
|
2,
|
||||||
clan === 'sklld' ? '30 days stats' : 'career stats'
|
)}%)`,
|
||||||
}):\n\n${issues.join('\n')}`
|
);
|
||||||
}\n\n${blitzLinks(data)}`,
|
}
|
||||||
),
|
if (blitzStarsAccount.period30d.wn8 < 2100) {
|
||||||
),
|
issues.push(
|
||||||
],
|
`**WN8**: ${blitzStarsAccount.period30d.wn8.toFixed(0)} (${(
|
||||||
});
|
blitzStarsAccount.period30d.wn8 - 2100
|
||||||
|
).toFixed(0)})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (blitzStarsAccount.period30d.special.dpb < 2400) {
|
||||||
|
issues.push(
|
||||||
|
`**Damage per battle**: ${blitzStarsAccount.period30d.special.dpb.toFixed(
|
||||||
|
0,
|
||||||
|
)} (${(blitzStarsAccount.period30d.special.dpb - 2400).toFixed(0)})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (blitzStarsAccount.statistics.all.battles < 1500) {
|
||||||
|
issues.push(
|
||||||
|
`**Battles**: ${blitzStarsAccount.statistics.all.battles} (${
|
||||||
|
blitzStarsAccount.statistics.all.battles - 1500
|
||||||
|
})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (blitzStarsAccount.statistics.special.winrate < 53) {
|
||||||
|
issues.push(
|
||||||
|
`**Winrate**: ${blitzStarsAccount.statistics.special.winrate.toFixed(
|
||||||
|
2,
|
||||||
|
)}% (${(blitzStarsAccount.statistics.special.winrate - 53).toFixed(
|
||||||
|
2,
|
||||||
|
)}%)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
const eligible = issues.length === 0;
|
||||||
`Showing ${data.nickname}'s eligibility for ${CLANS[clan].name}`,
|
|
||||||
);
|
await interaction.editReply({
|
||||||
},
|
embeds: [
|
||||||
);
|
poweredByBlitzStars(
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setTitle(
|
||||||
|
`${markdownEscape(blitzStarsAccount.nickname)} is ${
|
||||||
|
eligible ? '' : 'not '
|
||||||
|
}eligible for ${CLANS[clan].name}`,
|
||||||
|
)
|
||||||
|
.setColor(eligible ? POSITIVE_COLOR : NEGATIVE_COLOR)
|
||||||
|
.setDescription(
|
||||||
|
`${
|
||||||
|
eligible
|
||||||
|
? `${markdownEscape(
|
||||||
|
blitzStarsAccount.nickname,
|
||||||
|
)} meets all the requirements set for ${CLANS[clan].name}.`
|
||||||
|
: `${markdownEscape(
|
||||||
|
blitzStarsAccount.nickname,
|
||||||
|
)}'s shortcomings for ${CLANS[clan].name} (${
|
||||||
|
clan === 'sklld' ? '30 days stats' : 'career stats'
|
||||||
|
}):\n\n${issues.join('\n')}`
|
||||||
|
}\n\n${blitzLinks(blitzStarsAccount)}`,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Showing ${blitzStarsAccount.nickname}'s eligibility for ${CLANS[clan].name}`,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
@@ -10,7 +10,7 @@ import { client } from '../index.js';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -18,7 +18,7 @@ export default {
|
|||||||
.setDescription('All the help you need about the bot'),
|
.setDescription('All the help you need about the bot'),
|
||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
embeds: [
|
embeds: [
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setTitle(`${client.user?.username} help`)
|
.setTitle(`${client.user?.username} help`)
|
||||||
|
|||||||
+56
-64
@@ -3,8 +3,9 @@ import markdownEscape from 'markdown-escape';
|
|||||||
import { CommandRegistry } from '../behaviors/interactionCreate.js';
|
import { CommandRegistry } from '../behaviors/interactionCreate.js';
|
||||||
import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js';
|
import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js';
|
||||||
import { BlitzServer } from '../constants/servers.js';
|
import { BlitzServer } from '../constants/servers.js';
|
||||||
import { ClanInfo } from '../types/clanInfo.js';
|
|
||||||
import { AccountInfo } from '../types/accountInfo.js';
|
import { AccountInfo } from '../types/accountInfo.js';
|
||||||
|
import { ClanInfo } from '../types/clanInfo.js';
|
||||||
|
import { Clan } from '../types/clanList.js';
|
||||||
import addServerChoices from '../utilities/addServerChoices.js';
|
import addServerChoices from '../utilities/addServerChoices.js';
|
||||||
import { args } from '../utilities/args.js';
|
import { args } from '../utilities/args.js';
|
||||||
import getClan from '../utilities/getClan.js';
|
import getClan from '../utilities/getClan.js';
|
||||||
@@ -14,13 +15,13 @@ const DEFAULT_THRESHOLD = 7;
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
.setName('inactive')
|
.setName('inactive')
|
||||||
.setDescription('Lists all inactive players')
|
.setDescription('Lists all inactive players')
|
||||||
.addStringOption(addServerChoices)
|
.addStringOption((option) => addServerChoices(option).setRequired(true))
|
||||||
.addStringOption((option) =>
|
.addStringOption((option) =>
|
||||||
option
|
option
|
||||||
.setName('name')
|
.setName('name')
|
||||||
@@ -39,73 +40,64 @@ export default {
|
|||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
const name = interaction.options.getString('name')!;
|
const name = interaction.options.getString('name')!;
|
||||||
const server = interaction.options.getString('server') as BlitzServer;
|
const server = interaction.options.getString('server') as BlitzServer;
|
||||||
const command = `inactive ${server} ${name}`;
|
|
||||||
|
|
||||||
getClan(interaction, command, name, server, async (clan) => {
|
const clan = (await getClan(interaction, name, server)) as Clan;
|
||||||
const threshold =
|
if (!clan) return;
|
||||||
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
|
||||||
const time = new Date().getTime() / 1000;
|
|
||||||
|
|
||||||
getWargamingResponse<ClanInfo>(
|
const threshold =
|
||||||
`https://api.wotblitz.${server}/wotb/clans/info/?application_id=${args['wargaming-application-id']}&clan_id=${clan.clan_id}`,
|
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
||||||
interaction,
|
const time = new Date().getTime() / 1000;
|
||||||
command,
|
|
||||||
async (clanInfo) => {
|
|
||||||
const memberIds = clanInfo[clan.clan_id].members_ids;
|
|
||||||
|
|
||||||
getWargamingResponse<AccountInfo>(
|
const clanInfo = await getWargamingResponse<ClanInfo>(
|
||||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${
|
`https://api.wotblitz.${server}/wotb/clans/info/?application_id=${args['wargaming-application-id']}&clan_id=${clan.clan_id}`,
|
||||||
args['wargaming-application-id']
|
);
|
||||||
}&account_id=${memberIds.join(',')}`,
|
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (playerPersonalData) => {
|
|
||||||
const inactiveInfo = memberIds
|
|
||||||
.map((memberId) => {
|
|
||||||
const member = playerPersonalData[memberId];
|
|
||||||
const inactiveDays =
|
|
||||||
(time - member.last_battle_time) / 60 / 60 / 24;
|
|
||||||
|
|
||||||
return [member.nickname, inactiveDays] as const;
|
const memberIds = clanInfo[clan.clan_id].members_ids;
|
||||||
})
|
|
||||||
.filter(([, inactiveDays]) => inactiveDays >= threshold)
|
|
||||||
.sort((a, b) => b[1] - a[1])
|
|
||||||
.map(([nickname, inactiveDays]) => {
|
|
||||||
const days = Math.floor(inactiveDays);
|
|
||||||
return `**${markdownEscape(nickname)}**: ${days} day${
|
|
||||||
days === 1 ? '' : 's'
|
|
||||||
}`;
|
|
||||||
});
|
|
||||||
const hasInactiveMembers = inactiveInfo.length > 0;
|
|
||||||
|
|
||||||
await interaction.editReply({
|
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||||
embeds: [
|
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${
|
||||||
new EmbedBuilder()
|
args['wargaming-application-id']
|
||||||
.setColor(
|
}&account_id=${memberIds.join(',')}`,
|
||||||
hasInactiveMembers ? NEGATIVE_COLOR : POSITIVE_COLOR,
|
);
|
||||||
)
|
|
||||||
.setTitle(
|
|
||||||
hasInactiveMembers
|
|
||||||
? `${markdownEscape(clan.name)}'s inactive members`
|
|
||||||
: `No inactive members in ${markdownEscape(clan.name)}`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
hasInactiveMembers
|
|
||||||
? `Players that exceed the threshold of ${threshold} days:\n\n${inactiveInfo.join(
|
|
||||||
'\n',
|
|
||||||
)}`
|
|
||||||
: `No players exceed the threshold of ${threshold} days.`,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(
|
const inactiveInfo = memberIds
|
||||||
`Displaying inactive members in ${clan.name} for ${threshold} days`,
|
.map((memberId) => {
|
||||||
);
|
const member = accountInfo[memberId];
|
||||||
},
|
const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24;
|
||||||
);
|
|
||||||
},
|
return [member.nickname, inactiveDays] as const;
|
||||||
);
|
})
|
||||||
|
.filter(([, inactiveDays]) => inactiveDays >= threshold)
|
||||||
|
.sort((a, b) => b[1] - a[1])
|
||||||
|
.map(([nickname, inactiveDays]) => {
|
||||||
|
const days = Math.floor(inactiveDays);
|
||||||
|
return `**${markdownEscape(nickname)}**: ${days} day${
|
||||||
|
days === 1 ? '' : 's'
|
||||||
|
}`;
|
||||||
|
});
|
||||||
|
const hasInactiveMembers = inactiveInfo.length > 0;
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(hasInactiveMembers ? NEGATIVE_COLOR : POSITIVE_COLOR)
|
||||||
|
.setTitle(
|
||||||
|
hasInactiveMembers
|
||||||
|
? `${markdownEscape(clan.name)}'s inactive members`
|
||||||
|
: `No inactive members in ${markdownEscape(clan.name)}`,
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
hasInactiveMembers
|
||||||
|
? `Players that exceed the threshold of ${threshold} days:\n\n${inactiveInfo.join(
|
||||||
|
'\n',
|
||||||
|
)}`
|
||||||
|
: `No players exceed the threshold of ${threshold} days.`,
|
||||||
|
),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Displaying inactive members in ${clan.name} for ${threshold} days`,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
@@ -9,15 +9,15 @@ import { args } from '../utilities/args.js';
|
|||||||
import getWargamingResponse from '../utilities/getWargamingResponse.js';
|
import getWargamingResponse from '../utilities/getWargamingResponse.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
.setName('searchplayers')
|
.setName('searchplayers')
|
||||||
.setDescription('Search players in a Blitz server')
|
.setDescription('Search players in a Blitz server')
|
||||||
.addStringOption(addServerChoices)
|
.addStringOption((option) => addServerChoices(option).setRequired(true))
|
||||||
.addStringOption(addIGNOption)
|
.addStringOption((option) => addIGNOption(option).setRequired(true))
|
||||||
.addIntegerOption((option) =>
|
.addIntegerOption((option) =>
|
||||||
option
|
option
|
||||||
.setName('limit')
|
.setName('limit')
|
||||||
@@ -26,34 +26,30 @@ export default {
|
|||||||
.setMaxValue(100),
|
.setMaxValue(100),
|
||||||
),
|
),
|
||||||
|
|
||||||
execute(interaction) {
|
async execute(interaction) {
|
||||||
const server = interaction.options.getString('server')!;
|
const server = interaction.options.getString('server')!;
|
||||||
const name = interaction.options.getString('name')!;
|
const name = interaction.options.getString('name')!;
|
||||||
const limit = interaction.options.getInteger('limit') ?? 25;
|
const limit = interaction.options.getInteger('limit') ?? 25;
|
||||||
const command = `searchplayers ${server} ${name} ${limit}`;
|
|
||||||
|
|
||||||
getWargamingResponse<Players>(
|
const players = await getWargamingResponse<Players>(
|
||||||
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}&limit=${limit}`,
|
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}&limit=${limit}`,
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
(players) => {
|
|
||||||
interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(SKILLED_COLOR)
|
|
||||||
.setTitle(`Player search results for "${markdownEscape(name)}"`)
|
|
||||||
.setDescription(
|
|
||||||
`\`\`\`${
|
|
||||||
players.length === 0
|
|
||||||
? 'No players found.'
|
|
||||||
: players
|
|
||||||
.map((player) => markdownEscape(player.nickname))
|
|
||||||
.join('\n')
|
|
||||||
}\`\`\``,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(SKILLED_COLOR)
|
||||||
|
.setTitle(`Player search results for "${markdownEscape(name)}"`)
|
||||||
|
.setDescription(
|
||||||
|
`\`\`\`${
|
||||||
|
players.length === 0
|
||||||
|
? 'No players found.'
|
||||||
|
: players
|
||||||
|
.map((player) => markdownEscape(player.nickname))
|
||||||
|
.join('\n')
|
||||||
|
}\`\`\``,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
+143
-172
@@ -3,7 +3,7 @@ import markdownEscape from 'markdown-escape';
|
|||||||
import { CommandRegistry } from '../behaviors/interactionCreate.js';
|
import { CommandRegistry } from '../behaviors/interactionCreate.js';
|
||||||
import { SKILLED_COLOR } from '../constants/colors.js';
|
import { SKILLED_COLOR } from '../constants/colors.js';
|
||||||
import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
||||||
import { PeriodStatistics } from '../types/statistics.js';
|
import { PeriodStatistics, PlayerStatistics } from '../types/statistics.js';
|
||||||
import addIGNOption from '../utilities/addIGNOption.js';
|
import addIGNOption from '../utilities/addIGNOption.js';
|
||||||
import addServerChoices from '../utilities/addServerChoices.js';
|
import addServerChoices from '../utilities/addServerChoices.js';
|
||||||
import { args } from '../utilities/args.js';
|
import { args } from '../utilities/args.js';
|
||||||
@@ -18,7 +18,7 @@ type Period = 'today' | '30' | '90' | 'career';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -48,185 +48,156 @@ export default {
|
|||||||
const { name, server } = extractedUser;
|
const { name, server } = extractedUser;
|
||||||
const command = `stats ${server} ${name} ${period}`;
|
const command = `stats ${server} ${name} ${period}`;
|
||||||
|
|
||||||
getBlitzAccount(
|
const blitzAccount = await getBlitzAccount(interaction, name, server);
|
||||||
|
if (!blitzAccount) return;
|
||||||
|
|
||||||
|
const blitzStarsAccount = (await getBlitzStarsAccount(
|
||||||
interaction,
|
interaction,
|
||||||
command,
|
blitzAccount.account_id,
|
||||||
name,
|
name,
|
||||||
server,
|
)) as PlayerStatistics;
|
||||||
async (blitzAccount) => {
|
if (!blitzStarsAccount) return;
|
||||||
getBlitzStarsAccount(
|
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
blitzAccount.account_id,
|
|
||||||
name,
|
|
||||||
async (blitzStarsAccount) => {
|
|
||||||
async function reply(stats: PeriodStatistics) {
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
poweredByBlitzStars(
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(SKILLED_COLOR)
|
|
||||||
.setTitle(
|
|
||||||
`${markdownEscape(blitzStarsAccount.nickname)}'s ${
|
|
||||||
period === 'career' ? period : `${period} day`
|
|
||||||
} stats`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
`${
|
|
||||||
period === 'today'
|
|
||||||
? '**⚠ Some stats are not available**\n\n'
|
|
||||||
: ''
|
|
||||||
}${[
|
|
||||||
['Winrate', `${stats.special.winrate.toFixed(2)}%`],
|
|
||||||
[
|
|
||||||
'Survival',
|
|
||||||
`${stats.special.survivalRate.toFixed(2)}%`,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Accuracy',
|
|
||||||
`${(
|
|
||||||
(stats.all.hits / stats.all.shots) *
|
|
||||||
100
|
|
||||||
).toFixed(2)}%`,
|
|
||||||
],
|
|
||||||
['WN8', stats.wn8.toFixed(0)],
|
|
||||||
['WN7', stats.wn7.toFixed(0)],
|
|
||||||
[],
|
|
||||||
['Battles', stats.all.battles],
|
|
||||||
['Wins', stats.all.wins],
|
|
||||||
['Losses', stats.all.losses],
|
|
||||||
['Average tier', stats.avg_tier.toFixed(2)],
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
'Shots per battle',
|
|
||||||
(stats.all.shots / stats.all.battles).toFixed(2),
|
|
||||||
],
|
|
||||||
['Hits per battle', stats.special.hpb.toFixed(2)],
|
|
||||||
['Damage per battle', stats.special.dpb.toFixed(0)],
|
|
||||||
['Kills per battle', stats.special.kpb.toFixed(2)],
|
|
||||||
['Spots per battle', stats.special.spb.toFixed(2)],
|
|
||||||
[
|
|
||||||
'XP per battle',
|
|
||||||
(stats.all.xp / stats.all.battles).toFixed(0),
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
'Damage ratio',
|
|
||||||
stats.special.damageRatio.toFixed(2),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Kills to death ratio',
|
|
||||||
stats.special.kdr.toFixed(2),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
.filter((array) => array[1] !== `${-Infinity}`)
|
|
||||||
.map((array) =>
|
|
||||||
array.length === 0
|
|
||||||
? ''
|
|
||||||
: `**${array[0]}**: ${array[1]}`,
|
|
||||||
)
|
|
||||||
.join('\n')}\n\n${blitzLinks(blitzStarsAccount)}`,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(
|
async function reply(stats: PeriodStatistics) {
|
||||||
`Showing ${blitzStarsAccount.nickname}'s ${period} stats`,
|
await interaction.editReply({
|
||||||
);
|
embeds: [
|
||||||
}
|
poweredByBlitzStars(
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(SKILLED_COLOR)
|
||||||
|
.setTitle(
|
||||||
|
`${markdownEscape(blitzStarsAccount.nickname)}'s ${
|
||||||
|
period === 'career' ? period : `${period} day`
|
||||||
|
} stats`,
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
`${
|
||||||
|
period === 'today'
|
||||||
|
? '**⚠ "Today" stats are in development. Some stats are not available/wrong.**\n\n'
|
||||||
|
: ''
|
||||||
|
}${[
|
||||||
|
['Winrate', `${stats.special.winrate.toFixed(2)}%`],
|
||||||
|
['Survival', `${stats.special.survivalRate.toFixed(2)}%`],
|
||||||
|
[
|
||||||
|
'Accuracy',
|
||||||
|
`${((stats.all.hits / stats.all.shots) * 100).toFixed(2)}%`,
|
||||||
|
],
|
||||||
|
['WN8', stats.wn8.toFixed(0)],
|
||||||
|
['WN7', stats.wn7.toFixed(0)],
|
||||||
|
[],
|
||||||
|
['Battles', stats.all.battles],
|
||||||
|
['Wins', stats.all.wins],
|
||||||
|
['Losses', stats.all.losses],
|
||||||
|
['Average tier', stats.avg_tier.toFixed(2)],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
'Shots per battle',
|
||||||
|
(stats.all.shots / stats.all.battles).toFixed(2),
|
||||||
|
],
|
||||||
|
['Hits per battle', stats.special.hpb.toFixed(2)],
|
||||||
|
['Damage per battle', stats.special.dpb.toFixed(0)],
|
||||||
|
['Kills per battle', stats.special.kpb.toFixed(2)],
|
||||||
|
['Spots per battle', stats.special.spb.toFixed(2)],
|
||||||
|
[
|
||||||
|
'XP per battle',
|
||||||
|
(stats.all.xp / stats.all.battles).toFixed(0),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
['Damage ratio', stats.special.damageRatio.toFixed(2)],
|
||||||
|
['Kills to death ratio', stats.special.kdr.toFixed(2)],
|
||||||
|
]
|
||||||
|
.filter((array) => array[1] !== `${-Infinity}`)
|
||||||
|
.map((array) =>
|
||||||
|
array.length === 0 ? '' : `**${array[0]}**: ${array[1]}`,
|
||||||
|
)
|
||||||
|
.join('\n')}\n\n${blitzLinks(blitzStarsAccount)}`,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
let stats: PeriodStatistics | null = null;
|
console.log(`Showing ${blitzStarsAccount.nickname}'s ${period} stats`);
|
||||||
|
}
|
||||||
|
|
||||||
if (period === 'career') {
|
let stats: PeriodStatistics | null = null;
|
||||||
stats = blitzStarsAccount.statistics;
|
|
||||||
} else if (period === 'today') {
|
|
||||||
getWargamingResponse<AccountInfo>(
|
|
||||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${blitzAccount.account_id}`,
|
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (accountInfo) => {
|
|
||||||
const a1 = blitzStarsAccount.statistics;
|
|
||||||
const a2 = accountInfo[blitzAccount.account_id].statistics;
|
|
||||||
|
|
||||||
const battles = a2.all.battles - a1.all.battles;
|
if (period === 'career') {
|
||||||
|
stats = blitzStarsAccount.statistics;
|
||||||
|
} else if (period === 'today') {
|
||||||
|
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||||
|
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${blitzAccount.account_id}`,
|
||||||
|
);
|
||||||
|
|
||||||
function pb(value: (allStats: AllStats) => number) {
|
const a1 = blitzStarsAccount.statistics;
|
||||||
return (value(a2.all) - value(a1.all)) / battles;
|
const a2 = accountInfo[blitzAccount.account_id].statistics;
|
||||||
}
|
|
||||||
function diff(value: (allStats: AllStats) => number) {
|
|
||||||
return value(a2.all) - value(a1.all);
|
|
||||||
}
|
|
||||||
function span(
|
|
||||||
value1: (allStats: AllStats) => number,
|
|
||||||
value2: (allStats: AllStats) => number,
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
(value1(a2.all) - value1(a1.all)) /
|
|
||||||
(value2(a2.all) - value2(a1.all))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
stats = {
|
const battles = a2.all.battles - a1.all.battles;
|
||||||
all: {
|
|
||||||
battles,
|
|
||||||
capture_points: pb((a) => a.capture_points),
|
|
||||||
damage_dealt: pb((a) => a.damage_dealt),
|
|
||||||
damage_received: pb((a) => a.damage_received),
|
|
||||||
dropped_capture_points: diff(
|
|
||||||
(a) => a.dropped_capture_points,
|
|
||||||
),
|
|
||||||
frags: pb((a) => a.frags),
|
|
||||||
frags8p: pb((a) => a.frags8p),
|
|
||||||
hits: diff((a) => a.hits),
|
|
||||||
losses: diff((a) => a.losses),
|
|
||||||
max_frags: pb((a) => a.max_frags),
|
|
||||||
max_frags_tank_id: pb((a) => a.max_frags_tank_id),
|
|
||||||
max_xp: pb((a) => a.max_xp),
|
|
||||||
max_xp_tank_id: pb((a) => a.max_xp_tank_id),
|
|
||||||
shots: diff((a) => a.shots),
|
|
||||||
spotted: pb((a) => a.spotted),
|
|
||||||
survived_battles: pb((a) => a.survived_battles),
|
|
||||||
win_and_survived: pb((a) => a.win_and_survived),
|
|
||||||
wins: diff((a) => a.wins),
|
|
||||||
xp: diff((a) => a.xp),
|
|
||||||
},
|
|
||||||
special: {
|
|
||||||
winrate: pb((a) => a.wins) * 100,
|
|
||||||
dpb: pb((a) => a.damage_dealt),
|
|
||||||
survivalRate: pb((a) => a.survived_battles) * 100,
|
|
||||||
damageRatio: span(
|
|
||||||
(a) => a.damage_dealt,
|
|
||||||
(a) => a.damage_received,
|
|
||||||
),
|
|
||||||
hitRate: pb((a) => a.hits / a.shots),
|
|
||||||
hpb: pb((a) => a.hits),
|
|
||||||
kdr:
|
|
||||||
diff((a) => a.frags) /
|
|
||||||
diff((a) => a.battles - a.survived_battles),
|
|
||||||
kpb: pb((a) => a.frags),
|
|
||||||
spb: pb((a) => a.spotted),
|
|
||||||
},
|
|
||||||
|
|
||||||
avg_tier: -Infinity,
|
function pb(value: (allStats: AllStats) => number) {
|
||||||
pwp: -Infinity,
|
return (value(a2.all) - value(a1.all)) / battles;
|
||||||
wn7: -Infinity,
|
}
|
||||||
wn8: -Infinity,
|
function diff(value: (allStats: AllStats) => number) {
|
||||||
};
|
return value(a2.all) - value(a1.all);
|
||||||
|
}
|
||||||
reply(stats);
|
function span(
|
||||||
},
|
value1: (allStats: AllStats) => number,
|
||||||
);
|
value2: (allStats: AllStats) => number,
|
||||||
} else {
|
) {
|
||||||
stats = blitzStarsAccount[`period${period}d`];
|
return (
|
||||||
}
|
(value1(a2.all) - value1(a1.all)) / (value2(a2.all) - value2(a1.all))
|
||||||
|
|
||||||
if (stats) {
|
|
||||||
reply(stats);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
stats = {
|
||||||
|
all: {
|
||||||
|
battles,
|
||||||
|
capture_points: pb((a) => a.capture_points),
|
||||||
|
damage_dealt: pb((a) => a.damage_dealt),
|
||||||
|
damage_received: pb((a) => a.damage_received),
|
||||||
|
dropped_capture_points: diff((a) => a.dropped_capture_points),
|
||||||
|
frags: pb((a) => a.frags),
|
||||||
|
frags8p: pb((a) => a.frags8p),
|
||||||
|
hits: diff((a) => a.hits),
|
||||||
|
losses: diff((a) => a.losses),
|
||||||
|
max_frags: pb((a) => a.max_frags),
|
||||||
|
max_frags_tank_id: pb((a) => a.max_frags_tank_id),
|
||||||
|
max_xp: pb((a) => a.max_xp),
|
||||||
|
max_xp_tank_id: pb((a) => a.max_xp_tank_id),
|
||||||
|
shots: diff((a) => a.shots),
|
||||||
|
spotted: pb((a) => a.spotted),
|
||||||
|
survived_battles: pb((a) => a.survived_battles),
|
||||||
|
win_and_survived: pb((a) => a.win_and_survived),
|
||||||
|
wins: diff((a) => a.wins),
|
||||||
|
xp: diff((a) => a.xp),
|
||||||
|
},
|
||||||
|
special: {
|
||||||
|
winrate: pb((a) => a.wins) * 100,
|
||||||
|
dpb: pb((a) => a.damage_dealt),
|
||||||
|
survivalRate: pb((a) => a.survived_battles) * 100,
|
||||||
|
damageRatio: span(
|
||||||
|
(a) => a.damage_dealt,
|
||||||
|
(a) => a.damage_received,
|
||||||
|
),
|
||||||
|
hitRate: pb((a) => a.hits / a.shots),
|
||||||
|
hpb: pb((a) => a.hits),
|
||||||
|
kdr:
|
||||||
|
diff((a) => a.frags) / diff((a) => a.battles - a.survived_battles),
|
||||||
|
kpb: pb((a) => a.frags),
|
||||||
|
spb: pb((a) => a.spotted),
|
||||||
|
},
|
||||||
|
|
||||||
|
avg_tier: -Infinity,
|
||||||
|
pwp: -Infinity,
|
||||||
|
wn7: -Infinity,
|
||||||
|
wn8: -Infinity,
|
||||||
|
};
|
||||||
|
|
||||||
|
reply(stats);
|
||||||
|
} else {
|
||||||
|
stats = blitzStarsAccount[`period${period}d`];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats) {
|
||||||
|
reply(stats);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
+43
-52
@@ -34,7 +34,7 @@ const COMP_TANKS = [
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -53,64 +53,55 @@ export default {
|
|||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
const tier = interaction.options.getInteger('tier')!;
|
const tier = interaction.options.getInteger('tier')!;
|
||||||
|
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
const extractedUser = await extractUser(interaction);
|
const extractedUser = await extractUser(interaction);
|
||||||
if (!extractedUser) return;
|
if (!extractedUser) return;
|
||||||
|
|
||||||
const { name, server } = extractedUser;
|
const { name, server } = extractedUser;
|
||||||
const command = `tanks ${server} ${name} ${tier}`;
|
|
||||||
|
|
||||||
getBlitzAccount(interaction, command, name, server, async (account) => {
|
const account = await getBlitzAccount(interaction, name, server);
|
||||||
getWargamingResponse<TanksStats>(
|
if (!account) return;
|
||||||
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}`,
|
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (tankStats) => {
|
|
||||||
const tanks = tankStats[account.account_id]
|
|
||||||
.map((tankData) => tankopedia.data[tankData.tank_id])
|
|
||||||
.filter((tank) => tank.tier === tier);
|
|
||||||
|
|
||||||
await interaction.editReply({
|
const tankStats = await getWargamingResponse<TanksStats>(
|
||||||
embeds: [
|
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}`,
|
||||||
new EmbedBuilder()
|
);
|
||||||
.setTitle(
|
const tanks = tankStats[account.account_id]
|
||||||
`${markdownEscape(account.nickname)}'s owned ${
|
.map((tankData) => tankopedia.data[tankData.tank_id])
|
||||||
tier === null ? '' : `tier ${tier} `
|
.filter((tank) => tank.tier === tier);
|
||||||
}tanks`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
`${
|
|
||||||
tanks.length === 0
|
|
||||||
? `No tanks found in tier ${tier}`
|
|
||||||
: tanks
|
|
||||||
.map(
|
|
||||||
(tank) =>
|
|
||||||
`${TANK_TYPE_EMOJIS[tank.type]} ${markdownEscape(
|
|
||||||
tank.name,
|
|
||||||
)} ${tank.is_premium ? '⭐' : ''}${
|
|
||||||
COMP_TANKS.includes(tank.tank_id) ? '🏆' : ''
|
|
||||||
}`,
|
|
||||||
)
|
|
||||||
.join('\n')
|
|
||||||
}\n\n**Legend**\n⭐ = Premium/Collector\n${
|
|
||||||
tier === 10 ? '🏆 = Comp Tank\n' : ''
|
|
||||||
}${TANK_TYPE_EMOJIS.heavyTank} = Heavy\n${
|
|
||||||
TANK_TYPE_EMOJIS.mediumTank
|
|
||||||
} = Medium\n${TANK_TYPE_EMOJIS.lightTank} = Light\n${
|
|
||||||
TANK_TYPE_EMOJIS['AT-SPG']
|
|
||||||
} = Tank Destroyer`,
|
|
||||||
)
|
|
||||||
.setColor(SKILLED_COLOR),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(
|
await interaction.editReply({
|
||||||
`Displaying ${account.nickname}'s owned tanks in tier ${tier}`,
|
embeds: [
|
||||||
);
|
new EmbedBuilder()
|
||||||
},
|
.setTitle(
|
||||||
);
|
`${markdownEscape(account.nickname)}'s owned ${
|
||||||
|
tier === null ? '' : `tier ${tier} `
|
||||||
|
}tanks`,
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
`${
|
||||||
|
tanks.length === 0
|
||||||
|
? `No tanks found in tier ${tier}`
|
||||||
|
: tanks
|
||||||
|
.map(
|
||||||
|
(tank) =>
|
||||||
|
`${TANK_TYPE_EMOJIS[tank.type]} ${markdownEscape(
|
||||||
|
tank.name,
|
||||||
|
)} ${tank.is_premium ? '⭐' : ''}${
|
||||||
|
COMP_TANKS.includes(tank.tank_id) ? '🏆' : ''
|
||||||
|
}`,
|
||||||
|
)
|
||||||
|
.join('\n')
|
||||||
|
}\n\n**Legend**\n⭐ = Premium/Collector\n${
|
||||||
|
tier === 10 ? '🏆 = Comp Tank\n' : ''
|
||||||
|
}${TANK_TYPE_EMOJIS.heavyTank} = Heavy\n${
|
||||||
|
TANK_TYPE_EMOJIS.mediumTank
|
||||||
|
} = Medium\n${TANK_TYPE_EMOJIS.lightTank} = Light\n${
|
||||||
|
TANK_TYPE_EMOJIS['AT-SPG']
|
||||||
|
} = Tank Destroyer`,
|
||||||
|
)
|
||||||
|
.setColor(SKILLED_COLOR),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(`Displaying ${account.nickname}'s owned tanks in tier ${tier}`);
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
+102
-119
@@ -13,7 +13,7 @@ import getWargamingResponse from '../utilities/getWargamingResponse.js';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -22,131 +22,114 @@ export default {
|
|||||||
.addStringOption((option) => addServerChoices(option).setRequired(true))
|
.addStringOption((option) => addServerChoices(option).setRequired(true))
|
||||||
.addStringOption((Option) => addIGNOption(Option).setRequired(true)),
|
.addStringOption((Option) => addIGNOption(Option).setRequired(true)),
|
||||||
|
|
||||||
execute(interaction) {
|
async execute(interaction) {
|
||||||
let name = interaction.options.getString('name')!;
|
let name = interaction.options.getString('name')!;
|
||||||
const server = interaction.options.getString('server') as BlitzServer;
|
const server = interaction.options.getString('server') as BlitzServer;
|
||||||
const command = `verify ${server} ${name}`;
|
const account = await getBlitzAccount(interaction, name, server);
|
||||||
|
|
||||||
getBlitzAccount(interaction, command, name, server, async (account) => {
|
if (!account) return;
|
||||||
name = account.nickname;
|
|
||||||
|
|
||||||
getWargamingResponse<PlayerClanData>(
|
name = account.nickname;
|
||||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}&extra=clan`,
|
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (clanData) => {
|
|
||||||
const clan = clanData[account.account_id].clan;
|
|
||||||
const clanTag = clan === null ? '' : ` [${clan!.tag}]`;
|
|
||||||
|
|
||||||
if (
|
const clanData = await getWargamingResponse<PlayerClanData>(
|
||||||
!interaction.guild?.members.me?.permissions.has('ManageNicknames')
|
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}&extra=clan`,
|
||||||
) {
|
);
|
||||||
interaction.editReply({
|
const clan = clanData[account.account_id]?.clan;
|
||||||
embeds: [
|
const clanTag = clan ? ` [${clan!.tag}]` : '';
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(NEGATIVE_COLOR)
|
|
||||||
.setTitle(
|
|
||||||
`${markdownEscape(
|
|
||||||
interaction.user.username,
|
|
||||||
)} failed to verify`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
"I don't have the permission to change your nickname.",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.warn(
|
if (!interaction.guild?.members.me?.permissions.has('ManageNicknames')) {
|
||||||
`${interaction.user.username} failed to verify because of no nickname permission.`,
|
interaction.editReply({
|
||||||
);
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(NEGATIVE_COLOR)
|
||||||
|
.setTitle(
|
||||||
|
`${markdownEscape(interaction.user.username)} failed to verify`,
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
"I don't have the permission to change your nickname.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
console.warn(
|
||||||
}
|
`${interaction.user.username} failed to verify because of no nickname permission.`,
|
||||||
|
|
||||||
if (interaction.member) {
|
|
||||||
const member = interaction.guild?.members.cache.get(
|
|
||||||
interaction.member?.user.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (member) {
|
|
||||||
await member
|
|
||||||
?.setNickname(
|
|
||||||
`${name} (${BLITZ_SERVERS_SHORT[server]})${clanTag}`,
|
|
||||||
)
|
|
||||||
.then(async () => {
|
|
||||||
if (interaction.guildId === discord.guild_id) {
|
|
||||||
if (
|
|
||||||
!interaction.guild?.members.me?.permissions.has(
|
|
||||||
'ManageRoles',
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(NEGATIVE_COLOR)
|
|
||||||
.setTitle(
|
|
||||||
`${markdownEscape(
|
|
||||||
interaction.user.username,
|
|
||||||
)} failed to verify`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
"I don't have the permission to change your manage roles.",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.warn(
|
|
||||||
`${interaction.user.username} failed to verify because of no manage roles permission.`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await member.roles.remove(discord.verify_role);
|
|
||||||
await member.roles.add(discord.peasant_role);
|
|
||||||
}
|
|
||||||
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(POSITIVE_COLOR)
|
|
||||||
.setTitle(`${interaction.user.username} is verified`)
|
|
||||||
.setDescription(
|
|
||||||
`The user is now verified as ${markdownEscape(
|
|
||||||
name,
|
|
||||||
)} (${BLITZ_SERVERS_SHORT[server]})${markdownEscape(
|
|
||||||
clanTag,
|
|
||||||
)}`,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`${interaction.user.username} verified as ${name} (${BLITZ_SERVERS_SHORT[server]})${clanTag}`,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(async () => {
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(NEGATIVE_COLOR)
|
|
||||||
.setTitle(
|
|
||||||
`${interaction.user.username} failed to verify`,
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
"I can't change your nickname because you have higher permissions than me.",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.warn(
|
|
||||||
'Failed to verify because of higher permissions.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.member) {
|
||||||
|
const member = interaction.guild?.members.cache.get(
|
||||||
|
interaction.member?.user.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (member) {
|
||||||
|
try {
|
||||||
|
await member.setNickname(
|
||||||
|
`${name} (${BLITZ_SERVERS_SHORT[server]})${clanTag}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (interaction.guildId === discord.guild_id) {
|
||||||
|
if (
|
||||||
|
!interaction.guild?.members.me?.permissions.has('ManageRoles')
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(NEGATIVE_COLOR)
|
||||||
|
.setTitle(
|
||||||
|
`${markdownEscape(
|
||||||
|
interaction.user.username,
|
||||||
|
)} failed to verify`,
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
"I don't have the permission to change your manage roles.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.warn(
|
||||||
|
`${interaction.user.username} failed to verify because of no manage roles permission.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await member.roles.remove(discord.verify_role);
|
||||||
|
await member.roles.add(discord.peasant_role);
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(POSITIVE_COLOR)
|
||||||
|
.setTitle(`${interaction.user.username} is verified`)
|
||||||
|
.setDescription(
|
||||||
|
`The user is now verified as ${markdownEscape(name)} (${
|
||||||
|
BLITZ_SERVERS_SHORT[server]
|
||||||
|
})${markdownEscape(clanTag)}`,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`${interaction.user.username} verified as ${name} (${BLITZ_SERVERS_SHORT[server]})${clanTag}`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(NEGATIVE_COLOR)
|
||||||
|
.setTitle(`${interaction.user.username} failed to verify`)
|
||||||
|
.setDescription(
|
||||||
|
"I can't change your nickname because you have higher permissions than me.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.warn('Failed to verify because of higher permissions.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
} satisfies CommandRegistry;
|
} satisfies CommandRegistry;
|
||||||
@@ -14,5 +14,5 @@ export type PlayerClanData = {
|
|||||||
clan_id: number;
|
clan_id: number;
|
||||||
emblem_set_id: number;
|
emblem_set_id: number;
|
||||||
};
|
};
|
||||||
};
|
} | null;
|
||||||
};
|
};
|
||||||
@@ -6,58 +6,49 @@ import {
|
|||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
||||||
import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js';
|
import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js';
|
||||||
import { Player, Players } from '../types/players.js';
|
import { Players } from '../types/players.js';
|
||||||
import { args } from './args.js';
|
import { args } from './args.js';
|
||||||
import getWargamingResponse from './getWargamingResponse.js';
|
import getWargamingResponse from './getWargamingResponse.js';
|
||||||
|
|
||||||
export default async function getBlitzAccount(
|
export default async function getBlitzAccount(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
command: string,
|
|
||||||
name: string,
|
name: string,
|
||||||
server: BlitzServer,
|
server: BlitzServer,
|
||||||
callback: (account: Player) => void,
|
|
||||||
) {
|
) {
|
||||||
const serverName = BLITZ_SERVERS[server];
|
const serverName = BLITZ_SERVERS[server];
|
||||||
|
|
||||||
getWargamingResponse<Players>(
|
const players = await getWargamingResponse<Players>(
|
||||||
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (players) => {
|
|
||||||
if (
|
|
||||||
players.length > 0 &&
|
|
||||||
players[0].nickname.toLowerCase() === name.toLowerCase()
|
|
||||||
) {
|
|
||||||
callback(players[0]);
|
|
||||||
} else {
|
|
||||||
// no exact match
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(NEGATIVE_COLOR)
|
|
||||||
.setTitle(`Account not found`)
|
|
||||||
.setDescription(
|
|
||||||
`I couldn't find "${markdownEscape(
|
|
||||||
name,
|
|
||||||
)}" in the ${serverName} server. I found ${
|
|
||||||
players
|
|
||||||
? players.length < 100
|
|
||||||
? players.length
|
|
||||||
: 'over 100'
|
|
||||||
: 0
|
|
||||||
} similarly spelled account${
|
|
||||||
players?.length !== 1 ? 's' : ''
|
|
||||||
}. ${
|
|
||||||
players && players.length > 0
|
|
||||||
? `Did you mean "${markdownEscape(players[0].nickname)}"? `
|
|
||||||
: ''
|
|
||||||
}Re-run the command and don't make typos.`,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`Account not found for ${name} in ${serverName} server.`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
players.length > 0 &&
|
||||||
|
players[0].nickname.toLowerCase() === name.toLowerCase()
|
||||||
|
) {
|
||||||
|
return players[0];
|
||||||
|
} else {
|
||||||
|
// no exact match
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(NEGATIVE_COLOR)
|
||||||
|
.setTitle(`Account not found`)
|
||||||
|
.setDescription(
|
||||||
|
`I couldn't find "${markdownEscape(
|
||||||
|
name,
|
||||||
|
)}" in the ${serverName} server. I found ${
|
||||||
|
players ? (players.length < 100 ? players.length : 'over 100') : 0
|
||||||
|
} similarly spelled account${players?.length !== 1 ? 's' : ''}. ${
|
||||||
|
players && players.length > 0
|
||||||
|
? `Did you mean "${markdownEscape(players[0].nickname)}"? `
|
||||||
|
: ''
|
||||||
|
}Use the \`/verify\` command to fix any issues or re-run the command and don't make typos.`,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Account not found for ${name} in ${serverName} server.`);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,35 @@
|
|||||||
import {
|
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||||
CacheType,
|
|
||||||
ChatInputCommandInteraction,
|
|
||||||
EmbedBuilder,
|
|
||||||
} from 'discord.js';
|
|
||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
|
||||||
import { PlayerStatistics } from '../types/statistics.js';
|
import { PlayerStatistics } from '../types/statistics.js';
|
||||||
import blitzStarsError from './blitzStarsError.js';
|
import errorEmbed from './errorEmbed.js';
|
||||||
|
|
||||||
export default async function getBlitzStarsAccount(
|
export default async function getBlitzStarsAccount(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
command: string,
|
|
||||||
accountId: number,
|
accountId: number,
|
||||||
name: string,
|
name: string,
|
||||||
callback: (account: PlayerStatistics) => void,
|
|
||||||
) {
|
) {
|
||||||
if (!interaction.deferred) await interaction.deferReply();
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`https://www.blitzstars.com/api/top/player/${accountId}`,
|
||||||
|
);
|
||||||
|
const parsed = (await response.json()) as PlayerStatistics;
|
||||||
|
|
||||||
fetch(`https://www.blitzstars.com/api/top/player/${accountId}`)
|
if (parsed.statistics) {
|
||||||
.then(async (response) => {
|
return parsed;
|
||||||
const data = (await response.json()) as PlayerStatistics;
|
} else throw new Error('No data to display');
|
||||||
|
} catch (error) {
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
errorEmbed(
|
||||||
|
'No data to display',
|
||||||
|
`${markdownEscape(name)} is not tracked by BlitzStars.`,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
if (data.statistics) {
|
console.log(`${name} is not tracked by BlitzStars.`);
|
||||||
callback(data);
|
|
||||||
} else {
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setTitle('No data to display')
|
|
||||||
.setDescription(
|
|
||||||
`${markdownEscape(name)} is not tracked by BlitzStars.`,
|
|
||||||
)
|
|
||||||
.setColor(NEGATIVE_COLOR),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`${name} is not tracked by BlitzStars.`);
|
return null;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch((error) => blitzStarsError(interaction, error, command));
|
|
||||||
}
|
}
|
||||||
+36
-39
@@ -6,55 +6,52 @@ import {
|
|||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
||||||
import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js';
|
import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js';
|
||||||
import { Clan, ClanList } from '../types/clanList.js';
|
import { ClanList } from '../types/clanList.js';
|
||||||
import { args } from './args.js';
|
import { args } from './args.js';
|
||||||
import getWargamingResponse from './getWargamingResponse.js';
|
import getWargamingResponse from './getWargamingResponse.js';
|
||||||
|
|
||||||
export default async function getClan(
|
export default async function getClan(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
command: string,
|
|
||||||
name: string,
|
name: string,
|
||||||
server: BlitzServer,
|
server: BlitzServer,
|
||||||
callback: (account: Clan) => void,
|
|
||||||
) {
|
) {
|
||||||
const serverName = BLITZ_SERVERS[server];
|
const serverName = BLITZ_SERVERS[server];
|
||||||
|
|
||||||
getWargamingResponse<ClanList>(
|
const clans = await getWargamingResponse<ClanList>(
|
||||||
`https://api.wotblitz.${server}/wotb/clans/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
`https://api.wotblitz.${server}/wotb/clans/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
||||||
interaction,
|
|
||||||
command,
|
|
||||||
async (clans) => {
|
|
||||||
if (
|
|
||||||
clans.length > 0 &&
|
|
||||||
(clans[0].name.toLowerCase() === name.toLowerCase() ||
|
|
||||||
clans[0].tag.toLowerCase() === name.toLowerCase())
|
|
||||||
) {
|
|
||||||
callback(clans[0]);
|
|
||||||
} else {
|
|
||||||
// no exact match
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [
|
|
||||||
new EmbedBuilder()
|
|
||||||
.setColor(NEGATIVE_COLOR)
|
|
||||||
.setTitle(`Clan not found`)
|
|
||||||
.setDescription(
|
|
||||||
`I couldn't find "${markdownEscape(
|
|
||||||
name,
|
|
||||||
)}" in the ${serverName} server. I found ${
|
|
||||||
clans ? (clans.length < 100 ? clans.length : 'over 100') : 0
|
|
||||||
} similarly spelled clan${clans?.length !== 1 ? 's' : ''}. ${
|
|
||||||
clans && clans.length > 0
|
|
||||||
? `Did you mean "${markdownEscape(
|
|
||||||
clans[0].name,
|
|
||||||
)}" or "${markdownEscape(clans[0].tag)}"? `
|
|
||||||
: ''
|
|
||||||
}Re-run the command, don't make typos.`,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`Clan not found for ${name} in ${serverName} server.`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
clans.length > 0 &&
|
||||||
|
(clans[0].name.toLowerCase() === name.toLowerCase() ||
|
||||||
|
clans[0].tag.toLowerCase() === name.toLowerCase())
|
||||||
|
) {
|
||||||
|
return clans[0];
|
||||||
|
} else {
|
||||||
|
// no exact match
|
||||||
|
await interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setColor(NEGATIVE_COLOR)
|
||||||
|
.setTitle(`Clan not found`)
|
||||||
|
.setDescription(
|
||||||
|
`I couldn't find "${markdownEscape(
|
||||||
|
name,
|
||||||
|
)}" in the ${serverName} server. I found ${
|
||||||
|
clans ? (clans.length < 100 ? clans.length : 'over 100') : 0
|
||||||
|
} similarly spelled clan${clans?.length !== 1 ? 's' : ''}. ${
|
||||||
|
clans && clans.length > 0
|
||||||
|
? `Did you mean "${markdownEscape(
|
||||||
|
clans[0].name,
|
||||||
|
)}" or "${markdownEscape(clans[0].tag)}"? `
|
||||||
|
: ''
|
||||||
|
}Re-run the command, don't make typos.`,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Clan not found for ${name} in ${serverName} server.`);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,17 @@
|
|||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import { WargamingResponse } from '../types/wargamingResponse.js';
|
import { WargamingResponse } from '../types/wargamingResponse.js';
|
||||||
import wargamingError from './wargamingError.js';
|
|
||||||
|
|
||||||
export default async function getWargamingResponse<Data extends object>(
|
export default async function getWargamingResponse<Data extends object>(
|
||||||
url: string,
|
url: string,
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
|
||||||
command: string,
|
|
||||||
callback: (data: Data) => void,
|
|
||||||
) {
|
) {
|
||||||
if (!interaction.deferred) await interaction.deferReply();
|
let parsed: WargamingResponse<Data>;
|
||||||
|
|
||||||
fetch(url)
|
const response = await fetch(url);
|
||||||
.then((response) => response.json() as Promise<WargamingResponse<Data>>)
|
parsed = (await response.json()) as WargamingResponse<Data>;
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 'ok') {
|
if (parsed.status === 'ok') {
|
||||||
callback(response.data);
|
return parsed.data;
|
||||||
} else {
|
} else {
|
||||||
wargamingError(
|
throw new Error(`Wargaming response status ${parsed.status}`);
|
||||||
interaction,
|
}
|
||||||
new Error(`Status ${response.status}`),
|
|
||||||
command,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => wargamingError(interaction, error, command));
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user