mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-25 03:29:51 +01:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6c0e02fea | ||
|
|
028f4230e5 | ||
|
|
cf31ad8f7a | ||
|
|
9418526897 |
No files matched your search
@@ -206,8 +206,6 @@
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.6.1",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/react": "^19.2.15",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/three": "^0.184.1",
|
||||
"@vite-pwa/astro": "^1.2.0",
|
||||
"@wooorm/starry-night": "^3.9.0",
|
||||
@@ -3109,8 +3107,6 @@
|
||||
|
||||
"@blitzkit/website-ue/@gltf-transform/core": ["@gltf-transform/[email protected]", "", { "dependencies": { "property-graph": "^4.1.0" } }, "sha512-cOPxOhHFFz5hwmix+li1+Nnq5qMV/QD3fTCsVlApxxFACtFdjkt2R/juseD4gvZ7D2c/yl6OilKH0pvI735YyQ=="],
|
||||
|
||||
"@blitzkit/website-ue/@types/react": ["@types/[email protected]", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q=="],
|
||||
|
||||
"@blitzkit/website-ue/astro": ["[email protected]", "", { "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/internal-helpers": "0.7.6", "@astrojs/markdown-remark": "6.3.11", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "acorn": "^8.15.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.3.1", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.1.1", "cssesc": "^3.0.0", "debug": "^4.4.3", "deterministic-object-hash": "^2.0.2", "devalue": "^5.6.2", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.27.3", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.4.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.1", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.3", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.3", "unist-util-visit": "^5.0.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^6.4.1", "vitefu": "^1.1.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.3", "zod": "^3.25.76", "zod-to-json-schema": "^3.25.1", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "astro.js" } }, "sha512-TnFwLnAXty5MXKPDGuKXqK4AMBXG+FH6RUdK7Oyc3gyfNoFIthT+4eRbzOK43bdRlLaZuxgciDSjgtggZ3OtGQ=="],
|
||||
|
||||
"@blitzkit/website-ue/astro-favicons": ["[email protected]", "", { "dependencies": { "favilib": "^1.0.5", "ultrahtml": "^1.5.3" }, "peerDependencies": { "astro": ">= 4.0.0" } }, "sha512-9YfNWaBEFz1nCHy4P1l4wfPRvuLe4qHuHovIcqD5HYfZeW82wyVG1+CZUVGhcjwbRCVkGRJ3G+CKTyX9BcoI5w=="],
|
||||
|
||||
@@ -240,14 +240,16 @@ public partial class GameInterface
|
||||
|
||||
if (dataTable == null)
|
||||
{
|
||||
throw new ArgumentException($"Unknown tank part: {part}");
|
||||
Console.WriteLine($"Unknown tank part (no matching data table): {part}");
|
||||
return [];
|
||||
}
|
||||
|
||||
dataTable.TryGetDataTableRow(part, StringComparison.Ordinal, out var row);
|
||||
|
||||
if (row == null)
|
||||
{
|
||||
throw new ArgumentException($"Unknown tank part: {part}");
|
||||
Console.WriteLine($"Unknown tank part (no matching row): {part}");
|
||||
return [];
|
||||
}
|
||||
|
||||
var visualData = row.Get<UObject>("VisualData");
|
||||
|
||||
@@ -34,11 +34,11 @@ public class MonoGltf
|
||||
|
||||
readonly MaterialBuilder emptyMaterial = new("empty_material");
|
||||
readonly ExporterOptions options = new() { TextureFormat = ETextureFormat.Jpeg };
|
||||
public static readonly Dictionary<string, KnownChannel> knownChannels = new()
|
||||
public static readonly Dictionary<string, KnownChannel[]> knownChannels = new()
|
||||
{
|
||||
{ "BaseColor", KnownChannel.BaseColor },
|
||||
{ "Normal", KnownChannel.Normal },
|
||||
{ "RMAO", KnownChannel.MetallicRoughness },
|
||||
{ "BaseColor", [KnownChannel.BaseColor] },
|
||||
{ "Normal", [KnownChannel.Normal] },
|
||||
{ "RMAO", [KnownChannel.MetallicRoughness, KnownChannel.Occlusion] },
|
||||
// { "CDE", ?? },
|
||||
};
|
||||
readonly byte[] stubBytes = File.ReadAllBytes("../game/stub/small.png");
|
||||
@@ -152,7 +152,7 @@ public class MonoGltf
|
||||
|
||||
foreach (var parameterTexture in materialData.Parameters.Textures)
|
||||
{
|
||||
if (knownChannels.TryGetValue(parameterTexture.Key, out var channel))
|
||||
if (knownChannels.TryGetValue(parameterTexture.Key, out var channels))
|
||||
{
|
||||
var texture = parameterTexture.Value;
|
||||
var name = Path.GetFileNameWithoutExtension(texture.GetPathName());
|
||||
@@ -163,8 +163,11 @@ public class MonoGltf
|
||||
var uniqueBytes = (byte[])stubBytes.Clone();
|
||||
var stubImage = new MemoryImage(uniqueBytes);
|
||||
|
||||
materialBuilder.WithChannelImage(channel, stubImage);
|
||||
materialBuilder.GetChannel(channel).Texture.PrimaryImage.Name = path;
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
materialBuilder.WithChannelImage(channel, stubImage);
|
||||
materialBuilder.GetChannel(channel).Texture.PrimaryImage.Name = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.6.1",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/react": "^19.2.15",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/three": "^0.184.1",
|
||||
"@vite-pwa/astro": "^1.2.0",
|
||||
"@wooorm/starry-night": "^3.9.0",
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="@react-three/fiber" />
|
||||
@@ -0,0 +1,20 @@
|
||||
import { notFoundResponse } from "./responses";
|
||||
|
||||
const cache = new Map<string, Uint8Array<ArrayBuffer>>();
|
||||
|
||||
export function bufferProxy(cook: () => number[], key: string) {
|
||||
let array = cache.get(key);
|
||||
|
||||
if (array === undefined) {
|
||||
const bytes = cook();
|
||||
array = new Uint8Array(bytes);
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
cache.set(key, array);
|
||||
}
|
||||
}
|
||||
|
||||
if (array.length === 0) return notFoundResponse;
|
||||
|
||||
return new Response(array);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import sharp from "sharp";
|
||||
import { bufferProxy } from "./bufferProxy";
|
||||
|
||||
export async function imageProxy(url: string) {
|
||||
if (import.meta.env.DEV) {
|
||||
|
||||
@@ -33,7 +33,7 @@ const strings = await api.strings(locale);
|
||||
width: 100%;
|
||||
height: calc(100% - var(--space-5) / 2);
|
||||
|
||||
background-image: url(/assets/home-hero.webp);
|
||||
background-image: url(/media/home-hero.webp);
|
||||
background-size: cover;
|
||||
background-position: top;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export function TankopediaSandbox({ parameters }: TankopediaSandboxProps) {
|
||||
<div className={styles.sandbox}>
|
||||
<Canvas
|
||||
// scene={{ fog: new FogExp2("black", 0.05) }}
|
||||
camera={{ fov: 40 }}
|
||||
shadows
|
||||
className={styles.canvas}
|
||||
frameloop="demand"
|
||||
@@ -42,11 +43,11 @@ function Content({ parameters }: TankopediaSandboxProps) {
|
||||
<primitive object={hull} />
|
||||
</group>
|
||||
|
||||
<group position={[0, 0, 5]}>
|
||||
<group position={[19.515463 / 100, 129.6958 / 100, 0.0039617573 / 100]}>
|
||||
<primitive object={turret} />
|
||||
</group>
|
||||
|
||||
<group position={[0, 0, -5]}>
|
||||
<group position={[154.39078 / 100, 178.7401 / 100, 0.11611016 / 100]}>
|
||||
<primitive object={gun} />
|
||||
</group>
|
||||
|
||||
|
||||
@@ -74,14 +74,14 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
<div
|
||||
class="tool-banner"
|
||||
style={{
|
||||
backgroundImage: `url(/assets/tools/${tool.id}.webp)`,
|
||||
backgroundImage: `url(/media/tools/banners/${tool.id}.webp)`,
|
||||
backgroundPosition: tool.banner_background_position ?? "top",
|
||||
}}
|
||||
>
|
||||
<div class="content">
|
||||
<div
|
||||
class="pattern"
|
||||
style={{ backgroundImage: `url(/assets/patterns/${tool.id}.svg)` }}
|
||||
style={{ backgroundImage: `url(/media/patterns/${tool.id}.svg)` }}
|
||||
>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useLoader } from "@react-three/fiber";
|
||||
import { useEffect } from "react";
|
||||
import { Mesh, MeshStandardMaterial } from "three";
|
||||
import { GLTFLoader } from "three-stdlib";
|
||||
import { OnObjectUpdate } from "three/src/nodes/utils/EventNode.js";
|
||||
|
||||
export function useTankModel(url: string, map: Record<string, boolean>) {
|
||||
const gltf = useLoader(GLTFLoader, url);
|
||||
@@ -17,8 +16,6 @@ export function useTankModel(url: string, map: Record<string, boolean>) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(gltf.nodes);
|
||||
|
||||
for (const node of Object.values(gltf.nodes)) {
|
||||
if (node instanceof Mesh) {
|
||||
node.castShadow = true;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { mixStaticPaths } from "../../../astro/mixStaticPaths";
|
||||
import { game } from "../../../game/game";
|
||||
import { getStaticPaths as _getStaticPaths } from "../_index";
|
||||
import { assertDiscoveryTag } from "../../../game/assertDiscoveryTag";
|
||||
import { bufferProxy } from "../../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||
return api.metadata
|
||||
@@ -11,13 +12,10 @@ export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||
.map(({ id }) => ({ params: { id } }));
|
||||
});
|
||||
|
||||
|
||||
export function GET({ params }: APIContext<never, { id: string }>) {
|
||||
const item = api.metadata.item(params.id);
|
||||
const assetsDiscovery = item.BlitzStaticAssetsDiscovery();
|
||||
const tag = assertDiscoveryTag(assetsDiscovery);
|
||||
const icon = game!.consumableIcon(tag);
|
||||
const array = new Uint8Array(icon);
|
||||
|
||||
return new Response(array);
|
||||
return bufferProxy(() => game!.consumableIcon(tag), `consumable-icon-${tag}`);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { mixStaticPaths } from "../../../astro/mixStaticPaths";
|
||||
import { game } from "../../../game/game";
|
||||
import { getStaticPaths as _getStaticPaths } from "../_index";
|
||||
import { assertDiscoveryTag } from "../../../game/assertDiscoveryTag";
|
||||
import { bufferProxy } from "../../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||
return api.metadata
|
||||
@@ -20,8 +21,6 @@ export function GET({ params }: APIContext<never, { id: string }>) {
|
||||
const item = api.metadata.item(params.id);
|
||||
const assetsDiscovery = item.BlitzStaticAssetsDiscovery();
|
||||
const tag = assertDiscoveryTag(assetsDiscovery);
|
||||
const icon = game!.equipmentIcon(tag);
|
||||
const array = new Uint8Array(icon);
|
||||
|
||||
return new Response(array);
|
||||
return bufferProxy(() => game!.equipmentIcon(tag), `equipment-icon-${tag}`);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { mixStaticPaths } from "../../../../astro/mixStaticPaths";
|
||||
import { game } from "../../../../game/game";
|
||||
import { clientUnmounted } from "../../../../game/unmounted";
|
||||
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||
import { bufferProxy } from "../../../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||
return Object.values(Nation)
|
||||
@@ -20,7 +21,6 @@ export async function GET({ params }: APIContext<never, { id: string }>) {
|
||||
|
||||
const enumName = Nation[Number(params.id)];
|
||||
const nationName = enumName.replace("NATION_", "").toLowerCase();
|
||||
const flag = game!.flag(nationName);
|
||||
|
||||
return new Response(new Uint8Array(flag));
|
||||
return bufferProxy(() => game!.flag(nationName), `flag-card-${nationName}`);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { assertDiscoveryTag } from "../../../../game/assertDiscoveryTag";
|
||||
import { game } from "../../../../game/game";
|
||||
import { clientUnmounted } from "../../../../game/unmounted";
|
||||
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||
import { bufferProxy } from "../../../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||
const { list } = await api.tankList();
|
||||
@@ -18,8 +19,6 @@ export async function GET({ params }: APIContext<never, { id: string }>) {
|
||||
const item = api.metadata.item(params.id);
|
||||
const assetDiscovery = item.BlitzStaticAssetsDiscovery();
|
||||
const tag = assertDiscoveryTag(assetDiscovery);
|
||||
const icon = game!.tankBigIcon(tag);
|
||||
const array = new Uint8Array(icon);
|
||||
|
||||
return new Response(array);
|
||||
return bufferProxy(() => game!.tankBigIcon(tag), `tank-icon-big-${tag}`);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { mixStaticPaths } from "../../../../astro/mixStaticPaths";
|
||||
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||
import { assertDiscoveryTag } from "../../../../game/assertDiscoveryTag";
|
||||
import { game } from "../../../../game/game";
|
||||
import { bufferProxy } from "../../../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||
const tanks = await api.tanks();
|
||||
@@ -36,8 +37,9 @@ export async function GET({
|
||||
const item = api.metadata.item(params.id);
|
||||
const assetDiscovery = item.BlitzStaticAssetsDiscovery();
|
||||
const tag = assertDiscoveryTag(assetDiscovery);
|
||||
const bytes = game!.tankPart(tag, params.part);
|
||||
const array = new Uint8Array(bytes);
|
||||
|
||||
return new Response(array);
|
||||
return bufferProxy(
|
||||
() => game!.tankPart(tag, params.part),
|
||||
`tank-part-${tag}-${params.part}`,
|
||||
);
|
||||
}
|
||||
@@ -2,13 +2,15 @@ import type { APIContext } from "astro";
|
||||
import { mixStaticPaths } from "../../astro/mixStaticPaths";
|
||||
import { game } from "../../game/game";
|
||||
import { getStaticPaths as _getStaticPaths } from "./_index";
|
||||
import { bufferProxy } from "../../api/bufferProxy";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||
return game!.textures.map((name) => ({ params: { name } }));
|
||||
});
|
||||
|
||||
export function GET({ params }: APIContext<never, { name: string }>) {
|
||||
const image = game!.texture(params.name);
|
||||
const array = new Uint8Array(image);
|
||||
return new Response(array);
|
||||
return bufferProxy(
|
||||
() => game!.texture(params.name),
|
||||
`texture-${params.name}`,
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"extends": ["../../tsconfig.json", "astro/tsconfigs/base"],
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@protos/*": ["../../packages/closed/protos/*"]
|
||||
}
|
||||
}
|
||||
"@protos/*": ["../../packages/closed/protos/*"],
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in new issue
Block a user