Compare commits

...
195 Commits
Author SHA1 Message Date
TrèsAbhi eed9d23646 fix: use root node modules 2025-12-01 16:58:18 -06:00
TrèsAbhi 2101dba7c6 New Crowdin updates (#184)
* New translations en.json (Russian)

* New translations en.json (Russian)

* New translations en.json (Russian)
2025-11-28 18:12:19 -06:00
TrèsAbhi 1b398a5f66 fix: initialize Tankopedia with model definitions for improved data handling 2025-11-28 12:55:55 -06:00
TrèsAbhi d8f9a2633d New Crowdin updates (#183)
* 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 (Ukrainian)

* New translations en.json (Chinese Simplified)
2025-11-27 21:53:42 -06:00
TrèsAbhi 2e79ccf7eb feat: update ts-proto executable handling to support multiple locations 2025-11-27 17:59:34 -06:00
TrèsAbhi be778acf39 feat: logs 2025-11-27 17:56:28 -06:00
TrèsAbhi 8d10d7cffa feat: integrate CompareCell component into TankRow and Tanks for improved performance metrics display 2025-11-27 17:48:58 -06:00
TrèsAbhi 5b9041a972 feat: performance tank table occupy more real estate 2025-11-27 17:34:29 -06:00
TrèsAbhi 1e60b1f61f fix: remove unused PerformanceInfo component from performance page 2025-11-27 17:33:44 -06:00
TrèsAbhi 13a636c023 fix: update playerCountPeriod to use "total" value 2025-11-27 17:33:05 -06:00
TrèsAbhi 8bc0693f3b fix: compare table occupy minimum width 2025-11-27 17:31:28 -06:00
TrèsAbhi 9b842c501c feat: update guessing game text for clarity 2025-11-27 17:26:10 -06:00
TrèsAbhi 8aadda4fb8 feat: add ToolOpenGraph component to guess page 2025-11-27 17:25:54 -06:00
TrèsAbhi 58c70f98e1 refactor: remove 'naked' prop from Controls and TankSandbox components 2025-11-27 17:24:12 -06:00
TrèsAbhi 54b73d11ce Merge branch 'main' into dev 2025-11-27 17:16:12 -06:00
TrèsAbhi d1ac5644a4 feat: logs 2025-11-27 14:14:18 -06:00
TrèsAbhi ae35c1516c Merge branch 'main' into fix-lighting 2025-11-27 14:12:38 -06:00
TrèsAbhi fd364d434f feat: hemispehre 2025-11-27 14:10:57 -06:00
TrèsAbhi fd37f72f8c feat: some simplification 2025-11-27 13:54:36 -06:00
TrèsAbhi 1427f61c52 feat: complete transition 2025-11-27 13:42:37 -06:00
TrèsAbhi cd4fa366a0 feat: requestedDisplay 2025-11-27 13:20:06 -06:00
TrèsAbhi 344e7caa81 feat: overhead lighting 2025-11-27 13:05:08 -06:00
TrèsAbhi fe7b2aea02 Add files via upload 2025-11-27 15:57:34 +00:00
TrèsAbhi fced1e96ef feat: remove transition skeleton 2025-11-26 21:10:54 -06:00
TrèsAbhi 778efb2372 feat: transiton and reveal 2025-11-26 21:10:03 -06:00
TrèsAbhi b67fd5b58c feat: new lighting 2025-11-26 20:48:25 -06:00
TrèsAbhi 2559782a28 fix: ground phasing through 2025-11-26 20:25:45 -06:00
TrèsAbhi efb479fece fix: vfs in core 2025-11-26 19:27:58 -06:00
TrèsAbhi fb829d4b81 Merge branch 'main' into dev 2025-11-26 19:22:48 -06:00
TrèsAbhi 91f4f2edcf Comment out unchanged change log statement
Comment out the log statement for unchanged changes.
2025-11-26 18:23:25 -06:00
TrèsAbhi a692d1ee0b Merge branch 'main' into dev 2025-11-26 13:58:44 -06:00
TrèsAbhi 31d2ab4746 feat: workflow 2025-11-26 13:44:45 -06:00
TrèsAbhi e4e2c30748 feat: logs 2025-11-26 13:42:43 -06:00
TrèsAbhi d633874d90 fix: path normalization 2025-11-26 13:38:40 -06:00
TrèsAbhi 9cb1d0cb3f fix: read dvpl files 2025-11-26 13:25:46 -06:00
TrèsAbhi a0bccc7973 feat: update all 2025-11-26 13:18:44 -06:00
TrèsAbhi 3efe807e35 feat: migrate definitiosn 2025-11-26 13:07:53 -06:00
TrèsAbhi 1cc15f64b0 feat: augment 2025-11-26 12:58:19 -06:00
TrèsAbhi f70864a0db feat: vfs file 2025-11-26 12:46:03 -06:00
TrèsAbhi 5de40b220f feat: rename 2025-11-26 12:34:26 -06:00
TrèsAbhi bd19c9aac9 Merge branch 'main' into fix-mangler 2025-11-26 12:28:32 -06:00
TrèsAbhi 6bc5b7dcb6 feat: .well-known dir 2025-11-26 12:22:15 -06:00
TrèsAbhi 00795eecdd feat: sort 2025-11-25 22:21:58 -06:00
TrèsAbhi f4e7b2ed98 feat: normalize path 2025-11-25 22:20:46 -06:00
TrèsAbhi 81612793e3 feat: manifest storing 2025-11-25 22:16:39 -06:00
TrèsAbhi d3bdbc39d2 feat: unified abstraction 2025-11-25 22:14:09 -06:00
TrèsAbhi 7cb67bd44b feat: steam client 2025-11-25 21:37:31 -06:00
TrèsAbhi 9df09c9a53 rm nm 2025-11-24 13:01:07 -06:00
TrèsAbhi a9f1d9ebec disable patches 2025-11-24 12:58:36 -06:00
TrèsAbhi 1b834eb848 just remove it 2025-11-24 12:46:32 -06:00
TrèsAbhi c5518ec9bc hide others 2025-11-24 12:45:39 -06:00
TrèsAbhi 8c705d7e2e root reserve 2025-11-24 12:45:05 -06:00
TrèsAbhi efe9f91a2d hide lvm 2025-11-24 12:44:33 -06:00
TrèsAbhi e84bf6b31c str 2025-11-24 12:44:01 -06:00
TrèsAbhi 46234b6cbb disable all 2025-11-24 12:43:02 -06:00
TrèsAbhi 0bda743a91 feat: reintroduce 2025-11-24 12:38:50 -06:00
TrèsAbhi b19866a1f5 feat: remove maximize-build-space 2025-11-24 12:35:45 -06:00
TrèsAbhi 9ca329e53f feat: start vfs 2025-11-24 11:02:18 -06:00
TrèsAbhi 47b1eb9ab0 feat: always use max build space 2025-11-20 12:45:57 -06:00
TrèsAbhi 6c8fbf7245 fix: use package node modules 2025-11-13 12:53:19 -06:00
TrèsAbhi 2ea22512d4 feat: new protos 2025-11-13 12:47:51 -06:00
TrèsAbhi 697d1fa1b4 Merge branch 'main' into dev 2025-11-13 12:40:59 -06:00
TrèsAbhi e4429f15bd feat: moar!! 2025-11-12 14:18:54 -06:00
TrèsAbhi cd8083ae30 feat: more patchnotes 2025-11-12 14:10:02 -06:00
TrèsAbhi 9dcf7441c9 feat: start of patch notes 2025-11-12 13:50:17 -06:00
TrèsAbhi d4e1f99ce2 fix: mk dir 2025-11-12 11:00:02 -06:00
TrèsAbhi 98de246578 mooooooove 2025-11-12 10:24:38 -06:00
TrèsAbhi 45097f198c debug 2025-11-12 10:23:22 -06:00
TrèsAbhi e063719caa debug 2025-11-12 10:22:27 -06:00
TrèsAbhi 975d579d21 New translations en.json (Russian) (#181) 2025-11-07 16:39:13 -06:00
TrèsAbhi b963ef0981 fix: name 2025-11-06 09:54:06 -06:00
TrèsAbhi 49fab21113 fix: use relative script 2025-11-06 09:52:47 -06:00
TrèsAbhi cbde48d41b fix: PUBLIC_ASSET_BASE 2025-11-06 09:40:11 -06:00
TrèsAbhi 1210baa545 fix: env type 2025-11-06 09:39:27 -06:00
TrèsAbhi 2c03b530d2 feat: group array 2025-11-06 09:37:14 -06:00
TrèsAbhi ec977899fb New translations en.json (Russian) (#180) 2025-11-05 14:44:13 -06:00
TrèsAbhi e5fc2faad7 Update youtubers.ts 2025-11-05 14:43:21 -06:00
TrèsAbhi 541dfc186b New Crowdin updates (#179)
* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)
2025-11-03 09:45:21 -06:00
TrèsAbhi 182471c4d6 feat: buildCatalogItemAccessor 2025-11-02 18:10:11 -06:00
TrèsAbhi e5c66cf232 Update isHalloween.ts 2025-10-31 15:07:27 -05:00
TrèsAbhi fbbc0b82b4 Update Lighting.tsx 2025-10-31 08:06:11 -05:00
TrèsAbhi aecc2adb07 feat: generalize colored delta cells 2025-10-26 22:01:42 -05:00
TrèsAbhi f8ee2b64a6 feat: simplify ownership and test filters 2025-10-26 21:49:48 -05:00
TrèsAbhi 7c4e28bd09 fix: show remove played even when logged out 2025-10-26 21:43:23 -05:00
TrèsAbhi 80d61d9e04 fix: fallback 2025-10-26 21:19:42 -05:00
TrèsAbhi 0c22ac3a97 fix: step title 2025-10-26 21:06:38 -05:00
TrèsAbhi efad6e61f7 Update assets.yml 2025-10-23 22:15:56 -05:00
TrèsAbhi 3563aaecd5 fix: move depots 2025-10-23 21:49:54 -05:00
TrèsAbhi 5294de848f fix: manual flag 2025-10-23 21:29:44 -05:00
TrèsAbhi e82aa56cb2 feat: logs 2025-10-23 21:28:27 -05:00
TrèsAbhi e1b2b130a5 feat: hide uploader 2025-10-23 21:26:51 -05:00
TrèsAbhi 28f22f1d40 fix: include missing module 2025-10-23 21:22:34 -05:00
TrèsAbhi a3bb023309 feat: migrate to asset uploader 2025-10-23 21:22:21 -05:00
TrèsAbhi 797307fb81 feat: asset uploader 2025-10-23 20:29:30 -05:00
TrèsAbhi f9802b44ff feat: update readme 2025-10-23 19:48:23 -05:00
TrèsAbhi e26b9c78a3 feat: remove unnecessary submodules 2025-10-23 19:46:31 -05:00
TrèsAbhi 925ae1a0b7 fix: type 2025-10-23 19:37:14 -05:00
TrèsAbhi 9584ecf38b feat: logs 2025-10-23 19:36:15 -05:00
TrèsAbhi 338168d7e4 remove url echos 2025-10-23 15:36:28 -05:00
TrèsAbhi 711d92887e fix: naming 2025-10-23 15:27:50 -05:00
TrèsAbhi 78160041e8 feat: parallel 2025-10-23 15:18:12 -05:00
TrèsAbhi 1b884a52f9 name 2025-10-23 15:09:54 -05:00
TrèsAbhi f13c658ef4 no spaced 2025-10-23 15:09:19 -05:00
TrèsAbhi b72d4058be feat: unarchive 2025-10-23 15:01:18 -05:00
TrèsAbhi 029a781c50 fix: hardcode app path 2025-10-23 10:31:26 -05:00
TrèsAbhi adc1791f56 feat: game archive mounting 2025-10-23 10:30:21 -05:00
TrèsAbhi 15b6ff43c5 feat: handle different asset repors 2025-10-23 10:01:17 -05:00
TrèsAbhi e2c02f3d86 fix: GH_TOKEN 2025-10-22 22:10:16 -05:00
TrèsAbhi 3ce47f6ed0 fix: token 2025-10-22 20:54:18 -05:00
TrèsAbhi fa91b37d92 Merge branch 'main' of https://github.com/blitzkit/blitzkit 2025-10-22 20:51:29 -05:00
TrèsAbhi 108644bd44 fix: protoc 2025-10-22 20:51:27 -05:00
TrèsAbhi 413436376b New translations en.json (Russian) (#178) 2025-10-22 20:49:39 -05:00
TrèsAbhi 7d118015d0 fix: merge commands 2025-10-22 19:17:09 -05:00
TrèsAbhi 92e7390a5d fix: merge commands 2025-10-22 19:16:07 -05:00
TrèsAbhi 475e25a0d8 fix: prisma client 2025-10-22 18:57:03 -05:00
TrèsAbhi 17115af0d8 fix: protos 2025-10-22 18:52:45 -05:00
TrèsAbhi a9894ade78 fix: prisma, protoc 2025-10-22 18:47:34 -05:00
TrèsAbhi f5b09873a9 feat: logs 2025-10-22 18:45:13 -05:00
TrèsAbhi ac768d0897 fix: the last of the errors 2025-10-22 18:42:51 -05:00
TrèsAbhi f802b997c0 feat: cleanup 2025-10-22 18:27:37 -05:00
TrèsAbhi db94edea69 fix: even more locale props 2025-10-22 17:55:17 -05:00
TrèsAbhi 0809c9ee0c fix: some locale props 2025-10-22 17:52:01 -05:00
TrèsAbhi 0326e8d1d7 Merge branch 'main' into fix-modules 2025-10-22 17:31:21 -05:00
TrèsAbhi 912c1fb125 no message 2025-10-20 22:13:14 -05:00
TrèsAbhi d07383a722 New Crowdin updates (#176)
* New translations en.json (Russian)

* New translations en.json (Russian)
2025-10-17 12:08:12 -05:00
TrèsAbhi 582e608203 fix: @bufbuild/protobuf 2025-10-15 18:26:14 -05:00
TrèsAbhi 501a618d5f Merge branch 'main' into fix-modules 2025-10-15 18:17:21 -05:00
TrèsAbhi 7c7f34d899 Merge branch 'main' of https://github.com/blitzkit/blitzkit 2025-10-15 18:14:22 -05:00
TrèsAbhi 864d34f344 feat: remove checked 2025-10-15 18:14:20 -05:00
TrèsAbhi 9201fc72ce New Crowdin updates (#175)
* 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 (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)
2025-10-15 09:02:02 -05:00
TrèsAbhi 50f82d68b4 feat: logs 2025-10-14 22:34:11 -05:00
TrèsAbhi b81f664379 Merge branch 'main' into dev 2025-10-14 22:28:12 -05:00
TrèsAbhi 389707d0c8 fix: keys 2025-10-14 22:28:00 -05:00
TrèsAbhi 9fbd623d91 feat: enable playlist 2025-10-14 22:27:12 -05:00
TrèsAbhi f36df9e902 feat: landing page for mobile 2025-10-14 22:26:13 -05:00
TrèsAbhi 437bbfdc89 feat: large warning 2025-10-14 22:21:22 -05:00
TrèsAbhi 7becb7b6ad fix: modify only when needed 2025-10-14 22:06:01 -05:00
TrèsAbhi 94e8a07f90 feat: hide playlist 2025-10-14 22:03:51 -05:00
TrèsAbhi 4ae5283ac4 feat: landing page cleanup 2025-10-14 22:02:47 -05:00
TrèsAbhi ade238966b feat: some cleanup 2025-10-14 21:53:58 -05:00
TrèsAbhi ea048da7a2 feat: tracking 2025-10-14 21:36:37 -05:00
TrèsAbhi 263f292a59 feat: shuffle button 2025-10-14 20:19:52 -05:00
TrèsAbhi ff4a87e5b8 perf: reactive updates 2025-10-14 20:15:00 -05:00
TrèsAbhi 222b690fba feat: action buttons 2025-10-14 12:19:28 -05:00
TrèsAbhi e1a6e4e38d feat: spotify like table 2025-10-14 12:11:31 -05:00
TrèsAbhi 37adc04cda feat: drag handles 2025-10-14 11:32:43 -05:00
TrèsAbhi 3fc7279f0e feat: main package 2025-10-13 23:22:58 -05:00
TrèsAbhi bd852b9368 feat: some more type prefixes 2025-10-13 23:20:41 -05:00
TrèsAbhi 26304fc281 feat: some more type prefixes 2025-10-13 23:20:26 -05:00
TrèsAbhi 0d8cb5c1ae feat: some type prefixes 2025-10-13 23:15:32 -05:00
TrèsAbhi dc60cffdff i made things worse 2025-10-13 23:10:48 -05:00
TrèsAbhi a3e74de277 fix: missing percentage 2025-10-13 22:55:24 -05:00
TrèsAbhi 49b5d4f7dc fix: script imports 2025-10-13 22:26:11 -05:00
TrèsAbhi 2c55455cd7 fix: types and lodash-es 2025-10-13 16:59:31 -05:00
TrèsAbhi 648ac57424 fix: build proxy client 2025-10-13 16:58:16 -05:00
TrèsAbhi 5e3cf816ee fix: build protos in workflows 2025-10-13 16:54:32 -05:00
TrèsAbhi 98ea42c7b0 fix: protos 2025-10-13 16:53:37 -05:00
TrèsAbhi 873c8a54d3 feat: start fixing modules 2025-10-13 16:48:04 -05:00
TrèsAbhi 927495ca16 New translations en.json (Chinese Simplified) (#174) 2025-10-13 16:41:50 -05:00
TrèsAbhi cc957466fc feat: action button 2025-10-12 23:10:09 -05:00
TrèsAbhi ef173758aa feat: better landing screen 2025-10-12 22:48:14 -05:00
TrèsAbhi bfceacdf3c feat: playlist table 2025-10-12 19:37:44 -05:00
TrèsAbhi ed0dde37d2 feat: playlist 2025-10-12 18:51:28 -05:00
TrèsAbhi 5ba64f231a fix: trimmer pagewrapper min height 2025-10-12 18:20:00 -05:00
TrèsAbhi 1f06b1fef4 fix: checkout 2025-10-12 18:00:51 -05:00
TrèsAbhi 7b0625fc8d fix: @protos path 2025-10-12 17:57:49 -05:00
TrèsAbhi 5dce234447 fix: dvp 2025-10-12 14:12:47 -05:00
TrèsAbhi 0f609717d0 adjacent 2025-10-12 13:40:32 -05:00
TrèsAbhi 3958709348 fix: adjacent submodule 2025-10-12 13:39:03 -05:00
TrèsAbhi 2d869c9fac Remove submodule submodules/blitzkit-closed 2025-10-12 13:36:15 -05:00
TrèsAbhi 82afaf9494 fix: lz4js 2025-10-12 13:24:03 -05:00
TrèsAbhi b1d82e624a fix: crc 2025-10-12 13:12:10 -05:00
TrèsAbhi 9b60d56a36 fix: immer 2025-10-12 12:26:19 -05:00
TrèsAbhi ee0d4f6996 fix: varuna 2025-10-12 17:22:26 +00:00
TrèsAbhi 2d43408822 fix: remove closed 2025-10-12 17:21:18 +00:00
TrèsAbhi 868f132105 fix: core and closed dep 2025-10-12 17:20:33 +00:00
TrèsAbhi ce428e093b fix: i18n dep 2025-10-12 17:18:39 +00:00
TrèsAbhi ab430dc0ca fix: bot imports 2025-10-12 17:17:05 +00:00
TrèsAbhi 03a51c47bb fix: self core imports 2025-10-12 15:05:58 +00:00
TrèsAbhi 1790443698 feat: rename 2025-10-12 09:51:21 -05:00
TrèsAbhi a60f95340c fix: deps 2025-10-12 09:49:31 -05:00
TrèsAbhi e407463ca7 New Crowdin updates (#173) 2025-10-12 09:47:24 -05:00
TrèsAbhi 61cc15aafc Update package.json 2025-10-12 09:38:02 -05:00
TrèsAbhi 1a947a6300 feat: logs 2025-10-11 21:54:11 -05:00
TrèsAbhi 75262647f7 Merge branch 'main' into dev 2025-10-11 21:50:24 -05:00
TrèsAbhi 9914371dd8 fix: tier list filters 2025-10-11 21:49:20 -05:00
TrèsAbhi a4e48a2feb fix: performance filters 2025-10-11 21:45:18 -05:00
TrèsAbhi 4ab03e56a2 feat: support transparency 2025-10-11 21:22:48 -05:00
TrèsAbhi 06a3791ddd fix: settings title 2025-10-11 20:51:12 -05:00
TrèsAbhi 36cce4b0c1 fix: make settings page responsive again 2025-10-11 20:48:33 -05:00
TrèsAbhi 158141fdc7 Update index.ts 2025-10-06 20:58:45 -05:00
TrèsAbhi 1d319551e7 Update literals.ts 2025-10-06 18:24:48 -05:00
TrèsAbhi 0552ac790e Update assets.yml 2025-10-06 11:10:39 -05:00
TrèsAbhi 5ad7566874 fix: show controls in all display modes 2025-10-05 18:34:03 -05:00
TrèsAbhi 638f178fbf fix: trimmer heading 2025-10-05 18:31:07 -05:00
318 changed files with 5686 additions and 4289 deletions

No files matched your search

+26 -98
View File
@@ -1,4 +1,4 @@
name: Build Assets
name: Assets
on:
push:
@@ -6,30 +6,30 @@ on:
workflow_dispatch:
inputs:
cdn_branch:
asset_repo:
type: choice
required: false
description: What asset repo to write to
options:
- blitzkit/assets
- blitzkit/assets-preview
- blitzkit/assets-dev
default: blitzkit/assets
archive_url:
type: string
required: false
default: main
description: What CDN branch to write to
zip_url:
type: string
required: false
description: ZIP URL to download instead of Steam client
zip_root:
type: string
required: false
description: Root dir of ZIP which houses the executable and Data dir
description: Archive URL to download instead of Steam client
schedule:
- cron: '0 2 * * *'
- cron: "0 2 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.cdn_branch }}
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.asset_repo }}
cancel-in-progress: true
env:
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
@@ -37,8 +37,8 @@ env:
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
WOTB_DLC_CDN: ${{ secrets.WOTB_DLC_CDN }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_REPO: blitzkit/assets
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ github.event.inputs.asset_repo != '' && github.event.inputs.asset_repo || secrets.PUBLIC_ASSET_REPO }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
@@ -54,100 +54,28 @@ env:
PUBLIC_ASSET_FAST_USER: blitzkit
PUBLIC_ASSET_FAST_REPO: assets
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
jobs:
download_client:
name: Download client
runs-on: ubuntu-latest
steps:
- name: (ZIP) Maximize build space
if: github.event.inputs.zip_url != ''
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 512
swap-size-mb: 1024
remove-dotnet: 'true'
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- name: (Steam) Setup bun
uses: oven-sh/setup-bun@v1
if: github.event.inputs.zip_url == ''
- name: (Steam) Install dependencies
if: github.event.inputs.zip_url == ''
run: bun install
- name: (Steam) Setup DepotDownloader
if: github.event.inputs.zip_url == ''
run: bun run setup:depotdownloader
- name: (Steam) Download client
if: github.event.inputs.zip_url == ''
run: |
chmod +x ./temp/depotDownloader/DepotDownloader
./temp/depotDownloader/DepotDownloader -q -os windows -app 444200 -username ${{ secrets.DEPOT_DOWNLOADER_USERNAME }} -password "${{ secrets.DEPOT_DOWNLOADER_PASSWORD }}"
- name: (Steam) Apply patches
if: github.event.inputs.zip_url == ''
run: bun setup:patches --depot
- name: (ZIP) Download client
if: github.event.inputs.zip_url != ''
env:
ZIP_URL: ${{ github.event.inputs.zip_url }}
ZIP_ROOT: ${{ github.event.inputs.zip_root }}
run: |
wget -q -O client.zip $ZIP_URL
unzip -q client.zip -d client
rm client.zip
mkdir -p depots/444202/0
mv client/$ZIP_ROOT/* depots/444202/0
- name: Archive depots
uses: actions/upload-artifact@v4
with:
name: depots
path: depots
build_assets:
name: Build assets
runs-on: ubuntu-latest
needs: download_client
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- name: Setup bun
uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- name: Lint
run: bun run lint:website
- name: Download depots
uses: actions/download-artifact@v4
- uses: arduino/setup-protoc@v3
with:
name: depots
path: depots
repo-token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- run: bun run setup
- name: AppArmor hack
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
- name: Start server and build assets
run: |
bun dev:website --verbosepa &
SERVER_PID=$!
bun run build:assets --all-targets --depot --production
kill $SERVER_PID || true
- name: Build assets
run: bun run build:assets --all-targets --manual
+11 -6
View File
@@ -3,7 +3,7 @@ name: Averages
on:
workflow_dispatch:
schedule:
- cron: '0 8 * * *'
- cron: "0 8 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -15,7 +15,7 @@ env:
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: 'true'
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
@@ -25,6 +25,7 @@ env:
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
@@ -32,16 +33,20 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Build averages
env:
PUBLIC_ASSET_BRANCH: main
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
+8 -7
View File
@@ -1,4 +1,4 @@
name: Build Bot
name: Bot
on:
push:
@@ -15,13 +15,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- name: Build Prisma
run: bun run build:prisma
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Build bot
run: bun run build:bot
+10 -6
View File
@@ -1,9 +1,9 @@
name: Discover IDs
name: IDs
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 1'
- cron: "0 0 * * 1"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -11,11 +11,11 @@ concurrency:
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
@@ -23,10 +23,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Discover IDs
run: bun build:ids --production
+6 -4
View File
@@ -1,10 +1,10 @@
name: Host Bot
name: Host
on:
push:
branches: main
schedule:
- cron: '0 */5 * * *'
- cron: "0 */5 * * *"
workflow_dispatch:
release:
types: [created, published, released, edited]
@@ -35,6 +35,7 @@ env:
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
SERVICING: ${{ secrets.SERVICING }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
@@ -42,8 +43,9 @@ jobs:
steps:
- uses: oven-sh/setup-bun@v1
# with:
# bun-version: 1.1.33
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- name: Download release assets
run: |
+30 -25
View File
@@ -3,7 +3,29 @@ name: Rating Asia
on:
workflow_dispatch:
schedule:
- cron: '0 17 * * *'
- cron: "0 17 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
@@ -11,31 +33,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: 'true'
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
run: bun build:ratingleaderboard --region=asia
+30 -25
View File
@@ -3,7 +3,29 @@ name: Rating Europe
on:
workflow_dispatch:
schedule:
- cron: '0 23 * * *'
- cron: "0 23 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
@@ -11,31 +33,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: 'true'
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
run: bun build:ratingleaderboard --region=eu
+30 -25
View File
@@ -3,7 +3,29 @@ name: Rating North America
on:
workflow_dispatch:
schedule:
- cron: '0 5 * * *'
- cron: "0 5 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
@@ -11,31 +33,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: 'true'
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
run: bun build:ratingleaderboard --region=com
+7 -6
View File
@@ -11,12 +11,13 @@ concurrency:
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
jobs:
build:
@@ -27,11 +28,11 @@ jobs:
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Find reviews
run: bun packages/scripts/src/reviews.ts
run: bun run build:reviews
+6 -5
View File
@@ -5,7 +5,7 @@ on:
workflow_dispatch:
schedule:
- cron: '0 4 * * *'
- cron: "0 4 * * *"
permissions:
contents: read
@@ -31,6 +31,7 @@ env:
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
SERVICING: ${{ secrets.SERVICING }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
@@ -41,12 +42,12 @@ jobs:
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v1
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- uses: actions/configure-pages@v5
- name: Install dependencies
run: bun install
- run: bun run setup
- name: Build website
run: bun run build:website
+3 -9
View File
@@ -1,9 +1,3 @@
[submodule "submodules/blitzkit-closed"]
path = submodules/blitzkit-closed
url = https://github.com/tresabhi/blitzkit-closed
[submodule "submodules/CUE4Parse"]
path = submodules/CUE4Parse
url = https://github.com/FabianFG/CUE4Parse
[submodule "submodules/blitzkit-internal"]
path = submodules/blitzkit-internal
url = https://github.com/blitzkit/internal
[submodule "packages/closed"]
path = packages/closed
url = https://github.com/blitzkit/closed.git
+17
View File
@@ -11,6 +11,7 @@
"analyticsreporting",
"APAC",
"apcr",
"appinfo",
"applypatches",
"artefacts",
"astrojs",
@@ -34,12 +35,14 @@
"blitzkit",
"blitzrinth",
"blitzstars",
"bufbuild",
"cacheable",
"Callouts",
"Camo",
"Carro",
"CCPAOPTOUT",
"CDON",
"clanid",
"classname",
"cleandist",
"closedkrieg",
@@ -62,8 +65,10 @@
"deburr",
"decalmask",
"decompressor",
"dedup",
"defence",
"degressive",
"depotdownloader",
"devkrieg",
"diacriticless",
"DIDS",
@@ -74,6 +79,7 @@
"DVPLCRC",
"dvpm",
"dxgi",
"easimon",
"echarts",
"Everytime",
"FASTNAME",
@@ -92,6 +98,7 @@
"GLTF",
"gtag",
"haha",
"Herdbreaker",
"highp",
"iife",
"imgur",
@@ -105,6 +112,7 @@
"leaderboards",
"lerp",
"LINEARSIZE",
"linktarget",
"lmao",
"loadouts",
"loddist",
@@ -127,6 +135,7 @@
"NEGATIVEX",
"NEGATIVEY",
"NEGATIVEZ",
"networkidle",
"NITROPAY",
"nivo",
"nmatname",
@@ -137,11 +146,13 @@
"Oopsy",
"opentest",
"OPTML",
"otemp",
"outdir",
"outfile",
"ownedtanks",
"padder",
"partytown",
"patchnotes",
"PIXELFORMAT",
"playerachievements",
"playerinfo",
@@ -154,11 +165,15 @@
"Promisable",
"proto",
"protobuf",
"protoc",
"protos",
"proxyclient",
"prunestrings",
"Pyogenics",
"ratingleaderboard",
"raycaster",
"Redirector",
"Relogin",
"researchable",
"Resvg",
"rizz",
@@ -207,12 +222,14 @@
"Unregistering",
"unrotate",
"unwrapper",
"userns",
"vercel",
"vickers",
"vitepress",
"Vovko",
"wargaming",
"webp",
"wgpkg",
"whitespaces",
"WHSS",
"winrate",
+5 -7
View File
@@ -16,22 +16,20 @@ If you intend to contribute to the code, note that you may need to check out sen
| [packages/i18n](packages/i18n) | | [Crowdin](https://crowdin.com/project/blitzkrieg) | Translations served as JSON shared across all other packages, including some utility code. |
| [packages/scripts](packages/scripts) | | | CLI utilities for the development and deployment of BlitzKit services. |
| [packages/varuna](packages/varuna) | Varuna | [NPM](https://www.npmjs.com/package/varuna) | React and Astro-oriented state management library, awaiting separation from BlitzKit. Unavailable from NPM at this time. |
| [packages/website](packages/website) | BlitzKit | https://blitzkit.app | The BlitzKit website provides a wide range of tools, APIs, and interconnects all other services. |
| [packages/website](packages/website) | BlitzKit | https://blitzkit.app | The BlitzKit website provides a wide range of tools, APIs, and interconnects all other services. |
## Submodules
| Submodule | Title | Source | Memo |
| ------------------------------------------------------------ | ----------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [submodules/blitzkit-closed](submodules/blitzkit-closed) | ClosedKit | [blitzkit/closed](https://github.com/blitzkit/closed) | Closed source, sensitive code hidden from the public to prevent bad actors from abusing the game. Discuss with `@tresabhi` on Discord for **special permission** to access. |
| [submodules/blitzkit-internal](submodules/blitzkit-internal) | InternalKit | [blitzkit/internal](https://github.com/blitzkit/internal) | Closed source, sensitive internal documentation hidden from the public to prevent bad actors from abusing the game. Access to this submodule is **not negotiable**. |
| [submodules/CUE4Parse](submodules/CUE4Parse) | CUE4Parse | [FabianFG/CUE4Parse](https://github.com/FabianFG/CUE4Parse) | An Unreal Engine archives and packages parsing library in C#. |
| Submodule | Title | Source | Memo |
| ------------------------------------------------------ | --------- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [submodules/blitzkit-closed](packages/blitzkit-closed) | ClosedKit | [blitzkit/closed](https://github.com/blitzkit/closed) | Closed source, sensitive code hidden from the public to prevent bad actors from abusing the game. Discuss with `@tresabhi` on Discord for **special permission** to access. |
## Environment Variables
| Name | Source | BlitzKit Default | Memo |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `PUBLIC_WARGAMING_APPLICATION_ID` | [Wargaming Developer's Room](https://developers.wargaming.net/) | | Application ID needed to communicate with Wargaming APIs. |
| `PUBLIC_PROMOTE_OPENTEST` | | `false` | Optional boolean dictating whether the website advertises [the opentest subdomain of BlitzKit](https://opentest.blitzkit.app/). |
| `PUBLIC_PROMOTE_OPENTEST` | | `false` | Optional boolean dictating whether the website advertises [the opentest subdomain of BlitzKit](https://opentest.blitzkit.app/). |
| `ALLOW_ROBOTS` | | `true` | Toggles between `Allow: /` and `Disallow: /` in the website's `/robots.txt`. This is usually `false` for all BlitzKit's subdomains. |
| `WOTB_GLOSSARY`, `WOTB_GLOSSARY_DOMAIN`, `WOTB_GLOSSARY_PATH` | | | |
| `PUBLIC_GOOGLE_TAG_MANAGER_ID` | [Google Tag Manager](https://tagmanager.google.com/) | `G-GL2JVHCGPQ` | Google Tag Manager's unique identifier for analytical purposes. |
+228 -328
View File
File diff suppressed because it is too large. Load diff
+10
View File
@@ -0,0 +1,10 @@
# BlitzKit 1.28.4
## Fixes
- The tank names in the Tankopedia sandbox now have less margin from the navbar
- Controls in the Tankopedia sandbox are now shown in all modes, except for the advanced highlighting button which only appears in the dynamic armor mode
- The settings page now reacts to input again
- The settings page now has a tab title and description for search engines
- Added support for transparent textures, fixing tanks like the Herdbreaker and the WZ-132-1
- The tank filters in the Performance and Tier-List tools work once again
+12
View File
@@ -0,0 +1,12 @@
# BlitzKit 1.29.0
## Features
- Added the Playlist tool
- Don't know what to play today? Let BlitzKit do the thinking!
- Navigate to [the tool on BlitzKit](https://blitzkit.app/playlist)
- Make sure you login with your Wargaming account to unlock all features like live tracking and filtering by owned tanks
- Use filters to pick tiers, nations, etc. then hit Generate playlist
- BlitzKit will generate a checklist for you to go through as you play
- Don't like the order of tanks? Hit Shuffle, Sort by Last played and Least played, or straight up remove tanks from the list by using the (-) button
- If you're logged in, BlitzKit will automatically check off tanks as you play them
+5
View File
@@ -0,0 +1,5 @@
# BlitzKit 1.29.1
## Technical Changes
- Recreated the full dependency tree for BlitzKit
+5
View File
@@ -0,0 +1,5 @@
# BlitzKit 1.29.2
## Technical Changes
- Implemented new workflow capabilities to deploy BlitzKit OpenTest and Preview remotely, from any device
+5
View File
@@ -0,0 +1,5 @@
# BlitzKit 1.29.3
## Technical Changes
- Added a significantly more memory and network efficient AssetUploader abstraction
+5
View File
@@ -0,0 +1,5 @@
# BlitzKit 1.29.4
## Technical Changes
- BlitzKit now partially downloads game files instead of the entire game, allowing for faster updates
+11
View File
@@ -0,0 +1,11 @@
# BlitzKit 1.29.5
## Features
- Added new lighting to be a bit softer on tanks
- Added a button with the sun icon to toggle high graphics
- Added a new reveal and transition animation between tabs
## Fixes
- Track wheels on some tanks no longer look translucent
+18
View File
@@ -0,0 +1,18 @@
# BlitzKit 1.29.6
## Features
- Simplified the ownership and test tank filters in the tank search
- Renamed "Guess the tank" to simply "Guess"
- The player count value in the Performance tool is now set to Total by default
- Added Compare-like red/green highlighting to the Performance tool
## Changes
- Removed the last updated info bar in Performance for some more screen real estate
## Fixes
- The remove played tanks in the Playlist tool now shows even when logged out
- The Guess game now has a page title
- The compare table now occupies the minimum width possible instead of expanding all columns excessively
+15 -30
View File
@@ -1,22 +1,16 @@
{
"name": "blitzkit",
"version": "1.29.6",
"license": "BlitzKit License",
"private": true,
"version": "1.28.3",
"description": "🎉 Tools for everything World of Tanks Blitz",
"type": "module",
"types": "./types.d.ts",
"workspaces": [
"packages/*"
],
"scripts": {
"build:assets": "cd packages/scripts && bun run build:assets",
"build:averages": "bun --filter=@blitzkit/scripts run build:averages",
"build:bot": "cd packages/scripts && bun run build:bot",
"build:website": "bun build:prisma --no-hints && cd packages/website && bun run build",
"build:website": "cd packages/website && bun run build",
"build:prisma": "prisma generate",
"build:sitemap": "bun scripts/sitemap.ts",
"build:docs": "vitepress build docs",
"build:proxyclient": "cd packages/scripts && bun run build:proxyclient",
"build:catalogitemaccesssor": "cd packages/scripts && bun run build:catalogitemaccesssor",
"build:ratingleaderboard": "cd packages/scripts && bun run build:ratingleaderboard",
"build:app": "cd packages/app && bun run build",
"dev:bot": "bun run build:bot --dev && bun start:bot",
@@ -36,30 +30,21 @@
"update": "yarn upgrade --latest",
"tunnel": "cloudflared tunnel --url http://localhost:3000",
"discoverids": "scripts/discoverIds.ts",
"build:protos": "bun packages/scripts/src/protos.ts",
"build:protos": "cd packages/scripts && bun run build:protos",
"preview:website": "cd packages/website && bun run preview",
"build:reviews": "cd packages/scripts && bun build:reviews",
"build:ids": "cd packages/scripts && bun build:ids",
"prunestrings": "cd packages/scripts && bun prunestrings"
"prunestrings": "cd packages/scripts && bun prunestrings",
"setup": "bun install && bun run build:prisma && bun run build:protos && bun run build:proxyclient",
"patchnotes": "cd packages/scripts && bun run patchnotes"
},
"license": "MIT",
"type": "module",
"workspaces": [
"packages/*"
],
"dependencies": {
"@types/xmpp__client": "^0.13.3",
"@xmpp/client": "^0.13.6",
"astro-favicons": "^3.1.5",
"cheerio": "^1.1.2",
"googleapis": "^160.0.0",
"lodash-es": "^4.17.21",
"protobufjs": "^7.5.4",
"quicklime": "^1.2.0",
"sharp": "^0.34.4"
},
"devDependencies": {
"@types/bun": "^1.2.22",
"@types/lodash-es": "^4.17.12",
"@types/node": "^24.5.2",
"prettier": "^3.6.2",
"prisma": "^6.16.2",
"typescript": "^5.9.2"
"@prisma/client": "^6.18.0",
"prisma": "^6.18.0",
"typescript": "^5.9.3"
}
}
+20 -12
View File
@@ -1,26 +1,34 @@
{
"name": "@blitzkit/bot",
"private": true,
"type": "module",
"types": "src/types.d.ts",
"dependencies": {
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"satori": "^0.18.3",
"@resvg/resvg-js": "^2.6.2",
"discord.js": "^14.22.1",
"react": "^19.1.1",
"@radix-ui/colors": "^3.0.0",
"fuzzysort": "^3.1.0",
"@radix-ui/themes": "^3.2.1",
"@resvg/resvg-js": "^2.6.2",
"@types/adm-zip": "^0.5.7",
"@types/lodash-es": "^4.17.12",
"@types/markdown-escape": "^1.1.3",
"@types/react": "^19.2.2",
"adm-zip": "^0.5.16",
"bepaint": "^0.1.0-beta.3",
"discord.js": "^14.22.1",
"dotenv": "^17.2.2",
"markdown-escape": "^2.0.0"
"fuzzysort": "^3.1.0",
"lodash-es": "^4.17.21",
"markdown-escape": "^2.0.0",
"pickleparser": "^0.2.1",
"prisma": "^6.17.1",
"protobufjs": "^7.5.4",
"react": "^19.2.0",
"satori": "^0.18.3",
"sharp": "^0.34.4"
},
"private": true,
"scripts": {
"dev": "bun --watch src/main.ts",
"start": "bun src/main.ts"
},
"devDependencies": {
"@types/markdown-escape": "^1.1.3"
}
"type": "module",
"types": "src/types.d.ts"
}
+22 -19
View File
@@ -1,28 +1,31 @@
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { translator } from '../core/localization/translator';
import { COMMANDS_RAW, CommandRegistry } from '../events/interactionCreate';
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { translator } from "../core/localization/translator";
import {
COMMANDS_RAW,
type CommandRegistry,
} from "../events/interactionCreate";
const subcommands = [
'embeds',
'introduction',
'invite',
'timezones',
'credits',
"embeds",
"introduction",
"invite",
"timezones",
"credits",
] as const;
type Subcommand = (typeof subcommands)[number];
const DOCS: Record<Subcommand, string> = {
embeds: 'guide/embeds',
introduction: 'guide/introduction',
invite: 'guide/invite',
timezones: 'guide/timezones',
credits: 'about/credits',
embeds: "guide/embeds",
introduction: "guide/introduction",
invite: "guide/invite",
timezones: "guide/timezones",
credits: "about/credits",
};
export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
resolve({
command: createLocalizedCommand('about', [
{ subcommand: 'commands' },
command: createLocalizedCommand("about", [
{ subcommand: "commands" },
...subcommands.map((subcommand) => ({ subcommand })),
]),
@@ -30,7 +33,7 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
const subcommand = interaction.options.getSubcommand();
const { strings } = translator(interaction.locale);
if (subcommand === 'commands') {
if (subcommand === "commands") {
return `${strings.bot.commands.about.subcommands.commands.body}${(
await Promise.all(COMMANDS_RAW)
)
@@ -40,7 +43,7 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
(b.command.name_localizations?.[interaction.locale] ??
b.command.name)
? -1
: 1,
: 1
)
.map(
(registry) =>
@@ -51,9 +54,9 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
registry.command.description_localizations?.[
interaction.locale
] ?? registry.command.description
}`,
}`
)
.join('\n')}`;
.join("\n")}`;
}
const url = `https://raw.githubusercontent.com/tresabhi/blitzkit/main/docs/${DOCS[subcommand as Subcommand]}.md`;
@@ -13,7 +13,7 @@ import { resolvePeriodFromButton } from '../../core/discord/resolvePeriodFromBut
import { resolvePeriodFromCommand } from '../../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../../core/discord/resolvePlayerFromButton';
import { resolvePlayerFromCommand } from '../../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../../events/interactionCreate';
import type { CommandRegistry } from '../../events/interactionCreate';
import { renderBreakdown } from './render';
export const breakdownCommand = new Promise<CommandRegistry>(
@@ -1,5 +1,5 @@
import {
BlitzStats,
type BlitzStats,
calculateWN8,
getAccountInfo,
getClanAccountInfo,
@@ -17,11 +17,11 @@ import { TitleBar } from "../../components/TitleBar";
import { filtersToDescription } from "../../core/blitzkit/filtersToDescription";
import { tankDefinitions } from "../../core/blitzkit/nonBlockingPromises";
import { UserError } from "../../core/blitzkit/userError";
import { filterStats, StatFilters } from "../../core/blitzstars/filterStats";
import { filterStats, type StatFilters } from "../../core/blitzstars/filterStats";
import { getStatsInPeriod } from "../../core/blitzstars/getStatsInPeriod";
import { blitzStarsTankAverages } from "../../core/blitzstars/tankAverages";
import { ResolvedPeriod } from "../../core/discord/resolvePeriodFromCommand";
import { ResolvedPlayer } from "../../core/discord/resolvePlayerFromCommand";
import type { ResolvedPeriod } from "../../core/discord/resolvePeriodFromCommand";
import type { ResolvedPlayer } from "../../core/discord/resolvePlayerFromCommand";
import { translator } from "../../core/localization/translator";
const ROWS_PER_PAGE = 8;
+9 -9
View File
@@ -1,14 +1,14 @@
import packageJSON from '../../../../package.json';
import { client } from '../core/discord/client';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { translator } from '../core/localization/translator';
import { CommandRegistry } from '../events/interactionCreate';
import packageJSON from "../../../../package.json";
import { client } from "../core/discord/client";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { translator } from "../core/localization/translator";
import type { CommandRegistry } from "../events/interactionCreate";
const executionStart = new Date().getTime();
export const debugCommand = new Promise<CommandRegistry>((resolve) => {
resolve({
command: createLocalizedCommand('debug'),
command: createLocalizedCommand("debug"),
async handler(interaction) {
const { strings } = translator(interaction.locale);
@@ -23,15 +23,15 @@ export const debugCommand = new Promise<CommandRegistry>((resolve) => {
[
strings.bot.commands.debug.body.uptime,
`${Math.floor((uptime / 1000 / 60 / 60) % 24)}h ${Math.floor(
(uptime / 1000 / 60) % 60,
(uptime / 1000 / 60) % 60
)}m ${Math.floor((uptime / 1000) % 60)}s ${Math.floor(
uptime % 1000,
uptime % 1000
)}ms`,
],
];
return `${strings.bot.commands.debug.body.title}${list
.map(([key, value]) => `- ${key}: ${value}`)
.join('\n')}`;
.join("\n")}`;
},
});
});
+47 -47
View File
@@ -1,48 +1,48 @@
import { emblemURL, getAccountInfo, getClanAccountInfo } from '@blitzkit/core';
import { Locale, SlashCommandSubcommandGroupBuilder } from 'discord.js';
import { CommandWrapper } from '../components/CommandWrapper';
import * as Graph from '../components/Graph';
import { LineColor } from '../components/Graph/components/Line/constants';
import { NoData } from '../components/NoData';
import { TitleBar } from '../components/TitleBar';
import { resolveTankId } from '../core/blitz/resolveTankId';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import { getPlayerHistories } from '../core/blitzstars/getPlayerHistories';
import { getTankHistories } from '../core/blitzstars/getTankHistories';
import { addPeriodSubCommands } from '../core/discord/addPeriodSubCommands';
import { addTankChoices } from '../core/discord/addTankChoices';
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
import { autocompleteTanks } from '../core/discord/autocompleteTanks';
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
import { buttonRefresh } from '../core/discord/buttonRefresh';
import { commandToURL } from '../core/discord/commandToURL';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
import { emblemURL, getAccountInfo, getClanAccountInfo } from "@blitzkit/core";
import { Locale, SlashCommandSubcommandGroupBuilder } from "discord.js";
import { CommandWrapper } from "../components/CommandWrapper";
import * as Graph from "../components/Graph";
import { LineColor } from "../components/Graph/components/Line/constants";
import { NoData } from "../components/NoData";
import { TitleBar } from "../components/TitleBar";
import { resolveTankId } from "../core/blitz/resolveTankId";
import { getBlitzStarsLinkButton } from "../core/blitzstars/getBlitzStarsLinkButton";
import { getPlayerHistories } from "../core/blitzstars/getPlayerHistories";
import { getTankHistories } from "../core/blitzstars/getTankHistories";
import { addPeriodSubCommands } from "../core/discord/addPeriodSubCommands";
import { addTankChoices } from "../core/discord/addTankChoices";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { buttonRefresh } from "../core/discord/buttonRefresh";
import { commandToURL } from "../core/discord/commandToURL";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getCustomPeriodParams } from "../core/discord/getCustomPeriodParams";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import {
ResolvedPeriod,
type ResolvedPeriod,
resolvePeriodFromCommand,
} from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
} from "../core/discord/resolvePeriodFromCommand";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import {
ResolvedPlayer,
type ResolvedPlayer,
resolvePlayerFromCommand,
} from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
} from "../core/discord/resolvePlayerFromCommand";
import type { CommandRegistry } from "../events/interactionCreate";
type EvolutionStatType = 'player' | 'tank';
type EvolutionStatType = "player" | "tank";
async function render(
{ region, id }: ResolvedPlayer,
{ start, end, name }: ResolvedPeriod,
type: 'player' | 'tank',
type: "player" | "tank",
tankId: number | null,
locale: Locale,
locale: Locale
) {
const accountInfo = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
const logo = clan ? emblemURL(clan.emblem_set_id) : undefined;
const histories = await (type === 'player'
const histories = await (type === "player"
? getPlayerHistories(region, id, {
start,
end,
@@ -61,7 +61,7 @@ async function render(
[
history.all.battles,
(history.all.wins / history.all.battles) * 100,
] as Graph.PlotItem,
] as Graph.PlotItem
);
const times = histories.map((history) => history.last_battle_time);
const minTime = Math.min(...times);
@@ -82,7 +82,7 @@ async function render(
verticalMargin={{
min: minY,
max: maxY,
suffix: '%',
suffix: "%",
precision: 2,
}}
horizontalMargin={{
@@ -110,22 +110,22 @@ async function render(
export const evolutionCommand = new Promise<CommandRegistry>(
async (resolve) => {
resolve({
command: createLocalizedCommand('evolution', [
command: createLocalizedCommand("evolution", [
{
group: 'player',
group: "player",
modify(option: SlashCommandSubcommandGroupBuilder) {
addPeriodSubCommands(option, (option) =>
option.addStringOption(addUsernameChoices),
option.addStringOption(addUsernameChoices)
);
},
},
{
group: 'tank',
group: "tank",
modify(option: SlashCommandSubcommandGroupBuilder) {
addPeriodSubCommands(option, (option) =>
option
.addStringOption(addTankChoices)
.addStringOption(addUsernameChoices),
.addStringOption(addUsernameChoices)
);
},
},
@@ -136,9 +136,9 @@ export const evolutionCommand = new Promise<CommandRegistry>(
interaction.options.getSubcommandGroup() as EvolutionStatType;
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString('tank')!;
const tankIdRaw = interaction.options.getString("tank")!;
const tankId =
commandGroup === 'tank'
commandGroup === "tank"
? await resolveTankId(tankIdRaw, interaction.locale)
: null;
const path = commandToURL(interaction, {
@@ -153,13 +153,13 @@ export const evolutionCommand = new Promise<CommandRegistry>(
period,
commandGroup,
tankId,
interaction.locale,
interaction.locale
),
buttonRefresh(interaction, path),
await getBlitzStarsLinkButton(
player.region,
player.id,
tankId ?? undefined,
tankId ?? undefined
),
];
},
@@ -171,7 +171,7 @@ export const evolutionCommand = new Promise<CommandRegistry>(
async button(interaction) {
const url = new URL(`https://example.com/${interaction.customId}`);
const path = url.pathname.split('/');
const path = url.pathname.split("/");
const commandGroup = path[2] as EvolutionStatType;
const player = await resolvePlayerFromButton(interaction);
const period = resolvePeriodFromButton(player.region, interaction);
@@ -180,10 +180,10 @@ export const evolutionCommand = new Promise<CommandRegistry>(
player,
period,
commandGroup,
parseInt(url.searchParams.get('tankId') ?? '0') || null,
interaction.locale,
parseInt(url.searchParams.get("tankId") ?? "0") || null,
interaction.locale
);
},
});
},
}
);
+4 -4
View File
@@ -11,7 +11,7 @@ import { NoData } from '../components/NoData';
import { TierWeights } from '../components/TierWeights';
import { TitleBar } from '../components/TitleBar';
import { filtersToDescription } from '../core/blitzkit/filtersToDescription';
import { filterStats, StatFilters } from '../core/blitzstars/filterStats';
import { filterStats, type StatFilters } from '../core/blitzstars/filterStats';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import { getStatsInPeriod } from '../core/blitzstars/getStatsInPeriod';
import { addPeriodicFilterOptions } from '../core/discord/addPeriodicFilterOptions';
@@ -26,15 +26,15 @@ import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
import {
ResolvedPeriod,
type ResolvedPeriod,
resolvePeriodFromCommand,
} from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
import {
ResolvedPlayer,
type ResolvedPlayer,
resolvePlayerFromCommand,
} from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
import type { CommandRegistry } from '../events/interactionCreate';
async function render(
{ region, id }: ResolvedPlayer,
+1 -1
View File
@@ -11,7 +11,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { localizationObject } from "../core/discord/localizationObject";
import { resolveClanFromCommand } from "../core/discord/resolveClanFromCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
const DEFAULT_THRESHOLD = 7;
+1 -1
View File
@@ -9,7 +9,7 @@ import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { embedInfo } from '../core/discord/embedInfo';
import { resolvePlayerFromCommand } from '../core/discord/resolvePlayerFromCommand';
import { translator } from '../core/localization/translator';
import { CommandRegistry } from '../events/interactionCreate';
import type { CommandRegistry } from '../events/interactionCreate';
import { theme } from '../stitches.config';
export const verifyCommand = new Promise<CommandRegistry>((resolve) => {
+1 -1
View File
@@ -19,7 +19,7 @@ import { chunkLines } from "../core/discord/chunkLines";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import { type CommandRegistry } from "../events/interactionCreate";
export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
resolve({
+1 -1
View File
@@ -1,7 +1,7 @@
import { literals } from "@blitzkit/i18n";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
export const pingCommand = new Promise<CommandRegistry>((resolve) => {
resolve({
+1 -1
View File
@@ -22,7 +22,7 @@ import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
import { theme } from "../stitches.config";
const LEAGUE_ACCENT = [
@@ -10,13 +10,13 @@ import {
imgur,
isOnGoingRatingSeason,
LEAGUES,
RatingInfo,
type RatingInfo,
RatingLeaderboard,
Region,
type Region,
} from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import {
APIApplicationCommandOptionChoice,
type APIApplicationCommandOptionChoice,
Locale,
SlashCommandSubcommandBuilder,
} from "discord.js";
@@ -33,7 +33,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { localizationObject } from "../core/discord/localizationObject";
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
interface SimplifiedPlayer {
id: number;
+1 -1
View File
@@ -20,7 +20,7 @@ import { blitzStarsTankAverages } from '../core/blitzstars/tankAverages';
import { buttonLink } from '../core/discord/buttonLink';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { translator } from '../core/localization/translator';
import { CommandRegistry } from '../events/interactionCreate';
import { type CommandRegistry } from '../events/interactionCreate';
import { theme } from '../stitches.config';
type WotInspectorReplaySubmission =
+1 -1
View File
@@ -25,7 +25,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { localizationObject } from "../core/discord/localizationObject";
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import { type CommandRegistry } from "../events/interactionCreate";
import { theme } from "../stitches.config";
export const researchCommand = new Promise<CommandRegistry>((resolve) => {
+2 -2
View File
@@ -1,4 +1,4 @@
import { ClanList, fetchBlitz, Region } from "@blitzkit/core";
import { type ClanList, fetchBlitz, type Region } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import { Locale } from "discord.js";
import markdownEscape from "markdown-escape";
@@ -8,7 +8,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { embedInfo } from "../core/discord/embedInfo";
import { localizationObject } from "../core/discord/localizationObject";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
const DEFAULT_LIMIT = 25;
+3 -3
View File
@@ -1,7 +1,7 @@
import {
AccountList,
type AccountList,
fetchBlitz,
Region,
type Region,
usernamePattern,
} from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
@@ -13,7 +13,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { embedInfo } from "../core/discord/embedInfo";
import { localizationObject } from "../core/discord/localizationObject";
import { translator } from "../core/localization/translator";
import { CommandRegistry } from "../events/interactionCreate";
import type { CommandRegistry } from "../events/interactionCreate";
const DEFAULT_LIMIT = 25;
+32 -32
View File
@@ -1,50 +1,50 @@
import { emblemURL, getAccountInfo, getClanAccountInfo } from '@blitzkit/core';
import { Locale } from 'discord.js';
import { AllStatsOverview } from '../components/AllStatsOverview';
import { CommandWrapper } from '../components/CommandWrapper';
import { NoData } from '../components/NoData';
import { TitleBar } from '../components/TitleBar';
import { filtersToDescription } from '../core/blitzkit/filtersToDescription';
import { filterStats, StatFilters } from '../core/blitzstars/filterStats';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import { getStatsInPeriod } from '../core/blitzstars/getStatsInPeriod';
import { addPeriodicFilterOptions } from '../core/discord/addPeriodicFilterOptions';
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
import { autocompleteTanks } from '../core/discord/autocompleteTanks';
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
import { buttonRefresh } from '../core/discord/buttonRefresh';
import { commandToURL } from '../core/discord/commandToURL';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
import { emblemURL, getAccountInfo, getClanAccountInfo } from "@blitzkit/core";
import { Locale } from "discord.js";
import { AllStatsOverview } from "../components/AllStatsOverview";
import { CommandWrapper } from "../components/CommandWrapper";
import { NoData } from "../components/NoData";
import { TitleBar } from "../components/TitleBar";
import { filtersToDescription } from "../core/blitzkit/filtersToDescription";
import { filterStats, type StatFilters } from "../core/blitzstars/filterStats";
import { getBlitzStarsLinkButton } from "../core/blitzstars/getBlitzStarsLinkButton";
import { getStatsInPeriod } from "../core/blitzstars/getStatsInPeriod";
import { addPeriodicFilterOptions } from "../core/discord/addPeriodicFilterOptions";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { buttonRefresh } from "../core/discord/buttonRefresh";
import { commandToURL } from "../core/discord/commandToURL";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getCustomPeriodParams } from "../core/discord/getCustomPeriodParams";
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
import { getFiltersFromCommand } from "../core/discord/getFiltersFromCommand";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import {
ResolvedPeriod,
type ResolvedPeriod,
resolvePeriodFromCommand,
} from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
} from "../core/discord/resolvePeriodFromCommand";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import {
ResolvedPlayer,
type ResolvedPlayer,
resolvePlayerFromCommand,
} from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
} from "../core/discord/resolvePlayerFromCommand";
import type { CommandRegistry } from "../events/interactionCreate";
async function render(
{ region, id }: ResolvedPlayer,
{ start, end, name }: ResolvedPeriod,
filters: StatFilters,
locale: Locale,
locale: Locale
) {
const { nickname } = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
const diffedTankStats = await getStatsInPeriod(
region,
id,
start,
end,
locale,
locale
);
const { stats, supplementary } = await filterStats(diffedTankStats, filters);
const filterDescriptions = await filtersToDescription(filters, locale);
@@ -72,8 +72,8 @@ async function render(
export const statsCommand = new Promise<CommandRegistry>(async (resolve) => {
resolve({
command: await addPeriodicFilterOptions(
createLocalizedCommand('stats'),
(option) => option.addStringOption(addUsernameChoices),
createLocalizedCommand("stats"),
(option) => option.addStringOption(addUsernameChoices)
),
async handler(interaction) {
+1 -1
View File
@@ -14,7 +14,7 @@ import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton
import { resolvePeriodFromCommand } from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
import { resolvePlayerFromCommand } from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
import { type CommandRegistry } from '../events/interactionCreate';
import { renderBreakdown } from './breakdown/render';
export const todayCommand = new Promise<CommandRegistry>(async (resolve) => {
@@ -1,8 +1,8 @@
import { ComponentProps } from 'react';
import { type ComponentProps } from "react";
export interface GlowProps extends ComponentProps<'div'> {
export interface GlowProps extends ComponentProps<"div"> {
color: string;
direction?: 'default' | 'reverse';
direction?: "default" | "reverse";
rotation?: number;
startOpacity?: number;
endOpacity?: number;
@@ -12,7 +12,7 @@ const width = 16;
export function Glow({
color,
direction = 'default',
direction = "default",
rotation = 0,
style,
startOpacity = 0,
@@ -21,20 +21,20 @@ export function Glow({
}: GlowProps) {
const color1 = `${color}${Math.round(endOpacity * 255)
.toString(16)
.padStart(2, '0')}`;
.padStart(2, "0")}`;
const color2 = `${color}${Math.round(startOpacity * 255)
.toString(16)
.padStart(2, '0')}`;
.padStart(2, "0")}`;
const background = `linear-gradient(${
direction === 'default' ? 0 : 180
direction === "default" ? 0 : 180
}deg, ${color1} 0%, ${color2} 100%)`;
return (
<div
style={{
display: 'flex',
alignItems: direction === 'default' ? 'flex-end' : 'flex-start',
justifyContent: 'center',
display: "flex",
alignItems: direction === "default" ? "flex-end" : "flex-start",
justifyContent: "center",
transform: `rotate(${rotation}deg)`,
...style,
}}
@@ -1,7 +1,7 @@
import {
getWN8Percentile,
Percentile,
SupplementaryStats,
type SupplementaryStats,
} from '@blitzkit/core';
import { Locale } from 'discord.js';
import { translator } from '../../core/localization/translator';
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from "react";
interface RootProps {
children: ReactNode;
@@ -8,7 +8,7 @@ export function Root({ children }: RootProps) {
return (
<div
className="session-tracker-root"
style={{ display: 'flex', flexDirection: 'column', gap: 8 }}
style={{ display: "flex", flexDirection: "column", gap: 8 }}
>
{children}
</div>
@@ -6,8 +6,8 @@ import {
} from '@blitzkit/core';
import { createColors } from 'bepaint';
import {
AccentColor,
GrayColor,
type AccentColor,
type GrayColor,
PALETTES,
} from '../../../core/radix/radixColors';
import { RowStat } from './RowStat';
@@ -1,11 +1,11 @@
import { Percentile } from '@blitzkit/core';
import { createColors } from 'bepaint';
import { Percentile } from "@blitzkit/core";
import { createColors } from "bepaint";
import {
AccentColor,
GrayColor,
type AccentColor,
type GrayColor,
PALETTES,
} from '../../../core/radix/radixColors';
import { PercentileIndicator } from '../../PercentileIndicator';
} from "../../../core/radix/radixColors";
import { PercentileIndicator } from "../../PercentileIndicator";
interface RowStatProps {
name: string;
@@ -22,7 +22,7 @@ export function RowStat({
delta,
percentile,
minimized = false,
color = 'slate',
color = "slate",
}: RowStatProps) {
const theme = createColors(PALETTES[`${color}Dark`]);
@@ -30,29 +30,29 @@ export function RowStat({
<div
className="session-tracker-row-stat"
style={{
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
gap: 4,
alignItems: 'center',
justifyContent: 'center',
alignItems: "center",
justifyContent: "center",
flex: 1,
}}
>
<div
style={{
display: 'flex',
display: "flex",
gap: 4,
alignItems: 'center',
justifyContent: 'center',
alignItems: "center",
justifyContent: "center",
}}
>
{percentile === undefined && delta !== undefined && delta !== 0 && (
<img
alt={delta > 0 ? 'Increase' : 'Decrease'}
alt={delta > 0 ? "Increase" : "Decrease"}
src={
(delta ?? 0) > 0
? 'https://i.imgur.com/qbjiXa1.png'
: 'https://i.imgur.com/3uyNhun.png'
? "https://i.imgur.com/qbjiXa1.png"
: "https://i.imgur.com/3uyNhun.png"
}
style={{ width: 12, height: 12 }}
/>
@@ -66,7 +66,7 @@ export function RowStat({
color: theme.textHighContrast,
fontWeight: 700,
fontSize: 16,
textAlign: 'center',
textAlign: "center",
}}
>
{value}
@@ -77,7 +77,7 @@ export function RowStat({
<span
style={{
color: theme.textLowContrast,
textAlign: 'center',
textAlign: "center",
fontSize: 12,
}}
>
@@ -1,5 +1,5 @@
import { ReactNode } from 'react';
import { theme } from '../stitches.config';
import { type ReactNode } from "react";
import { theme } from "../stitches.config";
interface CommandWrapperProps {
children: ReactNode;
@@ -10,14 +10,14 @@ export function CommandWrapper({ children, fat }: CommandWrapperProps) {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
padding: `16px ${fat ? 0 : 16}px`,
gap: 16,
width: '100%',
width: "100%",
color: theme.colors.textHighContrast,
backgroundColor: theme.colors.appBackground1,
position: 'relative',
position: "relative",
}}
>
{children}
@@ -1,8 +1,8 @@
import {
BlitzStats,
type BlitzStats,
getWN8Percentile,
isNumber,
SupplementaryStats,
type SupplementaryStats,
} from '@blitzkit/core';
import { Locale } from 'discord.js';
import { translator } from '../../core/localization/translator';
@@ -1,5 +1,5 @@
import { GenericStat } from '..';
import { GenericStatsRow } from './GenericStatsRow';
import { type GenericStat } from "..";
import { GenericStatsRow } from "./GenericStatsRow";
interface GenericStatsColumnProps {
stats: GenericStat[];
@@ -7,7 +7,7 @@ interface GenericStatsColumnProps {
export function GenericStatsColumn({ stats }: GenericStatsColumnProps) {
return (
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
<div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
{stats.map((stat) => (
<GenericStatsRow key={stat[0]} stat={stat} />
))}
@@ -1,6 +1,6 @@
import { GenericStat } from '..';
import { theme } from '../../../stitches.config';
import { PercentileIndicator } from '../../PercentileIndicator';
import { type GenericStat } from "..";
import { theme } from "../../../stitches.config";
import { PercentileIndicator } from "../../PercentileIndicator";
interface GenericStatsRowProps {
stat: GenericStat;
@@ -10,18 +10,18 @@ export function GenericStatsRow({ stat }: GenericStatsRowProps) {
return (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<span
style={{
color: theme.colors.textLowContrast,
fontSize: 16,
whiteSpace: 'nowrap',
whiteSpace: "nowrap",
maxWidth: 128,
overflow: 'hidden',
overflow: "hidden",
}}
>
{stat[0]}
@@ -32,9 +32,9 @@ export function GenericStatsRow({ stat }: GenericStatsRowProps) {
color: theme.colors.textHighContrast,
fontWeight: 700,
fontSize: 16,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
gap: 4,
}}
>
@@ -1,6 +1,6 @@
import { times } from 'lodash-es';
import { theme } from '../../../../stitches.config';
import { MarginInputProps } from '../Root';
import { type MarginInputProps } from '../Root';
import { MarginOrientation } from './constants';
interface MarginProps extends MarginInputProps {
@@ -1,9 +1,9 @@
import { times } from 'lodash-es';
import { ReactNode } from 'react';
import { theme } from '../../../../stitches.config';
import { Margin } from '../Margin';
import { MarginOrientation } from '../Margin/constants';
import { GRAPH_HEIGHT, GRAPH_WIDTH } from './constants';
import { times } from "lodash-es";
import { type ReactNode } from "react";
import { theme } from "../../../../stitches.config";
import { Margin } from "../Margin";
import { MarginOrientation } from "../Margin/constants";
import { GRAPH_HEIGHT, GRAPH_WIDTH } from "./constants";
export interface MarginInputProps {
min: number;
@@ -32,12 +32,12 @@ export function Root({
xTitle,
}: RootProps) {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
<div
style={{
paddingLeft: 64,
display: 'flex',
justifyContent: 'space-between',
display: "flex",
justifyContent: "space-between",
}}
>
<span style={{ fontSize: 16, color: theme.colors.textHighContrast }}>
@@ -48,7 +48,7 @@ export function Root({
</span>
</div>
<div style={{ display: 'flex', gap: 16 }}>
<div style={{ display: "flex", gap: 16 }}>
{verticalMargin && (
<Margin {...verticalMargin} verticalSeparations={separations} />
)}
@@ -94,9 +94,9 @@ export function Root({
<div
style={{
paddingLeft: 64,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
@@ -1,7 +1,7 @@
import { ComponentProps } from 'react';
import { theme } from '../../../stitches.config';
import { type ComponentProps } from "react";
import { theme } from "../../../stitches.config";
interface ItemProps extends ComponentProps<'div'> {
interface ItemProps extends ComponentProps<"div"> {
position: number;
deltaPosition?: number;
score?: number;
@@ -25,15 +25,15 @@ export function Item({
<div
{...props}
style={{
cursor: 'pointer',
display: 'flex',
cursor: "pointer",
display: "flex",
padding: 8,
backgroundColor: highlight
? theme.colors.componentInteractive_blue
: theme.colors.componentInteractive,
borderRadius: 4,
alignItems: 'center',
justifyContent: 'center',
alignItems: "center",
justifyContent: "center",
gap: 8,
}}
>
@@ -50,9 +50,9 @@ export function Item({
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
gap: 4,
}}
>
@@ -83,22 +83,22 @@ export function Item({
{deltaPosition !== undefined && deltaPosition !== 0 && (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
gap: 4,
}}
>
<img
alt={deltaPosition > 0 ? 'Increase' : 'Decrease'}
alt={deltaPosition > 0 ? "Increase" : "Decrease"}
style={{
width: 8,
height: 8,
}}
src={
deltaPosition > 0
? 'https://i.imgur.com/qbjiXa1.png'
: 'https://i.imgur.com/3uyNhun.png'
? "https://i.imgur.com/qbjiXa1.png"
: "https://i.imgur.com/3uyNhun.png"
}
/>
<span
@@ -119,11 +119,11 @@ export function Item({
<div
style={{
display: 'flex',
display: "flex",
gap: 4,
alignItems: 'center',
alignItems: "center",
width: 96,
justifyContent: 'flex-end',
justifyContent: "flex-end",
}}
>
{deltaScore !== 0 && deltaScore !== undefined && (
@@ -140,15 +140,15 @@ export function Item({
)}
{deltaScore !== 0 && deltaScore !== undefined && (
<img
alt={deltaScore > 0 ? 'Increase' : 'Decrease'}
alt={deltaScore > 0 ? "Increase" : "Decrease"}
style={{
width: 8,
height: 8,
}}
src={
deltaScore > 0
? 'https://i.imgur.com/qbjiXa1.png'
: 'https://i.imgur.com/3uyNhun.png'
? "https://i.imgur.com/qbjiXa1.png"
: "https://i.imgur.com/3uyNhun.png"
}
/>
)}
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';
interface RootProps {
children: ReactNode;
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';
interface ColumnProps {
children: ReactNode;
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from "react";
interface RootProps {
children: ReactNode;
@@ -8,8 +8,8 @@ export function Root({ children }: RootProps) {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
gap: 16,
}}
>
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from "react";
interface RowProps {
children: ReactNode;
@@ -8,7 +8,7 @@ export function Row({ children }: RowProps) {
return (
<div
style={{
display: 'flex',
display: "flex",
gap: 8,
}}
>
+7 -7
View File
@@ -1,5 +1,5 @@
import { TierWeightsRecord } from '@blitzkit/core';
import { theme } from '../stitches.config';
import type { TierWeightsRecord } from "@blitzkit/core";
import { theme } from "../stitches.config";
interface TierWeightsProps {
weights: TierWeightsRecord;
@@ -7,7 +7,7 @@ interface TierWeightsProps {
export function TierWeights({ weights }: TierWeightsProps) {
return (
<div style={{ display: 'flex', gap: 8 }}>
<div style={{ display: "flex", gap: 8 }}>
{Object.entries(weights).map(([tier, weight]) => (
<div
key={tier}
@@ -15,11 +15,11 @@ export function TierWeights({ weights }: TierWeightsProps) {
backgroundColor: theme.colors.appBackground1_light,
flex: weight,
color: theme.colors.textHighContrast_light,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 16,
overflow: 'hidden',
overflow: "hidden",
borderRadius: 8,
minWidth: 16,
}}
@@ -1,7 +1,7 @@
import { fetchTankDefinitions, TIER_ROMAN_NUMERALS } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import { Locale } from "discord.js";
import { StatFilters } from "../blitzstars/filterStats";
import { type StatFilters } from "../blitzstars/filterStats";
import { translator } from "../localization/translator";
export async function filtersToDescription(
@@ -1,5 +1,5 @@
import { getTimeDaysAgo, Region } from '@blitzkit/core';
import { PeriodSize } from '../discord/addPeriodSubCommands';
import { getTimeDaysAgo, type Region } from '@blitzkit/core';
import type { PeriodSize } from '../discord/addPeriodSubCommands';
export function getPeriodStart(region: Region, period: PeriodSize) {
if (period === 'career') return 0;
+3 -3
View File
@@ -1,9 +1,9 @@
import sharp from 'sharp';
import sharp from "sharp";
const cache: Record<string, Buffer> = {};
export async function iconPng(url: string) {
if (!url.endsWith('.webp')) return url;
if (!url.endsWith(".webp")) return url;
if (!cache[url]) {
const imageResponse = await fetch(url);
@@ -12,5 +12,5 @@ export async function iconPng(url: string) {
cache[url] = imageBufferPNG;
}
return `data:image/png;base64,${cache[url].toString('base64')}`;
return `data:image/png;base64,${cache[url].toString("base64")}`;
}
+12 -12
View File
@@ -1,10 +1,10 @@
import { TankClass, TankType } from '@blitzkit/core';
import { SupplementaryStats } from '@blitzkit/core/src/blitz/getAccountInfo';
import { calculateWN8 } from '@blitzkit/core/src/statistics/calculateWN8';
import { BlitzStats } from '@blitzkit/core/src/statistics/compositeStats';
import { sumAllStats } from '@blitzkit/core/src/statistics/sumAllStats';
import { tankDefinitions } from '../blitzkit/nonBlockingPromises';
import { blitzStarsTankAverages } from './tankAverages';
import { TankClass, TankType } from "@blitzkit/core";
import type { SupplementaryStats } from "@blitzkit/core/src/blitz/getAccountInfo";
import { calculateWN8 } from "@blitzkit/core/src/statistics/calculateWN8";
import type { BlitzStats } from "@blitzkit/core/src/statistics/compositeStats";
import { sumAllStats } from "@blitzkit/core/src/statistics/sumAllStats";
import { tankDefinitions } from "../blitzkit/nonBlockingPromises";
import { blitzStarsTankAverages } from "./tankAverages";
export interface StatFilters {
nation?: string;
@@ -16,7 +16,7 @@ export interface StatFilters {
export async function filterStats(
{ diff, order }: DiffedTankStats,
filters: StatFilters,
filters: StatFilters
) {
// tank, if provided, takes priority over all other filters
if (filters.tank) filters = { tank: filters.tank };
@@ -45,14 +45,14 @@ export async function filterStats(
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
(accumulator, id) =>
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
0,
0
);
const battlesOfTanksWithTankDefinition = filteredOrder.reduce<number>(
(accumulator, id) =>
awaitedTankDefinitions.tanks[id]
? accumulator + diff[id].battles
: accumulator,
0,
0
);
const supplementary = {
WN8:
@@ -63,7 +63,7 @@ export async function filterStats(
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
diff[id].battles
: accumulator,
0,
0
) / battlesOfTanksWithAverages,
tier:
filteredOrder.reduce<number>(
@@ -72,7 +72,7 @@ export async function filterStats(
? accumulator +
awaitedTankDefinitions.tanks[id]!.tier * diff[id].battles
: accumulator,
0,
0
) / battlesOfTanksWithTankDefinition,
} satisfies SupplementaryStats;
@@ -1,17 +1,17 @@
import { getAccountInfo, Region } from '@blitzkit/core';
import { buttonLink } from '../discord/buttonLink';
import { getAccountInfo, type Region } from "@blitzkit/core";
import { buttonLink } from "../discord/buttonLink";
export async function getBlitzStarsLinkButton(
region: Region,
id: number,
tankId?: number,
tankId?: number
) {
const { nickname } = await getAccountInfo(region, id);
return buttonLink(
`https://www.blitzstars.com/player/${region}/${nickname}${
tankId ? `/tank/${tankId!}` : ''
tankId ? `/tank/${tankId!}` : ""
}`,
'BlitzStars',
"BlitzStars"
);
}
@@ -1,11 +1,11 @@
import { Region, emptyAllStats, getAccountInfo } from '@blitzkit/core';
import { type Region, emptyAllStats, getAccountInfo } from '@blitzkit/core';
import {
GetHistoriesOptions,
Histories,
History,
type GetHistoriesOptions,
type Histories,
type History,
getHistoriesDefaultOptions,
} from '../../types/histories';
import { PlayerStats } from './getPlayerStats';
import type { PlayerStats } from './getPlayerStats';
export async function getPlayerHistories(
server: Region,
@@ -1,4 +1,4 @@
import { BlitzStats, Region } from '@blitzkit/core';
import type { BlitzStats, Region } from "@blitzkit/core";
interface IndividualPlayerStats {
clan: { clan_id: number; name: string; tag: string };
@@ -25,13 +25,13 @@ export async function getPlayerStats<
ReturnType = Ids extends number ? PlayerStats : PlayerStats[],
>(region: Region, ids: Ids) {
const stats = await Promise.all(
((typeof ids === 'number' ? [ids] : ids) as number[]).map((id) =>
((typeof ids === "number" ? [ids] : ids) as number[]).map((id) =>
fetch(`https://www.blitzstars.com/api/playerstats/${id}`).then(
(response) => response.json() as Promise<PlayerStats>,
),
),
(response) => response.json() as Promise<PlayerStats>
)
)
);
if (typeof ids === 'number') return stats[0] as ReturnType;
if (typeof ids === "number") return stats[0] as ReturnType;
return stats as ReturnType;
}
@@ -1,11 +1,11 @@
import { BlitzStats, emptyAllStats, Region } from '@blitzkit/core';
import { Locale } from 'discord.js';
import { DiffedTankStats } from './filterStats';
import { type BlitzStats, emptyAllStats, type Region } from "@blitzkit/core";
import { Locale } from "discord.js";
import type { DiffedTankStats } from "./filterStats";
import {
getTankHistories,
TankHistories,
TankHistoryRaw,
} from './getTankHistories';
type TankHistories,
type TankHistoryRaw,
} from "./getTankHistories";
const emptyTankHistoryNode: TankHistoryRaw = {
account_id: 0,
@@ -22,7 +22,7 @@ export async function getStatsInPeriod(
id: number,
start: number,
end: number,
locale: Locale,
locale: Locale
) {
const history = await getTankHistories(server, id, locale, {
includeLatestHistories: true,
@@ -43,8 +43,8 @@ export async function getStatsInPeriod(
// find the ones played within the range
const inRangeTanks = tanks.filter((tankId) =>
tankSortedHistory[tankId].some(
(node) => node.last_battle_time > start && node.last_battle_time < end,
),
(node) => node.last_battle_time > start && node.last_battle_time < end
)
);
const playedTanks: number[] = [];
@@ -1,13 +1,13 @@
import { Region, emptyAllStats, getTankStats } from '@blitzkit/core';
import { Locale } from 'discord.js';
import { type Region, emptyAllStats, getTankStats } from "@blitzkit/core";
import { Locale } from "discord.js";
import {
GetHistoriesOptions,
Histories,
History,
type GetHistoriesOptions,
type Histories,
type History,
getHistoriesDefaultOptions,
} from '../../types/histories';
import { UserError } from '../blitzkit/userError';
import { translator } from '../localization/translator';
} from "../../types/histories";
import { UserError } from "../blitzkit/userError";
import { translator } from "../localization/translator";
export interface TankHistory extends History {
tank_id: number;
@@ -36,12 +36,12 @@ export async function getTankHistories(
server: Region,
id: number,
locale: Locale,
options?: Partial<GetTankHistoriesOptions>,
options?: Partial<GetTankHistoriesOptions>
) {
const { strings } = translator(locale);
const mergedOptions = { ...getTankHistoriesDefaultOptions, ...options };
const tankHistoriesResponse = await fetch(
`https://www.blitzstars.com/api/tankhistories/for/${id}/`,
`https://www.blitzstars.com/api/tankhistories/for/${id}/`
);
const tankHistories = (
(await tankHistoriesResponse.json()) as TankHistoriesRaw
@@ -51,7 +51,7 @@ export async function getTankHistories(
all: history.all,
last_battle_time: history.last_battle_time,
tank_id: history.tank_id,
}) satisfies TankHistory,
}) satisfies TankHistory
);
const compliantTanks: number[] = [];
const lastBattles: Record<number, number> = {};
@@ -73,7 +73,7 @@ export async function getTankHistories(
lastBattles[tank_id] = battles;
return complies;
},
}
);
const latestNodes: TankHistories = [];
@@ -112,7 +112,7 @@ export async function getTankHistories(
all: emptyAllStats,
last_battle_time: -Infinity,
tank_id: tankId,
} satisfies TankHistory),
} satisfies TankHistory)
);
}
});
@@ -4,7 +4,7 @@ import {
TANK_TYPES,
} from '@blitzkit/core';
import {
APIApplicationCommandOptionChoice,
type APIApplicationCommandOptionChoice,
Locale,
SlashCommandBuilder,
SlashCommandSubcommandBuilder,
@@ -1,11 +1,11 @@
import { REGIONS } from '@blitzkit/core';
import { REGIONS } from "@blitzkit/core";
import {
APIApplicationCommandOptionChoice,
type APIApplicationCommandOptionChoice,
Locale,
SlashCommandStringOption,
} from 'discord.js';
import { translator } from '../localization/translator';
import { localizationObject } from './localizationObject';
} from "discord.js";
import { translator } from "../localization/translator";
import { localizationObject } from "./localizationObject";
export function addRegionChoices(option: SlashCommandStringOption) {
const { strings } = translator(Locale.EnglishUS);
@@ -16,14 +16,14 @@ export function addRegionChoices(option: SlashCommandStringOption) {
localizationObject(
(strings) => strings.bot.common.options.region.name,
undefined,
true,
),
true
)
)
.setDescription(strings.bot.common.options.region.description)
.setDescriptionLocalizations(
localizationObject(
(strings) => strings.bot.common.options.region.description,
),
(strings) => strings.bot.common.options.region.description
)
)
.addChoices(
...REGIONS.map(
@@ -32,10 +32,10 @@ export function addRegionChoices(option: SlashCommandStringOption) {
value: region,
name: strings.common.regions.normal[region],
name_localizations: localizationObject(
(strings) => strings.common.regions.normal[region],
(strings) => strings.common.regions.normal[region]
),
}) satisfies APIApplicationCommandOptionChoice,
),
}) satisfies APIApplicationCommandOptionChoice
)
)
.setRequired(true);
}
@@ -1,25 +1,25 @@
import { fetchTankNames, SEARCH_KEYS, TankType } from '@blitzkit/core';
import { fetchTankNames, SEARCH_KEYS, TankType } from "@blitzkit/core";
import {
ApplicationCommandOptionChoiceData,
type ApplicationCommandOptionChoiceData,
AutocompleteInteraction,
CacheType,
} from 'discord.js';
import { go } from 'fuzzysort';
import { tankNames } from '../blitzkit/nonBlockingPromises';
import { translator } from '../localization/translator';
type CacheType,
} from "discord.js";
import { go } from "fuzzysort";
import { tankNames } from "../blitzkit/nonBlockingPromises";
import { translator } from "../localization/translator";
import {
DISCORD_CHOICES_MAX_NAME_SIZE,
OVERFLOW_SUFFIX,
} from './autocompleteClan/constants';
} from "./autocompleteClan/constants";
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE),
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE)
);
export async function autocompleteTanks(
interaction: AutocompleteInteraction<CacheType>,
techTreeOnly = false,
fields = ['tank'],
fields = ["tank"]
) {
const { unwrap } = translator(interaction.locale);
const focusedOption = interaction.options.getFocused(true);
@@ -31,7 +31,7 @@ export async function autocompleteTanks(
go(
focusedOption.value,
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
{ keys: SEARCH_KEYS, limit: 10 },
{ keys: SEARCH_KEYS, limit: 10 }
).map(async (item) => {
let name = unwrap(item.obj.searchableName);
@@ -42,7 +42,7 @@ export async function autocompleteTanks(
0,
unwrap(item.obj.searchableName).length -
overSize -
OVERFLOW_SUFFIX.length,
OVERFLOW_SUFFIX.length
)}${OVERFLOW_SUFFIX}`;
}
@@ -50,8 +50,8 @@ export async function autocompleteTanks(
name,
value: `${item.obj.id}`,
} satisfies ApplicationCommandOptionChoiceData<string>;
}),
})
)
: [],
: []
);
}
+3 -3
View File
@@ -1,13 +1,13 @@
import {
ButtonBuilder,
ButtonStyle,
ComponentEmojiResolvable,
} from 'discord.js';
type ComponentEmojiResolvable,
} from "discord.js";
export function buttonLink(
url: string,
label: string,
emoji?: ComponentEmojiResolvable,
emoji?: ComponentEmojiResolvable
) {
const button = new ButtonBuilder()
.setStyle(ButtonStyle.Link)
@@ -1,13 +1,13 @@
import {
ButtonBuilder,
ButtonStyle,
ComponentEmojiResolvable,
} from 'discord.js';
type ComponentEmojiResolvable,
} from "discord.js";
export function buttonPrimary(
id: string,
label: string,
emoji?: ComponentEmojiResolvable,
emoji?: ComponentEmojiResolvable
) {
const button = new ButtonBuilder()
.setCustomId(id)
@@ -1,4 +1,4 @@
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
export interface Parameters {
[key: string]: string | number | boolean | undefined | null;
@@ -9,7 +9,7 @@ export interface Parameters {
export function commandToURL(
interaction: ChatInputCommandInteraction<CacheType>,
parameters?: Parameters,
parameters?: Parameters
) {
const pathname = [
interaction.commandName,
@@ -17,11 +17,11 @@ export function commandToURL(
interaction.options.getSubcommand(false),
]
.filter(Boolean)
.join('/');
.join("/");
const params = (parameters ? Object.entries(parameters) : [])
.filter(([, value]) => value !== undefined && value !== null)
.map(([key, value]) => `${key}=${value}`)
.join('&');
.join("&");
return `${pathname}${params.length > 0 ? `?${params}` : ''}`;
return `${pathname}${params.length > 0 ? `?${params}` : ""}`;
}
@@ -1,12 +1,12 @@
import { BlitzKitStrings } from '@blitzkit/i18n';
import { type BlitzKitStrings } from "@blitzkit/i18n";
import {
Locale,
SlashCommandBuilder,
SlashCommandSubcommandBuilder,
SlashCommandSubcommandGroupBuilder,
} from 'discord.js';
import { translator } from '../localization/translator';
import { localizationObject } from './localizationObject';
} from "discord.js";
import { translator } from "../localization/translator";
import { localizationObject } from "./localizationObject";
interface CreateLocalizedCommandSubcommand {
subcommand: string;
@@ -22,12 +22,12 @@ export function createLocalizedCommand(
command: string,
sub?:
| CreateLocalizedCommandSubcommand[]
| CreateLocalizedCommandSubcommandGroup[],
| CreateLocalizedCommandSubcommandGroup[]
) {
const commandPathItem = command.replaceAll(
'-',
'_',
) as keyof BlitzKitStrings['bot']['commands'];
"-",
"_"
) as keyof BlitzKitStrings["bot"]["commands"];
const { strings } = translator(Locale.EnglishUS);
const slashCommand = new SlashCommandBuilder()
.setName(command)
@@ -35,19 +35,19 @@ export function createLocalizedCommand(
localizationObject(
(strings) => strings.bot.commands[commandPathItem].name,
undefined,
true,
),
true
)
)
.setDescription(strings.bot.commands[commandPathItem].description)
.setDescriptionLocalizations(
localizationObject(
(strings) => strings.bot.commands[commandPathItem].description,
),
(strings) => strings.bot.commands[commandPathItem].description
)
);
if (sub) {
sub.map((subItem) => {
if ('subcommand' in subItem) {
if ("subcommand" in subItem) {
const subcommandNameLocalizations = localizationObject(
(strings) =>
(
@@ -56,7 +56,7 @@ export function createLocalizedCommand(
}
).subcommands[subItem.subcommand].name,
undefined,
true,
true
);
const subcommandDescriptionLocalizations = localizationObject(
(strings) =>
@@ -64,7 +64,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
subcommands: Record<string, { description: string }>;
}
).subcommands[subItem.subcommand].description,
).subcommands[subItem.subcommand].description
);
slashCommand.addSubcommand((option) => {
@@ -78,7 +78,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
subcommands: Record<string, { description: string }>;
}
).subcommands[subItem.subcommand].description,
).subcommands[subItem.subcommand].description
)
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
});
@@ -91,7 +91,7 @@ export function createLocalizedCommand(
}
).groups[subItem.group].name,
undefined,
true,
true
);
const subcommandDescriptionLocalizations = localizationObject(
(strings) =>
@@ -99,7 +99,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
groups: Record<string, { description: string }>;
}
).groups[subItem.group].description,
).groups[subItem.group].description
);
slashCommand.addSubcommandGroup((option) => {
@@ -113,7 +113,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
groups: Record<string, { description: string }>;
}
).groups[subItem.group].description,
).groups[subItem.group].description
)
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
});
@@ -1,17 +1,17 @@
import { ChatInputCommandInteraction } from 'discord.js';
import { PeriodType } from './addPeriodSubCommands';
import { ChatInputCommandInteraction } from "discord.js";
import type { PeriodType } from "./addPeriodSubCommands";
export function getCustomPeriodParams(
interaction: ChatInputCommandInteraction,
forcedNonCustomPeriod = false,
forcedNonCustomPeriod = false
) {
if (
!forcedNonCustomPeriod &&
(interaction.options.getSubcommand() as PeriodType) === 'custom'
(interaction.options.getSubcommand() as PeriodType) === "custom"
) {
return {
start: interaction.options.getInteger('start', true),
end: interaction.options.getInteger('end', true),
start: interaction.options.getInteger("start", true),
end: interaction.options.getInteger("end", true),
};
}
@@ -1,19 +1,19 @@
import { TankClass, TankType } from '@blitzkit/core';
import { ButtonInteraction } from 'discord.js';
import { StatFilters } from '../blitzstars/filterStats';
import { TankClass, TankType } from "@blitzkit/core";
import { ButtonInteraction } from "discord.js";
import type { StatFilters } from "../blitzstars/filterStats";
export function getFiltersFromButton(interaction: ButtonInteraction) {
const url = new URL(`https://example.com/${interaction.customId}`);
return {
nation: url.searchParams.get('nation') ?? undefined,
tank: parseInt(url.searchParams.get('tank') ?? '0') || undefined,
nation: url.searchParams.get("nation") ?? undefined,
tank: parseInt(url.searchParams.get("tank") ?? "0") || undefined,
class:
(Number(url.searchParams.get('class')) as TankClass | undefined) ??
(Number(url.searchParams.get("class")) as TankClass | undefined) ??
undefined,
type:
(Number(url.searchParams.get('type')) as TankType | undefined) ??
(Number(url.searchParams.get("type")) as TankType | undefined) ??
undefined,
tier: parseInt(url.searchParams.get('tier') ?? '0') || undefined,
tier: parseInt(url.searchParams.get("tier") ?? "0") || undefined,
} satisfies StatFilters;
}
@@ -1,6 +1,6 @@
import { ChatInputCommandInteraction } from 'discord.js';
import { resolveTankId } from '../blitz/resolveTankId';
import { StatFilters } from '../blitzstars/filterStats';
import type { StatFilters } from '../blitzstars/filterStats';
export async function getFiltersFromCommand(
interaction: ChatInputCommandInteraction,
@@ -1,7 +1,7 @@
import { literals } from "@blitzkit/i18n";
import { Locale } from "discord.js";
import { translator } from "../localization/translator";
import { PeriodSize } from "./addPeriodSubCommands";
import type { PeriodSize } from "./addPeriodSubCommands";
export function getPeriodOptionName(period: PeriodSize, locale: Locale) {
const { strings } = translator(locale);
@@ -1,4 +1,4 @@
import { BlitzKitStrings, literals as literalsFunc } from "@blitzkit/i18n";
import { type BlitzKitStrings, literals as literalsFunc } from "@blitzkit/i18n";
import { Locale } from "discord.js";
import { SUPPORTED_LOCALES_DISCORD } from "../localization/strings/constants";
import { translator } from "../localization/translator";
@@ -3,12 +3,12 @@ import {
AttachmentBuilder,
ButtonBuilder,
EmbedBuilder,
InteractionEditReplyOptions,
InteractionReplyOptions,
MessageEditOptions,
type InteractionEditReplyOptions,
type InteractionReplyOptions,
type MessageEditOptions,
} from "discord.js";
import { InteractionReturnable } from "../../events/interactionCreate";
import { Writeable } from "../../types/writable";
import type { InteractionReturnable } from "../../events/interactionCreate";
import type { Writeable } from "../../types/writable";
import { jsxToPngThreaded } from "../blitzkit/jsxToPngThreaded";
import { RenderConfiguration } from "../blitzkit/renderConfiguration";
@@ -1,4 +1,4 @@
import { Region } from "@blitzkit/core";
import type { Region } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import { ChatInputCommandInteraction } from "discord.js";
import markdownEscape from "markdown-escape";
@@ -1,25 +1,25 @@
import { getTimeDaysAgo, Region } from '@blitzkit/core';
import { ButtonInteraction } from 'discord.js';
import { getPeriodNow } from '../blitzkit/getPeriodNow';
import { getPeriodStart } from '../blitzkit/getPeriodStart';
import { PeriodType } from './addPeriodSubCommands';
import { getPeriodOptionName } from './getPeriodOptionName';
import { ResolvedPeriod } from './resolvePeriodFromCommand';
import { getTimeDaysAgo, type Region } from "@blitzkit/core";
import { ButtonInteraction } from "discord.js";
import { getPeriodNow } from "../blitzkit/getPeriodNow";
import { getPeriodStart } from "../blitzkit/getPeriodStart";
import type { PeriodType } from "./addPeriodSubCommands";
import { getPeriodOptionName } from "./getPeriodOptionName";
import type { ResolvedPeriod } from "./resolvePeriodFromCommand";
export function resolvePeriodFromButton(
region: Region,
interaction: ButtonInteraction,
interaction: ButtonInteraction
) {
let name: string;
let start: number;
let end: number;
const url = new URL(`https://example.com/${interaction.customId}`);
const path = url.pathname.split('/');
const path = url.pathname.split("/");
const periodSubcommand = path.at(-1) as PeriodType;
if (periodSubcommand === 'custom') {
const startRaw = parseInt(url!.searchParams.get('start')!);
const endRaw = parseInt(url!.searchParams.get('end')!);
if (periodSubcommand === "custom") {
const startRaw = parseInt(url!.searchParams.get("start")!);
const endRaw = parseInt(url!.searchParams.get("end")!);
const startDaysAgoMin = Math.min(startRaw, endRaw);
const endDaysAgoMax = Math.max(startRaw, endRaw);
@@ -1,10 +1,10 @@
import { getTimeDaysAgo, Region } from "@blitzkit/core";
import { getTimeDaysAgo, type Region } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import { CacheType, ChatInputCommandInteraction } from "discord.js";
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
import { getPeriodNow } from "../blitzkit/getPeriodNow";
import { getPeriodStart } from "../blitzkit/getPeriodStart";
import { translator } from "../localization/translator";
import { PeriodType } from "./addPeriodSubCommands";
import type { PeriodType } from "./addPeriodSubCommands";
import { getPeriodOptionName } from "./getPeriodOptionName";
export interface ResolvedPeriod {
@@ -1,12 +1,12 @@
import { Region } from '@blitzkit/core';
import { ButtonInteraction } from 'discord.js';
import { ResolvedPlayer } from './resolvePlayerFromCommand';
import type { Region } from "@blitzkit/core";
import { ButtonInteraction } from "discord.js";
import type { ResolvedPlayer } from "./resolvePlayerFromCommand";
export async function resolvePlayerFromButton(interaction: ButtonInteraction) {
const url = new URL(`https://exmaple.com/${interaction.customId}`);
return {
id: parseInt(url.searchParams.get('id')!),
region: url.searchParams.get('region') as Region,
id: parseInt(url.searchParams.get("id")!),
region: url.searchParams.get("region") as Region,
} satisfies ResolvedPlayer;
}
@@ -1,6 +1,6 @@
import { idToRegion, Region } from "@blitzkit/core";
import { idToRegion, type Region } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n";
import { CacheType, ChatInputCommandInteraction } from "discord.js";
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
import markdownEscape from "markdown-escape";
import { searchPlayersAcrossRegionsBotWrapper } from "../../blitz/searchPlayersAcrossRegionsBotWrapper";
import { getBlitzFromDiscord } from "../../blitzkit/getBlitzFromDiscord";
+38 -38
View File
@@ -1,52 +1,52 @@
import * as colors from '@radix-ui/colors';
import { Theme } from '@radix-ui/themes';
import { ComponentProps } from 'react';
import * as colors from "@radix-ui/colors";
import { Theme } from "@radix-ui/themes";
import type { ComponentProps } from "react";
export type AccentColor = Exclude<
ComponentProps<typeof Theme>['accentColor'],
'gray' | undefined
ComponentProps<typeof Theme>["accentColor"],
"gray" | undefined
>;
export type AccentColorDark = `${AccentColor}Dark`;
export type GrayColor = Exclude<
ComponentProps<typeof Theme>['grayColor'],
'auto' | undefined
ComponentProps<typeof Theme>["grayColor"],
"auto" | undefined
>;
export type GrayColorDark = `${GrayColor}Dark`;
export const ACCENT_COLORS: AccentColor[] = [
'tomato',
'red',
'ruby',
'crimson',
'pink',
'plum',
'purple',
'violet',
'iris',
'indigo',
'blue',
'cyan',
'teal',
'jade',
'green',
'grass',
'brown',
'orange',
'sky',
'mint',
'lime',
'yellow',
'amber',
'gold',
'bronze',
"tomato",
"red",
"ruby",
"crimson",
"pink",
"plum",
"purple",
"violet",
"iris",
"indigo",
"blue",
"cyan",
"teal",
"jade",
"green",
"grass",
"brown",
"orange",
"sky",
"mint",
"lime",
"yellow",
"amber",
"gold",
"bronze",
];
export const GRAY_COLORS: GrayColor[] = [
'gray',
'mauve',
'slate',
'sage',
'olive',
'sand',
"gray",
"mauve",
"slate",
"sage",
"olive",
"sand",
];
export const PALETTES: Record<
@@ -3,21 +3,21 @@ import {
AttachmentBuilder,
ButtonBuilder,
ButtonStyle,
CacheType,
type CacheType,
ChatInputCommandInteraction,
InteractionReplyOptions,
} from 'discord.js';
import { InteractionRawReturnable, commands } from '..';
import { UserError } from '../../../core/blitzkit/userError';
import { buttonLink } from '../../../core/discord/buttonLink';
import { embedWarning } from '../../../core/discord/embedWarning';
import { normalizeInteractionReturnable } from '../../../core/discord/normalizeInteractionReturnable';
import { psa } from '../../../core/discord/psa';
import { translator } from '../../../core/localization/translator';
import { Writeable } from '../../../types/writable';
type InteractionReplyOptions,
} from "discord.js";
import { type InteractionRawReturnable, commands } from "..";
import { UserError } from "../../../core/blitzkit/userError";
import { buttonLink } from "../../../core/discord/buttonLink";
import { embedWarning } from "../../../core/discord/embedWarning";
import { normalizeInteractionReturnable } from "../../../core/discord/normalizeInteractionReturnable";
import { psa } from "../../../core/discord/psa";
import { translator } from "../../../core/localization/translator";
import type { Writeable } from "../../../types/writable";
export async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>,
interaction: ChatInputCommandInteraction<CacheType>
) {
await interaction.deferReply();
@@ -33,10 +33,10 @@ export async function handleChatInputCommand(
(Array.isArray(returnable) ? returnable : [returnable]).forEach(
(object) => {
if (typeof object === 'string') {
if (typeof object === "string") {
chunks.push([object]);
} else chunks.at(-1)?.push(object!);
},
}
);
let index = 0;
@@ -49,17 +49,17 @@ export async function handleChatInputCommand(
(psa.data.commands === undefined ||
psa.data.commands.includes(interaction.commandName))
) {
if (psa.data.type === undefined || psa.data.type === 'embed') {
if (psa.data.type === undefined || psa.data.type === "embed") {
if (!reply.embeds) reply.embeds = [];
const embed = embedWarning(psa.data.title, psa.data.description);
if (psa.data.image) embed.setImage(psa.data.image);
(reply.embeds as Writeable<typeof reply.embeds>).push(embed);
} else if (psa.data.type === 'image') {
} else if (psa.data.type === "image") {
if (!reply.files) reply.files = [];
(reply.files as Writeable<typeof reply.files>).push(
new AttachmentBuilder(psa.data.image),
new AttachmentBuilder(psa.data.image)
);
reply.content = reply.content ?? psa.data.title;
}
@@ -72,7 +72,7 @@ export async function handleChatInputCommand(
(
reply.components[0] as ActionRowBuilder<ButtonBuilder>
).addComponents(
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
psa.data.links.map(({ title, url }) => buttonLink(url, title))
);
}
}
@@ -93,17 +93,17 @@ export async function handleChatInputCommand(
ephemeral: true,
};
if (psa.data.type === undefined || psa.data.type === 'embed') {
if (psa.data.type === undefined || psa.data.type === "embed") {
if (!followUp.embeds) followUp.embeds = [];
const embed = embedWarning(psa.data.title, psa.data.description);
if (psa.data.image) embed.setImage(psa.data.image);
(followUp.embeds as Writeable<typeof followUp.embeds>).push(embed);
} else if (psa.data.type === 'image') {
} else if (psa.data.type === "image") {
if (!followUp.files) followUp.files = [];
(followUp.files as Writeable<typeof followUp.files>).push(
new AttachmentBuilder(psa.data.image),
new AttachmentBuilder(psa.data.image)
);
followUp.content = followUp.content ?? psa.data.title;
}
@@ -116,7 +116,7 @@ export async function handleChatInputCommand(
(
followUp.components[0] as ActionRowBuilder<ButtonBuilder>
).addComponents(
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
psa.data.links.map(({ title, url }) => buttonLink(url, title))
);
}
@@ -132,8 +132,8 @@ export async function handleChatInputCommand(
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setLabel(strings.bot.common.errors.get_help)
.setURL('https://discord.gg/nDt7AjGJQH')
.setStyle(ButtonStyle.Link),
.setURL("https://discord.gg/nDt7AjGJQH")
.setStyle(ButtonStyle.Link)
),
];
if (error instanceof UserError) {
@@ -4,15 +4,15 @@ import {
AutocompleteInteraction,
ButtonBuilder,
ButtonInteraction,
CacheType,
type CacheType,
ChatInputCommandInteraction,
EmbedBuilder,
Interaction,
type Interaction,
REST,
Routes,
SlashCommandBuilder,
SlashCommandOptionsOnlyBuilder,
SlashCommandSubcommandsOnlyBuilder,
type SlashCommandOptionsOnlyBuilder,
type SlashCommandSubcommandsOnlyBuilder,
} from "discord.js";
import { aboutCommand } from "../../commands/about";
import { breakdownCommand } from "../../commands/breakdown";
+1 -1
View File
@@ -1,6 +1,6 @@
// a cleaner simplification of Blitz Stars' histories because it's a mess there
import { BlitzStats } from '@blitzkit/core';
import { type BlitzStats } from '@blitzkit/core';
export interface History {
all: BlitzStats;
+1
Submodule packages/closed added at 5b4a85d503.
+10 -4
View File
@@ -4,20 +4,26 @@
"type": "module",
"main": "src/index.ts",
"dependencies": {
"@blitzkit/i18n": "workspace:*",
"@bufbuild/protobuf": "^2.9.0",
"@octokit/plugin-throttling": "^11.0.1",
"@octokit/rest": "^22.0.0",
"@prisma/client": "^6.16.2",
"@types/adm-zip": "^0.5.7",
"@types/bun": "^1.3.1",
"@types/lodash-es": "^4.17.12",
"@types/lz4js": "^0.2.1",
"@types/three": "^0.180.0",
"adm-zip": "^0.5.16",
"crc": "^4.3.2",
"dotenv": "^17.2.2",
"fast-xml-parser": "^5.3.2",
"lodash-es": "^4.17.21",
"lz4js": "^0.2.0",
"pickleparser": "^0.2.1",
"protobufjs": "^7.5.4",
"three": "^0.180.0",
"ts-proto": "^2.7.7",
"yaml": "^2.8.1"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7",
"@types/lz4js": "^0.2.1"
}
}
+25
View File
@@ -0,0 +1,25 @@
export enum BlitzVFSSourceType {
Steam,
}
type BlitzVFSSource = {
type: BlitzVFSSourceType;
username: string;
password: string;
app: number;
os: "windows";
};
export class BlitzVFS {
constructor(private source: BlitzVFSSource) {}
async init() {
return this;
}
async file(path: string) {
return new Uint8Array();
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { type ShellDefinition, ShellType } from '@blitzkit/core';
import { ShellDefinition, ShellType } from "../protos";
export function canSplash(type: ShellDefinition['type']): type is ShellType.HE {
export function canSplash(type: ShellDefinition["type"]): type is ShellType.HE {
return type === ShellType.HE;
}
+5 -5
View File
@@ -1,5 +1,5 @@
import { TankClass, TankType } from '../protos';
import { BlitzStats } from '../statistics';
import { TankClass, TankType } from "../protos";
import type { BlitzStats } from "../statistics";
export const TANK_TYPES = [
TankType.RESEARCHABLE,
@@ -8,9 +8,9 @@ export const TANK_TYPES = [
];
export const TANK_TYPE_COMMAND_NAMES = {
[TankType.RESEARCHABLE]: 'researchable',
[TankType.PREMIUM]: 'premium',
[TankType.COLLECTOR]: 'collector',
[TankType.RESEARCHABLE]: "researchable",
[TankType.PREMIUM]: "premium",
[TankType.COLLECTOR]: "collector",
};
export const TANK_CLASSES = [
+1 -1
View File
@@ -1,4 +1,4 @@
import { Vector3Tuple } from 'three';
import type { Vector3Tuple } from "three";
export const equipmentPriceMatrix: Record<number, Vector3Tuple> = {
1: [100, 200, 300],
+11 -11
View File
@@ -1,19 +1,19 @@
import { assertSecret, EventManager } from '../blitzkit';
import { patientFetch } from '../blitzkit/patientFetch';
import { Region } from './regions';
import { assertSecret, EventManager } from "../blitzkit";
import { patientFetch } from "../blitzkit/patientFetch";
import type { Region } from "./regions";
const RETRY_ERRORS = ['REQUEST_LIMIT_EXCEEDED', 'SOURCE_NOT_AVAILABLE'];
const RETRY_ERRORS = ["REQUEST_LIMIT_EXCEEDED", "SOURCE_NOT_AVAILABLE"];
export const retryAbleBlitzFetchEvent = new EventManager();
export const blitzFetchQueueAvailableEvent = new EventManager();
type BlitzResponse<Data extends object> =
| {
status: 'error';
status: "error";
error: { field: string; message: string; code: 402; value: null };
}
| {
status: 'ok';
status: "ok";
data: Data;
};
@@ -36,11 +36,11 @@ async function manageQueue() {
const request = queue.shift()!;
const data = (await patientFetch(request.url)
.then((response) => response.json())
.catch((error) => ({ status: 'error', error }))) as BlitzResponse<
.catch((error) => ({ status: "error", error }))) as BlitzResponse<
typeof request.resolve
>;
if (data.status === 'ok') {
if (data.status === "ok") {
request.resolve(data.data);
} else {
if (RETRY_ERRORS.includes(data.error.message)) {
@@ -67,19 +67,19 @@ export type FetchBlitzParams = Record<string, string | number | undefined>;
export function fetchBlitz<Data extends object>(
region: Region,
path: string,
params: FetchBlitzParams = {},
params: FetchBlitzParams = {}
) {
return new Promise<Data>((resolve) => {
queue.push({
url: `https://api.wotblitz.${region}/wotb/${path}/?${Object.entries({
application_id: assertSecret(
import.meta.env.PUBLIC_WARGAMING_APPLICATION_ID,
import.meta.env.PUBLIC_WARGAMING_APPLICATION_ID
),
...params,
})
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => `${key}=${encodeURIComponent(value!)}`)
.join('&')}`,
.join("&")}`,
resolve(data) {
resolve(data as Data);
},
+4 -4
View File
@@ -1,11 +1,11 @@
import { assertSecret } from '../blitzkit';
import { BlitzGlossary } from '../types';
import { assertSecret } from "../blitzkit";
import type { BlitzGlossary } from "../types";
export async function fetchGlossary(locale: string) {
const response = await fetch(
`${assertSecret(
import.meta.env.WOTB_GLOSSARY_DOMAIN,
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`,
import.meta.env.WOTB_GLOSSARY_DOMAIN
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`
);
return (await response.json()) as BlitzGlossary;
}
+8 -8
View File
@@ -1,14 +1,14 @@
import { BlitzStats, calculateWN8 } from '@blitzkit/core';
import { type BlitzStats, calculateWN8 } from "../statistics";
export type Stat = keyof ReturnType<typeof generateStats>;
export const STAT_NAMES: Record<Stat, string> = {
battles: 'Battles',
winrate: 'Winrate',
wn8: 'WN8',
averageDamage: 'Damage',
damage: 'Accumulated damage',
wins: 'Wins',
battles: "Battles",
winrate: "Winrate",
wn8: "WN8",
averageDamage: "Damage",
damage: "Accumulated damage",
wins: "Wins",
};
export const STAT_KEYS = Object.keys(STAT_NAMES) as Stat[];
@@ -29,7 +29,7 @@ export function prettifyStats(s: ReturnType<typeof generateStats>) {
battles: `${s.battles}`,
wins: `${s.wins}`,
winrate: `${(s.winrate * 100).toFixed(0)}%`,
wn8: s.wn8 ? s.wn8.toFixed(0) : '--',
wn8: s.wn8 ? s.wn8.toFixed(0) : "--",
damage: `${s.damage}`,
averageDamage: s.averageDamage.toFixed(0),
} satisfies Record<Stat, string>;
@@ -1,5 +1,6 @@
import { fetchBlitz, Region } from '@blitzkit/core';
import { normalizeIds } from './normalizeIds';
import { fetchBlitz } from "./fetchBlitz";
import { normalizeIds } from "./normalizeIds";
import type { Region } from "./regions";
interface IndividualAccountAchievements {
achievements: {
@@ -22,11 +23,11 @@ export async function getAccountAchievements<
>(region: Region, ids: Ids) {
const object = await fetchBlitz<AccountAchievements>(
region,
'account/achievements',
{ account_id: normalizeIds(ids) },
"account/achievements",
{ account_id: normalizeIds(ids) }
);
if (typeof ids === 'number') {
if (typeof ids === "number") {
return object[ids as number] as ReturnType;
} else {
return ids.map((id) => object[id]) as ReturnType;
Loaded 100 of 318 files, more files were not shown because too many files have changed in this diff. Show more