Skip to content

Commit 27f4dca

Browse files
committed
Some more work on the verification tool
1 parent 0067ffd commit 27f4dca

File tree

2 files changed

+142
-60
lines changed

2 files changed

+142
-60
lines changed

TACTTool/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.CommandLine;
33
using System.Diagnostics;
44
using TACTSharp;
5+
using TACTTool.RunModes;
56

67
namespace TACTTool
78
{
@@ -86,7 +87,7 @@ static async Task Main(string[] args)
8687

8788
if(RunModeSetting == RunMode.Verify)
8889
{
89-
RunModes.Verify.Run(build);
90+
Verify.Run(build);
9091
return;
9192
}
9293

TACTTool/RunModes/Verify.cs

Lines changed: 140 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Security.Cryptography;
4-
using System.Text;
1+
using System.Security.Cryptography;
52
using TACTSharp;
63

74
namespace TACTTool.RunModes
@@ -15,79 +12,163 @@ public static void Run(BuildInstance buildInstance)
1512
Console.WriteLine("NOTE: This is currently a very basic implementation that only checks archive/loose file existence & sizes.");
1613
Console.WriteLine("!!!");
1714

18-
if (buildInstance.Settings.CDNConfig is null)
19-
{
20-
Console.WriteLine("!!! Warning, no CDN config given so will check entire directory. This may take a long time and may fail on SMB mounted shares.");
21-
Console.WriteLine("Also, this is not yet implemented.");
22-
throw new NotImplementedException();
23-
}
24-
else
15+
var badFiles = new List<string>();
16+
var missingFiles = new List<string>();
17+
18+
var buildConfigs = new List<string>();
19+
var cdnConfigs = new List<string>();
20+
var patchConfigs = new List<string>();
21+
var keyRings = new List<string>();
22+
23+
var checkedFiles = new HashSet<string>();
24+
25+
Console.WriteLine("Scanning configs...");
26+
var configPath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "config");
27+
foreach (var file in Directory.GetFiles(configPath, "*", SearchOption.AllDirectories))
2528
{
26-
var config = new TACTSharp.Config(buildInstance.cdn, buildInstance.Settings.CDNConfig, false);
29+
using (var stream = File.OpenRead(file))
30+
{
31+
using (var reader = new StreamReader(stream))
32+
{
33+
var firstLine = reader.ReadLine();
34+
if (firstLine == "# Build Configuration")
35+
buildConfigs.Add(file);
36+
else if (firstLine == "# CDN Configuration")
37+
cdnConfigs.Add(file);
38+
else if (firstLine == "# Patch Configuration")
39+
patchConfigs.Add(file);
40+
else if (firstLine!.StartsWith("key"))
41+
keyRings.Add(file);
42+
else
43+
Console.WriteLine($"!!! Warning, unknown config file {file} with first line of : " + firstLine);
44+
}
45+
}
2746

28-
var archiveCount = config.Values["archives"].Length;
29-
for (var i = 0; i < archiveCount; i++)
47+
var md5 = Convert.ToHexStringLower(MD5.HashData(File.ReadAllBytes(file)));
48+
if (md5 != Path.GetFileNameWithoutExtension(file))
3049
{
31-
var archiveIndex = config.Values["archives"][i];
50+
Console.WriteLine($"!!! Warning, config file {file} has incorrect MD5 hash! Expected {Path.GetFileNameWithoutExtension(file)} but got {md5}.");
51+
badFiles.Add(file);
52+
}
3253

33-
var indexPath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", archiveIndex[0..2], archiveIndex[2..4], archiveIndex + ".index");
34-
if (!File.Exists(indexPath))
35-
throw new FileNotFoundException(indexPath);
54+
checkedFiles.Add(file);
55+
}
3656

37-
var index = new IndexInstance(indexPath);
57+
Console.WriteLine("Found " + buildConfigs.Count + " build configs, " + cdnConfigs.Count + " CDN configs and " + patchConfigs.Count + " patch configs.");
3858

