Compare commits

..
205 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
tresabhi 1a90e9312d feat: logs 2025-05-18 09:55:02 -05:00
tresabhi 2c7082fe04 feat: fast assets 2025-05-18 09:54:12 -05:00
tresabhi 518a83ee73 fix: bruh what 2025-05-16 23:03:56 -05:00
tresabhi 25c40bcea2 feat: logs 2025-05-16 22:33:31 -05:00
tresabhi f88ac8daf7 feat: more heuristic formats 2025-05-16 22:23:58 -05:00
tresabhi c4be6b78b6 feat: heuristics 2025-05-16 22:23:34 -05:00
tresabhi 2cfc65a990 feat: migrate tanks 2025-05-16 22:11:01 -05:00
tresabhi a8eb751048 feat: migrate tanks search page 2025-05-16 19:20:29 -05:00
tresabhi f030fd53b1 feat: slugs 2025-05-16 19:14:56 -05:00
tresabhi da506083c9 feat: migrate tier list 2025-05-16 18:15:27 -05:00
tresabhi 8bdc4d9b1b fix: sessio 2025-05-16 18:13:57 -05:00
tresabhi e0718d9ebb fix: migrate performance 2025-05-16 18:12:19 -05:00
tresabhi dbf1718d39 fix: migrate guess 2025-05-16 18:09:33 -05:00
tresabhi 84dd13c0ac feat: rename to path 2025-05-16 18:07:15 -05:00
tresabhi fdecef5f9c feat: migrate gallery 2025-05-16 18:06:04 -05:00
tresabhi 198e800958 feat: remove rybbit 2025-05-16 18:02:08 -05:00
tresabhi 29bb8ada06 feat: reduced navbar shadow 2025-05-16 18:01:10 -05:00
tresabhi 662f116afe fix: move guess components to src/components 2025-05-16 18:00:08 -05:00
tresabhi 02f0c078a5 fix: legacy redirect embed pages 2025-05-16 00:07:43 -05:00
tresabhi 4dd1113b6d feat: migrate embed and fix embed not rendering because of no context 2025-05-16 00:03:47 -05:00
tresabhi e656b83719 feat: migrate compare 2025-05-15 23:54:07 -05:00
tresabhi b90b355f8f feat: migrate urls 2025-05-15 23:44:20 -05:00
tresabhi 165a9cd719 feat: logs 2025-05-15 23:31:26 -05:00
tresabhi 5b8da36fb8 feat: effective and persistent angle 2025-05-15 23:21:01 -05:00
tresabhi bbe682fa73 feat: bigger icons 2025-05-15 23:03:10 -05:00
tresabhi af08df1526 feat: ricochet visualizer shell switcher 2025-05-15 23:02:15 -05:00
tresabhi 47a60adac7 feat: disable reload visualizer 2025-05-15 22:46:17 -05:00
tresabhi 10f3bc0026 fix: compare labels 2025-05-15 22:45:09 -05:00
tresabhi e7da1d582f fix: use pitch angle of transition of 15deg 2025-05-15 22:40:09 -05:00
tresabhi df70816f7e fix: use svh 2025-05-15 22:37:58 -05:00
tresabhi 091364d7f3 Merge branch 'main' into dev 2025-05-15 22:35:42 -05:00
tresabhi 753c06eee8 feat: logs 2025-05-07 20:54:24 -05:00
tresabhi 17713243b5 feat: final stuff 2025-05-07 20:51:52 -05:00
tresabhi 4e4f070368 feat: shinier 2025-05-07 19:43:40 -05:00
tresabhi 4064f163ec feat: remove plug 2025-05-07 19:42:49 -05:00
tresabhi b911f64847 feat: out animation 2025-05-07 19:41:47 -05:00
tresabhi b86b6e09d0 feat: font 2025-05-07 19:32:18 -05:00
tresabhi d2e7a477bb feat: fullscreen 2025-05-07 19:16:10 -05:00
tresabhi f9c182e68c feat: hide guess 2025-05-06 21:30:35 -05:00
tresabhi 7c497ab681 feat: more tintgs 2025-05-06 13:59:41 -05:00
tresabhi c840086c11 feat: tints 2025-05-06 13:56:56 -05:00
tresabhi 8649d09a94 feat: shadow 2025-05-06 13:39:07 -05:00
tresabhi c764564a96 feat: outline title 2025-05-06 13:29:40 -05:00
tresabhi ad8cbb96b7 feat: nerd time 2025-05-05 22:54:39 -05:00
tresabhi b409e26ca5 feat: reveal titles 2025-05-05 21:41:45 -05:00
tresabhi fbbfa5307c feat: skip 2025-05-05 21:22:05 -05:00
tresabhi 4165533838 feat: simplier hiding 2025-05-05 21:05:46 -05:00
tresabhi fb47ab3e64 feat: new auto rotate animation 2025-05-04 22:11:41 -05:00
tresabhi 57971453ad feat: stats 2025-05-04 21:45:38 -05:00
tresabhi c8cb490b48 feat: full logic 2025-05-04 21:39:09 -05:00
tresabhi 232f24181f feat: some guessing mechanics 2025-05-04 21:02:50 -05:00
tresabhi 46441d74d8 feat: some baswork 2025-05-04 13:08:28 -05:00
tresabhi a2274a6f0c idk man 2025-05-04 11:24:33 -05:00
tresabhi 0eb2827e7b Merge branch 'main' into dev 2025-05-02 21:28:54 -05:00
TrèsAbhi 41cb3f8511 Update Party3.astro 2025-05-02 09:32:22 -05:00
tresabhi 9405dccee9 feat: even more robust 2025-04-29 16:36:59 -05:00
tresabhi 83b0c6abc3 feat: persistent shells 2025-04-29 16:23:22 -05:00
tresabhi bf1621001b feat: more glow 2025-04-29 00:11:27 -05:00
tresabhi 8a5a4bf696 feat: glow and shells 2025-04-29 00:10:42 -05:00
tresabhi a99cce07dc feat: background 2025-04-28 17:43:29 -05:00
tresabhi d8c26ba24a feat: begennings of reload visuals 2025-04-28 17:21:42 -05:00
imgbot[bot]andImgBotApp f0b393c48f [ImgBot] Optimize images (#152)
*Total -- 1,028.23kb -> 900.50kb (12.42%)

/packages/website/public/assets/images/3d/grid.png -- 610.88kb -> 490.28kb (19.74%)
/packages/website/public/assets/images/icons/aim-caret.png -- 1.93kb -> 1.84kb (4.6%)
/packages/website/public/assets/images/icons/xp-multiplier.png -- 4.54kb -> 4.43kb (2.28%)
/packages/website/public/assets/images/third-party/wotb-news.png -- 404.33kb -> 397.41kb (1.71%)
/packages/website/public/assets/images/icons/custom-shell.png -- 6.55kb -> 6.54kb (0.18%)

Signed-off-by: ImgBotApp <[email protected]>
Co-authored-by: ImgBotApp <[email protected]>
2025-04-26 13:32:03 -05:00
TrèsAbhi d0d205bb93 New Crowdin updates (#150)
* New translations en.json (Ukrainian)

* New translations en.json (Ukrainian)

* 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 (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Chinese Simplified)

* New translations en.json (Russian)

* New translations en.json (Ukrainian)

* New translations en.json (Ukrainian)

* New translations en.json (Ukrainian)

* New translations en.json (Ukrainian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Japanese)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Russian)

* New translations en.json (French)
2025-04-26 13:31:52 -05:00
tresabhi aeaf52d3ac feat: darker view range 2025-04-24 22:06:28 -05:00
tresabhi e05358952a feat: stat search 2025-04-24 22:04:33 -05:00
tresabhi c1000e1608 feat: more responsive 2025-04-24 20:54:24 -05:00
tresabhi 46c86c5352 feat: more decimal places for dimensios 2025-04-24 20:37:31 -05:00
tresabhi 507b503560 feat: remove units and make ranks softer 2025-04-24 20:35:58 -05:00
tresabhi 37ca981d33 feat: more responsive 2025-04-24 20:24:12 -05:00
tresabhi efe6d2b1a5 feat: better navbar background 2025-04-24 20:07:17 -05:00
tresabhi 9f79f9c1e8 fix: no draggable images 2025-04-22 22:01:36 -05:00
tresabhi 38b4c62777 feat: new maps 2025-04-22 21:56:39 -05:00
tresabhi df1bc56a4c feat: isolate stat sections 2025-04-22 21:22:26 -05:00
tresabhi c3d2b063bc feat: new ricochet visualizer 2025-04-22 21:10:22 -05:00
tresabhi 1b94748668 feat: start of ricochet visual 2 2025-04-22 16:35:49 -05:00
tresabhi f4f804727f feat: slicker design 2025-04-22 14:42:04 -05:00
tresabhi 3729072594 feat: prettier 2025-04-22 14:36:31 -05:00
tresabhi c174f32e15 feat: view range visualizer 2025-04-22 14:35:34 -05:00
tresabhi 2443ecde2f feat: turretless support 2025-04-22 13:10:01 -05:00
tresabhi 9c027b3dde feat: puncture hole 2025-04-22 01:06:38 -05:00
tresabhi 22d794ac65 feat: animations 2025-04-22 00:50:14 -05:00
tresabhi 35073c184e test 2025-04-21 18:39:28 -05:00
tresabhi 4741406e4a fix: include prisma only in bot 2025-04-21 18:30:35 -05:00
tresabhi 24107433c6 fix: use built prisma 2025-04-21 18:24:19 -05:00
tresabhi 05c6fcfb34 fix: inline 2025-04-21 18:21:12 -05:00
tresabhi be7a16d399 feat: lower contrast 2025-04-21 18:19:05 -05:00
tresabhi c7f781dbb2 feat: ricochet visualizer 2025-04-21 18:09:57 -05:00
tresabhi a66c6ebb27 feat: classic styled components 2025-04-21 17:01:32 -05:00
tresabhi 83aeca2e5e Merge branch 'main' into dev 2025-04-21 16:39:49 -05:00
tresabhi 89a3db05d8 Merge branch 'main' of https://github.com/tresabhi/blitzkit 2025-04-21 16:39:08 -05:00
tresabhi 6050145b16 fix: home page hot tanks 2025-04-21 16:39:06 -05:00
tresabhi 77c78741b3 fix: remove unused type 2025-04-21 16:37:29 -05:00
TrèsAbhi f35670d6a8 Update Party3.astro 2025-04-21 14:36:24 -05:00
tresabhi 3392a57480 feat: rotation visualize 2025-04-20 23:00:08 -05:00
tresabhi ed64ee8228 feat: hull traverse visualizer 2025-04-20 22:51:53 -05:00
tresabhi 4f47d6ce85 Merge branch 'main' into dev 2025-04-20 21:35:06 -05:00
tresabhi 92d56ac086 fix: onPointerDown 2025-04-20 21:34:57 -05:00
tresabhi 671b8b60b9 feat: update prisma with custom output 2025-04-20 21:31:15 -05:00
tresabhi ba5a5245d9 feat: update prisma 2025-04-20 21:27:00 -05:00
tresabhi eee262add7 fix: submodules 2025-04-20 21:18:54 -05:00
tresabhi e5eaf3fd75 fix: submodules 2025-04-20 21:18:02 -05:00
tresabhi 5fdc9044ca fix: hero interactibility 2025-04-20 21:16:50 -05:00
tresabhi 0924a77776 fix: mas width for meta section 2025-04-20 21:13:40 -05:00
tresabhi 1a46e176f5 fix: tankopedia title 2025-04-20 21:11:16 -05:00
tresabhi efb8df9769 feat: logs 2025-04-20 21:00:57 -05:00
tresabhi 04e09b84ff feat: skeleton and proper file extensions 2025-04-20 20:49:54 -05:00
tresabhi b52c107af9 feat: parrelel api 2025-04-19 00:48:29 -05:00
tresabhi c5e6f5e2eb feat: glossary cron 2025-04-19 00:47:28 -05:00
tresabhi 365c68aa4d feat: move popular tanks to cron job 2025-04-18 23:57:04 -05:00
tresabhi ff9ec55da6 feat: increase title gap 2025-04-17 13:06:40 -05:00
tresabhi 2a2994ae69 feat: more responsive 2025-04-17 13:00:53 -05:00
tresabhi e3c6497d29 feat: better meta 2025-04-17 00:23:01 -05:00
tresabhi bdc013b4c8 fix: cleaner clear button 2025-04-16 23:34:30 -05:00
tresabhi e20d65d218 feat: darker 2025-04-16 23:22:12 -05:00
tresabhi 8b726c12d9 fix: invalidate frams on reveal 2025-04-16 23:20:44 -05:00
tresabhi da704e6181 feat: transition skeleton 2025-04-16 23:18:24 -05:00
tresabhi 64d346ccb6 feat: in-hero controls 2025-04-15 16:54:36 -05:00
tresabhi c090ad6492 feat: disturb on tab change and no title select 2025-04-15 16:37:10 -05:00
tresabhi 8b6610151e fix: keys 2025-04-15 16:29:14 -05:00
tresabhi 545b655d4e feat: slicker loading 2025-04-15 00:35:12 -05:00
tresabhi 0e6aa734cb feat: advanced jsxTree 2025-04-15 00:11:49 -05:00
tresabhi 2bef96475c feat: quick controls 2025-04-14 23:56:29 -05:00
tresabhi 45938c875f feat: skeleton search 2025-04-14 23:28:35 -05:00
tresabhi 9d916a588d feat: cooler header 2025-04-14 19:26:41 -05:00
tresabhi f0295079cc feat: quiz input angles animaiton 2025-04-14 18:56:02 -05:00
tresabhi 6d8387fa9d feat: foggy transition 2025-04-14 18:52:49 -05:00
tresabhi 7a18de6650 fix: don't reset camera on tab change 2025-04-14 17:30:51 -05:00
tresabhi cc6c4faa2d feat: migration 2025-04-06 22:57:35 -05:00
TrèsAbhi 4253cd3e1b fix: allow 2025-04-06 22:04:01 -05:00
TrèsAbhi 75cf827082 Update website.yml 2025-04-06 19:59:27 -05:00
TrèsAbhi 73c8807f14 no, no, no, NOW all hail pyogenics i messed up the last time 2025-04-06 16:03:04 -05:00
TrèsAbhi 9fac6dd40d all hail pyogenics 2025-04-06 15:53:23 -05:00
TrèsAbhi c06c338536 fix: add env and remove compressors 2025-04-06 10:48:08 -05:00
TrèsAbhi 9258623931 Update astro.config.mjs 2025-04-06 00:12:01 -05:00
tresabhi 3b02c25973 fix: disable playformCompress 2025-04-05 22:02:26 -05:00
tresabhi f90768d155 fix: env 2025-04-05 17:08:55 -05:00
tresabhi d77bd6a5f9 feat: logs 2025-04-05 16:15:55 -05:00
tresabhi 6836cb327f feat: more images 2025-04-05 16:07:42 -05:00
tresabhi 4373efd0cd feat: move images to blitzkit 2025-04-05 16:00:52 -05:00
tresabhi f13165e77d feat: better ui 2025-04-05 15:09:15 -05:00
tresabhi 8a5b0c1170 fix: gun-specific shell discrimination 2025-04-05 15:09:12 -05:00
tresabhi f16511a72e Merge branch 'main' into dev 2025-04-05 14:57:41 -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 df0dc4f118 feat: shell filters 2025-04-03 16:33:48 -05:00
tresabhi 92399de5e2 fix: navbar interact 2025-04-03 13:00:23 -05:00
tresabhi 8d9dff8d73 feat: inline 2025-04-03 12:53:54 -05:00
tresabhi f91744f2f0 feat: compressor again 2025-04-03 12:51:24 -05:00
tresabhi e946dfdb69 feat: compressor 2025-04-03 12:48:17 -05:00
tresabhi 6283ddc57a feat: astro seo 2025-04-03 12:45:33 -05:00
tresabhi 2d66e0ab28 fix: missing padding backgrond 2025-04-03 12:34:02 -05:00
tresabhi c3d8f15a2a feat: better robots.txt 2025-04-03 12:23:53 -05:00
tresabhi 21a37ec6cc feat: new nav bar 2025-04-03 12:15:08 -05:00
tresabhi de471400ad feat: partytown 2025-04-03 11:34:57 -05:00
tresabhi 0b16295853 fix: keys 2025-04-03 11:31:31 -05:00
TrèsAbhi 63eea81856 Update stitches.config.ts 2025-04-02 21:55:08 -05:00
tresabhi ba57d61af5 feat: skeleton 2025-04-02 17:59:23 -05:00
tresabhi 3d940f4b47 feat: discord plug 2025-04-02 17:48:51 -05:00
tresabhi 8ef355c574 feat: we don't talk about it 2025-04-02 16:11:09 -05:00
tresabhi 71e1ab1362 aaaaaaaaaaaaaaaa 2025-04-01 19:38:58 -05:00
tresabhi 53dc108356 Merge branch 'main' of https://github.com/tresabhi/blitzkit 2025-04-01 19:38:01 -05:00
tresabhi 57b3218c5a undo cue4 2025-04-01 19:38:00 -05:00
tresabhi 7472e39faf fix: gifs 2025-04-01 19:34:03 -05:00
tresabhi 034417d19f fix: remove cue4 2025-03-31 17:49:23 -05:00
tresabhi 0368e9ceda feat: pink bot 2025-03-31 17:44:08 -05:00
tresabhi 28f365f762 fix: no class list 2025-03-31 17:39:42 -05:00
tresabhi 40a81f6b1b fix: class list 2025-03-31 17:39:01 -05:00
tresabhi 9475d22472 feat: uh hahaha you'll see ... again! 2025-03-31 17:36:40 -05:00
tresabhi 9538a03afb feat: uh hahaha you'll see 2025-03-31 16:54:32 -05:00
tresabhi d5d171bea6 4 2025-03-30 14:37:40 -05:00
tresabhi a9c9a90ac1 fix: disable /auction 2025-03-30 12:53:14 -05:00
tresabhi f7c562f8b6 fix: detect invalid 0-length translations 2025-03-30 12:51:34 -05:00
TrèsAbhi 836cf69f01 New Crowdin updates (#149)
* New translations en.json (Russian)

* New translations en.json (Ukrainian)

* New translations en.json (Spanish)

* New translations en.json (Chinese Simplified)
2025-03-26 14:37:29 -05: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
345 changed files with 9193 additions and 4296 deletions

No files matched your search

+4 -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 }}
@@ -50,6 +50,9 @@ env:
PATREON_CLIENT_SECRET: ${{ secrets.PATREON_CLIENT_SECRET }} PATREON_CLIENT_SECRET: ${{ secrets.PATREON_CLIENT_SECRET }}
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_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
+4 -1
View File
@@ -21,13 +21,16 @@ 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 }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
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_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
jobs: jobs:
build: build:
+3 -3
View File
@@ -22,9 +22,9 @@ 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
/src /src
/packages/bot/src/prisma
+3
View File
@@ -1,3 +1,6 @@
[submodule "submodules/blitzkit-closed"] [submodule "submodules/blitzkit-closed"]
path = submodules/blitzkit-closed path = submodules/blitzkit-closed
url = https://github.com/tresabhi/blitzkit-closed url = https://github.com/tresabhi/blitzkit-closed
[submodule "submodules/CUE4Parse"]
path = submodules/CUE4Parse
url = https://github.com/FabianFG/CUE4Parse
+14
View File
@@ -14,6 +14,7 @@
"applypatches", "applypatches",
"artefacts", "artefacts",
"astrojs", "astrojs",
"astrolib",
"atgm", "atgm",
"Autoloader", "Autoloader",
"Autoreloader", "Autoreloader",
@@ -32,9 +33,11 @@
"blitzkit", "blitzkit",
"blitzrinth", "blitzrinth",
"blitzstars", "blitzstars",
"bufbuild",
"cacheable", "cacheable",
"Callouts", "Callouts",
"Camo", "Camo",
"Carro",
"CCPAOPTOUT", "CCPAOPTOUT",
"CDON", "CDON",
"classname", "classname",
@@ -42,6 +45,7 @@
"closedkrieg", "closedkrieg",
"cockroackdb", "cockroackdb",
"Coef", "Coef",
"Combattimento",
"cooldown", "cooldown",
"corelations", "corelations",
"corsproxy", "corsproxy",
@@ -53,6 +57,7 @@
"dbid", "dbid",
"Ddpf", "Ddpf",
"Ddsd", "Ddsd",
"deadrail",
"debugflags", "debugflags",
"deburr", "deburr",
"decalmask", "decalmask",
@@ -71,6 +76,7 @@
"dxgi", "dxgi",
"echarts", "echarts",
"Everytime", "Everytime",
"FABLEGEAR",
"FASTNAME", "FASTNAME",
"flexdirection", "flexdirection",
"FOURCC", "FOURCC",
@@ -104,6 +110,7 @@
"Maddoxkkm", "Maddoxkkm",
"malum", "malum",
"mantlets", "mantlets",
"MECHA",
"metallicness", "metallicness",
"metalness", "metalness",
"minitelrose", "minitelrose",
@@ -130,17 +137,22 @@
"outdir", "outdir",
"outfile", "outfile",
"ownedtanks", "ownedtanks",
"padder",
"partytown",
"PIXELFORMAT", "PIXELFORMAT",
"playerachievements", "playerachievements",
"playerinfo", "playerinfo",
"playform",
"pngjs", "pngjs",
"POSITIVEX", "POSITIVEX",
"POSITIVEY", "POSITIVEY",
"POSITIVEZ", "POSITIVEZ",
"precompute", "precompute",
"PROGRESSTON",
"Promisable", "Promisable",
"proto", "proto",
"protobuf", "protobuf",
"protoc",
"protos", "protos",
"Pyogenics", "Pyogenics",
"ratingleaderboard", "ratingleaderboard",
@@ -181,6 +193,7 @@
"TEXCOORD", "TEXCOORD",
"tresabhi", "tresabhi",
"tungstentip", "tungstentip",
"Turretless",
"TYPELESS", "TYPELESS",
"ubjson", "ubjson",
"Unicum", "Unicum",
@@ -195,6 +208,7 @@
"vitepress", "vitepress",
"Vovko", "Vovko",
"wargaming", "wargaming",
"WARHAMMER",
"webp", "webp",
"whitespaces", "whitespaces",
"WHSS", "WHSS",
BIN
View File
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
# BlitzKit 1.27.10
This update changes the URLs across the whole website, removing the "tools" prefix and simplifying other aspects too.
## Changes
- Removed "full" tank names
- For example, tanks like the "Carro 45t" had full names like "Carro Combattimento 45t" which remained pretty much unused, so they have been removed
- Reduced the shadow below the navigation bar
- Removed the "tools" prefix from the URLs; here are the paths:
- `/tools/tankopedia` -> `/tanks`
- `/tools/tankopedia/12345` -> `/tanks/tank-name`
- `/tools/compare` -> `/compare`
- `/tools/embed` -> `/embed`
- `/tools/embed/embed-name` -> `/embed/embed-name`
- `/tools/gallery` -> `/gallery`
- `/tools/performance` -> `/performance`
- `/tools/session` -> `/session`
- `/tools/tier-list` -> `/tier-list`
## Technical Features
- The asset mangler now uses http headers and even more heuristics to minimize re-creating unchanged assets
+7
View File
@@ -0,0 +1,7 @@
# BlitzKit 1.27.11
This update affects both the bot and the website.
## Technical Changes
- Added a proper CDN domain to avoid error 429s and any slowdowns
+3
View File
@@ -0,0 +1,3 @@
# FreakKit 1.27.4
It has come to our attention that tanks are very harsh objects. To even it out, we made the website a pretty pretty princess <3
+11
View File
@@ -0,0 +1,11 @@
# BlitzKit 1.27.5
This update only affects the bot.
## Changes
- Removed `/auction`
## Fixes
- Fixed a bug that caused `/rating` to disappear
+23
View File
@@ -0,0 +1,23 @@
# BlitzKit 1.27.6
This update only affects the website.
## Features
- Added a promotional card for [the official Discord server](https://discord.gg/nDt7AjGJQH) to the homepage
- Added a better navbar
- The added spaces and padding helps add more room for error when clicking, especially on mobile
- The dropdown menu is now a lost smaller, disposing of the need to scroll at all
- Added shell filters to the tank search
- Reworked the filter buttons and their positions to allow for more space
## Fixes
- Moved most images from imgur to BlitzKit allowing for users in certain countries to load BlitzKit without getting blocked
## Technical Features
- Added Partytown to offload some workload off the main thread, allowing for a more responsive experience
- Reworked `robots.txt` to disallow indexing of BlitzKit variants
- Improved the SEO further for most pages
- Added a few compressor library to speed up load times
+25
View File
@@ -0,0 +1,25 @@
# BlitzKit 1.27.7
![](https://i.imgur.com/qFepOaT.png)
This update only affects the website.
## Features
- Added a new foggy-wireframe transition between tabs to smooth out the jarring jumps
- Added animations pop-in and out animations on a few elements
- The tank name title now shrinks in size as soon as a disturbance is caused
- The shell selector, antagonist switcher, and thicknesses range now ease into frame
- The Tankopedia search page now loads as a skeleton by default before populating with tanks, allowing for the recently viewed tanks to load without cumulative shift
- Something similar was done to the Gallery tool
- Gave the meta section of the website some zest with nation-based backdrops
- The compare tabs in the Tankopedia are now centered
## Fixes
- The camera no longer snaps to the initial position when switching between tabs
## Technical Changes
- Backported some technologies from BlitzKit Reforged; you will not notice any differences in usage
- The popular tanks and gallery indexings have been moved to the asynchronous cron job
+12
View File
@@ -0,0 +1,12 @@
# BlitzKit 1.27.8
![](https://i.imgur.com/WO5MS94.png)
## Features
- The website now uses Inter as the font
- Added a cool new non-disturbed state for the Tankopedia because why not
## Changes
- Removed the Discord plug and language changer from the homepage
+27
View File
@@ -0,0 +1,27 @@
# BlitzKit 1.27.9
BlitzKit's great, but there's far too many numbers. This update adds a few visualizers to help new players understand how things relate numerically.
![](https://i.imgur.com/OV5ak4T.png)
## Features
- Added the turret and hull traverse speed visualizer
- Added the shell ricochet and normalization angles visualizer
- Added the view-range visualizer
- Added a search bar to the Tankopedia characteristics
- Bumped the decimal places for vehicle dimensions and volume
- Made tank ranks softer (the bars beneath the tank characteristics)
- Gave the navigation bar better distinction from the rest of the page
- Increased the number of characteristics rows to 3 on select devices
- Switched to a more contrasting classic style of components across the website (it's subtle, but beautiful)
## Changes
- Removed units
## Fixes
- Clarified a few confusing row labels in the Compare tool
- Made the Tankopedia hero section dynamically smaller on mobile phones to allow scrolling
- Tank ranks no longer reach 0 or go above the number of vehicles in the comparison
+21 -9
View File
@@ -1,12 +1,13 @@
{ {
"name": "blitzkit", "name": "@blitzkit",
"private": true, "private": true,
"version": "1.27.3", "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",
@@ -40,15 +41,26 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"sharp": "^0.33.5", "googleapis": "^144.0.0",
"lodash-es": "^4.17.21" "js-yaml": "^4.1.0",
"lodash-es": "^4.17.21",
"protobufjs": "^7.5.2",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"quicklime": "^1.2.0",
"sharp": "^0.33.5"
}, },
"devDependencies": { "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/node": "^22.5.4", "@types/react": "^19.1.5",
"prettier": "^3.3.3", "@types/react-dom": "^19.1.5",
"prisma": "^6.0.0", "@types/node": "^22.14.1",
"typescript": "^5.5.4" "astro": "^5.8.0",
"prettier": "^3.5.3",
"prisma": "^6.6.0",
"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",
+2 -2
View File
@@ -107,8 +107,8 @@ export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
if (!tank) return ''; if (!tank) return '';
const name = `[${tank.name}](<https://blitzkit.app/tools/tankopedia/${ const name = `[${tank.name}](<https://blitzkit.app/tanks/${
tank.id tank.slug
}>)`; }>)`;
const next = const next =
data.next_price === null data.next_price === null
+2 -5
View File
@@ -1,11 +1,8 @@
import { import { getAccountInfo, getClanAccountInfo } from '@blitzkit/core';
getAccountInfo,
getClanAccountInfo,
linkBlitzAndDiscord,
} from '@blitzkit/core';
import { teal } from '@radix-ui/colors'; import { teal } from '@radix-ui/colors';
import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow'; import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow';
import { CommandWrapper } from '../components/CommandWrapper'; import { CommandWrapper } from '../components/CommandWrapper';
import { linkBlitzAndDiscord } from '../core/db/linkBlitzAndDiscord';
import { addUsernameChoices } from '../core/discord/addUsernameChoices'; import { addUsernameChoices } from '../core/discord/addUsernameChoices';
import { autocompleteUsername } from '../core/discord/autocompleteUsername'; import { autocompleteUsername } from '../core/discord/autocompleteUsername';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand'; import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
+1 -1
View File
@@ -78,7 +78,7 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
) )
.map( .map(
(tank) => (tank) =>
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name))}](<https://blitzkit.app/tools/tankopedia/${tank.id}>)`, `[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name))}](<https://blitzkit.app/tanks/${tank.slug}>)`,
); );
const lines = [title, ...tankList]; const lines = [title, ...tankList];
@@ -16,8 +16,8 @@ export function CommandWrapper({ children, fat }: CommandWrapperProps) {
gap: 16, gap: 16,
width: '100%', width: '100%',
color: theme.colors.textHighContrast, color: theme.colors.textHighContrast,
backgroundColor: theme.colors.appBackground1,
position: 'relative', position: 'relative',
background: theme.colors.appBackground1,
}} }}
> >
{children} {children}
@@ -1,5 +1,6 @@
import { idToRegion, usersDatabase } from '@blitzkit/core'; import { idToRegion } from '@blitzkit/core';
import { flagUserActivity } from '@blitzkit/core/src/blitzkit/flagUserActivity'; import { flagUserActivity } from '../db/flagUserActivity';
import { usersDatabase } from '../db/users';
export async function getBlitzFromDiscord(discordId: bigint) { export async function getBlitzFromDiscord(discordId: bigint) {
const unique = await usersDatabase.discordUser.findUnique({ const unique = await usersDatabase.discordUser.findUnique({
+1 -1
View File
@@ -1,4 +1,4 @@
import { usersDatabase } from '@blitzkit/core'; import { usersDatabase } from '../db/users';
import { client } from '../discord/client'; import { client } from '../discord/client';
const EXIT_EVENTS = [ const EXIT_EVENTS = [
@@ -1,4 +1,4 @@
import { usersDatabase } from '@blitzkit/core'; import { usersDatabase } from './users';
export async function flagUserActivity(blitzId: number) { export async function flagUserActivity(blitzId: number) {
await usersDatabase.user.upsert({ await usersDatabase.user.upsert({
@@ -1,5 +1,5 @@
import { usersDatabase } from '@blitzkit/core';
import { flagUserActivity } from './flagUserActivity'; import { flagUserActivity } from './flagUserActivity';
import { usersDatabase } from './users';
export async function linkBlitzAndDiscord(discordId: bigint, blitzId: number) { export async function linkBlitzAndDiscord(discordId: bigint, blitzId: number) {
await usersDatabase.discordUser.upsert({ await usersDatabase.discordUser.upsert({
@@ -1,3 +1,3 @@
import { PrismaClient } from '@prisma/client'; import { PrismaClient } from '../../prisma';
export const usersDatabase = new PrismaClient(); export const usersDatabase = new PrismaClient();
@@ -15,7 +15,8 @@ export function localizationObject(
(localizations, locale) => { (localizations, locale) => {
const { strings } = translator(locale); const { strings } = translator(locale);
const translation = literalsFunc(path(strings), literals); const translation = literalsFunc(path(strings), literals);
const isValid = !strict || validNameRegex.test(translation); const isValid =
(!strict || validNameRegex.test(translation)) && translation.length > 0;
if (!isValid) { if (!isValid) {
console.warn( console.warn(
@@ -19,11 +19,11 @@ import { Writeable } from '../../../types/writable';
export async function handleChatInputCommand( export async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>, interaction: ChatInputCommandInteraction<CacheType>,
) { ) {
await interaction.deferReply();
const awaitedCommands = await commands; const awaitedCommands = await commands;
const registry = awaitedCommands[interaction.commandName]; const registry = awaitedCommands[interaction.commandName];
await interaction.deferReply();
try { try {
const returnable = await registry.handler(interaction); const returnable = await registry.handler(interaction);
@@ -15,7 +15,6 @@ import {
SlashCommandSubcommandsOnlyBuilder, SlashCommandSubcommandsOnlyBuilder,
} from 'discord.js'; } from 'discord.js';
import { aboutCommand } from '../../commands/about'; import { aboutCommand } from '../../commands/about';
import { auctionCommand } from '../../commands/auction';
import { breakdownCommand } from '../../commands/breakdown'; import { breakdownCommand } from '../../commands/breakdown';
import { debugCommand } from '../../commands/debug'; import { debugCommand } from '../../commands/debug';
import { evolutionCommand } from '../../commands/evolution'; import { evolutionCommand } from '../../commands/evolution';
@@ -80,7 +79,7 @@ interface CommandRegistryExplicit extends CommandRegistryBase {
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit; export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [ export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
auctionCommand, // auctionCommand,
permissionsCommand, permissionsCommand,
debugCommand, debugCommand,
aboutCommand, aboutCommand,
+8 -1
View File
@@ -45,7 +45,7 @@ const interval = setInterval(async () => {
const usernames = awaitedDiscoveredIdsDefinitions.count; const usernames = awaitedDiscoveredIdsDefinitions.count;
manager.broadcastEval( manager.broadcastEval(
(client, { servers, users, channels, tanks, usernames }) => { async (client, { servers, users, channels, tanks, usernames }) => {
const bios = [ const bios = [
`Living in ${servers.toLocaleString()} servers`, `Living in ${servers.toLocaleString()} servers`,
`Serving ${users.toLocaleString()} users`, `Serving ${users.toLocaleString()} users`,
@@ -62,6 +62,13 @@ const interval = setInterval(async () => {
}, },
], ],
}); });
for (const guild of client.guilds.cache.values()) {
try {
const botMember = await guild.members.fetch(client.user.id);
await botMember.setNickname('BlitzKit');
} catch {}
}
}, },
{ context: { servers, channels, users, tanks, usernames } }, { context: { servers, channels, users, tanks, usernames } },
); );
+1 -1
View File
@@ -23,7 +23,7 @@ export const theme = {
spaces: createSpaces(), spaces: createSpaces(),
colors: { colors: {
...createColors(slateDark), ...createColors(mauveDark),
...createColors(slateDarkA, 'alpha'), ...createColors(slateDarkA, 'alpha'),
...createColors(slate, 'light'), ...createColors(slate, 'light'),
+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": "../../"
}
} }
+2 -1
View File
@@ -4,9 +4,10 @@
"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": "^5.19.1", "@prisma/client": "^6.6.0",
"adm-zip": "^0.5.16", "adm-zip": "^0.5.16",
"crc": "^4.3.2", "crc": "^4.3.2",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
@@ -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('.');
}
@@ -1,4 +1,5 @@
import { assertSecret, type BlitzGlossary } from '@blitzkit/core'; import { assertSecret } from '../blitzkit';
import { BlitzGlossary } from '../types';
export async function fetchGlossary(locale: string) { export async function fetchGlossary(locale: string) {
const response = await fetch( const response = await fetch(
+4
View File
@@ -1,9 +1,12 @@
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 './generateStats'; export * from './generateStats';
export * from './getAccountAchievements'; export * from './getAccountAchievements';
export * from './getAccountInfo'; export * from './getAccountInfo';
@@ -17,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);
}
}
+8 -3
View File
@@ -1,7 +1,12 @@
import { assertSecret } from './assertSecret'; import { assertSecret } from './assertSecret';
const repo = assertSecret(import.meta.env.PUBLIC_ASSET_REPO);
const branch = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
const fastUser = assertSecret(import.meta.env.PUBLIC_ASSET_FAST_USER);
const fastRepo = assertSecret(import.meta.env.PUBLIC_ASSET_FAST_REPO);
export function asset(path: string) { export function asset(path: string) {
return `https://raw.githubusercontent.com/${assertSecret( return branch === 'main'
import.meta.env.PUBLIC_ASSET_REPO, ? `https://${fastUser}.github.io/${fastRepo}/${path}`
)}/${assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH)}/${path}`; : `https://raw.githubusercontent.com/${repo}/${branch}/${path}`;
} }
+7
View File
@@ -0,0 +1,7 @@
import { fetchPB } from '../protobuf';
import { Gallery } from '../protos';
import { asset } from './asset';
export function fetchGallery() {
return fetchPB(asset('definitions/gallery.pb'), Gallery);
}
+3 -2
View File
@@ -13,7 +13,6 @@ export * from './discoveredIdDefinitions';
export * from './emblemURL'; export * from './emblemURL';
export * from './equipmentDefinitions'; export * from './equipmentDefinitions';
export * from './eventManager'; export * from './eventManager';
// export * from './flagUserActivity';
export * from './gameDefinitions'; export * from './gameDefinitions';
export * from './getArchivedLatestSeasonNumber'; export * from './getArchivedLatestSeasonNumber';
// export * from './getArchivedRatingInfo'; // export * from './getArchivedRatingInfo';
@@ -21,7 +20,6 @@ export * from './getArchivedRatingLeaderboard';
// export * from './getArchivedRatingMidnightLeaderboard'; // export * from './getArchivedRatingMidnightLeaderboard';
export * from './getTimeDaysAgo'; export * from './getTimeDaysAgo';
export * from './isExplosive'; export * from './isExplosive';
export * from './linkBlitzAndDiscord';
export * from './mapDefinitions'; export * from './mapDefinitions';
export * from './modelDefinitions'; export * from './modelDefinitions';
export * from './normalizeBoundingBox'; export * from './normalizeBoundingBox';
@@ -44,6 +42,9 @@ export * from './unwrapBlitzkitResponse';
export * from './votes'; export * from './votes';
// export * from './withCORSProxy'; // export * from './withCORSProxy';
export * from './createDefaultProvisions'; export * from './createDefaultProvisions';
export * from './gallery';
export * from './metaSortTank'; export * from './metaSortTank';
export * from './popularTanks';
export * from './romanize'; export * from './romanize';
export * from './slugify';
export * from './youtubers'; export * from './youtubers';
@@ -0,0 +1,7 @@
import { fetchPB } from '../protobuf';
import { PopularTanks } from '../protos';
import { asset } from './asset';
export function fetchPopularTanks() {
return fetchPB(asset('definitions/popular-tanks.pb'), PopularTanks);
}
+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;
}
+15 -9
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';
@@ -15,18 +15,22 @@ export async function fetchTankNames() {
tankDefinitionsArray.map(async (tank) => { tankDefinitionsArray.map(async (tank) => {
const searchableNameDeburr: I18nString = { locales: {} }; const searchableNameDeburr: I18nString = { locales: {} };
Object.entries(tank.name_full ?? tank.name).forEach(([key, value]) => { Object.entries(tank.name).forEach(([key, value]) => {
searchableNameDeburr.locales[key] = deburr(value); searchableNameDeburr.locales[key] = deburr(value);
}); });
return { return {
id: tank.id, id: tank.id,
name: tank.name, name: tank.name,
nameFull: tank.name_full, searchableName: tank.name,
searchableName: tank.name_full ?? tank.name,
searchableNameDeburr, searchableNameDeburr,
camouflages: tank.camouflages camouflages: tank.camouflages
?.map((id) => SUPPORTED_LOCALES.map((locale) => camouflageDefinitions.camouflages[id]?.name.locales[locale])) ?.map((id) =>
locales.supported.map(
({ locale }) =>
camouflageDefinitions.camouflages[id]?.name.locales[locale],
),
)
.flat() .flat()
.filter(Boolean) .filter(Boolean)
.map(deburr) .map(deburr)
@@ -38,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',
]; ];
-1
View File
@@ -1 +0,0 @@
export * from './users';
-1
View File
@@ -1,6 +1,5 @@
export * from './blitz'; export * from './blitz';
export * from './blitzkit'; export * from './blitzkit';
export * from './databases';
export * from './imgur'; export * from './imgur';
export * from './math'; export * from './math';
export * from './patreon'; export * from './patreon';
@@ -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 };
} }
+15
View File
@@ -0,0 +1,15 @@
syntax = "proto2";
package blitzkit;
import "i18n.proto";
message Gallery {
repeated Avatar avatars = 1;
}
message Avatar {
required string id = 1;
required I18nString name = 2;
required string extension = 3;
}
+209
View File
@@ -0,0 +1,209 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: gallery.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
export interface Gallery {
avatars: Avatar[];
}
export interface Avatar {
id: string;
name: I18nString;
extension: string;
}
export function createBaseGallery(): Gallery {
return { avatars: [] };
}
export const Gallery: MessageFns<Gallery> = {
encode(message: Gallery, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.avatars) {
Avatar.encode(v!, writer.uint32(10).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGallery();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.avatars.push(Avatar.decode(reader, reader.uint32()));
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): Gallery {
return {
avatars: globalThis.Array.isArray(object?.avatars) ? object.avatars.map((e: any) => Avatar.fromJSON(e)) : [],
};
},
toJSON(message: Gallery): unknown {
const obj: any = {};
if (message.avatars?.length) {
obj.avatars = message.avatars.map((e) => Avatar.toJSON(e));
}
return obj;
},
create<I extends Exact<DeepPartial<Gallery>, I>>(base?: I): Gallery {
return Gallery.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<Gallery>, I>>(object: I): Gallery {
const message = createBaseGallery();
message.avatars = object.avatars?.map((e) => Avatar.fromPartial(e)) || [];
return message;
},
};
export function createBaseAvatar(): Avatar {
return { id: "", name: createBaseI18nString(), extension: "" };
}
export const Avatar: MessageFns<Avatar> = {
encode(message: Avatar, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.id !== "") {
writer.uint32(10).string(message.id);
}
if (message.name !== undefined) {
I18nString.encode(message.name, writer.uint32(18).fork()).join();
}
if (message.extension !== "") {
writer.uint32(26).string(message.extension);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAvatar();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.id = reader.string();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.name = I18nString.decode(reader, reader.uint32());
continue;
}
case 3: {
if (tag !== 26) {
break;
}
message.extension = reader.string();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): Avatar {
return {
id: globalThis.String(assertSet("Avatar.id", object.id)),
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
};
},
toJSON(message: Avatar): unknown {
const obj: any = {};
if (message.id !== "") {
obj.id = message.id;
}
if (message.name !== undefined) {
obj.name = I18nString.toJSON(message.name);
}
if (message.extension !== "") {
obj.extension = message.extension;
}
return obj;
},
create<I extends Exact<DeepPartial<Avatar>, I>>(base?: I): Avatar {
return Avatar.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<Avatar>, I>>(object: I): Avatar {
const message = createBaseAvatar();
message.id = object.id ?? "";
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
message.extension = object.extension ?? "";
return message;
},
};
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
fromJSON(object: any): T;
toJSON(message: T): unknown;
create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
}
@@ -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
View File
@@ -3,10 +3,12 @@ export * from './average_definitions.ts';
export * from './camouflage_definitions.ts'; export * from './camouflage_definitions.ts';
export * from './consumable_definitions.ts'; export * from './consumable_definitions.ts';
export * from './equipment_definitions.ts'; export * from './equipment_definitions.ts';
export * from './gallery.ts';
export * from './game_definitions.ts'; export * from './game_definitions.ts';
export * from './i18n.ts'; export * from './i18n.ts';
export * from './map_definitions.ts'; export * from './map_definitions.ts';
export * from './model_definitions.ts'; export * from './model_definitions.ts';
export * from './popular_tanks.ts';
export * from './provision_definitions.ts'; export * from './provision_definitions.ts';
export * from './rating_leaderboard.ts'; export * from './rating_leaderboard.ts';
export * from './reviews.ts'; export * from './reviews.ts';
@@ -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 };
} }
@@ -0,0 +1,12 @@
syntax = "proto2";
package blitzkit;
message PopularTanks {
repeated PopularTank tanks = 1;
}
message PopularTank {
required uint32 id = 1;
required uint32 views = 2; // views in the last 7 days
}
+190
View File
@@ -0,0 +1,190 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: popular_tanks.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
export const protobufPackage = "blitzkit";
export interface PopularTanks {
tanks: PopularTank[];
}
export interface PopularTank {
id: number;
/** views in the last 7 days */
views: number;
}
export function createBasePopularTanks(): PopularTanks {
return { tanks: [] };
}
export const PopularTanks: MessageFns<PopularTanks> = {
encode(message: PopularTanks, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.tanks) {
PopularTank.encode(v!, writer.uint32(10).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): PopularTanks {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBasePopularTanks();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.tanks.push(PopularTank.decode(reader, reader.uint32()));
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): PopularTanks {
return {
tanks: globalThis.Array.isArray(object?.tanks) ? object.tanks.map((e: any) => PopularTank.fromJSON(e)) : [],
};
},
toJSON(message: PopularTanks): unknown {
const obj: any = {};
if (message.tanks?.length) {
obj.tanks = message.tanks.map((e) => PopularTank.toJSON(e));
}
return obj;
},
create<I extends Exact<DeepPartial<PopularTanks>, I>>(base?: I): PopularTanks {
return PopularTanks.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<PopularTanks>, I>>(object: I): PopularTanks {
const message = createBasePopularTanks();
message.tanks = object.tanks?.map((e) => PopularTank.fromPartial(e)) || [];
return message;
},
};
export function createBasePopularTank(): PopularTank {
return { id: 0, views: 0 };
}
export const PopularTank: MessageFns<PopularTank> = {
encode(message: PopularTank, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.id !== 0) {
writer.uint32(8).uint32(message.id);
}
if (message.views !== 0) {
writer.uint32(16).uint32(message.views);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): PopularTank {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBasePopularTank();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 8) {
break;
}
message.id = reader.uint32();
continue;
}
case 2: {
if (tag !== 16) {
break;
}
message.views = reader.uint32();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): PopularTank {
return {
id: globalThis.Number(assertSet("PopularTank.id", object.id)),
views: globalThis.Number(assertSet("PopularTank.views", object.views)),
};
},
toJSON(message: PopularTank): unknown {
const obj: any = {};
if (message.id !== 0) {
obj.id = Math.round(message.id);
}
if (message.views !== 0) {
obj.views = Math.round(message.views);
}
return obj;
},
create<I extends Exact<DeepPartial<PopularTank>, I>>(base?: I): PopularTank {
return PopularTank.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<PopularTank>, I>>(object: I): PopularTank {
const message = createBasePopularTank();
message.id = object.id ?? 0;
message.views = object.views ?? 0;
return message;
},
};
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
fromJSON(object: any): T;
toJSON(message: T): unknown;
create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
}
@@ -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: [] };
} }
+11 -11
View File
@@ -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;
@@ -10,16 +10,16 @@ message TankDefinitions {
message TankDefinition { message TankDefinition {
required uint32 id = 1; required uint32 id = 1;
map<uint32, uint32> roles = 2; required string slug = 2;
required bool fixed_camouflage = 4; map<uint32, uint32> roles = 3;
repeated int32 camouflages = 5; required bool fixed_camouflage = 5;
repeated int32 ancestors = 6; repeated int32 camouflages = 6;
repeated int32 successors = 7; repeated int32 ancestors = 7;
repeated Crew crew = 8; repeated int32 successors = 8;
required uint32 health = 9; repeated Crew crew = 9;
required string nation = 10; required uint32 health = 10;
required I18nString name = 11; required string nation = 11;
optional I18nString name_full = 12; required I18nString name = 12;
required TankType type = 13; required TankType type = 13;
required uint32 max_consumables = 14; required uint32 max_consumables = 14;
required uint32 max_provisions = 15; required uint32 max_provisions = 15;
+145 -145
View File
@@ -2,27 +2,27 @@
// 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/tank_definitions.proto // source: tank_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 TankPriceType { export enum TankPriceType {
CREDITS = 0, TANK_PRICE_TYPE_CREDITS = 0,
GOLD = 1, TANK_PRICE_TYPE_GOLD = 1,
} }
export function tankPriceTypeFromJSON(object: any): TankPriceType { export function tankPriceTypeFromJSON(object: any): TankPriceType {
switch (object) { switch (object) {
case 0: case 0:
case "TANK_PRICE_TYPE_CREDITS": case "TANK_PRICE_TYPE_CREDITS":
return TankPriceType.CREDITS; return TankPriceType.TANK_PRICE_TYPE_CREDITS;
case 1: case 1:
case "TANK_PRICE_TYPE_GOLD": case "TANK_PRICE_TYPE_GOLD":
return TankPriceType.GOLD; return TankPriceType.TANK_PRICE_TYPE_GOLD;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankPriceType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankPriceType");
} }
@@ -30,9 +30,9 @@ export function tankPriceTypeFromJSON(object: any): TankPriceType {
export function tankPriceTypeToJSON(object: TankPriceType): string { export function tankPriceTypeToJSON(object: TankPriceType): string {
switch (object) { switch (object) {
case TankPriceType.CREDITS: case TankPriceType.TANK_PRICE_TYPE_CREDITS:
return "TANK_PRICE_TYPE_CREDITS"; return "TANK_PRICE_TYPE_CREDITS";
case TankPriceType.GOLD: case TankPriceType.TANK_PRICE_TYPE_GOLD:
return "TANK_PRICE_TYPE_GOLD"; return "TANK_PRICE_TYPE_GOLD";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankPriceType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankPriceType");
@@ -40,26 +40,26 @@ export function tankPriceTypeToJSON(object: TankPriceType): string {
} }
export enum ShellType { export enum ShellType {
AP = 0, SHELL_TYPE_AP = 0,
APCR = 1, SHELL_TYPE_APCR = 1,
HEAT = 2, SHELL_TYPE_HEAT = 2,
HE = 3, SHELL_TYPE_HE = 3,
} }
export function shellTypeFromJSON(object: any): ShellType { export function shellTypeFromJSON(object: any): ShellType {
switch (object) { switch (object) {
case 0: case 0:
case "SHELL_TYPE_AP": case "SHELL_TYPE_AP":
return ShellType.AP; return ShellType.SHELL_TYPE_AP;
case 1: case 1:
case "SHELL_TYPE_APCR": case "SHELL_TYPE_APCR":
return ShellType.APCR; return ShellType.SHELL_TYPE_APCR;
case 2: case 2:
case "SHELL_TYPE_HEAT": case "SHELL_TYPE_HEAT":
return ShellType.HEAT; return ShellType.SHELL_TYPE_HEAT;
case 3: case 3:
case "SHELL_TYPE_HE": case "SHELL_TYPE_HE":
return ShellType.HE; return ShellType.SHELL_TYPE_HE;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum ShellType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum ShellType");
} }
@@ -67,13 +67,13 @@ export function shellTypeFromJSON(object: any): ShellType {
export function shellTypeToJSON(object: ShellType): string { export function shellTypeToJSON(object: ShellType): string {
switch (object) { switch (object) {
case ShellType.AP: case ShellType.SHELL_TYPE_AP:
return "SHELL_TYPE_AP"; return "SHELL_TYPE_AP";
case ShellType.APCR: case ShellType.SHELL_TYPE_APCR:
return "SHELL_TYPE_APCR"; return "SHELL_TYPE_APCR";
case ShellType.HEAT: case ShellType.SHELL_TYPE_HEAT:
return "SHELL_TYPE_HEAT"; return "SHELL_TYPE_HEAT";
case ShellType.HE: case ShellType.SHELL_TYPE_HE:
return "SHELL_TYPE_HE"; return "SHELL_TYPE_HE";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum ShellType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum ShellType");
@@ -81,30 +81,30 @@ export function shellTypeToJSON(object: ShellType): string {
} }
export enum ModuleType { export enum ModuleType {
VEHICLE = 0, MODULE_TYPE_VEHICLE = 0,
ENGINE = 1, MODULE_TYPE_ENGINE = 1,
TRACKS = 2, MODULE_TYPE_TRACKS = 2,
TURRET = 3, MODULE_TYPE_TURRET = 3,
GUN = 4, MODULE_TYPE_GUN = 4,
} }
export function moduleTypeFromJSON(object: any): ModuleType { export function moduleTypeFromJSON(object: any): ModuleType {
switch (object) { switch (object) {
case 0: case 0:
case "MODULE_TYPE_VEHICLE": case "MODULE_TYPE_VEHICLE":
return ModuleType.VEHICLE; return ModuleType.MODULE_TYPE_VEHICLE;
case 1: case 1:
case "MODULE_TYPE_ENGINE": case "MODULE_TYPE_ENGINE":
return ModuleType.ENGINE; return ModuleType.MODULE_TYPE_ENGINE;
case 2: case 2:
case "MODULE_TYPE_TRACKS": case "MODULE_TYPE_TRACKS":
return ModuleType.TRACKS; return ModuleType.MODULE_TYPE_TRACKS;
case 3: case 3:
case "MODULE_TYPE_TURRET": case "MODULE_TYPE_TURRET":
return ModuleType.TURRET; return ModuleType.MODULE_TYPE_TURRET;
case 4: case 4:
case "MODULE_TYPE_GUN": case "MODULE_TYPE_GUN":
return ModuleType.GUN; return ModuleType.MODULE_TYPE_GUN;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum ModuleType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum ModuleType");
} }
@@ -112,15 +112,15 @@ export function moduleTypeFromJSON(object: any): ModuleType {
export function moduleTypeToJSON(object: ModuleType): string { export function moduleTypeToJSON(object: ModuleType): string {
switch (object) { switch (object) {
case ModuleType.VEHICLE: case ModuleType.MODULE_TYPE_VEHICLE:
return "MODULE_TYPE_VEHICLE"; return "MODULE_TYPE_VEHICLE";
case ModuleType.ENGINE: case ModuleType.MODULE_TYPE_ENGINE:
return "MODULE_TYPE_ENGINE"; return "MODULE_TYPE_ENGINE";
case ModuleType.TRACKS: case ModuleType.MODULE_TYPE_TRACKS:
return "MODULE_TYPE_TRACKS"; return "MODULE_TYPE_TRACKS";
case ModuleType.TURRET: case ModuleType.MODULE_TYPE_TURRET:
return "MODULE_TYPE_TURRET"; return "MODULE_TYPE_TURRET";
case ModuleType.GUN: case ModuleType.MODULE_TYPE_GUN:
return "MODULE_TYPE_GUN"; return "MODULE_TYPE_GUN";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum ModuleType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum ModuleType");
@@ -128,26 +128,26 @@ export function moduleTypeToJSON(object: ModuleType): string {
} }
export enum TankClass { export enum TankClass {
LIGHT = 0, TANK_CLASS_LIGHT = 0,
MEDIUM = 1, TANK_CLASS_MEDIUM = 1,
HEAVY = 2, TANK_CLASS_HEAVY = 2,
TANK_DESTROYER = 3, TANK_CLASS_TANK_DESTROYER = 3,
} }
export function tankClassFromJSON(object: any): TankClass { export function tankClassFromJSON(object: any): TankClass {
switch (object) { switch (object) {
case 0: case 0:
case "TANK_CLASS_LIGHT": case "TANK_CLASS_LIGHT":
return TankClass.LIGHT; return TankClass.TANK_CLASS_LIGHT;
case 1: case 1:
case "TANK_CLASS_MEDIUM": case "TANK_CLASS_MEDIUM":
return TankClass.MEDIUM; return TankClass.TANK_CLASS_MEDIUM;
case 2: case 2:
case "TANK_CLASS_HEAVY": case "TANK_CLASS_HEAVY":
return TankClass.HEAVY; return TankClass.TANK_CLASS_HEAVY;
case 3: case 3:
case "TANK_CLASS_TANK_DESTROYER": case "TANK_CLASS_TANK_DESTROYER":
return TankClass.TANK_DESTROYER; return TankClass.TANK_CLASS_TANK_DESTROYER;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankClass"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankClass");
} }
@@ -155,13 +155,13 @@ export function tankClassFromJSON(object: any): TankClass {
export function tankClassToJSON(object: TankClass): string { export function tankClassToJSON(object: TankClass): string {
switch (object) { switch (object) {
case TankClass.LIGHT: case TankClass.TANK_CLASS_LIGHT:
return "TANK_CLASS_LIGHT"; return "TANK_CLASS_LIGHT";
case TankClass.MEDIUM: case TankClass.TANK_CLASS_MEDIUM:
return "TANK_CLASS_MEDIUM"; return "TANK_CLASS_MEDIUM";
case TankClass.HEAVY: case TankClass.TANK_CLASS_HEAVY:
return "TANK_CLASS_HEAVY"; return "TANK_CLASS_HEAVY";
case TankClass.TANK_DESTROYER: case TankClass.TANK_CLASS_TANK_DESTROYER:
return "TANK_CLASS_TANK_DESTROYER"; return "TANK_CLASS_TANK_DESTROYER";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankClass"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankClass");
@@ -169,22 +169,22 @@ export function tankClassToJSON(object: TankClass): string {
} }
export enum TankType { export enum TankType {
RESEARCHABLE = 0, TANK_TYPE_RESEARCHABLE = 0,
PREMIUM = 1, TANK_TYPE_PREMIUM = 1,
COLLECTOR = 2, TANK_TYPE_COLLECTOR = 2,
} }
export function tankTypeFromJSON(object: any): TankType { export function tankTypeFromJSON(object: any): TankType {
switch (object) { switch (object) {
case 0: case 0:
case "TANK_TYPE_RESEARCHABLE": case "TANK_TYPE_RESEARCHABLE":
return TankType.RESEARCHABLE; return TankType.TANK_TYPE_RESEARCHABLE;
case 1: case 1:
case "TANK_TYPE_PREMIUM": case "TANK_TYPE_PREMIUM":
return TankType.PREMIUM; return TankType.TANK_TYPE_PREMIUM;
case 2: case 2:
case "TANK_TYPE_COLLECTOR": case "TANK_TYPE_COLLECTOR":
return TankType.COLLECTOR; return TankType.TANK_TYPE_COLLECTOR;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankType");
} }
@@ -192,11 +192,11 @@ export function tankTypeFromJSON(object: any): TankType {
export function tankTypeToJSON(object: TankType): string { export function tankTypeToJSON(object: TankType): string {
switch (object) { switch (object) {
case TankType.RESEARCHABLE: case TankType.TANK_TYPE_RESEARCHABLE:
return "TANK_TYPE_RESEARCHABLE"; return "TANK_TYPE_RESEARCHABLE";
case TankType.PREMIUM: case TankType.TANK_TYPE_PREMIUM:
return "TANK_TYPE_PREMIUM"; return "TANK_TYPE_PREMIUM";
case TankType.COLLECTOR: case TankType.TANK_TYPE_COLLECTOR:
return "TANK_TYPE_COLLECTOR"; return "TANK_TYPE_COLLECTOR";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum TankType");
@@ -204,30 +204,30 @@ export function tankTypeToJSON(object: TankType): string {
} }
export enum CrewType { export enum CrewType {
COMMANDER = 0, CREW_TYPE_COMMANDER = 0,
RADIOMAN = 1, CREW_TYPE_RADIOMAN = 1,
GUNNER = 2, CREW_TYPE_GUNNER = 2,
DRIVER = 3, CREW_TYPE_DRIVER = 3,
LOADER = 4, CREW_TYPE_LOADER = 4,
} }
export function crewTypeFromJSON(object: any): CrewType { export function crewTypeFromJSON(object: any): CrewType {
switch (object) { switch (object) {
case 0: case 0:
case "CREW_TYPE_COMMANDER": case "CREW_TYPE_COMMANDER":
return CrewType.COMMANDER; return CrewType.CREW_TYPE_COMMANDER;
case 1: case 1:
case "CREW_TYPE_RADIOMAN": case "CREW_TYPE_RADIOMAN":
return CrewType.RADIOMAN; return CrewType.CREW_TYPE_RADIOMAN;
case 2: case 2:
case "CREW_TYPE_GUNNER": case "CREW_TYPE_GUNNER":
return CrewType.GUNNER; return CrewType.CREW_TYPE_GUNNER;
case 3: case 3:
case "CREW_TYPE_DRIVER": case "CREW_TYPE_DRIVER":
return CrewType.DRIVER; return CrewType.CREW_TYPE_DRIVER;
case 4: case 4:
case "CREW_TYPE_LOADER": case "CREW_TYPE_LOADER":
return CrewType.LOADER; return CrewType.CREW_TYPE_LOADER;
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum CrewType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum CrewType");
} }
@@ -235,15 +235,15 @@ export function crewTypeFromJSON(object: any): CrewType {
export function crewTypeToJSON(object: CrewType): string { export function crewTypeToJSON(object: CrewType): string {
switch (object) { switch (object) {
case CrewType.COMMANDER: case CrewType.CREW_TYPE_COMMANDER:
return "CREW_TYPE_COMMANDER"; return "CREW_TYPE_COMMANDER";
case CrewType.RADIOMAN: case CrewType.CREW_TYPE_RADIOMAN:
return "CREW_TYPE_RADIOMAN"; return "CREW_TYPE_RADIOMAN";
case CrewType.GUNNER: case CrewType.CREW_TYPE_GUNNER:
return "CREW_TYPE_GUNNER"; return "CREW_TYPE_GUNNER";
case CrewType.DRIVER: case CrewType.CREW_TYPE_DRIVER:
return "CREW_TYPE_DRIVER"; return "CREW_TYPE_DRIVER";
case CrewType.LOADER: case CrewType.CREW_TYPE_LOADER:
return "CREW_TYPE_LOADER"; return "CREW_TYPE_LOADER";
default: default:
throw new globalThis.Error("Unrecognized enum value " + object + " for enum CrewType"); throw new globalThis.Error("Unrecognized enum value " + object + " for enum CrewType");
@@ -261,6 +261,7 @@ export interface TankDefinitions_TanksEntry {
export interface TankDefinition { export interface TankDefinition {
id: number; id: number;
slug: string;
roles: { [key: number]: number }; roles: { [key: number]: number };
fixed_camouflage: boolean; fixed_camouflage: boolean;
camouflages: number[]; camouflages: number[];
@@ -270,7 +271,6 @@ export interface TankDefinition {
health: number; health: number;
nation: string; nation: string;
name: I18nString; name: I18nString;
name_full?: I18nString | undefined;
type: TankType; type: TankType;
max_consumables: number; max_consumables: number;
max_provisions: number; max_provisions: number;
@@ -448,7 +448,7 @@ export interface Crew {
substitute: CrewType[]; substitute: CrewType[];
} }
function createBaseTankDefinitions(): TankDefinitions { export function createBaseTankDefinitions(): TankDefinitions {
return { tanks: {} }; return { tanks: {} };
} }
@@ -530,7 +530,7 @@ export const TankDefinitions: MessageFns<TankDefinitions> = {
}, },
}; };
function createBaseTankDefinitions_TanksEntry(): TankDefinitions_TanksEntry { export function createBaseTankDefinitions_TanksEntry(): TankDefinitions_TanksEntry {
return { key: 0, value: createBaseTankDefinition() }; return { key: 0, value: createBaseTankDefinition() };
} }
@@ -603,14 +603,15 @@ export const TankDefinitions_TanksEntry: MessageFns<TankDefinitions_TanksEntry>
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)
? TankDefinition.fromPartial(object.value) ? TankDefinition.fromPartial(object.value)
: undefined; : createBaseTankDefinition();
return message; return message;
}, },
}; };
function createBaseTankDefinition(): TankDefinition { export function createBaseTankDefinition(): TankDefinition {
return { return {
id: 0, id: 0,
slug: "",
roles: {}, roles: {},
fixed_camouflage: false, fixed_camouflage: false,
camouflages: [], camouflages: [],
@@ -620,7 +621,6 @@ function createBaseTankDefinition(): TankDefinition {
health: 0, health: 0,
nation: "", nation: "",
name: createBaseI18nString(), name: createBaseI18nString(),
name_full: undefined,
type: 0, type: 0,
max_consumables: 0, max_consumables: 0,
max_provisions: 0, max_provisions: 0,
@@ -648,41 +648,41 @@ export const TankDefinition: MessageFns<TankDefinition> = {
if (message.id !== 0) { if (message.id !== 0) {
writer.uint32(8).uint32(message.id); writer.uint32(8).uint32(message.id);
} }
if (message.slug !== "") {
writer.uint32(18).string(message.slug);
}
Object.entries(message.roles).forEach(([key, value]) => { Object.entries(message.roles).forEach(([key, value]) => {
TankDefinition_RolesEntry.encode({ key: key as any, value }, writer.uint32(18).fork()).join(); TankDefinition_RolesEntry.encode({ key: key as any, value }, writer.uint32(26).fork()).join();
}); });
if (message.fixed_camouflage !== false) { if (message.fixed_camouflage !== false) {
writer.uint32(32).bool(message.fixed_camouflage); writer.uint32(40).bool(message.fixed_camouflage);
} }
writer.uint32(42).fork(); writer.uint32(50).fork();
for (const v of message.camouflages) { for (const v of message.camouflages) {
writer.int32(v); writer.int32(v);
} }
writer.join(); writer.join();
writer.uint32(50).fork(); writer.uint32(58).fork();
for (const v of message.ancestors) { for (const v of message.ancestors) {
writer.int32(v); writer.int32(v);
} }
writer.join(); writer.join();
writer.uint32(58).fork(); writer.uint32(66).fork();
for (const v of message.successors) { for (const v of message.successors) {
writer.int32(v); writer.int32(v);
} }
writer.join(); writer.join();
for (const v of message.crew) { for (const v of message.crew) {
Crew.encode(v!, writer.uint32(66).fork()).join(); Crew.encode(v!, writer.uint32(74).fork()).join();
} }
if (message.health !== 0) { if (message.health !== 0) {
writer.uint32(72).uint32(message.health); writer.uint32(80).uint32(message.health);
} }
if (message.nation !== "") { if (message.nation !== "") {
writer.uint32(82).string(message.nation); writer.uint32(90).string(message.nation);
} }
if (message.name !== undefined) { if (message.name !== undefined) {
I18nString.encode(message.name, writer.uint32(90).fork()).join(); I18nString.encode(message.name, writer.uint32(98).fork()).join();
}
if (message.name_full !== undefined) {
I18nString.encode(message.name_full, writer.uint32(98).fork()).join();
} }
if (message.type !== 0) { if (message.type !== 0) {
writer.uint32(104).int32(message.type); writer.uint32(104).int32(message.type);
@@ -764,28 +764,36 @@ export const TankDefinition: MessageFns<TankDefinition> = {
break; break;
} }
const entry2 = TankDefinition_RolesEntry.decode(reader, reader.uint32()); message.slug = reader.string();
if (entry2.value !== undefined) { continue;
message.roles[entry2.key] = entry2.value; }
case 3: {
if (tag !== 26) {
break;
}
const entry3 = TankDefinition_RolesEntry.decode(reader, reader.uint32());
if (entry3.value !== undefined) {
message.roles[entry3.key] = entry3.value;
} }
continue; continue;
} }
case 4: { case 5: {
if (tag !== 32) { if (tag !== 40) {
break; break;
} }
message.fixed_camouflage = reader.bool(); message.fixed_camouflage = reader.bool();
continue; continue;
} }
case 5: { case 6: {
if (tag === 40) { if (tag === 48) {
message.camouflages.push(reader.int32()); message.camouflages.push(reader.int32());
continue; continue;
} }
if (tag === 42) { if (tag === 50) {
const end2 = reader.uint32() + reader.pos; const end2 = reader.uint32() + reader.pos;
while (reader.pos < end2) { while (reader.pos < end2) {
message.camouflages.push(reader.int32()); message.camouflages.push(reader.int32());
@@ -796,14 +804,14 @@ export const TankDefinition: MessageFns<TankDefinition> = {
break; break;
} }
case 6: { case 7: {
if (tag === 48) { if (tag === 56) {
message.ancestors.push(reader.int32()); message.ancestors.push(reader.int32());
continue; continue;
} }
if (tag === 50) { if (tag === 58) {
const end2 = reader.uint32() + reader.pos; const end2 = reader.uint32() + reader.pos;
while (reader.pos < end2) { while (reader.pos < end2) {
message.ancestors.push(reader.int32()); message.ancestors.push(reader.int32());
@@ -814,14 +822,14 @@ export const TankDefinition: MessageFns<TankDefinition> = {
break; break;
} }
case 7: { case 8: {
if (tag === 56) { if (tag === 64) {
message.successors.push(reader.int32()); message.successors.push(reader.int32());
continue; continue;
} }
if (tag === 58) { if (tag === 66) {
const end2 = reader.uint32() + reader.pos; const end2 = reader.uint32() + reader.pos;
while (reader.pos < end2) { while (reader.pos < end2) {
message.successors.push(reader.int32()); message.successors.push(reader.int32());
@@ -832,36 +840,28 @@ export const TankDefinition: MessageFns<TankDefinition> = {
break; break;
} }
case 8: { case 9: {
if (tag !== 66) { if (tag !== 74) {
break; break;
} }
message.crew.push(Crew.decode(reader, reader.uint32())); message.crew.push(Crew.decode(reader, reader.uint32()));
continue; continue;
} }
case 9: { case 10: {
if (tag !== 72) { if (tag !== 80) {
break; break;
} }
message.health = reader.uint32(); message.health = reader.uint32();
continue; continue;
} }
case 10: {
if (tag !== 82) {
break;
}
message.nation = reader.string();
continue;
}
case 11: { case 11: {
if (tag !== 90) { if (tag !== 90) {
break; break;
} }
message.name = I18nString.decode(reader, reader.uint32()); message.nation = reader.string();
continue; continue;
} }
case 12: { case 12: {
@@ -869,7 +869,7 @@ export const TankDefinition: MessageFns<TankDefinition> = {
break; break;
} }
message.name_full = I18nString.decode(reader, reader.uint32()); message.name = I18nString.decode(reader, reader.uint32());
continue; continue;
} }
case 13: { case 13: {
@@ -1036,6 +1036,7 @@ export const TankDefinition: MessageFns<TankDefinition> = {
fromJSON(object: any): TankDefinition { fromJSON(object: any): TankDefinition {
return { return {
id: globalThis.Number(assertSet("TankDefinition.id", object.id)), id: globalThis.Number(assertSet("TankDefinition.id", object.id)),
slug: globalThis.String(assertSet("TankDefinition.slug", object.slug)),
roles: isObject(object.roles) roles: isObject(object.roles)
? Object.entries(object.roles).reduce<{ [key: number]: number }>((acc, [key, value]) => { ? Object.entries(object.roles).reduce<{ [key: number]: number }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Number(value); acc[globalThis.Number(key)] = Number(value);
@@ -1052,11 +1053,12 @@ export const TankDefinition: MessageFns<TankDefinition> = {
successors: globalThis.Array.isArray(object?.successors) successors: globalThis.Array.isArray(object?.successors)
? object.successors.map((e: any) => globalThis.Number(e)) ? object.successors.map((e: any) => globalThis.Number(e))
: [], : [],
crew: globalThis.Array.isArray(object?.crew) ? object.crew.map((e: any) => Crew.fromJSON(e)) : [], crew: globalThis.Array.isArray(object?.crew)
? object.crew.map((e: any) => Crew.fromJSON(e))
: [],
health: globalThis.Number(assertSet("TankDefinition.health", object.health)), health: globalThis.Number(assertSet("TankDefinition.health", object.health)),
nation: globalThis.String(assertSet("TankDefinition.nation", object.nation)), nation: globalThis.String(assertSet("TankDefinition.nation", object.nation)),
name: I18nString.fromJSON(assertSet("TankDefinition.name", object.name)), name: I18nString.fromJSON(assertSet("TankDefinition.name", object.name)),
name_full: isSet(object.name_full) ? I18nString.fromJSON(object.name_full) : undefined,
type: tankTypeFromJSON(assertSet("TankDefinition.type", object.type)), type: tankTypeFromJSON(assertSet("TankDefinition.type", object.type)),
max_consumables: globalThis.Number(assertSet("TankDefinition.max_consumables", object.max_consumables)), max_consumables: globalThis.Number(assertSet("TankDefinition.max_consumables", object.max_consumables)),
max_provisions: globalThis.Number(assertSet("TankDefinition.max_provisions", object.max_provisions)), max_provisions: globalThis.Number(assertSet("TankDefinition.max_provisions", object.max_provisions)),
@@ -1090,6 +1092,9 @@ export const TankDefinition: MessageFns<TankDefinition> = {
if (message.id !== 0) { if (message.id !== 0) {
obj.id = Math.round(message.id); obj.id = Math.round(message.id);
} }
if (message.slug !== "") {
obj.slug = message.slug;
}
if (message.roles) { if (message.roles) {
const entries = Object.entries(message.roles); const entries = Object.entries(message.roles);
if (entries.length > 0) { if (entries.length > 0) {
@@ -1123,9 +1128,6 @@ export const TankDefinition: MessageFns<TankDefinition> = {
if (message.name !== undefined) { if (message.name !== undefined) {
obj.name = I18nString.toJSON(message.name); obj.name = I18nString.toJSON(message.name);
} }
if (message.name_full !== undefined) {
obj.name_full = I18nString.toJSON(message.name_full);
}
if (message.type !== 0) { if (message.type !== 0) {
obj.type = tankTypeToJSON(message.type); obj.type = tankTypeToJSON(message.type);
} }
@@ -1192,6 +1194,7 @@ export const TankDefinition: MessageFns<TankDefinition> = {
fromPartial<I extends Exact<DeepPartial<TankDefinition>, I>>(object: I): TankDefinition { fromPartial<I extends Exact<DeepPartial<TankDefinition>, I>>(object: I): TankDefinition {
const message = createBaseTankDefinition(); const message = createBaseTankDefinition();
message.id = object.id ?? 0; message.id = object.id ?? 0;
message.slug = object.slug ?? "";
message.roles = Object.entries(object.roles ?? {}).reduce<{ [key: number]: number }>((acc, [key, value]) => { message.roles = Object.entries(object.roles ?? {}).reduce<{ [key: number]: number }>((acc, [key, value]) => {
if (value !== undefined) { if (value !== undefined) {
acc[globalThis.Number(key)] = globalThis.Number(value); acc[globalThis.Number(key)] = globalThis.Number(value);
@@ -1208,9 +1211,6 @@ export const TankDefinition: MessageFns<TankDefinition> = {
message.name = (object.name !== undefined && object.name !== null) message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name) ? I18nString.fromPartial(object.name)
: createBaseI18nString(); : createBaseI18nString();
message.name_full = (object.name_full !== undefined && object.name_full !== null)
? I18nString.fromPartial(object.name_full)
: undefined;
message.type = object.type ?? 0; message.type = object.type ?? 0;
message.max_consumables = object.max_consumables ?? 0; message.max_consumables = object.max_consumables ?? 0;
message.max_provisions = object.max_provisions ?? 0; message.max_provisions = object.max_provisions ?? 0;
@@ -1238,7 +1238,7 @@ export const TankDefinition: MessageFns<TankDefinition> = {
}, },
}; };
function createBaseTankDefinition_RolesEntry(): TankDefinition_RolesEntry { export function createBaseTankDefinition_RolesEntry(): TankDefinition_RolesEntry {
return { key: 0, value: 0 }; return { key: 0, value: 0 };
} }
@@ -1314,7 +1314,7 @@ export const TankDefinition_RolesEntry: MessageFns<TankDefinition_RolesEntry> =
}, },
}; };
function createBaseResearchCost(): ResearchCost { export function createBaseResearchCost(): ResearchCost {
return { research_cost_type: undefined }; return { research_cost_type: undefined };
} }
@@ -1413,7 +1413,7 @@ export const ResearchCost: MessageFns<ResearchCost> = {
}, },
}; };
function createBaseResearchCostSeasonalTokens(): ResearchCostSeasonalTokens { export function createBaseResearchCostSeasonalTokens(): ResearchCostSeasonalTokens {
return { season: 0, tokens: 0 }; return { season: 0, tokens: 0 };
} }
@@ -1489,7 +1489,7 @@ export const ResearchCostSeasonalTokens: MessageFns<ResearchCostSeasonalTokens>
}, },
}; };
function createBaseTankPrice(): TankPrice { export function createBaseTankPrice(): TankPrice {
return { type: 0, value: 0 }; return { type: 0, value: 0 };
} }
@@ -1565,7 +1565,7 @@ export const TankPrice: MessageFns<TankPrice> = {
}, },
}; };
function createBaseTrackDefinition(): TrackDefinition { export function createBaseTrackDefinition(): TrackDefinition {
return { return {
id: 0, id: 0,
tier: 0, tier: 0,
@@ -1820,7 +1820,7 @@ export const TrackDefinition: MessageFns<TrackDefinition> = {
}, },
}; };
function createBaseEngineDefinition(): EngineDefinition { export function createBaseEngineDefinition(): EngineDefinition {
return { return {
id: 0, id: 0,
name: createBaseI18nString(), name: createBaseI18nString(),
@@ -2005,7 +2005,7 @@ export const EngineDefinition: MessageFns<EngineDefinition> = {
}, },
}; };
function createBaseTurretDefinition(): TurretDefinition { export function createBaseTurretDefinition(): TurretDefinition {
return { return {
id: 0, id: 0,
health: 0, health: 0,
@@ -2224,7 +2224,7 @@ export const TurretDefinition: MessageFns<TurretDefinition> = {
}, },
}; };
function createBaseGunDefinition(): GunDefinition { export function createBaseGunDefinition(): GunDefinition {
return { gun_type: undefined }; return { gun_type: undefined };
} }
@@ -2344,7 +2344,7 @@ export const GunDefinition: MessageFns<GunDefinition> = {
}, },
}; };
function createBaseGunDefinitionRegular(): GunDefinitionRegular { export function createBaseGunDefinitionRegular(): GunDefinitionRegular {
return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionRegularProperties() }; return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionRegularProperties() };
} }
@@ -2424,7 +2424,7 @@ export const GunDefinitionRegular: MessageFns<GunDefinitionRegular> = {
}, },
}; };
function createBaseGunDefinitionRegularProperties(): GunDefinitionRegularProperties { export function createBaseGunDefinitionRegularProperties(): GunDefinitionRegularProperties {
return { reload: 0 }; return { reload: 0 };
} }
@@ -2484,7 +2484,7 @@ export const GunDefinitionRegularProperties: MessageFns<GunDefinitionRegularProp
}, },
}; };
function createBaseGunDefinitionAutoLoader(): GunDefinitionAutoLoader { export function createBaseGunDefinitionAutoLoader(): GunDefinitionAutoLoader {
return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionAutoLoaderProperties() }; return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionAutoLoaderProperties() };
} }
@@ -2566,7 +2566,7 @@ export const GunDefinitionAutoLoader: MessageFns<GunDefinitionAutoLoader> = {
}, },
}; };
function createBaseGunDefinitionAutoLoaderProperties(): GunDefinitionAutoLoaderProperties { export function createBaseGunDefinitionAutoLoaderProperties(): GunDefinitionAutoLoaderProperties {
return { clip_reload: 0, intra_clip: 0, shell_count: 0 }; return { clip_reload: 0, intra_clip: 0, shell_count: 0 };
} }
@@ -2662,7 +2662,7 @@ export const GunDefinitionAutoLoaderProperties: MessageFns<GunDefinitionAutoLoad
}, },
}; };
function createBaseGunDefinitionAutoReloader(): GunDefinitionAutoReloader { export function createBaseGunDefinitionAutoReloader(): GunDefinitionAutoReloader {
return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionAutoReloaderProperties() }; return { base: createBaseGunDefinitionBase(), extension: createBaseGunDefinitionAutoReloaderProperties() };
} }
@@ -2744,7 +2744,7 @@ export const GunDefinitionAutoReloader: MessageFns<GunDefinitionAutoReloader> =
}, },
}; };
function createBaseGunDefinitionAutoReloaderProperties(): GunDefinitionAutoReloaderProperties { export function createBaseGunDefinitionAutoReloaderProperties(): GunDefinitionAutoReloaderProperties {
return { shell_reloads: [], intra_clip: 0, shell_count: 0 }; return { shell_reloads: [], intra_clip: 0, shell_count: 0 };
} }
@@ -2854,7 +2854,7 @@ export const GunDefinitionAutoReloaderProperties: MessageFns<GunDefinitionAutoRe
}, },
}; };
function createBaseGunDefinitionBase(): GunDefinitionBase { export function createBaseGunDefinitionBase(): GunDefinitionBase {
return { return {
id: 0, id: 0,
rotation_speed: 0, rotation_speed: 0,
@@ -3164,7 +3164,7 @@ export const GunDefinitionBase: MessageFns<GunDefinitionBase> = {
}, },
}; };
function createBaseShellDefinition(): ShellDefinition { export function createBaseShellDefinition(): ShellDefinition {
return { return {
id: 0, id: 0,
name: createBaseI18nString(), name: createBaseI18nString(),
@@ -3434,7 +3434,7 @@ export const ShellDefinition: MessageFns<ShellDefinition> = {
}, },
}; };
function createBaseShellPenetration(): ShellPenetration { export function createBaseShellPenetration(): ShellPenetration {
return { near: 0, far: 0 }; return { near: 0, far: 0 };
} }
@@ -3510,7 +3510,7 @@ export const ShellPenetration: MessageFns<ShellPenetration> = {
}, },
}; };
function createBaseUnlock(): Unlock { export function createBaseUnlock(): Unlock {
return { id: 0, type: 0, cost: createBaseUnlockCost() }; return { id: 0, type: 0, cost: createBaseUnlockCost() };
} }
@@ -3604,7 +3604,7 @@ export const Unlock: MessageFns<Unlock> = {
}, },
}; };
function createBaseUnlockCost(): UnlockCost { export function createBaseUnlockCost(): UnlockCost {
return { type: "", value: 0 }; return { type: "", value: 0 };
} }
@@ -3680,7 +3680,7 @@ export const UnlockCost: MessageFns<UnlockCost> = {
}, },
}; };
function createBaseCrew(): Crew { export function createBaseCrew(): Crew {
return { type: 0, count: 0, substitute: [] }; return { type: 0, count: 0, substitute: [] };
} }
+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": "../../"
}
} }
+14
View File
@@ -0,0 +1,14 @@
{
"default": "en",
"supported": [
{ "locale": "en" },
{ "locale": "es" },
{ "locale": "fr" },
{ "locale": "ja" },
{ "locale": "pl" },
{ "locale": "pt" },
{ "locale": "ru" },
{ "locale": "uk" },
{ "locale": "zh", "blitz": "zh_Hans_SG" }
]
}
+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];
}; };
} }
+140 -24
View File
@@ -6,12 +6,26 @@
}, },
"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",
"deg": "%s1°", "deg": "%s1°",
"hp": "%s1hp", "hp": "%s1hp",
"x": "x%s1" "x": "x%s1",
"percentage": "%s1%",
"deg_s": "%s1°/s"
}, },
"gun_types": { "gun_types": {
@@ -84,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": {
@@ -107,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",
@@ -131,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": {
@@ -739,6 +790,11 @@
}, },
"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"
@@ -756,6 +812,7 @@
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Search tanks...", "search_bar_hint": "Search tanks...",
"recent": "Recently viewed", "recent": "Recently viewed",
"select_all": "Select all", "select_all": "Select all",
@@ -824,6 +881,12 @@
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "By %s1 ❤️" "credit": "By %s1 ❤️"
}, },
@@ -838,8 +901,32 @@
"seo_description": "Tools for everything World of Tanks Blitz" "seo_description": "Tools for everything World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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",
@@ -847,6 +934,32 @@
"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",
@@ -924,6 +1037,8 @@
}, },
"meta": { "meta": {
"compensation": "Compensation",
"free": "Free",
"back": "Back", "back": "Back",
"compare": "Compare", "compare": "Compare",
"swap": { "swap": {
@@ -937,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": {
@@ -996,7 +1112,7 @@
"characteristics": { "characteristics": {
"title": "Characteristics", "title": "Characteristics",
"compare": { "compare": {
"label": "Compare against", "label": "Compare",
"class": "Tier %s1 %s2", "class": "Tier %s1 %s2",
"tier": "All of tier %s1", "tier": "All of tier %s1",
"all": "All tanks" "all": "All tanks"
@@ -1033,7 +1149,7 @@
"explosionRadius": "Explosion radius", "explosionRadius": "Explosion radius",
"shellVelocity": "Shell velocity", "shellVelocity": "Shell velocity",
"aimTime": "Aim time", "aimTime": "Aim time",
"dispersion": "Still", "dispersion": "Dispersion still",
"dispersionMoving": "Moving", "dispersionMoving": "Moving",
"dispersionHullTraversing": "Hull traversing", "dispersionHullTraversing": "Hull traversing",
"dispersionTurretTraversing": "Turret traversing", "dispersionTurretTraversing": "Turret traversing",
@@ -1047,28 +1163,28 @@
"gunRearElevation": "Rear elevation", "gunRearElevation": "Rear elevation",
"azimuthLeft": "Azimuth left", "azimuthLeft": "Azimuth left",
"azimuthRight": "Azimuth right", "azimuthRight": "Azimuth right",
"speedForwards": "Forwards", "speedForwards": "Speed forwards",
"speedBackwards": "Backwards", "speedBackwards": "Backwards",
"hardTerrainCoefficient": "Hard", "hardTerrainCoefficient": "Terrain coefficient hard",
"hardTerrainCoefficientRaw": "Hard", "hardTerrainCoefficientRaw": "Raw terrain coefficient hard",
"mediumTerrainCoefficient": "Medium", "mediumTerrainCoefficient": "Medium",
"mediumTerrainCoefficientRaw": "Medium", "mediumTerrainCoefficientRaw": "Medium",
"softTerrainCoefficient": "Soft", "softTerrainCoefficient": "Soft",
"softTerrainCoefficientRaw": "Soft", "softTerrainCoefficientRaw": "Soft",
"enginePower": "Engine power", "enginePower": "Engine power",
"powerToWeightRatioHardTerrain": "Hard", "powerToWeightRatioHardTerrain": "Power to weight ratio hard",
"powerToWeightRatioMediumTerrain": "Medium", "powerToWeightRatioMediumTerrain": "Medium",
"powerToWeightRatioSoftTerrain": "Soft", "powerToWeightRatioSoftTerrain": "Soft",
"weight": "Weight", "weight": "Weight",
"turretTraverseSpeed": "Turret traverse speed", "turretTraverseSpeed": "Turret traverse speed",
"gunTraverseSpeed": "Gun traverse speed", "gunTraverseSpeed": "Gun traverse speed",
"hullTraverseHardTerrain": "Hard", "hullTraverseHardTerrain": "Hull traverse hard",
"hullTraverseMediumTerrain": "Medium", "hullTraverseMediumTerrain": "Medium",
"hullTraverseSoftTerrain": "Soft", "hullTraverseSoftTerrain": "Soft",
"health": "Health", "health": "Health",
"fireChance": "Fire chance", "fireChance": "Fire chance",
"viewRange": "View range", "viewRange": "View range",
"camouflageStill": "Still", "camouflageStill": "Camouflage still",
"camouflageMoving": "Moving", "camouflageMoving": "Moving",
"camouflageShootingStill": "Still", "camouflageShootingStill": "Still",
"camouflageShootingMoving": "Moving", "camouflageShootingMoving": "Moving",
+162 -106
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"
@@ -665,6 +671,7 @@
"copied": "Copiado!" "copied": "Copiado!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Buscar tanques...", "search_bar_hint": "Buscar tanques...",
"recent": "Visto recientemente", "recent": "Visto recientemente",
"select_all": "Seleccionar todo", "select_all": "Seleccionar todo",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "Por %s1 ❤️" "credit": "Por %s1 ❤️"
}, },
@@ -744,14 +756,58 @@
"help_translate": "¡Por favor ayuda a traducir %s1 a %s2!", "help_translate": "¡Por favor ayuda a traducir %s1 a %s2!",
"seo_description": "Herramientas para todo lo que es World of Tanks Blitz" "seo_description": "Herramientas para todo lo que es World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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",
@@ -843,105 +899,105 @@
}, },
"tech_tree": { "tech_tree": {
"title": "Árbol tecnológico", "title": "Árbol tecnológico",
"battle": "1 battle", "battle": "1 batalla",
"battles": "%s1 battles", "battles": "%s1 batallas",
"route": "Route %s1 of %s2" "route": "Ruta %s1 de %s2"
}, },
"game_modes": { "game_modes": {
"title": "Game mode abilities" "title": "Habilidades del modo de juego"
}, },
"review": { "review": {
"title": "Review videos", "title": "Vídeos de reseña",
"disclaimer": "BlitzKit no respalda ningún vídeo de reseñas.", "disclaimer": "BlitzKit no respalda ningún vídeo de reseñas.",
"join": "Apply to %s1 YouTuber program" "join": "Aplica para el programa de YouTube de %s1"
}, },
"configuration": { "configuration": {
"title": "", "title": "",
"modules": { "modules": {
"title": "Modules", "title": "Módulos",
"stock": "Stock", "stock": "Base",
"upgrade": "Upgrade" "upgrade": "Mejorar"
}, },
"equipment": { "equipment": {
"title": "Equipment", "title": "Equipo",
"clear": "Clear" "clear": "Limpiar"
}, },
"provisions": { "provisions": {
"title": "Provisiones", "title": "Provisiones",
"clear": "Limpiar" "clear": "Limpiar"
}, },
"consumables": { "consumables": {
"title": "Consumables", "title": "Consumibles",
"clear": "Clear", "clear": "Limpiar",
"info": "Yellow consumables do not affect the statistics." "info": "Consumibles amarillos no afectan las estadísticas."
}, },
"skills": { "skills": {
"title": "Crew skills", "title": "Habilidades de tripulación",
"clear": "Clear", "clear": "Limpiar",
"maximize": "Maximize", "maximize": "Maximizar",
"info": "Yellow skills only apply under special circumstances. Hold Space to quickly toggle between level 0 and 7." "info": "Las habilidades en amarillo solo se aplican en circunstancias especiales. Mantenga el espacio para cambiar rápidamente entre los niveles 0 y 7."
}, },
"miscellaneous": { "miscellaneous": {
"title": "Misceláneo" "title": "Misceláneo"
} }
}, },
"characteristics": { "characteristics": {
"title": "Characteristics", "title": "Características",
"compare": { "compare": {
"label": "Compare against", "label": "Comparar con",
"class": "Tier %s1 %s2", "class": "Nivel %s1 - %s2",
"tier": "All of tier %s1", "tier": "Todos de nivel %s1",
"all": "All tanks" "all": "Todos los tanques"
}, },
"values": { "values": {
"shell_index": "Shell %s1", "shell_index": "Proyectil %s1",
"at_distance": "At %s1m", "at_distance": "A %s1m",
"at_distance_slider_label": "Distance", "at_distance_slider_label": "Distancia",
"dispersion_at_distance": "Dispersion at %s1m", "dispersion_at_distance": "Dispersión a %s1m",
"gun_flexibility": "Gun flexibility", "gun_flexibility": "Flexibilidad del arma",
"speed": "Speed", "speed": "Velocidad",
"terrain_coefficients": "Terrain coefficients", "terrain_coefficients": "Coeficientes de terreno",
"raw_terrain_coefficients": "Raw terrain coefficients", "raw_terrain_coefficients": "Coeficientes de terreno en bruto",
"power_to_weight_ratio": "Power to weight ratio", "power_to_weight_ratio": "Relación peso-potencia",
"hull_traverse_speed": "Hull traverse speed", "hull_traverse_speed": "Velocidad de rotación del casco",
"camouflage": "Camouflage", "camouflage": "Camuflaje",
"reload": "Reload", "reload": "Recarga",
"crewCount": "Crew count", "crewCount": "Cantidad de tripulantes",
"shellNormalization": "Normalización", "shellNormalization": "Normalización",
"shellRicochet": "Rebote", "shellRicochet": "Rebote",
"dpm": "DPM", "dpm": "DPM",
"dpmEffective": "Effective at 60s", "dpmEffective": "Effective at 60s",
"shells": "Shells", "shells": "Proyectiles",
"mostOptimalShellIndex": "Most optimal shell", "mostOptimalShellIndex": "Proyectil más óptimo",
"shellReloads": "Shell reloads", "shellReloads": "Tiempos de recarga",
"shellReload": "Shell reload", "shellReload": "Tiempo de recarga",
"intraClip": "Intra-clip", "intraClip": "Intra-clip",
"caliber": "Calibre", "caliber": "Calibre",
"penetration": "Penetración", "penetration": "Penetración",
"damage": "Daño", "damage": "Daño",
"clipDamage": "Clipping potential", "clipDamage": "Clipping potential",
"moduleDamage": "Module damage", "moduleDamage": "Daño a módulos",
"explosionRadius": "Radio de Explosión", "explosionRadius": "Radio de Explosión",
"shellVelocity": "Shell velocity", "shellVelocity": "Velocidad del proyectil",
"aimTime": "Aim time", "aimTime": "Tiempo de apuntado",
"dispersion": "Still", "dispersion": "Quieto",
"dispersionMoving": "Moving", "dispersionMoving": "En movimiento",
"dispersionHullTraversing": "Hull traversing", "dispersionHullTraversing": "Hull traversing",
"dispersionTurretTraversing": "Turret traversing", "dispersionTurretTraversing": "Turret traversing",
"dispersionShooting": "Shooting", "dispersionShooting": "Disparando",
"dispersionGunDamaged": "Gun damaged", "dispersionGunDamaged": "Arma dañada",
"gunDepression": "Depression", "gunDepression": "Depresión",
"gunElevation": "Elevation", "gunElevation": "Elevación",
"gunFrontalDepression": "Frontal depression", "gunFrontalDepression": "Depresión frontal",
"gunFrontalElevation": "Frontal elevation", "gunFrontalElevation": "Elevación frontal",
"gunRearDepression": "Rear depression", "gunRearDepression": "Depresión trasera",
"gunRearElevation": "Rear elevation", "gunRearElevation": "Elevación trasera",
"azimuthLeft": "Azimuth left", "azimuthLeft": "Azimuth left",
"azimuthRight": "Azimuth right", "azimuthRight": "Azimuth right",
"speedForwards": "Forwards", "speedForwards": "Avance",
"speedBackwards": "Backwards", "speedBackwards": "Marcha atrás",
"hardTerrainCoefficient": "Hard", "hardTerrainCoefficient": "Duro",
"hardTerrainCoefficientRaw": "Hard", "hardTerrainCoefficientRaw": "Duro",
"mediumTerrainCoefficient": "Medio", "mediumTerrainCoefficient": "Medio",
"mediumTerrainCoefficientRaw": "Medio", "mediumTerrainCoefficientRaw": "Medio",
"softTerrainCoefficient": "Suave", "softTerrainCoefficient": "Suave",
@@ -1026,7 +1082,7 @@
"maximize": "Maximizar" "maximize": "Maximizar"
}, },
"modules": { "modules": {
"stock": "Stock", "stock": "Base",
"upgrade": "Mejorar" "upgrade": "Mejorar"
}, },
"provisions": { "provisions": {
@@ -1107,22 +1163,22 @@
}, },
"no_battles": { "no_battles": {
"title": "No battles", "title": "No battles",
"hint": "Go ahead and play a game" "hint": "Sigue adelante y juega una partida"
}, },
"table": { "table": {
"tank": "Tanque", "tank": "Tanque",
"total": "Total", "total": "Total",
"remove": "Remove" "remove": "Remover"
} }
}, },
"tier_list": { "tier_list": {
"name": "Tier list", "name": "Tier list",
"button": "Rank tanks", "button": "Rank tanks",
"description": "Rank Blitz tanks", "description": "Rank Blitz tanks",
"seo_description": "Explore tier lists ranking tanks from best to worst, based on player ratings and statistical performance in World of Tanks Blitz", "seo_description": "Explora las listas de clasificación de los tanques de mejor a peor, basadas en las calificaciones de los jugadores y el rendimiento estadístico en World of Tanks Blitz",
"buttons": { "buttons": {
"reset": "Restablecer", "reset": "Restablecer",
"share": "Share" "share": "Compartir"
} }
}, },
"embed": { "embed": {
@@ -1131,54 +1187,54 @@
"description": "Embeds for streaming", "description": "Embeds for streaming",
"seo_description": "Create embeds for streaming World of Tanks Blitz with extreme customization", "seo_description": "Create embeds for streaming World of Tanks Blitz with extreme customization",
"coming_soon": "More embeds coming soon.", "coming_soon": "More embeds coming soon.",
"suggest": "Suggest ideas.", "suggest": "Sugerir ideas.",
"preview": { "preview": {
"title": "Example preview", "title": "Example preview",
"upload": "Upload test background" "upload": "Upload test background"
}, },
"configuration": { "configuration": {
"import": { "import": {
"title": "Import", "title": "Importar",
"description": "Paste your current URL if you have one already to import your settings", "description": "Pega tu URL actual si ya tienes una para importar la configuración",
"hint": "Paste URL...", "hint": "Pegar URL...",
"apply": "Apply", "apply": "Aplicar",
"idiot_title": "Invalid URL", "idiot_title": "URL inválida",
"idiot_description": "Try pasting the URL that BlitzKit previously generated, you silly goose!", "idiot_description": "Intenta pegar la URL que BlitzKit generó anteriormente, ¡Torpe!",
"idiot_button": "Okay, my bad" "idiot_button": "Okay, my bad"
}, },
"export": { "export": {
"title": "Export", "title": "Exportar",
"description": "Copy all properties for you streaming software", "description": "Copiar todas las propiedades para tu software de streaming",
"generate": { "generate": {
"button": "Generate URL", "button": "Generar URL",
"title": "Generate URL", "title": "Generar URL",
"subtitle": "Search an account to track", "subtitle": "Buscar una cuenta para seguir",
"cancel": "Cancel", "cancel": "Cancelar",
"success": { "success": {
"title": "Copy URL", "title": "Copiar URL",
"info": "Generated the URL for %s1. The embed will start tracking as soon as the URL is pasted. Reset at any time by right-clicking on PC or long-pressing on mobile and then selecting \"Reset\".", "info": "Se generó la URL para %s1. El embebido comenzará a rastrear tan pronto como se pegue. Restablece en cualquier momento haciendo clic derecho en PC o manteniendo presionado en móvil y luego seleccionando \"Restablecer\".",
"back": "Volver", "back": "Volver",
"copy": "Copy URL" "copy": "Copiar URL"
} }
}, },
"css": "Copy CSS", "css": "Copiar CSS",
"width": "Copy Width", "width": "Copiar ancho",
"height": "Copy Height", "height": "Copiar altura",
"framerate": "Copy Framerate" "framerate": "Copy Framerate"
}, },
"customize": { "customize": {
"title": "Customize", "title": "Personalizar",
"reset": "Restablecer", "reset": "Restablecer",
"description": "Bells and whistles of your embed" "description": "Bells and whistles of your embed"
} }
}, },
"types": { "types": {
"breakdown": { "breakdown": {
"name": "Breakdown", "name": "Desglose",
"options": { "options": {
"width": "Ancho", "width": "Ancho",
"height": "Altura", "height": "Altura",
"showTotal": "Show total", "showTotal": "Mostrar total",
"listGap": "List gap", "listGap": "List gap",
"listMaxTanks": "Max tanks", "listMaxTanks": "Max tanks",
"cardRadius": "Card radius", "cardRadius": "Card radius",
@@ -1189,25 +1245,25 @@
"cardTitleClassIcon": "Card title class icon", "cardTitleClassIcon": "Card title class icon",
"cardBodyBackgroundColor": "Card body background color", "cardBodyBackgroundColor": "Card body background color",
"cardBodyPadding": "Card body padding", "cardBodyPadding": "Card body padding",
"columnGap": "Column gap", "columnGap": "Espacio entre columnas",
"columnValue": "Column value", "columnValue": "Valor de columna",
"columnLabel": "Column label", "columnLabel": "Etiqueta de columna",
"column1": "Column 1", "column1": "Columna 1",
"column2": "Column 2", "column2": "Columna 2",
"column3": "Column 3", "column3": "Columna 3",
"column4": "Column 4", "column4": "Columna 4",
"column1CustomLabel": "Column 1 label", "column1CustomLabel": "Etiqueta de la columna 1",
"column2CustomLabel": "Column 2 label", "column2CustomLabel": "Etiqueta de la columna 2",
"column3CustomLabel": "Column 3 label" "column3CustomLabel": "Etiqueta de la columna 3"
} }
} }
} }
}, },
"charts": { "charts": {
"name": "Charts", "name": "Gráficos",
"button": "Nerd out", "button": "Nerd out",
"description": "Lots of graphs", "description": "Lots of graphs",
"seo_description": "Charts and graphs on anything and everything about tanks, players, and events in World of Tanks Blitz" "seo_description": "Gráficos y tablas sobre todo lo relacionado con tanques, jugadores y eventos en World of Tanks Blitz"
}, },
"rating": { "rating": {
"name": "Rating", "name": "Rating",
@@ -1218,11 +1274,11 @@
"discord": { "discord": {
"name": "Discord bot", "name": "Discord bot",
"button": "Install now", "button": "Install now",
"description": "Stats right in Discord", "description": "Estadísticas en Discord",
"seo_description": "Get stats right in Discord with BlitzKit's Discord bot" "seo_description": "Obtén estadísticas en Discord con el bot de Discord de BlitzKit"
}, },
"more": { "more": {
"name": "More coming soon", "name": "Más próximamente",
"button": "Join Discord", "button": "Join Discord",
"description": "What we're making", "description": "What we're making",
"seo_description": "What we're making with BlitzKit" "seo_description": "What we're making with BlitzKit"
@@ -1241,7 +1297,7 @@
}, },
"blitz_analysis": { "blitz_analysis": {
"name": "BlitzAnalysis[]", "name": "BlitzAnalysis[]",
"button": "Analyze now", "button": "Analizar ahora",
"description": "Rich historic average stats", "description": "Rich historic average stats",
"seo_description": "Rich historic average stats in World of Tanks Blitz" "seo_description": "Rich historic average stats in World of Tanks Blitz"
}, },
@@ -1253,19 +1309,19 @@
} }
}, },
"footer": { "footer": {
"motto": "Everything World of Tanks Blitz", "motto": "Todo sobre World of Tanks Blitz",
"copyright": "Unaffiliated with Wargaming or any service", "copyright": "No afiliado con Wargaming u otros servicios",
"about": { "about": {
"title": "About", "title": "About",
"credits": "Credits", "credits": "Credits",
"discord": "Discord", "discord": "Discord",
"github": "GitHub", "github": "GitHub",
"patches": "Patches" "patches": "Parches"
}, },
"legal": { "legal": {
"title": "Legal", "title": "Legal",
"privacy": "Privacy policy", "privacy": "Política de Privacidad",
"terms": "Terms of service" "terms": "Términos del servicio"
} }
} }
} }
+77 -21
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",
@@ -129,9 +131,9 @@
"asia": "Asie-Pacifique" "asia": "Asie-Pacifique"
}, },
"short": { "short": {
"com": "NA", "com": "Amérique du Nord",
"eu": "Europe", "eu": "Europe",
"asia": "APAC" "asia": "Asie-Pacifique"
} }
}, },
"leagues": { "leagues": {
@@ -350,7 +352,7 @@
} }
}, },
"body": { "body": {
"subtitle": "Research", "subtitle": "Recherche",
"total": "Total", "total": "Total",
"research": "Recherche: %s1", "research": "Recherche: %s1",
"upgrades": "Améliorations : %s1", "upgrades": "Améliorations : %s1",
@@ -377,7 +379,7 @@
"body": "# Commandes\n\nBlitzKit offre les commandes suivantes :\n\n" "body": "# Commandes\n\nBlitzKit offre les commandes suivantes :\n\n"
}, },
"embeds": { "embeds": {
"name": "embeds", "name": "intègre",
"description": "How embeds work" "description": "How embeds work"
}, },
"introduction": { "introduction": {
@@ -457,7 +459,7 @@
"body": { "body": {
"cards": { "cards": {
"games": { "games": {
"title": "Games", "title": "Parties",
"winrate": "Taux de victoires", "winrate": "Taux de victoires",
"battles": "Batailles", "battles": "Batailles",
"wins_losses": "Victoires/Défaites" "wins_losses": "Victoires/Défaites"
@@ -505,45 +507,45 @@
"description": "Search clans", "description": "Search clans",
"options": { "options": {
"limit": { "limit": {
"name": "limit", "name": "limite",
"description": "The max number of clan results (default: %s1)" "description": "The max number of clan results (default: %s1)"
} }
}, },
"body": { "body": {
"title": "Clan search for %s1 in region %s2", "title": "Clan search for %s1 in region %s2",
"no_results": "No clans found" "no_results": "Pas de clan trouvé"
} }
}, },
"search_players": { "search_players": {
"name": "search-players", "name": "recherche de joueur",
"description": "Search players", "description": "Recherche des joueurs",
"options": { "options": {
"limit": { "limit": {
"name": "limit", "name": "limite",
"description": "The max number of player results (default: %s1)" "description": "Le nombre maximum de résultats de joueur (par défaut: %s1)"
} }
}, },
"body": { "body": {
"title": "Player search for %s1 in region %s2", "title": "Recherche de %s1 dans la région %s2",
"no_results": "No players found" "no_results": "Pas de joueur de trouvé"
} }
}, },
"rating_leaderboard": { "rating_leaderboard": {
"name": "rating-leaderboard", "name": "Classement de côté",
"description": "Rating battles statistics", "description": "Statistiques des batailles de cotés",
"subcommands": { "subcommands": {
"neighbors": { "neighbors": {
"name": "neighbors", "name": "neighbors",
"description": "Neighboring players on the leaderboard" "description": "Neighboring players on the leaderboard"
}, },
"league": { "league": {
"name": "league", "name": "ligue",
"description": "Top players of a league" "description": "Top players of a league"
} }
}, },
"options": { "options": {
"limit": { "limit": {
"name": "limit", "name": "limite",
"description": "How many neighbors to display (default: %s1)" "description": "How many neighbors to display (default: %s1)"
}, },
"season": { "season": {
@@ -554,7 +556,7 @@
} }
}, },
"league": { "league": {
"name": "league", "name": "ligue",
"description": "The league to display" "description": "The league to display"
} }
}, },
@@ -572,7 +574,7 @@
"description": "Today's played tanks and statistics" "description": "Today's played tanks and statistics"
}, },
"stats": { "stats": {
"name": "stats", "name": "statistiques",
"description": "Quick statistics for a period" "description": "Quick statistics for a period"
}, },
"owned_tanks": { "owned_tanks": {
@@ -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"
@@ -665,6 +671,7 @@
"copied": "Copied!" "copied": "Copied!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Search tanks...", "search_bar_hint": "Search tanks...",
"recent": "Recently viewed", "recent": "Recently viewed",
"select_all": "Select all", "select_all": "Select all",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "By %s1 ❤️" "credit": "By %s1 ❤️"
}, },
@@ -744,14 +756,58 @@
"help_translate": "Please help translate %s1 to %s2!", "help_translate": "Please help translate %s1 to %s2!",
"seo_description": "Tools for everything World of Tanks Blitz" "seo_description": "Tools for everything World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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",
@@ -1092,7 +1148,7 @@
"lookup": "Look up a player to get started", "lookup": "Look up a player to get started",
"hint": "Search players...", "hint": "Search players...",
"searching": "Searching...", "searching": "Searching...",
"no_results": "No players found" "no_results": "Pas de joueur de trouvé"
}, },
"controls": { "controls": {
"title": "Tracking %s1", "title": "Tracking %s1",
+200 -144
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"
@@ -665,15 +671,16 @@
"copied": "コピーしました!" "copied": "コピーしました!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "車輌名を入力…", "search_bar_hint": "車輌名を入力…",
"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": {
@@ -686,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": "通常弾貫通力",
@@ -697,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": "馬力",
@@ -709,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": "降順"
} }
@@ -731,27 +738,76 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "By %s1 ❤️" "credit": "By %s1 ❤️"
}, },
"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": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
}, },
"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": "ハルダウン",
@@ -783,7 +839,7 @@
"normalization": "標準化", "normalization": "標準化",
"ricochet": "跳弾角度", "ricochet": "跳弾角度",
"explosion_radius": "爆風半径", "explosion_radius": "爆風半径",
"exit": "決定", "exit": "終了",
"reset": "リセット" "reset": "リセット"
}, },
"advanced": "高度なハイライト", "advanced": "高度なハイライト",
@@ -940,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": "視認範囲",
@@ -968,7 +1024,7 @@
"height": "全高", "height": "全高",
"length": "車体長", "length": "車体長",
"volume": "体積", "volume": "体積",
"shellRange": "射程範囲", "shellRange": "射程",
"shellCapacity": "総弾数", "shellCapacity": "総弾数",
"gunType": "主砲タイプ", "gunType": "主砲タイプ",
"penetrationAt250m": "250m での貫通力" "penetrationAt250m": "250m での貫通力"
+57 -1
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"
@@ -665,6 +671,7 @@
"copied": "Copied!" "copied": "Copied!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Search tanks...", "search_bar_hint": "Search tanks...",
"recent": "Recently viewed", "recent": "Recently viewed",
"select_all": "Select all", "select_all": "Select all",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "By %s1 ❤️" "credit": "By %s1 ❤️"
}, },
@@ -744,14 +756,58 @@
"help_translate": "Please help translate %s1 to %s2!", "help_translate": "Please help translate %s1 to %s2!",
"seo_description": "Tools for everything World of Tanks Blitz" "seo_description": "Tools for everything World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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",
+57 -1
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"
@@ -665,6 +671,7 @@
"copied": "Copiado!" "copied": "Copiado!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Procurar tanques...", "search_bar_hint": "Procurar tanques...",
"recent": "Visto recentemente", "recent": "Visto recentemente",
"select_all": "Selecionar todos", "select_all": "Selecionar todos",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "Por %s1 ❤️" "credit": "Por %s1 ❤️"
}, },
@@ -744,14 +756,58 @@
"help_translate": "Por favor, ajude a traduzir %s1 para %s2!", "help_translate": "Por favor, ajude a traduzir %s1 para %s2!",
"seo_description": "Ferramentas para tudo World of Tanks Blitz" "seo_description": "Ferramentas para tudo World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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",
+61 -5
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": "Барабан",
@@ -36,7 +38,7 @@
"local": "dev", "local": "dev",
"dev": "бета", "dev": "бета",
"opentest": "открытый тест", "opentest": "открытый тест",
"preview": "предварительный просмотр" "preview": "превью"
}, },
"locales": { "locales": {
"en": "Английский", "en": "Английский",
@@ -651,6 +653,10 @@
} }
}, },
"website": { "website": {
"redirect": {
"title": "301: перемещено навсегда",
"body": "Эта страница перемещена. Перенаправление..."
},
"settings": { "settings": {
"dev_mode": "Режим разработчика", "dev_mode": "Режим разработчика",
"language": "Язык" "language": "Язык"
@@ -665,6 +671,7 @@
"copied": "Скопировано!" "copied": "Скопировано!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Сбросить фильтры",
"search_bar_hint": "Поиск танков...", "search_bar_hint": "Поиск танков...",
"recent": "Недавние", "recent": "Недавние",
"select_all": "Выбрать всё", "select_all": "Выбрать всё",
@@ -716,7 +723,7 @@
"label": "Сортировка", "label": "Сортировка",
"fire": "Стрельба", "fire": "Стрельба",
"maneuverability": "Манёвренность", "maneuverability": "Манёвренность",
"survivability": "Живучесть" "survivability": "Выживаемость"
}, },
"direction": { "direction": {
"label": "Направление", "label": "Направление",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Присоединяйтесь к крутым ребятам!",
"join_long": "Присоединяйся к супер-дупер крутым ребятам!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "От %s1 ❤️" "credit": "От %s1 ❤️"
}, },
@@ -744,14 +756,58 @@
"help_translate": "Пожалуйста, помогите перевести %s1 на %s2!", "help_translate": "Пожалуйста, помогите перевести %s1 на %s2!",
"seo_description": "Инструменты для World of Tanks Blitz" "seo_description": "Инструменты для World of Tanks Blitz"
}, },
"docs": {
"patches": {
"name": "Списки изменений BlitzKit",
"seo_description": "Список изменений для бота Discord и сайта BlitzKit"
}
},
"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": "За холмом",
@@ -975,7 +1031,7 @@
} }
}, },
"firepower": { "firepower": {
"title": "Огневая мощь" "title": "Стрельба"
}, },
"crew": { "crew": {
"title": "Мастерство экипажа", "title": "Мастерство экипажа",
@@ -991,7 +1047,7 @@
"title": "Манёвренность" "title": "Манёвренность"
}, },
"survivability": { "survivability": {
"title": "Живучесть" "title": "Выживаемость"
} }
}, },
"compare": { "compare": {
+78 -22
View File
@@ -9,8 +9,10 @@
"m": "%s1м", "m": "%s1м",
"mm": "%s1мм", "mm": "%s1мм",
"deg": "%s1°", "deg": "%s1°",
"hp": "%s1hp", "hp": "%s1хп",
"x": "x%s1" "x": "х%s1",
"percentage": "%s1%",
"deg_s": "%s1°/s"
}, },
"gun_types": { "gun_types": {
"auto_loader": "Магазинна система заряджання", "auto_loader": "Магазинна система заряджання",
@@ -86,14 +88,14 @@
"other": "Збірна нація" "other": "Збірна нація"
}, },
"nations_adjectives": { "nations_adjectives": {
"ussr": "Радянська", "ussr": "Радянський",
"germany": "Німецька", "germany": "Німецький",
"usa": "Американська", "usa": "Американський",
"china": "Китайська", "china": "Китайський",
"uk": "Британська", "uk": "Британський",
"france": "Французька", "france": "Французький",
"japan": "Японська", "japan": "Японський",
"european": "Європейська", "european": "Європейський",
"other": "Гібрид" "other": "Гібрид"
}, },
"tank_class_short": { "tank_class_short": {
@@ -184,11 +186,11 @@
"common": { "common": {
"errors": { "errors": {
"clan_not_found": "# Не вдалося знайти клан\nНе вдалося знайти клан \"%s1\". Спробуйте вибрати клан з пошукового результату.", "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Не вдалось знайти танк за ID \"%s1\". Спробуйте ввести назву танка замість числа.",
"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Цей гравець не має статистики.\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": "# Ця команда є в попередньому перегляді\n\nВи можете отримати доступ лише до цієї команди на [офіційному сервері Discord](https://discord.gg/nDt7AjGJQH). Команда в цілому буде доступна найближчим часом.", "preview": "# Ця команда є в попередньому перегляді\n\nВи можете отримати доступ лише до цієї команди на [офіційному сервері Discord](https://discord.gg/nDt7AjGJQH). Команда в цілому буде доступна найближчим часом.",
@@ -363,8 +365,8 @@
"tier_1": "# %s1 це рівень I\n\nТанки рівню I завжди відкриті для всіх гравців безкоштовно.", "tier_1": "# %s1 це рівень I\n\nТанки рівню I завжди відкриті для всіх гравців безкоштовно.",
"already_researched": "# %s1 уже досліджено!\n\nСпробуйте забезпечити `starting-tank` коли використовуєте команду щоб подивитись підсумки гілки, яку ви вже дослідили.", "already_researched": "# %s1 уже досліджено!\n\nСпробуйте забезпечити `starting-tank` коли використовуєте команду щоб подивитись підсумки гілки, яку ви вже дослідили.",
"start_end_equal": "# %s1 було надано двічі\n\nПереконайся, що `starting-tank` та `target-tank` різні.", "start_end_equal": "# %s1 було надано двічі\n\nПереконайся, що `starting-tank` та `target-tank` різні.",
"tanks_not_on_line": "# %s1 and %s2 are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.", "tanks_not_on_line": ".",
"unordered": "# %s1 higher tiered to %s2\n\nMake sure to provide %s3 as the `starting-tank` instead as it is the lower tiered tank." "unordered": ""
} }
}, },
"about": { "about": {
@@ -399,8 +401,8 @@
} }
}, },
"breakdown": { "breakdown": {
"name": "breakdown", "name": "аналіз",
"description": "A period's breakdown by tanks played", "description": "Аналіз періоду за зіграними танками",
"body": { "body": {
"total": "Загалом", "total": "Загалом",
"battles": "Бої", "battles": "Бої",
@@ -511,7 +513,7 @@
}, },
"body": { "body": {
"title": "Clan search for %s1 in region %s2", "title": "Clan search for %s1 in region %s2",
"no_results": "No clans found" "no_results": "Жодного клану не знайдено"
} }
}, },
"search_players": { "search_players": {
@@ -544,7 +546,7 @@
"options": { "options": {
"limit": { "limit": {
"name": "ліміт", "name": "ліміт",
"description": "How many neighbors to display (default: %s1)" "description": ""
}, },
"season": { "season": {
"name": "season", "name": "season",
@@ -594,7 +596,7 @@
} }
}, },
"ping": { "ping": {
"name": "ping", "name": "",
"description": "Check wether the bot is alive.", "description": "Check wether the bot is alive.",
"body": { "body": {
"pong": "Pong 🏓", "pong": "Pong 🏓",
@@ -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": "Мова"
@@ -665,6 +671,7 @@
"copied": "Скопійовано!" "copied": "Скопійовано!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "Шукайте техніку...", "search_bar_hint": "Шукайте техніку...",
"recent": "Недавно переглянуті", "recent": "Недавно переглянуті",
"select_all": "Вибрати все", "select_all": "Вибрати все",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "Зроблено %s1 ❤" "credit": "Зроблено %s1 ❤"
}, },
@@ -744,14 +756,58 @@
"help_translate": "Будь ласка, допоможіть перекласти %s1 на %s2!", "help_translate": "Будь ласка, допоможіть перекласти %s1 на %s2!",
"seo_description": "Інструменти для всього, пов'язаного з WoT Blitz" "seo_description": "Інструменти для всього, пов'язаного з WoT Blitz"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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": "Від башти",
+81 -25
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": "語言"
@@ -665,6 +671,7 @@
"copied": "已複製!" "copied": "已複製!"
}, },
"tank_search": { "tank_search": {
"clear_filters": "Clear filters",
"search_bar_hint": "搜尋戰車....", "search_bar_hint": "搜尋戰車....",
"recent": "最近查看", "recent": "最近查看",
"select_all": "選擇全部", "select_all": "選擇全部",
@@ -731,6 +738,11 @@
} }
}, },
"home": { "home": {
"discord": {
"join_short": "Join cool people!",
"join_long": "Join super duper cool people!",
"action": "Discord"
},
"hero": { "hero": {
"credit": "由 %s1 製作❤️" "credit": "由 %s1 製作❤️"
}, },
@@ -744,17 +756,61 @@
"help_translate": "請幫忙將 %s1 翻譯成 %s2!", "help_translate": "請幫忙將 %s1 翻譯成 %s2!",
"seo_description": "戰車世界閃擊戰 全方位工具" "seo_description": "戰車世界閃擊戰 全方位工具"
}, },
"docs": {
"patches": {
"name": "BlitzKit Changelogs",
"seo_description": "Changelogs for BlitzKit Discord bot and website"
}
},
"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": "戰車下部",
"face_hug": "面部色调", "face_hug": "面部色调",
"default": "預設" "default": "預設"
}, },
@@ -798,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%機率擊穿"
} }
} }
@@ -897,21 +953,21 @@
"shell_index": "炮弹 %s1", "shell_index": "炮弹 %s1",
"at_distance": "在 %s1m", "at_distance": "在 %s1m",
"at_distance_slider_label": "距离", "at_distance_slider_label": "距离",
"dispersion_at_distance": "%s1米的散射度", "dispersion_at_distance": "%s1公尺擴散度",
"gun_flexibility": "炮控灵活度", "gun_flexibility": "炮控灵活度",
"speed": "速度", "speed": "速度",
"terrain_coefficients": "地势系数", "terrain_coefficients": "地势系数",
"raw_terrain_coefficients": "原始地形系数", "raw_terrain_coefficients": "原始地形系数",
"power_to_weight_ratio": "推重比", "power_to_weight_ratio": "推重比",
"hull_traverse_speed": "炮塔旋转速度", "hull_traverse_speed": "炮塔旋转速度",
"camouflage": "伪装", "camouflage": "偽裝",
"reload": "裝填", "reload": "裝填",
"crewCount": "乘员人数", "crewCount": "乘员人数",
"shellNormalization": "轉正", "shellNormalization": "轉正",
"shellRicochet": "跳彈", "shellRicochet": "跳彈",
"dpm": "每分钟伤害", "dpm": "每分鍾傷害血量",
"dpmEffective": "60秒内生效", "dpmEffective": "60秒内生效",
"shells": "炮弹 ", "shells": "砲彈",
"mostOptimalShellIndex": "最优炮弹", "mostOptimalShellIndex": "最优炮弹",
"shellReloads": "炮弹重装", "shellReloads": "炮弹重装",
"shellReload": "炮弹重装", "shellReload": "炮弹重装",
@@ -1040,19 +1096,19 @@
"performance": { "performance": {
"name": "性能表现", "name": "性能表现",
"button": "查看坦克", "button": "查看坦克",
"description": "坦克性能统计", "description": "戰車性能統計",
"seo_description": "最好的坦克及其在世界坦克闪电战中的表现", "seo_description": "最好的戰車及其在戰車世界閃擊戰中的表現",
"estimation": { "estimation": {
"body": "基于 %s1个玩家的估计数据。更新 %s2 之前。", "body": "基于 %s1个玩家的估计数据。更新 %s2 之前。",
"hours": "%s1 小时", "hours": "%s1 小時",
"minutes": "%s1 分钟" "minutes": "%s1 分鐘"
}, },
"player_count": { "player_count": {
"label": "玩家数量" "label": "玩家数量"
}, },
"table": { "table": {
"tanks": { "tanks": {
"header": "坦克", "header": "戰車",
"total": "全部" "total": "全部"
}, },
"stats": { "stats": {
@@ -1068,15 +1124,15 @@
"hits": "命中數", "hits": "命中數",
"damage_ratio": "伤害效率", "damage_ratio": "伤害效率",
"damage_taken": "伤害值", "damage_taken": "伤害值",
"capture_points": "占领值" "capture_points": "佔領點數"
} }
} }
}, },
"gallery": { "gallery": {
"name": "图库", "name": "圖庫",
"button": "浏览全部", "button": "瀏覽所有",
"description": "Blitz玩家头像", "description": "Blitz 玩家頭像",
"seo_description": "所有坦克闪电战玩家头像", "seo_description": "所有戰車世界閃擊戰玩家頭像",
"last_updated": "最後更新於 %s1", "last_updated": "最後更新於 %s1",
"search": { "search": {
"hint": "搜尋頭像……", "hint": "搜尋頭像……",
@@ -1131,17 +1187,17 @@
"description": "串流嵌入功能", "description": "串流嵌入功能",
"seo_description": "創建具有極高自訂化的《戰車世界:閃擊戰》串流嵌入功能", "seo_description": "創建具有極高自訂化的《戰車世界:閃擊戰》串流嵌入功能",
"coming_soon": "更多嵌入功能即將推出。", "coming_soon": "更多嵌入功能即將推出。",
"suggest": "建议与想法", "suggest": "建議與想法。",
"preview": { "preview": {
"title": "示例预览", "title": "範例",
"upload": "上传测试背景" "upload": "上傳測試背景"
}, },
"configuration": { "configuration": {
"import": { "import": {
"title": "导入", "title": "導入",
"description": "如果您已经有一个要导入您的设置,请粘贴您当前的 URL", "description": "如果您已经有一个要导入您的设置,请粘贴您当前的 URL",
"hint": "粘贴链接...", "hint": "貼上 URL……",
"apply": "应用", "apply": "套用",
"idiot_title": "無效的 URL", "idiot_title": "無效的 URL",
"idiot_description": "試著貼上 BlitzKit 先前生成的網址吧,你這隻傻鵝!", "idiot_description": "試著貼上 BlitzKit 先前生成的網址吧,你這隻傻鵝!",
"idiot_button": "好吧,我的錯" "idiot_button": "好吧,我的錯"
+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;
+104 -9
View File
@@ -22,6 +22,7 @@ import {
ResearchCost, ResearchCost,
ShellType, ShellType,
SkillDefinitions, SkillDefinitions,
slugify,
TankClass, TankClass,
TankDefinitions, TankDefinitions,
TankPrice, TankPrice,
@@ -48,6 +49,18 @@ import { DATA } from './constants';
import { Avatar } from './skillIcons'; import { Avatar } from './skillIcons';
import { TankParameters } from './tankIcons'; import { TankParameters } from './tankIcons';
const nationSlugDiscriminators = {
china: 'cn',
european: 'eu',
france: 'fr',
germany: 'de',
japan: 'jp',
other: 'ot',
uk: 'gb',
usa: 'us',
ussr: 'ru',
};
function parseResearchCost(raw: number | string) { function parseResearchCost(raw: number | string) {
if (typeof raw === 'number') { if (typeof raw === 'number') {
return { return {
@@ -502,7 +515,7 @@ const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
HIGH_EXPLOSIVE: ShellType.HE, HIGH_EXPLOSIVE: ShellType.HE,
HOLLOW_CHARGE: ShellType.HEAT, HOLLOW_CHARGE: ShellType.HEAT,
}; };
export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU(R?)))$/; export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = { const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = {
chassis: ModuleType.TRACKS, chassis: ModuleType.TRACKS,
engine: ModuleType.ENGINE, engine: ModuleType.ENGINE,
@@ -703,6 +716,88 @@ export async function definitions() {
}; };
}); });
const slugRequesters = new Map<string, { id: number; key: string }[]>();
const idToNation: Record<number, string> = {};
await Promise.all(
nations.map(async (nation) => {
const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`,
);
for (const tankKey in tankList.root) {
if (botPattern.test(tankKey)) continue;
const tank = tankList.root[tankKey];
const tankId = toUniqueId(nation, tank.id);
const name = (
(tank.shortUserString
? getString(tank.shortUserString)
: undefined) ?? getString(tank.userString)
).locales.en;
const slug = slugify(name);
idToNation[tankId] = nation;
if (slugRequesters.has(slug)) {
slugRequesters.get(slug)!.push({ id: tankId, key: tankKey });
} else {
slugRequesters.set(slug, [{ id: tankId, key: tankKey }]);
}
}
}),
);
const slugs = new Map<number, string>();
slugRequesters.forEach((requesters, slug) => {
if (requesters.length === 1) {
slugs.set(requesters[0].id, slug);
return;
}
console.warn(
`Multiple tanks share slug ${slug}: ${requesters.map(({ key }) => key).join(', ')}`,
);
if (requesters.length !== 2) {
throw new Error('Unresolvable number of duplicates :(');
}
const nonCanonical = requesters.find(({ key }) => key.endsWith('TUR'));
if (nonCanonical === undefined) {
console.log('Using nations to discriminate');
// both are non-tutorial tanks, will have to discriminate using nation
requesters.forEach(({ id, key }) => {
const nation = idToNation[id];
const discriminator =
nationSlugDiscriminators[
nation as keyof typeof nationSlugDiscriminators
];
console.log(`Solution: ${key} -> ${slug}-${discriminator}`);
slugs.set(id, `${slug}-${discriminator}`);
});
} else {
console.log('Using tutorial bot suffix to discriminate');
const canonical = requesters.find(({ key }) => !key.endsWith('TUR'));
if (canonical === undefined) {
throw new Error(
'Two tutorial bots share the same slug? The world is truly broken.',
);
}
console.log(`Solution: ${canonical.key} -> ${slug}`);
slugs.set(canonical.id, slug);
console.log(`Solution: ${nonCanonical.key} -> ${slug}-tur`);
slugs.set(nonCanonical.id, `${slug}-tur`);
}
});
await Promise.all( await Promise.all(
nations.map(async (nation) => { nations.map(async (nation) => {
const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>( const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>(
@@ -787,6 +882,13 @@ export async function definitions() {
const hullArmor: Armor = { spaced: [], thickness: {} }; const hullArmor: Armor = { spaced: [], thickness: {} };
const equipment = tankDefinition.root.optDevicePreset; const equipment = tankDefinition.root.optDevicePreset;
tankStringIdMap[`${nation}:${tankKey}`] = tankId; tankStringIdMap[`${nation}:${tankKey}`] = tankId;
const slug = slugs.get(tankId);
if (slug === undefined) {
throw new Error(
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
);
}
if (tank.sellPrice) { if (tank.sellPrice) {
tankPrice = { tankPrice = {
@@ -903,7 +1005,7 @@ export async function definitions() {
(tank.shortUserString (tank.shortUserString
? getString(tank.shortUserString) ? getString(tank.shortUserString)
: undefined) ?? getString(tank.userString), : undefined) ?? getString(tank.userString),
name_full: getString(tank.userString), slug,
nation, nation,
type: tankTags.includes('collectible') type: tankTags.includes('collectible')
? TankType.COLLECTOR ? TankType.COLLECTOR
@@ -939,13 +1041,6 @@ export async function definitions() {
}); });
} }
if (
tankDefinitions.tanks[tankId].name ===
tankDefinitions.tanks[tankId].name_full
) {
delete tankDefinitions.tanks[tankId].name_full;
}
modelDefinitions.models[tankId] = { modelDefinitions.models[tankId] = {
armor: hullArmor, armor: hullArmor,
turret_origin: vector3TupleToBlitzkit(turretOrigin), turret_origin: vector3TupleToBlitzkit(turretOrigin),
@@ -0,0 +1,90 @@
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { extname } from 'path';
import ProgressBar from 'progress';
import { commitAssets } from '../core/github/commitAssets';
import { FileChange } from '../core/github/commitMultipleFiles';
export async function glossary() {
console.log('Building glossary...');
const avatars: Record<string, { avatar: Avatar; url: string }> = {};
await Promise.all(
locales.supported.map(async (supported) => {
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
console.log(
`Found ${Object.keys(glossary).length} things for ${supported.locale}`,
);
for (const key in glossary) {
const glossaryEntry = glossary[key];
if (
!key.startsWith('avatar') ||
key.endsWith('_part') ||
glossaryEntry.image_url === null
) {
continue;
}
if (key in avatars) {
avatars[key].avatar.name.locales[supported.locale] =
glossaryEntry.title;
} else {
const extension = extname(glossaryEntry.image_url);
avatars[key] = {
url: glossaryEntry.image_url,
avatar: {
id: key,
name: { locales: { [supported.locale]: glossaryEntry.title } },
extension,
},
};
}
}
}),
);
const changes: FileChange[] = [];
const gallery: Gallery = { avatars: [] };
const totalCount = Object.keys(avatars).length;
const bar = new ProgressBar(
`Fetching avatars of ${totalCount} things :bar`,
totalCount,
);
await Promise.all(
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
if (!(locales.default in avatars[key].avatar.name.locales)) {
console.warn(`Avatar ${key} has no ${locales.default} name`);
bar.tick();
return;
}
gallery.avatars.push(avatar);
const content = await fetch(url).then((response) =>
response.arrayBuffer(),
);
changes.push({
path: `gallery/avatars/${key}${avatar.extension}`,
content: Buffer.from(content),
});
bar.tick();
}),
);
changes.push({
path: 'definitions/gallery.pb',
content: encodePBBuffer(Gallery, gallery),
});
await commitAssets('glossary', changes);
}
@@ -18,7 +18,10 @@ import { definitions } from './definitions';
import { equipmentIcons } from './equipmentIcons'; import { equipmentIcons } from './equipmentIcons';
import { flags } from './flags'; import { flags } from './flags';
import { gameModeBanners } from './gameModeBanners'; import { gameModeBanners } from './gameModeBanners';
import { glossary } from './glossary';
import { migration } from './migration';
import { moduleIcons } from './moduleIcons'; import { moduleIcons } from './moduleIcons';
import { popularTanks } from './popularTanks';
import { shellIcons } from './shellIcons'; import { shellIcons } from './shellIcons';
import { skillIcons } from './skillIcons'; import { skillIcons } from './skillIcons';
import { tankArmors } from './tankArmors'; import { tankArmors } from './tankArmors';
@@ -28,6 +31,7 @@ import { tankModels } from './tankModels';
if (!targets && !allTargets) throw new Error('No target(s) specified'); if (!targets && !allTargets) throw new Error('No target(s) specified');
const methods = [ const methods = [
migration,
definitions, definitions,
tankModels, tankModels,
tankArmors, tankArmors,
@@ -43,6 +47,8 @@ const methods = [
boosterIcons, boosterIcons,
tankIcons, tankIcons,
blitzkitTankIcons, blitzkitTankIcons,
popularTanks,
glossary,
]; ];
for (const method of methods) { for (const method of methods) {
@@ -0,0 +1,38 @@
import { toUniqueId } from '@blitzkit/core';
import { readdir } from 'fs/promises';
import { readXMLDVPL } from '../core/blitz/readXMLDVPL';
import { commitAssets } from '../core/github/commitAssets';
import { DATA } from './constants';
import { VehicleDefinitionList } from './definitions';
export async function migration() {
console.log('Building migration map...');
const map: Record<string, number> = {};
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== 'common'),
);
await Promise.all(
nations.map(async (nation) => {
const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`,
);
for (const tankKey in tankList.root) {
const tank = tankList.root[tankKey];
const tankId = toUniqueId(nation, tank.id);
const davaKey = `${nation}:${tankKey}`;
map[davaKey] = tankId;
}
}),
);
await commitAssets('migration', [
{
path: 'definitions/migration.json',
content: Buffer.from(JSON.stringify(map)),
},
]);
}
@@ -0,0 +1,76 @@
import {
assertSecret,
encodePBBuffer,
fetchTankDefinitions,
PopularTanks,
} from '@blitzkit/core';
import { google } from 'googleapis';
import { commitAssets } from '../core/github/commitAssets';
export async function popularTanks() {
const tankDefinitions = await fetchTankDefinitions();
const auth = await google.auth.getClient({
keyFile: import.meta.env.GOOGLE_APPLICATION_CREDENTIALS,
scopes: ['https://www.googleapis.com/auth/analytics.readonly'],
});
const analytics = google.analyticsdata({ version: 'v1beta', auth });
const report = await analytics.properties.runReport({
property: `properties/${assertSecret(import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID)}`,
requestBody: {
dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
dimensions: [{ name: 'pagePath' }],
metrics: [{ name: 'screenPageViews' }],
orderBys: [{ metric: { metricName: 'screenPageViews' }, desc: true }],
dimensionFilter: {
filter: {
fieldName: 'pagePath',
stringFilter: {
matchType: 'BEGINS_WITH',
value: '/tanks/',
},
},
},
},
});
if (!report.data.rows) {
throw new Error('No rows in report');
}
const tanks = report.data.rows
.filter(
(row) =>
row.dimensionValues &&
row.dimensionValues[0].value &&
row.dimensionValues[0].value !== '/tanks/' &&
row.metricValues &&
row.metricValues[0].value,
)
.map((row) => ({
id: Number(
row.dimensionValues![0].value!.match(
/\/tools\/tankopedia\/(\d+)\/?/,
)?.[1],
),
views: Number(row.metricValues![0].value!),
}))
.filter((row) => {
if (!(row.id in tankDefinitions.tanks)) {
console.warn('Skipping unknown popular tank', row.id);
return false;
}
return row.id in tankDefinitions.tanks;
})
.slice(0, 8)
.map(({ id, views }) => ({ id, views }));
const popularTanks: PopularTanks = { tanks };
await commitAssets('popular tanks', [
{
path: 'definitions/popular-tanks.pb',
content: encodePBBuffer(PopularTanks, popularTanks),
},
]);
}
+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);
} }
@@ -166,28 +166,9 @@ export async function extractModel(data: string, path: string) {
break; break;
case 'TransformComponent': { case 'TransformComponent': {
const translation = new Vector3(); node.setTranslation(component['tc.localTranslation']);
const rotation = new Quaternion(); node.setRotation(component['tc.localRotation']);
const scale = new Vector3(); node.setScale(component['tc.localScale']);
new Matrix4()
.multiplyMatrices(
new Matrix4().compose(
new Vector3().fromArray(component['tc.worldTranslation']),
new Quaternion().fromArray(component['tc.worldRotation']),
new Vector3().fromArray(component['tc.worldScale']),
),
new Matrix4().compose(
new Vector3().fromArray(component['tc.localTranslation']),
new Quaternion().fromArray(component['tc.localRotation']),
new Vector3().fromArray(component['tc.localScale']),
),
)
.decompose(translation, rotation, scale);
node.setTranslation(translation.toArray());
node.setRotation(rotation.toArray() as Vector4Tuple);
node.setScale(scale.toArray());
break; break;
} }
+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;
} }
Loaded 100 of 345 files, more files were not shown because too many files have changed in this diff. Show more