Skip to content

Commit dab6610

Browse files
committed
First rough stab at WoW-specific TVFS support
1 parent 2b39878 commit dab6610

6 files changed

Lines changed: 527 additions & 20 deletions

File tree

TACTSharp/Build.cs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Text.Json;
22
using System.Text.Json.Nodes;
3+
using TACTSharp.Interfaces;
34

45
namespace TACTSharp
56
{
@@ -10,7 +11,7 @@ public class BuildInstance
1011
public string? ProductConfig { get; private set; }
1112

1213
public EncodingInstance? Encoding { get; private set; }
13-
public RootInstance? Root { get; private set; }
14+
public IRootInstance? Root { get; private set; }
1415
public InstallInstance? Install { get; private set; }
1516
public IndexInstance? GroupIndex { get; private set; }
1617
public IndexInstance? FileIndex { get; private set; }
@@ -189,17 +190,64 @@ public void Load()
189190
}
190191

191192
timer.Restart();
192-
if (!BuildConfig.Values.TryGetValue("root", out var rootKey))
193-
throw new Exception("No root key found in build config");
194193

195-
var rootEncodingKeys = Encoding.FindContentKey(Convert.FromHexString(rootKey[0]));
196-
if (!rootEncodingKeys)
197-
throw new Exception("Root key not found in encoding");
194+
var useTVFS = Settings.ManifestType == AssetManifestType.TVFS;
195+
if (!BuildConfig.Values.TryGetValue("root", out var rootKey) || rootKey[0] == "00000000000000000000000000000000")
196+
{
197+
if (Settings.LogLevel <= TSLogLevel.Info)
198+
Console.WriteLine("No root key found in build config, falling back to TVFS.");
199+
200+
useTVFS = true;
201+
}
202+
203+
if (!useTVFS)
204+
{
205+
var rootEncodingKeys = Encoding.FindContentKey(Convert.FromHexString(rootKey[0]));
206+
if (!rootEncodingKeys)
207+
throw new Exception("Root key not found in encoding");
208+
209+
Root = new RootInstance(cdn.GetDecodedFilePath("data", Convert.ToHexStringLower(rootEncodingKeys[0]), 0, rootEncodingKeys.DecodedFileSize), Settings);
210+
211+
if (Settings.LogLevel <= TSLogLevel.Info)
212+
Console.WriteLine("Root loaded in " + Math.Ceiling(timer.Elapsed.TotalMilliseconds) + "ms");
213+
}
214+
else
215+
{
216+
var vfsKeys = new Dictionary<uint, (string cKey, string eKey)>();
217+
var vfsSizes = new Dictionary<uint, (uint decodedSize, uint encodedSize)>();
218+
219+
foreach (var bcKey in BuildConfig.Values)
220+
{
221+
if (bcKey.Key.StartsWith("vfs") && !bcKey.Key.StartsWith("vfs-root")) // vfs-1 always seems to be the same as vfs-root
222+
{
223+
if (bcKey.Key.EndsWith("-size"))
224+
{
225+
if (uint.TryParse(bcKey.Key.Replace("-size", "").Replace("vfs-", ""), out var vfsIndex))
226+
vfsSizes.Add(vfsIndex, (uint.Parse(bcKey.Value[0]), uint.Parse(bcKey.Value[1])));
227+
else
228+
if (Settings.LogLevel <= TSLogLevel.Warn)
229+
Console.WriteLine("Warning: Failed to parse buildconfig VFS size " + bcKey.Key + ", skipping..");
230+
}
231+
else
232+
{
233+
if (uint.TryParse(bcKey.Key.Replace("vfs-", ""), out var vfsIndex))
234+
vfsKeys.Add(vfsIndex, (bcKey.Value[0], bcKey.Value[1]));
235+
else
236+
if (Settings.LogLevel <= TSLogLevel.Warn)
237+
Console.WriteLine("Warning: Failed to parse buildconfig VFS key " + bcKey.Key + ", skipping..");
238+
}
239+
}
240+
}
241+
242+
// TODO: Not great to feed all this stuff into it
243+
Root = new TVFSInstance(vfsKeys, vfsSizes, CDNConfig, GroupIndex, FileIndex, cdn, Settings);
198244

199-
Root = new RootInstance(cdn.GetDecodedFilePath("data", Convert.ToHexStringLower(rootEncodingKeys[0]), 0, rootEncodingKeys.DecodedFileSize), Settings);
245+
if (Settings.LogLevel <= TSLogLevel.Info)
246+
Console.WriteLine("TVFS loaded in " + Math.Ceiling(timer.Elapsed.TotalMilliseconds) + "ms");
247+
}
248+
200249
timer.Stop();
201-
if (Settings.LogLevel <= TSLogLevel.Info)
202-
Console.WriteLine("Root loaded in " + Math.Ceiling(timer.Elapsed.TotalMilliseconds) + "ms");
250+
203251

204252
timer.Restart();
205253
if (!BuildConfig.Values.TryGetValue("install", out var installKey))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using static TACTSharp.RootInstance;
2+
3+
namespace TACTSharp.Interfaces
4+
{
5+
public interface IRootInstance
6+
{
7+
public List<RootEntry> GetEntriesByFDID(uint fileDataID);
8+
public List<RootEntry> GetEntriesByLookup(ulong lookup);
9+
public uint[] GetAvailableFDIDs();
10+
public ulong[] GetAvailableLookups();
11+
public bool FileExists(ulong lookup);
12+
public bool FileExists(uint fileDataID);
13+
}
14+
}

TACTSharp/RootInstance.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
using System.IO.MemoryMappedFiles;
44
using System.Runtime.CompilerServices;
55
using System.Runtime.InteropServices;
6+
using TACTSharp.Interfaces;
67

78
namespace TACTSharp
89
{
910
// THIS IS MOSTLY YOINKED FROM BUILDBACKUP, REMAKE AT SOME POINT
10-
public class RootInstance
11+
public class RootInstance : IRootInstance
1112
{
1213
private readonly MemoryMappedFile rootFile;
1314
private readonly MemoryMappedViewAccessor accessor;
@@ -340,16 +341,6 @@ unsafe public RootInstance(string path, Settings Settings)
340341
blockCount++;
341342
}
342343

343-
//if(newRoot)
344-
//{
345-
// Console.WriteLine("Read " + entriesFDID.Count + "/" + totalFiles + " total files from root");
346-
// Console.WriteLine("Read " + namedCount + "/" + namedFiles + " named files from root");
347-
//}
348-
//else
349-
//{
350-
// Console.WriteLine("Read " + entriesFDID.Count + " files from root");
351-
//}
352-
353344
mmapViewHandle.ReleasePointer();
354345
}
355346
}

TACTSharp/Settings.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class Settings
66
public string Product = "wow";
77
public RootInstance.LocaleFlags Locale = RootInstance.LocaleFlags.enUS;
88
public RootInstance.LoadMode RootMode = RootInstance.LoadMode.Normal;
9+
public AssetManifestType ManifestType = AssetManifestType.Root;
910
public string? BaseDir;
1011
public string? BuildConfig;
1112
public string? CDNConfig;
@@ -20,6 +21,12 @@ public class Settings
2021
public static TSLogLevel LogLevel = TSLogLevel.Info;
2122
}
2223

24+
public enum AssetManifestType
25+
{
26+
Root,
27+
TVFS
28+
}
29+
2330
public enum TSLogLevel
2431
{
2532
Debug,

0 commit comments

Comments
 (0)