Skip to content

Commit

Permalink
Merge branch 'dev' into tmunlimiter
Browse files Browse the repository at this point in the history
  • Loading branch information
BigBang1112 committed Dec 31, 2024
2 parents 9a4362e + a7a5592 commit 09734ba
Show file tree
Hide file tree
Showing 12 changed files with 331 additions and 67 deletions.
14 changes: 14 additions & 0 deletions GBX.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PakToZip", "Tools\PakToZip\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtractPakFileHashes", "Tools\ExtractPakFileHashes\ExtractPakFileHashes.csproj", "{B3C5D493-3172-4780-95EC-CBEE73BE4850}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PakToFolder", "Tools\PakToFolder\PakToFolder.csproj", "{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjExporter", "Tools\ObjExporter\ObjExporter.csproj", "{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -424,6 +428,14 @@ Global
{B3C5D493-3172-4780-95EC-CBEE73BE4850}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3C5D493-3172-4780-95EC-CBEE73BE4850}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3C5D493-3172-4780-95EC-CBEE73BE4850}.Release|Any CPU.Build.0 = Release|Any CPU
{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559}.Release|Any CPU.Build.0 = Release|Any CPU
{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -495,6 +507,8 @@ Global
{55BD1330-7431-41A8-90EB-DEB20D9EB981} = {80DCE6B7-4BD9-415C-B053-92B059D7C938}
{47A58E42-EBBC-48D0-B4B1-C25DFD074506} = {F3336145-FDA9-4517-AEDC-7F4C4D526ECB}
{B3C5D493-3172-4780-95EC-CBEE73BE4850} = {F3336145-FDA9-4517-AEDC-7F4C4D526ECB}
{8BCA7A11-5A5E-4B9F-AC1A-384D46C68559} = {F3336145-FDA9-4517-AEDC-7F4C4D526ECB}
{57CF1E52-A9C7-4C6E-9B16-AB0F8D904AFB} = {F3336145-FDA9-4517-AEDC-7F4C4D526ECB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8EA2F0DE-BA72-486D-AB3A-9320C0CE5CFD}
Expand Down
3 changes: 2 additions & 1 deletion Src/GBX.NET.PAK/Pak.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,12 @@ public async ValueTask DisposeAsync()
/// <returns>Dictionary where the key is the hash (file name) and value is the true resolved file name.</returns>
public static async Task<Dictionary<string, string>> BruteforceFileHashesAsync(
string directoryPath,
PakListGame game = PakListGame.TM,
IProgress<KeyValuePair<string, string>>? progress = null,
bool onlyUsedHashes = true,
CancellationToken cancellationToken = default)
{
var pakList = await PakList.ParseAsync(Path.Combine(directoryPath, PakListFileName), cancellationToken);
var pakList = await PakList.ParseAsync(Path.Combine(directoryPath, PakListFileName), game, cancellationToken);

var allPossibleFileHashes = new Dictionary<string, string>();

Expand Down
52 changes: 42 additions & 10 deletions Src/GBX.NET.PAK/PakList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ public sealed partial class PakList : IReadOnlyDictionary<string, PakListItem>
{
private readonly IReadOnlyDictionary<string, PakListItem> packs;

private const string NameKeySalt = "6611992868945B0B59536FC3226F3FD0";
private const string KeyStringKeySalt = "B97C1205648A66E04F86A1B5D5AF9862";
private const string NameKeySaltTM = "6611992868945B0B59536FC3226F3FD0";
private const string NameKeySaltVsk5 = "33751203003810C43D169A5B608FC820";

private const string KeyStringKeySaltTM = "B97C1205648A66E04F86A1B5D5AF9862";
private const string KeyStringKeySaltVsk5 = "5A8BFF30451E627EAB838DADFB120FB6";

public byte Version { get; init; }
public uint CRC32 { get; init; }
Expand All @@ -39,7 +42,7 @@ public PakList(byte version, uint crc32, uint salt, byte[] signature, IReadOnlyD
}

[Zomp.SyncMethodGenerator.CreateSyncVersion]
public static async Task<PakList> ParseAsync(Stream stream, CancellationToken cancellationToken = default)
public static async Task<PakList> ParseAsync(Stream stream, string nameKeySalt, string keyStringKeySalt, CancellationToken cancellationToken = default)
{
using var r = new GbxReader(stream);

Expand All @@ -48,9 +51,9 @@ public static async Task<PakList> ParseAsync(Stream stream, CancellationToken ca
var crc32 = r.ReadUInt32();
var salt = r.ReadUInt32();

var nameKey = await MD5.ComputeAsync(NameKeySalt + salt, cancellationToken);
var nameKey = await MD5.ComputeAsync(nameKeySalt + salt, cancellationToken);

var packs = new Dictionary<string, PakListItem>(numPacks);
var packs = new Dictionary<string, PakListItem>(numPacks, StringComparer.OrdinalIgnoreCase);

for (var i = 0; i < numPacks; i++)
{
Expand All @@ -66,7 +69,7 @@ public static async Task<PakList> ParseAsync(Stream stream, CancellationToken ca

var name = Encoding.ASCII.GetString(encryptedName);

var keyStringKey = await MD5.ComputeAsync(name + salt + KeyStringKeySalt, cancellationToken);
var keyStringKey = await MD5.ComputeAsync(name + salt + keyStringKeySalt, cancellationToken);

for (var j = 0; j < encryptedKeyString.Length; j++)
{
Expand All @@ -83,19 +86,48 @@ public static async Task<PakList> ParseAsync(Stream stream, CancellationToken ca
return new PakList(version, crc32, salt, signature, packs);
}

public static async Task<PakList> ParseAsync(string filePath, CancellationToken cancellationToken = default)
public static async Task<PakList> ParseAsync(string filePath, string nameKeySalt, string keyStringKeySalt, CancellationToken cancellationToken = default)
{
#if !NETSTANDARD2_0
await
#endif
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true);
return await ParseAsync(fs, nameKeySalt, keyStringKeySalt, cancellationToken);
}

public static PakList Parse(string filePath, string nameKeySalt, string keyStringKeySalt)
{
using var fs = File.OpenRead(filePath);
return Parse(fs, nameKeySalt, keyStringKeySalt);
}

[Zomp.SyncMethodGenerator.CreateSyncVersion]
public static async Task<PakList> ParseAsync(Stream stream, PakListGame game = PakListGame.TM, CancellationToken cancellationToken = default)
{
switch (game)
{
case PakListGame.TM:
return await ParseAsync(stream, NameKeySaltTM, KeyStringKeySaltTM, cancellationToken);
case PakListGame.Vsk5:
return await ParseAsync(stream, NameKeySaltVsk5, KeyStringKeySaltVsk5, cancellationToken);
default:
throw new ArgumentOutOfRangeException(nameof(game));
}
}

public static async Task<PakList> ParseAsync(string filePath, PakListGame game = PakListGame.TM, CancellationToken cancellationToken = default)
{
#if !NETSTANDARD2_0
await
#endif
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true);
return await ParseAsync(fs, cancellationToken);
return await ParseAsync(fs, game, cancellationToken);
}

public static PakList Parse(string filePath)
public static PakList Parse(string filePath, PakListGame game = PakListGame.TM)
{
using var fs = File.OpenRead(filePath);
return Parse(fs);
return Parse(fs, game);
}

public bool ContainsKey(string key)
Expand Down
10 changes: 10 additions & 0 deletions Src/GBX.NET.PAK/PakListGame.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace GBX.NET.PAK;

public enum PakListGame
{
/// <summary>
/// TMF paks, also works for TMU paks.
/// </summary>
TM,
Vsk5
}
2 changes: 1 addition & 1 deletion Src/GBX.NET/Engines/Plug/CPlugVehicleCarPhyTuning.chunkl
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ CPlugVehicleCarPhyTuning 0x090ED000
int TurboDuration

0x030
CFuncKeysReal SteerDriveTorque
CFuncKeysReal SteerDriveTorque // encryption trick here

0x031
float LimitToMaxSpeedForce
Expand Down
45 changes: 28 additions & 17 deletions Src/GBX.NET/Engines/Plug/CPlugVisual3D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,37 +115,45 @@ private static void WriteTangents(GbxWriter w, int tangentsCount, byte[]? tangen
}
}

public readonly record struct Vertex(Vec3 Position, Vec3? Normal, Vec3? U02, float? U03, int? U04, Vec3? U05, int? U06, Vec4? U07, float? U08, int? U09)
public readonly record struct Vertex(Vec3 Position, Vec3? Normal, Vec3? U02, float? U03, Vec4? Color, float? U08, int? U09)
{
public static Vertex Read(GbxReader r, bool u01, bool u02, bool u03, bool u04, bool isSprite)
{
var pos = r.ReadVec3();
var vertU01 = default(int?);
var vertU02 = default(Vec3?);
var vertU03 = default(int?);
var vertU04 = default(Vec4?);
var normal = default(Vec3?);
var color = default(Vec4?);

if (u01)
{
if (u03)
{
vertU01 = r.ReadInt32();
var normalInt = r.ReadInt32();
normal = new Vec3(
((normalInt << 22) >> 22) / 511f,
((normalInt << 12) >> 22) / 511f,
((normalInt * 4) >> 22) / 511f);
}
else
{
vertU02 = r.ReadVec3();
normal = r.ReadVec3();
}
}

if (u02)
{
if (u04)
{
vertU03 = r.ReadInt32();
var colorInt = r.ReadInt32();
color = new Vec4(
(colorInt >> 0x10 & 0xFF) / 255f,
(colorInt >> 8 & 0xFF) / 255f,
(colorInt & 0xFF) / 255f,
(colorInt >> 0x18 & 0xFF) / 255f
);
}
else
{
vertU04 = r.ReadVec4();
color = r.ReadVec4();
}
}

Expand All @@ -161,10 +169,8 @@ public static Vertex Read(GbxReader r, bool u01, bool u02, bool u03, bool u04, b
return new Vertex
{
Position = pos,
U04 = vertU01,
U05 = vertU02,
U06 = vertU03,
U07 = vertU04,
Normal = normal,
Color = color,
U08 = vertU05,
U09 = vertU06,
};
Expand All @@ -178,23 +184,28 @@ public void Write(GbxWriter w, bool u01, bool u02, bool u03, bool u04, bool isSp
{
if (u03)
{
w.Write(U04.GetValueOrDefault());
w.Write((int)(Normal.GetValueOrDefault().X * 511) << 22
| (int)(Normal.GetValueOrDefault().Y * 511) << 12
| (int)(Normal.GetValueOrDefault().Z * 511));
}
else
{
w.Write(U05.GetValueOrDefault());
w.Write(Normal.GetValueOrDefault());
}
}

if (u02)
{
if (u04)
{
w.Write(U06.GetValueOrDefault());
w.Write((int)(Color.GetValueOrDefault().X * 255) << 0x10
| (int)(Color.GetValueOrDefault().Y * 255) << 8
| (int)(Color.GetValueOrDefault().Z * 255)
| (int)(Color.GetValueOrDefault().W * 255) << 0x18);
}
else
{
w.Write(U07.GetValueOrDefault());
w.Write(Color.GetValueOrDefault());
}
}

Expand Down
Loading

0 comments on commit 09734ba

Please sign in to comment.