mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22f42117df | ||
|
|
788edf5bdf | ||
|
|
d0170d53e4 | ||
|
|
ae5e38139b | ||
|
|
e38713f365 | ||
|
|
5903b8130b | ||
|
|
179ce62a55 | ||
|
|
a2f1593a0e | ||
|
|
6305db7ad6 | ||
|
|
5082e1b82b | ||
|
|
e7ca8f1b10 | ||
|
|
0d8a677ac5 | ||
|
|
a8dc271e0a | ||
|
|
f3d6ba68a7 | ||
|
|
e68b27bac4 | ||
|
|
d49eef7308 | ||
|
|
6e630a91aa | ||
|
|
2c66e79daf | ||
|
|
9a94a4e371 | ||
|
|
b1372c998d | ||
|
|
4ed93cb38f | ||
|
|
4d1b175c07 | ||
|
|
ecfedc32ad | ||
|
|
9da514c329 | ||
|
|
ee5386c925 | ||
|
|
76f7ae45ce | ||
|
|
ad2aaa7bf8 | ||
|
|
2a4375c718 | ||
|
|
134566f1d8 | ||
|
|
d592a95cae | ||
|
|
4f74556eb6 | ||
|
|
1342f434a3 | ||
|
|
6110471990 | ||
|
|
359eec5209 |
No files matched your search
@@ -29,7 +29,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.ASSET_BOT }}
|
||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
|
||||
@@ -51,6 +51,8 @@ env:
|
||||
PUBLIC_NITROPAY_ID: ${{ secrets.PUBLIC_NITROPAY_ID }}
|
||||
PUBLIC_DEBUG_MISSING_I18N: false
|
||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
|
||||
jobs:
|
||||
download_client:
|
||||
|
||||
@@ -12,6 +12,8 @@ concurrency:
|
||||
env:
|
||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -20,6 +20,8 @@ env:
|
||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
|
||||
jobs:
|
||||
host:
|
||||
@@ -27,8 +29,8 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
# with:
|
||||
# bun-version: 1.1.33
|
||||
# with:
|
||||
# bun-version: 1.1.33
|
||||
|
||||
- name: Download release assets
|
||||
run: |
|
||||
|
||||
@@ -25,4 +25,6 @@ jobs:
|
||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
run: bun build:ratingleaderboard --region=asia
|
||||
@@ -25,4 +25,6 @@ jobs:
|
||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
run: bun build:ratingleaderboard --region=eu
|
||||
@@ -25,4 +25,6 @@ jobs:
|
||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
run: bun build:ratingleaderboard --region=com
|
||||
@@ -21,7 +21,7 @@ env:
|
||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
||||
ALLOW_ROBOTS: "true"
|
||||
ALLOW_ROBOTS: 'true'
|
||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
||||
@@ -29,6 +29,8 @@ env:
|
||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+1
-2
@@ -22,8 +22,7 @@ depots
|
||||
public/sitemap*
|
||||
/firebase.json
|
||||
target
|
||||
# packages/core/src/protos/*
|
||||
# !packages/core/src/protos/*.proto
|
||||
# *.ts
|
||||
/.vercel
|
||||
/.astro
|
||||
.vercel
|
||||
|
||||
@@ -4,6 +4,3 @@
|
||||
[submodule "submodules/CUE4Parse"]
|
||||
path = submodules/CUE4Parse
|
||||
url = https://github.com/FabianFG/CUE4Parse
|
||||
[submodule "submodules/UAssetAPI"]
|
||||
path = submodules/UAssetAPI
|
||||
url = https://github.com/atenfyr/UAssetAPI
|
||||
Vendored
+6
@@ -33,6 +33,7 @@
|
||||
"blitzkit",
|
||||
"blitzrinth",
|
||||
"blitzstars",
|
||||
"bufbuild",
|
||||
"cacheable",
|
||||
"Callouts",
|
||||
"Camo",
|
||||
@@ -75,6 +76,7 @@
|
||||
"dxgi",
|
||||
"echarts",
|
||||
"Everytime",
|
||||
"FABLEGEAR",
|
||||
"FASTNAME",
|
||||
"flexdirection",
|
||||
"FOURCC",
|
||||
@@ -108,6 +110,7 @@
|
||||
"Maddoxkkm",
|
||||
"malum",
|
||||
"mantlets",
|
||||
"MECHA",
|
||||
"metallicness",
|
||||
"metalness",
|
||||
"minitelrose",
|
||||
@@ -145,9 +148,11 @@
|
||||
"POSITIVEY",
|
||||
"POSITIVEZ",
|
||||
"precompute",
|
||||
"PROGRESSTON",
|
||||
"Promisable",
|
||||
"proto",
|
||||
"protobuf",
|
||||
"protoc",
|
||||
"protos",
|
||||
"Pyogenics",
|
||||
"ratingleaderboard",
|
||||
@@ -203,6 +208,7 @@
|
||||
"vitepress",
|
||||
"Vovko",
|
||||
"wargaming",
|
||||
"WARHAMMER",
|
||||
"webp",
|
||||
"whitespaces",
|
||||
"WHSS",
|
||||
|
||||
+12
-2
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "blitzkit",
|
||||
"name": "@blitzkit",
|
||||
"private": true,
|
||||
"version": "1.27.11",
|
||||
"description": "🎉 Tools for everything World of Tanks Blitz",
|
||||
"type": "module",
|
||||
"types": "./types.d.ts",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
"packages/*",
|
||||
"submodules/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build:assets": "cd packages/scripts && bun run build:assets",
|
||||
@@ -41,14 +42,23 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"googleapis": "^144.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"protobufjs": "^7.5.2",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"quicklime": "^1.2.0",
|
||||
"sharp": "^0.33.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/react": "^4.3.0",
|
||||
"@types/bun": "latest",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/react": "^19.1.5",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@types/node": "^22.14.1",
|
||||
"astro": "^5.8.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prisma": "^6.6.0",
|
||||
"typescript": "^5.8.3"
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"satori": "^0.10.14",
|
||||
"@resvg/resvg-js": "^2.6.2",
|
||||
"discord.js": "^14.16.3",
|
||||
"react": "^18.3.1",
|
||||
"@radix-ui/colors": "^3.0.0",
|
||||
"fuzzysort": "^2.0.4",
|
||||
"bepaint": "^0.1.0-beta.3",
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src/**/*", "../core/src/blitzkit/supportedLocales.ts", "../i18n/src/unwrapper.ts"]
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../core/src/blitzkit/supportedLocales.ts",
|
||||
"../i18n/src/unwrapper.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "../../"
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"dependencies": {
|
||||
"@blitzkit/closed": "workspace:*",
|
||||
"@octokit/plugin-throttling": "^8.2.0",
|
||||
"@octokit/rest": "^20.1.1",
|
||||
"@prisma/client": "^6.6.0",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { CatalogItem } from '@protos/blitz_items';
|
||||
import { Any } from '@protos/google/protobuf/any';
|
||||
import { MessageFns } from '../protos';
|
||||
|
||||
export class CatalogItemAccessor {
|
||||
private components: Record<string, Any> = {};
|
||||
|
||||
constructor(item: CatalogItem) {
|
||||
for (const component of item.components) {
|
||||
if (
|
||||
component.value === undefined ||
|
||||
component.value.component === undefined
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.components[component.key] = component.value.component;
|
||||
}
|
||||
}
|
||||
|
||||
get<Type>(Message: MessageFns<Type>, component: string) {
|
||||
if (component in this.components) {
|
||||
return Message.decode(this.components[component].value);
|
||||
}
|
||||
|
||||
throw new Error(`Unknown component: ${component}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function entityName(entity: string) {
|
||||
const [_, ...name] = entity.split('.');
|
||||
return name.join('.');
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
export * from './canSplash';
|
||||
export * from './catalogItemAccessor';
|
||||
export * from './clans';
|
||||
export * from './classes';
|
||||
export * from './constants';
|
||||
export * from './entityName';
|
||||
export * from './equipmentPrice';
|
||||
export * from './fetchBlitz';
|
||||
export * from './fetchGlossary';
|
||||
@@ -18,6 +20,7 @@ export * from './getTankStats';
|
||||
export * from './idToRegion';
|
||||
export * from './isOnGoingRatingSeason';
|
||||
export * from './isValidBlitzId';
|
||||
export * from './metadataAccessor';
|
||||
export * from './nations';
|
||||
export * from './normalizeExtra';
|
||||
export * from './normalizeIds';
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { CatalogItem } from '@protos/blitz_items';
|
||||
import { Metadata } from '@protos/blitz_metadata';
|
||||
import { CatalogItemAccessor } from './catalogItemAccessor';
|
||||
|
||||
export class UnpackedMetadataAccessor {
|
||||
private items: Record<string, CatalogItemAccessor> = {};
|
||||
|
||||
constructor(metadata: Metadata) {
|
||||
for (const item of metadata.catalog_items) {
|
||||
if (item.catalog_id in this.items) {
|
||||
throw new Error(`Duplicate catalog ID: ${item.catalog_id}`);
|
||||
}
|
||||
|
||||
this.items[item.catalog_id] = new CatalogItemAccessor(item);
|
||||
}
|
||||
}
|
||||
|
||||
get(item: string) {
|
||||
if (item in this.items) return this.items[item];
|
||||
|
||||
throw new Error(`Unknown catalog ID: ${item}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class DiscreteMetadataAccessor {
|
||||
constructor(private base: string) {}
|
||||
|
||||
async get(item: string) {
|
||||
const response = await fetch(`${this.base}/${item}.pb`);
|
||||
|
||||
if (!response.ok) throw new Error(`Unknown catalog ID: ${item}`);
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const catalogItem = CatalogItem.decode(new Uint8Array(buffer));
|
||||
|
||||
return new CatalogItemAccessor(catalogItem);
|
||||
}
|
||||
}
|
||||
@@ -46,4 +46,5 @@ export * from './gallery';
|
||||
export * from './metaSortTank';
|
||||
export * from './popularTanks';
|
||||
export * from './romanize';
|
||||
export * from './slugify';
|
||||
export * from './youtubers';
|
||||
@@ -0,0 +1,16 @@
|
||||
import { deburr } from 'lodash-es';
|
||||
|
||||
const nonAlphanumericRegex = /[^a-z0-9]/g;
|
||||
const multipleDashesRegex = /--+/g;
|
||||
const trailingDashRegex = /-$/g;
|
||||
const leadingDashRegex = /^-/g;
|
||||
|
||||
export function slugify(name: string) {
|
||||
let slug = deburr(name).toLowerCase();
|
||||
slug = slug.replaceAll(nonAlphanumericRegex, '-');
|
||||
slug = slug.replaceAll(multipleDashesRegex, '-');
|
||||
slug = slug.replaceAll(trailingDashRegex, '');
|
||||
slug = slug.replaceAll(leadingDashRegex, '');
|
||||
|
||||
return slug;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { deburr } from 'lodash-es';
|
||||
import { SUPPORTED_LOCALES } from '../../../i18n/src/strings';
|
||||
import { I18nString } from '../protos';
|
||||
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
|
||||
import { fetchTankDefinitions } from './tankDefinitions';
|
||||
@@ -26,8 +26,8 @@ export async function fetchTankNames() {
|
||||
searchableNameDeburr,
|
||||
camouflages: tank.camouflages
|
||||
?.map((id) =>
|
||||
SUPPORTED_LOCALES.map(
|
||||
(locale) =>
|
||||
locales.supported.map(
|
||||
({ locale }) =>
|
||||
camouflageDefinitions.camouflages[id]?.name.locales[locale],
|
||||
),
|
||||
)
|
||||
@@ -42,9 +42,11 @@ export async function fetchTankNames() {
|
||||
}
|
||||
|
||||
export const SEARCH_KEYS = [
|
||||
...SUPPORTED_LOCALES.map((locale) => [
|
||||
`searchableName.locales.${locale}`,
|
||||
`searchableNameDeburr.locales.${locale}`,
|
||||
]).flat(),
|
||||
...locales.supported
|
||||
.map(({ locale }) => [
|
||||
`searchableName.locales.${locale}`,
|
||||
`searchableNameDeburr.locales.${locale}`,
|
||||
])
|
||||
.flat(),
|
||||
'camouflages',
|
||||
];
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/average_definitions.proto
|
||||
// source: average_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -58,7 +58,7 @@ export interface Samples {
|
||||
total: number;
|
||||
}
|
||||
|
||||
function createBaseAverageDefinitions(): AverageDefinitions {
|
||||
export function createBaseAverageDefinitions(): AverageDefinitions {
|
||||
return { averages: {}, samples: createBaseSamples(), time: 0 };
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||
export function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||
return { key: 0, value: createBaseAverageDefinitionsEntry() };
|
||||
}
|
||||
|
||||
@@ -251,12 +251,12 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? AverageDefinitionsEntry.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseAverageDefinitionsEntry();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||
export function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||
return {
|
||||
mu: createBaseAverageDefinitionsAllStats(),
|
||||
sigma: createBaseAverageDefinitionsAllStats(),
|
||||
@@ -377,7 +377,7 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||
export function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||
return {
|
||||
battles: 0,
|
||||
capture_points: 0,
|
||||
@@ -738,7 +738,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseSamples(): Samples {
|
||||
export function createBaseSamples(): Samples {
|
||||
return { d_1: 0, d_7: 0, d_30: 0, d_60: 0, d_90: 0, d_120: 0, total: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message CamouflageDefinitions {
|
||||
map<uint32, Camouflage> camouflages = 1;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/camouflage_definitions.proto
|
||||
// source: camouflage_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface Camouflage {
|
||||
tank_name_full?: I18nString | undefined;
|
||||
}
|
||||
|
||||
function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||
export function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||
return { camouflages: {} };
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||
export function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||
return { key: 0, value: createBaseCamouflage() };
|
||||
}
|
||||
|
||||
@@ -185,12 +185,12 @@ export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefini
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Camouflage.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseCamouflage();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseCamouflage(): Camouflage {
|
||||
export function createBaseCamouflage(): Camouflage {
|
||||
return { id: 0, name: createBaseI18nString(), tank_name: undefined, tank_name_full: undefined };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message ConsumableDefinitions {
|
||||
map<uint32, Consumable> consumables = 1;
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/consumable_definitions.proto
|
||||
// source: consumable_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
export enum ConsumableTankCategoryFilterCategory {
|
||||
CLIP = 0,
|
||||
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
|
||||
}
|
||||
|
||||
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
||||
switch (object) {
|
||||
case 0:
|
||||
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
||||
return ConsumableTankCategoryFilterCategory.CLIP;
|
||||
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
|
||||
default:
|
||||
throw new globalThis.Error(
|
||||
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
||||
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
|
||||
|
||||
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
||||
switch (object) {
|
||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
||||
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
||||
default:
|
||||
throw new globalThis.Error(
|
||||
@@ -82,7 +82,7 @@ export interface ConsumableTankNationFilter {
|
||||
nations: string[];
|
||||
}
|
||||
|
||||
function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||
export function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||
return { consumables: {} };
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||
export function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||
return { key: 0, value: createBaseConsumable() };
|
||||
}
|
||||
|
||||
@@ -241,12 +241,12 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Consumable.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseConsumable();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumable(): Consumable {
|
||||
export function createBaseConsumable(): Consumable {
|
||||
return {
|
||||
id: 0,
|
||||
name: createBaseI18nString(),
|
||||
@@ -416,7 +416,7 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
||||
export function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
||||
return { filter_type: undefined };
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||
export function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||
return { min: 0, max: 0 };
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
||||
export function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
||||
return { ids: [] };
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||
export function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||
return { categories: [] };
|
||||
}
|
||||
|
||||
@@ -784,7 +784,7 @@ export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilt
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||
export function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||
return { nations: [] };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message EquipmentDefinitions {
|
||||
map<string, EquipmentPreset> presets = 1;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/equipment_definitions.proto
|
||||
// source: equipment_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface EquipmentSlot {
|
||||
right: number;
|
||||
}
|
||||
|
||||
function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||
export function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||
return { presets: {}, equipments: {} };
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||
export function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||
return { key: "", value: createBaseEquipmentPreset() };
|
||||
}
|
||||
|
||||
@@ -236,12 +236,12 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
||||
message.key = object.key ?? "";
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? EquipmentPreset.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseEquipmentPreset();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||
export function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||
return { key: 0, value: createBaseEquipment() };
|
||||
}
|
||||
|
||||
@@ -318,12 +318,12 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Equipment.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseEquipment();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseEquipment(): Equipment {
|
||||
export function createBaseEquipment(): Equipment {
|
||||
return { name: createBaseI18nString(), description: createBaseI18nString() };
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ export const Equipment: MessageFns<Equipment> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseEquipmentPreset(): EquipmentPreset {
|
||||
export function createBaseEquipmentPreset(): EquipmentPreset {
|
||||
return { slots: [] };
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseEquipmentSlot(): EquipmentSlot {
|
||||
export function createBaseEquipmentSlot(): EquipmentSlot {
|
||||
return { left: 0, right: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message Gallery {
|
||||
repeated Avatar avatars = 1;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/gallery.proto
|
||||
// source: gallery.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
|
||||
import { I18nString, createBaseI18nString } from './i18n';
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = 'blitzkit';
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
export interface Gallery {
|
||||
avatars: Avatar[];
|
||||
@@ -20,15 +20,12 @@ export interface Avatar {
|
||||
extension: string;
|
||||
}
|
||||
|
||||
function createBaseGallery(): Gallery {
|
||||
export function createBaseGallery(): Gallery {
|
||||
return { avatars: [] };
|
||||
}
|
||||
|
||||
export const Gallery: MessageFns<Gallery> = {
|
||||
encode(
|
||||
message: Gallery,
|
||||
writer: BinaryWriter = new BinaryWriter(),
|
||||
): BinaryWriter {
|
||||
encode(message: Gallery, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
for (const v of message.avatars) {
|
||||
Avatar.encode(v!, writer.uint32(10).fork()).join();
|
||||
}
|
||||
@@ -36,8 +33,7 @@ export const Gallery: MessageFns<Gallery> = {
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
||||
const reader =
|
||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGallery();
|
||||
while (reader.pos < end) {
|
||||
@@ -62,9 +58,7 @@ export const Gallery: MessageFns<Gallery> = {
|
||||
|
||||
fromJSON(object: any): Gallery {
|
||||
return {
|
||||
avatars: globalThis.Array.isArray(object?.avatars)
|
||||
? object.avatars.map((e: any) => Avatar.fromJSON(e))
|
||||
: [],
|
||||
avatars: globalThis.Array.isArray(object?.avatars) ? object.avatars.map((e: any) => Avatar.fromJSON(e)) : [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -86,30 +80,26 @@ export const Gallery: MessageFns<Gallery> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseAvatar(): Avatar {
|
||||
return { id: '', name: createBaseI18nString(), extension: '' };
|
||||
export function createBaseAvatar(): Avatar {
|
||||
return { id: "", name: createBaseI18nString(), extension: "" };
|
||||
}
|
||||
|
||||
export const Avatar: MessageFns<Avatar> = {
|
||||
encode(
|
||||
message: Avatar,
|
||||
writer: BinaryWriter = new BinaryWriter(),
|
||||
): BinaryWriter {
|
||||
if (message.id !== '') {
|
||||
encode(message: Avatar, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.id !== "") {
|
||||
writer.uint32(10).string(message.id);
|
||||
}
|
||||
if (message.name !== undefined) {
|
||||
I18nString.encode(message.name, writer.uint32(18).fork()).join();
|
||||
}
|
||||
if (message.extension !== '') {
|
||||
if (message.extension !== "") {
|
||||
writer.uint32(26).string(message.extension);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
||||
const reader =
|
||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAvatar();
|
||||
while (reader.pos < end) {
|
||||
@@ -150,23 +140,21 @@ export const Avatar: MessageFns<Avatar> = {
|
||||
|
||||
fromJSON(object: any): Avatar {
|
||||
return {
|
||||
id: globalThis.String(assertSet('Avatar.id', object.id)),
|
||||
name: I18nString.fromJSON(assertSet('Avatar.name', object.name)),
|
||||
extension: globalThis.String(
|
||||
assertSet('Avatar.extension', object.extension),
|
||||
),
|
||||
id: globalThis.String(assertSet("Avatar.id", object.id)),
|
||||
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
|
||||
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: Avatar): unknown {
|
||||
const obj: any = {};
|
||||
if (message.id !== '') {
|
||||
if (message.id !== "") {
|
||||
obj.id = message.id;
|
||||
}
|
||||
if (message.name !== undefined) {
|
||||
obj.name = I18nString.toJSON(message.name);
|
||||
}
|
||||
if (message.extension !== '') {
|
||||
if (message.extension !== "") {
|
||||
obj.extension = message.extension;
|
||||
}
|
||||
return obj;
|
||||
@@ -177,43 +165,27 @@ export const Avatar: MessageFns<Avatar> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Avatar>, I>>(object: I): Avatar {
|
||||
const message = createBaseAvatar();
|
||||
message.id = object.id ?? '';
|
||||
message.name =
|
||||
object.name !== undefined && object.name !== null
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
message.extension = object.extension ?? '';
|
||||
message.id = object.id ?? "";
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
message.extension = object.extension ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
type Builtin =
|
||||
| Date
|
||||
| Function
|
||||
| Uint8Array
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| undefined;
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends { $case: string; value: unknown }
|
||||
? { $case: T['$case']; value?: DeepPartial<T['value']> }
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
|
||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
||||
};
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message GameDefinitions {
|
||||
required string version = 1;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/game_definitions.proto
|
||||
// source: game_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface GameModeRole {
|
||||
consumables: number[];
|
||||
}
|
||||
|
||||
function createBaseGameDefinitions(): GameDefinitions {
|
||||
export function createBaseGameDefinitions(): GameDefinitions {
|
||||
return { version: "", nations: [], gameModes: {}, roles: {} };
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||
export function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||
return { key: 0, value: createBaseGameMode() };
|
||||
}
|
||||
|
||||
@@ -260,12 +260,12 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? GameMode.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseGameMode();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||
export function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||
return { key: 0, value: createBaseGameModeRole() };
|
||||
}
|
||||
|
||||
@@ -338,12 +338,12 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? GameModeRole.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseGameModeRole();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGameMode(): GameMode {
|
||||
export function createBaseGameMode(): GameMode {
|
||||
return { name: createBaseI18nString() };
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ export const GameMode: MessageFns<GameMode> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGameModeRole(): GameModeRole {
|
||||
export function createBaseGameModeRole(): GameModeRole {
|
||||
return { provisions: [], consumables: [] };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/i18n.proto
|
||||
// source: i18n.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -97,7 +97,7 @@ export const I18nString: MessageFns<I18nString> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||
export function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||
return { key: "", value: "" };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message MapDefinitions {
|
||||
map<int32, MapDefinition> maps = 1;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/map_definitions.proto
|
||||
// source: map_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -24,7 +24,7 @@ export interface MapDefinition {
|
||||
name: I18nString;
|
||||
}
|
||||
|
||||
function createBaseMapDefinitions(): MapDefinitions {
|
||||
export function createBaseMapDefinitions(): MapDefinitions {
|
||||
return { maps: {} };
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||
export function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||
return { key: 0, value: createBaseMapDefinition() };
|
||||
}
|
||||
|
||||
@@ -176,12 +176,12 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? MapDefinition.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseMapDefinition();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseMapDefinition(): MapDefinition {
|
||||
export function createBaseMapDefinition(): MapDefinition {
|
||||
return { id: 0, name: createBaseI18nString() };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/model_definitions.proto
|
||||
// source: model_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -110,7 +110,7 @@ export interface PitchLimitsExtrema {
|
||||
range: number;
|
||||
}
|
||||
|
||||
function createBaseModelDefinitions(): ModelDefinitions {
|
||||
export function createBaseModelDefinitions(): ModelDefinitions {
|
||||
return { models: {} };
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ export const ModelDefinitions: MessageFns<ModelDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseModelDefinitions_ModelsEntry(): ModelDefinitions_ModelsEntry {
|
||||
export function createBaseModelDefinitions_ModelsEntry(): ModelDefinitions_ModelsEntry {
|
||||
return { key: 0, value: createBaseModelDefinition() };
|
||||
}
|
||||
|
||||
@@ -265,12 +265,12 @@ export const ModelDefinitions_ModelsEntry: MessageFns<ModelDefinitions_ModelsEnt
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? ModelDefinition.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseModelDefinition();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseModelDefinition(): ModelDefinition {
|
||||
export function createBaseModelDefinition(): ModelDefinition {
|
||||
return {
|
||||
armor: createBaseArmor(),
|
||||
turret_origin: createBaseVector3(),
|
||||
@@ -472,7 +472,7 @@ export const ModelDefinition: MessageFns<ModelDefinition> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseModelDefinition_TurretsEntry(): ModelDefinition_TurretsEntry {
|
||||
export function createBaseModelDefinition_TurretsEntry(): ModelDefinition_TurretsEntry {
|
||||
return { key: 0, value: createBaseTurretModelDefinition() };
|
||||
}
|
||||
|
||||
@@ -545,12 +545,12 @@ export const ModelDefinition_TurretsEntry: MessageFns<ModelDefinition_TurretsEnt
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? TurretModelDefinition.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseTurretModelDefinition();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseModelDefinition_TracksEntry(): ModelDefinition_TracksEntry {
|
||||
export function createBaseModelDefinition_TracksEntry(): ModelDefinition_TracksEntry {
|
||||
return { key: 0, value: createBaseTrackModelDefinition() };
|
||||
}
|
||||
|
||||
@@ -623,12 +623,12 @@ export const ModelDefinition_TracksEntry: MessageFns<ModelDefinition_TracksEntry
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? TrackModelDefinition.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseTrackModelDefinition();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseArmor(): Armor {
|
||||
export function createBaseArmor(): Armor {
|
||||
return { thickness: {}, spaced: [] };
|
||||
}
|
||||
|
||||
@@ -738,7 +738,7 @@ export const Armor: MessageFns<Armor> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseArmor_ThicknessEntry(): Armor_ThicknessEntry {
|
||||
export function createBaseArmor_ThicknessEntry(): Armor_ThicknessEntry {
|
||||
return { key: 0, value: 0 };
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ export const Armor_ThicknessEntry: MessageFns<Armor_ThicknessEntry> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseVector3(): Vector3 {
|
||||
export function createBaseVector3(): Vector3 {
|
||||
return { x: 0, y: 0, z: 0 };
|
||||
}
|
||||
|
||||
@@ -906,7 +906,7 @@ export const Vector3: MessageFns<Vector3> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseInitialTurretRotation(): InitialTurretRotation {
|
||||
export function createBaseInitialTurretRotation(): InitialTurretRotation {
|
||||
return { yaw: 0, pitch: 0, roll: 0 };
|
||||
}
|
||||
|
||||
@@ -998,7 +998,7 @@ export const InitialTurretRotation: MessageFns<InitialTurretRotation> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseTurretModelDefinition(): TurretModelDefinition {
|
||||
export function createBaseTurretModelDefinition(): TurretModelDefinition {
|
||||
return {
|
||||
bounding_box: createBaseBoundingBox(),
|
||||
armor: createBaseArmor(),
|
||||
@@ -1173,7 +1173,7 @@ export const TurretModelDefinition: MessageFns<TurretModelDefinition> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseTurretModelDefinition_GunsEntry(): TurretModelDefinition_GunsEntry {
|
||||
export function createBaseTurretModelDefinition_GunsEntry(): TurretModelDefinition_GunsEntry {
|
||||
return { key: 0, value: createBaseGunModelDefinition() };
|
||||
}
|
||||
|
||||
@@ -1248,12 +1248,12 @@ export const TurretModelDefinition_GunsEntry: MessageFns<TurretModelDefinition_G
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? GunModelDefinition.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseGunModelDefinition();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseYawLimits(): YawLimits {
|
||||
export function createBaseYawLimits(): YawLimits {
|
||||
return { min: 0, max: 0 };
|
||||
}
|
||||
|
||||
@@ -1329,7 +1329,7 @@ export const YawLimits: MessageFns<YawLimits> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseBoundingBox(): BoundingBox {
|
||||
export function createBaseBoundingBox(): BoundingBox {
|
||||
return { min: createBaseVector3(), max: createBaseVector3() };
|
||||
}
|
||||
|
||||
@@ -1409,7 +1409,7 @@ export const BoundingBox: MessageFns<BoundingBox> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseTrackModelDefinition(): TrackModelDefinition {
|
||||
export function createBaseTrackModelDefinition(): TrackModelDefinition {
|
||||
return { thickness: 0, origin: createBaseVector3() };
|
||||
}
|
||||
|
||||
@@ -1487,7 +1487,7 @@ export const TrackModelDefinition: MessageFns<TrackModelDefinition> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGunModelDefinition(): GunModelDefinition {
|
||||
export function createBaseGunModelDefinition(): GunModelDefinition {
|
||||
return { armor: createBaseArmor(), thickness: 0, model_id: 0, pitch: createBasePitchLimits(), mask: undefined };
|
||||
}
|
||||
|
||||
@@ -1615,7 +1615,7 @@ export const GunModelDefinition: MessageFns<GunModelDefinition> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBasePitchLimits(): PitchLimits {
|
||||
export function createBasePitchLimits(): PitchLimits {
|
||||
return { min: 0, max: 0, front: undefined, back: undefined, transition: undefined };
|
||||
}
|
||||
|
||||
@@ -1743,7 +1743,7 @@ export const PitchLimits: MessageFns<PitchLimits> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBasePitchLimitsExtrema(): PitchLimitsExtrema {
|
||||
export function createBasePitchLimitsExtrema(): PitchLimitsExtrema {
|
||||
return { min: 0, max: 0, range: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/popular_tanks.proto
|
||||
// source: popular_tanks.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -19,7 +19,7 @@ export interface PopularTank {
|
||||
views: number;
|
||||
}
|
||||
|
||||
function createBasePopularTanks(): PopularTanks {
|
||||
export function createBasePopularTanks(): PopularTanks {
|
||||
return { tanks: [] };
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBasePopularTank(): PopularTank {
|
||||
export function createBasePopularTank(): PopularTank {
|
||||
return { id: 0, views: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/consumable_definitions.proto";
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "consumable_definitions.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message ProvisionDefinitions {
|
||||
map<uint32, Provision> provisions = 1;
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/provision_definitions.proto
|
||||
// source: provision_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { ConsumableTankFilter } from "./consumable_definitions";
|
||||
import { I18nString, createBaseI18nString } from "./i18n";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface Provision {
|
||||
exclude: ConsumableTankFilter[];
|
||||
}
|
||||
|
||||
function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||
export function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||
return { provisions: {} };
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||
export function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||
return { key: 0, value: createBaseProvision() };
|
||||
}
|
||||
|
||||
@@ -188,12 +188,12 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Provision.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseProvision();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseProvision(): Provision {
|
||||
export function createBaseProvision(): Provision {
|
||||
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/rating_leaderboard.proto
|
||||
// source: rating_leaderboard.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -36,7 +36,7 @@ export interface RatingLeaderboardEntryV2 {
|
||||
kills: number;
|
||||
}
|
||||
|
||||
function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||
export function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||
return { version: undefined };
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||
export function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||
return { entries: [] };
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
||||
export function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
||||
return { id: 0, score: 0 };
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
||||
export function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
||||
return { entries: [] };
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
||||
export function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
||||
return { id: 0, score: 0, battles: 0, wins: 0, survived: 0, damage: 0, kills: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/reviews.proto
|
||||
// source: reviews.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -28,7 +28,7 @@ export interface Video {
|
||||
author: string;
|
||||
}
|
||||
|
||||
function createBaseReviews(): Reviews {
|
||||
export function createBaseReviews(): Reviews {
|
||||
return { reviews: {} };
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export const Reviews: MessageFns<Reviews> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||
export function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||
return { key: 0, value: createBaseReview() };
|
||||
}
|
||||
|
||||
@@ -180,12 +180,12 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Review.fromPartial(object.value)
|
||||
: undefined;
|
||||
: createBaseReview();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseReview(): Review {
|
||||
export function createBaseReview(): Review {
|
||||
return { last_updated: 0, videos: [] };
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ export const Review: MessageFns<Review> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseVideo(): Video {
|
||||
export function createBaseVideo(): Video {
|
||||
return { id: "", author: "" };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/skill_definitions.proto
|
||||
// source: skill_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -23,7 +23,7 @@ export interface Skill {
|
||||
skills: string[];
|
||||
}
|
||||
|
||||
function createBaseSkillDefinitions(): SkillDefinitions {
|
||||
export function createBaseSkillDefinitions(): SkillDefinitions {
|
||||
return { classes: {} };
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||
export function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||
return { key: 0, value: createBaseSkill() };
|
||||
}
|
||||
|
||||
@@ -175,12 +175,14 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
||||
): SkillDefinitions_ClassesEntry {
|
||||
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null) ? Skill.fromPartial(object.value) : undefined;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Skill.fromPartial(object.value)
|
||||
: createBaseSkill();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseSkill(): Skill {
|
||||
export function createBaseSkill(): Skill {
|
||||
return { skills: [] };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message TankDefinitions {
|
||||
map<uint32, TankDefinition> tanks = 1;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src/**/*", "../i18n/src/strings.ts"]
|
||||
"include": ["src/**/*", "../i18n/src/strings.ts"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "../../"
|
||||
}
|
||||
}
|
||||
@@ -1,89 +1,8 @@
|
||||
import { merge } from 'ts-deepmerge';
|
||||
import en from '../strings/en.json';
|
||||
import es from '../strings/es.json';
|
||||
import fr from '../strings/fr.json';
|
||||
import ja from '../strings/ja.json';
|
||||
import pl from '../strings/pl.json';
|
||||
import pt from '../strings/pt.json';
|
||||
import ru from '../strings/ru.json';
|
||||
import uk from '../strings/uk.json';
|
||||
import zh from '../strings/zh.json';
|
||||
import type en from '../strings/en.json';
|
||||
|
||||
export type BlitzKitStrings = typeof en;
|
||||
|
||||
const stringsRaw = { en, es, fr, ja, pl, pt, ru, uk, zh };
|
||||
|
||||
export const SUPPORTED_LOCALES = Object.keys(stringsRaw) as SupportedLocale[];
|
||||
|
||||
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
|
||||
|
||||
function redact(string: string) {
|
||||
const matches = [...string.matchAll(/%s\d+/g)];
|
||||
const characters = string
|
||||
.split('')
|
||||
.map((char) => (char === ' ' ? ' ' : '█')) as string[];
|
||||
|
||||
matches.forEach((match) => {
|
||||
const start = match.index;
|
||||
const matchText = match[0];
|
||||
for (let i = 0; i < matchText.length; i++) {
|
||||
characters[start + i] = matchText[i];
|
||||
}
|
||||
});
|
||||
|
||||
return characters.join('');
|
||||
}
|
||||
|
||||
function nuke(object: TranslationTree) {
|
||||
for (const key in object) {
|
||||
const typedKey = key as keyof typeof object;
|
||||
|
||||
if (typeof object[typedKey] === 'string') {
|
||||
const value = object[typedKey];
|
||||
object[typedKey] = redact(value as string);
|
||||
} else nuke(object[typedKey] as TranslationTree);
|
||||
}
|
||||
}
|
||||
|
||||
const stringsPartial: Partial<Record<SupportedLocale, TranslationTree>> = {};
|
||||
|
||||
for (const locale in stringsRaw) {
|
||||
if (locale === DEFAULT_LOCALE) {
|
||||
stringsPartial[DEFAULT_LOCALE] = stringsRaw[DEFAULT_LOCALE];
|
||||
continue;
|
||||
}
|
||||
|
||||
const localeStrings = stringsRaw[locale as SupportedLocale];
|
||||
stringsPartial[locale as SupportedLocale] = merge(
|
||||
stringsRaw[DEFAULT_LOCALE],
|
||||
localeStrings,
|
||||
);
|
||||
|
||||
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') {
|
||||
nuke(stringsPartial[locale as SupportedLocale]!);
|
||||
}
|
||||
}
|
||||
|
||||
export const STRINGS = stringsPartial as Record<
|
||||
SupportedLocale,
|
||||
BlitzKitStrings
|
||||
>;
|
||||
|
||||
export type SupportedLocale = keyof typeof stringsRaw;
|
||||
|
||||
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
|
||||
en: 'en',
|
||||
es: 'es',
|
||||
fr: 'fr',
|
||||
ja: 'ja',
|
||||
pt: 'pt',
|
||||
ru: 'ru',
|
||||
uk: 'uk',
|
||||
zh: 'zh-Hans',
|
||||
pl: 'pl',
|
||||
};
|
||||
|
||||
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
||||
export const SUPPORTED_LOCALE_FLAGS: Record<string, string> = {
|
||||
en: '🇺🇸',
|
||||
es: '🇪🇸',
|
||||
fr: '🇫🇷',
|
||||
@@ -94,7 +13,3 @@ export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
||||
zh: '🇨🇳',
|
||||
pl: '🇵🇱',
|
||||
};
|
||||
|
||||
export type TranslationTree = { [key: string]: TranslationNode };
|
||||
|
||||
export type TranslationNode = string | TranslationTree;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { I18nString } from '@blitzkit/core';
|
||||
import { DEFAULT_LOCALE } from './strings';
|
||||
import locales from '../locales.json' with { type: 'json' };
|
||||
|
||||
export function unwrapper(locale: string) {
|
||||
return function (i18nString: I18nString) {
|
||||
@@ -7,6 +7,6 @@ export function unwrapper(locale: string) {
|
||||
return i18nString.locales[locale];
|
||||
}
|
||||
|
||||
return i18nString.locales[DEFAULT_LOCALE];
|
||||
return i18nString.locales[locales.default];
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,18 @@
|
||||
},
|
||||
|
||||
"common": {
|
||||
"tiers": {
|
||||
"0": "Unknown tier",
|
||||
"1": "I",
|
||||
"2": "II",
|
||||
"3": "III",
|
||||
"4": "IV",
|
||||
"5": "V",
|
||||
"6": "VI",
|
||||
"7": "VII",
|
||||
"8": "Vintage"
|
||||
},
|
||||
|
||||
"units": {
|
||||
"m": "%s1m",
|
||||
"mm": "%s1mm",
|
||||
@@ -86,15 +98,44 @@
|
||||
},
|
||||
|
||||
"nations": {
|
||||
"ussr": "U.S.S.R.",
|
||||
"germany": "Germany",
|
||||
"usa": "U.S.A.",
|
||||
"china": "China",
|
||||
"uk": "U.K.",
|
||||
"france": "France",
|
||||
"japan": "Japan",
|
||||
"european": "European Nation",
|
||||
"other": "Hybrid Nation"
|
||||
"0": "Unknown nation",
|
||||
"1": "U.S.S.R.",
|
||||
"2": "Germany",
|
||||
"3": "U.S.A.",
|
||||
"4": "China",
|
||||
"5": "France",
|
||||
"6": "U.K.",
|
||||
"7": "Japan",
|
||||
"8": "Europe",
|
||||
"9": "Poland",
|
||||
"10": "Australia",
|
||||
"11": "Canada",
|
||||
"12": "Italy",
|
||||
"13": "Finland",
|
||||
"14": "Czech",
|
||||
"15": "Hybrid Nation",
|
||||
"16": "GDR",
|
||||
"17": "Ireland",
|
||||
"18": "Scotland",
|
||||
"19": "Sweden",
|
||||
"20": "Argo Coalition",
|
||||
"21": "Titan Lab",
|
||||
"22": "Defender",
|
||||
"23": "Progresston",
|
||||
"24": "Wasteland",
|
||||
"25": "Hunters Moon",
|
||||
"26": "Cold Front",
|
||||
"27": "The Explorer",
|
||||
"28": "Fablegear",
|
||||
"29": "Outlaws",
|
||||
"30": "GUP",
|
||||
"31": "Dune",
|
||||
"32": "Terminator",
|
||||
"33": "Warhammer",
|
||||
"34": "Valkirya Chronicles",
|
||||
"35": "Mecha",
|
||||
"36": "TMNT",
|
||||
"37": "Star Trek"
|
||||
},
|
||||
|
||||
"nations_adjectives": {
|
||||
@@ -109,6 +150,14 @@
|
||||
"other": "Hybrid"
|
||||
},
|
||||
|
||||
"tank_class": {
|
||||
"0": "Unknown Class",
|
||||
"1": "Heavy",
|
||||
"2": "Light",
|
||||
"3": "Medium",
|
||||
"4": "Tank destroyer"
|
||||
},
|
||||
|
||||
"tank_class_short": {
|
||||
"-1": "unrecognized",
|
||||
"0": "Light",
|
||||
@@ -133,10 +182,10 @@
|
||||
},
|
||||
|
||||
"tree_type": {
|
||||
"-1": "unrecognized",
|
||||
"0": "Tech tree",
|
||||
"1": "Premium",
|
||||
"2": "Collector"
|
||||
"0": "Unknown tree type",
|
||||
"1": "Common",
|
||||
"2": "Premium",
|
||||
"3": "Collector"
|
||||
},
|
||||
|
||||
"regions": {
|
||||
@@ -988,6 +1037,8 @@
|
||||
},
|
||||
|
||||
"meta": {
|
||||
"compensation": "Compensation",
|
||||
"free": "Free",
|
||||
"back": "Back",
|
||||
"compare": "Compare",
|
||||
"swap": {
|
||||
@@ -1001,11 +1052,12 @@
|
||||
"class": "Class",
|
||||
"tier": "Tier",
|
||||
"type": "Type",
|
||||
"dev_id": "DEV: ID",
|
||||
"id": "ID",
|
||||
"purchase": "Purchase price",
|
||||
"restoration": "Restoration price",
|
||||
"sale": "Sale price",
|
||||
"research": "Research XP"
|
||||
"set": "Set",
|
||||
"price": "Price"
|
||||
},
|
||||
|
||||
"tech_tree": {
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1mm",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1pv",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Auto cargador",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Modo de desarrollador",
|
||||
"language": "Idioma"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "Sin resultados"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Tankopedia",
|
||||
"button": "Encuentra tanques",
|
||||
"description": "Enciclopedia de tanques de WOTB",
|
||||
"seo_description": "Estadísticas, armaduras y más para todos los tanques en World of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - Nivel %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 blindaje, estadisticas, equipamiento, proviciones y mas.\n%s2 DPM, %3hp alfa, %s4mm penetracion, %s5kph velocidad maxima, %s6 hp salud",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Medio",
|
||||
"soft": "Suave",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "Normalización",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "Blindaje",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "Hull down",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Características",
|
||||
"compare": {
|
||||
"label": "Comparar",
|
||||
"label": "Comparar con",
|
||||
"class": "Nivel %s1 - %s2",
|
||||
"tier": "Todos de nivel %s1",
|
||||
"all": "Todos los tanques"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1mm",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1ps",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Chargement auto",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Development mode",
|
||||
"language": "Language"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "No results"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Tankopedia",
|
||||
"button": "Find tanks",
|
||||
"description": "Blitz tank encyclopedia",
|
||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Moyen",
|
||||
"soft": "Soft",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "Normalization",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "Armor",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "Hull down",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Compare",
|
||||
"label": "Compare against",
|
||||
"class": "Tier %s1 %s2",
|
||||
"tier": "All of tier %s1",
|
||||
"all": "All tanks"
|
||||
|
||||
+189
-145
@@ -2,7 +2,7 @@
|
||||
"test": {
|
||||
"default": "test",
|
||||
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is %s1 because it has the color of %s2. I like it so much that I will say its name 3 times! %s1! %s1! %s1! Once again, it's %s2, not %s3.",
|
||||
"fox": "The quick brown fox jumps over the lazy dog."
|
||||
"fox": "すばしっこい茶色のキツネが怠け者の犬を飛び越した。"
|
||||
},
|
||||
"common": {
|
||||
"units": {
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1mm",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1hp",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "自動装填砲",
|
||||
@@ -33,10 +35,10 @@
|
||||
"d_1": "昨日"
|
||||
},
|
||||
"branches": {
|
||||
"local": "dev",
|
||||
"dev": "beta",
|
||||
"opentest": "opentest",
|
||||
"preview": "preview"
|
||||
"local": "開発",
|
||||
"dev": "ベータ版",
|
||||
"opentest": "オープンテスト",
|
||||
"preview": "プレビュー"
|
||||
},
|
||||
"locales": {
|
||||
"en": "英語",
|
||||
@@ -104,10 +106,10 @@
|
||||
"3": "駆逐戦車"
|
||||
},
|
||||
"tank_class_short_plural_lowercase": {
|
||||
"0": "LT",
|
||||
"1": "MT",
|
||||
"2": "HT",
|
||||
"3": "TD"
|
||||
"0": "軽戦車",
|
||||
"1": "中戦車",
|
||||
"2": "重戦車",
|
||||
"3": "駆逐戦車"
|
||||
},
|
||||
"tank_class_medium": {
|
||||
"-1": "不明",
|
||||
@@ -124,9 +126,9 @@
|
||||
},
|
||||
"regions": {
|
||||
"normal": {
|
||||
"com": "North America",
|
||||
"eu": "Europe",
|
||||
"asia": "Asia-Pacific"
|
||||
"com": "北米",
|
||||
"eu": "ヨーロッパ",
|
||||
"asia": "アジア太平洋"
|
||||
},
|
||||
"short": {
|
||||
"com": "NA",
|
||||
@@ -142,58 +144,58 @@
|
||||
"bronze": "ブロンズ"
|
||||
},
|
||||
"composite_stats": {
|
||||
"normalized_damage_dealt": "Damage",
|
||||
"normalized_damage_received": "Damage received",
|
||||
"normalized_deaths": "Deathrate",
|
||||
"normalized_frags": "Kills",
|
||||
"normalized_hits": "Hits",
|
||||
"normalized_losses": "Lossrate",
|
||||
"normalized_misses": "Misses",
|
||||
"normalized_shots": "Shots",
|
||||
"normalized_spotted": "Spots",
|
||||
"normalized_survived_battles": "Survival rate",
|
||||
"normalized_win_and_survived": "Winning and surviving rate",
|
||||
"normalized_wins": "Winrate",
|
||||
"normalized_xp": "XP",
|
||||
"normalized_battle_life_time": "Battle time",
|
||||
"cumulative_accuracy": "Accuracy",
|
||||
"cumulative_battles": "Battles",
|
||||
"cumulative_capture_points": "Total capture points",
|
||||
"cumulative_damage_dealt": "Total damage",
|
||||
"cumulative_damage_ratio": "Damage ratio",
|
||||
"cumulative_damage_received": "Total damage received",
|
||||
"cumulative_deaths": "Total deaths",
|
||||
"cumulative_dropped_capture_points": "Total dropped capture points",
|
||||
"cumulative_frags": "Total kills",
|
||||
"cumulative_hits": "Total hits",
|
||||
"cumulative_inaccuracy": "Inaccuracy",
|
||||
"cumulative_kills_to_death_ratio": "Kills to death ratio",
|
||||
"cumulative_losses": "Losses",
|
||||
"cumulative_misses": "Total misses",
|
||||
"cumulative_shots": "Total shots",
|
||||
"cumulative_spotted": "Total spots",
|
||||
"cumulative_survived_battles": "Survived battles",
|
||||
"cumulative_win_and_survived": "Won and survived battles",
|
||||
"cumulative_wins": "Wins",
|
||||
"cumulative_xp": "Total XP",
|
||||
"normalized_damage_dealt": "ダメージ",
|
||||
"normalized_damage_received": "被ダメージ",
|
||||
"normalized_deaths": "被撃破率",
|
||||
"normalized_frags": "撃破",
|
||||
"normalized_hits": "命中",
|
||||
"normalized_losses": "減衰率",
|
||||
"normalized_misses": "非命中数",
|
||||
"normalized_shots": "射撃数",
|
||||
"normalized_spotted": "発見数",
|
||||
"normalized_survived_battles": "生存率",
|
||||
"normalized_win_and_survived": "勝率・生還率",
|
||||
"normalized_wins": "勝率",
|
||||
"normalized_xp": "経験値",
|
||||
"normalized_battle_life_time": "戦闘時間",
|
||||
"cumulative_accuracy": "精度",
|
||||
"cumulative_battles": "戦闘数",
|
||||
"cumulative_capture_points": "総占領ポイント",
|
||||
"cumulative_damage_dealt": "総ダメージ",
|
||||
"cumulative_damage_ratio": "ダメージ率",
|
||||
"cumulative_damage_received": "総被ダメージ",
|
||||
"cumulative_deaths": "総被撃破数",
|
||||
"cumulative_dropped_capture_points": "総喪失占領ポイント",
|
||||
"cumulative_frags": "総撃破数",
|
||||
"cumulative_hits": "総命中数",
|
||||
"cumulative_inaccuracy": "非命中率",
|
||||
"cumulative_kills_to_death_ratio": "撃破/被撃破比",
|
||||
"cumulative_losses": "敗北",
|
||||
"cumulative_misses": "総非命中数",
|
||||
"cumulative_shots": "総射撃数",
|
||||
"cumulative_spotted": "総発見数",
|
||||
"cumulative_survived_battles": "生還した戦闘数",
|
||||
"cumulative_win_and_survived": "勝利し生還した戦闘数",
|
||||
"cumulative_wins": "勝利",
|
||||
"cumulative_xp": "総経験値",
|
||||
"cumulative_wn8": "WN8",
|
||||
"cumulative_battle_life_time": "Total battle time"
|
||||
"cumulative_battle_life_time": "総戦闘時間"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Could not find clan\nCouldn't find \"%s1\". Try selecting a clan from the search result.",
|
||||
"player_not_found": "# Could not find user\nI couldn't find user \"%s1\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
|
||||
"player_not_linked": "# Use `/link` to get started\nI don't know who you are but you can tell me today!",
|
||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"%s1\".",
|
||||
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"%s1\". Try typing the name of the tank instead of a number.",
|
||||
"no_tank_stats": "# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for.",
|
||||
"clan_not_found": "# クランが見つかりませんでした\n\"%s1\"は見つかりませんでした。検索結果からクランを選択してください。",
|
||||
"player_not_found": "# ユーザーが見つかりませんでした\nユーザー「\"%s1\"」は見つかりませんでした。検索結果からユーザーを選択するか、有効な名前を入力してください。`/link`コマンドを使用することも可能です。",
|
||||
"player_not_linked": "# `/link`を使用して始めましょう\nはじめまして!あなたが誰か、私に教えてください。",
|
||||
"tank_name_not_found": "# 車輌が見つかりませんでした\n\"%s1\"という名前の車輌は見つかりませんでした。",
|
||||
"tank_id_not_found": "# 車輌が見つかりませんでした\n\"%s1\"というIDの車輌は見つかりませんでした。番号ではなく名前で検索してください。",
|
||||
"no_tank_stats": "# 利用可能な車輌統計がありません\nこのプレイヤーには利用可能な統計がありません。あなたが探しているプレイヤーではない可能性があります。",
|
||||
"get_help": "Discordサーバーに参加する",
|
||||
"uncaught_error": "# BlitzKit がエラーに遭遇しました!\n申し訳ありません。お気軽に[Discordの公式サーバー](https://discord.gg/nDt7AjGJQH) をご利用ください。",
|
||||
"preview": "# This command is in preview\n\nYou can only access this command in [the official Discord server](https://discord.gg/nDt7AjGJQH). The command will be generally available soon.",
|
||||
"query_too_small": "# Your search is too short\nYour search must be at least 3 characters long.",
|
||||
"query_too_long": "# Your search is too long\nYour search must be at most 100 characters long."
|
||||
"uncaught_error": "# BlitzKitがエラーに遭遇しました!\n申し訳ありません。お気軽に[公式Discordサーバー](https://discord.gg/nDt7AjGJQH)にお問い合わせください。",
|
||||
"preview": "このコマンドは現在[公式Discardサーバー](https://discord.gg/nDt7AjGJQH)でのみ利用可能です。間もなく全体で利用可能になります。",
|
||||
"query_too_small": "# 単語が短すぎます\n検索には少なくとも3文字が含まれている必要があります。",
|
||||
"query_too_long": "# 単語が長すぎます\n検索は最大で100文字までです。"
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
@@ -217,26 +219,26 @@
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 days"
|
||||
"description": "30日"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 days"
|
||||
"description": "60日"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90日"
|
||||
"description": "90日"
|
||||
},
|
||||
"career": {
|
||||
"name": "総合戦績",
|
||||
"description": "Career"
|
||||
},
|
||||
"custom": {
|
||||
"name": "custom",
|
||||
"name": "カスタム",
|
||||
"description": "Custom range",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "start",
|
||||
"name": "開始",
|
||||
"description": "Start in number of days ago from today"
|
||||
},
|
||||
"end": {
|
||||
@@ -248,21 +250,21 @@
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "clan",
|
||||
"description": "The clan name or tag"
|
||||
"name": "クラン",
|
||||
"description": "クラン名もしくはタグ"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tank",
|
||||
"description": "The tank to get stats for"
|
||||
"name": "車輌",
|
||||
"description": "統計を得る車輌"
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"description": "The Blitz username of the player"
|
||||
"name": "ユーザー名",
|
||||
"description": "プレイヤーのBlitzユーザー名"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "nation",
|
||||
"description": "Nation"
|
||||
"name": "国家",
|
||||
"description": "国家"
|
||||
},
|
||||
"class": {
|
||||
"name": "",
|
||||
@@ -274,8 +276,8 @@
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "region",
|
||||
"description": "Region"
|
||||
"name": "地域",
|
||||
"description": "地域"
|
||||
},
|
||||
"tier": {
|
||||
"name": "tier",
|
||||
@@ -292,7 +294,7 @@
|
||||
"custom": "%s1 - %s2 days"
|
||||
},
|
||||
"filters": {
|
||||
"none": "No filters",
|
||||
"none": "フィルターなし",
|
||||
"tier": "Tier %s1"
|
||||
},
|
||||
"no_data": {
|
||||
@@ -305,31 +307,31 @@
|
||||
"refresh": "Refresh"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Battles",
|
||||
"winrate": "Winrate",
|
||||
"damage": "Damage",
|
||||
"damage_ratio": "Damage ratio",
|
||||
"battles": "戦闘数",
|
||||
"winrate": "勝率",
|
||||
"damage": "ダメージ",
|
||||
"damage_ratio": "ダメージ率",
|
||||
"tier": "Tier",
|
||||
"survival": "Survival",
|
||||
"accuracy": "Accuracy",
|
||||
"kills": "Kills"
|
||||
"survival": "生存",
|
||||
"accuracy": "命中率",
|
||||
"kills": "撃破"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"auction": {
|
||||
"name": "auction",
|
||||
"description": "Tanks available right now in the auction",
|
||||
"name": "オークション",
|
||||
"description": "現在オークションで購入可能な車輌",
|
||||
"body": {
|
||||
"title": "Blitz Auction",
|
||||
"subtitle": "%s1 available • next prices %s2\nBid now: %s3",
|
||||
"next": "Next price: %s1",
|
||||
"available": "Available: %s1 / %s2"
|
||||
"title": "Blitzオークション",
|
||||
"subtitle": "%s1 残り• 次の価格 %s2\n今すぐ入札: %s3",
|
||||
"next": "次の価格: %s1",
|
||||
"available": "残り: %s1 / %s2"
|
||||
},
|
||||
"errors": {
|
||||
"no_auction": "# No ongoing auction\n\nCurrently, there are no tanks available for purchase in the auction. If you think this is an error, please report this discrepancy in [the official Discord Server](https://discord.gg/nDt7AjGJQH)."
|
||||
"no_auction": "# 進行中のオークションはありません\n現在、オークションで購入可能な車輌はありません。もしこれが間違いの場合、[公式Discardサーバー](https://discord.gg/nDt7AjGJQH)に報告してください。"
|
||||
},
|
||||
"actions": {
|
||||
"bid": "Bid now"
|
||||
"bid": "今すぐ入札"
|
||||
}
|
||||
},
|
||||
"replay": {
|
||||
@@ -337,7 +339,7 @@
|
||||
"description": "Display replay results"
|
||||
},
|
||||
"research": {
|
||||
"name": "research",
|
||||
"name": "研究",
|
||||
"description": "Lists the expenses in researching a line",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
@@ -369,32 +371,32 @@
|
||||
},
|
||||
"about": {
|
||||
"name": "about",
|
||||
"description": "All the info you need about the bot",
|
||||
"description": "botについての情報の全て",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "commands",
|
||||
"description": "List of all commands and their descriptions",
|
||||
"body": "# Commands\n\nBlitzKit offers the following commands:\n\n"
|
||||
"name": "コマンド",
|
||||
"description": "全コマンドのリストと説明",
|
||||
"body": "# コマンド\nBlitzKitは以下のコマンドを提供します:"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "embeds",
|
||||
"description": "How embeds work"
|
||||
"name": "埋め込み",
|
||||
"description": "埋め込みがどう機能するか"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "introduction",
|
||||
"description": "About the bot"
|
||||
"description": "botについて"
|
||||
},
|
||||
"invite": {
|
||||
"name": "invite",
|
||||
"description": "How to invite the bot"
|
||||
"name": "招待",
|
||||
"description": "botを招待する方法"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "timezones",
|
||||
"name": "タイムゾーン",
|
||||
"description": "How BlitzKit infers and uses your timezone"
|
||||
},
|
||||
"credits": {
|
||||
"name": "credits",
|
||||
"description": "People who have helped BlitzKit"
|
||||
"name": "クレジット",
|
||||
"description": "BlitzKitを支援した人々"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -403,10 +405,10 @@
|
||||
"description": "A period's breakdown by tanks played",
|
||||
"body": {
|
||||
"total": "トータル",
|
||||
"battles": "Battles",
|
||||
"battles": "戦闘数",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Winrate",
|
||||
"damage": "Damage",
|
||||
"winrate": "勝率",
|
||||
"damage": "ダメージ",
|
||||
"unknown_tank": "Unknown tank %s1"
|
||||
}
|
||||
},
|
||||
@@ -432,7 +434,7 @@
|
||||
"description": "Player statistics"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tank",
|
||||
"name": "車輌",
|
||||
"description": "Tank statistics"
|
||||
}
|
||||
}
|
||||
@@ -458,21 +460,21 @@
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Games",
|
||||
"winrate": "Winrate",
|
||||
"battles": "Battles",
|
||||
"winrate": "勝率",
|
||||
"battles": "戦闘数",
|
||||
"wins_losses": "Wins / losses"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Efficiency",
|
||||
"wn8": "WN8",
|
||||
"survival": "Survival",
|
||||
"accuracy": "Accuracy"
|
||||
"survival": "生存",
|
||||
"accuracy": "精度"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Lethality",
|
||||
"average_damage": "Average damage",
|
||||
"damage_per_tier": "Damage per tier",
|
||||
"damage_ratio": "Damage ratio",
|
||||
"damage_ratio": "ダメージ比",
|
||||
"average_kills": "Average kills"
|
||||
},
|
||||
"miscellaneous": {
|
||||
@@ -480,7 +482,7 @@
|
||||
"average_tier": "Average tier",
|
||||
"average_spots": "Average spots",
|
||||
"average_xp": "Average XP",
|
||||
"kills_to_death_ratio": "Kills to death ratio"
|
||||
"kills_to_death_ratio": "撃破/被撃破比"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,7 +570,7 @@
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "today",
|
||||
"name": "今日",
|
||||
"description": "Today's played tanks and statistics"
|
||||
},
|
||||
"stats": {
|
||||
@@ -617,8 +619,8 @@
|
||||
"body": {
|
||||
"title": "%s1's information",
|
||||
"nickname": "Nickname",
|
||||
"battles": "Battles",
|
||||
"winrate": "Winrate",
|
||||
"battles": "戦闘数",
|
||||
"winrate": "勝率",
|
||||
"account_id": "Account ID",
|
||||
"created": "Created",
|
||||
"last_battle": "Last battle"
|
||||
@@ -629,7 +631,7 @@
|
||||
"description": "Rating player's statistics",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "today",
|
||||
"name": "今日",
|
||||
"description": "Today's rating statistics"
|
||||
},
|
||||
"season": {
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "開発者モード",
|
||||
"language": "言語 / Language"
|
||||
@@ -670,11 +676,11 @@
|
||||
"recent": "最近の閲覧",
|
||||
"select_all": "全て選択",
|
||||
"count_singular": "1 輌",
|
||||
"count_plural": "%s1 輌",
|
||||
"sorting_by": "並べ替え:%s1",
|
||||
"count_plural": "%s1輌",
|
||||
"sorting_by": ":%s1で並び替え",
|
||||
"no_tanks_found": {
|
||||
"body": "該当する車輌が存在しません。",
|
||||
"search_again": "もう一度探してください。",
|
||||
"search_again": "もう一度検索してください。",
|
||||
"clear_filters": "フィルターをクリアしてください"
|
||||
},
|
||||
"sort": {
|
||||
@@ -687,7 +693,7 @@
|
||||
"survivability.volume": "体積",
|
||||
"survivability.length": "全長",
|
||||
"fire.dpm": "通常弾DPM",
|
||||
"fire.dpmPremium": "課金弾DPM",
|
||||
"fire.dpmPremium": "プレミアム弾DPM",
|
||||
"fire.reload": "装填時間",
|
||||
"fire.caliber": "砲口径",
|
||||
"fire.standardPenetration": "通常弾貫通力",
|
||||
@@ -698,10 +704,10 @@
|
||||
"fire.shellRange": "射程範囲",
|
||||
"fire.shellCapacity": "総弾数",
|
||||
"fire.aimTime": "照準時間",
|
||||
"fire.dispersionStill": "静止時散布界",
|
||||
"fire.dispersionMoving": "移動時散布界",
|
||||
"fire.gunDepression": "主砲俯角",
|
||||
"fire.gunElevation": "主砲仰角",
|
||||
"fire.dispersionStill": "静止時拡散",
|
||||
"fire.dispersionMoving": "移動時拡散",
|
||||
"fire.gunDepression": "俯角",
|
||||
"fire.gunElevation": "仰角",
|
||||
"maneuverability.forwardsSpeed": "前進速度",
|
||||
"maneuverability.backwardsSpeed": "後退速度",
|
||||
"maneuverability.power": "馬力",
|
||||
@@ -710,17 +716,17 @@
|
||||
"maneuverability.traverseSpeed": "車体旋回速度"
|
||||
},
|
||||
"sort_dropdown": {
|
||||
"label": "ソート",
|
||||
"label": "並び替え",
|
||||
"groups": {
|
||||
"sort": {
|
||||
"no_sort": "ソートなし",
|
||||
"no_sort": "並び替えなし",
|
||||
"label": "並べ替え項目",
|
||||
"fire": "火力",
|
||||
"maneuverability": "機動性",
|
||||
"survivability": "生存性"
|
||||
},
|
||||
"direction": {
|
||||
"label": "方法",
|
||||
"label": "方向",
|
||||
"ascending": "昇順",
|
||||
"descending": "降順"
|
||||
}
|
||||
@@ -742,13 +748,13 @@
|
||||
},
|
||||
"hot_tanks": {
|
||||
"title": "人気の車輌",
|
||||
"subtitle": "過去 %s1 日間"
|
||||
"subtitle": "過去 %s1日間"
|
||||
},
|
||||
"other_projects": {
|
||||
"title": "Other cool projects"
|
||||
"title": "他のプロジェクト"
|
||||
},
|
||||
"help_translate": "%s1の %s2への翻訳にご協力ください!",
|
||||
"seo_description": "Tools for everything World of Tanks Blitz"
|
||||
"seo_description": "World of Tanks Blitz全般のツール"
|
||||
},
|
||||
"docs": {
|
||||
"patches": {
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "該当なし"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Tankopedia",
|
||||
"button": "戦車を探す",
|
||||
"description": "Blitz戦車百科",
|
||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "不整地",
|
||||
"soft": "軟弱地",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "標準化",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "装甲",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "ハルダウン",
|
||||
@@ -795,7 +839,7 @@
|
||||
"normalization": "標準化",
|
||||
"ricochet": "跳弾角度",
|
||||
"explosion_radius": "爆風半径",
|
||||
"exit": "決定",
|
||||
"exit": "終了",
|
||||
"reset": "リセット"
|
||||
},
|
||||
"advanced": "高度なハイライト",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "性能値",
|
||||
"compare": {
|
||||
"label": "性能比較",
|
||||
"label": "比較対象",
|
||||
"class": "Tier %s1 %s2",
|
||||
"tier": "Tier %s1 全車輌",
|
||||
"all": "全車輌"
|
||||
@@ -952,22 +996,22 @@
|
||||
"azimuthRight": "右射界",
|
||||
"speedForwards": "前進",
|
||||
"speedBackwards": "後退",
|
||||
"hardTerrainCoefficient": "道",
|
||||
"hardTerrainCoefficientRaw": "道",
|
||||
"mediumTerrainCoefficient": "地面",
|
||||
"mediumTerrainCoefficientRaw": "地面",
|
||||
"softTerrainCoefficient": "水辺",
|
||||
"softTerrainCoefficientRaw": "水辺",
|
||||
"hardTerrainCoefficient": "舗装路での地形走破能力",
|
||||
"hardTerrainCoefficientRaw": "舗装路での地形係数",
|
||||
"mediumTerrainCoefficient": "不整地",
|
||||
"mediumTerrainCoefficientRaw": "不整地",
|
||||
"softTerrainCoefficient": "軟弱地",
|
||||
"softTerrainCoefficientRaw": "軟弱地",
|
||||
"enginePower": "エンジン出力",
|
||||
"powerToWeightRatioHardTerrain": "道",
|
||||
"powerToWeightRatioMediumTerrain": "地面",
|
||||
"powerToWeightRatioSoftTerrain": "水辺",
|
||||
"powerToWeightRatioHardTerrain": "舗装路での重量毎出力値",
|
||||
"powerToWeightRatioMediumTerrain": "不整地",
|
||||
"powerToWeightRatioSoftTerrain": "軟弱地",
|
||||
"weight": "重量",
|
||||
"turretTraverseSpeed": "砲塔旋回速度",
|
||||
"gunTraverseSpeed": "主砲旋回速度",
|
||||
"hullTraverseHardTerrain": "道",
|
||||
"hullTraverseMediumTerrain": "地面",
|
||||
"hullTraverseSoftTerrain": "水辺",
|
||||
"hullTraverseHardTerrain": "舗装路での旋回速度",
|
||||
"hullTraverseMediumTerrain": "不整地",
|
||||
"hullTraverseSoftTerrain": "軟弱地",
|
||||
"health": "耐久値",
|
||||
"fireChance": "火災発生率",
|
||||
"viewRange": "視認範囲",
|
||||
@@ -980,7 +1024,7 @@
|
||||
"height": "全高",
|
||||
"length": "車体長",
|
||||
"volume": "体積",
|
||||
"shellRange": "射程範囲",
|
||||
"shellRange": "射程",
|
||||
"shellCapacity": "総弾数",
|
||||
"gunType": "主砲タイプ",
|
||||
"penetrationAt250m": "250m での貫通力"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1mm",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1hp",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Auto loader",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Development mode",
|
||||
"language": "Language"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "Brak wyników"
|
||||
},
|
||||
"stats": ""
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Tankopedia",
|
||||
"button": "Find tanks",
|
||||
"description": "Blitz tank encyclopedia",
|
||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Medium",
|
||||
"soft": "Soft",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "Normalization",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "Armor",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "Hull down",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Compare",
|
||||
"label": "Compare against",
|
||||
"class": "Tier %s1 %s2",
|
||||
"tier": "All of tier %s1",
|
||||
"all": "All tanks"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1mm",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1hp",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Autocarregador",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Modo de desenvolvimento",
|
||||
"language": "Idioma"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "Sem resultados"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Tanquepedia",
|
||||
"button": "Encontrar tanques",
|
||||
"description": "Blitz enciclopédia de tanques",
|
||||
"seo_description": "Estatísticas, blindagem, e mais para todos os tanques de Wolrd of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - Nível %s2 %s3 %s4 | %s5 Tanquepedia | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 blindagem, estatísticas, equipamentos, provisões e mais. %s2 DPM, %s3hp alfa, %s4mm de penetração, %s5km/h velocidade máxima, %s6hp vida.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Médio",
|
||||
"soft": "Macio",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "Normalização",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "Blindagem",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "Casco para baixo",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Características",
|
||||
"compare": {
|
||||
"label": "Comparar",
|
||||
"label": "Comparar com",
|
||||
"class": "Nível %s1 %s2",
|
||||
"tier": "Tudo de nível %s1",
|
||||
"all": "Todos os tanques"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1мм",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1hp",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/с"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Барабан",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: перемещено навсегда",
|
||||
"body": "Эта страница перемещена. Перенаправление..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Режим разработчика",
|
||||
"language": "Язык"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Угадайте танк",
|
||||
"button": "Угадать",
|
||||
"description": "Мини-игра «Силуэт»",
|
||||
"seo_description": "Играйте угадывая силуэт танка из World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Введите догадку...",
|
||||
"skip": "Пропустить",
|
||||
"guess": "Угадать",
|
||||
"next": "Следующий",
|
||||
"no_results": "Ничего не найденo"
|
||||
},
|
||||
"stats": "%s1 / %s2 угадано верно"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Поиск характеристик...",
|
||||
"name": "Танкопедия",
|
||||
"button": "Поиск танков",
|
||||
"description": "Танковая энциклопедия Blitz",
|
||||
"seo_description": "Статистика, броня и многое другое по всем танкам World of Tanks Blitz",
|
||||
"tank_seo_title": "%s1 - %s4 %s3 %s2 уровня | Танкопедия %s5 | World of Tanks Blitz (WoTB)",
|
||||
"tank_seo_description": "%s1 броня, статистика, оборудование, снабжение и многое другое. %s2 УВМ, %s3hp альфа, %s4mm пробитие, %s5км/ч лучшая скорость, %s6hp здоровье.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Корпус",
|
||||
"turret": "Башня",
|
||||
"hard": "Твёрдые",
|
||||
"medium": "Средний танк",
|
||||
"soft": "На мягком грунте",
|
||||
"effective": "Эффективно"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Угол",
|
||||
"normalization": "Нормализация",
|
||||
"effective_angle": "Эффективный угол",
|
||||
"armor": "Броня",
|
||||
"no_ricochet": "Разрывные снаряды не рикошетят"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Камо",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Промзона",
|
||||
"dead_rail": "Эшелон"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "За холмом",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Характеристики",
|
||||
"compare": {
|
||||
"label": "Сравнение",
|
||||
"label": "Сравнивать с",
|
||||
"class": "%s2 %s1 уровня",
|
||||
"tier": "Все %s1 уровня",
|
||||
"all": "Все танки"
|
||||
@@ -1143,7 +1187,7 @@
|
||||
"description": "Встраиваемые элементы для стримов",
|
||||
"seo_description": "Создать вставки для стримов по World of Tanks Blitz с невероятной кастомизации",
|
||||
"coming_soon": "Скоро появятся новые встраиваемые элементы.",
|
||||
"suggest": "Предложить идеи",
|
||||
"suggest": "Предложить идеи.",
|
||||
"preview": {
|
||||
"title": "Предпросмотр",
|
||||
"upload": "Загрузить фон для теста"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s1мм",
|
||||
"deg": "%s1°",
|
||||
"hp": "%s1хп",
|
||||
"x": "х%s1"
|
||||
"x": "х%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Магазинна система заряджання",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "Development mode",
|
||||
"language": "Мова"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "Немає результатів"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "Танкопедія",
|
||||
"button": "Знайти танки",
|
||||
"description": "Танкова енциклопедія",
|
||||
"seo_description": "Характеристики, броня та інше для всіх танків WoT Blitz",
|
||||
"tank_seo_title": "%s1 - Рівень %s2 %s3 %s4 | %s5 Танкопедія | WoT Blitz",
|
||||
"tank_seo_description": "%s1 броня, характеристики, обладнання, амуніція та більше. %s2 шкода на хвилину, %s3 разова шкода, %s4 мм пробиття, %s5 км/год максимальна швидкість, %s6 міцність.",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Середній",
|
||||
"soft": "Soft",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "Нормалізація",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "Броня",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "Від башти",
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Порівняти",
|
||||
"label": "Compare against",
|
||||
"class": "Tier %s1 %s2",
|
||||
"tier": "All of tier %s1",
|
||||
"all": "Усі танки"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"mm": "%s毫米",
|
||||
"deg": "%s1度",
|
||||
"hp": "%s生命值",
|
||||
"x": "x%s1"
|
||||
"x": "x%s1",
|
||||
"percentage": "%s1%",
|
||||
"deg_s": "%s1°/s"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "彈夾型戰車",
|
||||
@@ -651,6 +653,10 @@
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
"body": "This page has moved. Redirecting..."
|
||||
},
|
||||
"settings": {
|
||||
"dev_mode": "開發人員模式",
|
||||
"language": "語言"
|
||||
@@ -757,13 +763,51 @@
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"guess": {
|
||||
"name": "Guess the tank",
|
||||
"button": "Guess away",
|
||||
"description": "Silhouette mini-game",
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"no_results": "沒有結果"
|
||||
},
|
||||
"stats": "%s1 / %s2 guessed correctly"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"name": "戰車百科",
|
||||
"button": "尋找戰車",
|
||||
"description": "閃擊戰戰車百科全書",
|
||||
"seo_description": "世界坦克布莱茨坦克坦克世界闪击战的所有坦克的统计数字、装甲和更多",
|
||||
"tank_seo_title": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
||||
"tank_seo_description": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
||||
"visualizers": {
|
||||
"rotator": {
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "中型戰車",
|
||||
"soft": "柔软的",
|
||||
"effective": "Effective"
|
||||
},
|
||||
"ricochet": {
|
||||
"angle": "Angle",
|
||||
"normalization": "轉正",
|
||||
"effective_angle": "Effective angle",
|
||||
"armor": "裝甲",
|
||||
"no_ricochet": "Explosive shells don't ricochet"
|
||||
},
|
||||
"view_range": {
|
||||
"camo": "Camo",
|
||||
"percentage": "%s1%",
|
||||
"ghost_factory": "Ghost Factory",
|
||||
"dead_rail": "Dead Rail"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
"poses": {
|
||||
"hull_down": "戰車下部",
|
||||
@@ -810,14 +854,14 @@
|
||||
"track": "履帶"
|
||||
},
|
||||
"status": {
|
||||
"penetration": "%s生命值 擊穿",
|
||||
"penetration": "%s1生命值 擊穿",
|
||||
"blocked": "阻擋傷害",
|
||||
"ricochet": "跳彈",
|
||||
"splash": "%s生命值 爆炸範圍"
|
||||
},
|
||||
"stats": {
|
||||
"thickness_and_angle": "等效%s毫米 %s2度",
|
||||
"nominal": "%s毫米 裝甲厚度",
|
||||
"thickness_and_angle": "等效%s1毫米 %s2度",
|
||||
"nominal": "%s1毫米 裝甲厚度",
|
||||
"ricochet_loss": "%s1%機率擊穿"
|
||||
}
|
||||
}
|
||||
@@ -900,7 +944,7 @@
|
||||
"characteristics": {
|
||||
"title": "属性",
|
||||
"compare": {
|
||||
"label": "比較",
|
||||
"label": "比较",
|
||||
"class": "%s1 %s2 级",
|
||||
"tier": "所有级别 %s1",
|
||||
"all": "所有坦克"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mkdir, writeFile } from 'fs/promises';
|
||||
import { parse as parsePath } from 'path';
|
||||
import ProgressBar from 'progress';
|
||||
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
||||
import { dvp } from '../../../submodules/blitzkit-closed/src/dvp';
|
||||
import { dvp } from '../../../submodules/blitzkit-closed/src/dava/dvp';
|
||||
import { readStringDVPL } from '../src/core/blitz/readStringDVPL';
|
||||
import { DATA } from './buildAssets/constants';
|
||||
import { readYAMLDVPL } from './core/blitz/readYAMLDVPL';
|
||||
|
||||
@@ -5,11 +5,15 @@ const WINDOWS_APPS = 'C:/Program Files/WindowsApps';
|
||||
const wotbPackageRegex = /7458BE2C\..+_\d+(\.\d+)+_x64__.+/;
|
||||
|
||||
const isDepot = argv.includes('--depot');
|
||||
const isManual = argv.includes('--manual');
|
||||
|
||||
let data: string;
|
||||
let compressed: boolean;
|
||||
|
||||
if (isDepot) {
|
||||
if (isManual) {
|
||||
data = '../../temp/game/Data';
|
||||
compressed = true;
|
||||
} else if (isDepot) {
|
||||
const [installationVersion] = await readdir(`../../depots/444202`);
|
||||
data = `../../depots/444202/${installationVersion}/Data`;
|
||||
compressed = true;
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ResearchCost,
|
||||
ShellType,
|
||||
SkillDefinitions,
|
||||
slugify,
|
||||
TankClass,
|
||||
TankDefinitions,
|
||||
TankPrice,
|
||||
@@ -37,7 +38,6 @@ import {
|
||||
SUPPORTED_LOCALES,
|
||||
} from '@blitzkit/i18n';
|
||||
import { readdir } from 'fs/promises';
|
||||
import { deburr } from 'lodash-es';
|
||||
import { parse as parsePath } from 'path';
|
||||
import { Vector3Tuple } from 'three';
|
||||
import { parse as parseYaml } from 'yaml';
|
||||
@@ -49,11 +49,6 @@ import { DATA } from './constants';
|
||||
import { Avatar } from './skillIcons';
|
||||
import { TankParameters } from './tankIcons';
|
||||
|
||||
const nonAlphanumericRegex = /[^a-z0-9]/g;
|
||||
const multipleDashesRegex = /--+/g;
|
||||
const trailingDashRegex = /-$/g;
|
||||
const leadingDashRegex = /^-/g;
|
||||
|
||||
const nationSlugDiscriminators = {
|
||||
china: 'cn',
|
||||
european: 'eu',
|
||||
@@ -740,12 +735,7 @@ export async function definitions() {
|
||||
? getString(tank.shortUserString)
|
||||
: undefined) ?? getString(tank.userString)
|
||||
).locales.en;
|
||||
|
||||
let slug = deburr(name).toLowerCase();
|
||||
slug = slug.replaceAll(nonAlphanumericRegex, '-');
|
||||
slug = slug.replaceAll(multipleDashesRegex, '-');
|
||||
slug = slug.replaceAll(trailingDashRegex, '');
|
||||
slug = slug.replaceAll(leadingDashRegex, '');
|
||||
const slug = slugify(name);
|
||||
|
||||
idToNation[tankId] = nation;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
|
||||
import locales from '@blitzkit/i18n/locales.json';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { extname } from 'path';
|
||||
import ProgressBar from 'progress';
|
||||
import { commitAssets } from '../core/github/commitAssets';
|
||||
|
||||
@@ -28,26 +28,24 @@ export async function tankModels() {
|
||||
|
||||
console.log(`Building models for ${nation}`);
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(tanks.root).map(async ([tankKey, tank]) => {
|
||||
if (tankKey.includes('tutorial_bot')) return;
|
||||
for (const [tankKey, tank] of Object.entries(tanks.root)) {
|
||||
if (tankKey.includes('tutorial_bot')) continue;
|
||||
|
||||
const id = toUniqueId(nation, tank.id);
|
||||
const id = toUniqueId(nation, tank.id);
|
||||
|
||||
const parameters = await readYAMLDVPL<TankParameters>(
|
||||
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||
);
|
||||
const model = await extractModel(
|
||||
DATA,
|
||||
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ''),
|
||||
);
|
||||
const parameters = await readYAMLDVPL<TankParameters>(
|
||||
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||
);
|
||||
const model = await extractModel(
|
||||
DATA,
|
||||
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ''),
|
||||
);
|
||||
|
||||
changes.push({
|
||||
path: `3d/tanks/models/${id}.glb`,
|
||||
content: Buffer.from(await nodeIO.writeBinary(model)),
|
||||
});
|
||||
}),
|
||||
);
|
||||
changes.push({
|
||||
path: `3d/tanks/models/${id}.glb`,
|
||||
content: Buffer.from(await nodeIO.writeBinary(model)),
|
||||
});
|
||||
}
|
||||
|
||||
await commitAssets(`tank models ${nation}`, changes);
|
||||
}
|
||||
|
||||
@@ -46,13 +46,13 @@ export function readDVPL(buffer: Buffer) {
|
||||
source.length,
|
||||
0,
|
||||
);
|
||||
|
||||
|
||||
if (decompressedSize !== footerData.oSize) {
|
||||
throw new RangeError(
|
||||
`Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return Buffer.from(destination);
|
||||
} else {
|
||||
throw new SyntaxError('Unknown DVPL format');
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { readFile } from 'fs/promises';
|
||||
import { DATA_COMPRESSED } from '../../buildAssets/constants';
|
||||
import { readDVPL } from './readDVPL';
|
||||
|
||||
export async function readDVPLFile(file: string) {
|
||||
if (DATA_COMPRESSED && !file.endsWith('.dvpl')) {
|
||||
return readDVPL(await readFile(`${file}.dvpl`));
|
||||
}
|
||||
const path = `${file}${file.endsWith('.dvpl') ? '' : '.dvpl'}`;
|
||||
const content = await readFile(path);
|
||||
const dvpl = readDVPL(content);
|
||||
|
||||
return readFile(file);
|
||||
return dvpl;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
|
||||
const resolvedTexturePath = isDds
|
||||
? ddsTexturePath
|
||||
: ddsTexturePath.replace('.dds', '.pvr');
|
||||
const decompressedDvpl = await readDVPLFile(resolvedTexturePath);
|
||||
const decompressedDvpl = await readDVPLFile(`${resolvedTexturePath}.dvpl`);
|
||||
|
||||
const raw = isDds
|
||||
? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds()
|
||||
@@ -75,4 +75,5 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
|
||||
default:
|
||||
return await sharp(raw.data, { raw }).jpeg().toBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { exec as execSync } from 'child_process';
|
||||
import { existsSync } from 'fs';
|
||||
import { readdir, rm, writeFile } from 'fs/promises';
|
||||
import { chunk } from 'lodash-es';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const ROOT = 'packages/core/src/protos';
|
||||
|
||||
const exec = promisify(execSync);
|
||||
|
||||
let executableFileExtension: string;
|
||||
@@ -15,33 +14,42 @@ if (existsSync('node_modules/.bin/protoc-gen-ts_proto.exe')) {
|
||||
executableFileExtension = '';
|
||||
}
|
||||
|
||||
const filesRaw = await readdir(`${ROOT}`);
|
||||
await Promise.all(
|
||||
filesRaw.map(async (file) => {
|
||||
if (!file.endsWith('.proto')) {
|
||||
await rm(`${ROOT}/${file}`);
|
||||
}
|
||||
}),
|
||||
);
|
||||
await compile('packages/core/src/protos');
|
||||
await compile('submodules/blitzkit-closed/src/protos');
|
||||
|
||||
const files = filesRaw.filter((file) => file.endsWith('.proto'));
|
||||
const args = [
|
||||
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
|
||||
'--ts_proto_opt=esModuleInterop=true',
|
||||
'--ts_proto_opt=oneof=unions-value',
|
||||
'--ts_proto_opt=removeEnumPrefix=true',
|
||||
'--ts_proto_opt=unrecognizedEnum=false',
|
||||
'--ts_proto_opt=snakeToCamel=false',
|
||||
'--ts_proto_out=.',
|
||||
...files.map((file) => `${ROOT}/${file}`),
|
||||
];
|
||||
async function compile(root: string) {
|
||||
const filesRaw = await readdir(root);
|
||||
|
||||
await exec(`protoc ${args.join(' ')}`);
|
||||
await writeFile(
|
||||
`${ROOT}/index.ts`,
|
||||
'// @ts-nocheck\n' +
|
||||
files
|
||||
.map((file) => file.replace('.proto', ''))
|
||||
.map((file) => `export * from './${file}.ts';`)
|
||||
.join('\n'),
|
||||
);
|
||||
for (const file of filesRaw) {
|
||||
if (!file.endsWith('.ts')) continue;
|
||||
await rm(`${root}/${file}`);
|
||||
}
|
||||
|
||||
const allFiles = filesRaw.filter((file) => file.endsWith('.proto'));
|
||||
|
||||
for (const files of chunk(allFiles, 32)) {
|
||||
const args = [
|
||||
`-I=${root}`,
|
||||
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
|
||||
'--ts_proto_opt=esModuleInterop=true',
|
||||
'--ts_proto_opt=oneof=unions-value',
|
||||
// '--ts_proto_opt=removeEnumPrefix=true',
|
||||
'--ts_proto_opt=unrecognizedEnum=false',
|
||||
'--ts_proto_opt=snakeToCamel=false',
|
||||
`--ts_proto_out=${root}`,
|
||||
...files.map((file) => `${root}/${file}`),
|
||||
];
|
||||
|
||||
await exec(`protoc ${args.join(' ')}`);
|
||||
}
|
||||
|
||||
await writeFile(
|
||||
`${root}/index.ts`,
|
||||
'// @ts-nocheck\n' +
|
||||
allFiles
|
||||
.sort()
|
||||
.map((file) => file.replace('.proto', ''))
|
||||
.map((file) => `export * from './${file}.ts';`)
|
||||
.join('\n'),
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src/**/*"]
|
||||
"include": ["src/**/*"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "../../"
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@
|
||||
import partytown from '@astrojs/partytown';
|
||||
import react from '@astrojs/react';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
export default defineConfig({
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: [...SUPPORTED_LOCALES],
|
||||
defaultLocale: locales.default,
|
||||
locales: locales.supported.map(({ locale }) => locale),
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@astrojs/partytown": "^2.1.4",
|
||||
"@astrolib/seo": "^1.0.0-beta.8",
|
||||
"@blitzkit/closed": "workspace:*",
|
||||
"@blitzkit/core": "workspace:*",
|
||||
"@blitzkit/i18n": "workspace:*",
|
||||
"@fontsource/inter": "^5.2.5",
|
||||
@@ -20,10 +21,10 @@
|
||||
"@nivo/bar": "^0.87.0",
|
||||
"@nivo/line": "^0.88.0",
|
||||
"@radix-ui/colors": "^3.0.0",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/themes": "^3.1.4",
|
||||
"@react-three/drei": "^9.115.0",
|
||||
"@react-three/fiber": "^8.17.10",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@radix-ui/themes": "^3.2.1",
|
||||
"@react-three/drei": "^10.0.8",
|
||||
"@react-three/fiber": "^9.1.2",
|
||||
"compare-versions": "^6.1.1",
|
||||
"echarts": "^5.5.1",
|
||||
"immer": "^10.1.1",
|
||||
@@ -31,9 +32,7 @@
|
||||
"markdown-to-jsx": "^7.5.0",
|
||||
"nanostores": "^0.11.3",
|
||||
"quicklime": "^1.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-promise-suspense": "^0.3.4",
|
||||
"three": "^0.169.0",
|
||||
"urlon": "^3.1.0",
|
||||
@@ -46,10 +45,7 @@
|
||||
"@playform/compress": "^0.1.9",
|
||||
"@playform/inline": "^0.1.2",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@types/three": "^0.160.0",
|
||||
"astro": "^4.16.7",
|
||||
"astro-compressor": "^1.0.0"
|
||||
"astro": "^4.16.7"
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -23,7 +23,9 @@ export function AesonPlug() {
|
||||
|
||||
<Flex py="3" px="5" direction="column" justify="center">
|
||||
<Heading size="5">Preview brought to you by WoT Blitz News</Heading>
|
||||
<Text color="gray">What the hell do I put here haha</Text>
|
||||
<Text color="gray">
|
||||
Join the Discord for the absolute latest news
|
||||
</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Link>
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
import { TankClass } from '@blitzkit/core';
|
||||
import { TankClass as TankClass_dava } from '@blitzkit/core';
|
||||
import { TankClass } from '@protos/blitz_static_tank_component';
|
||||
import { QuestionMarkIcon } from '@radix-ui/react-icons';
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { ClassHeavy } from './components/ClassHeavy';
|
||||
import { ClassLight } from './components/ClassLight';
|
||||
import { ClassMedium } from './components/ClassMedium';
|
||||
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
|
||||
|
||||
export const classIcons: Record<
|
||||
export const classIcons_ue: Record<
|
||||
TankClass,
|
||||
((props: ComponentProps<'svg'>) => ReactNode) | typeof QuestionMarkIcon
|
||||
> = {
|
||||
[TankClass.TANK_CLASS_UNSPECIFIED]: QuestionMarkIcon,
|
||||
[TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
|
||||
[TankClass.TANK_CLASS_HEAVY]: ClassHeavy,
|
||||
[TankClass.TANK_CLASS_LIGHT]: ClassLight,
|
||||
[TankClass.TANK_CLASS_MEDIUM]: ClassMedium,
|
||||
};
|
||||
|
||||
export const classIcons: Record<
|
||||
TankClass_dava,
|
||||
(props: ComponentProps<'svg'>) => ReactNode
|
||||
> = {
|
||||
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
|
||||
[TankClass.HEAVY]: ClassHeavy,
|
||||
[TankClass.LIGHT]: ClassLight,
|
||||
[TankClass.MEDIUM]: ClassMedium,
|
||||
[TankClass_dava.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
|
||||
[TankClass_dava.TANK_CLASS_HEAVY]: ClassHeavy,
|
||||
[TankClass_dava.TANK_CLASS_LIGHT]: ClassLight,
|
||||
[TankClass_dava.TANK_CLASS_MEDIUM]: ClassMedium,
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { RewardCurrency } from '@protos/blitz_static_reward_currency';
|
||||
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
||||
import { entityName } from 'packages/core/src';
|
||||
import { useLocale } from '../hooks/useLocale';
|
||||
|
||||
type CurrencyProps = TextProps & {
|
||||
reward: RewardCurrency;
|
||||
};
|
||||
|
||||
export function Currency({ reward, ...props }: CurrencyProps) {
|
||||
const { locale } = useLocale();
|
||||
|
||||
return (
|
||||
<Text {...props}>
|
||||
<Flex align="center" gap="1">
|
||||
{reward.amount.toLocaleString(locale)}
|
||||
<img
|
||||
src={`/api/currencies/${entityName(reward.currency_catalog_id)}.webp`}
|
||||
/>
|
||||
</Flex>
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
@@ -130,15 +130,13 @@ const strings = getStrings(locale);
|
||||
<Flex gap="5" display={{ initial: 'flex', sm: 'none' }}>
|
||||
<Flex direction="column" justify="between" align="end">
|
||||
<Text size="2" color="gray">BlitzKit</Text>
|
||||
|
||||
{
|
||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
||||
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||
<Text size="2" color="gray">
|
||||
WoTB
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
<Text size="2" color="gray">CDN</Text>
|
||||
</Flex>
|
||||
|
||||
@@ -146,15 +144,13 @@ const strings = getStrings(locale);
|
||||
<Code size="2" color="gray">
|
||||
{packageJson.version}
|
||||
</Code>
|
||||
|
||||
{
|
||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
||||
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||
<Code size="2" color="gray">
|
||||
{gameDefinitions.version}
|
||||
</Code>
|
||||
)
|
||||
}
|
||||
|
||||
<Code size="2" color="gray">
|
||||
{PUBLIC_ASSET_BRANCH}
|
||||
</Code>
|
||||
@@ -168,7 +164,7 @@ const strings = getStrings(locale);
|
||||
</Code>
|
||||
|
||||
{
|
||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
||||
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||
<>
|
||||
<Text size="2" color="gray">
|
||||
WoTB
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import locales from '@blitzkit/i18n/locales.json';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { literals } from '@blitzkit/i18n/src/literals';
|
||||
import { Flex, Text } from '@radix-ui/themes';
|
||||
import fuzzysort from 'fuzzysort';
|
||||
|
||||
@@ -3,11 +3,16 @@ import { Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { resolveBranchName } from '../core/blitzkit/branches';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import { literals } from '@blitzkit/i18n/src/literals';
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
|
||||
const { locale } = Astro.params;
|
||||
interface Props {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
const branchName = resolveBranchName(locale);
|
||||
const isBranchNamed = branchName !== undefined;
|
||||
const strings = getStrings(locale);
|
||||
---
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
||||
import { Link, type LinkProps } from '@radix-ui/themes';
|
||||
import type { LocaleAcceptorProps } from '../hooks/useLocale';
|
||||
|
||||
type LinkI18nProps = LinkProps & LocaleAcceptorProps;
|
||||
type LinkI18nProps = LinkProps & {
|
||||
locale: string;
|
||||
};
|
||||
|
||||
export function LinkI18n({ locale, href, ...props }: LinkI18nProps) {
|
||||
const prefix =
|
||||
locale === undefined || locale === DEFAULT_LOCALE ? '' : `/${locale}`;
|
||||
const prefix = locale === DEFAULT_LOCALE ? '' : `/${locale}`;
|
||||
|
||||
return (
|
||||
<Link href={href?.startsWith('/') ? `${prefix}${href}` : href} {...props} />
|
||||
|
||||
@@ -15,11 +15,11 @@ import { LinkI18n } from './LinkI18n';
|
||||
|
||||
export interface Props {
|
||||
integrated?: boolean;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { integrated } = Astro.props;
|
||||
const { integrated, locale } = Astro.props;
|
||||
const toolsFiltered = TOOLS.filter((tool) => !('href' in tool));
|
||||
const { locale } = Astro.params;
|
||||
const branchName = resolveBranchName(locale);
|
||||
const isBranchNamed = branchName !== undefined;
|
||||
const strings = getStrings(locale);
|
||||
|
||||
@@ -13,7 +13,9 @@ export function Listing({ label, ...props }: ListingProps) {
|
||||
gap="4"
|
||||
style={{ borderBottom: `1px solid ${Var('gray-a9')}` }}
|
||||
>
|
||||
<Text size="4">{label}</Text>
|
||||
<Text size="4" wrap="nowrap">
|
||||
{label}
|
||||
</Text>
|
||||
<Text align="right" size="4" weight="medium" {...props} />
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
import { Nation, TankType } from '@protos/blitz_static_tank_component';
|
||||
import { Box, Code, Flex } from '@radix-ui/themes';
|
||||
import { asset, TIER_ROMAN_NUMERALS } from 'packages/core/src';
|
||||
import { Var } from '../../core/radix/var';
|
||||
import { useLocale } from '../../hooks/useLocale';
|
||||
import { TankopediaEphemeral_ue } from '../../stores/tankopediaEphemeral_ue';
|
||||
import { classIcons_ue } from '../ClassIcon';
|
||||
import { Currency } from '../Currency';
|
||||
import { Listing } from '../Tankopedia/MetaSection/components/Listing';
|
||||
|
||||
const NATIONAL_BANNER_POSITION_OVERRIDES: Partial<Record<Nation, string>> = {
|
||||
[Nation.NATION_GERMANY]: '50% 35%',
|
||||
[Nation.NATION_FRANCE]: '50% 35%',
|
||||
[Nation.NATION_OTHER]: '50% 35%',
|
||||
};
|
||||
|
||||
export function MetaSection() {
|
||||
const tank = TankopediaEphemeral_ue.use((state) => state.tank);
|
||||
const entity = TankopediaEphemeral_ue.use((state) => state.entity);
|
||||
const set = TankopediaEphemeral_ue.use((state) => state.set);
|
||||
const compensation = TankopediaEphemeral_ue.use(
|
||||
(state) => state.compensation,
|
||||
);
|
||||
const catalogueId = TankopediaEphemeral_ue.use((state) => state.entity);
|
||||
const ClassIcon = classIcons_ue[tank.tank_class];
|
||||
const { locale, strings, gameStrings } = useLocale();
|
||||
const reward = set.tank_set_rewards.find(
|
||||
(reward) =>
|
||||
reward.tank_set_reward_on_level &&
|
||||
reward.tank_set_reward_on_level.reward_list.some(
|
||||
(rewardOnLevel) =>
|
||||
rewardOnLevel.tank_reward &&
|
||||
rewardOnLevel.tank_reward.tank_catalog_id === catalogueId,
|
||||
),
|
||||
)!;
|
||||
const price =
|
||||
reward.tank_set_reward_price?.price_list[0].currency_price!.amount;
|
||||
|
||||
return (
|
||||
<Flex justify="center" mt="-9">
|
||||
<Box
|
||||
style={{
|
||||
background: `url(/assets/images/national-wallpapers/${tank.nation}.jpg)`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition:
|
||||
NATIONAL_BANNER_POSITION_OVERRIDES[tank.nation] ?? 'center',
|
||||
}}
|
||||
flexGrow="1"
|
||||
maxWidth="120rem"
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
background: `url(${asset(`flags/scratched/${tank.nation}.webp`)})`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: 'min(53rem, 80vw)',
|
||||
backgroundPosition: '-8rem 50%',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
justify="center"
|
||||
align="center"
|
||||
py="6rem"
|
||||
style={{
|
||||
background: `linear-gradient(${Var('black-a8')}, ${Var('black-a8')}, ${Var('gray-1')})`,
|
||||
}}
|
||||
>
|
||||
<Flex direction="column" align="center" gap="6">
|
||||
<Flex
|
||||
gap={{ initial: '2', sm: '8' }}
|
||||
direction={{ initial: 'column', sm: 'row' }}
|
||||
>
|
||||
<Flex direction="column" width="100%" gap="2">
|
||||
<Listing label={strings.website.tools.tankopedia.meta.nation}>
|
||||
<Flex align="center" gap="1">
|
||||
<img
|
||||
style={{ width: '1em', height: '1em' }}
|
||||
alt={Nation[tank.nation]}
|
||||
src={asset(`flags/circle/${tank.nation}.webp`)}
|
||||
/>
|
||||
{strings.common.nations[tank.nation]}
|
||||
</Flex>
|
||||
</Listing>
|
||||
<Listing label={strings.website.tools.tankopedia.meta.class}>
|
||||
<Flex align="center" gap="1">
|
||||
<ClassIcon width="1em" height="1em" />
|
||||
{strings.common.tank_class[tank.tank_class]}
|
||||
</Flex>
|
||||
</Listing>
|
||||
|
||||
<Listing label={strings.website.tools.tankopedia.meta.tier}>
|
||||
{TIER_ROMAN_NUMERALS[tank.tier]}
|
||||
</Listing>
|
||||
|
||||
<Listing
|
||||
label={strings.website.tools.tankopedia.meta.type}
|
||||
color={
|
||||
tank.tank_type === TankType.TANK_TYPE_COLLECTIBLE
|
||||
? 'blue'
|
||||
: tank.tank_type === TankType.TANK_TYPE_PREMIUM
|
||||
? 'amber'
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{strings.common.tree_type[tank.tank_type]}
|
||||
</Listing>
|
||||
|
||||
<Listing label={strings.website.tools.tankopedia.meta.id}>
|
||||
<Code variant="ghost">
|
||||
{entity.replace('TankEntity.', '')}
|
||||
</Code>
|
||||
</Listing>
|
||||
</Flex>
|
||||
|
||||
<Flex direction="column" width="100%" gap="2">
|
||||
<Listing label={strings.website.tools.tankopedia.meta.set}>
|
||||
{gameStrings[set.tank_set_ui!.tank_set_displayed_name]}
|
||||
</Listing>
|
||||
|
||||
<Listing label={strings.website.tools.tankopedia.meta.price}>
|
||||
<Flex align="center" gap="1">
|
||||
{reward.tank_set_reward_price === undefined ? (
|
||||
strings.website.tools.tankopedia.meta.free
|
||||
) : (
|
||||
<>
|
||||
{price?.toLocaleString(locale)}
|
||||
|
||||
<img
|
||||
style={{ width: '1em', height: '1em' }}
|
||||
alt="xp"
|
||||
src={
|
||||
'https://wotblitz-gc.gcdn.co/dlc/ultra_test2_25abc2385a5/assets/Medusa/Currency/T_UI_Currency_Silver_S.webp'
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
</Listing>
|
||||
|
||||
{compensation.compensation?.currency_reward && (
|
||||
<Listing
|
||||
label={strings.website.tools.tankopedia.meta.compensation}
|
||||
>
|
||||
<Currency
|
||||
reward={compensation.compensation.currency_reward}
|
||||
/>
|
||||
</Listing>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
type CompositeStats,
|
||||
type CompositeStatsKey,
|
||||
} from '@blitzkit/core';
|
||||
import strings from '@blitzkit/i18n/strings/en.json';
|
||||
import { amberDark, blueDark } from '@radix-ui/colors';
|
||||
import { Flex, Text, type FlexProps } from '@radix-ui/themes';
|
||||
import { times } from 'lodash-es';
|
||||
@@ -53,7 +52,7 @@ export function BreakdownEmbedCard({
|
||||
}: BreakdownEmbedCardProps) {
|
||||
const { useEmbedState, useRichText } =
|
||||
useEmbedStateCurry<typeof breakdownConfig>();
|
||||
const { unwrap } = useLocale();
|
||||
const { unwrap, strings } = useLocale();
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export function TestComponent({ data }: { data: any }) {
|
||||
useEffect(() => {
|
||||
console.log(data);
|
||||
}, []);
|
||||
|
||||
return 'TestComponent';
|
||||
}
|
||||
@@ -2,20 +2,20 @@
|
||||
import { assertSecret } from '@blitzkit/core';
|
||||
import { CaretRightIcon } from '@radix-ui/react-icons';
|
||||
import { Box, Button, Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
import type { Tool } from '../constants/tools';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import { LinkI18n } from './LinkI18n';
|
||||
|
||||
interface Props {
|
||||
tool: Tool;
|
||||
strings: BlitzKitStrings;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { tool } = Astro.props;
|
||||
const { tool, strings, locale } = Astro.props;
|
||||
const disabled = tool.branches?.every(
|
||||
(branch) => branch !== assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH),
|
||||
);
|
||||
const { locale } = Astro.params;
|
||||
const strings = getStrings(locale);
|
||||
const toolStrings =
|
||||
strings.website.tools[
|
||||
(tool.stringsId ?? tool.id) as keyof typeof strings.website.tools
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import { DiscreteMetadataAccessor } from 'packages/core/src';
|
||||
|
||||
export const discreteMetadata = new DiscreteMetadataAccessor('/api/catalog');
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { TankSetCatalogComponent } from '@protos/blitz_static_tank_set_component';
|
||||
import type { MetadataAccessor } from 'submodules/blitzkit-closed/src';
|
||||
|
||||
export async function tankToSet(metadata: MetadataAccessor, tank: string) {
|
||||
for (const [id] of metadata.items) {
|
||||
if (!id.startsWith('TankSetEntity')) continue;
|
||||
|
||||
const components = await metadata.get(id);
|
||||
const set = await components.get<TankSetCatalogComponent>(
|
||||
'tankSetCatalogComponent',
|
||||
);
|
||||
|
||||
for (const reward of set.tank_set_rewards) {
|
||||
if (!reward.tank_set_reward_on_level) continue;
|
||||
|
||||
for (const rewardOnLevel of reward.tank_set_reward_on_level.reward_list) {
|
||||
if (!rewardOnLevel.tank_reward) continue;
|
||||
|
||||
if (rewardOnLevel.tank_reward.tank_catalog_id === tank) {
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Tank ${tank} not found in any set`);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { requestAutoProxyClient, unpackMetadata } from '@blitzkit/closed';
|
||||
import type { GetPackedMetadataAsyncResponse } from '@blitzkit/closed/src/unreal/protos/auto_legacy_proxy_client';
|
||||
import { UnpackedMetadataAccessor } from 'packages/core/src';
|
||||
|
||||
export const unpackedMetadata = new UnpackedMetadataAccessor(
|
||||
await requestAutoProxyClient<GetPackedMetadataAsyncResponse>(
|
||||
'GetPackedMetadataAsyncRequest',
|
||||
).then(unpackMetadata),
|
||||
);
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DEFAULT_LOCALE, STRINGS, type SupportedLocale } from '@blitzkit/i18n';
|
||||
import en from '@strings/en.json' with { type: 'json' };
|
||||
import { merge } from 'lodash-es';
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
|
||||
export function getStrings(locale: string = DEFAULT_LOCALE) {
|
||||
if (locale in STRINGS) return STRINGS[locale as SupportedLocale];
|
||||
throw new Error(`Unsupported locale: ${locale}`);
|
||||
export async function getStrings(locale: string) {
|
||||
const strings = await import(`../../../../i18n/strings/${locale}.json`);
|
||||
return merge({}, en, strings) as BlitzKitStrings;
|
||||
}
|
||||
@@ -1,39 +1,30 @@
|
||||
import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n';
|
||||
import { createContext, useContext, type ReactNode } from 'react';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
import { createContext, use, useContext } from 'react';
|
||||
const LocaleContext = createContext<string | null>(null);
|
||||
|
||||
const LocaleContext = createContext<{
|
||||
interface LocaleProviderProps {
|
||||
locale: string;
|
||||
localeRaw: string | undefined;
|
||||
} | null>(null);
|
||||
|
||||
interface LocaleProviderProps extends LocaleAcceptorProps {
|
||||
children: ReactNode;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function LocaleProvider({ locale, children }: LocaleProviderProps) {
|
||||
const isSupported = locales.supported.some(
|
||||
(supported) => supported.locale === locale,
|
||||
);
|
||||
|
||||
if (!isSupported) throw new Error(`Unsupported locale: ${locale}`);
|
||||
|
||||
return (
|
||||
<LocaleContext.Provider
|
||||
value={{ locale: locale ?? DEFAULT_LOCALE, localeRaw: locale }}
|
||||
>
|
||||
{children}
|
||||
</LocaleContext.Provider>
|
||||
<LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useLocale() {
|
||||
const context = useContext(LocaleContext);
|
||||
const locale = useContext(LocaleContext);
|
||||
const strings = use<BlitzKitStrings>(
|
||||
fetch(`/api/strings/${locale}.json`).then((response) => response.json()),
|
||||
);
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useLocale must be used within a LocaleProvider');
|
||||
}
|
||||
|
||||
const strings = getStrings(context.locale);
|
||||
const unwrap = unwrapper(context.locale);
|
||||
|
||||
return { locale: context.locale, strings, unwrap };
|
||||
}
|
||||
|
||||
export interface LocaleAcceptorProps {
|
||||
locale: string | undefined;
|
||||
return { locale, strings };
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
import '@fontsource/inter';
|
||||
import { Flex } from '@radix-ui/themes';
|
||||
import { BlitzKitTheme } from '../components/BlitzKitTheme';
|
||||
import { Checks } from '../components/Checks';
|
||||
@@ -7,16 +6,18 @@ import Footer from '../components/Footer.astro';
|
||||
import Navbar from '../components/Navbar.astro';
|
||||
import Party3 from '../components/Party3.astro';
|
||||
import './base.css';
|
||||
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
|
||||
export interface Props {
|
||||
noFooter?: boolean;
|
||||
noNavbar?: boolean;
|
||||
integrated?: boolean;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { noFooter, noNavbar, integrated } = Astro.props;
|
||||
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||
const { noFooter, noNavbar, integrated, locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
---
|
||||
|
||||
<html lang={locale}>
|
||||
@@ -30,25 +31,26 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||
<Party3 />
|
||||
|
||||
<script>
|
||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { getBestLocale } from '../core/i18n/getBestLocale';
|
||||
const isAPI = window.location.pathname.startsWith('/api');
|
||||
const isI18nPath = SUPPORTED_LOCALES.some((locale) =>
|
||||
const isI18nPath = locales.supported.some(({ locale }) =>
|
||||
window.location.pathname.startsWith(`/${locale}`),
|
||||
);
|
||||
const bestLocale = getBestLocale();
|
||||
const currentPathLocale = SUPPORTED_LOCALES.find((locale) =>
|
||||
const currentPathLocale = locales.supported.find(({ locale }) =>
|
||||
window.location.pathname.startsWith(`/${locale}`),
|
||||
);
|
||||
|
||||
if (
|
||||
!isAPI && // not an api, duh!
|
||||
localStorage.getItem('preferred-locale') !== null && // no preference, so probably google's crawler
|
||||
bestLocale !== currentPathLocale // we need to redirect
|
||||
currentPathLocale &&
|
||||
bestLocale !== currentPathLocale.locale // we need to redirect
|
||||
) {
|
||||
window.location.pathname = isI18nPath
|
||||
? window.location.pathname.replace(
|
||||
`/${currentPathLocale}`,
|
||||
`/${currentPathLocale.locale}`,
|
||||
bestLocale === undefined ? '' : `/${bestLocale}`,
|
||||
)
|
||||
: `/${bestLocale}${window.location.pathname}`;
|
||||
@@ -61,9 +63,9 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||
<body class={noNavbar ? 'no-navbar' : ''}>
|
||||
<BlitzKitTheme>
|
||||
<Flex direction="column" minHeight="100vh">
|
||||
<Navbar {integrated} />
|
||||
<Navbar {locale} {integrated} />
|
||||
|
||||
<Checks {locale} client:only="react" />
|
||||
<Checks localeContext={{ locale, strings }} client:only="react" />
|
||||
|
||||
<slot />
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
@import '@radix-ui/themes/styles.css';
|
||||
|
||||
.radix-themes {
|
||||
--default-font-family: 'Inter';
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
---
|
||||
import { AstroSeo } from '@astrolib/seo';
|
||||
import { assertSecret } from '@blitzkit/core';
|
||||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { literals } from '@blitzkit/i18n/src/literals';
|
||||
import { Box, Flex, Heading, Link } from '@radix-ui/themes';
|
||||
import type { GetStaticPaths } from 'astro';
|
||||
import { AesonPlug } from '../../components/AesonPlug';
|
||||
import HomeHero from '../../components/HomeHero.astro';
|
||||
import { HomePageHotTanks } from '../../components/HomePageHotTanks';
|
||||
import { Plugs } from '../../components/Plugs';
|
||||
import ToolCard from '../../components/ToolCard.astro';
|
||||
import {
|
||||
@@ -25,17 +24,16 @@ import { getStrings } from '../../core/i18n/getStrings';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
|
||||
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
||||
const MODE = assertSecret(import.meta.env.MODE);
|
||||
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||
const strings = getStrings(Astro.params.locale);
|
||||
const { locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return [
|
||||
...SUPPORTED_LOCALES.filter((locale) => locale !== DEFAULT_LOCALE).map(
|
||||
(locale) => ({ params: { locale } }),
|
||||
),
|
||||
{ params: { locale: undefined } },
|
||||
];
|
||||
return locales.supported.map(({ locale, blitz }) => {
|
||||
return {
|
||||
params: { locale: locale === locales.default ? undefined : locale },
|
||||
props: { locale, blitzLocale: blitz ?? locale },
|
||||
};
|
||||
});
|
||||
}) satisfies GetStaticPaths;
|
||||
---
|
||||
|
||||
@@ -52,8 +50,8 @@ export const getStaticPaths = (() => {
|
||||
twitter={{ cardType: 'summary_large_image' }}
|
||||
/>
|
||||
|
||||
<BaseLayout>
|
||||
<HomeHero />
|
||||
<BaseLayout {locale}>
|
||||
<HomeHero {locale} />
|
||||
|
||||
<!-- <Flex justify="center" py="6" px="4" justify="center">
|
||||
<Flex
|
||||
@@ -72,7 +70,7 @@ export const getStaticPaths = (() => {
|
||||
</Flex> -->
|
||||
|
||||
{
|
||||
locale !== DEFAULT_LOCALE && (
|
||||
locale !== locales.default && (
|
||||
<Flex justify="center" mb="4">
|
||||
<Link
|
||||
href="https://crowdin.com/project/blitzkrieg"
|
||||
@@ -81,7 +79,9 @@ export const getStaticPaths = (() => {
|
||||
>
|
||||
{literals(strings.website.home.help_translate, [
|
||||
'BlitzKit',
|
||||
strings.common.locales[locale],
|
||||
strings.common.locales[
|
||||
locale as keyof typeof strings.common.locales
|
||||
],
|
||||
])}
|
||||
</Link>
|
||||
</Flex>
|
||||
@@ -100,35 +100,29 @@ export const getStaticPaths = (() => {
|
||||
|
||||
<Flex p="4" justify="center" gap="4" mt="3">
|
||||
<Flex maxWidth="80rem" flexGrow="1" gap="4" direction="column">
|
||||
<ToolCard tool={tankopediaTool} />
|
||||
|
||||
{
|
||||
(PUBLIC_ASSET_BRANCH === 'main' || MODE === 'development') && (
|
||||
<HomePageHotTanks {locale} />
|
||||
)
|
||||
}
|
||||
<ToolCard {locale} {strings} tool={tankopediaTool} />
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
{/* <ToolCard tool={playerStatsTool} /> */}
|
||||
<ToolCard tool={compareTool} />
|
||||
<ToolCard tool={performanceTool} />
|
||||
{/* <ToolCard {locale} {strings} tool={playerStatsTool} /> */}
|
||||
<ToolCard {locale} {strings} tool={compareTool} />
|
||||
<ToolCard {locale} {strings} tool={performanceTool} />
|
||||
</Flex>
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
<!-- <ToolCard tool={chartsTool} /> -->
|
||||
<!-- <ToolCard tool={guessTool} /> -->
|
||||
<ToolCard tool={galleryTool} />
|
||||
<ToolCard tool={sessionTool} />
|
||||
<!-- <ToolCard {locale} {strings} tool={chartsTool} /> -->
|
||||
<!-- <ToolCard {locale} {strings} tool={guessTool} /> -->
|
||||
<ToolCard {locale} {strings} tool={galleryTool} />
|
||||
<ToolCard {locale} {strings} tool={sessionTool} />
|
||||
</Flex>
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
<ToolCard tool={discordTool} />
|
||||
<ToolCard tool={tierListTool} />
|
||||
<ToolCard {locale} {strings} tool={discordTool} />
|
||||
<ToolCard {locale} {strings} tool={tierListTool} />
|
||||
</Flex>
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
<ToolCard tool={embedTool} />
|
||||
<ToolCard tool={moreTool} />
|
||||
<ToolCard {locale} {strings} tool={embedTool} />
|
||||
<ToolCard {locale} {strings} tool={moreTool} />
|
||||
</Flex>
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
@@ -141,6 +135,8 @@ export const getStaticPaths = (() => {
|
||||
|
||||
<Flex gap="4" mb="6" direction={{ initial: 'column', sm: 'row' }}>
|
||||
<ToolCard
|
||||
{locale}
|
||||
{strings}
|
||||
tool={{
|
||||
button: { color: 'blue' },
|
||||
id: 'blitz-analysis',
|
||||
@@ -149,6 +145,8 @@ export const getStaticPaths = (() => {
|
||||
}}
|
||||
/>
|
||||
<ToolCard
|
||||
{locale}
|
||||
{strings}
|
||||
tool={{
|
||||
button: { color: 'purple', highContrast: true },
|
||||
id: 'blitz-insider',
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { PageWrapper } from 'packages/website/src/components/PageWrapper';
|
||||
import { MetaSection } from 'packages/website/src/components/Tankopedia_ue/MetaSection';
|
||||
import {
|
||||
LocaleProvider,
|
||||
type LocaleAcceptorProps,
|
||||
} from 'packages/website/src/hooks/useLocale';
|
||||
import { App } from 'packages/website/src/stores/app';
|
||||
import { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue';
|
||||
|
||||
interface PageProps extends LocaleAcceptorProps {
|
||||
tankContext: TankopediaEphemeral_ue;
|
||||
}
|
||||
|
||||
export function Page({ localeContext, tankContext }: PageProps) {
|
||||
return (
|
||||
<LocaleProvider data={localeContext}>
|
||||
<App.Provider>
|
||||
<TankopediaEphemeral_ue.Provider data={tankContext}>
|
||||
<PageWrapper p="0" maxWidth="unset" color="purple" gap="9" pb="9">
|
||||
<MetaSection />
|
||||
</PageWrapper>
|
||||
</TankopediaEphemeral_ue.Provider>
|
||||
</App.Provider>
|
||||
</LocaleProvider>
|
||||
);
|
||||
}
|
||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user