diff --git a/.github/workflows/cd-assets.yml b/.github/workflows/cd-assets.yml index 70480c78a..7207bba0e 100644 --- a/.github/workflows/cd-assets.yml +++ b/.github/workflows/cd-assets.yml @@ -44,7 +44,7 @@ jobs: run: yarn setup:depotdownloader - name: Run DepotDownloader - run: ./temp/depotDownloader/DepotDownloader.exe -app 444200 -username ${{ secrets.DEPOT_DOWNLOADER_USERNAME }} -password "${{ secrets.DEPOT_DOWNLOADER_PASSWORD }}" + run: ./temp/depotDownloader/DepotDownloader.exe -app 444202 -username ${{ secrets.DEPOT_DOWNLOADER_USERNAME }} -password "${{ secrets.DEPOT_DOWNLOADER_PASSWORD }}" - name: Build assets run: | diff --git a/.github/workflows/ci-version.yml b/.github/workflows/ci-version.yml deleted file mode 100644 index 3e567d42d..000000000 --- a/.github/workflows/ci-version.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: CI Version - -on: push - -jobs: - host: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Use node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'npm' - - - name: Install Yarn - run: npm install --location=global yarn - - - name: Use node_modules cache - uses: actions/cache@v3 - with: - path: '**/node_modules' - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - - - name: Install dependencies - run: yarn - - - name: Generate leaderboard - run: yarn lint:version diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..6b4e7c7e0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "submodules/closedkrieg"] + path = submodules/closedkrieg + url = https://github.com/tresabhi/closedkrieg diff --git a/.vscode/settings.json b/.vscode/settings.json index b395babe4..40ca50cf8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "accountinfo", "aeson", "alphatest", + "APAC", "apcr", "artefacts", "atgm", @@ -40,8 +41,10 @@ "donotremove", "drei", "Droodles", + "dvpd", "dvpl", "DVPLCRC", + "dvpm", "dxgi", "Everytime", "FASTNAME", @@ -129,6 +132,7 @@ "TYPELESS", "ubjson", "Unicum", + "UNLOCALIZED", "UNORM", "Unregistering", "vickers", @@ -138,6 +142,7 @@ "webp", "winrate", "wireframe", + "WOTB", "wotblitz", "xffn", "xkdkw", diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..3abba759a --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,3 @@ +files: + - source: /src/lang/en-US.json + translation: /src/lang/%locale%.json diff --git a/docs/changelogs/1.16.2.md b/docs/changelogs/1.16.2.md new file mode 100644 index 000000000..09b4bce4d --- /dev/null +++ b/docs/changelogs/1.16.2.md @@ -0,0 +1,36 @@ +# Blitzkrieg 1.16.2 + +¡Hola desde el mundo del español! + +## Features + +- Added translations for Spanish to the bot + - Your language will be inferred automatically from your Discord settings + - Any untranslated languages and words we forgot to translate will be left in English + - If you have your language set to Spanish and see English in any places, please let us know on [the official Discord server](https://discord.gg/nDt7AjGJQH) + - All `/about` commands except for `commands` remain in English + - Tank names are still in English + - The website remains unchanged +- The title bar (featured as the big text on top of most commands) has now been made more compact + +## Changes + +- "Tank type" is now called "tank class" +- Removed `/player-achievements` and `search-tanks` + - They will be reintroduced in the future in a far better way + - Also removed a `SKLLD` server exclusive `/eligible` command + - This will be generalized for all clans in the future + +## Fixes + +- Fixed the red glowing floor underneath the tank sandbox + - This has been replaced with a static image +- The refresh button is now properly removed when lacking permissions +- Tank names that start with a number are now properly inferred from command inputs + +## Technical Changes + +- Command registration is now error tolerant meaning that if a single command fails to initiate, it will be discarded until the next restart + - We are currently looking into how we can allow the command to retry registration after a fixed amount of time +- Due to the implications of the code added which can be very easily exploited by hackers, a single file has been added to the repository as a closed source submodule and will remain closed unless a third party open-source implementation is made public +- Removed preview commands diff --git a/package.json b/package.json index 729329ee7..b4f9ff3f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkrieg", - "version": "1.16.0", + "version": "1.16.2", "description": "🎉 Tools for everything World of Tanks Blitz", "main": "src/server.ts", "type": "module", @@ -25,7 +25,8 @@ "lint:version": "vite-node --script scripts/checkVersionMissMatch", "knip": "knip", "update": "yarn upgrade --latest", - "setup:depotdownloader": "vite-node --script scripts/setupDepotDownloader" + "setup:depotdownloader": "vite-node --script scripts/setupDepotDownloader", + "tunnel": "cloudflared tunnel --url http://localhost:3000" }, "license": "MIT", "dependencies": { diff --git a/scripts/buildAssets/constants.ts b/scripts/buildAssets/constants.ts index 741fa1fb0..d9c07cac5 100644 --- a/scripts/buildAssets/constants.ts +++ b/scripts/buildAssets/constants.ts @@ -1,12 +1,13 @@ -import { readdir } from 'fs/promises'; import { argv } from 'process'; const isDepot = argv.includes('--depot'); +export const WOTB_WIN32_DEPOT = 444202; export const DATA = isDepot - ? await (async () => { - const [installationVersion] = await readdir('depots/444202'); - return `depots/444202/${installationVersion}/Data`; - })() + ? // ? await (async () => { + // const [installationVersion] = await readdir(`depots/${WOTB_WIN32_DEPOT}`); + // return `depots/${WOTB_WIN32_DEPOT}/${installationVersion}/Data`; + // })() + `depots/${WOTB_WIN32_DEPOT}/Data` : 'C:/Program Files (x86)/Steam/steamapps/common/World of Tanks Blitz/Data'; export const POI = { diff --git a/scripts/buildAssets/definitions.ts b/scripts/buildAssets/definitions.ts index 41a7c5f08..d73cf9208 100644 --- a/scripts/buildAssets/definitions.ts +++ b/scripts/buildAssets/definitions.ts @@ -2,7 +2,7 @@ import { readdir } from 'fs/promises'; import { parse as parsePath } from 'path'; import { Vector3Tuple } from 'three'; import { parse as parseYaml } from 'yaml'; -import { TankType } from '../../src/components/Tanks'; +import { TankClass } from '../../src/components/Tanks'; import { readXMLDVPL } from '../../src/core/blitz/readXMLDVPL'; import { readYAMLDVPL } from '../../src/core/blitz/readYAMLDVPL'; import { toUniqueId } from '../../src/core/blitz/toUniqueId'; @@ -34,7 +34,6 @@ import { import { DATA, POI } from './constants'; import { TankParameters } from './tankIcons'; -type BlitzTankType = 'AT-SPG' | 'lightTank' | 'mediumTank' | 'heavyTank'; interface Strings { [key: string]: string; } @@ -306,19 +305,6 @@ type ConsumablesVehicleFilter = | { name: string } | { extendedTags: string }; -const consumableProvisionEffectSuffixes = [ - 'Increase', - 'Factor', - 'Bias', - 'Coef', - 'Percent', -]; -const blitzTankTypeToBlitzkrieg: Record = { - 'AT-SPG': 'tankDestroyer', - lightTank: 'light', - mediumTank: 'medium', - heavyTank: 'heavy', -}; const blitzShellKindToBLitzkrieg: Record = { ARMOR_PIERCING: 'ap', ARMOR_PIERCING_CR: 'ap_cr', @@ -502,7 +488,7 @@ export async function definitions(production: boolean) { ? 'premium' : 'researchable', tier: tank.level as Tier, - type: blitzTankTypeToBlitzkrieg[tankTags[0] as BlitzTankType], + class: tankTags[0] as TankClass, testing: tankTags.includes('testTank') ? true : undefined, price: tankPrice, camouflage: { diff --git a/src/app/embeds/session/page.tsx b/src/app/embeds/session/page.tsx index c4b81a6f9..85b766b22 100644 --- a/src/app/embeds/session/page.tsx +++ b/src/app/embeds/session/page.tsx @@ -311,7 +311,7 @@ export default function SessionPage({ naked = true }: SessionPageProps) { tankDefinitions?.name ?? `Unknown tank ${stats.tank_id}` } type="tank" - tankType={tankDefinitions?.type} + tankType={tankDefinitions?.class} treeType={tankDefinitions?.treeType} stats={session.customColumns.map((customColumn) => { const rowStat = rowStats[customColumn.display]; diff --git a/src/app/tools/ratings/page.tsx b/src/app/tools/ratings/page.tsx index 979e4c1c3..555bb9f8d 100644 --- a/src/app/tools/ratings/page.tsx +++ b/src/app/tools/ratings/page.tsx @@ -20,7 +20,11 @@ import PageWrapper from '../../../components/PageWrapper'; import { Skeleton } from '../../../components/Skeleton'; import { LEAGUES } from '../../../constants/leagues'; import { FIRST_ARCHIVED_RATINGS_SEASON } from '../../../constants/ratings'; -import { REGIONS, REGION_NAMES, Region } from '../../../constants/regions'; +import { + REGIONS, + Region, + UNLOCALIZED_REGION_NAMES, +} from '../../../constants/regions'; import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID'; import fetchBlitz from '../../../core/blitz/fetchBlitz'; import { getClanAccountInfo } from '../../../core/blitz/getClanAccountInfo'; @@ -556,7 +560,7 @@ export default function Page() { {REGIONS.map((region) => ( - {REGION_NAMES[region]} + {UNLOCALIZED_REGION_NAMES[region]} ))} diff --git a/src/app/tools/session/page.tsx b/src/app/tools/session/page.tsx index eecd2e180..a092b4f8a 100644 --- a/src/app/tools/session/page.tsx +++ b/src/app/tools/session/page.tsx @@ -18,7 +18,7 @@ import { import { debounce } from 'lodash'; import { ChangeEvent, useEffect, useRef, useState } from 'react'; import PageWrapper from '../../../components/PageWrapper'; -import { REGION_NAMES } from '../../../constants/regions'; +import { UNLOCALIZED_REGION_NAMES } from '../../../constants/regions'; import searchPlayersAcrossRegions, { AccountListWithServer, } from '../../../core/blitz/searchPlayersAcrossRegions'; @@ -107,7 +107,7 @@ export default function Page() { setShowSearchResults(false); setSession(region, id, nickname); }} - shortcut={REGION_NAMES[region]} + shortcut={UNLOCALIZED_REGION_NAMES[region]} > {nickname} diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx index b7d4d3e17..a7b4b308c 100644 --- a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx @@ -136,12 +136,13 @@ export function Characteristics() { ]); const enginePowerCoefficient = coefficient( [ - hasEngineAccelerator && (tank.type === 'light' || tank.type === 'medium'), + hasEngineAccelerator && + (tank.class === 'lightTank' || tank.class === 'mediumTank'), 0.05, ], [ hasEngineAccelerator && - (tank.type === 'heavy' || tank.type === 'tankDestroyer'), + (tank.class === 'heavyTank' || tank.class === 'AT-SPG'), 0.07, ], [hasEnginePowerBoost, 0.2], @@ -163,7 +164,7 @@ export function Characteristics() { const viewRangeCoefficient = coefficient([ hasImprovedOptics, - tank.type === 'tankDestroyer' ? 0.05 : tank.type === 'heavy' ? 0.07 : 0.1, + tank.class === 'AT-SPG' ? 0.05 : tank.class === 'heavyTank' ? 0.07 : 0.1, ]) * coefficient([true, progressiveStat(commanderMastery)]); const fireChanceCoefficient = coefficient([hasProtectiveKit, -0.2]); @@ -180,38 +181,26 @@ export function Characteristics() { const camouflageSumMoving = sum( [ hasCamouflageNet, - tank.type === 'heavy' - ? 0.03 - : tank.type === 'tankDestroyer' - ? 0.07 - : 0.05, + tank.class === 'heavyTank' ? 0.03 : tank.class === 'AT-SPG' ? 0.07 : 0.05, ], [ camouflage, - tank.type === 'tankDestroyer' - ? 0.04 - : tank.type === 'heavy' - ? 0.03 - : 0.02, + tank.class === 'AT-SPG' ? 0.04 : tank.class === 'heavyTank' ? 0.03 : 0.02, ], ); const camouflageSumStill = sum( [ hasCamouflageNet, 2 * - (tank.type === 'heavy' + (tank.class === 'heavyTank' ? 0.03 - : tank.type === 'tankDestroyer' + : tank.class === 'AT-SPG' ? 0.07 : 0.05), ], [ camouflage, - tank.type === 'tankDestroyer' - ? 0.04 - : tank.type === 'heavy' - ? 0.03 - : 0.02, + tank.class === 'AT-SPG' ? 0.04 : tank.class === 'heavyTank' ? 0.03 : 0.02, ], ); diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx index 472675451..e5253be2e 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx @@ -10,7 +10,7 @@ import { ModelTransformEventData, modelTransformEvent, } from '../../../../../../../core/blitzkrieg/modelTransform'; -import { normalizeAnglePI } from '../../../../../../../core/math/normalizeAngle180'; +import { normalizeAngleRad } from '../../../../../../../core/math/normalizeAngleRad'; import { useAwait } from '../../../../../../../hooks/useAwait'; import { useModel } from '../../../../../../../hooks/useModel'; import { mutateDuel, useDuel } from '../../../../../../../stores/duel'; @@ -172,8 +172,8 @@ export const TankModel = memo(() => { } function handlePointerUp() { mutateDuel((draft) => { - draft.protagonist!.pitch = normalizeAnglePI(pitch); - draft.protagonist!.yaw = normalizeAnglePI(yaw); + draft.protagonist!.pitch = normalizeAngleRad(pitch); + draft.protagonist!.yaw = normalizeAngleRad(yaw); }); mutateTankopediaPersistent((draft) => { draft.model.visual.controlsEnabled = true; @@ -234,8 +234,8 @@ export const TankModel = memo(() => { draft.model.visual.controlsEnabled = true; }); mutateDuel((draft) => { - draft.protagonist!.pitch = normalizeAnglePI(pitch); - draft.protagonist!.yaw = normalizeAnglePI(yaw); + draft.protagonist!.pitch = normalizeAngleRad(pitch); + draft.protagonist!.yaw = normalizeAngleRad(yaw); }); window.removeEventListener('pointermove', handlePointerMove); window.removeEventListener('pointerup', handlePointerUp); diff --git a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx index 2be3155b5..203d41d05 100644 --- a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx +++ b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx @@ -1,32 +1,30 @@ -import { Color } from 'three'; -import InfiniteGridHelper from '../../../../../components/InfiniteGridHelper'; +import { useFrame, useLoader } from '@react-three/fiber'; +import { clamp } from 'lodash'; +import { useRef } from 'react'; +import { MeshStandardMaterial, TextureLoader } from 'three'; import { useTankopediaPersistent } from '../../../../../stores/tankopedia'; export function SceneProps() { - const showGrid = useTankopediaPersistent( - (state) => state.model.visual.showGrid, - ); - const showEnvironment = useTankopediaPersistent( - (state) => state.model.visual.showEnvironment, + const show = useTankopediaPersistent( + (state) => + state.model.visual.showGrid && !state.model.visual.showEnvironment, ); + const texture = useLoader(TextureLoader, 'https://i.imgur.com/C28Z8nU.png'); + const material = useRef(null); - if (!showGrid || showEnvironment) return null; + useFrame(({ camera }) => { + if (!material.current) return; + material.current.opacity = clamp(0.1 * camera.position.y, 0, 1); + }); + + texture.anisotropy = 2; + + if (!show) return null; return ( - <> - - - + + + + ); } diff --git a/src/app/tools/tankopedia/[id]/components/Title.tsx b/src/app/tools/tankopedia/[id]/components/Title.tsx index 24a8febde..22caff8ce 100644 --- a/src/app/tools/tankopedia/[id]/components/Title.tsx +++ b/src/app/tools/tankopedia/[id]/components/Title.tsx @@ -30,7 +30,7 @@ export function Title() { - {[...TANK_TYPES].map((type, index) => ( + {[...TANK_CLASSES].map((type, index) => (