Compare commits

..
34 Commits
Author SHA1 Message Date
TrèsAbhi 22f42117df feat: more hot garbage 2025-05-26 18:30:00 -05:00
TrèsAbhi 788edf5bdf feat: more hot garbage 2025-05-26 18:29:29 -05:00
TrèsAbhi d0170d53e4 feat: hot garbage 2025-05-26 14:23:00 -05:00
TrèsAbhi ae5e38139b feat: some set info in meta section 2025-05-25 18:49:00 -05:00
TrèsAbhi e38713f365 feat: meta section wallpapers 2025-05-25 18:08:00 -05:00
TrèsAbhi 5903b8130b feat: some of meta section 2025-05-25 18:03:55 -05:00
TrèsAbhi 179ce62a55 feat: strings 2025-05-25 15:18:22 -05:00
TrèsAbhi a2f1593a0e feat: add accessors 2025-05-24 18:41:03 -05:00
TrèsAbhi 6305db7ad6 feat: update to correct branch 2025-05-24 12:28:57 -05:00
TrèsAbhi 5082e1b82b feat: new protos 2025-05-24 12:24:53 -05:00
TrèsAbhi e7ca8f1b10 feat: remove UAssetAPI 2025-05-23 20:05:08 -05:00
tresabhi 0d8a677ac5 Merge branch 'main' into dev 2025-05-21 13:25:49 -05:00
tresabhi a8dc271e0a feat: update to imported base creators 2025-05-21 13:24:02 -05:00
TrèsAbhi f3d6ba68a7 New Crowdin updates (#154)
* New translations en.json (Ukrainian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Japanese)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Polish)

* New translations en.json (Ukrainian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Japanese)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Polish)

* New translations en.json (Russian)

* New translations en.json (Russian)

* New translations en.json (Ukrainian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Japanese)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Polish)

* New translations en.json (Polish)

* New translations en.json (Russian)

* New translations en.json (Ukrainian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Japanese)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Polish)

* New translations en.json (Japanese)

* New translations en.json (Japanese)

* New translations en.json (Chinese Simplified)
2025-05-20 09:04:31 -05:00
TrèsAbhi e68b27bac4 fix: don't return on bot 2025-05-19 17:39:02 -05:00
tresabhi d49eef7308 feat: update uasset 2025-05-19 12:47:49 -05:00
tresabhi 6e630a91aa Merge branch 'main' of https://github.com/tresabhi/blitzkit 2025-05-19 12:47:37 -05:00
tresabhi 2c66e79daf Merge branch 'preview' 2025-05-19 12:47:32 -05:00
TrèsAbhi 9a94a4e371 Update rating-na.yml 2025-05-18 19:00:33 -05:00
TrèsAbhi b1372c998d Update rating-eu.yml 2025-05-18 18:59:44 -05:00
TrèsAbhi 4ed93cb38f Update rating-asia.yml 2025-05-18 18:59:15 -05:00
TrèsAbhi 4d1b175c07 Update averages.yml 2025-05-18 18:58:37 -05:00
TrèsAbhi ecfedc32ad Update assets.yml 2025-05-18 18:58:01 -05:00
TrèsAbhi 9da514c329 Update assets.yml 2025-05-18 11:38:41 -05:00
tresabhi ee5386c925 fix: secrets 2025-05-18 09:58:38 -05:00
TrèsAbhi 76f7ae45ce Update index.astro 2025-04-04 21:27:42 -05:00
TresAbhi ad2aaa7bf8 feat: some sketchy code 2025-04-05 02:07:35 +00:00
TresAbhi 2a4375c718 Merge branch 'main' into preview 2025-04-04 20:26:22 +00:00
tresabhi 134566f1d8 feat: hide version... correctly 2025-01-10 12:06:20 -06:00
tresabhi d592a95cae feat: hide on preview 2025-01-10 11:56:00 -06:00
tresabhi 4f74556eb6 feat: hide version 2025-01-10 11:53:14 -06:00
tresabhi 1342f434a3 feat: desc 2025-01-10 11:14:43 -06:00
TrèsAbhi 6110471990 Update index.astro 2025-01-10 11:03:55 -06:00
TrèsAbhi 359eec5209 Update package.json 2025-01-10 10:46:57 -06:00
113 changed files with 2456 additions and 2287 deletions

No files matched your search

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