mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28172f7f8f | ||
|
|
cb5347cbb8 | ||
|
|
1ce0781d2d | ||
|
|
1257aa76d7 | ||
|
|
6ec3835896 | ||
|
|
506fe7d9bd | ||
|
|
14ef9f6295 | ||
|
|
0d76e1a29e | ||
|
|
9e42d7e8f5 | ||
|
|
364f97332b | ||
|
|
caa7bb8a65 | ||
|
|
3e956b34c1 | ||
|
|
038374e5aa | ||
|
|
dafd54f830 | ||
|
|
cb65e6b0af | ||
|
|
4ca8590c83 | ||
|
|
c5ef02d7e6 | ||
|
|
8175aa8715 | ||
|
|
b426634659 | ||
|
|
e92da1b700 | ||
|
|
7e0a2e88ee | ||
|
|
16afa8c2d4 | ||
|
|
907288455a | ||
|
|
64689e4e3b | ||
|
|
294377846a | ||
|
|
70e4cbaba2 | ||
|
|
9e2f9526fb | ||
|
|
84bec20fa5 |
No files matched your search
@@ -29,4 +29,4 @@ jobs:
|
|||||||
unzip dist.zip
|
unzip dist.zip
|
||||||
|
|
||||||
- name: Run bot
|
- name: Run bot
|
||||||
run: NODE_ENV=production GH_TOKEN=${{ secrets.GH_TOKEN }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} WARGAMING_APPLICATION_ID=${{ secrets.WARGAMING_APPLICATION_ID }} node --enable-source-maps --trace-warnings bot.js
|
run: NODE_ENV=production GH_TOKEN=${{ secrets.GH_TOKEN }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} WARGAMING_APPLICATION_ID=${{ secrets.WARGAMING_APPLICATION_ID }} node --enable-source-maps --trace-warnings bot.cjs
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
import { DefaultTheme, defineConfig } from 'vitepress';
|
import { compareVersions } from 'compare-versions';
|
||||||
|
import { readdirSync } from 'fs';
|
||||||
|
import { parse } from 'path';
|
||||||
|
import { defineConfig } from 'vitepress';
|
||||||
import { getSidebar } from 'vitepress-plugin-auto-sidebar';
|
import { getSidebar } from 'vitepress-plugin-auto-sidebar';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -9,17 +12,27 @@ export default defineConfig({
|
|||||||
themeConfig: {
|
themeConfig: {
|
||||||
nav: [
|
nav: [
|
||||||
{ text: 'Home', link: '/' },
|
{ text: 'Home', link: '/' },
|
||||||
{ text: 'Examples', link: '/markdown-examples' },
|
{ text: 'Guide', link: '/guide/about' },
|
||||||
],
|
],
|
||||||
|
|
||||||
sidebar: getSidebar({
|
sidebar: [
|
||||||
collapsed: false,
|
...getSidebar({
|
||||||
contentDirs: ['guide', 'legal', 'changelogs'],
|
collapsed: false,
|
||||||
contentRoot: '/docs/',
|
contentDirs: ['guide', 'legal'],
|
||||||
}) as DefaultTheme.Sidebar,
|
contentRoot: '/docs/',
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
text: 'Changelogs',
|
||||||
|
items: readdirSync('./docs/changelogs')
|
||||||
|
.map((file) => parse(file).name)
|
||||||
|
.sort(compareVersions)
|
||||||
|
.map((name) => ({ text: name, link: `/changelogs/${name}.html` })),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' },
|
{ icon: 'github', link: 'https://github.com/tresabhi/blitzkrieg' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Blitzkrieg 1.12.1
|
||||||
|
|
||||||
|
A duo of nasty bugs fixed.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Fixed a tank index and id mismatch
|
||||||
|
- Reverted username pattern infrence in command username inputs
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Blitzkrieg 1.12.2
|
||||||
|
|
||||||
|
A much needed room service is here!
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
- Tier selection is now easier
|
||||||
|
- Tier options across all commands have been unified to a single style
|
||||||
|
- Tiers are now sorted from `10` to `1`
|
||||||
|
- Tiers now show up in the format `Tier {tier_number} - {tier_roman_numeral}` (example: `Tier 8 - VIII`)
|
||||||
|
- Removed powered by footer as links are provided regardless
|
||||||
|
- Changed invite instructions to instead use application directory
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Guide link on the website is now fixed
|
||||||
|
- Versions now show up in the correct order in the navigation bar
|
||||||
|
- Added Blitzkrieg's GitHub link instead of the default Vitepress
|
||||||
|
- Changed examples to guide in the navigation bar
|
||||||
|
- Clan name and icon now show up with multi-tank filters
|
||||||
|
- Removed a random `console.log`
|
||||||
|
|
||||||
|
## Technical Changes
|
||||||
|
|
||||||
|
- Added `knip`
|
||||||
|
- Removed a lot of unused files and dependencies
|
||||||
|
- Updated all dependencies to their latest
|
||||||
|
- Code split `bot.ts`
|
||||||
|
- `client` and `octokit` now reside separately
|
||||||
@@ -1,10 +1,3 @@
|
|||||||
# Inviting the Bot
|
# Inviting the Bot
|
||||||
|
|
||||||
It's quite simple really. Just follow the steps below:
|
Go to [application directory for Blitzkrieg](https://discord.com/application-directory/1097673957865443370) and click "Add to Server." Voila! You're ready to go.
|
||||||
|
|
||||||
1. Join a Discord server that already has Blitzkrieg installed or [the official Discord Server](https://discord.gg/nDt7AjGJQH).
|
|
||||||
2. Click on the bot's profile.
|
|
||||||
3. Click the "Add to Server" button under the bot's name and ID.
|
|
||||||
4. Select what server you want it in and see what permissions you seem fit for the bot.
|
|
||||||
|
|
||||||
Voila! You're ready to go.
|
|
||||||
+1
-1
@@ -15,7 +15,7 @@ hero:
|
|||||||
link: guide/install
|
link: guide/install
|
||||||
- theme: alt
|
- theme: alt
|
||||||
text: Guide
|
text: Guide
|
||||||
link: /guide
|
link: /guide/about
|
||||||
|
|
||||||
features:
|
features:
|
||||||
- title: Clean and Efficient UI
|
- title: Clean and Efficient UI
|
||||||
|
|||||||
+1
-1
@@ -2,6 +2,6 @@
|
|||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --enable-source-maps --trace-warnings server.js"
|
"start": "node --enable-source-maps --trace-warnings server.cjs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+21
-19
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkrieg",
|
"name": "blitzkrieg",
|
||||||
"version": "1.12.0",
|
"version": "1.12.1",
|
||||||
"description": "",
|
"description": "🎉 All-in-one Discord bot for everything World of Tanks Blitz",
|
||||||
"main": "src/server.ts",
|
"main": "src/server.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:bot": "vite-node --script scripts/build --build=bot",
|
"build:bot": "node scripts/build --build=bot",
|
||||||
"build:server": "vite-node --script scripts/build --build=server",
|
"build:server": "node scripts/build --build=server",
|
||||||
"build:docs": "vitepress build docs",
|
"build:docs": "vitepress build docs",
|
||||||
"build:ratingsleaderboard": "vite-node --script scripts/buildRatingsLeaderboard",
|
"build:ratingsleaderboard": "vite-node --script scripts/buildRatingsLeaderboard",
|
||||||
"build": "vite-node --script scripts/build --build=all",
|
"build": "node scripts/build --build=all",
|
||||||
"dev:bot": "yarn build:bot --dev && yarn start:bot",
|
"dev:bot": "yarn build:bot --dev && yarn start:bot",
|
||||||
"dev:server": "yarn build:server --dev && yarn start:server",
|
"dev:server": "yarn build:server --dev && yarn start:server",
|
||||||
"dev:docs": "vitepress dev docs",
|
"dev:docs": "vitepress dev docs",
|
||||||
@@ -19,37 +19,39 @@
|
|||||||
"publish:ratingsleaderboard": "vite-node --script scripts/buildRatingsLeaderboard --publish",
|
"publish:ratingsleaderboard": "vite-node --script scripts/buildRatingsLeaderboard --publish",
|
||||||
"zip": "zip -r dist.zip dist",
|
"zip": "zip -r dist.zip dist",
|
||||||
"lint": "npx tsc",
|
"lint": "npx tsc",
|
||||||
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\""
|
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
||||||
|
"knip": "knip",
|
||||||
|
"update": "yarn upgrade --latest"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/rest": "^20.0.1",
|
"@octokit/rest": "^20.0.1",
|
||||||
"@radix-ui/colors": "^0.1.8",
|
"@radix-ui/colors": "^2.1.0",
|
||||||
"@resvg/resvg-js": "^2.4.1",
|
"@resvg/resvg-js": "^2.4.1",
|
||||||
"bepaint": "^0.1.0-beta.3",
|
"bepaint": "^0.1.0-beta.3",
|
||||||
"discord.js": "^14.12.0",
|
"discord.js": "^14.13.0",
|
||||||
"esbuild": "^0.18.10",
|
"esbuild": "^0.19.2",
|
||||||
"escape-html": "^1.0.3",
|
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"false": "^0.0.4",
|
|
||||||
"fuzzysort": "^2.0.4",
|
"fuzzysort": "^2.0.4",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"markdown-escape": "^2.0.0",
|
"markdown-escape": "^2.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"satori": "^0.9.1",
|
"satori": "^0.10.3",
|
||||||
"vite-node": "^0.33.0",
|
"vite-node": "^0.34.2",
|
||||||
"vitepress-plugin-auto-sidebar": "^1.1.0"
|
"vitepress-plugin-auto-sidebar": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@total-typescript/ts-reset": "^0.4.2",
|
"@total-typescript/ts-reset": "^0.5.1",
|
||||||
"@types/escape-html": "^1.0.2",
|
"@types/escape-html": "^1.0.2",
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/lodash": "^4.14.195",
|
"@types/lodash": "^4.14.197",
|
||||||
"@types/markdown-escape": "^1.1.0",
|
"@types/markdown-escape": "^1.1.0",
|
||||||
"@types/node": "^20.2.1",
|
"@types/node": "^20.5.3",
|
||||||
"@types/react": "^18.2.7",
|
"@types/react": "^18.2.21",
|
||||||
"prettier": "^3.0.0",
|
"compare-versions": "^6.1.0",
|
||||||
|
"knip": "^2.19.9",
|
||||||
|
"prettier": "^3.0.2",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.0.4",
|
||||||
"vitepress": "^1.0.0-beta.3"
|
"vitepress": "^1.0.0-rc.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BuildOptions, build } from 'esbuild';
|
import { build } from 'esbuild';
|
||||||
import { copyFile, mkdirSync, rmSync } from 'fs';
|
import { copyFile, mkdirSync, rmSync } from 'fs';
|
||||||
import { argv } from 'process';
|
import { argv } from 'process';
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ if (isProd) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const commonOptions: BuildOptions = {
|
const commonOptions = {
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
loader: {
|
loader: {
|
||||||
'.node': 'copy',
|
'.node': 'copy',
|
||||||
+1
-14
@@ -1,19 +1,6 @@
|
|||||||
import { Octokit } from '@octokit/rest';
|
import { client } from './core/discord/client';
|
||||||
import { Client, GatewayIntentBits } from 'discord.js';
|
|
||||||
import { secrets } from './core/node/secrets';
|
import { secrets } from './core/node/secrets';
|
||||||
import { registerErrorHandlers } from './events/error';
|
import { registerErrorHandlers } from './events/error';
|
||||||
import guildMemberAdd from './events/guildMemberAdd';
|
|
||||||
import interactionCreate from './events/interactionCreate';
|
|
||||||
import ready from './events/ready';
|
|
||||||
|
|
||||||
export const client = new Client({
|
|
||||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
|
||||||
})
|
|
||||||
.on('ready', ready)
|
|
||||||
.on('guildMemberAdd', guildMemberAdd)
|
|
||||||
.on('interactionCreate', interactionCreate);
|
|
||||||
|
|
||||||
export const octokit = new Octokit({ auth: secrets.GH_TOKEN });
|
|
||||||
|
|
||||||
registerErrorHandlers();
|
registerErrorHandlers();
|
||||||
client.login(secrets.DISCORD_TOKEN);
|
client.login(secrets.DISCORD_TOKEN);
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
import packageJSON from '../../package.json' assert { type: 'json' };
|
import packageJSON from '../../package.json' assert { type: 'json' };
|
||||||
import { client } from '../bot';
|
|
||||||
import { tankopedia } from '../core/blitz/tankopedia';
|
import { tankopedia } from '../core/blitz/tankopedia';
|
||||||
import { tankAverages } from '../core/blitzstars/tankAverages';
|
import { tankAverages } from '../core/blitzstars/tankAverages';
|
||||||
|
import { client } from '../core/discord/client';
|
||||||
import embedInfo from '../core/discord/embedInfo';
|
import embedInfo from '../core/discord/embedInfo';
|
||||||
import markdownTable from '../core/discord/markdownTable';
|
import markdownTable from '../core/discord/markdownTable';
|
||||||
import getClientId from '../core/node/getClientId';
|
import getClientId from '../core/node/getClientId';
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
|
|||||||
)
|
)
|
||||||
)[player.id];
|
)[player.id];
|
||||||
|
|
||||||
|
const tierOption = interaction.options.getString('tier');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
await fullStats(
|
await fullStats(
|
||||||
commandGroup,
|
commandGroup,
|
||||||
@@ -74,7 +76,7 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
|
|||||||
'tank-type':
|
'tank-type':
|
||||||
interaction.options.getString('tank-type') ?? undefined,
|
interaction.options.getString('tank-type') ?? undefined,
|
||||||
nation: interaction.options.getString('nation') ?? undefined,
|
nation: interaction.options.getString('nation') ?? undefined,
|
||||||
tier: interaction.options.getInteger('tier') ?? undefined,
|
tier: tierOption ? parseInt(tierOption) : undefined,
|
||||||
'tree-type': (interaction.options.getString('tree-type') ??
|
'tree-type': (interaction.options.getString('tree-type') ??
|
||||||
undefined) as TreeTypeString | undefined,
|
undefined) as TreeTypeString | undefined,
|
||||||
} satisfies Partial<MultiTankFilters>)
|
} satisfies Partial<MultiTankFilters>)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
import GenericStats from '../components/GenericStats';
|
import GenericStats from '../components/GenericStats';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
import getBlitzClan from '../core/blitz/getBlitzClan';
|
import getBlitzClan from '../core/blitz/getBlitzClan';
|
||||||
@@ -74,8 +73,6 @@ export const inactiveCommand: CommandRegistry = {
|
|||||||
|
|
||||||
{!hasInactiveMembers && <NoData type={NoDataType.PlayersInPeriod} />}
|
{!hasInactiveMembers && <NoData type={NoDataType.PlayersInPeriod} />}
|
||||||
{hasInactiveMembers && <GenericStats stats={inactive} />}
|
{hasInactiveMembers && <GenericStats stats={inactive} />}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.Wargaming} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import * as Tanks from '../components/Tanks';
|
import * as Tanks from '../components/Tanks';
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
@@ -15,6 +14,7 @@ import {
|
|||||||
tankopedia,
|
tankopedia,
|
||||||
tankopediaInfo,
|
tankopediaInfo,
|
||||||
} from '../core/blitz/tankopedia';
|
} from '../core/blitz/tankopedia';
|
||||||
|
import addTierChoices from '../core/discord/addTierChoices';
|
||||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||||
@@ -52,24 +52,7 @@ export const ownedTanksCommand: CommandRegistry = {
|
|||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
.setName('owned-tanks')
|
.setName('owned-tanks')
|
||||||
.setDescription("Shows a player's owned tanks")
|
.setDescription("Shows a player's owned tanks")
|
||||||
.addStringOption((option) =>
|
.addStringOption(addTierChoices)
|
||||||
option
|
|
||||||
.setName('tier')
|
|
||||||
.setDescription('The tier you want to see')
|
|
||||||
.setChoices(
|
|
||||||
{ name: 'Tier I (1)', value: '1' },
|
|
||||||
{ name: 'Tier II (2)', value: '2' },
|
|
||||||
{ name: 'Tier III (3)', value: '3' },
|
|
||||||
{ name: 'Tier IV (4)', value: '4' },
|
|
||||||
{ name: 'Tier V (5)', value: '5' },
|
|
||||||
{ name: 'Tier VI (6)', value: '6' },
|
|
||||||
{ name: 'Tier VII (7)', value: '7' },
|
|
||||||
{ name: 'Tier VIII (8)', value: '8' },
|
|
||||||
{ name: 'Tier IX (9)', value: '9' },
|
|
||||||
{ name: 'Tier X (10)', value: '10' },
|
|
||||||
)
|
|
||||||
.setRequired(true),
|
|
||||||
)
|
|
||||||
.addStringOption(addUsernameChoices),
|
.addStringOption(addUsernameChoices),
|
||||||
|
|
||||||
async handler(interaction) {
|
async handler(interaction) {
|
||||||
@@ -170,8 +153,6 @@ export const ownedTanksCommand: CommandRegistry = {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.Wargaming} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
|
|||||||
)
|
)
|
||||||
)[player.id];
|
)[player.id];
|
||||||
|
|
||||||
|
const tierOption = interaction.options.getString('tier');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
await stats(
|
await stats(
|
||||||
commandGroup,
|
commandGroup,
|
||||||
@@ -72,7 +74,7 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
|
|||||||
'tank-type':
|
'tank-type':
|
||||||
interaction.options.getString('tank-type') ?? undefined,
|
interaction.options.getString('tank-type') ?? undefined,
|
||||||
nation: interaction.options.getString('nation') ?? undefined,
|
nation: interaction.options.getString('nation') ?? undefined,
|
||||||
tier: interaction.options.getInteger('tier') ?? undefined,
|
tier: tierOption ? parseInt(tierOption) : undefined,
|
||||||
'tree-type': (interaction.options.getString('tree-type') ??
|
'tree-type': (interaction.options.getString('tree-type') ??
|
||||||
undefined) as TreeTypeString | undefined,
|
undefined) as TreeTypeString | undefined,
|
||||||
} satisfies Partial<MultiTankFilters>)
|
} satisfies Partial<MultiTankFilters>)
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import { theme } from '../stitches.config';
|
|
||||||
|
|
||||||
export enum PoweredByType {
|
|
||||||
BlitzStars,
|
|
||||||
Wargaming,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PoweredByProps {
|
|
||||||
type: PoweredByType;
|
|
||||||
footer?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const POWERED_BY_IMAGES: Record<PoweredByType, string> = {
|
|
||||||
[PoweredByType.BlitzStars]:
|
|
||||||
'https://www.blitzstars.com/assets/images/4b4cb591.TankyMcPewpew.png',
|
|
||||||
[PoweredByType.Wargaming]: 'https://i.imgur.com/jADGWm0.png',
|
|
||||||
};
|
|
||||||
|
|
||||||
const POWERED_BY_NAMES: Record<PoweredByType, string> = {
|
|
||||||
[PoweredByType.BlitzStars]: 'BlitzStars',
|
|
||||||
[PoweredByType.Wargaming]: 'Wargaming',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function PoweredBy({ type, footer }: PoweredByProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: footer === undefined ? 'space-around' : 'space-between',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{footer !== undefined && <div style={{ display: 'flex' }}>{footer}</div>}
|
|
||||||
|
|
||||||
<div style={{ display: 'flex', gap: 4 }}>
|
|
||||||
<img src={POWERED_BY_IMAGES[type]} style={{ height: 16, width: 16 }} />
|
|
||||||
<span style={{ color: theme.colors.textLowContrast, fontSize: 16 }}>
|
|
||||||
Powered by {POWERED_BY_NAMES[type]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
export const CYCLIC_API = 'https://blitzkrieg.cyclic.app';
|
export const CYCLIC_API = 'https://blitzkrieg-embeds.cyclic.app';
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { AllStats } from '../../types/accountInfo';
|
|
||||||
|
|
||||||
export default function diffStats(stats1: AllStats, stats2: AllStats) {
|
|
||||||
function diff(value: (allStats: AllStats) => number) {
|
|
||||||
return value(stats2) - value(stats1);
|
|
||||||
}
|
|
||||||
function max(value: (allStats: AllStats) => number) {
|
|
||||||
return Math.max(value(stats1), value(stats2));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
battles: diff((a) => a.battles),
|
|
||||||
wins: diff((a) => a.wins),
|
|
||||||
capture_points: diff((a) => a.capture_points),
|
|
||||||
damage_dealt: diff((a) => a.damage_dealt),
|
|
||||||
damage_received: diff((a) => a.damage_received),
|
|
||||||
dropped_capture_points: diff((a) => a.dropped_capture_points),
|
|
||||||
frags: diff((a) => a.frags),
|
|
||||||
frags8p: diff((a) => a.frags8p),
|
|
||||||
hits: diff((a) => a.hits),
|
|
||||||
losses: diff((a) => a.losses),
|
|
||||||
max_frags: max((a) => a.max_frags),
|
|
||||||
max_xp: max((a) => a.max_xp),
|
|
||||||
shots: diff((a) => a.shots),
|
|
||||||
spotted: diff((a) => a.spotted),
|
|
||||||
survived_battles: diff((a) => a.survived_battles),
|
|
||||||
win_and_survived: diff((a) => a.win_and_survived),
|
|
||||||
xp: diff((a) => a.xp),
|
|
||||||
} satisfies AllStats;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Thanks, August!
|
||||||
|
* https://stackoverflow.com/a/41358305/12294756
|
||||||
|
*/
|
||||||
|
const ROMAN = {
|
||||||
|
M: 1000,
|
||||||
|
CM: 900,
|
||||||
|
D: 500,
|
||||||
|
CD: 400,
|
||||||
|
C: 100,
|
||||||
|
XC: 90,
|
||||||
|
L: 50,
|
||||||
|
XL: 40,
|
||||||
|
X: 10,
|
||||||
|
IX: 9,
|
||||||
|
V: 5,
|
||||||
|
IV: 4,
|
||||||
|
I: 1,
|
||||||
|
};
|
||||||
|
const ROMAN_KEYS = Object.keys(ROMAN) as (keyof typeof ROMAN)[];
|
||||||
|
|
||||||
|
export default function numberToRomanNumeral(value: number) {
|
||||||
|
let string = '';
|
||||||
|
|
||||||
|
ROMAN_KEYS.forEach((index) => {
|
||||||
|
const part = Math.floor(value / ROMAN[index]);
|
||||||
|
value -= part * ROMAN[index];
|
||||||
|
string += index.repeat(part);
|
||||||
|
});
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
@@ -40,13 +40,15 @@ export const TANK_NAMES = new Promise<string[]>(async (resolve) => {
|
|||||||
export const TANK_NAMES_DIACRITICS = TANK_NAMES.then((tankNames) =>
|
export const TANK_NAMES_DIACRITICS = TANK_NAMES.then((tankNames) =>
|
||||||
Promise.all(
|
Promise.all(
|
||||||
tankNames.map(async (tankName, index) => {
|
tankNames.map(async (tankName, index) => {
|
||||||
const name = tankName ?? `Unknown Tank ${(await TANKS)[index].tank_id}`;
|
const id = (await TANKS)[index].tank_id;
|
||||||
|
const name = tankName ?? `Unknown Tank ${id}`;
|
||||||
const diacriticless = deburr(name);
|
const diacriticless = deburr(name);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
original: name,
|
original: name,
|
||||||
diacriticless,
|
diacriticless,
|
||||||
combined: `${name}${diacriticless}`,
|
combined: `${name}${diacriticless}`,
|
||||||
|
id,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import sumStats from '../blitz/sumStats';
|
|
||||||
import { emptyAllStats } from './getDiffedTankStats';
|
|
||||||
import { tankAverages } from './tankAverages';
|
|
||||||
|
|
||||||
console.log('Calculating player average...');
|
|
||||||
export const playerAverage = Object.entries(await tankAverages).reduce(
|
|
||||||
(accumulator, [, tankAverage]) => {
|
|
||||||
return sumStats([accumulator, tankAverage.all]);
|
|
||||||
},
|
|
||||||
emptyAllStats,
|
|
||||||
);
|
|
||||||
console.log('Calculated player average');
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
||||||
import { octokit } from '../../bot';
|
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
import { octokit } from '../express/octokit';
|
||||||
|
|
||||||
export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-db' };
|
export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-db' };
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { StatType } from '../../renderers/stats';
|
|||||||
import { tankopediaInfo } from '../blitz/tankopedia';
|
import { tankopediaInfo } from '../blitz/tankopedia';
|
||||||
import addPeriodSubCommands from './addPeriodSubCommands';
|
import addPeriodSubCommands from './addPeriodSubCommands';
|
||||||
import addTankChoices from './addTankChoices';
|
import addTankChoices from './addTankChoices';
|
||||||
|
import addTierChoices from './addTierChoices';
|
||||||
import addUsernameChoices from './addUsernameChoices';
|
import addUsernameChoices from './addUsernameChoices';
|
||||||
|
|
||||||
export default async function addStatTypeSubCommandGroups(
|
export default async function addStatTypeSubCommandGroups(
|
||||||
@@ -61,13 +62,8 @@ export default async function addStatTypeSubCommandGroups(
|
|||||||
)
|
)
|
||||||
.setRequired(false),
|
.setRequired(false),
|
||||||
)
|
)
|
||||||
.addIntegerOption((option) =>
|
.addStringOption((option) =>
|
||||||
option
|
addTierChoices(option).setRequired(false),
|
||||||
.setName('tier')
|
|
||||||
.setDescription('Tier')
|
|
||||||
.setMinValue(1)
|
|
||||||
.setMaxValue(10)
|
|
||||||
.setRequired(false),
|
|
||||||
)
|
)
|
||||||
.addStringOption((option) =>
|
.addStringOption((option) =>
|
||||||
option
|
option
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { SlashCommandStringOption } from 'discord.js';
|
||||||
|
import { range } from 'lodash';
|
||||||
|
import numberToRomanNumeral from '../blitz/numberToRomanNumeral';
|
||||||
|
|
||||||
|
export default function addTierChoices(option: SlashCommandStringOption) {
|
||||||
|
return option
|
||||||
|
.setName('tier')
|
||||||
|
.setDescription('The tier you want to see')
|
||||||
|
.setChoices(
|
||||||
|
...range(10, 0).map((tier) => ({
|
||||||
|
name: `Tier ${tier} - ${numberToRomanNumeral(tier)}`,
|
||||||
|
value: `${tier}`,
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.setRequired(true);
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
CacheType,
|
CacheType,
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { go } from 'fuzzysort';
|
import { go } from 'fuzzysort';
|
||||||
import { TANKS, TANK_NAMES_DIACRITICS } from '../blitz/tankopedia';
|
import { TANK_NAMES_DIACRITICS } from '../blitz/tankopedia';
|
||||||
|
|
||||||
export default async function autocompleteTanks(
|
export default async function autocompleteTanks(
|
||||||
interaction: AutocompleteInteraction<CacheType>,
|
interaction: AutocompleteInteraction<CacheType>,
|
||||||
@@ -19,10 +19,10 @@ export default async function autocompleteTanks(
|
|||||||
keys: ['combined'],
|
keys: ['combined'],
|
||||||
limit: 10,
|
limit: 10,
|
||||||
}).map(
|
}).map(
|
||||||
async (item, index) =>
|
async (item) =>
|
||||||
({
|
({
|
||||||
name: item.obj.original,
|
name: item.obj.original,
|
||||||
value: `${(await TANKS)[index].tank_id}`,
|
value: `${item.obj.id}`,
|
||||||
}) satisfies ApplicationCommandOptionChoiceData<string>,
|
}) satisfies ApplicationCommandOptionChoiceData<string>,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { Client, GatewayIntentBits } from 'discord.js';
|
||||||
|
import guildMemberAdd from '../../events/guildMemberAdd';
|
||||||
|
import interactionCreate from '../../events/interactionCreate';
|
||||||
|
import ready from '../../events/ready';
|
||||||
|
|
||||||
|
export const client = new Client({
|
||||||
|
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
||||||
|
})
|
||||||
|
.on('ready', ready)
|
||||||
|
.on('guildMemberAdd', guildMemberAdd)
|
||||||
|
.on('interactionCreate', interactionCreate);
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import listPlayers, {
|
import listPlayers, {
|
||||||
usernamePattern,
|
|
||||||
usernamePatternWithoutPosition,
|
usernamePatternWithoutPosition,
|
||||||
} from '../blitz/listPlayers';
|
} from '../blitz/listPlayers';
|
||||||
import throwError from '../node/throwError';
|
import throwError from '../node/throwError';
|
||||||
@@ -20,7 +19,7 @@ export default async function resolvePlayerFromCommand(
|
|||||||
const displayName = interaction.guild?.members.cache
|
const displayName = interaction.guild?.members.cache
|
||||||
.get(interaction.user.id)
|
.get(interaction.user.id)
|
||||||
?.displayName.match(usernamePatternWithoutPosition)?.[0];
|
?.displayName.match(usernamePatternWithoutPosition)?.[0];
|
||||||
const username = commandUsername?.match(usernamePattern)?.[0] ?? displayName;
|
const username = commandUsername ?? displayName;
|
||||||
|
|
||||||
if (username === undefined) {
|
if (username === undefined) {
|
||||||
throw throwError(
|
throw throwError(
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import { ButtonBuilder, ButtonStyle } from 'discord.js';
|
|
||||||
|
|
||||||
// TODO: ADD THIS AGAIN IMMEDIATELY
|
|
||||||
export const supportBlitzStars = new ButtonBuilder()
|
|
||||||
.setLabel('Support BlitzStars')
|
|
||||||
.setURL('https://www.blitzstars.com/supporters')
|
|
||||||
.setStyle(ButtonStyle.Link);
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { Octokit } from '@octokit/rest';
|
||||||
|
import { secrets } from '../node/secrets';
|
||||||
|
|
||||||
|
export const octokit = new Octokit({ auth: secrets.GH_TOKEN });
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import { EmbedBuilder, TextChannel } from 'discord.js';
|
import { EmbedBuilder, TextChannel } from 'discord.js';
|
||||||
import discord from '../../discord.json' assert { type: 'json' };
|
import discord from '../../discord.json' assert { type: 'json' };
|
||||||
import { client } from '../bot';
|
|
||||||
import { NEGATIVE_COLOR } from '../constants/colors';
|
import { NEGATIVE_COLOR } from '../constants/colors';
|
||||||
|
import { client } from '../core/discord/client';
|
||||||
import isDev from '../core/node/isDev';
|
import isDev from '../core/node/isDev';
|
||||||
|
|
||||||
const PROCESS_ERROR_EVENTS = ['uncaughtException'];
|
const PROCESS_ERROR_EVENTS = ['uncaughtException'];
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import * as Graph from '../components/Graph';
|
import * as Graph from '../components/Graph';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||||
@@ -118,8 +117,6 @@ export default async function evolution<Type extends StatType>(
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{plot.length === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
{plot.length === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.BlitzStars} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import GenericAllStats from '../components/GenericAllStats';
|
import GenericAllStats from '../components/GenericAllStats';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import TierWeights, { TierWeightsRecord } from '../components/TierWeights';
|
import TierWeights, { TierWeightsRecord } from '../components/TierWeights';
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
@@ -35,7 +34,7 @@ export default async function fullStats<Type extends StatType>(
|
|||||||
let nameDiscriminator: string | undefined;
|
let nameDiscriminator: string | undefined;
|
||||||
let image: string | undefined;
|
let image: string | undefined;
|
||||||
|
|
||||||
if (type === 'player') {
|
if (type === 'player' || type === 'multi-tank') {
|
||||||
const clan = (
|
const clan = (
|
||||||
await getWargamingResponse<PlayerClanData>(
|
await getWargamingResponse<PlayerClanData>(
|
||||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${secrets.WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${secrets.WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||||
@@ -49,7 +48,6 @@ export default async function fullStats<Type extends StatType>(
|
|||||||
} else if (type === 'tank') {
|
} else if (type === 'tank') {
|
||||||
nameDiscriminator = `(${await resolveTankName(filters as number)})`;
|
nameDiscriminator = `(${await resolveTankName(filters as number)})`;
|
||||||
image = (await tankopedia)[filters as number]?.images.normal;
|
image = (await tankopedia)[filters as number]?.images.normal;
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { diffed, order } = await getDiffedTankStats(server, id, start, end);
|
const { diffed, order } = await getDiffedTankStats(server, id, start, end);
|
||||||
@@ -165,8 +163,6 @@ export default async function fullStats<Type extends StatType>(
|
|||||||
supplementaryStats={supplementaryStats}
|
supplementaryStats={supplementaryStats}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.BlitzStars} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import AllStatsOverview from '../components/AllStatsOverview';
|
import AllStatsOverview from '../components/AllStatsOverview';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import { TreeTypeString } from '../components/Tanks';
|
import { TreeTypeString } from '../components/Tanks';
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
@@ -45,7 +44,7 @@ export default async function stats<Type extends StatType>(
|
|||||||
let nameDiscriminator: string | undefined;
|
let nameDiscriminator: string | undefined;
|
||||||
let image: string | undefined;
|
let image: string | undefined;
|
||||||
|
|
||||||
if (type === 'player') {
|
if (type === 'player' || type === 'multi-tank') {
|
||||||
const clan = (
|
const clan = (
|
||||||
await getWargamingResponse<PlayerClanData>(
|
await getWargamingResponse<PlayerClanData>(
|
||||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${secrets.WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${secrets.WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||||
@@ -168,8 +167,6 @@ export default async function stats<Type extends StatType>(
|
|||||||
|
|
||||||
{!stats?.battles && <NoData type={NoDataType.BattlesInPeriod} />}
|
{!stats?.battles && <NoData type={NoDataType.BattlesInPeriod} />}
|
||||||
{stats?.battles > 0 && overview}
|
{stats?.battles > 0 && overview}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.BlitzStars} footer={footer} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import * as Breakdown from '../components/Breakdown';
|
import * as Breakdown from '../components/Breakdown';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
|
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
import Wrapper from '../components/Wrapper';
|
import Wrapper from '../components/Wrapper';
|
||||||
import calculateWN8 from '../core/blitz/calculateWN8';
|
import calculateWN8 from '../core/blitz/calculateWN8';
|
||||||
@@ -27,8 +26,6 @@ export default async function today(
|
|||||||
showTotal = true,
|
showTotal = true,
|
||||||
naked?: boolean,
|
naked?: boolean,
|
||||||
) {
|
) {
|
||||||
console.log(maximized);
|
|
||||||
|
|
||||||
const { diffed, order } = await getDiffedTankStats(
|
const { diffed, order } = await getDiffedTankStats(
|
||||||
server,
|
server,
|
||||||
id,
|
id,
|
||||||
@@ -174,8 +171,6 @@ export default async function today(
|
|||||||
|
|
||||||
{rows.length === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
{rows.length === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
||||||
{rows.length > 0 && <Breakdown.Root>{rows}</Breakdown.Root>}
|
{rows.length > 0 && <Breakdown.Root>{rows}</Breakdown.Root>}
|
||||||
|
|
||||||
<PoweredBy type={PoweredByType.BlitzStars} />
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user