mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: 1.29.12
This commit is contained in:
1 parent
1d8c823703
commit
c8ba6b1eca
24 files changed
+482
-404
No files matched your search
@@ -1,11 +1,13 @@
|
||||
import {
|
||||
fetchAverageDefinitions,
|
||||
fetchDiscoveredIdsDefinitions,
|
||||
fetchGameDefinitions,
|
||||
fetchMapDefinitions,
|
||||
fetchTankDefinitions,
|
||||
fetchTankNames,
|
||||
} from '@blitzkit/core';
|
||||
} from "@blitzkit/core";
|
||||
|
||||
export const averageDefinitions = fetchAverageDefinitions();
|
||||
export const tankDefinitions = fetchTankDefinitions();
|
||||
export const gameDefinitions = fetchGameDefinitions();
|
||||
export const tankNames = fetchTankNames();
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
import { usersDatabase } from '../db/users';
|
||||
import { client } from '../discord/client';
|
||||
import { usersDatabase } from "../db/users";
|
||||
import { client } from "../discord/client";
|
||||
|
||||
const EXIT_EVENTS = [
|
||||
'beforeExit',
|
||||
'exit',
|
||||
'SIGINT',
|
||||
'SIGTERM',
|
||||
'SIGUSR1',
|
||||
'SIGUSR2',
|
||||
];
|
||||
const EXIT_EVENTS = ["SIGINT", "SIGTERM", "SIGUSR1", "SIGUSR2"];
|
||||
|
||||
async function cleanup() {
|
||||
console.log('Cleaning up...');
|
||||
let cleaningUp = false;
|
||||
|
||||
await Promise.all([usersDatabase.$disconnect(), client.destroy()]);
|
||||
async function cleanup(signal: string) {
|
||||
if (cleaningUp) return;
|
||||
cleaningUp = true;
|
||||
|
||||
console.log('Gracefully exiting...');
|
||||
console.log(`Cleaning up... (${signal})`);
|
||||
|
||||
try {
|
||||
await Promise.all([usersDatabase.$disconnect(), client.destroy()]);
|
||||
} catch (err) {
|
||||
console.error("Cleanup error:", err);
|
||||
}
|
||||
|
||||
console.log("Gracefully exiting...");
|
||||
|
||||
EXIT_EVENTS.forEach((event) => process.off(event, cleanup));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
export function registerProcesses() {
|
||||
process.on('uncaughtException', console.error);
|
||||
client.on('error', console.error);
|
||||
process.on("uncaughtException", (err) => {
|
||||
console.error("uncaughtException:", err);
|
||||
});
|
||||
|
||||
EXIT_EVENTS.forEach((event) => process.on(event, cleanup));
|
||||
process.on("unhandledRejection", (err) => {
|
||||
console.error("unhandledRejection:", err);
|
||||
});
|
||||
|
||||
client.on("error", console.error);
|
||||
|
||||
EXIT_EVENTS.forEach((event) => process.on(event, () => cleanup(event)));
|
||||
}
|
||||
@@ -3,8 +3,10 @@ import type { SupplementaryStats } from "@blitzkit/core/src/blitz/getAccountInfo
|
||||
import { calculateWN8 } from "@blitzkit/core/src/statistics/calculateWN8";
|
||||
import type { BlitzStats } from "@blitzkit/core/src/statistics/compositeStats";
|
||||
import { sumAllStats } from "@blitzkit/core/src/statistics/sumAllStats";
|
||||
import { tankDefinitions } from "../blitzkit/nonBlockingPromises";
|
||||
import { blitzStarsTankAverages } from "./tankAverages";
|
||||
import {
|
||||
averageDefinitions,
|
||||
tankDefinitions,
|
||||
} from "../blitzkit/nonBlockingPromises";
|
||||
|
||||
export interface StatFilters {
|
||||
nation?: string;
|
||||
@@ -16,13 +18,13 @@ export interface StatFilters {
|
||||
|
||||
export async function filterStats(
|
||||
{ diff, order }: DiffedTankStats,
|
||||
filters: StatFilters
|
||||
filters: StatFilters,
|
||||
) {
|
||||
// tank, if provided, takes priority over all other filters
|
||||
if (filters.tank) filters = { tank: filters.tank };
|
||||
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const awaitedTankAverages = await blitzStarsTankAverages;
|
||||
const awaitedTankAverages = await averageDefinitions;
|
||||
const filteredOrder = order.filter((id) => {
|
||||
const entry = awaitedTankDefinitions.tanks[id];
|
||||
|
||||
@@ -44,26 +46,28 @@ export async function filterStats(
|
||||
const stats = sumAllStats(filteredOrder.map((id) => diff[id]));
|
||||
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
|
||||
0
|
||||
awaitedTankAverages.averages[id]
|
||||
? accumulator + diff[id].battles
|
||||
: accumulator,
|
||||
0,
|
||||
);
|
||||
const battlesOfTanksWithTankDefinition = filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankDefinitions.tanks[id]
|
||||
? accumulator + diff[id].battles
|
||||
: accumulator,
|
||||
0
|
||||
0,
|
||||
);
|
||||
const supplementary = {
|
||||
WN8:
|
||||
filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankAverages[id]
|
||||
awaitedTankAverages.averages[id]
|
||||
? accumulator +
|
||||
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
|
||||
calculateWN8(awaitedTankAverages.averages[id].mu, diff[id]) *
|
||||
diff[id].battles
|
||||
: accumulator,
|
||||
0
|
||||
0,
|
||||
) / battlesOfTanksWithAverages,
|
||||
tier:
|
||||
filteredOrder.reduce<number>(
|
||||
@@ -72,7 +76,7 @@ export async function filterStats(
|
||||
? accumulator +
|
||||
awaitedTankDefinitions.tanks[id]!.tier * diff[id].battles
|
||||
: accumulator,
|
||||
0
|
||||
0,
|
||||
) / battlesOfTanksWithTankDefinition,
|
||||
} satisfies SupplementaryStats;
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import { BlitzStats } from '@blitzkit/core';
|
||||
import { context } from '@blitzkit/core/src/blitzkit/context';
|
||||
|
||||
interface SpecialStats {
|
||||
winrate: number;
|
||||
damageRatio: number;
|
||||
kdr: number;
|
||||
damagePerBattle: number;
|
||||
killsPerBattle: number;
|
||||
hitsPerBattle: number;
|
||||
spotsPerBattle: number;
|
||||
wpm: number;
|
||||
dpm: number;
|
||||
kpm: number;
|
||||
hitRate: number;
|
||||
survivalRate: number;
|
||||
}
|
||||
|
||||
export type Percentiles = [
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
];
|
||||
|
||||
export interface SpecialPercentiles {
|
||||
winRate: Percentiles;
|
||||
damageRatio: Percentiles;
|
||||
kdr: Percentiles;
|
||||
damagePerBattle: Percentiles;
|
||||
killsPerBattle: Percentiles;
|
||||
hitsPerBattle: Percentiles;
|
||||
spotsPerBattle: Percentiles;
|
||||
wpm: Percentiles;
|
||||
dpm: Percentiles;
|
||||
kpm: Percentiles;
|
||||
hitRate: Percentiles;
|
||||
survivalRate: Percentiles;
|
||||
}
|
||||
|
||||
export interface MeanSd {
|
||||
winrateMean: number;
|
||||
winrateSd: number;
|
||||
hitRateMean: number;
|
||||
hitRateSd: number;
|
||||
survivalRateMean: number;
|
||||
survivalRateSd: number;
|
||||
damageRatioMean: number;
|
||||
damageRatioSd: number;
|
||||
kdrMean: number;
|
||||
kdrSd: number;
|
||||
dpbMean: number;
|
||||
dpbSd: number;
|
||||
kpbMean: number;
|
||||
kpbSd: number;
|
||||
hpbMean: number;
|
||||
hpbSd: number;
|
||||
spbMean: number;
|
||||
spbSd: number;
|
||||
}
|
||||
|
||||
export interface IndividualTankAverage {
|
||||
_id: number;
|
||||
battle_life_time: number;
|
||||
total_battle_life_time: number;
|
||||
number_of_players: number;
|
||||
tank_id: number;
|
||||
all: BlitzStats;
|
||||
special: SpecialStats;
|
||||
percentiles: SpecialPercentiles;
|
||||
percentiles_player_count: number;
|
||||
meanSd: MeanSd;
|
||||
shotEff: number;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
export type BlitzStarsTankAverages = Record<number, IndividualTankAverage>;
|
||||
|
||||
export const blitzStarsTankAverages = fetch(
|
||||
'https://www.blitzstars.com/api/tankaverages.json',
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
if (context === 'server') {
|
||||
const partialTankAverages: BlitzStarsTankAverages = {};
|
||||
|
||||
(json as IndividualTankAverage[]).forEach((individualTankAverage) => {
|
||||
partialTankAverages[individualTankAverage.tank_id] =
|
||||
individualTankAverage;
|
||||
});
|
||||
|
||||
return partialTankAverages;
|
||||
} else {
|
||||
return json as BlitzStarsTankAverages;
|
||||
}
|
||||
});
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Client, GatewayIntentBits } from 'discord.js';
|
||||
import { interactionCreate } from '../../events/interactionCreate';
|
||||
import { ready } from '../../events/ready';
|
||||
import { Client, GatewayIntentBits } from "discord.js";
|
||||
import { interactionCreate } from "../../events/interactionCreate";
|
||||
import { ready } from "../../events/ready";
|
||||
|
||||
export const client = new Client({
|
||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
||||
})
|
||||
.on('ready', ready)
|
||||
.on('interactionCreate', interactionCreate);
|
||||
.on("clientReady", ready)
|
||||
.on("interactionCreate", interactionCreate);
|
||||
@@ -22,11 +22,11 @@ export function createLocalizedCommand(
|
||||
command: string,
|
||||
sub?:
|
||||
| CreateLocalizedCommandSubcommand[]
|
||||
| CreateLocalizedCommandSubcommandGroup[]
|
||||
| CreateLocalizedCommandSubcommandGroup[],
|
||||
) {
|
||||
const commandPathItem = command.replaceAll(
|
||||
"-",
|
||||
"_"
|
||||
"_",
|
||||
) as keyof BlitzKitStrings["bot"]["commands"];
|
||||
const { strings } = translator(Locale.EnglishUS);
|
||||
const slashCommand = new SlashCommandBuilder()
|
||||
@@ -35,14 +35,14 @@ export function createLocalizedCommand(
|
||||
localizationObject(
|
||||
(strings) => strings.bot.commands[commandPathItem].name,
|
||||
undefined,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
)
|
||||
.setDescription(strings.bot.commands[commandPathItem].description)
|
||||
.setDescriptionLocalizations(
|
||||
localizationObject(
|
||||
(strings) => strings.bot.commands[commandPathItem].description
|
||||
)
|
||||
(strings) => strings.bot.commands[commandPathItem].description,
|
||||
),
|
||||
);
|
||||
|
||||
if (sub) {
|
||||
@@ -56,7 +56,7 @@ export function createLocalizedCommand(
|
||||
}
|
||||
).subcommands[subItem.subcommand].name,
|
||||
undefined,
|
||||
true
|
||||
true,
|
||||
);
|
||||
const subcommandDescriptionLocalizations = localizationObject(
|
||||
(strings) =>
|
||||
@@ -64,7 +64,7 @@ export function createLocalizedCommand(
|
||||
strings.bot.commands[commandPathItem] as unknown as {
|
||||
subcommands: Record<string, { description: string }>;
|
||||
}
|
||||
).subcommands[subItem.subcommand].description
|
||||
).subcommands[subItem.subcommand].description,
|
||||
);
|
||||
|
||||
slashCommand.addSubcommand((option) => {
|
||||
@@ -78,7 +78,7 @@ export function createLocalizedCommand(
|
||||
strings.bot.commands[commandPathItem] as unknown as {
|
||||
subcommands: Record<string, { description: string }>;
|
||||
}
|
||||
).subcommands[subItem.subcommand].description
|
||||
).subcommands[subItem.subcommand].description,
|
||||
)
|
||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||
});
|
||||
@@ -91,7 +91,7 @@ export function createLocalizedCommand(
|
||||
}
|
||||
).groups[subItem.group].name,
|
||||
undefined,
|
||||
true
|
||||
true,
|
||||
);
|
||||
const subcommandDescriptionLocalizations = localizationObject(
|
||||
(strings) =>
|
||||
@@ -99,7 +99,7 @@ export function createLocalizedCommand(
|
||||
strings.bot.commands[commandPathItem] as unknown as {
|
||||
groups: Record<string, { description: string }>;
|
||||
}
|
||||
).groups[subItem.group].description
|
||||
).groups[subItem.group].description,
|
||||
);
|
||||
|
||||
slashCommand.addSubcommandGroup((option) => {
|
||||
@@ -113,7 +113,7 @@ export function createLocalizedCommand(
|
||||
strings.bot.commands[commandPathItem] as unknown as {
|
||||
groups: Record<string, { description: string }>;
|
||||
}
|
||||
).groups[subItem.group].description
|
||||
).groups[subItem.group].description,
|
||||
)
|
||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user