Skip to content

Commit 904988a

Browse files
committed
fix model corrupted findings are incorrectly reported if the the engine had crc collision and loaded a different file.
1 parent c661b7e commit 904988a

2 files changed

Lines changed: 70 additions & 17 deletions

File tree

src/ModVerify/Verifiers/Commons/SingleModelVerifier.cs

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Threading;
45
using AET.ModVerify.Reporting;
56
using AET.ModVerify.Settings;
@@ -182,14 +183,31 @@ private void VerifyModelClass(ModelClass modelClass, IReadOnlyCollection<string>
182183
}
183184
catch (BinaryCorruptedException e)
184185
{
185-
var message = $"'{fileName}' is corrupted: {e.Message}";
186-
AddError(VerificationError.Create(
187-
this,
188-
VerifierErrorCodes.BinaryFileCorrupt,
189-
message,
190-
VerificationSeverity.Critical,
191-
contextInfo,
192-
NormalizeFileName(fileName)));
186+
if (!CheckBinaryCorruptedFileIsActuallyRenderable(fileName, out var actualFilePath))
187+
{
188+
var message = $"Possible file CRC32 collision: '{fileName}' was requested but '{actualFilePath}' was found by the engine.";
189+
AddError(VerificationError.Create(
190+
this,
191+
VerifierErrorCodes.UnexpectedFileLoad,
192+
message,
193+
// Error, because loading a model/particle directly impacts game behavior and would be very hard to debug
194+
// for mod creators, unaware of the CRC32 collision issue.
195+
VerificationSeverity.Error,
196+
contextInfo,
197+
NormalizeFileName(fileName)));
198+
}
199+
else
200+
{
201+
var message = $"'{fileName}' is corrupted: {e.Message}";
202+
AddError(VerificationError.Create(
203+
this,
204+
VerifierErrorCodes.BinaryFileCorrupt,
205+
message,
206+
VerificationSeverity.Critical,
207+
contextInfo,
208+
NormalizeFileName(fileName)));
209+
}
210+
193211
exists = true;
194212
return null;
195213
}
@@ -213,20 +231,39 @@ private void VerifyModelClass(ModelClass modelClass, IReadOnlyCollection<string>
213231
alamoFile.FileName, @"DATA\ART\MODELS", true,
214232
(_, _, alaFile) =>
215233
{
216-
var alaFileName = NormalizeFileName(alaFile);
217-
AddError(VerificationError.Create(
218-
this,
219-
VerifierErrorCodes.BinaryFileCorrupt,
220-
$"Invalid animation file '{alaFileName}' for model '{alamoFile.FileName}'",
221-
VerificationSeverity.Error,
222-
[NormalizeFileName(alamoFile.FileName)],
223-
alaFileName));
234+
var alaFileName = NormalizeFileName(alaFile);
235+
236+
if (!CheckBinaryCorruptedFileIsActuallyRenderable(alaFileName, out var actualFilePath))
237+
{
238+
var message =
239+
$"Possible file CRC32 collision: '{fileName}' was requested but '{actualFilePath}' was found by the engine.";
240+
AddError(VerificationError.Create(
241+
this,
242+
VerifierErrorCodes.UnexpectedFileLoad,
243+
message,
244+
// Information, because for animations, as there is more likely to be a CRC32 collision than an actual corrupted file.
245+
// This is because the engine attempts to load all possible animations for each model and thus
246+
// there are simply more chances for a CRC32 collision.
247+
VerificationSeverity.Information,
248+
contextInfo,
249+
NormalizeFileName(fileName)));
250+
}
251+
else
252+
{
253+
AddError(VerificationError.Create(
254+
this,
255+
VerifierErrorCodes.BinaryFileCorrupt,
256+
$"Invalid animation file '{alaFileName}' for model '{alamoFile.FileName}'",
257+
VerificationSeverity.Error,
258+
[NormalizeFileName(alamoFile.FileName)],
259+
alaFileName));
260+
}
224261
});
225262
}
226263

227264
return new ModelClass(alamoFile, animationCollection);
228265
}
229-
266+
230267
private void VerifyParticle(IAloParticleFile file, IReadOnlyCollection<string> contextInfo)
231268
{
232269
IReadOnlyList<string> particleContext = [.. contextInfo, NormalizeFileName(file.FileName)];
@@ -396,6 +433,21 @@ private void VerifyShaderExists(IPetroglyphFileHolder model, string shader, IRea
396433
}
397434
}
398435

436+
// NB: This method assures that the BinaryCorruptedException resulted from a file
437+
// that is actually an Alamo file (and thus should be reported as a corrupted file),
438+
// and not from some other file that was found due to e.g., CRC32 collision.
439+
private bool CheckBinaryCorruptedFileIsActuallyRenderable(string fileName, out string actualFilePath)
440+
{
441+
var filePath = FileSystem.Path.Join(@"DATA\ART\MODELS", fileName);
442+
var exists = GameEngine.GameRepository.FileExists(filePath, false, out _, out actualFilePath!);
443+
Debug.Assert(exists);
444+
445+
var extension = FileSystem.Path.GetExtension(actualFilePath);
446+
447+
return string.IsNullOrEmpty(actualFilePath) || extension.Equals(".alo", StringComparison.OrdinalIgnoreCase) ||
448+
extension.Equals(".ala", StringComparison.OrdinalIgnoreCase);
449+
}
450+
399451
private string NormalizeFileName(string fileName)
400452
{
401453
return GameEngine.GameRepository.PGFileSystem.GetFileName(fileName).ToUpperInvariant();

src/ModVerify/Verifiers/VerifierErrorCodes.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public static class VerifierErrorCodes
1818
public const string FileNotFound = "FILE00";
1919
public const string FilePathTooLong = "FILE01";
2020
public const string InvalidFilePath = "FILE02";
21+
public const string UnexpectedFileLoad = "FILE03";
2122

2223
public const string Duplicate = "DUP00";
2324
public const string MissingXRef = "XREF00";

0 commit comments

Comments
 (0)