Skip to content

Commit b8b8121

Browse files
committed
Add optional read-only CDN cache
1 parent 7a7913c commit b8b8121

4 files changed

Lines changed: 58 additions & 3 deletions

File tree

TACTSharp/CDN.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,21 @@ public async Task<string> GetPatchServiceFile(string product, string file = "ver
184184
return File.ReadAllBytes(cachePath);
185185
}
186186

187+
if (!string.IsNullOrEmpty(Settings.CDNDir))
188+
{
189+
var cdnPath = Path.Combine(Settings.CDNDir, ProductDirectory, type, $"{hash[0]}{hash[1]}", $"{hash[2]}{hash[3]}", hash);
190+
FileLocks.TryAdd(cdnPath, new Lock());
191+
192+
if (File.Exists(cdnPath))
193+
{
194+
if (size > 0 && (ulong)new FileInfo(cdnPath).Length != size)
195+
Console.WriteLine("Warning! Found " + hash + " in CDN dir but size does not match! " + size + " != " + new FileInfo(cachePath).Length + ", continuing to download.");
196+
else
197+
lock (FileLocks[cdnPath])
198+
return File.ReadAllBytes(cdnPath);
199+
}
200+
}
201+
187202
for (var i = 0; i < CDNServers.Count; i++)
188203
{
189204
var url = $"http://{CDNServers[i]}/{ProductDirectory}/{type}/{hash[0]}{hash[1]}/{hash[2]}{hash[3]}/{hash}";
@@ -301,6 +316,31 @@ public unsafe bool TryGetLocalFile(string eKey, out ReadOnlySpan<byte> data)
301316
File.Delete(cachePath);
302317
}
303318

319+
if (!string.IsNullOrEmpty(Settings.CDNDir))
320+
{
321+
var cdnPath = Path.Combine(Settings.CDNDir, ProductDirectory, "data", $"{archive[0]}{archive[1]}", $"{archive[2]}{archive[3]}", archive);
322+
if (File.Exists(cdnPath))
323+
{
324+
if (new FileInfo(cdnPath).Length != (offset + size))
325+
Console.WriteLine("Warning! Found " + archive + " in CDN dir but size is lower than offset+size " + offset + size + " != " + new FileInfo(cachePath).Length + ", continuing to download.");
326+
else
327+
{
328+
lock (FileLocks[cdnPath])
329+
{
330+
using (var ms = new MemoryStream())
331+
{
332+
using (var fs = new FileStream(cdnPath, FileMode.Open, FileAccess.Read))
333+
{
334+
var buffer = new byte[size];
335+
fs.ReadExactly(buffer, offset, size);
336+
return buffer;
337+
}
338+
}
339+
}
340+
}
341+
}
342+
}
343+
304344
lock (cdnLock)
305345
{
306346
if (CDNServers.Count == 0)

TACTSharp/GroupIndex.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@ public string Generate(CDN CDN, Settings Settings, string? hash, string[] archiv
2929

3030
Parallel.For(0, archives.Length, archiveIndex =>
3131
{
32+
var archiveName = archives[archiveIndex];
3233
string indexPath = "";
33-
if (!string.IsNullOrEmpty(Settings.BaseDir) && File.Exists(Path.Combine(Settings.BaseDir, "Data", "indices", archives[archiveIndex] + ".index")))
34+
if (!string.IsNullOrEmpty(Settings.BaseDir) && File.Exists(Path.Combine(Settings.BaseDir, "Data", "indices", archiveName + ".index")))
3435
{
35-
indexPath = Path.Combine(Settings.BaseDir, "Data", "indices", archives[archiveIndex] + ".index");
36+
indexPath = Path.Combine(Settings.BaseDir, "Data", "indices", archiveName + ".index");
37+
}
38+
else if(!string.IsNullOrEmpty(Settings.CDNDir) && File.Exists(Path.Combine(Settings.CDNDir, CDN.ProductDirectory, "data", $"{archiveName[0]}{archiveName[1]}", $"{archiveName[2]}{archiveName[3]}", archiveName + ".index")))
39+
{
40+
indexPath = Path.Combine(Settings.CDNDir, CDN.ProductDirectory, "data", $"{archiveName[0]}{archiveName[1]}", $"{archiveName[2]}{archiveName[3]}", archiveName + ".index");
3641
}
3742
else
3843
{
@@ -166,6 +171,9 @@ public string Generate(CDN CDN, Settings Settings, string? hash, string[] archiv
166171
if (fullFooterMD5Hash != hash)
167172
throw new Exception("Footer MD5 of group index does not match group index filename");
168173

174+
if (!Directory.Exists(Path.Combine(Settings.CacheDir, CDN.ProductDirectory, "data")))
175+
Directory.CreateDirectory(Path.Combine(Settings.CacheDir, CDN.ProductDirectory, "data"));
176+
169177
File.WriteAllBytes(Path.Combine(Settings.CacheDir, CDN.ProductDirectory, "data", hash + ".index"), ms.ToArray());
170178
}
171179
else

TACTSharp/Settings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Settings
1010
public string? BuildConfig;
1111
public string? CDNConfig;
1212
public string CacheDir = "cache";
13+
public string CDNDir = "";
1314
public bool ListfileFallback = true;
1415
public string ListfileURL = "https://github.com/wowdev/wow-listfile/releases/latest/download/community-listfile.csv";
1516
}

TACTTool/Program.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ static async Task Main(string[] args)
6565
baseDirOption.AddAlias("-d");
6666
rootCommand.AddOption(baseDirOption);
6767

68+
var cdnDirOption = new Option<string?>(name: "--cdndir", description: "CDN folder to use as read-only file cache (if available)");
69+
cdnDirOption.AddAlias("-cdn");
70+
rootCommand.AddOption(cdnDirOption);
71+
6872
rootCommand.SetHandler(CommandLineArgHandler);
6973

7074
build = new BuildInstance();
@@ -234,7 +238,9 @@ private static async Task CommandLineArgHandler(InvocationContext context)
234238
_ => throw new Exception("Invalid input mode. Available modes: list, ekey/ehash, ckey/chash, fdid/id, filename/name"),
235239
};
236240
break;
237-
241+
case "cdndir":
242+
build.Settings.CDNDir = (string)optionValue;
243+
break;
238244
case "version":
239245
case "help":
240246
break;

0 commit comments

Comments
 (0)