Skip to content

Commit 333551b

Browse files
committed
fixed dependencies and incompatibilities, added unit tests
1 parent 600ceec commit 333551b

File tree

8 files changed

+656
-64
lines changed

8 files changed

+656
-64
lines changed

src/Mods/Addons/Addon.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Mods.Addons
88
/// <summary>
99
/// Base class for campaigns and maps
1010
/// </summary>
11-
public class Addon : IAddon
11+
public abstract class Addon : IAddon
1212
{
1313
/// <inheritdoc/>
1414
public required AddonTypeEnum Type { get; init; }

src/Mods/Providers/InstalledAddonsProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,11 @@ newAddon.Version is not null &&
425425
{
426426
var isEnabled = !_config.DisabledAutoloadMods.Contains(id);
427427

428+
if (mainDef is not null)
429+
{
430+
ThrowHelper.ArgumentException($"Autoload mod can't have Main DEF");
431+
}
432+
428433
addon = new AutoloadMod()
429434
{
430435
Id = id,
@@ -436,7 +441,7 @@ newAddon.Version is not null &&
436441
Author = author,
437442
IsEnabled = isEnabled,
438443
PathToFile = pathToFile,
439-
MainDef = mainDef,
444+
MainDef = null,
440445
AdditionalDefs = addDefs,
441446
AdditionalCons = addCons,
442447
SupportedGame = new(supportedGame, gameVersion, gameCrc),

src/Ports/Ports/BasePort.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,28 +214,50 @@ protected bool ValidateAutoloadMod(AutoloadMod autoloadMod, IAddon campaign, Dic
214214

215215
if (autoloadMod.DependentAddons is not null)
216216
{
217-
foreach (var dep in autoloadMod.DependentAddons)
217+
foreach (var dependantAddon in autoloadMod.DependentAddons)
218218
{
219-
if (!addons.ContainsKey(new(dep.Key, dep.Value)) &&
220-
!campaign.Id.Equals(dep.Key, StringComparison.OrdinalIgnoreCase))
219+
foreach (var addon in addons)
221220
{
222-
//skipping mod that doesn't have every dependency
223-
return false;
221+
if (dependantAddon.Key != addon.Key.Id)
222+
{
223+
continue;
224+
}
225+
else if (dependantAddon.Value is null)
226+
{
227+
return true;
228+
}
229+
else if (VersionComparer.Compare(addon.Key.Version, dependantAddon.Value))
230+
{
231+
return true;
232+
}
224233
}
225234
}
235+
236+
return false;
226237
}
227238

228239
if (autoloadMod.IncompatibleAddons is not null)
229240
{
230-
foreach (var dep in autoloadMod.IncompatibleAddons)
241+
foreach (var incompatibleAddon in autoloadMod.IncompatibleAddons)
231242
{
232-
if (addons.ContainsKey(new(dep.Key, dep.Value)) ||
233-
campaign.Id.Equals(dep.Key, StringComparison.OrdinalIgnoreCase))
243+
foreach (var addon in addons)
234244
{
235-
//skipping incompatible mods
236-
return false;
245+
if (incompatibleAddon.Key != addon.Key.Id)
246+
{
247+
continue;
248+
}
249+
else if (incompatibleAddon.Value is null)
250+
{
251+
return false;
252+
}
253+
else if (VersionComparer.Compare(addon.Key.Version, incompatibleAddon.Value))
254+
{
255+
return false;
256+
}
237257
}
238258
}
259+
260+
return true;
239261
}
240262

241263
return true;

src/Tests/BloodCmdArgumentsTests.cs

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
using Common;
2+
using Common.Enums;
3+
using Common.Interfaces;
4+
using Games.Games;
5+
using Mods.Addons;
6+
using Ports.Ports;
7+
using Ports.Ports.EDuke32;
8+
9+
namespace Tests;
10+
11+
public class BloodLineArgumentsTests
12+
{
13+
private readonly BloodGame _bloodGame;
14+
private readonly BloodCampaign _bloodCamp;
15+
16+
private readonly AutoloadMod _enabledMod;
17+
private readonly AutoloadMod _incompatibleMod;
18+
private readonly AutoloadMod _incompatibleModWithIncompatibleVersion;
19+
private readonly AutoloadMod _incompatibleModWithCompatibleVersion;
20+
private readonly AutoloadMod _dependantMod;
21+
private readonly AutoloadMod _dependantModWithIncompatibleVersion;
22+
private readonly AutoloadMod _dependantModWithCompatibleVersion;
23+
private readonly AutoloadMod _disabledMod;
24+
private readonly AutoloadMod _customDudeMod;
25+
26+
public BloodLineArgumentsTests()
27+
{
28+
_bloodGame = new()
29+
{
30+
GameInstallFolder = @"D:\Games\Blood"
31+
};
32+
33+
_bloodCamp = new()
34+
{
35+
Id = nameof(GameEnum.Blood).ToLower(),
36+
Type = AddonTypeEnum.Official,
37+
Title = "Duke Nukem 3D",
38+
GridImage = null,
39+
Author = "3D Realms",
40+
Description = """
41+
Duke Nukem 3D is a first-person shooter developed and published by **3D Realms**.
42+
Released on April 19, 1996, Duke Nukem 3D is the third game in the Duke Nukem series and a sequel to Duke Nukem II.
43+
44+
The player assumes the role of Duke Nukem, an imperious action hero, and fights through 48 levels spread across 5 episodes. The player encounters a host of enemies and fights them with a range of weaponry.
45+
In the end, Duke annihilates the alien overlords and celebrates by desecrating their corpses.
46+
""",
47+
Version = null,
48+
SupportedGame = new(GameEnum.Blood),
49+
RequiredFeatures = null,
50+
PathToFile = null,
51+
DependentAddons = null,
52+
IncompatibleAddons = null,
53+
MainDef = null,
54+
AdditionalDefs = null,
55+
StartMap = null,
56+
PreviewImage = null,
57+
INI = null,
58+
RFF = null,
59+
SND = null
60+
};
61+
62+
_enabledMod = new()
63+
{
64+
Id = "blood-enabledMod",
65+
Type = AddonTypeEnum.Mod,
66+
Title = "enabledMod",
67+
GridImage = null,
68+
Author = "test",
69+
Description = "test",
70+
Version = "1.5",
71+
SupportedGame = new(GameEnum.Blood),
72+
IncompatibleAddons = null,
73+
RequiredFeatures = null,
74+
PathToFile = "enabled_mod.zip",
75+
DependentAddons = null,
76+
AdditionalCons = null,
77+
MainDef = null,
78+
AdditionalDefs = ["ENABLED1.DEF", "ENABLED2.DEF"],
79+
StartMap = null,
80+
PreviewImage = null,
81+
IsEnabled = true
82+
};
83+
84+
_incompatibleMod = new()
85+
{
86+
Id = "blood-incompatibleMod",
87+
Type = AddonTypeEnum.Mod,
88+
Title = "incompatibleMod",
89+
GridImage = null,
90+
Author = "test",
91+
Description = "test",
92+
Version = "1.0",
93+
SupportedGame = new(GameEnum.Blood),
94+
RequiredFeatures = null,
95+
PathToFile = null,
96+
DependentAddons = null,
97+
IncompatibleAddons = new() { { "blood-enabledMod", null } },
98+
AdditionalCons = null,
99+
MainDef = null,
100+
AdditionalDefs = null,
101+
StartMap = null,
102+
PreviewImage = null,
103+
IsEnabled = true
104+
};
105+
106+
_incompatibleModWithCompatibleVersion = new()
107+
{
108+
Id = "blood-incompatibleModWithIncompatibleVersion",
109+
Type = AddonTypeEnum.Mod,
110+
Title = "incompatibleModWithIncompatibleVersion",
111+
GridImage = null,
112+
Author = "test",
113+
Description = "test",
114+
Version = "1.0",
115+
SupportedGame = new(GameEnum.Blood),
116+
RequiredFeatures = null,
117+
PathToFile = "incompatible_mod_with_compatible_version.zip",
118+
DependentAddons = null,
119+
IncompatibleAddons = new() { { "blood-enabledMod", "<=1.0" } },
120+
AdditionalCons = null,
121+
MainDef = null,
122+
AdditionalDefs = null,
123+
StartMap = null,
124+
PreviewImage = null,
125+
IsEnabled = true
126+
};
127+
128+
_incompatibleModWithIncompatibleVersion = new()
129+
{
130+
Id = "blood-incompatibleModWithCompatibleVersion",
131+
Type = AddonTypeEnum.Mod,
132+
Title = "incompatibleModWithCompatibleVersion",
133+
GridImage = null,
134+
Author = "test",
135+
Description = "test",
136+
Version = "1.0",
137+
SupportedGame = new(GameEnum.Blood),
138+
RequiredFeatures = null,
139+
PathToFile = "incompatible_mod_with_incompatible_version.zip",
140+
DependentAddons = null,
141+
IncompatibleAddons = new() { { "blood-enabledMod", ">1.1" } },
142+
AdditionalCons = null,
143+
MainDef = null,
144+
AdditionalDefs = null,
145+
StartMap = null,
146+
PreviewImage = null,
147+
IsEnabled = true
148+
};
149+
150+
_dependantMod = new()
151+
{
152+
Id = "blood-dependantMod",
153+
Type = AddonTypeEnum.Mod,
154+
Title = "dependantMod",
155+
GridImage = null,
156+
Author = "test",
157+
Description = "test",
158+
Version = "1.0",
159+
SupportedGame = new(GameEnum.Blood),
160+
RequiredFeatures = null,
161+
PathToFile = "dependant_mod.zip",
162+
DependentAddons = new() { { "blood-enabledMod", null } },
163+
IncompatibleAddons = null,
164+
AdditionalCons = null,
165+
MainDef = null,
166+
AdditionalDefs = null,
167+
StartMap = null,
168+
PreviewImage = null,
169+
IsEnabled = true
170+
};
171+
172+
_dependantModWithIncompatibleVersion = new()
173+
{
174+
Id = "blood-dependantModWithIncompatibleVersion",
175+
Type = AddonTypeEnum.Mod,
176+
Title = "dependantModWithIncompatibleVersion",
177+
GridImage = null,
178+
Author = "test",
179+
Description = "test",
180+
Version = "1.0",
181+
SupportedGame = new(GameEnum.Blood),
182+
RequiredFeatures = null,
183+
PathToFile = "dependant_mod_with_incompatible_version.zip",
184+
DependentAddons = new() { { "blood-enabledMod", "<=1.0" } },
185+
IncompatibleAddons = null,
186+
AdditionalCons = null,
187+
MainDef = null,
188+
AdditionalDefs = null,
189+
StartMap = null,
190+
PreviewImage = null,
191+
IsEnabled = true
192+
};
193+
194+
_dependantModWithCompatibleVersion = new()
195+
{
196+
Id = "blood-dependantModWithCompatibleVersion",
197+
Type = AddonTypeEnum.Mod,
198+
Title = "dependantModWithCompatibleVersion",
199+
GridImage = null,
200+
Author = "test",
201+
Description = "test",
202+
Version = "1.0",
203+
SupportedGame = new(GameEnum.Blood),
204+
RequiredFeatures = null,
205+
PathToFile = "dependant_mod_with_compatible_version.zip",
206+
DependentAddons = new() { { "blood-enabledMod", ">1.1" } },
207+
IncompatibleAddons = null,
208+
AdditionalCons = null,
209+
MainDef = null,
210+
AdditionalDefs = null,
211+
StartMap = null,
212+
PreviewImage = null,
213+
IsEnabled = true
214+
};
215+
216+
_disabledMod = new()
217+
{
218+
Id = "blood-disabledMod",
219+
Type = AddonTypeEnum.Mod,
220+
Title = "disabledMod",
221+
GridImage = null,
222+
Author = "test",
223+
Description = "test",
224+
Version = "1.0",
225+
SupportedGame = new(GameEnum.Blood),
226+
RequiredFeatures = null,
227+
PathToFile = "disabled_mod.zip",
228+
DependentAddons = null,
229+
IncompatibleAddons = null,
230+
AdditionalCons = null,
231+
MainDef = null,
232+
AdditionalDefs = null,
233+
StartMap = null,
234+
PreviewImage = null,
235+
IsEnabled = false
236+
};
237+
238+
_customDudeMod = new()
239+
{
240+
Id = "blood-eduke32mod",
241+
Type = AddonTypeEnum.Mod,
242+
Title = "eduke32mod",
243+
GridImage = null,
244+
Author = "test",
245+
Description = "test",
246+
Version = "1.0",
247+
SupportedGame = new(GameEnum.Blood),
248+
RequiredFeatures = [FeatureEnum.CustomDude],
249+
PathToFile = "custom_dude_mod.zip",
250+
DependentAddons = null,
251+
IncompatibleAddons = null,
252+
AdditionalCons = null,
253+
MainDef = null,
254+
AdditionalDefs = null,
255+
StartMap = null,
256+
PreviewImage = null,
257+
IsEnabled = true
258+
};
259+
}
260+
261+
[Fact]
262+
public void RazeTest()
263+
{
264+
var mods = new List<AutoloadMod>() {
265+
_enabledMod,
266+
_incompatibleMod,
267+
_disabledMod,
268+
_incompatibleModWithIncompatibleVersion,
269+
_incompatibleModWithCompatibleVersion,
270+
_dependantMod,
271+
_dependantModWithIncompatibleVersion,
272+
_dependantModWithCompatibleVersion,
273+
_customDudeMod
274+
}.ToDictionary(x => new AddonVersion(x.Id, x.Version), x => (IAddon)x);
275+
276+
Raze raze = new();
277+
278+
var args = raze.GetStartGameArgs(_bloodGame, _bloodCamp, mods, true, true);
279+
var expected = @" -quick -nosetup -file ""enabled_mod.zip"" -adddef ""ENABLED1.DEF"" -adddef ""ENABLED2.DEF"" -file ""incompatible_mod_with_compatible_version.zip"" -file ""dependant_mod.zip"" -file ""dependant_mod_with_compatible_version.zip"" -savedir ""E:\MyApps\BuildLauncher\artifacts\bin\Tests\debug\Data\Ports\Raze\Save\blood"" -def ""a""";
280+
281+
Assert.Equal(expected, args);
282+
}
283+
284+
[Fact]
285+
public void NBloodTest()
286+
{
287+
var mods = new List<AutoloadMod>() {
288+
_enabledMod,
289+
_incompatibleMod,
290+
_disabledMod,
291+
_incompatibleModWithIncompatibleVersion,
292+
_incompatibleModWithCompatibleVersion,
293+
_dependantMod,
294+
_dependantModWithIncompatibleVersion,
295+
_dependantModWithCompatibleVersion,
296+
_customDudeMod
297+
}.ToDictionary(x => new AddonVersion(x.Id, x.Version), x => (IAddon)x);
298+
299+
NBlood nblood = new();
300+
301+
var args = nblood.GetStartGameArgs(_bloodGame, _bloodCamp, mods, true, true, 3);
302+
var expected = @$" -quick -nosetup -j ""E:\MyApps\BuildLauncher\artifacts\bin\Tests\debug\Data\Blood\Mods"" -g ""enabled_mod.zip"" -mh ""ENABLED1.DEF"" -mh ""ENABLED2.DEF"" -g ""incompatible_mod_with_compatible_version.zip"" -g ""dependant_mod.zip"" -g ""dependant_mod_with_compatible_version.zip"" -g ""custom_dude_mod.zip"" -usecwd -j ""D:\Games\Blood"" -h ""a"" -s3";
303+
304+
Assert.Equal(expected, args);
305+
}
306+
}

0 commit comments

Comments
 (0)