From bc0004574a23a34b876a39c0f5b458ab5f105f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 26 Apr 2026 18:02:45 -0500 Subject: [PATCH] feat: nation flags --- packages/closed | 2 +- packages/game/JSExport/GameInterface.cs | 51 +++++++++++++++++-- .../src/components/TankCard/index.tsx | 2 +- .../src/pages/api/nations/[id].webp.ts | 20 ++++++++ 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 packages/website-ue/src/pages/api/nations/[id].webp.ts diff --git a/packages/closed b/packages/closed index 660413e95..52a584736 160000 --- a/packages/closed +++ b/packages/closed @@ -1 +1 @@ -Subproject commit 660413e955b6e875802351b11eb5512025e3693a +Subproject commit 52a58473683121e3d5d70171f0658f23313bcfd3 diff --git a/packages/game/JSExport/GameInterface.cs b/packages/game/JSExport/GameInterface.cs index 3d958b8b8..1b62496c8 100644 --- a/packages/game/JSExport/GameInterface.cs +++ b/packages/game/JSExport/GameInterface.cs @@ -1,4 +1,6 @@ -using BlitzKit.Game.Models; +using System.IO; +using System.Text.RegularExpressions; +using BlitzKit.Game.Models; using CUE4Parse_Conversion.Textures; using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Objects.Engine; @@ -9,7 +11,7 @@ using SkiaSharp; namespace BlitzKit.Game.JSExport; [JSExport] -public class GameInterface +public partial class GameInterface { private readonly BlitzFileProvider provider; @@ -51,7 +53,7 @@ public class GameInterface if (cTexture is null) { - continue; + return []; } SKBitmap bitmap = cTexture.ToSkBitmap(); @@ -60,10 +62,51 @@ public class GameInterface return bytes; } - else + } + + return []; + } + + [GeneratedRegex(@"T_UI_Flag_(\w+)_S")] + private static partial Regex FlagNameRegex(); + + public byte[] Flag(string nation) + { + var flagsBase = "Blitz/Content/UI/Textures/Flag/TankCard/"; + + foreach (var path in provider.Files.Keys) + { + if (!path.StartsWith(flagsBase)) { continue; } + + var fileName = Path.GetFileNameWithoutExtension(path); + var match = FlagNameRegex().Match(fileName); + + if ( + match.Success + && match.Groups[1].Value.Equals(nation, StringComparison.CurrentCultureIgnoreCase) + ) + { + if (provider.TryLoadPackageObject($"{path}.{fileName}", out var uTexture)) + { + CTexture? cTexture = uTexture.Decode(ETexturePlatform.DesktopMobile); + + if (cTexture is null) + { + return []; + } + + SKBitmap bitmap = cTexture.ToSkBitmap(); + SKData data = bitmap.Encode(SKEncodedImageFormat.Webp, 80); + byte[] bytes = data.ToArray(); + + return bytes; + } + + return []; + } } return []; diff --git a/packages/website-ue/src/components/TankCard/index.tsx b/packages/website-ue/src/components/TankCard/index.tsx index 19b8563e3..784f8bcc5 100644 --- a/packages/website-ue/src/components/TankCard/index.tsx +++ b/packages/website-ue/src/components/TankCard/index.tsx @@ -23,7 +23,7 @@ export function TankCard({ id }: PopularTank) {
diff --git a/packages/website-ue/src/pages/api/nations/[id].webp.ts b/packages/website-ue/src/pages/api/nations/[id].webp.ts new file mode 100644 index 000000000..870c3c2b7 --- /dev/null +++ b/packages/website-ue/src/pages/api/nations/[id].webp.ts @@ -0,0 +1,20 @@ +import { Nation } from "@protos/game/proto/legacy/blitz_static_tank_component"; +import type { APIContext, GetStaticPaths } from "astro"; +import { game } from "../../../core/game/game"; + +export const getStaticPaths = (async () => { + return Object.values(Nation) + .filter(Number.isInteger) + .map((id) => ({ params: { id } })); +}) satisfies GetStaticPaths; + +/** + * Even Noah can't save these animals. + */ +export async function GET({ params }: APIContext) { + const enumName = Nation[Number(params.id)]; + const nationName = enumName.replace("NATION_", "").toLowerCase(); + const flag = game.flag(nationName); + + return new Response(new Uint8Array(flag)); +}