feat: cleaned up directories

This commit is contained in:
TresAbhi committed 2023-05-13 22:01:58 +00:00
1 parent 473ebfa46c
commit 613527e78f
41 files changed
+116 -832

No files matched your search

+3 -4
View File
@@ -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>),
)
+54
View File
@@ -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;
}
}
+57
View File
@@ -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;
}
}
+18
View File
@@ -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;
}
}
+26
View File
@@ -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);
}
+28
View File
@@ -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);
}
+5
View File
@@ -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;
}
}
+16
View File
@@ -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',
});
}
+53
View File
@@ -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: '🇱',
};
-6
View File
@@ -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.',
);
+8
View File
@@ -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');
}
+5
View File
@@ -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.
+8
View File
@@ -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);
}
+14
View File
@@ -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);
}
+9
View File
@@ -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);
}
+21
View File
@@ -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}`);
}
});
+6
View File
@@ -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;
}
+5
View File
@@ -0,0 +1,5 @@
const isDevBoolean = process.argv.includes('--dev');
export default function isDev() {
return isDevBoolean;
}