39-
var allFiles = index.GetAllEntries();
40-
var highestOffset = allFiles.Select(x => x.offset + x.size).Max();
59+
for (var c = 0; c < cdnConfigs.Count; c++)
60+
{
61+
{
62+
var cdnConfig = cdnConfigs[c];
63+
var config = new TACTSharp.Config(buildInstance.cdn, cdnConfig, true);
64+
var configName = Path.GetFileNameWithoutExtension(cdnConfig);
4165

42-
var archiveFileInfo = new FileInfo(indexPath.Replace(".index", ""));
43-
if (!archiveFileInfo.Exists)
44-
throw new FileNotFoundException(archiveFileInfo.FullName);
45-
var archiveLength = archiveFileInfo.Length;
66+
Console.Write("Checking cdnconfigs.. " + (c + 1) + "/" + cdnConfigs.Count + "\r");
4667

47-
if (highestOffset != archiveLength)
68+
var archiveCount = config.Values["archives"].Length;
69+
for (var i = 0; i < archiveCount; i++)
4870
{
49-
Console.WriteLine($"!!! Archive {archiveIndex} has wrong size! Expected {highestOffset} bytes but only found {archiveLength} bytes.");
50-
}
71+
var archiveIndex = config.Values["archives"][i];
72+
if (checkedFiles.Contains(archiveIndex))
73+
continue;
5174

52-
Console.Write("Checking archives.. " + (i + 1) + "/" + archiveCount + "\r");
53-
}
75+
var indexPath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", archiveIndex[0..2], archiveIndex[2..4], archiveIndex + ".index");
76+
if (!File.Exists(indexPath))
77+
{
78+
Console.WriteLine($"!!! [{configName}] Archive index {archiveIndex} is missing!\n");
79+
missingFiles.Add(indexPath);
80+
checkedFiles.Add(indexPath);
81+
continue;
82+
}
5483

55-
Console.WriteLine();
84+
var index = new IndexInstance(indexPath);
5685

57-
if (config.Values.TryGetValue("file-index", out string[]? fileIndexName))
58-
{
59-
var fileIndexPath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", fileIndexName[0][0..2], fileIndexName[0][2..4], fileIndexName[0] + ".index");
60-
var fileIndex = new IndexInstance(fileIndexPath);
61-
var allFiles = fileIndex.GetAllEntries();
62-
var looseFileCount = allFiles.Count;
63-
for(var i = 0; i < looseFileCount; i++)
86+
// TODO: Check index integrity
87+
88+
var allFiles = index.GetAllEntries();
89+
var highestOffset = allFiles.Select(x => x.offset + x.size).Max();
90+
91+
var archiveFileInfo = new FileInfo(indexPath.Replace(".index", ""));
92+
if (archiveFileInfo.Exists)
93+
{
94+
var archiveLength = archiveFileInfo.Length;
95+
96+
if (highestOffset != archiveLength)
97+
{
98+
Console.WriteLine($"!!! [{configName}] Archive {archiveIndex} has wrong size! Expected {highestOffset} bytes but only found {archiveLength} bytes.\n");
99+
badFiles.Add(archiveFileInfo.FullName);
100+
}
101+
}
102+
else
103+
{
104+
Console.WriteLine($"!!! [{configName}] Archive file {archiveIndex} is missing!\n");
105+
missingFiles.Add(indexPath);
106+
}
107+
108+
checkedFiles.Add(archiveIndex);
109+
110+
//Console.Write("Checking archives.. " + (i + 1) + "/" + archiveCount + "\r");
111+
}
112+
113+
if (config.Values.TryGetValue("file-index", out string[]? fileIndexName))
64114
{
65-
Console.Write("Checking loose files.. " + (i + 1) + "/" + looseFileCount + "\r");
66-
var looseFile = allFiles[i];
67-
var looseFileName = Convert.ToHexStringLower(looseFile.eKey);
68-
var looseFilePath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", looseFileName[0..2], looseFileName[2..4], looseFileName);
69-
var looseFileInfo = new FileInfo(looseFilePath);
70-
if (!looseFileInfo.Exists)
71-
throw new FileNotFoundException(looseFilePath);
72-
73-
var looseFileSize = looseFileInfo.Length;
74-
var looseFileSupposedSize = looseFile.size;
75-
76-
//var looseFileMD5 = Convert.ToHexStringLower(MD5.HashData(File.ReadAllBytes(looseFilePath)));
77-
//if(looseFileMD5 != looseFileName)
78-
//{
79-
// Console.WriteLine($"!!! MD5 for file {looseFileName} is incorrect ({looseFileName} != {looseFileMD5}!");
80-
//}
81-
82-
if (looseFileSize != looseFileSupposedSize)
115+
var fileIndexPath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", fileIndexName[0][0..2], fileIndexName[0][2..4], fileIndexName[0] + ".index");
116+
var fileIndex = new IndexInstance(fileIndexPath);
117+
var allFiles = fileIndex.GetAllEntries();
118+
var looseFileCount = allFiles.Count;
119+
for (var i = 0; i < looseFileCount; i++)
83120
{
84-
Console.WriteLine($"!!! Loose file {looseFileName} has wrong size! Expected {looseFileSupposedSize} bytes but only found {looseFileSize} bytes.");
121+
//Console.Write("Checking loose files.. " + (i + 1) + "/" + looseFileCount + "\r");
122+
123+
var looseFile = allFiles[i];
124+
var looseFileName = Convert.ToHexStringLower(looseFile.eKey);
125+
126+
if (checkedFiles.Contains(looseFileName))
127+
continue;
128+
129+
var looseFilePath = Path.Combine(buildInstance.Settings.CDNDir, "tpr", "wow", "data", looseFileName[0..2], looseFileName[2..4], looseFileName);
130+
var looseFileInfo = new FileInfo(looseFilePath);
131+
if (looseFileInfo.Exists)
132+
{
133+
var looseFileSize = looseFileInfo.Length;
134+
var looseFileSupposedSize = looseFile.size;
135+
136+
// bad assumption here
137+
//var looseFileMD5 = Convert.ToHexStringLower(MD5.HashData(File.ReadAllBytes(looseFilePath)));
138+
//if (looseFileMD5 != looseFileName)
139+
//{
140+
// Console.WriteLine($"!!! MD5 for file {looseFileName} is incorrect ({looseFileName} != {looseFileMD5}!");
141+
// badFiles.Add(looseFilePath);
142+
//}
143+
144+
if (looseFileSize != looseFileSupposedSize)
145+
{
146+
Console.WriteLine($"!!! [{configName}] Loose file {looseFileName} has wrong size! Expected {looseFileSupposedSize} bytes but only found {looseFileSize} bytes.\n");
147+
badFiles.Add(looseFileName);
148+
}
149+
}
150+
else
151+
{
152+
Console.WriteLine($"!!! [{configName}] Loose file {looseFileName} is missing!\n");
153+
missingFiles.Add(looseFileName);
154+
}
155+
156+
checkedFiles.Add(looseFileName);
85157
}
86158
}
87-
}
159+
else
160+
{
161+
// TODO: No file index, list loose files from connected builds => encodings?
162+
//Console.WriteLine($"!!! [{configName}] No file index specified, skipping loose file checks.\n");
163+
}
88164

89-
Console.WriteLine();
165+
// TODO: Other cdnconfig listed things such as patch archives
166+
}
90167
}
168+
169+
Console.WriteLine("Verification complete! " + (badFiles.Count + missingFiles.Count) + " total issues found (" + badFiles.Count + " bad files, " + missingFiles.Count + " missing files).");
170+
File.WriteAllLines("badFiles.txt", badFiles);
171+
File.WriteAllLines("missingFiles.txt", missingFiles);
91172
}
92173
}
93174
}

0 commit comments

Comments
 (0)