This commit is contained in:
tresabhi committed 2026-06-22 20:23:51 -05:00
1 parent 4e72ea567f
commit f41eeba25e
9 files changed
+150 -34

No files matched your search

+12 -8
View File
@@ -28,16 +28,18 @@ namespace BlitzKit.Game.JSExport;
public partial class GameInterface
{
private readonly BlitzFileProvider provider;
public HashSet<string> files;
public int textureChunks;
public GameInterface(string directory, string map, string temp)
public GameInterface(string directory, string map, string temp, int textureChunks)
{
provider = new(directory, map, temp);
files = [.. provider.Files.Keys];
this.textureChunks = textureChunks;
}
readonly Dictionary<string, string> texturePaths = new();
readonly Dictionary<string, (int, string)> texturePaths = [];
readonly string textureCache = "../../temp/textures.json";
public void DiscoverTextures(string[] tankTags)
@@ -47,7 +49,7 @@ public partial class GameInterface
Console.WriteLine("Found textures cache");
var content = File.ReadAllText(textureCache);
var cached = JsonSerializer.Deserialize<Dictionary<string, string>>(content);
var cached = JsonSerializer.Deserialize<Dictionary<string, (int, string)>>(content);
foreach (var (key, value) in cached)
{
@@ -110,9 +112,10 @@ public partial class GameInterface
if (MonoGltf.knownChannels.TryGetValue(parameterTexture.Key, out var channel))
{
var path = parameterTexture.Value.GetPathName();
var modulus = MonoGltf.TextureModulus(path, textureChunks);
var name = Path.GetFileNameWithoutExtension(path);
texturePaths[name] = path;
texturePaths[name] = (modulus, path);
}
}
}
@@ -132,11 +135,12 @@ public partial class GameInterface
Console.WriteLine("Saved textures cache");
}
public List<string> Textures => [.. texturePaths.Keys];
public List<(int, string)> Textures =>
[.. texturePaths.Select(texture => (texture.Value.Item1, texture.Key))];
public byte[] Texture(string name)
{
var path = texturePaths[name];
var (_, path) = texturePaths[name];
var texture = provider.LoadPackageObject<UTexture2D>(path);
var isRMAO = name.EndsWith("_RMAO");
var postProcess = isRMAO ? ImagePostProcess.RMAO : ImagePostProcess.None;
@@ -257,7 +261,7 @@ public partial class GameInterface
// var meshes = CollectMeshes(meshSettings);
// var gltf = new MonoGltf(meshes);
var gltf = new MonoGltf(meshSettings);
var gltf = new MonoGltf(meshSettings, textureChunks);
return gltf.Write($"{tag}/{part}");
}
@@ -1,4 +1,3 @@
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using CUE4Parse_Conversion.Textures;
using CUE4Parse.Compression;
+26 -4
View File
@@ -1,4 +1,6 @@
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using CUE4Parse_Conversion;
using CUE4Parse_Conversion.Materials;
using CUE4Parse_Conversion.Meshes;
@@ -44,9 +46,12 @@ public class MonoGltf
static readonly byte[] stubBytes = File.ReadAllBytes("../game/stub/small.png");
static readonly float scaleCorrection = 0.01f;
public MonoGltf(FStructFallback settings)
readonly int textureChunks;
public MonoGltf(FStructFallback settings, int textureChunks)
{
var root = new NodeBuilder("root");
this.textureChunks = textureChunks;
Traverse(settings, root);
scene.AddNode(root);
@@ -173,9 +178,7 @@ public class MonoGltf
{
if (knownChannels.TryGetValue(parameterTexture.Key, out var channels))
{
var texture = parameterTexture.Value;
var name = Path.GetFileNameWithoutExtension(texture.GetPathName());
var path = $"../../../textures/{name}.webp";
var path = TexturePath(parameterTexture.Value.GetPathName(), textureChunks);
var lastIndex = stubBytes.Length - 1;
stubBytes[lastIndex] = (byte)(++stubBytes[lastIndex] % 255);
@@ -214,6 +217,25 @@ public class MonoGltf
return meshBuilder;
}
public static int TextureModulus(string path, int textureChunks)
{
var name = Path.GetFileNameWithoutExtension(path);
var bytes = Encoding.UTF8.GetBytes(name);
var hash = SHA256.HashData(bytes);
var value = BitConverter.ToUInt32(hash, 0);
var modulus = value % textureChunks;
return (int)modulus;
}
public static string TexturePath(string path, int textureChunks)
{
var modulus = TextureModulus(path, textureChunks);
var name = Path.GetFileNameWithoutExtension(path);
return $"../../../textures-{modulus}/{name}.webp";
}
public byte[] Write(string name)
{
var model = scene.ToGltf2();
+2 -12
View File
@@ -3,22 +3,12 @@
"type": "module",
"private": true,
"scripts": {
"build:assets": "bun src/buildAssets/index.ts",
"build:averages": "bun src/averages.ts",
"setup:depotdownloader": "bun src/setupDepotDownloader.ts",
"setup:patches": "bun src/applyPatches.ts",
"build:reviews": "bun src/reviews.ts",
"build:ids": "bun src/discoverIds.ts",
"build:bot": "bun src/buildBot.ts",
"build:ratingleaderboard": "bun src/buildRatingLeaderboard.ts",
"build:proxyclient": "bun src/buildProxyClient.ts",
"build:catalogitemaccessor": "bun src/buildCatalogItemAccessor.ts",
"build:protos": "bun src/protos.ts",
"patchnotes": "bun src/patchNotes.ts"
"discover-servers": "bun src/discoverServers.ts"
},
"dependencies": {
"@blitzkit/closed": "workspace:*",
"@blitzkit/core": "workspace:*",
"@blitzkit/game": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@gltf-transform/core": "^4.2.1",
"@gltf-transform/extensions": "^4.2.1",
+92
View File
@@ -0,0 +1,92 @@
import { GameInterface } from "@blitzkit/game";
const urls = [
//
];
interface Bindings {
bindings: Binding[];
forbidden: string[];
}
interface Binding {
name: string;
versions: string[];
discovery: string;
env: string;
show_server_selection: boolean;
}
interface Discovery {
version: "1";
clusters: string[];
default_server: string;
servers: Record<string, Server>;
icmp_servers: Record<string, ICMPServer>;
clusters_versions: Record<string, ClusterVersion[]>;
countries_by_clusters: Record<string, Countries>;
extensions: Record<string, Extension>;
}
interface ClusterVersion {
version: string;
server: string;
}
interface Countries {
countries: string[];
}
interface Extension {
playability_config_url: string;
fullscreen_notifications_url: string;
mgg_frontier_url: string;
mgg_pay_url: string;
}
type ICMPServer = Record<string, string[]>;
interface Server {
name: string;
addr: string;
addr_dsapp?: string;
}
const game = new GameInterface();
urls.forEach(async (url) => {
const bindings = await fetch(url).then(
(response) => response.json() as Promise<Bindings>,
);
bindings.bindings.forEach(async (binding) => {
const discovery = await fetch(binding.discovery).then(
(response) => response.json() as Promise<Discovery>,
);
if (discovery.version !== "1") {
throw new Error(`Unsupported discovery version: ${discovery.version}`);
}
Object.values(discovery.servers).forEach(async (server) => {
const url = server.addr
.replace("wss://", "https://")
.replace(/:\d+$/, "");
const response = await fetch(url).catch(() => null);
if (response === null || response.status !== 426) return;
let message = "";
message += `${server.name}:\n`;
message += ` address: ${server.addr}\n`;
message += ` versions:\n`;
for (const version of binding.versions) {
message += ` - ${version}\n`;
}
console.log(message);
});
});
});
+1
View File
@@ -13,6 +13,7 @@ if (!clientUnmounted && import.meta.env.SSR) {
assertSecret(import.meta.env.PUBLIC_WOTB_CLIENT),
assertSecret(import.meta.env.WOTB_USMAP),
"../../temp",
Number(assertSecret(import.meta.env.TEXTURE_CHUNKS)),
);
const tankTags: string[] = [];