mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 03:29:51 +02:00
feat: cleaned up directories
This commit is contained in:
1 parent
473ebfa46c
commit
613527e78f
41 files changed
+116
-832
No files matched your search
@@ -4,7 +4,8 @@ import {
|
||||
CacheType,
|
||||
} from 'discord.js';
|
||||
import { go } from 'fuzzysort';
|
||||
import { tanks } from '../../utilities/tankopedia.js';
|
||||
import resolveTankName from '../../utilities/resolveTankName.js';
|
||||
import { tanks } from '../blitzstars/tankopedia.js';
|
||||
|
||||
export default async function tanksAutocomplete(
|
||||
interaction: AutocompleteInteraction<CacheType>,
|
||||
@@ -16,9 +17,7 @@ export default async function tanksAutocomplete(
|
||||
? go(focusedValue, tanks, { keys: ['name'], limit: 10 }).map(
|
||||
(item) =>
|
||||
({
|
||||
name: item.obj.name
|
||||
? item.obj.name
|
||||
: `Unknown Tank ${item.obj.tank_id}`,
|
||||
name: item.obj.name ? item.obj.name : resolveTankName(item.obj),
|
||||
value: `${item.obj.tank_id}`,
|
||||
} satisfies ApplicationCommandOptionChoiceData<string>),
|
||||
)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
} from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { NEGATIVE_COLOR } from '../../constants/colors.js';
|
||||
import { BLITZ_SERVERS, BlitzServer } from '../../constants/servers.js';
|
||||
import { Players } from '../../types/players.js';
|
||||
import { args } from '../process/args.js';
|
||||
import getWargamingResponse from './getWargamingResponse.js';
|
||||
|
||||
export default async function getBlitzAccount(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
name: string,
|
||||
server: BlitzServer,
|
||||
) {
|
||||
const serverName = BLITZ_SERVERS[server];
|
||||
|
||||
const players = await getWargamingResponse<Players>(
|
||||
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
} from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { NEGATIVE_COLOR } from '../../constants/colors.js';
|
||||
import { BLITZ_SERVERS, BlitzServer } from '../../constants/servers.js';
|
||||
import { ClanList } from '../../types/clanList.js';
|
||||
import { args } from '../process/args.js';
|
||||
import getWargamingResponse from './getWargamingResponse.js';
|
||||
|
||||
export default async function getClan(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
name: string,
|
||||
server: BlitzServer,
|
||||
) {
|
||||
const serverName = BLITZ_SERVERS[server];
|
||||
|
||||
const clans = await getWargamingResponse<ClanList>(
|
||||
`https://api.wotblitz.${server}/wotb/clans/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import fetch from 'node-fetch';
|
||||
import { WargamingResponse } from '../../types/wargamingResponse.js';
|
||||
|
||||
export default async function getWargamingResponse<Data extends object>(
|
||||
url: string,
|
||||
) {
|
||||
let parsed: WargamingResponse<Data>;
|
||||
|
||||
const response = await fetch(url);
|
||||
parsed = (await response.json()) as WargamingResponse<Data>;
|
||||
|
||||
if (parsed.status === 'ok') {
|
||||
return parsed.data;
|
||||
} else {
|
||||
console.error(`Wargaming response status ${parsed.status}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
} from 'discord.js';
|
||||
import { handleError } from '../../behaviors/error.js';
|
||||
import { NEGATIVE_COLOR } from '../../constants/colors.js';
|
||||
import { client } from '../../index.js';
|
||||
|
||||
export default async function wargamingError(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
error: Error,
|
||||
command: string,
|
||||
) {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(NEGATIVE_COLOR)
|
||||
.setTitle(`${client.user?.username} ran into an issue`)
|
||||
.setDescription('Wargaming returned an error. Please try again later.'),
|
||||
],
|
||||
});
|
||||
|
||||
console.log(`Wargaming returned an error`);
|
||||
handleError(error, client, command);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
} from 'discord.js';
|
||||
import { handleError } from '../behaviors/error.js';
|
||||
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
||||
import { client } from '../index.js';
|
||||
|
||||
export default async function blitzStarsError(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
error: Error,
|
||||
command: string,
|
||||
) {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(NEGATIVE_COLOR)
|
||||
.setTitle(`${client.user?.username} ran into an issue`)
|
||||
.setDescription(
|
||||
'BlitzStars returned an error. Please try again later.',
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
console.log(`BlitzStars returned an error`);
|
||||
handleError(error, client, command);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { BlitzServer } from '../../constants/servers.js';
|
||||
|
||||
export default function blitzStarsLinks(server: BlitzServer, nickname: string) {
|
||||
return `[View full stats](https://www.blitzstars.com/player/${server}/${nickname}) • [Support BlitzStars](https://www.blitzstars.com/supporters)`;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||
import fetch from 'node-fetch';
|
||||
import { PlayerPeriodicStatsCollection } from '../../types/statistics.js';
|
||||
import { notTrackedByBlitzStars } from '../interaction/notTrackedByBlitzStars.js';
|
||||
|
||||
export default async function getBlitzStarsAccount(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
accountId: number,
|
||||
) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://www.blitzstars.com/api/top/player/${accountId}`,
|
||||
);
|
||||
const parsed = (await response.json()) as PlayerPeriodicStatsCollection;
|
||||
|
||||
if (parsed.statistics) {
|
||||
return parsed;
|
||||
} else throw new Error('No data to display');
|
||||
} catch (error) {
|
||||
await interaction.editReply({
|
||||
embeds: [notTrackedByBlitzStars],
|
||||
});
|
||||
|
||||
console.log(`Not tracked by BlitzStars.`);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||
import fetch from 'node-fetch';
|
||||
import { PlayerStats } from '../../types/playerStats.js';
|
||||
|
||||
export default async function getPlayerStats(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
command: string,
|
||||
id: number,
|
||||
callback: (playerStats: PlayerStats) => void,
|
||||
) {
|
||||
fetch(`https://www.blitzstars.com/api/playerstats/${id}`).then(
|
||||
async (response) => {
|
||||
callback((await response.json()) as PlayerStats);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
|
||||
export default function poweredByBlitzStars(embed: EmbedBuilder) {
|
||||
return embed.setTimestamp().setFooter({
|
||||
text: 'Powered by BlitzStars',
|
||||
iconURL: 'https://www.blitzstars.com/assets/images/TankyMcPewpew.png',
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
export type TankType = 'heavyTank' | 'AT-SPG' | 'mediumTank' | 'lightTank';
|
||||
|
||||
export interface Tankopedia {
|
||||
status: 'ok'; // always will be ok since it is cached
|
||||
meta: {
|
||||
count: number;
|
||||
};
|
||||
data: {
|
||||
[tankId: number]: {
|
||||
name?: string;
|
||||
nation: string;
|
||||
is_premium: boolean;
|
||||
tier: number;
|
||||
cost: {
|
||||
price_credit: number;
|
||||
price_gold: number;
|
||||
};
|
||||
images: {
|
||||
preview: string;
|
||||
normal: string;
|
||||
};
|
||||
tank_id: number;
|
||||
type: TankType;
|
||||
description: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const tankopedia = (await (
|
||||
await fetch('https://www.blitzstars.com/bs-tankopedia.json')
|
||||
).json()) as Tankopedia;
|
||||
|
||||
export const tankIds = Object.keys(tankopedia.data) as unknown as number[];
|
||||
|
||||
export const tankNames = tankIds.map((id) => tankopedia.data[id].name);
|
||||
|
||||
export const tanks = tankIds.map((id) => tankopedia.data[id]);
|
||||
|
||||
export const TANK_TYPE_NAMES: Record<TankType, string> = {
|
||||
'AT-SPG': 'Tank Destroyer',
|
||||
heavyTank: 'Heavy Tank',
|
||||
mediumTank: 'Medium Tank',
|
||||
lightTank: 'Light Tank',
|
||||
};
|
||||
|
||||
export const TANK_TYPE_EMOJIS: Record<TankType, string> = {
|
||||
'AT-SPG': '🔽',
|
||||
heavyTank: '🇭',
|
||||
mediumTank: '🇲',
|
||||
lightTank: '🇱',
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
import errorEmbed from './errorEmbed.js';
|
||||
|
||||
export const badNicknameFormat = errorEmbed(
|
||||
'Bad nickname format',
|
||||
'I expected your nickname to be... \n\n```\nIN_GAME_NAME (SERVER) [CLAN_TAG]\n```\nUse the `/verify` command to setup your nickname correctly or manually provide me with your in-game name and server in the command.',
|
||||
);
|
||||
@@ -0,0 +1,8 @@
|
||||
export type TableInput = ([] | [string, string | number])[];
|
||||
|
||||
export default function cleanTable(input: TableInput) {
|
||||
return input
|
||||
.filter((array) => array[1] !== `${-Infinity}`)
|
||||
.map((array) => (array.length === 0 ? '' : `**${array[0]}**: ${array[1]}`))
|
||||
.join('\n');
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import isDev from '../process/isDev.js';
|
||||
|
||||
export default function cmdName(name: string) {
|
||||
return isDev() ? `${name}dev` : name;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,8 @@
|
||||
import { SlashCommandStringOption } from 'discord.js';
|
||||
|
||||
export default function addIGNOption(option: SlashCommandStringOption) {
|
||||
return option
|
||||
.setName('name')
|
||||
.setDescription('The username you use in Blitz')
|
||||
.setRequired(true);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { SlashCommandStringOption } from 'discord.js';
|
||||
import { BLITZ_SERVERS } from '../../constants/servers.js';
|
||||
|
||||
export default function addServerChoices(option: SlashCommandStringOption) {
|
||||
return option
|
||||
.setName('server')
|
||||
.setDescription('The Blitz server you are in')
|
||||
.addChoices(
|
||||
{ name: BLITZ_SERVERS.com, value: 'com' },
|
||||
{ name: BLITZ_SERVERS.eu, value: 'eu' },
|
||||
{ name: BLITZ_SERVERS.asia, value: 'asia' },
|
||||
)
|
||||
.setRequired(true);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { SlashCommandStringOption } from 'discord.js';
|
||||
|
||||
export default function addTankChoices(option: SlashCommandStringOption) {
|
||||
return option
|
||||
.setName('tank')
|
||||
.setDescription('The tank to get stats for')
|
||||
.setAutocomplete(true)
|
||||
.setRequired(true);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { argv } from 'process';
|
||||
|
||||
type ArgumentName = 'discord-token' | 'wargaming-application-id';
|
||||
|
||||
export const args: Record<ArgumentName, string> = {
|
||||
'discord-token': '',
|
||||
'wargaming-application-id': '',
|
||||
};
|
||||
|
||||
argv.forEach((arg) => {
|
||||
if (arg.includes('=')) {
|
||||
const [name, value] = arg.split('=');
|
||||
args[name as ArgumentName] = value;
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(args).forEach((arg) => {
|
||||
if (args[arg as ArgumentName] === '') {
|
||||
throw new Error(`Missing argument: ${arg}`);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
import discord from '../../../discord.json' assert { type: 'json' };
|
||||
import isDev from './isDev.js';
|
||||
|
||||
export default function getClientId() {
|
||||
return isDev() ? discord.client_id_dev : discord.client_id;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
const isDevBoolean = process.argv.includes('--dev');
|
||||
|
||||
export default function isDev() {
|
||||
return isDevBoolean;
|
||||
}
|
||||
Reference in new issue
Block a user