Skip to content

Commit b24f6ad

Browse files
committed
add crc collision test
1 parent ce4a240 commit b24f6ad

2 files changed

Lines changed: 53 additions & 19 deletions

File tree

src/PetroglyphTools/PG.StarWarsGame.Engine.Test/IO/GameRepositoryTests.MegLoading.cs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public abstract partial class GameRepositoryTests
66
{
77
private const string TextEntry = "Data/Text/text.txt";
88

9-
// ----------------------- intra-origin: several MEGs in the same game -----------------------
9+
#region Intra-origin: several MEGs in the same game
1010

1111
[Fact]
1212
public void MegaFilesXml_ThreeListedMegs_LastListedWins()
@@ -58,7 +58,9 @@ public void MasterMeg_PatchSlotsOverrideMegaFilesXml_64PatchWinsOverall()
5858
Assert.Equal("64Patch", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
5959
}
6060

61-
// ----------------------- inter-origin: mod MEGs shadow game MEGs -----------------------
61+
#endregion
62+
63+
#region Inter-origin: mod MEGs shadow game MEGs
6264

6365
[Fact]
6466
public void ModPatchMeg_ShadowsGamePatchMeg()
@@ -133,32 +135,37 @@ public void MegaFilesXml_MixesModAndGameMegs_LaterListedWins()
133135
Assert.Equal("game", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
134136
}
135137

136-
// ----------------------- RegisterAndWriteMeg convenience -----------------------
137-
138-
[Fact]
139-
public void RegisterAndWriteMeg_LoadsMegViaGeneratedMegaFilesXml()
140-
{
141-
using var repo = CreateBuilder()
142-
.ConfigureGame(g => g.RegisterAndWriteMeg("Data/Custom.meg",
143-
m => m.Add(TextEntry, "registered")))
144-
.Build();
145-
var gameRepo = CreateRepository(repo);
138+
#endregion
146139

147-
Assert.Equal("registered", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
148-
}
140+
// Both of these normalized paths hash to CRC32 0x2AAF63A4:
141+
// model : DATA\ART\MODELS\MOV_EMPIRE_INTRO_SHUTTLE_FIRE_DIE_00.ALA
142+
// WAV entry : U000_EMP0212_ENG.WAV
143+
// The model request collides with the bare WAV entry once the engine has prefixed the model directory,
144+
// which is why the lookup is driven through DATA\ART\MODELS below.
145+
private const string ModelLookup = @"Data\Art\Models\MOV_EMPIRE_INTRO_SHUTTLE_FIRE_DIE_00.ALA";
146+
private const string CollidingWav = "U000_EMP0212_ENG.WAV";
149147

150148
[Fact]
151-
public void RegisterAndWriteMeg_RegistrationOrderIsLoadOrder()
149+
public void Crc32Collision_ModelLoadedFirst_ShadowedByLaterWav()
152150
{
151+
// Both files genuinely exist in the master MEG. The model's MEG (First.meg) is loaded before the
152+
// WAV's MEG (Second.meg), so the later WAV takes over the shared CRC32 slot.
153153
using var repo = CreateBuilder()
154154
.ConfigureGame(g =>
155155
{
156-
g.RegisterAndWriteMeg("Data/First.meg", m => m.Add(TextEntry, "first"));
157-
g.RegisterAndWriteMeg("Data/Second.meg", m => m.Add(TextEntry, "second"));
156+
g.RegisterAndWriteMeg("Data/First.meg", meg => meg.Add(ModelLookup, "model-bytes"));
157+
g.RegisterAndWriteMeg("Data/Second.meg", meg => meg.Add(CollidingWav, "wav-bytes"));
158158
})
159159
.Build();
160-
var gameRepo = CreateRepository(repo);
160+
var modelRepo = CreateRepository(repo).ModelRepository;
161+
162+
var found = modelRepo.FileExists(ModelLookup, megFileOnly: false, out var inMeg, out var actualFilePath);
161163

162-
Assert.Equal("second", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
164+
// The model exists, yet requesting it resolves to the colliding WAV that was loaded later: the
165+
// engine reports the WAV's path and hands back the WAV's bytes instead of the model.
166+
Assert.True(found);
167+
Assert.True(inMeg);
168+
Assert.Equal(CollidingWav, actualFilePath);
169+
Assert.Equal("wav-bytes", ReadAll(modelRepo.OpenFile(ModelLookup)));
163170
}
164171
}

src/PetroglyphTools/PG.StarWarsGame.Engine.Test/IO/GameRepositoryTests.MegLookup.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,31 @@ public void EmptyMegaFilesXml_DoesNotCrash()
125125

126126
Assert.False(gameRepo.FileExists("anything.txt"));
127127
}
128+
129+
[Fact]
130+
public void RegisterAndWriteMeg_LoadsMegViaGeneratedMegaFilesXml()
131+
{
132+
using var repo = CreateBuilder()
133+
.ConfigureGame(g => g.RegisterAndWriteMeg("Data/Custom.meg",
134+
m => m.Add(TextEntry, "registered")))
135+
.Build();
136+
var gameRepo = CreateRepository(repo);
137+
138+
Assert.Equal("registered", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
139+
}
140+
141+
[Fact]
142+
public void RegisterAndWriteMeg_RegistrationOrderIsLoadOrder()
143+
{
144+
using var repo = CreateBuilder()
145+
.ConfigureGame(g =>
146+
{
147+
g.RegisterAndWriteMeg("Data/First.meg", m => m.Add(TextEntry, "first"));
148+
g.RegisterAndWriteMeg("Data/Second.meg", m => m.Add(TextEntry, "second"));
149+
})
150+
.Build();
151+
var gameRepo = CreateRepository(repo);
152+
153+
Assert.Equal("second", ReadAll(gameRepo.OpenFile(TextEntry, megFileOnly: true)));
154+
}
128155
}

0 commit comments

Comments
 (0)