Files
blitzkit/src/CLI/Functions/Unpacker.cs
T

149 lines
4.2 KiB
C#
Raw Normal View History

2025-01-25 23:51:18 -06:00
using System.Text.Json;
using CLI.Models;
2025-01-25 22:44:50 -06:00
using CLI.Utils;
2025-01-25 22:17:41 -06:00
using CUE4Parse.FileProvider.Objects;
using CUE4Parse.UE4.Pak;
2025-01-25 23:59:10 -06:00
using CUE4Parse.UE4.Readers;
2025-01-25 22:17:41 -06:00
2025-01-23 21:43:54 -06:00
namespace CLI.Functions
{
2025-01-25 23:51:18 -06:00
public static class Unpacker
2025-01-23 21:43:54 -06:00
{
2025-01-25 23:51:18 -06:00
private const string CONTENT_GROUP = "p14y73c7_p5e_b10gg3RS_big_play";
private const string VFS_PATH = "../../temp/vfs/";
2025-01-25 22:44:50 -06:00
// this may be different from the one provided in args so check this and not args[1]
// we don't wanna delete my local installation of the game when debugging haha!
2025-01-25 23:51:18 -06:00
private const string TEMP_DEPOT_DIR = "../../temp/depot/";
private const string WG_DLC_DOMAIN = "http://dl-wotblitz-gc.wargaming.net";
private const string BUILD_MANIFEST_OS = "Windows";
2025-01-25 22:17:41 -06:00
2025-01-25 23:51:18 -06:00
public static async Task Unpack(string[] args)
2025-01-23 21:43:54 -06:00
{
2025-01-25 21:42:25 -06:00
if (args.Length < 2)
{
2025-01-25 22:17:41 -06:00
throw new ArgumentException("Missing required initial paks directory");
2025-01-25 21:42:25 -06:00
}
2025-01-25 13:49:28 -06:00
2025-01-25 22:44:50 -06:00
AgnosticZlibHelper.Initialize();
2025-01-25 22:17:41 -06:00
2025-01-25 23:27:39 -06:00
UnpackDepot(args[1]);
2025-01-25 23:51:18 -06:00
await UnpackDLC();
2025-01-25 23:27:39 -06:00
}
2025-01-25 23:51:18 -06:00
private static async Task UnpackDLC()
2025-01-25 23:27:39 -06:00
{
2025-01-25 23:51:18 -06:00
string defaultDlcPath = Path.Combine(VFS_PATH, "Blitz/Config/DefaultDlc.ini");
2025-01-25 23:27:39 -06:00
IniParser iniParser = new(defaultDlcPath);
string? contentBuildId = iniParser.GetString("DefaultContentBuildId");
if (string.IsNullOrEmpty(contentBuildId))
{
throw new Exception("Failed to read content build id from DefaultDlc.ini");
}
2025-01-25 23:51:18 -06:00
Console.WriteLine($"Exploring DLC {contentBuildId} within group {CONTENT_GROUP}");
using HttpClient httpClient = new();
DlcManifest manifest = await FetchManifest(CONTENT_GROUP, contentBuildId);
foreach (var pakFile in manifest.PakFiles)
{
Console.WriteLine($"{pakFile.FileName} downloading exergy...");
string url = $"{WG_DLC_DOMAIN}/dlc/{CONTENT_GROUP}/dlc/{pakFile.RelativeUrl}";
2025-01-25 23:59:10 -06:00
// load to stream
Stream stream = await httpClient.GetStreamAsync(url);
FStreamArchive archive = new(url, stream);
PakFileReader reader = new(archive);
reader.Mount();
foreach (var file in reader.Files)
{
var gameFile = file.Value;
Console.WriteLine(gameFile.Path);
}
break;
2025-01-25 23:51:18 -06:00
}
}
public static async Task<DlcManifest> FetchManifest(string group, string build)
{
string url =
$"{WG_DLC_DOMAIN}/dlc/{group}/dlc/BuildManifest-{BUILD_MANIFEST_OS}-{build}.json";
using HttpClient client = new();
string jsonString = await client.GetStringAsync(url);
DlcManifest manifest =
JsonSerializer.Deserialize<DlcManifest>(jsonString)
?? throw new Exception("Failed to deserialize manifest");
return manifest;
2025-01-25 23:27:39 -06:00
}
private static void UnpackDepot(string workingDirectory)
{
2025-01-25 21:42:25 -06:00
string paksDirectory = Path.Combine(workingDirectory, "Blitz/Content/Paks");
2025-01-25 22:17:41 -06:00
string[] containers = Directory.GetFiles(paksDirectory, "*.pak");
2025-01-25 21:42:25 -06:00
2025-01-25 22:17:41 -06:00
foreach (string container in containers)
2025-01-25 21:42:25 -06:00
{
2025-01-25 22:17:41 -06:00
Exergy(container);
2025-01-25 21:42:25 -06:00
}
2025-01-25 22:44:50 -06:00
2025-01-25 23:51:18 -06:00
if (Directory.Exists(TEMP_DEPOT_DIR))
2025-01-25 22:44:50 -06:00
{
Console.WriteLine("Deleting temp depots directory...");
2025-01-25 23:51:18 -06:00
Directory.Delete(TEMP_DEPOT_DIR, true);
2025-01-25 22:44:50 -06:00
}
2025-01-25 22:17:41 -06:00
}
2025-01-25 21:42:25 -06:00
2025-01-25 23:27:39 -06:00
private static void Exergy(string container)
2025-01-25 22:17:41 -06:00
{
Console.WriteLine($"Filtering {container}");
2025-01-25 21:42:25 -06:00
2025-01-25 22:17:41 -06:00
PakFileReader reader = new(container);
2025-01-25 13:49:28 -06:00
2025-01-25 22:17:41 -06:00
reader.Mount();
2025-01-23 21:43:54 -06:00
2025-01-25 22:17:41 -06:00
foreach (var file in reader.Files)
{
GameFile gameFile = file.Value;
bool exergizable = ShouldExergize(gameFile.Path);
if (!exergizable)
{
continue;
}
2025-01-25 23:51:18 -06:00
string writePath = Path.Combine(VFS_PATH, gameFile.Path);
2025-01-25 22:17:41 -06:00
if (File.Exists(writePath))
{
Console.WriteLine($"{gameFile.Path} already exists; skipping...");
continue;
}
Console.WriteLine($"{gameFile.Path} writing from vfs...");
string? directory = Path.GetDirectoryName(writePath);
if (directory != null && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllBytes(writePath, gameFile.Read());
}
}
2025-01-25 23:27:39 -06:00
private static string[] ExergizableFiles = ["Blitz/Config/DefaultDlc.ini"];
2025-01-25 22:17:41 -06:00
2025-01-25 23:27:39 -06:00
private static bool ShouldExergize(string path)
2025-01-25 22:17:41 -06:00
{
return ExergizableFiles.Contains(path);
2025-01-23 21:43:54 -06:00
}
}
}