Skip to content

Commit e7ff82d

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

File tree

8 files changed

+582
-64
lines changed

8 files changed

+582
-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: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
using Common;
2+
using Common.Enums;
3+
using Common.Enums.Versions;
4+
using Common.Interfaces;
5+
using Games.Games;
6+
using Mods.Addons;
7+
using Ports.Ports;
8+
using Ports.Ports.EDuke32;
9+
10+
namespace Tests;
11+
12+
public class BloodLineArgumentsTests
13+
{
14+
private readonly BloodGame _bloodGame;
15+
private readonly BloodCampaign _bloodCamp;
16+
17+
private readonly AutoloadMod _enabledMod;
18+
private readonly AutoloadMod _incompatibleMod;
19+
private readonly AutoloadMod _incompatibleModWithIncompatibleVersion;
20+
private readonly AutoloadMod _incompatibleModWithCompatibleVersion;
21+
private readonly AutoloadMod _disabledMod;
22+
private readonly AutoloadMod _eduke32mod;
23+
24+
public BloodLineArgumentsTests()
25+
{
26+
_bloodGame = new()
27+
{
28+
GameInstallFolder = @"D:\Games\Duke3D"
29+
};
30+
31+
_bloodCamp = new()
32+
{
33+
Id = nameof(GameEnum.Duke3D).ToLower(),
34+
Type = AddonTypeEnum.Official,
35+
Title = "Duke Nukem 3D",
36+
GridImage = null,
37+
Author = "3D Realms",
38+
Description = """
39+
Duke Nukem 3D is a first-person shooter developed and published by **3D Realms**.
40+
Released on April 19, 1996, Duke Nukem 3D is the third game in the Duke Nukem series and a sequel to Duke Nukem II.
41+
42+
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.
43+
In the end, Duke annihilates the alien overlords and celebrates by desecrating their corpses.
44+
""",
45+
Version = null,
46+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
47+
RequiredFeatures = null,
48+
PathToFile = null,
49+
DependentAddons = null,
50+
IncompatibleAddons = null,
51+
MainDef = null,
52+
AdditionalDefs = null,
53+
StartMap = null,
54+
PreviewImage = null,
55+
INI = null,
56+
RFF = null,
57+
SND = null
58+
};
59+
60+
_enabledMod = new()
61+
{
62+
Id = "duke3d-enabledMod",
63+
Type = AddonTypeEnum.Mod,
64+
Title = "enabledMod",
65+
GridImage = null,
66+
Author = "test",
67+
Description = "test",
68+
Version = "1.5",
69+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
70+
IncompatibleAddons = null,
71+
RequiredFeatures = null,
72+
PathToFile = "enabled_mod.zip",
73+
DependentAddons = null,
74+
AdditionalCons = ["ENABLED1.CON", "ENABLED2.CON"],
75+
MainDef = null,
76+
AdditionalDefs = ["ENABLED1.DEF", "ENABLED2.DEF"],
77+
StartMap = null,
78+
PreviewImage = null,
79+
IsEnabled = true
80+
};
81+
82+
_incompatibleMod = new()
83+
{
84+
Id = "duke3d-incompatibleMod",
85+
Type = AddonTypeEnum.Mod,
86+
Title = "incompatibleMod",
87+
GridImage = null,
88+
Author = "test",
89+
Description = "test",
90+
Version = "1.0",
91+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
92+
RequiredFeatures = null,
93+
PathToFile = null,
94+
DependentAddons = null,
95+
IncompatibleAddons = new() { { "duke3d-enabledMod", null } },
96+
AdditionalCons = null,
97+
MainDef = null,
98+
AdditionalDefs = null,
99+
StartMap = null,
100+
PreviewImage = null,
101+
IsEnabled = true
102+
};
103+
104+
_incompatibleModWithCompatibleVersion = new()
105+
{
106+
Id = "duke3d-incompatibleModWithIncompatibleVersion",
107+
Type = AddonTypeEnum.Mod,
108+
Title = "incompatibleModWithIncompatibleVersion",
109+
GridImage = null,
110+
Author = "test",
111+
Description = "test",
112+
Version = "1.0",
113+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
114+
RequiredFeatures = null,
115+
PathToFile = "incompatible_mod_with_compatible_version.zip",
116+
DependentAddons = null,
117+
IncompatibleAddons = new() { { "duke3d-enabledMod", "<=1.0" } },
118+
AdditionalCons = null,
119+
MainDef = null,
120+
AdditionalDefs = null,
121+
StartMap = null,
122+
PreviewImage = null,
123+
IsEnabled = true
124+
};
125+
126+
_incompatibleModWithIncompatibleVersion = new()
127+
{
128+
Id = "duke3d-incompatibleModWithCompatibleVersion",
129+
Type = AddonTypeEnum.Mod,
130+
Title = "incompatibleModWithCompatibleVersion",
131+
GridImage = null,
132+
Author = "test",
133+
Description = "test",
134+
Version = "1.0",
135+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
136+
RequiredFeatures = null,
137+
PathToFile = "incompatible_mod_with_incompatible_version.zip",
138+
DependentAddons = null,
139+
IncompatibleAddons = new() { { "duke3d-enabledMod", ">1.1" } },
140+
AdditionalCons = null,
141+
MainDef = null,
142+
AdditionalDefs = null,
143+
StartMap = null,
144+
PreviewImage = null,
145+
IsEnabled = true
146+
};
147+
148+
_disabledMod = new()
149+
{
150+
Id = "duke3d-disabledMod",
151+
Type = AddonTypeEnum.Mod,
152+
Title = "disabledMod",
153+
GridImage = null,
154+
Author = "test",
155+
Description = "test",
156+
Version = "1.0",
157+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
158+
RequiredFeatures = null,
159+
PathToFile = "disabled_mod.zip",
160+
DependentAddons = null,
161+
IncompatibleAddons = null,
162+
AdditionalCons = null,
163+
MainDef = null,
164+
AdditionalDefs = null,
165+
StartMap = null,
166+
PreviewImage = null,
167+
IsEnabled = false
168+
};
169+
170+
_eduke32mod = new()
171+
{
172+
Id = "duke3d-eduke32mod",
173+
Type = AddonTypeEnum.Mod,
174+
Title = "eduke32mod",
175+
GridImage = null,
176+
Author = "test",
177+
Description = "test",
178+
Version = "1.0",
179+
SupportedGame = new(GameEnum.Duke3D, DukeVersionEnum.Duke3D_Atomic),
180+
RequiredFeatures = [FeatureEnum.EDuke32_CON],
181+
PathToFile = "eduke32_mod.zip",
182+
DependentAddons = null,
183+
IncompatibleAddons = null,
184+
AdditionalCons = null,
185+
MainDef = null,
186+
AdditionalDefs = null,
187+
StartMap = null,
188+
PreviewImage = null,
189+
IsEnabled = true
190+
};
191+
}
192+
193+
[Fact]
194+
public void RazeTest()
195+
{
196+
var mods = new List<AutoloadMod>() {
197+
_enabledMod,
198+
_incompatibleMod,
199+
_disabledMod,
200+
_incompatibleModWithIncompatibleVersion,
201+
_incompatibleModWithCompatibleVersion,
202+
_eduke32mod
203+
}.ToDictionary(x => new AddonVersion(x.Id, x.Version), x => (IAddon)x);
204+
205+
Raze raze = new();
206+
207+
var args = raze.GetStartGameArgs(_bloodGame, _bloodCamp, mods, true, true);
208+
var expected = @" -quick -nosetup -file ""enabled_mod.zip"" -adddef ""ENABLED1.DEF"" -adddef ""ENABLED2.DEF"" -addcon ""ENABLED1.CON"" -addcon ""ENABLED2.CON"" -file ""incompatible_mod_with_compatible_version.zip"" -savedir ""E:\MyApps\BuildLauncher\artifacts\bin\Tests\debug\Data\Ports\Raze\Save\duke3d"" -def ""a"" -addon 0";
209+
210+
Assert.Equal(expected, args);
211+
}
212+
213+
[Fact]
214+
public void EDuke32Test()
215+
{
216+
var mods = new List<AutoloadMod>() {
217+
_enabledMod,
218+
_incompatibleMod,
219+
_disabledMod,
220+
_incompatibleModWithIncompatibleVersion,
221+
_incompatibleModWithCompatibleVersion,
222+
_eduke32mod
223+
}.ToDictionary(x => new AddonVersion(x.Id, x.Version), x => (IAddon)x);
224+
225+
EDuke32 eduke32 = new();
226+
227+
var args = eduke32.GetStartGameArgs(_bloodGame, _bloodCamp, mods, true, true, 3);
228+
var expected = @$" -quick -nosetup -j ""{Directory.GetCurrentDirectory()}\Data\Duke3D\Mods"" -g ""enabled_mod.zip"" -mh ""ENABLED1.DEF"" -mh ""ENABLED2.DEF"" -mx ""ENABLED1.CON"" -mx ""ENABLED2.CON"" -g ""incompatible_mod_with_compatible_version.zip"" -g ""eduke32_mod.zip"" -usecwd -h ""a"" -j ""D:\Games\Duke3D"" -addon 0 -s3";
229+
230+
Assert.Equal(expected, args);
231+
}
232+
}

0 commit comments

Comments
 (0)