diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml index da6e48eda..b4f0e5770 100644 --- a/.github/workflows/assets.yml +++ b/.github/workflows/assets.yml @@ -55,117 +55,13 @@ env: 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: - - if: github.event.inputs.archive_url != '' - uses: easimon/maximize-build-space@master - with: - root-reserve-mb: 512 - swap-size-mb: 1024 - remove-dotnet: "true" - remove-haskell: "true" - remove-android: "true" - remove-codeql: "true" - remove-docker-images: "true" - - - if: github.event.inputs.archive_url != '' && endsWith(github.event.inputs.archive_url, '.wgpkg') - run: | - sudo apt update - sudo apt install -y p7zip-full - - - uses: actions/checkout@v4 - if: github.event.inputs.archive_url == '' - with: - submodules: recursive - token: ${{ secrets.GH_TOKEN }} - - - uses: arduino/setup-protoc@v3 - if: github.event.inputs.archive_url == '' - with: - repo-token: ${{ secrets.GH_TOKEN }} - - - uses: oven-sh/setup-bun@v1 - if: github.event.inputs.archive_url == '' - - - run: bun run setup - if: github.event.inputs.archive_url == '' - - - name: (Steam) Setup DepotDownloader - if: github.event.inputs.archive_url == '' - run: bun run setup:depotdownloader - - - name: (Steam) Download client - if: github.event.inputs.archive_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 }}" - mkdir -p temp/game - mv depots/444202/*/* temp/game - rm -rf depots - - - name: (Steam) Apply patches - if: github.event.inputs.archive_url == '' - run: bun setup:patches --manual - - - name: (ZIP) Download client - if: github.event.inputs.archive_url != '' && endsWith(github.event.inputs.archive_url, '.zip') - env: - ARCHIVE_URL: ${{ github.event.inputs.archive_url }} - run: | - mkdir -p temp/game - wget -q -O temp/archive.zip $ARCHIVE_URL - unzip -q temp/archive.zip -d temp/archive - rm temp/archive.zip - mv temp/archive/app/* temp/game - - - name: (WGPKG) Download client - if: github.event.inputs.archive_url != '' && endsWith(github.event.inputs.archive_url, '.wgpkg') - env: - ARCHIVE_URL: ${{ github.event.inputs.archive_url }} - run: | - mkdir -p temp/archives - mkdir -p temp/game - - i=1 - urls=() - - while :; do - part=$(printf "%03d" $i) - url="${ARCHIVE_URL}.${part}" - if wget --spider -q "$url"; then - urls+=("$url") - ((i++)) - else - break - fi - done - - for url in "${urls[@]}"; do - dest="temp/archives/$(basename "$url")" - wget -q -O "$dest" "$url" & - done - wait - - first=$(ls temp/archives/*.001 | head -n 1) - 7z x "$first" -otemp/game - - rm -rf temp/archives - - - name: Archive game - uses: actions/upload-artifact@v4 - with: - name: game - path: temp/game - build_assets: name: Build assets runs-on: ubuntu-latest - needs: download_client steps: - uses: actions/checkout@v4 @@ -178,12 +74,6 @@ jobs: - uses: oven-sh/setup-bun@v1 - run: bun run setup - - name: Download game - uses: actions/download-artifact@v4 - with: - name: game - path: temp/game - - name: AppArmor hack run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns diff --git a/.vscode/settings.json b/.vscode/settings.json index 105b58ef8..7304e64d5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ "analyticsreporting", "APAC", "apcr", + "appinfo", "applypatches", "artefacts", "astrojs", @@ -111,6 +112,7 @@ "leaderboards", "lerp", "LINEARSIZE", + "linktarget", "lmao", "loadouts", "loddist", @@ -171,6 +173,7 @@ "ratingleaderboard", "raycaster", "Redirector", + "Relogin", "researchable", "Resvg", "rizz", diff --git a/bun.lock b/bun.lock index 8e8802475..068d732a4 100644 --- a/bun.lock +++ b/bun.lock @@ -69,14 +69,17 @@ "@types/bun": "^1.3.1", "@types/lodash-es": "^4.17.12", "@types/lz4js": "^0.2.1", + "@types/steam-user": "^5.1.0", "@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", + "steam-user": "^5.2.3", "three": "^0.180.0", "ts-proto": "^2.7.7", "yaml": "^2.8.1", @@ -382,6 +385,10 @@ "@babel/types": ["@babel/types@7.28.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q=="], + "@bbob/parser": ["@bbob/parser@2.9.0", "", { "dependencies": { "@bbob/plugin-helper": "^2.9.0" } }, "sha512-tldSYsMoEclke/B1nqL7+HbYMWZHTKvpbEHRSHuY+sZvS1o7Jpdfjb+KPpwP9wLI3p3r7GPv69/wGy+Xibs9yA=="], + + "@bbob/plugin-helper": ["@bbob/plugin-helper@2.9.0", "", {}, "sha512-idpUcNQ2co6T1oU/7/DG/ZRfipSSkTn9Ozw9f5vaXH7nzV3qhqZnhFVlHTzGGnRlzKlBwWOBzOdWi4Zeqg1c5A=="], + "@blitzkit/app": ["@blitzkit/app@workspace:packages/app"], "@blitzkit/bot": ["@blitzkit/bot@workspace:packages/bot"], @@ -414,6 +421,12 @@ "@discordjs/ws": ["@discordjs/ws@1.2.3", "", { "dependencies": { "@discordjs/collection": "^2.1.0", "@discordjs/rest": "^2.5.1", "@discordjs/util": "^1.1.0", "@sapphire/async-queue": "^1.5.2", "@types/ws": "^8.5.10", "@vladfrangu/async_event_emitter": "^2.2.4", "discord-api-types": "^0.38.1", "tslib": "^2.6.2", "ws": "^8.17.0" } }, "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw=="], + "@doctormckay/stdlib": ["@doctormckay/stdlib@2.10.0", "", { "dependencies": { "psl": "^1.9.0" } }, "sha512-bwy+gPn6oa2KTpfxJKX3leZoV/wHDVtO0/gq3usPvqPswG//dcf3jVB8LcbRRsKO3BXCt5DqctOQ+Xb07ivxnw=="], + + "@doctormckay/steam-crypto": ["@doctormckay/steam-crypto@1.2.0", "", {}, "sha512-lsxgLw640gEdZBOXpVIcYWcYD+V+QbtEsMPzRvjmjz2XXKc7QeEMyHL07yOFRmay+cUwO4ObKTJO0dSInEuq5g=="], + + "@doctormckay/user-agents": ["@doctormckay/user-agents@1.0.0", "", {}, "sha512-F+sL1YmebZTY2CnjoR9BXFEULpq7y8dxyLx48LZVa0BSDseXdLG/DtPISfM1iNv1XKCeiBzVNfAT/MOQ69v1Zw=="], + "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="], @@ -914,6 +927,8 @@ "@types/bun": ["@types/bun@1.3.1", "", { "dependencies": { "bun-types": "1.3.1" } }, "sha512-4jNMk2/K9YJtfqwoAa28c8wK+T7nvJFOjxI4h/7sORWcypRNxBpr+TPNaCfVWq70tLCJsqoFwcf0oI0JU/fvMQ=="], + "@types/bytebuffer": ["@types/bytebuffer@5.0.49", "", { "dependencies": { "@types/long": "^3.0.0", "@types/node": "*" } }, "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ=="], + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], "@types/decompress": ["@types/decompress@4.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g=="], @@ -922,6 +937,8 @@ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "@types/file-manager": ["@types/file-manager@2.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-gEq6de+iMbjmkL3Wj183JQ651h9b331wQ3svXp2K6RkgBg+TtiyIZTMols/a3UtXllVV9kSelz/N3Rgh0n6S4g=="], + "@types/fontkit": ["@types/fontkit@2.0.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew=="], "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], @@ -930,6 +947,8 @@ "@types/lodash-es": ["@types/lodash-es@4.17.12", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ=="], + "@types/long": ["@types/long@3.0.32", "", {}, "sha512-ZXyOOm83p7X8p3s0IYM3VeueNmHpkk/yMlP8CLeOnEcu6hIwPH7YjZBvhQkR0ZFS2DqZAxKtJ/M5fcuv3OU5BA=="], + "@types/lz4js": ["@types/lz4js@0.2.1", "", {}, "sha512-aAnbA4uKPNqZqu0XK1QAwKP0Wskb4Oa7ZFqxW5CMIyGgqYQKFgBxTfK3m3KODXoOLv5t14VregzgrEak13uGQA=="], "@types/markdown-escape": ["@types/markdown-escape@1.1.3", "", {}, "sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw=="], @@ -960,6 +979,10 @@ "@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="], + "@types/steam-user": ["@types/steam-user@5.1.0", "", { "dependencies": { "@types/bytebuffer": "*", "@types/file-manager": "*", "@types/node": "*", "@types/steamid": "*" } }, "sha512-jMCzwmvBA1DaqLTD9h23LzVmzyHy53cdzpJjBSYDI6qT/1LqEUM9xRt4Vb0Y9kOIr+BZckCewDw8Bk6n8e3BTA=="], + + "@types/steamid": ["@types/steamid@2.0.4", "", {}, "sha512-LC0oaiNq3gqMI18MV935CnlyHmDooKRszK56jHv0+b7EbJwf5k++YsD52zWeJUD8nuYqP9LpIgpXGiYBOxpcYQ=="], + "@types/three": ["@types/three@0.180.0", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~0.22.0" } }, "sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], @@ -1006,7 +1029,7 @@ "adm-zip": ["adm-zip@0.5.16", "", {}, "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ=="], - "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], @@ -1086,6 +1109,8 @@ "bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], + "binarykvparser": ["binarykvparser@2.3.0", "", { "dependencies": { "long": "^3.2.0" } }, "sha512-B1N5ZxC8I9oSLis7Rg36DxsZJoIikUGU2XwpI0FKFCaPIJIEYi0B9UeIk3QU006axzq0TI9KC3iXelfGGgnWew=="], + "bl": ["bl@1.2.3", "", { "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], @@ -1118,6 +1143,8 @@ "bun-types": ["bun-types@1.3.1", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-NMrcy7smratanWJ2mMXdpatalovtxVggkj11bScuWuiOoXTiKIu2eVS1/7qbyI/4yHedtsn175n4Sm4JcdHLXw=="], + "bytebuffer": ["bytebuffer@5.0.1", "", { "dependencies": { "long": "~3" } }, "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ=="], + "c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="], "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], @@ -1238,6 +1265,8 @@ "csv-parse": ["csv-parse@6.1.0", "", {}, "sha512-CEE+jwpgLn+MmtCpVcPtiCZpVtB6Z2OKPTr34pycYYoL7sxdOkXDdQ4lRiw6ioC0q6BLqhc6cKweCVvral8yhw=="], + "cuint": ["cuint@0.2.2", "", {}, "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw=="], + "cwise-compiler": ["cwise-compiler@1.1.3", "", { "dependencies": { "uniq": "^1.0.0" } }, "sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ=="], "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], @@ -1410,7 +1439,7 @@ "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], - "fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], + "fast-xml-parser": ["fast-xml-parser@5.3.2", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-n8v8b6p4Z1sMgqRmqLJm3awW4NX7NkaKPfb3uJIBTSH7Pdvufi3PQ3/lJLQrvxcMYl7JI2jnDO90siPEpD8JBA=="], "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], @@ -1424,6 +1453,8 @@ "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], + "file-manager": ["file-manager@2.0.1", "", { "dependencies": { "@doctormckay/stdlib": "^1.14.1" } }, "sha512-y/K/1OCha04OXOxzo3cXJYtIzEk/CUMBb7Okipxueu0u+xCiuoocbwPyh1smUBasOobo4GAYmjgjD9Vh5zI51w=="], + "file-type": ["file-type@5.2.0", "", {}, "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ=="], "filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="], @@ -1702,6 +1733,8 @@ "ktx-parse": ["ktx-parse@1.1.0", "", {}, "sha512-mKp3y+FaYgR7mXWAbyyzpa/r1zDWeaunH+INJO4fou3hb45XuNSwar+7llrRyvpMWafxSIi99RNFJ05MHedaJQ=="], + "kvparser": ["kvparser@1.0.2", "", {}, "sha512-5P/5qpTAHjVYWqcI55B3yQwSY2FUrYYrJj5i65V1Wmg7/4W4OnBcaodaEvLyVuugeOnS+BAaKm9LbPazGJcRyA=="], + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], @@ -1728,6 +1761,8 @@ "lz4js": ["lz4js@0.2.0", "", {}, "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg=="], + "lzma": ["lzma@2.3.2", "", { "bin": { "lzma.js": "bin/lzma.js" } }, "sha512-DcfiawQ1avYbW+hsILhF38IKAlnguc/fjHrychs9hdxe4qLykvhT5VTGNs5YRWgaNePh7NTxGD4uv4gKsRomCQ=="], + "maath": ["maath@0.10.8", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="], "magic-bytes.js": ["magic-bytes.js@1.12.1", "", {}, "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA=="], @@ -1868,6 +1903,8 @@ "nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="], + "node-bignumber": ["node-bignumber@1.2.2", "", {}, "sha512-VoTZHmdFQpZH1+q1dz2qcHNCwTWsJg2T3PYwlAyDNFOfVhSYUKQBLFcCpCud+wJBGgCttGavZILaIggDIKqEQQ=="], + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], @@ -1948,6 +1985,8 @@ "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + "permessage-deflate": ["permessage-deflate@0.1.7", "", { "dependencies": { "safe-buffer": "*" } }, "sha512-EUNi/RIsyJ1P1u9QHFwMOUWMYetqlE22ZgGbad7YP856WF4BFF0B7DuNy6vEGsgNNud6c/SkdWzkne71hH8MjA=="], + "pickleparser": ["pickleparser@0.2.1", "", { "bin": { "pickletojson": "bin/pickletojson.js", "pickleparser": "bin/pickletojson.js" } }, "sha512-kMzY3uFYcR6OjOqr7nV2nkaXaBsUEOafu3zgPxeD6s/2ueMfVQH8lrymcDWBPGx0OkVxGMikxQit6jgByXjwBg=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], @@ -1996,6 +2035,8 @@ "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "psl": ["psl@1.15.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w=="], + "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -2172,7 +2213,7 @@ "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], - "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "socks-proxy-agent": ["socks-proxy-agent@7.0.0", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="], "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], @@ -2190,6 +2231,16 @@ "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "steam-appticket": ["steam-appticket@1.0.2", "", { "dependencies": { "@doctormckay/stdlib": "^1.6.0", "@doctormckay/steam-crypto": "^1.2.0", "bytebuffer": "^5.0.1", "protobufjs": "^6.8.8", "steamid": "^1.1.0" } }, "sha512-zwDwZALGv3RanE8RHNYcQU3u4Ez23EzMuQ4Lh15uIHddpDh6TI6uFGbC0HNyt6y+UJYSILe77A33VhFZKQiaqQ=="], + + "steam-session": ["steam-session@1.9.4", "", { "dependencies": { "@doctormckay/stdlib": "^2.9.0", "@doctormckay/user-agents": "^1.0.0", "debug": "^4.3.4", "kvparser": "^1.0.1", "node-bignumber": "^1.2.2", "protobufjs": "^7.1.0", "socks-proxy-agent": "^7.0.0", "steamid": "^2.0.0", "tiny-typed-emitter": "^2.1.0", "websocket13": "^4.0.0" } }, "sha512-MLvg1uMLEOIRHZS5LKruy1w5OqHb8EL7TeMxIY2a4mUcaVOgszz060+jo4c7s3gFeedyuoqGcfwJrR0pLKYzLw=="], + + "steam-totp": ["steam-totp@2.1.2", "", {}, "sha512-bTKlc/NoIUQId+my+O556s55DDsNNXfVIPWFDNVu68beql7AJhV0c+GTjFxfwCDYfdc4NkAme+0WrDdnY2D2VA=="], + + "steam-user": ["steam-user@5.2.3", "", { "dependencies": { "@bbob/parser": "^2.2.0", "@doctormckay/stdlib": "^2.9.1", "@doctormckay/steam-crypto": "^1.2.0", "adm-zip": "^0.5.10", "binarykvparser": "^2.2.0", "bytebuffer": "^5.0.0", "file-manager": "^2.0.0", "kvparser": "^1.0.1", "lzma": "^2.3.2", "protobufjs": "^7.2.4", "socks-proxy-agent": "^7.0.0", "steam-appticket": "^1.0.1", "steam-session": "^1.8.0", "steam-totp": "^2.0.1", "steamid": "^2.0.0", "websocket13": "^4.0.0", "zstddec": "^0.1.0" } }, "sha512-6Yzaa0l7fcSRaaJzHjfuqettYqAsrW3+1AEu/cj4M/lgRYXa0DfOAjuWj0/wesfkogwuXNE4N/ZMZvNir8TVtw=="], + + "steamid": ["steamid@2.1.0", "", {}, "sha512-ndt1cvuuSC+i8fcxVsmeyRlgGsR1QsoAuIXz+eabj8/Y4GIWE2+mgHA7Hys61JDHOxttfWtXHtN2m5TNYTlORg=="], + "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], "streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="], @@ -2246,6 +2297,8 @@ "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], + "tiny-typed-emitter": ["tiny-typed-emitter@2.1.0", "", {}, "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="], + "tinyexec": ["tinyexec@1.0.1", "", {}, "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], @@ -2438,6 +2491,10 @@ "webidl-conversions": ["webidl-conversions@4.0.2", "", {}, "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="], + "websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="], + + "websocket13": ["websocket13@4.1.0", "", { "dependencies": { "@doctormckay/stdlib": "^2.7.1", "bytebuffer": "^5.0.1", "permessage-deflate": "^0.1.7", "tiny-typed-emitter": "^2.1.0", "websocket-extensions": "^0.1.4" } }, "sha512-7+hxkUVTKQlUDTzN2rJI7fJRBXCT6dvRXr1aZflxUZlpNJutHBkKiEIbZOCGs0A1s7vxAmcAXngsNUQMSUTiVQ=="], + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], @@ -2532,6 +2589,8 @@ "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], + "zstddec": ["zstddec@0.1.0", "", {}, "sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg=="], + "zustand": ["zustand@5.0.8", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], @@ -2556,6 +2615,8 @@ "@blitzkit/scripts/@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="], + "@blitzkit/scripts/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], + "@blitzkit/website/vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], "@discordjs/rest/@discordjs/collection": ["@discordjs/collection@2.1.1", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="], @@ -2594,8 +2655,12 @@ "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "binarykvparser/long": ["long@3.2.0", "", { "bundled": true }, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="], + "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + "bytebuffer/long": ["long@3.2.0", "", {}, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="], + "c12/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], "cheerio/undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="], @@ -2612,6 +2677,8 @@ "favilib/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], + "file-manager/@doctormckay/stdlib": ["@doctormckay/stdlib@1.16.1", "", {}, "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug=="], + "filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], "get-uri/data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="], @@ -2622,6 +2689,10 @@ "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], + "http-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "its-fine/@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="], "linebreak/base64-js": ["base64-js@0.0.8", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="], @@ -2630,12 +2701,20 @@ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "pac-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "pac-proxy-agent/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + "proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + "proxy-agent/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "react-dom/scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "react-promise-suspense/fast-deep-equal": ["fast-deep-equal@2.0.1", "", {}, "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w=="], @@ -2650,6 +2729,12 @@ "stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="], + "steam-appticket/@doctormckay/stdlib": ["@doctormckay/stdlib@1.16.1", "", {}, "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug=="], + + "steam-appticket/protobufjs": ["protobufjs@6.11.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/long": "^4.0.1", "@types/node": ">=13.7.0", "long": "^4.0.0" }, "bin": { "pbjs": "bin/pbjs", "pbts": "bin/pbts" } }, "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw=="], + + "steam-appticket/steamid": ["steamid@1.1.3", "", { "dependencies": { "cuint": "^0.2.1" } }, "sha512-t86YjtP1LtPt8D+TaIARm6PtC9tBnF1FhxQeLFs6ohG7vDUfQuy/M8II14rx1TTUkVuYoWHP/7DlvTtoCGULcw=="], + "string_decoder/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "tar-fs/tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="], @@ -2770,6 +2855,10 @@ "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "steam-appticket/protobufjs/@types/long": ["@types/long@4.0.2", "", {}, "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="], + + "steam-appticket/protobufjs/long": ["long@4.0.0", "", {}, "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="], + "widest-line/string-width/emoji-regex": ["emoji-regex@10.5.0", "", {}, "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="], "widest-line/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], diff --git a/docs/changelogs/1.29.4.md b/docs/changelogs/1.29.4.md new file mode 100644 index 000000000..38f41a4c7 --- /dev/null +++ b/docs/changelogs/1.29.4.md @@ -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 diff --git a/package.json b/package.json index d0072e941..5913b4b5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkit", - "version": "1.29.3", + "version": "1.29.4", "license": "BlitzKit License", "private": true, "scripts": { diff --git a/packages/core/package.json b/packages/core/package.json index 964bc4308..fd9e69734 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -13,14 +13,17 @@ "@types/bun": "^1.3.1", "@types/lodash-es": "^4.17.12", "@types/lz4js": "^0.2.1", + "@types/steam-user": "^5.1.0", "@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", + "steam-user": "^5.2.3", "three": "^0.180.0", "ts-proto": "^2.7.7", "yaml": "^2.8.1" diff --git a/packages/core/src/blitz/blitzVFS.ts b/packages/core/src/blitz/blitzVFS.ts new file mode 100644 index 000000000..776381056 --- /dev/null +++ b/packages/core/src/blitz/blitzVFS.ts @@ -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(); + } +} diff --git a/packages/core/src/blitz/index.ts b/packages/core/src/blitz/index.ts index d1bd1b37d..6b8193288 100644 --- a/packages/core/src/blitz/index.ts +++ b/packages/core/src/blitz/index.ts @@ -1,32 +1,33 @@ -export * from './canSplash'; -export * from './clans'; -export * from './classes'; -export * from './constants'; -export * from './equipmentPrice'; -export * from './fetchBlitz'; -export * from './fetchGlossary'; -export * from './generateStats'; -export * from './getAccountAchievements'; -export * from './getAccountInfo'; -export * from './getClanAccountInfo'; -export * from './getClanInfo'; -export * from './getLeagueFromScore'; -export * from './getRatingInfo'; -export * from './getRatingLeague'; -export * from './getRatingNeighbors'; -export * from './getTankStats'; -export * from './idToRegion'; -export * from './isOnGoingRatingSeason'; -export * from './isValidBlitzId'; -export * from './nations'; -export * from './normalizeExtra'; -export * from './normalizeIds'; -export * from './permanentSkills'; -export * from './rating'; -export * from './regions'; -export * from './regionSubdomainToRegion'; -export * from './regionToRegionSubdomain'; -export * from './searchClansAcrossRegions'; -export * from './searchCurrentRatingPlayers'; -export * from './searchPlayersAcrossRegions'; -export * from './toUniqueId'; +export * from "./canSplash"; +export * from "./clans"; +export * from "./classes"; +export * from "./constants"; +export * from "./equipmentPrice"; +export * from "./fetchBlitz"; +export * from "./fetchGlossary"; +export * from "./generateStats"; +export * from "./getAccountAchievements"; +export * from "./getAccountInfo"; +export * from "./getClanAccountInfo"; +export * from "./getClanInfo"; +export * from "./getLeagueFromScore"; +export * from "./getRatingInfo"; +export * from "./getRatingLeague"; +export * from "./getRatingNeighbors"; +export * from "./getTankStats"; +export * from "./idToRegion"; +export * from "./isOnGoingRatingSeason"; +export * from "./isValidBlitzId"; +export * from "./nations"; +export * from "./normalizeExtra"; +export * from "./normalizeIds"; +export * from "./permanentSkills"; +export * from "./rating"; +export * from "./readDVPL"; +export * from "./regions"; +export * from "./regionSubdomainToRegion"; +export * from "./regionToRegionSubdomain"; +export * from "./searchClansAcrossRegions"; +export * from "./searchCurrentRatingPlayers"; +export * from "./searchPlayersAcrossRegions"; +export * from "./toUniqueId"; diff --git a/packages/scripts/src/core/blitz/readDVPL.ts b/packages/core/src/blitz/readDVPL.ts similarity index 75% rename from packages/scripts/src/core/blitz/readDVPL.ts rename to packages/core/src/blitz/readDVPL.ts index a7dea2f2e..856bc0cd5 100644 --- a/packages/scripts/src/core/blitz/readDVPL.ts +++ b/packages/core/src/blitz/readDVPL.ts @@ -1,5 +1,5 @@ -import { crc32 } from 'crc'; -import { decompressBlock } from 'lz4js'; +import { crc32 } from "crc"; +import { decompressBlock } from "lz4js"; /** * Thanks Maddoxkkm! Modified heavily to be modern. @@ -9,10 +9,10 @@ export function readDVPL(buffer: Buffer) { const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length); if ( - footerBuffer.toString('utf8', 16, 20) !== 'DVPL' || + footerBuffer.toString("utf8", 16, 20) !== "DVPL" || footerBuffer.length !== 20 ) { - throw new SyntaxError('Invalid DVPL footer'); + throw new SyntaxError("Invalid DVPL footer"); } const footerData = { @@ -24,15 +24,15 @@ export function readDVPL(buffer: Buffer) { const targetBlock = buffer.subarray(0, buffer.length - 20); if (targetBlock.length !== footerData.cSize) { - throw new RangeError('DVPL size mismatch'); + throw new RangeError("DVPL size mismatch"); } if (crc32(targetBlock) !== footerData.crc32) { - throw new TypeError('DVPL CRC32 mismatch'); + throw new TypeError("DVPL CRC32 mismatch"); } if (footerData.type === 0) { if (!(footerData.oSize === footerData.cSize && footerData.type === 0)) { - throw new RangeError('DVPL type and size mismatch'); + throw new RangeError("DVPL type and size mismatch"); } return targetBlock; @@ -44,17 +44,17 @@ export function readDVPL(buffer: Buffer) { destination, 0, source.length, - 0, + 0 ); - + if (decompressedSize !== footerData.oSize) { throw new RangeError( - `Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})`, + `Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})` ); } - + return Buffer.from(destination); } else { - throw new SyntaxError('Unknown DVPL format'); + throw new SyntaxError("Unknown DVPL format"); } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8fd80f89d..e34feae46 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,10 +1,11 @@ -export * from './blitz'; -export * from './blitzkit'; -export * from './imgur'; -export * from './math'; -export * from './patreon'; -export * from './protobuf'; -export * from './protos'; -export * from './statistics'; -export * from './streams'; -export * from './types'; +export * from "./blitz"; +export * from "./blitzkit"; +export * from "./imgur"; +export * from "./math"; +export * from "./patreon"; +export * from "./protobuf"; +export * from "./protos"; +export * from "./statistics"; +export * from "./steam"; +export * from "./streams"; +export * from "./types"; diff --git a/packages/core/src/steam/index.ts b/packages/core/src/steam/index.ts new file mode 100644 index 000000000..d4f7cee39 --- /dev/null +++ b/packages/core/src/steam/index.ts @@ -0,0 +1 @@ +export * from "./vfs"; diff --git a/packages/core/src/steam/vfs.ts b/packages/core/src/steam/vfs.ts new file mode 100644 index 000000000..ec024dad4 --- /dev/null +++ b/packages/core/src/steam/vfs.ts @@ -0,0 +1,155 @@ +import { XMLParser } from "fast-xml-parser"; +import { normalize } from "path/posix"; +import SteamUser, { EConnectionProtocol } from "steam-user"; +import { parse } from "yaml"; +import { readDVPL } from "../blitz"; + +interface SteamManifestFile { + chunks: { + sha: string; + crc: number; + offset: string; + cb_original: number; + cb_compressed: number; + }[]; + filename: string; + size: string; + flags: number; + sha_filename: string; + sha_content: string; + linktarget: unknown; +} + +interface SteamManifest { + files: SteamManifestFile[]; + depot_id: number; + gid_manifest: string; + creation_time: number; + filenames_encrypted: boolean; + cb_disk_original: string; + cb_disk_compressed: string; + unique_chunks: number; + crc_encrypted: number; + crc_clear: number; +} + +export class SteamVFS { + private steam = new SteamUser({ protocol: EConnectionProtocol.TCP }); + private textDecoder = new TextDecoder(); + private xmlParser = new XMLParser(); + + private manifest: Map = new Map(); + + constructor( + private username: string, + private password: string, + private app: number, + private depot: number + ) {} + + async init() { + this.steam.logOn({ + accountName: this.username, + password: this.password, + }); + + await new Promise((resolve) => this.steam.once("loggedOn", resolve)); + + const productInfo = await this.steam.getProductInfo([this.app], []); + const manifest: SteamManifest = await new Promise((resolve) => { + // @ts-expect-error + this.steam.getManifest( + this.app, + this.depot, + productInfo.apps[this.app].appinfo.depots[this.depot].manifests.public + .gid, + "public", + // @ts-expect-error + (_, response) => { + resolve(response); + } + ); + }); + + const paths: string[] = []; + for (const file of manifest.files) { + const path = file.filename.replaceAll("\\", "/"); + paths.push(path); + this.manifest.set(path, file); + } + + return this; + } + + has(path: string) { + const normalized = normalize(path); + const dvplPath = `${normalized}.dvpl`; + + return ( + (this.manifest.has(dvplPath) && dvplPath) || + (this.manifest.has(normalized) && normalized) + ); + } + + assert(requested: string) { + const path = this.has(requested); + + if (!path) throw new Error(`File not found: ${requested}`); + + return path; + } + + dir(path: string) { + const parentSegments = path.split("/").length; + const children: string[] = []; + + for (const child of this.manifest.keys()) { + const childSegments = child.split("/"); + + if ( + child.startsWith(path) && + parentSegments + 1 === childSegments.length + ) { + children.push(childSegments.at(-1)!); + } + } + + return children; + } + + async file(requested: string) { + const path = this.assert(requested); + const fileManifest = this.manifest.get(path)!; + const downloaded: { type: "complete"; file: Buffer } = + // @ts-expect-error + await this.steam.downloadFile(this.app, this.depot, fileManifest); + let buffer = downloaded.file; + + if (path.endsWith(".dvpl")) buffer = readDVPL(downloaded.file); + + return new Uint8Array(buffer); + } + + async text(path: string) { + const file = await this.file(path); + return this.textDecoder.decode(file); + } + + async yaml(path: string) { + const file = await this.text(path); + return parse(file) as Type; + } + + async xml(path: string) { + const file = await this.text(path); + return this.xmlParser.parse(file) as Type; + } + + dispose() { + this.steam.logOff(); + } + + [Symbol.dispose]() { + this.dispose(); + } +} diff --git a/packages/scripts/src/applyPatches.ts b/packages/scripts/src/applyPatches.ts index 83ab198b4..7064ce932 100644 --- a/packages/scripts/src/applyPatches.ts +++ b/packages/scripts/src/applyPatches.ts @@ -4,12 +4,10 @@ import { mkdir, writeFile } from "fs/promises"; import { parse as parsePath } from "path"; import ProgressBar from "progress"; import { parse as parseYaml, stringify as stringifyYaml } from "yaml"; -import { readStringDVPL } from "../src/core/blitz/readStringDVPL"; -import { DATA } from "./buildAssets/constants"; -import { readYAMLDVPL } from "./core/blitz/readYAMLDVPL"; +import { vfs } from "./buildAssets/constants"; import { writeDVPL } from "./core/blitz/writeDVPL"; -const versionTextFile = await readStringDVPL(`${DATA}/version.txt`); +const versionTextFile = await vfs.text(`Data/version.txt`); const currentVersion = versionTextFile .split(" ")[0] .split(".") @@ -51,7 +49,7 @@ while (true) { const { dir } = parsePath(path); try { - await mkdir(`${DATA}/${dir}`, { recursive: true }); + await mkdir(`Data/${dir}`, { recursive: true }); } catch (error) { console.warn(`Failed to make directory "${dir}"`); } @@ -60,7 +58,7 @@ while (true) { const buffer = Buffer.from(data); await writeFile( - `${DATA}/${path}${isDvpl ? "" : ".dvpl"}`, + `Data/${path}${isDvpl ? "" : ".dvpl"}`, new Uint8Array(isDvpl ? buffer : writeDVPL(buffer)) ); @@ -76,14 +74,14 @@ while (true) { }/en.yaml` ); const newStrings = parseYaml(await localizationsResponse.text()); - const oldStrings = await readYAMLDVPL>( - `${DATA}/Strings/en.yaml` + const oldStrings = await vfs.yaml>( + `Data/Strings/en.yaml` ); const patchedStrings = { ...oldStrings, ...newStrings }; const patchedContent = stringifyYaml(patchedStrings); await writeFile( - `${DATA}/Strings/en.yaml`, + `Data/Strings/en.yaml`, new Uint8Array(writeDVPL(Buffer.from(patchedContent))) ); } diff --git a/packages/scripts/src/buildAssets/boosterIcons.ts b/packages/scripts/src/buildAssets/boosterIcons.ts index d1cb9d316..486a732b2 100644 --- a/packages/scripts/src/buildAssets/boosterIcons.ts +++ b/packages/scripts/src/buildAssets/boosterIcons.ts @@ -1,19 +1,16 @@ -import { readdir } from "fs/promises"; import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; -import { readStringDVPL } from "../../src/core/blitz/readStringDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; export async function boosterIcons() { console.log("Building booster icons..."); using uploader = new AssetUploader("booster icons"); - const boosterFiles = (await readdir(`${DATA}/Gfx/Shared/boosters`)).filter( + const boosterFiles = (vfs.dir(`Data/Gfx/Shared/boosters`)).filter( (file) => !file.includes("@2x.txt") && !file.startsWith("texture0") ); const image = sharp( - await readDVPLFile(`${DATA}/Gfx/Shared/boosters/texture0.packed.webp`) + await vfs.file(`Data/Gfx/Shared/boosters/texture0.packed.webp`) ); for (const file of boosterFiles) { @@ -21,7 +18,7 @@ export async function boosterIcons() { if (name === undefined) continue; - const sizes = (await readStringDVPL(`${DATA}/Gfx/Shared/boosters/${file}`)) + const sizes = (await vfs.text(`Data/Gfx/Shared/boosters/${file}`)) .split("\n")[4] .split(" ") .map(Number); diff --git a/packages/scripts/src/buildAssets/camouflageIcons.ts b/packages/scripts/src/buildAssets/camouflageIcons.ts index 726a0c866..f0125a091 100644 --- a/packages/scripts/src/buildAssets/camouflageIcons.ts +++ b/packages/scripts/src/buildAssets/camouflageIcons.ts @@ -1,13 +1,12 @@ -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; export async function camouflageIcons() { console.log("Building camouflage icons..."); using uploader = new AssetUploader("camo icons"); - const content = await readDVPLFile( - `${DATA}/Gfx/UI/Hangar/IconCamouflage.packed.webp` + const content = await vfs.file( + `Data/Gfx/UI/Hangar/IconCamouflage.packed.webp` ); await uploader.add({ content, path: "icons/camo.webp" }); diff --git a/packages/scripts/src/buildAssets/constants.ts b/packages/scripts/src/buildAssets/constants.ts index 850946d67..e9013f625 100644 --- a/packages/scripts/src/buildAssets/constants.ts +++ b/packages/scripts/src/buildAssets/constants.ts @@ -1,32 +1,11 @@ -import { readdir } from "fs/promises"; -import { argv } from "process"; +import { assertSecret, SteamVFS } from "@blitzkit/core"; -const WINDOWS_APPS = "C:/Program Files/WindowsApps"; -const wotbPackageRegex = /7458BE2C\..+_\d+(\.\d+)+_x64__.+/; +const APP = 444200; +const DEPOT = 444202; -const isManual = argv.includes("--manual"); - -let data: string; -let compressed: boolean; - -if (isManual) { - data = "../../temp/game/Data"; - compressed = true; -} else { - const directories = await readdir(WINDOWS_APPS).then((files) => - files.filter((file) => wotbPackageRegex.test(file)) - ); - - if (directories.length !== 1) { - throw new Error( - `Expected 1 directory for WoTB Windows App, got ${directories.length}.` - ); - } - - const [windowsApp] = directories; - data = `${WINDOWS_APPS}/${windowsApp}/Data`; - compressed = false; -} - -export const DATA = data; -export const DATA_COMPRESSED = compressed; +export const vfs = await new SteamVFS( + assertSecret(import.meta.env.STEAM_USERNAME), + assertSecret(import.meta.env.STEAM_PASSWORD), + APP, + DEPOT +).init(); diff --git a/packages/scripts/src/buildAssets/consumableProvisionIcons.ts b/packages/scripts/src/buildAssets/consumableProvisionIcons.ts index 5028f730c..d99903e9c 100644 --- a/packages/scripts/src/buildAssets/consumableProvisionIcons.ts +++ b/packages/scripts/src/buildAssets/consumableProvisionIcons.ts @@ -1,11 +1,6 @@ -import { existsSync } from "fs"; import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; -import { readStringDVPL } from "../../src/core/blitz/readStringDVPL"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { ConsumablesCommon, ProvisionsCommon } from "./definitions"; interface Mappings { @@ -33,20 +28,20 @@ export async function consumableProvisionIcons() { styles.map(async (path) => Object.values( ( - await readYAMLDVPL(`${DATA}/${path}`) + await vfs.yaml(`Data/${path}`) ).StyleSheets ) ) ).then((array) => array.flat()); for (const match of ( - await readStringDVPL( - `${DATA}/XML/item_defs/vehicles/common/consumables/list.xml` + await vfs.text( + `Data/XML/item_defs/vehicles/common/consumables/list.xml` ) ).matchAll(listItemsPattern)) { - const consumablesCommon = await readXMLDVPL<{ + const consumablesCommon = await vfs.xml<{ root: ConsumablesCommon; - }>(`${DATA}/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`); + }>(`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`); for (const consumable of Object.values(consumablesCommon.root)) { const styleSheet = styleSheets.find((styleSheet) => @@ -67,9 +62,9 @@ export async function consumableProvisionIcons() { .replace(".psd", "") .replace(".txt", ""); - if (existsSync(`${DATA}/${configPath}.packed.webp`)) { + if (vfs.has(`Data/${configPath}.packed.webp`)) { const image = sharp( - await readDVPLFile(`${DATA}/${configPath}.packed.webp`) + await vfs.file(`Data/${configPath}.packed.webp`) ); const content = await image.trim({ threshold: 100 }).toBuffer(); @@ -79,14 +74,14 @@ export async function consumableProvisionIcons() { }); } else { const consumablesTexture = sharp( - await readDVPLFile( - `${`${DATA}/${configPath}` + await vfs.file( + `${`Data/${configPath}` .split("/") .slice(0, -1) .join("/")}/texture0.packed.webp` ) ); - const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`)) + const sizes = (await vfs.text(`Data/${configPath}.txt`)) .split("\n")[4] .split(" ") .map(Number); @@ -109,13 +104,13 @@ export async function consumableProvisionIcons() { } for (const match of ( - await readStringDVPL( - `${DATA}/XML/item_defs/vehicles/common/provisions/list.xml` + await vfs.text( + `Data/XML/item_defs/vehicles/common/provisions/list.xml` ) ).matchAll(listItemsPattern)) { - const provisionsCommon = await readXMLDVPL<{ + const provisionsCommon = await vfs.xml<{ root: ProvisionsCommon; - }>(`${DATA}/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`); + }>(`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`); for (const provision of Object.values(provisionsCommon.root)) { const styleSheet = styleSheets.find((styleSheet) => @@ -136,9 +131,9 @@ export async function consumableProvisionIcons() { .replace(".psd", "") .replace(".txt", ""); - if (existsSync(`${DATA}/${configPath}.packed.webp`)) { + if (vfs.has(`Data/${configPath}.packed.webp`)) { const image = sharp( - await readDVPLFile(`${DATA}/${configPath}.packed.webp`) + await vfs.file(`Data/${configPath}.packed.webp`) ); const content = await image.trim({ threshold: 100 }).toBuffer(); @@ -148,14 +143,14 @@ export async function consumableProvisionIcons() { }); } else { const provisionsTexture = sharp( - await readDVPLFile( - `${`${DATA}/${configPath}` + await vfs.file( + `${`Data/${configPath}` .split("/") .slice(0, -1) .join("/")}/texture0.packed.webp` ) ); - const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`)) + const sizes = (await vfs.text(`Data/${configPath}.txt`)) .split("\n")[4] .split(" ") .map(Number); diff --git a/packages/scripts/src/buildAssets/currencies.ts b/packages/scripts/src/buildAssets/currencies.ts index b6a0467a8..71eb4272d 100644 --- a/packages/scripts/src/buildAssets/currencies.ts +++ b/packages/scripts/src/buildAssets/currencies.ts @@ -1,8 +1,7 @@ import { assertSecret, BlitzGlossary } from "@blitzkit/core"; import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; const ICONS = [ ["currency_silver_m.packed.webp", "silver"], @@ -21,7 +20,7 @@ export async function currencies() { for (const [file, name] of ICONS) { const content = await sharp( - await readDVPLFile(`${DATA}/Gfx/Lobby/currency/${file}`) + await vfs.file(`Data/Gfx/Lobby/currency/${file}`) ) .trim() .toBuffer(); diff --git a/packages/scripts/src/buildAssets/definitions.ts b/packages/scripts/src/buildAssets/definitions.ts index 5ed83c7d1..fc669459f 100644 --- a/packages/scripts/src/buildAssets/definitions.ts +++ b/packages/scripts/src/buildAssets/definitions.ts @@ -32,16 +32,12 @@ import { } from "@blitzkit/core"; import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n"; import locales from "@blitzkit/i18n/locales.json"; -import { readdir } from "fs/promises"; import { deburr } from "lodash-es"; import { parse as parsePath } from "path"; import type { Vector3Tuple } from "three"; import { parse as parseYaml } from "yaml"; -import { readStringDVPL } from "../core/blitz/readStringDVPL"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import type { Avatar } from "./skillIcons"; import type { TankParameters } from "./tankIcons"; @@ -540,9 +536,9 @@ export async function definitions() { using uploader = new AssetUploader("definitions"); const gameDefinitions: GameDefinitions = { - version: (await readStringDVPL(`${DATA}/version.txt`)).split(" ")[0], + version: (await vfs.text('Data/version.txt')).split(" ")[0], nations: ( - await readYAMLDVPL(`${DATA}/available_nations.yaml`) + await vfs.yaml('Data/available_nations.yaml') ).available_nations, gameModes: {}, roles: {}, @@ -565,12 +561,10 @@ export async function definitions() { [TankClass.TANK_DESTROYER]: { skills: [] }, }, }; - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== "common") - ); + const nations = vfs.dir('Data/XML/item_defs/vehicles').filter((nation) => nation !== "common") const tankStringIdMap: Record = {}; - const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>( - `${DATA}/XML/item_defs/vehicles/common/optional_devices.xml` + const optionalDevices = await vfs.xml<{ root: OptionalDevices }>( + 'Data/XML/item_defs/vehicles/common/optional_devices.xml' ); const stringsI18n: Record> = {}; @@ -582,8 +576,8 @@ export async function definitions() { ) .then((response) => response.text()) .then((string) => parseYaml(string) as BlitzStrings); - const preInstalled = await readYAMLDVPL( - `${DATA}/Strings/${blitzLocale}.yaml` + const preInstalled = await vfs.yaml( + `Data/Strings/${blitzLocale}.yaml` ); stringsI18n[locale] = { @@ -616,15 +610,15 @@ export async function definitions() { return { locales: collection } satisfies I18nString; } - const optionalDeviceSlots = await readXMLDVPL<{ + const optionalDeviceSlots = await vfs.xml<{ root: OptionalDeviceSlots; - }>(`${DATA}/XML/item_defs/vehicles/common/optional_device_slots.xml`); + }>(`Data/XML/item_defs/vehicles/common/optional_device_slots.xml`); const consumables: ConsumablesCommon = {}; const provisions: ProvisionsCommon = {}; for (const match of ( - await readStringDVPL( - `${DATA}/XML/item_defs/vehicles/common/consumables/list.xml` + await vfs.text( + `Data/XML/item_defs/vehicles/common/consumables/list.xml` ) ).matchAll(//g)) { if (match[1] === "prototypes") continue; @@ -632,16 +626,16 @@ export async function definitions() { Object.assign( consumables, ( - await readXMLDVPL<{ root: ConsumablesCommon }>( - `${DATA}/XML/item_defs/vehicles/common/consumables/${match[1]}.xml` + await vfs.xml<{ root: ConsumablesCommon }>( + `Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml` ) ).root ); } for (const match of ( - await readStringDVPL( - `${DATA}/XML/item_defs/vehicles/common/provisions/list.xml` + await vfs.text( + `Data/XML/item_defs/vehicles/common/provisions/list.xml` ) ).matchAll(//g)) { if (match[1] === "prototypes") continue; @@ -649,34 +643,34 @@ export async function definitions() { Object.assign( provisions, ( - await readXMLDVPL<{ root: ConsumablesCommon }>( - `${DATA}/XML/item_defs/vehicles/common/provisions/${match[1]}.xml` + await vfs.xml<{ root: ConsumablesCommon }>( + `Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml` ) ).root ); } - const avatar = await readXMLDVPL<{ root: Avatar }>( - `${DATA}/XML/item_defs/tankmen/avatar.xml` + const avatar = await vfs.xml<{ root: Avatar }>( + `Data/XML/item_defs/tankmen/avatar.xml` ); - const maps = await readYAMLDVPL(`${DATA}/maps.yaml`); + const maps = await vfs.yaml(`Data/maps.yaml`); const tankXps = new Map(); - const camouflagesXml = await readXMLDVPL<{ root: CamouflagesXML }>( - `${DATA}/XML/item_defs/vehicles/common/camouflages.xml` + const camouflagesXml = await vfs.xml<{ root: CamouflagesXML }>( + `Data/XML/item_defs/vehicles/common/camouflages.xml` ); - const camouflagesYaml = await readYAMLDVPL( - `${DATA}/camouflages.yaml` + const camouflagesYaml = await vfs.yaml( + `Data/camouflages.yaml` ); const camouflagesXmlEntries = Object.entries(camouflagesXml.root.camouflages); - const squadBattleTypeStyles = await readYAMLDVPL( - `${DATA}/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml` + const squadBattleTypeStyles = await vfs.yaml( + `Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml` ); - const gameTypeSelectorStyles = await readYAMLDVPL( - `${DATA}/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml` + const gameTypeSelectorStyles = await vfs.yaml( + `Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml` ); const gameModeNativeNames: Record = {}; - const combatRoles = await readYAMLDVPL( - `${DATA}/XML/item_defs/vehicles/common/combat_roles.yaml` + const combatRoles = await vfs.yaml( + `Data/XML/item_defs/vehicles/common/combat_roles.yaml` ); const consumableNativeNames: Record = {}; const provisionNativeNames: Record = {}; @@ -727,8 +721,8 @@ export async function definitions() { const idToNation: Record = {}; for (const nation of nations) { - const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tankList = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); for (const tankKey in tankList.root) { @@ -811,24 +805,24 @@ export async function definitions() { }); for (const nation of nations) { - const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tankList = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); - const turretList = await readXMLDVPL<{ + const turretList = await vfs.xml<{ root: TurretDefinitionsList; - }>(`${DATA}/XML/item_defs/vehicles/${nation}/components/turrets.xml`); - const gunList = await readXMLDVPL<{ + }>(`Data/XML/item_defs/vehicles/${nation}/components/turrets.xml`); + const gunList = await vfs.xml<{ root: GunDefinitionsList; - }>(`${DATA}/XML/item_defs/vehicles/${nation}/components/guns.xml`); - const shellList = await readXMLDVPL<{ + }>(`Data/XML/item_defs/vehicles/${nation}/components/guns.xml`); + const shellList = await vfs.xml<{ root: ShellDefinitionsList; - }>(`${DATA}/XML/item_defs/vehicles/${nation}/components/shells.xml`); - const enginesList = await readXMLDVPL<{ + }>(`Data/XML/item_defs/vehicles/${nation}/components/shells.xml`); + const enginesList = await vfs.xml<{ root: EngineDefinitionsList; - }>(`${DATA}/XML/item_defs/vehicles/${nation}/components/engines.xml`); - const chassisList = await readXMLDVPL<{ + }>(`Data/XML/item_defs/vehicles/${nation}/components/engines.xml`); + const chassisList = await vfs.xml<{ root: ChassisDefinitionsList; - }>(`${DATA}/XML/item_defs/vehicles/${nation}/components/chassis.xml`); + }>(`Data/XML/item_defs/vehicles/${nation}/components/chassis.xml`); function resolveUnlocks(unlocks?: BlitzModuleType) { if (!unlocks) return []; @@ -879,11 +873,11 @@ export async function definitions() { const trackXps = new Map(); const tank = tankList.root[tankKey]; let tankPrice: TankPrice; - const tankDefinition = await readXMLDVPL<{ root: VehicleDefinitions }>( - `${DATA}/XML/item_defs/vehicles/${nation}/${tankKey}.xml` + const tankDefinition = await vfs.xml<{ root: VehicleDefinitions }>( + `Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml` ); - const tankParameters = await readYAMLDVPL( - `${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` + const tankParameters = await vfs.yaml( + `Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` ); const turretOrigin = tankDefinition.root.hull.turretPositions.turret .split(" ") diff --git a/packages/scripts/src/buildAssets/equipmentIcons.ts b/packages/scripts/src/buildAssets/equipmentIcons.ts index 40a6cd55b..783d1458d 100644 --- a/packages/scripts/src/buildAssets/equipmentIcons.ts +++ b/packages/scripts/src/buildAssets/equipmentIcons.ts @@ -1,10 +1,6 @@ import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; -import { readStringDVPL } from "../../src/core/blitz/readStringDVPL"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { OptionalDevices } from "./definitions"; interface Mappings { @@ -20,15 +16,15 @@ export async function equipmentIcons() { console.log("Building equipment icons..."); using uploader = new AssetUploader("equipment icons"); - const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>( - `${DATA}/XML/item_defs/vehicles/common/optional_devices.xml` + const optionalDevices = await vfs.xml<{ root: OptionalDevices }>( + `Data/XML/item_defs/vehicles/common/optional_devices.xml` ); - const mappings = await readYAMLDVPL( - `${DATA}/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml` + const mappings = await vfs.yaml( + `Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml` ); const image = sharp( - await readDVPLFile( - `${DATA}/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp` + await vfs.file( + `Data/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp` ) ); @@ -54,7 +50,7 @@ export async function equipmentIcons() { if (configPath.startsWith("Gfx/Lobby")) { const configPathWebp = configPath.replace(".txt", ""); const image = sharp( - await readDVPLFile(`${DATA}/${configPathWebp}.packed.webp`) + await vfs.file(`Data/${configPathWebp}.packed.webp`) ); const content = await image.trim().toBuffer(); @@ -63,7 +59,7 @@ export async function equipmentIcons() { content, }); } else { - const config = await readStringDVPL(`${DATA}/${configPath}`); + const config = await vfs.text(`Data/${configPath}`); const sizes = config.split("\n")[4].split(" ").map(Number); const content = await image .clone() diff --git a/packages/scripts/src/buildAssets/flags.ts b/packages/scripts/src/buildAssets/flags.ts index 59dc04409..dbf3664ff 100644 --- a/packages/scripts/src/buildAssets/flags.ts +++ b/packages/scripts/src/buildAssets/flags.ts @@ -1,37 +1,28 @@ -import { readdir } from "fs/promises"; import sharp from "sharp"; -import { readDVPLFile } from "../core/blitz/readDVPLFile"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; export async function flags() { console.log("Building flags..."); using uploader = new AssetUploader("flags"); - const circleFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) => - files.filter( + const circleFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter( (flag) => flag.startsWith("flag_profile-stat_") && !flag.endsWith("@2x.packed.webp") - ) - ); - const scratchedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then( - (files) => - files.filter( + ); + const scratchedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter( (flag) => flag.startsWith("flag_tutor-tank_") && !flag.endsWith("@2x.packed.webp") ) - ); - const fadedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) => - files.filter( + const fadedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter( (flag) => flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp") ) - ); for (const flag of circleFiles) { - const image = sharp(await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`)); + const image = sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`)); const content = await image.trim({ threshold: 100 }).toBuffer(); const name = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1]; @@ -42,7 +33,7 @@ export async function flags() { } for (const flag of scratchedFiles) { - const content = await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`); + const content = await vfs.file(`Data/Gfx/Lobby/flags/${flag}`); const name = flag.match(/flag_tutor-tank_(.+)\.packed\.webp/)![1]; uploader.add({ @@ -53,7 +44,7 @@ export async function flags() { for (const flag of fadedFiles) { const content = await sharp( - await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`) + await vfs.file(`Data/Gfx/Lobby/flags/${flag}`) ) .trim({ threshold: 100, diff --git a/packages/scripts/src/buildAssets/gameModeBanners.ts b/packages/scripts/src/buildAssets/gameModeBanners.ts index 6c3bb1c10..feaf3b1f9 100644 --- a/packages/scripts/src/buildAssets/gameModeBanners.ts +++ b/packages/scripts/src/buildAssets/gameModeBanners.ts @@ -1,19 +1,17 @@ import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { SquadBattleTypeStyles } from "./definitions"; export async function gameModeBanners() { console.log("Building game mode banners..."); using uploader = new AssetUploader("game mode banners"); - const gameTypeSelectorStyles = await readYAMLDVPL( - `${DATA}/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml` + const gameTypeSelectorStyles = await vfs.yaml( + `Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml` ); - const squadBattleTypeStyles = await readYAMLDVPL( - `${DATA}/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml` + const squadBattleTypeStyles = await vfs.yaml( + `Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml` ); const bannerMatches: { name: string; path: string }[] = []; @@ -37,7 +35,7 @@ export async function gameModeBanners() { } const content = await sharp( - await readDVPLFile(`${DATA}${path}.packed.webp`) + await vfs.file(`Data${path}.packed.webp`) ) .trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } }) .toBuffer(); diff --git a/packages/scripts/src/buildAssets/index.ts b/packages/scripts/src/buildAssets/index.ts index 323d601a4..495765e0c 100644 --- a/packages/scripts/src/buildAssets/index.ts +++ b/packages/scripts/src/buildAssets/index.ts @@ -1,16 +1,8 @@ import { config } from "dotenv"; import { argv } from "process"; - -config(); - -const allTargets = argv.includes("--all-targets"); -const targets = argv - .find((argument) => argument.startsWith("--target")) - ?.split("=")[1] - .split(","); - import { boosterIcons } from "./boosterIcons"; import { camouflageIcons } from "./camouflageIcons"; +import { vfs } from "./constants"; import { consumableProvisionIcons } from "./consumableProvisionIcons"; import { currencies } from "./currencies"; import { definitions } from "./definitions"; @@ -27,6 +19,14 @@ import { tankArmors } from "./tankArmors"; import { tankIcons } from "./tankIcons"; import { tankModels } from "./tankModels"; +config(); + +const allTargets = argv.includes("--all-targets"); +const targets = argv + .find((argument) => argument.startsWith("--target")) + ?.split("=")[1] + .split(","); + if (!targets && !allTargets) throw new Error("No target(s) specified"); const methods = [ @@ -59,3 +59,6 @@ for (const method of methods) { } } } + +vfs.dispose(); +process.exit(0); diff --git a/packages/scripts/src/buildAssets/migration.ts b/packages/scripts/src/buildAssets/migration.ts index 128f4d3d1..64501700b 100644 --- a/packages/scripts/src/buildAssets/migration.ts +++ b/packages/scripts/src/buildAssets/migration.ts @@ -1,8 +1,6 @@ import { toUniqueId } from "@blitzkit/core"; -import { readdir } from "fs/promises"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { VehicleDefinitionList } from "./definitions"; export async function migration() { @@ -10,13 +8,11 @@ export async function migration() { using uploader = new AssetUploader("migration map"); const map: Record = {}; - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== "common") - ); + const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common"); for (const nation of nations) { - const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tankList = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); for (const tankKey in tankList.root) { diff --git a/packages/scripts/src/buildAssets/moduleIcons.ts b/packages/scripts/src/buildAssets/moduleIcons.ts index 9c8ed681c..3d372e489 100644 --- a/packages/scripts/src/buildAssets/moduleIcons.ts +++ b/packages/scripts/src/buildAssets/moduleIcons.ts @@ -1,24 +1,20 @@ -import { readdir } from "fs/promises"; import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; export async function moduleIcons() { console.log("Building module icons..."); using uploader = new AssetUploader("module icons"); - const files = await readdir(`${DATA}/Gfx/UI/ModulesTechTree`).then((dir) => - dir.filter( + const files = vfs.dir(`Data/Gfx/UI/ModulesTechTree`).filter( (file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle") ) - ); for (const file of files) { const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1]; const name = nameRaw[0].toLowerCase() + nameRaw.slice(1); const content = await sharp( - await readDVPLFile(`${DATA}/Gfx/UI/ModulesTechTree/${file}`) + await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`) ) .trim() .toBuffer(); diff --git a/packages/scripts/src/buildAssets/shellIcons.ts b/packages/scripts/src/buildAssets/shellIcons.ts index c7557eca5..ead72a07d 100644 --- a/packages/scripts/src/buildAssets/shellIcons.ts +++ b/packages/scripts/src/buildAssets/shellIcons.ts @@ -1,28 +1,25 @@ -import { readdir } from "fs/promises"; import sharp from "sharp"; -import { readDVPLFile } from "../../src/core/blitz/readDVPLFile"; -import { readStringDVPL } from "../../src/core/blitz/readStringDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; export async function shellIcons() { console.log("Building shell icons..."); using uploader = new AssetUploader("shell icons"); const image = sharp( - await readDVPLFile( - `${DATA}/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp` + await vfs.file( + `Data/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp` ) ); - const files = await readdir( - `${DATA}/Gfx/Shared/tank-supply/ammunition/big` - ).then((files) => files.filter((file) => file.endsWith("_l.txt"))); + const files = vfs.dir( + `Data/Gfx/Shared/tank-supply/ammunition/big` + ).filter((file) => file.endsWith("_l.txt")) for (const file of files) { const name = file.match(/(.+)_l\.txt/)![1]; const sizes = ( - await readStringDVPL( - `${DATA}/Gfx/Shared/tank-supply/ammunition/big/${file}` + await vfs.text( + `Data/Gfx/Shared/tank-supply/ammunition/big/${file}` ) ) .split("\n")[4] diff --git a/packages/scripts/src/buildAssets/skillIcons.ts b/packages/scripts/src/buildAssets/skillIcons.ts index 2088b31a8..4c6b67a4c 100644 --- a/packages/scripts/src/buildAssets/skillIcons.ts +++ b/packages/scripts/src/buildAssets/skillIcons.ts @@ -1,9 +1,7 @@ import { TankClass } from "@blitzkit/core"; import sharp from "sharp"; -import { readDVPLFile } from "../core/blitz/readDVPLFile"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; interface SkillIcon { name: string; @@ -27,8 +25,8 @@ export interface Avatar { export async function skillIcons() { console.log("Building skill icons..."); - const avatar = await readXMLDVPL<{ root: Avatar }>( - `${DATA}/XML/item_defs/tankmen/avatar.xml` + const avatar = await vfs.xml<{ root: Avatar }>( + `Data/XML/item_defs/tankmen/avatar.xml` ); using uploader = new AssetUploader("skill icons"); @@ -36,8 +34,8 @@ export async function skillIcons() { const skill = avatar.root.skills[key]; const icon = Array.isArray(skill.icon) ? skill.icon[0] : skill.icon; const name = icon.name.split("/").at(-1)!.replace(/_\d$/, ""); - const path = `${DATA}${icon.name.replace("~res:", "")}.packed.webp`; - const image = sharp(await readDVPLFile(path)).trim(); + const path = `Data${icon.name.replace("~res:", "")}.packed.webp`; + const image = sharp(await vfs.file(path)).trim(); const content = await image.toBuffer(); await uploader.add({ content, path: `icons/skills/${name}.webp` }); diff --git a/packages/scripts/src/buildAssets/tankArmors.ts b/packages/scripts/src/buildAssets/tankArmors.ts index e69807d70..0e8de7940 100644 --- a/packages/scripts/src/buildAssets/tankArmors.ts +++ b/packages/scripts/src/buildAssets/tankArmors.ts @@ -1,10 +1,8 @@ import { toUniqueId } from "@blitzkit/core"; import { NodeIO } from "@gltf-transform/core"; -import { readdir } from "fs/promises"; import { extractArmor } from "../core/blitz/extractArmor"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { VehicleDefinitionList } from "./definitions"; export async function tankArmors() { @@ -12,13 +10,11 @@ export async function tankArmors() { using uploader = new AssetUploader("tank armors"); const nodeIO = new NodeIO(); - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== "common") - ); + const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common"); for (const nation of nations) { - const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tanks = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); for (const tankKey in tanks.root) { @@ -27,7 +23,7 @@ export async function tankArmors() { if (tankKey.includes("tutorial_bot")) continue; const id = toUniqueId(nation, tank.id); - const model = await extractArmor(DATA, `${nation}-${tankKey}`); + const model = await extractArmor(vfs, `${nation}-${tankKey}`); const content = await nodeIO.writeBinary(model); await uploader.add({ path: `3d/tanks/armor/${id}.glb`, content }); diff --git a/packages/scripts/src/buildAssets/tankIcons.ts b/packages/scripts/src/buildAssets/tankIcons.ts index 7c69043f4..4ab8000fb 100644 --- a/packages/scripts/src/buildAssets/tankIcons.ts +++ b/packages/scripts/src/buildAssets/tankIcons.ts @@ -1,12 +1,8 @@ import { NATION_IDS } from "@blitzkit/core"; -import { readdir } from "fs/promises"; import sharp from "sharp"; import type { Vector3Tuple } from "three"; -import { readDVPLFile } from "../core/blitz/readDVPLFile"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import type { VehicleDefinitionList } from "./definitions"; export interface TankParameters { @@ -45,13 +41,11 @@ export async function tankIcons() { console.log("Building tank icons..."); using uploader = new AssetUploader("tank icons"); - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== "common") - ); + const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common") for (const nation of nations) { - const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tanks = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); for (const tankKey in tanks.root) { @@ -62,19 +56,19 @@ export async function tankIcons() { const nationVehicleId = tank.id; const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1; - const parameters = await readYAMLDVPL( - `${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` + const parameters = await vfs.yaml( + `Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` ); - const smallPath = `${DATA}/${parameters.resourcesPath.smallIconPath + const smallPath = `Data/${parameters.resourcesPath.smallIconPath .replace(/~res:\//, "") .replace(/\..+/, "")}.packed.webp`; - const bigPath = `${DATA}/${parameters.resourcesPath.bigIconPath + const bigPath = `Data/${parameters.resourcesPath.bigIconPath .replace(/~res:\//, "") .replace(/\..+/, "")}.packed.webp`; - const big = await sharp(await readDVPLFile(bigPath)) + const big = await sharp(await vfs.file(bigPath)) .trim() .toBuffer(); - const small = await sharp(await readDVPLFile(smallPath)) + const small = await sharp(await vfs.file(smallPath)) .trim() .toBuffer(); diff --git a/packages/scripts/src/buildAssets/tankModels.ts b/packages/scripts/src/buildAssets/tankModels.ts index ff206605b..ca206dad4 100644 --- a/packages/scripts/src/buildAssets/tankModels.ts +++ b/packages/scripts/src/buildAssets/tankModels.ts @@ -1,12 +1,9 @@ import { toUniqueId } from "@blitzkit/core"; import { NodeIO } from "@gltf-transform/core"; import { ALL_EXTENSIONS } from "@gltf-transform/extensions"; -import { readdir } from "fs/promises"; import { extractModel } from "../core/blitz/extractModel"; -import { readXMLDVPL } from "../core/blitz/readXMLDVPL"; -import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL"; import { AssetUploader } from "../core/github/assetUploader"; -import { DATA } from "./constants"; +import { vfs } from "./constants"; import { VehicleDefinitionList } from "./definitions"; import { TankParameters } from "./tankIcons"; @@ -15,14 +12,12 @@ export async function tankModels() { using uploader = new AssetUploader("tank models"); const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS); - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== "common") - ); + const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common") for (const nationIndex in nations) { const nation = nations[nationIndex]; - const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml` + const tanks = await vfs.xml<{ root: VehicleDefinitionList }>( + `Data/XML/item_defs/vehicles/${nation}/list.xml` ); const entries = Object.entries(tanks.root); @@ -30,11 +25,11 @@ export async function tankModels() { if (tankKey.includes("tutorial_bot")) continue; const id = toUniqueId(nation, tank.id); - const parameters = await readYAMLDVPL( - `${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` + const parameters = await vfs.yaml( + `Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml` ); const model = await extractModel( - DATA, + vfs, parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, "") ); const content = Buffer.from(await nodeIO.writeBinary(model)); diff --git a/packages/scripts/src/core/blitz/extractArmor.ts b/packages/scripts/src/core/blitz/extractArmor.ts index 5d55e9a63..2973e5a8f 100644 --- a/packages/scripts/src/core/blitz/extractArmor.ts +++ b/packages/scripts/src/core/blitz/extractArmor.ts @@ -2,24 +2,24 @@ import { Hierarchy, Sc2ReadStream, ScgReadStream, + SteamVFS, VertexAttribute, -} from '@blitzkit/core'; -import { Accessor, Document, Node, Scene } from '@gltf-transform/core'; -import { times } from 'lodash-es'; +} from "@blitzkit/core"; +import { Accessor, Document, Node, Scene } from "@gltf-transform/core"; +import { times } from "lodash-es"; import { vertexAttributeGLTFName, vertexAttributeGltfVectorSizes, -} from './extractModel/constants'; -import { readDVPLFile } from './readDVPLFile'; +} from "./extractModel/constants"; -export async function extractArmor(data: string, fileName: string) { - const sc2Path = `${data}/3d/Tanks/CollisionMeshes/${fileName}.sc2`; - const scgPath = `${data}/3d/Tanks/CollisionMeshes/${fileName}.scg`; +export async function extractArmor(vfs: SteamVFS, fileName: string) { + const sc2Path = `Data/3d/Tanks/CollisionMeshes/${fileName}.sc2`; + const scgPath = `Data/3d/Tanks/CollisionMeshes/${fileName}.scg`; const sc2 = new Sc2ReadStream( - (await readDVPLFile(sc2Path)).buffer as ArrayBuffer, + (await vfs.file(sc2Path)).buffer as ArrayBuffer ).sc2(); const scg = new ScgReadStream( - (await readDVPLFile(scgPath)).buffer as ArrayBuffer, + (await vfs.file(scgPath)).buffer as ArrayBuffer ).scg(); const document = new Document(); const scene = document.createScene(); @@ -29,21 +29,21 @@ export async function extractArmor(data: string, fileName: string) { hierarchies.forEach((hierarchy) => { const components = times( hierarchy.components.count, - (index) => hierarchy.components[index.toString().padStart(4, '0')], + (index) => hierarchy.components[index.toString().padStart(4, "0")] ); components.forEach((component) => { - switch (component['comp.typename']) { - case 'TransformComponent': + switch (component["comp.typename"]) { + case "TransformComponent": break; - case 'RenderComponent': { - const batch = component['rc.renderObj']['ro.batches']['0000']; - const polygonGroup = scg.get(batch['rb.datasource']); + case "RenderComponent": { + const batch = component["rc.renderObj"]["ro.batches"]["0000"]; + const polygonGroup = scg.get(batch["rb.datasource"]); if (!polygonGroup) { console.warn( - `Missing polygon group ${batch['rb.datasource']} (${hierarchy.name}); skipping...`, + `Missing polygon group ${batch["rb.datasource"]} (${hierarchy.name}); skipping...` ); break; @@ -73,7 +73,7 @@ export async function extractArmor(data: string, fileName: string) { VertexAttribute.TANGENT, attributes .get(VertexAttribute.TANGENT)! - .map((tangent) => [...tangent, 1]), + .map((tangent) => [...tangent, 1]) ); } @@ -85,7 +85,7 @@ export async function extractArmor(data: string, fileName: string) { const vertexSize = vertexAttributeGltfVectorSizes[attribute]; const accessor = document .createAccessor(name) - .setType(vertexSize === 1 ? 'SCALAR' : `VEC${vertexSize}`) + .setType(vertexSize === 1 ? "SCALAR" : `VEC${vertexSize}`) .setArray(new Float32Array(value.flat())) .setBuffer(buffer); @@ -94,19 +94,19 @@ export async function extractArmor(data: string, fileName: string) { hardJointIndices.forEach((hardJointIndex) => { const node = document.createNode( - `${hierarchy.name}_armor_${hardJointIndex}`, + `${hierarchy.name}_armor_${hardJointIndex}` ); - const mesh = document.createMesh(batch['##name']); + const mesh = document.createMesh(batch["##name"]); const indicesAccessor = document .createAccessor() - .setType('SCALAR') + .setType("SCALAR") .setArray( new Uint16Array( polygonGroup.indices.filter( (index) => - vertexHardJointIndices.get(index) === hardJointIndex, - ), - ), + vertexHardJointIndices.get(index) === hardJointIndex + ) + ) ) .setBuffer(buffer); const primitive = document @@ -127,18 +127,18 @@ export async function extractArmor(data: string, fileName: string) { default: throw new TypeError( - `Unhandled component type: ${component['comp.typename']}`, + `Unhandled component type: ${component["comp.typename"]}` ); } }); - if (hierarchy['#hierarchy']) { - parseHierarchies(hierarchy['#hierarchy'], parent); + if (hierarchy["#hierarchy"]) { + parseHierarchies(hierarchy["#hierarchy"], parent); } }); } - parseHierarchies(sc2['#hierarchy'], scene); + parseHierarchies(sc2["#hierarchy"], scene); return document; } diff --git a/packages/scripts/src/core/blitz/extractModel/index.ts b/packages/scripts/src/core/blitz/extractModel/index.ts index 7f888def8..20b7ce82e 100644 --- a/packages/scripts/src/core/blitz/extractModel/index.ts +++ b/packages/scripts/src/core/blitz/extractModel/index.ts @@ -2,6 +2,7 @@ import { Hierarchy, Sc2ReadStream, ScgReadStream, + SteamVFS, Textures, VertexAttribute, } from "@blitzkit/core"; @@ -10,7 +11,6 @@ import { dedup, prune } from "@gltf-transform/functions"; import { times } from "lodash-es"; import { dirname } from "path"; import { readBaseColor } from "../readBaseColor"; -import { readDVPLFile } from "../readDVPLFile"; import { readNormal } from "../readNormal"; import { readRoughnessMetallic } from "../readRoughnessMetallic"; import { @@ -25,14 +25,14 @@ const omitMeshNames = { end: ["_POINT"], }; -export async function extractModel(data: string, path: string) { - const sc2Path = `${data}/3d/${path}.sc2`; - const scgPath = `${data}/3d/${path}.scg`; +export async function extractModel(vfs: SteamVFS, path: string) { + const sc2Path = `Data/3d/${path}.sc2`; + const scgPath = `Data/3d/${path}.scg`; const sc2 = new Sc2ReadStream( - (await readDVPLFile(sc2Path)).buffer as ArrayBuffer + (await vfs.file(sc2Path)).buffer as ArrayBuffer ).sc2(); const scg = new ScgReadStream( - (await readDVPLFile(scgPath)).buffer as ArrayBuffer + (await vfs.file(scgPath)).buffer as ArrayBuffer ).scg(); const document = new Document(); const scene = document.createScene(); @@ -67,11 +67,11 @@ export async function extractModel(data: string, path: string) { .setMimeType("image/webp") .setImage( await readBaseColor( - `${data}/3d/${dirname(path)}/${ + `Data/3d/${dirname(path)}/${ textures.baseColorMap ?? textures.albedo }`, textures.miscMap - ? `${data}/3d/${dirname(path)}/${textures.miscMap}` + ? `Data/3d/${dirname(path)}/${textures.miscMap}` : undefined ) ) @@ -103,7 +103,7 @@ export async function extractModel(data: string, path: string) { .setMimeType("image/webp") .setImage( await readRoughnessMetallic( - `${data}/3d/${dirname(path)}/${textures.baseRMMap}` + `Data/3d/${dirname(path)}/${textures.baseRMMap}` ) ) ); @@ -118,7 +118,7 @@ export async function extractModel(data: string, path: string) { .setMimeType("image/webp") .setImage( await readNormal( - `${data}/3d/${dirname(path)}/${ + `Data/3d/${dirname(path)}/${ textures.baseNormalMap ?? textures.normalmap }`, isBase diff --git a/packages/scripts/src/core/blitz/readBase64DVPL.ts b/packages/scripts/src/core/blitz/readBase64DVPL.ts deleted file mode 100644 index 4e50b9042..000000000 --- a/packages/scripts/src/core/blitz/readBase64DVPL.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { readDVPLFile } from './readDVPLFile'; - -export async function readBase64DVPL(file: string) { - const buffer = await readDVPLFile(file); - return buffer.toString('base64'); -} diff --git a/packages/scripts/src/core/blitz/readDVPLFile.ts b/packages/scripts/src/core/blitz/readDVPLFile.ts deleted file mode 100644 index 422ef7258..000000000 --- a/packages/scripts/src/core/blitz/readDVPLFile.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { readFile } from 'fs/promises'; -import { DATA_COMPRESSED } from '../../buildAssets/constants'; -import { readDVPL } from './readDVPL'; - -export async function readDVPLFile(file: string) { - let path: string; - - if (DATA_COMPRESSED) { - path = file.endsWith('.dvpl') ? file : `${file}.dvpl`; - } else { - path = file.replace('.dvpl', ''); - } - - const content = await readFile(path); - - if (!DATA_COMPRESSED) return content; - - const dvpl = readDVPL(content); - - return dvpl; -} diff --git a/packages/scripts/src/core/blitz/readStringDVPL.ts b/packages/scripts/src/core/blitz/readStringDVPL.ts deleted file mode 100644 index 46c799be9..000000000 --- a/packages/scripts/src/core/blitz/readStringDVPL.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { readDVPLFile } from './readDVPLFile'; - -export async function readStringDVPL(file: string) { - const buffer = await readDVPLFile(file); - return buffer.toString(); -} diff --git a/packages/scripts/src/core/blitz/readTexture/index.ts b/packages/scripts/src/core/blitz/readTexture/index.ts index 9893fcd2b..4d45f6605 100644 --- a/packages/scripts/src/core/blitz/readTexture/index.ts +++ b/packages/scripts/src/core/blitz/readTexture/index.ts @@ -1,81 +1,17 @@ import { DdsReadStream, PvrReadStream } from "@blitzkit/core"; -import { existsSync } from "fs"; -import { DATA_COMPRESSED } from "../../../buildAssets/constants"; -import { readDVPLFile } from "../readDVPLFile"; +import { vfs } from "../../../buildAssets/constants"; export async function readTexture(path: string) { const ddsTexturePath = path.replace(".tex", ".dx11.dds"); - const isDds = existsSync( - `${ddsTexturePath}${DATA_COMPRESSED ? ".dvpl" : ""}` - ); + const isDds = vfs.has(ddsTexturePath); const resolvedTexturePath = isDds ? ddsTexturePath : ddsTexturePath.replace(".dds", ".pvr"); - const decompressedDvpl = await readDVPLFile(`${resolvedTexturePath}.dvpl`); + const file = await vfs.file(resolvedTexturePath); const raw = isDds - ? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds() - : new PvrReadStream(decompressedDvpl.buffer as ArrayBuffer).pvr(); + ? await new DdsReadStream(file.buffer as ArrayBuffer).dds() + : new PvrReadStream(file.buffer as ArrayBuffer).pvr(); return raw; - - // switch (mutation) { - // case TextureMutation.Normal: { - // const bytes = 4 * raw.width * raw.height; - // for (let index = 0; index < bytes; index += 4) { - // /** - // * Red is always 255 and blue is always 0. Only alpha and green contain any - // * sort of information. - // */ - // let x = raw.data[index + 3] * (2 / 255) - 1; - // let y = raw.data[index + 1] * (2 / 255) - 1; - // const underSqrt = 1 - x ** 2 - y ** 2; - // let z = underSqrt > 0 ? Math.sqrt(underSqrt) : -Math.sqrt(-underSqrt); - - // raw.data[index] = Math.round((x + 1) * (255 / 2)); - // raw.data[index + 1] = Math.round((y + 1) * (255 / 2)); - // raw.data[index + 2] = Math.round((z + 1) * (255 / 2)); - // raw.data[index + 3] = 255; - // } - - // return await sharp(raw.data, { raw }).jpeg().toBuffer(); - // } - - // case TextureMutation.RoughnessMetallicness: { - // const newImage = sharp(Buffer.alloc(raw.width * raw.height), { - // raw: { ...raw, channels: 1 }, - // }); - // const metallicness = sharp(raw.data, { raw }) - // .extractChannel("green") - // .jpeg() - // .toBuffer(); - // const roughness = sharp(raw.data, { raw }) - // .extractChannel("alpha") - // .jpeg() - // .toBuffer(); - - // return await newImage - // .joinChannel(await Promise.all([roughness, metallicness])) - // .jpeg() - // .toBuffer(); - // } - - // case TextureMutation.Miscellaneous: { - // /** - // * Alpha is ambient occlusion and green is emissive. But very few tanks - // * use emissive so I am ignoring it for now. - // */ - // return await sharp(raw.data, { raw }) - // .extractChannel("alpha") - // .jpeg() - // .toBuffer(); - // } - - // case TextureMutation.Albedo: { - // return await sharp(raw.data, { raw }).removeAlpha().jpeg().toBuffer(); - // } - - // default: - // return await sharp(raw.data, { raw }).jpeg().toBuffer(); - // } } diff --git a/packages/scripts/src/core/blitz/readXMLDVPL.ts b/packages/scripts/src/core/blitz/readXMLDVPL.ts deleted file mode 100644 index 9ace498ad..000000000 --- a/packages/scripts/src/core/blitz/readXMLDVPL.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { XMLParser } from 'fast-xml-parser'; -import { readStringDVPL } from './readStringDVPL'; - -export async function readXMLDVPL(file: string) { - const parser = new XMLParser(); - const xml = await readStringDVPL(file); - - return parser.parse(xml) as Type; -} diff --git a/packages/scripts/src/core/blitz/readYAML.ts b/packages/scripts/src/core/blitz/readYAML.ts deleted file mode 100644 index e459e5426..000000000 --- a/packages/scripts/src/core/blitz/readYAML.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { readFile } from 'fs/promises'; -import { parse } from 'yaml'; - -export async function readYAML(file: string) { - const yaml = (await readFile(file)).toString(); - return parse(yaml) as Type; -} diff --git a/packages/scripts/src/core/blitz/readYAMLDVPL.ts b/packages/scripts/src/core/blitz/readYAMLDVPL.ts deleted file mode 100644 index c95623225..000000000 --- a/packages/scripts/src/core/blitz/readYAMLDVPL.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { parse } from 'yaml'; -import { readStringDVPL } from './readStringDVPL'; - -export async function readYAMLDVPL(file: string) { - const yaml = await readStringDVPL(file); - - return parse(yaml) as Type; -} diff --git a/packages/scripts/src/core/github/assetUploader.ts b/packages/scripts/src/core/github/assetUploader.ts index ce24de2e3..0a064e25e 100644 --- a/packages/scripts/src/core/github/assetUploader.ts +++ b/packages/scripts/src/core/github/assetUploader.ts @@ -99,7 +99,7 @@ export class AssetUploader { } if (diff.status === DiffStatus.Unchanged) { - // console.log(`🔵 ${change.path}`); + console.log(`🔵 ${change.path}`); } else { console.log( `${diff.status === DiffStatus.New ? "🟢" : "🟡"} (${ diff --git a/packages/scripts/src/setupDepotDownloader.ts b/packages/scripts/src/setupDepotDownloader.ts index ab4fe84f4..72ef9322b 100644 --- a/packages/scripts/src/setupDepotDownloader.ts +++ b/packages/scripts/src/setupDepotDownloader.ts @@ -1,39 +1,39 @@ -import decompress from 'decompress'; -import { existsSync } from 'fs'; -import { mkdir, readdir, writeFile } from 'fs/promises'; +import decompress from "decompress"; +import { existsSync } from "fs"; +import { mkdir, readdir, writeFile } from "fs/promises"; -if (!existsSync('../../temp')) { - console.log('Creating temp directory...'); - await mkdir('../../temp'); +if (!existsSync("../../temp")) { + console.log("Creating temp directory..."); + await mkdir("../../temp"); } -console.log('Downloading depot downloader...'); +console.log("Downloading depot downloader..."); await fetch( - 'https://api.github.com/repos/SteamRE/DepotDownloader/releases/latest', + "https://api.github.com/repos/SteamRE/DepotDownloader/releases/latest" ) .then( (response) => response.json() as Promise<{ assets: { browser_download_url: string; name: string }[]; - }>, + }> ) .then(({ assets }) => { - const asset = assets.find(({ name }) => name.includes('linux-x64')); - if (!asset) throw new Error('No asset found'); + const asset = assets.find(({ name }) => name.includes("linux-x64")); + if (!asset) throw new Error("No asset found"); return fetch(asset.browser_download_url); }) .then((response) => response.arrayBuffer()) .then((arrayBuffer) => - writeFile('../../temp/depotDownloader.zip', new Uint8Array(arrayBuffer)), + writeFile("../../temp/depotDownloader.zip", new Uint8Array(arrayBuffer)) ); -console.log('Unzipping...'); +console.log("Unzipping..."); await decompress( - '../../temp/depotDownloader.zip', - '../../temp/depotDownloader', + "../../temp/depotDownloader.zip", + "../../temp/depotDownloader" ); console.log( - 'Download complete; files:', - await readdir('../../temp/depotDownloader'), + "Download complete; files:", + await readdir("../../temp/depotDownloader") ); diff --git a/packages/scripts/tsconfig.json b/packages/scripts/tsconfig.json index 52d43eaaa..6dd4197cd 100644 --- a/packages/scripts/tsconfig.json +++ b/packages/scripts/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*"] + "include": ["src/**/*", "../core/src/blitz/readDVPL.ts"] } diff --git a/packages/website/public/PROPOUND.WAV b/packages/website/public/PROPOUND.WAV new file mode 100644 index 000000000..aaece2351 Binary files /dev/null and b/packages/website/public/PROPOUND.WAV differ