mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
consumable icons
This commit is contained in:
1 parent
f58d06b3c3
commit
0cb4aadec3
6 files changed
+96
-19
No files matched your search
+3
-1
@@ -2,6 +2,8 @@
|
|||||||
"words": [
|
"words": [
|
||||||
"gltf",
|
"gltf",
|
||||||
"amogos",
|
"amogos",
|
||||||
"Tankopedia"
|
"Tankopedia",
|
||||||
|
"uasset",
|
||||||
|
"oodle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,10 @@ using CUE4Parse.UE4.Objects.UObject;
|
|||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.JavaScript.NodeApi;
|
using Microsoft.JavaScript.NodeApi;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
using CUE4Parse.UE4.AssetRegistry.Objects;
|
||||||
|
using CUE4Parse.UE4.Readers;
|
||||||
|
using CUE4Parse.UE4.AssetRegistry.Readers;
|
||||||
|
using CUE4Parse.UE4.AssetRegistry;
|
||||||
|
|
||||||
namespace BlitzKit.Game.JSExport;
|
namespace BlitzKit.Game.JSExport;
|
||||||
|
|
||||||
@@ -24,7 +28,7 @@ public partial class GameInterface
|
|||||||
|
|
||||||
public GameInterface(string directory, string map, string temp)
|
public GameInterface(string directory, string map, string temp)
|
||||||
{
|
{
|
||||||
provider = new(directory, map);
|
provider = new(directory, map, temp);
|
||||||
|
|
||||||
files = [.. provider.Files.Keys];
|
files = [.. provider.Files.Keys];
|
||||||
|
|
||||||
@@ -38,10 +42,6 @@ public partial class GameInterface
|
|||||||
.Where(nation => !nation.EndsWith(".uasset") && nation != "TankStub")
|
.Where(nation => !nation.EndsWith(".uasset") && nation != "TankStub")
|
||||||
.Distinct(),
|
.Distinct(),
|
||||||
];
|
];
|
||||||
|
|
||||||
string oodlePath = $"{temp}/oodle.so";
|
|
||||||
OodleHelper.DownloadOodleDll(ref oodlePath!);
|
|
||||||
OodleHelper.Initialize(oodlePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSet<string> Files => files;
|
public HashSet<string> Files => files;
|
||||||
@@ -123,6 +123,13 @@ public partial class GameInterface
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] ConsumableIcon(string tag)
|
||||||
|
{
|
||||||
|
var pda = provider.Discovered<UPrimaryDataAsset>(tag);
|
||||||
|
var icon = pda.Get<FSoftObjectPath>("Icon");
|
||||||
|
return provider.Image(icon);
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly string equipmentPDAPrefix =
|
private static readonly string equipmentPDAPrefix =
|
||||||
"Blitz/Content/TanksStuff/Equipment/PDA_Equipment";
|
"Blitz/Content/TanksStuff/Equipment/PDA_Equipment";
|
||||||
private static readonly string equipmentPDASuffix = ".uasset";
|
private static readonly string equipmentPDASuffix = ".uasset";
|
||||||
|
|||||||
@@ -10,12 +10,21 @@ using CUE4Parse.UE4.Objects.UObject;
|
|||||||
using CUE4Parse.UE4.Versions;
|
using CUE4Parse.UE4.Versions;
|
||||||
using CUE4Parse.Utils;
|
using CUE4Parse.Utils;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
using CUE4Parse.UE4.Readers;
|
||||||
|
using CUE4Parse.UE4.AssetRegistry;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using CUE4Parse.UE4.Assets.Exports;
|
||||||
|
|
||||||
namespace BlitzKit.Game.Models;
|
namespace BlitzKit.Game.Models;
|
||||||
|
|
||||||
public class BlitzFileProvider : DefaultFileProvider
|
public partial class BlitzFileProvider : DefaultFileProvider
|
||||||
{
|
{
|
||||||
public BlitzFileProvider(string directory, string map)
|
[GeneratedRegex(@"\(GameplayTags=\(\(TagName=""(.+)""\)\)\)")]
|
||||||
|
private static partial Regex GameplayTagsRegex();
|
||||||
|
|
||||||
|
private readonly Dictionary<string, string> discovered = [];
|
||||||
|
|
||||||
|
public BlitzFileProvider(string directory, string map, string temp)
|
||||||
: base(
|
: base(
|
||||||
directory: directory,
|
directory: directory,
|
||||||
searchOption: SearchOption.AllDirectories,
|
searchOption: SearchOption.AllDirectories,
|
||||||
@@ -27,6 +36,38 @@ public class BlitzFileProvider : DefaultFileProvider
|
|||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
Mount();
|
Mount();
|
||||||
|
|
||||||
|
string oodlePath = $"{temp}/oodle.so";
|
||||||
|
OodleHelper.DownloadOodleDll(ref oodlePath!);
|
||||||
|
OodleHelper.Initialize(oodlePath);
|
||||||
|
|
||||||
|
if (TryGetGameFile("Blitz/AssetRegistry.bin", out var file))
|
||||||
|
{
|
||||||
|
var bytes = file.Read();
|
||||||
|
var archive = new FByteArchive(file.Path, bytes, Versions);
|
||||||
|
var state = new FAssetRegistryState(archive);
|
||||||
|
|
||||||
|
foreach (var asset in state.PreallocatedAssetDataBuffers)
|
||||||
|
{
|
||||||
|
if (asset.TagsAndValues.TryGetValue("DiscoveryTags", out var tags))
|
||||||
|
{
|
||||||
|
var match = GameplayTagsRegex().Match(tags);
|
||||||
|
|
||||||
|
if (!match.Success)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tag = match.Groups[1].Value;
|
||||||
|
discovered[tag] = asset.ObjectPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Discovered<T>(string path) where T : UObject
|
||||||
|
{
|
||||||
|
return LoadPackageObject<T>(discovered[path]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UPrimaryDataAsset PDA(string path)
|
public UPrimaryDataAsset PDA(string path)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import type { BlitzStaticAssetsDiscoveryComponent } from "@protos/blitz_static_assets_discovery_component";
|
||||||
|
|
||||||
|
export function assertDiscoveryTag(discovery: BlitzStaticAssetsDiscoveryComponent) {
|
||||||
|
if (
|
||||||
|
discovery.blocked_tags !== undefined ||
|
||||||
|
discovery.required_tags === undefined ||
|
||||||
|
discovery.required_tags.tags.length !== 1
|
||||||
|
) {
|
||||||
|
throw new TypeError("Unexpected discovery tag format");
|
||||||
|
}
|
||||||
|
|
||||||
|
return discovery.required_tags.tags[0].value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import type { APIContext } from "astro";
|
||||||
|
import { api } from "../../../api/dynamic";
|
||||||
|
import { mixStaticPaths } from "../../../astro/mixStaticPaths";
|
||||||
|
import { game } from "../../../game/game";
|
||||||
|
import { getStaticPaths as _getStaticPaths } from "../_index";
|
||||||
|
import { assertDiscoveryTag } from "../../../game/assertDiscoveryTag";
|
||||||
|
|
||||||
|
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||||
|
return api.metadata
|
||||||
|
.group("ConsumableEntity")
|
||||||
|
.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);
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import { notFoundResponse } from "../../../api/responses";
|
|||||||
import { mixStaticPaths } from "../../../astro/mixStaticPaths";
|
import { mixStaticPaths } from "../../../astro/mixStaticPaths";
|
||||||
import { game } from "../../../game/game";
|
import { game } from "../../../game/game";
|
||||||
import { getStaticPaths as _getStaticPaths } from "../_index";
|
import { getStaticPaths as _getStaticPaths } from "../_index";
|
||||||
|
import { assetsDiscovery } from "../../../game/assetsDiscovery";
|
||||||
|
|
||||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||||
return api.metadata
|
return api.metadata
|
||||||
@@ -17,17 +18,7 @@ const HACK_nameMap: Record<string, string> = {
|
|||||||
|
|
||||||
export function GET({ params }: APIContext<never, { id: string }>) {
|
export function GET({ params }: APIContext<never, { id: string }>) {
|
||||||
const item = api.metadata.item(params.id);
|
const item = api.metadata.item(params.id);
|
||||||
const assetDiscovery = item.BlitzStaticAssetsDiscovery();
|
const names = assetsDiscovery(item, HACK_nameMap);
|
||||||
const names = assetDiscovery.required_tags!.tags.map(
|
|
||||||
(tag) => tag.value.split(".").at(-1)!,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const name of names) {
|
|
||||||
if (name in HACK_nameMap) {
|
|
||||||
names.push(HACK_nameMap[name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const icon = game!.equipmentIcon(names);
|
const icon = game!.equipmentIcon(names);
|
||||||
|
|
||||||
if (icon.length === 0) {
|
if (icon.length === 0) {
|
||||||
|
|||||||
Reference in new issue
Block a user