Skip to content

Commit e52c1b1

Browse files
committed
imp - brk|doc - Moved mod loading code (pt. 2)
--- We've finally managed to separate mod loading code from the base part of the kernel. However, some parts, such as mod path and mod information class, remain in the base kernel. --- Type: imp Breaking: True Doc Required: True Backport Required: False Part: 1/1
1 parent 4785ff1 commit e52c1b1

File tree

16 files changed

+287
-148
lines changed

16 files changed

+287
-148
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
changes!
2424
-->
2525
<NitrocidModAPIVersionMajor>3.0.27</NitrocidModAPIVersionMajor>
26-
<NitrocidModAPIVersionChangeset>28</NitrocidModAPIVersionChangeset>
26+
<NitrocidModAPIVersionChangeset>30</NitrocidModAPIVersionChangeset>
2727

2828
<!-- The above two properties are to be installed to the file version -->
2929
<NitrocidModAPIVersion>$(NitrocidModAPIVersionMajor).$(NitrocidModAPIVersionChangeset)</NitrocidModAPIVersion>

private/Nitrocid.Tests/Modifications/BlacklistManipulationTests.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
using Shouldly;
2222
using Nitrocid.Files;
2323
using Nitrocid.Files.Paths;
24-
using Nitrocid.Modifications;
24+
using Nitrocid.Kernel.Extensions;
25+
using System.Collections.Generic;
2526

2627
namespace Nitrocid.Tests.Modifications
2728
{
@@ -37,8 +38,10 @@ public class BlacklistManipulationTests
3738
[Description("Management")]
3839
public void TestAddModToBlacklist()
3940
{
40-
ModManager.AddModToBlacklist("MaliciousMod.dll");
41-
ModManager.GetBlacklistedMods().ShouldContain(FilesystemTools.NeutralizePath("MaliciousMod.dll", PathsManagement.GetKernelPath(KernelPathType.Mods)));
41+
var modManagerType = InterAddonTools.GetTypeFromAddon(KnownAddons.ExtrasMods, "Nitrocid.Extras.Mods.Modifications.ModManager");
42+
InterAddonTools.ExecuteCustomAddonFunction(KnownAddons.ExtrasMods, "AddModToBlacklist", modManagerType, "MaliciousMod.dll");
43+
var blacklistedMods = (IEnumerable<string>?)InterAddonTools.ExecuteCustomAddonFunction(KnownAddons.ExtrasMods, "GetBlacklistedMods", modManagerType) ?? [];
44+
blacklistedMods.ShouldContain(FilesystemTools.NeutralizePath("MaliciousMod.dll", PathsManagement.GetKernelPath(KernelPathType.Mods)));
4245
}
4346

4447
/// <summary>
@@ -48,8 +51,10 @@ public void TestAddModToBlacklist()
4851
[Description("Management")]
4952
public void TestRemoveModFromBlacklist()
5053
{
51-
ModManager.RemoveModFromBlacklist("MaliciousMod.dll");
52-
ModManager.GetBlacklistedMods().ShouldNotContain(FilesystemTools.NeutralizePath("MaliciousMod.dll", PathsManagement.GetKernelPath(KernelPathType.Mods)));
54+
var modManagerType = InterAddonTools.GetTypeFromAddon(KnownAddons.ExtrasMods, "Nitrocid.Extras.Mods.Modifications.ModManager");
55+
InterAddonTools.ExecuteCustomAddonFunction(KnownAddons.ExtrasMods, "RemoveModFromBlacklist", modManagerType, "MaliciousMod.dll");
56+
var blacklistedMods = (IEnumerable<string>?)InterAddonTools.ExecuteCustomAddonFunction(KnownAddons.ExtrasMods, "GetBlacklistedMods", modManagerType) ?? [];
57+
blacklistedMods.ShouldNotContain(FilesystemTools.NeutralizePath("MaliciousMod.dll", PathsManagement.GetKernelPath(KernelPathType.Mods)));
5358
}
5459

5560
}

public/Nitrocid.Addons/Nitrocid.Extras.Mods/Modifications/ModManager.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ public static void AddModToBlacklist(string ModFilename)
228228
DebugWriter.WriteDebug(DebugLevel.I, "Mod {0} not on the blacklist. Adding...", ModFilename);
229229
BlacklistedMods.Add(ModFilename);
230230
}
231-
Config.MainConfig.BlacklistedModsString = string.Join(";", BlacklistedMods);
231+
ModsInit.ModsConfig.BlacklistedModsString = string.Join(";", BlacklistedMods);
232232
Config.CreateConfig();
233233
}
234234

@@ -246,15 +246,15 @@ public static void RemoveModFromBlacklist(string ModFilename)
246246
DebugWriter.WriteDebug(DebugLevel.I, "Mod {0} on the blacklist. Removing...", ModFilename);
247247
BlacklistedMods.Remove(ModFilename);
248248
}
249-
Config.MainConfig.BlacklistedModsString = string.Join(";", BlacklistedMods);
249+
ModsInit.ModsConfig.BlacklistedModsString = string.Join(";", BlacklistedMods);
250250
Config.CreateConfig();
251251
}
252252

253253
/// <summary>
254254
/// Gets the blacklisted mods list
255255
/// </summary>
256256
public static List<string> GetBlacklistedMods() =>
257-
[.. Config.MainConfig.BlacklistedModsString.Split(';')];
257+
[.. ModsInit.ModsConfig.BlacklistedModsString.Split(';')];
258258

259259
/// <summary>
260260
/// Installs the mod DLL or single code file to the mod directory
@@ -424,6 +424,43 @@ public static CommandInfo[] ListModCommands(string ShellType) =>
424424
return null;
425425
}
426426

427+
/// <summary>
428+
/// Gets the localized text from all mods
429+
/// </summary>
430+
/// <param name="text">Text to translate</param>
431+
/// <param name="lang">Language to query</param>
432+
/// <returns>A translated string if there is localization information for this text in a specified language</returns>
433+
public static string GetLocalizedText(string text, string lang)
434+
{
435+
foreach (ModInfo mod in ListMods().Values)
436+
{
437+
var strings = mod.ModStrings;
438+
439+
// Check for English first, as we need it to translate a string
440+
if (!strings.TryGetValue("eng", out string[]? localizationsEng))
441+
continue;
442+
if (!localizationsEng.Contains(text))
443+
continue;
444+
445+
// Now, use the English strings to get an index of this string, then get the localization from the
446+
// same index.
447+
int textIdx;
448+
for (textIdx = 0; textIdx < localizationsEng.Length; textIdx++)
449+
{
450+
if (localizationsEng[textIdx] == text)
451+
break;
452+
}
453+
if (strings.TryGetValue(lang, out string[]? localizations))
454+
{
455+
if (textIdx < localizations.Length)
456+
return localizations[textIdx];
457+
}
458+
}
459+
460+
// We haven't found anything in all mods.
461+
return text;
462+
}
463+
427464
internal static void Manage(bool start, ModLoadPriority priority = ModLoadPriority.Optional)
428465
{
429466
string ModPath = PathsManagement.GetKernelPath(KernelPathType.Mods);

public/Nitrocid.Addons/Nitrocid.Extras.Mods/Modifications/ModParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public static void ParseMod(string modFile, ModLoadPriority priority = ModLoadPr
8080
bool signed = AssemblySigning.IsStronglySigned(ModPath + modFile);
8181
if (!signed)
8282
{
83-
if (Config.MainConfig.AllowUntrustedMods)
83+
if (ModsInit.ModsConfig.AllowUntrustedMods)
8484
SplashReport.ReportProgressWarning(Translate.DoTranslation("The mod is not strongly signed. It may contain untrusted code."));
8585
else
8686
throw new KernelException(KernelExceptionType.ModManagement, Translate.DoTranslation("The mod is not strongly signed. It may contain untrusted code."));

public/Nitrocid.Addons/Nitrocid.Extras.Mods/ModsInit.cs

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,73 @@
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
//
1919

20+
using Nitrocid.Extras.Mods.Commands;
2021
using Nitrocid.Extras.Mods.Modifications;
22+
using Nitrocid.Extras.Mods.Settings;
23+
using Nitrocid.Kernel.Configuration;
2124
using Nitrocid.Kernel.Extensions;
25+
using Nitrocid.Shell.ShellBase.Arguments;
26+
using Nitrocid.Shell.ShellBase.Commands;
27+
using Nitrocid.Shell.ShellBase.Shells;
28+
using System.Collections.Generic;
29+
using System.Linq;
2230

2331
namespace Nitrocid.Extras.Mods
2432
{
2533
internal class ModsInit : IAddon
2634
{
35+
private readonly List<CommandInfo> addonCommands =
36+
[
37+
new CommandInfo("modman", /* Localizable */ "Manage your mods",
38+
[
39+
new CommandArgumentInfo(new[]
40+
{
41+
new CommandArgumentPart(true, "start/stop/info/reload/install/uninstall", new()
42+
{
43+
ExactWording = ["start", "stop", "info", "reload", "install", "uninstall"]
44+
}),
45+
new CommandArgumentPart(true, "modfilename"),
46+
}),
47+
new CommandArgumentInfo(new[]
48+
{
49+
new CommandArgumentPart(true, "list/reloadall/stopall/startall", new()
50+
{
51+
ExactWording = ["list", "reloadall", "stopall", "startall"]
52+
}),
53+
}),
54+
], new ModManCommand(), CommandFlags.Strict),
55+
56+
new CommandInfo("modmanual", /* Localizable */ "Mod manual",
57+
[
58+
new CommandArgumentInfo(new[]
59+
{
60+
new CommandArgumentPart(true, "modname"),
61+
})
62+
], new ModManualCommand()),
63+
];
64+
2765
string IAddon.AddonName =>
2866
InterAddonTranslations.GetAddonName(KnownAddons.ExtrasMods);
2967

3068
ModLoadPriority IAddon.AddonType => ModLoadPriority.Important;
3169

70+
internal static ModsConfig ModsConfig =>
71+
(ModsConfig)Config.baseConfigurations[nameof(ModsConfig)];
72+
3273
void IAddon.FinalizeAddon()
33-
{
34-
if (Config.MainConfig.StartKernelMods)
35-
ModManager.StartMods();
36-
}
74+
{ }
3775

3876
void IAddon.StartAddon()
3977
{
40-
78+
var config = new ModsConfig();
79+
ConfigTools.RegisterBaseSetting(config);
80+
CommandManager.RegisterAddonCommands(ShellType.Shell, [.. addonCommands]);
4181
}
4282

4383
void IAddon.StopAddon()
44-
{ }
84+
{
85+
CommandManager.UnregisterAddonCommands(ShellType.Shell, [.. addonCommands.Select((ci) => ci.Command)]);
86+
ConfigTools.UnregisterBaseSetting(nameof(ModsConfig));
87+
}
4588
}
4689
}

public/Nitrocid.Addons/Nitrocid.Extras.Mods/Nitrocid.Extras.Mods.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<DefineDebug>false</DefineDebug>
2424
<Optimize>true</Optimize>
2525
</PropertyGroup>
26+
<ItemGroup>
27+
<EmbeddedResource Include="Resources\ModsSettings.json" />
28+
</ItemGroup>
2629
<ItemGroup>
2730
<ProjectReference Include="..\..\..\private\Nitrocid.LocaleChecker\Nitrocid.LocaleChecker.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
2831
<ProjectReference Include="..\..\Nitrocid\Nitrocid.csproj" Private="false" />
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[
2+
{
3+
"Name": "Mods",
4+
"Desc": "This section lets you configure how the kernel modification system works.",
5+
"Keys": [
6+
{
7+
"Name": "Show the mod commands count on help",
8+
"Type": "SBoolean",
9+
"Variable": "ShowModCommandsCount",
10+
"Description": "Show the count of kernel modification commands when listing them in the help command"
11+
},
12+
{
13+
"Name": "Start kernel modifications on boot",
14+
"Type": "SBoolean",
15+
"Variable": "StartKernelMods",
16+
"Description": "Automatically start the kernel modifications on boot."
17+
},
18+
{
19+
"Name": "Allow loading untrusted mods",
20+
"Type": "SBoolean",
21+
"Variable": "AllowUntrustedMods",
22+
"Description": "If set to true, the kernel won't error out upon loading mods that don't have the signed public key."
23+
},
24+
{
25+
"Name": "Blacklisted mods",
26+
"Type": "SList",
27+
"Variable": "BlacklistedModsString",
28+
"SelectionFunctionName": "GetBlacklistedMods",
29+
"SelectionFunctionType": "ModManager",
30+
"Delimiter": ";",
31+
"IsValuePath": true,
32+
"IsPathCurrentPath": false,
33+
"ValuePathType": "Mods",
34+
"Description": "Write the filenames of the mods that will not run on startup. When you're finished, write \"q\". Write a minus sign next to the path to remove an existing mod."
35+
}
36+
]
37+
}
38+
]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// Nitrocid KS Copyright (C) 2018-2025 Aptivi
3+
//
4+
// This file is part of Nitrocid KS
5+
//
6+
// Nitrocid KS is free software: you can redistribute it and/or modify
7+
// it under the terms of the GNU General Public License as published by
8+
// the Free Software Foundation, either version 3 of the License, or
9+
// (at your option) any later version.
10+
//
11+
// Nitrocid KS is distributed in the hope that it will be useful,
12+
// but WITHOUT ANY WARRANTY, without even the implied warranty of
13+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
// GNU General Public License for more details.
15+
//
16+
// You should have received a copy of the GNU General Public License
17+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
//
19+
20+
using Newtonsoft.Json;
21+
using Nitrocid.Kernel.Configuration;
22+
using Nitrocid.Kernel.Configuration.Instances;
23+
using Nitrocid.Kernel.Configuration.Settings;
24+
using Nitrocid.Kernel.Exceptions;
25+
using Nitrocid.Languages;
26+
using Nitrocid.Misc.Reflection.Internal;
27+
using Nitrocid.Shell.Prompts;
28+
29+
namespace Nitrocid.Extras.Mods.Settings
30+
{
31+
/// <summary>
32+
/// Configuration instance for Mods
33+
/// </summary>
34+
public class ModsConfig : BaseKernelConfig, IKernelConfig
35+
{
36+
/// <inheritdoc/>
37+
[JsonIgnore]
38+
public override SettingsEntry[] SettingsEntries =>
39+
ConfigTools.GetSettingsEntries(ResourcesManager.GetData("ModsSettings.json", ResourcesType.Misc, typeof(ModsConfig).Assembly) ??
40+
throw new KernelException(KernelExceptionType.Config, Translate.DoTranslation("Failed to obtain settings entries.")));
41+
42+
/// <summary>
43+
/// Automatically start the kernel modifications on boot.
44+
/// </summary>
45+
public bool StartKernelMods { get; set; }
46+
/// <summary>
47+
/// Allow untrusted mods
48+
/// </summary>
49+
public bool AllowUntrustedMods { get; set; }
50+
/// <summary>
51+
/// Write the filenames of the mods that will not run on startup. When you're finished, write "q". Write a minus sign next to the path to remove an existing mod.
52+
/// </summary>
53+
public string BlacklistedModsString { get; set; } = "";
54+
/// <summary>
55+
/// Show the mod commands count on help
56+
/// </summary>
57+
public bool ShowModCommandsCount { get; set; } = true;
58+
}
59+
}

public/Nitrocid.Templates/templates/KSMod/ModName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class ModName : IMod
1111

1212
public string Version => "1.0.0";
1313

14-
public Version MinimumSupportedApiVersion => new(3, 0, 27, 28);
14+
public Version MinimumSupportedApiVersion => new(3, 0, 27, 30);
1515

1616
public ModLoadPriority LoadPriority => ModLoadPriority.Optional;
1717

public/Nitrocid/Kernel/Configuration/Instances/KernelMainConfig.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,6 @@ public string CurrentLanguage
104104
/// </summary>
105105
public bool ShowStageFinishTimes { get; set; }
106106
/// <summary>
107-
/// Automatically start the kernel modifications on boot.
108-
/// </summary>
109-
public bool StartKernelMods { get; set; }
110-
/// <summary>
111107
/// Shows the current time, time zone, and date before logging in.
112108
/// </summary>
113109
public bool ShowCurrentTimeBeforeLogin { get; set; } = true;
@@ -160,10 +156,6 @@ public string CurrentLanguage
160156
/// </summary>
161157
public bool DevNoticeConsented { get; set; }
162158
/// <summary>
163-
/// Allow untrusted mods
164-
/// </summary>
165-
public bool AllowUntrustedMods { get; set; }
166-
/// <summary>
167159
/// Whether to use the operating system time zone or to use the kernel-wide time zone
168160
/// </summary>
169161
public bool UseSystemTimeZone
@@ -1237,10 +1229,6 @@ public int HexEditAutoSaveInterval
12371229
/// </summary>
12381230
public bool DrawBorderNotification { get; set; } = true;
12391231
/// <summary>
1240-
/// Write the filenames of the mods that will not run on startup. When you're finished, write "q". Write a minus sign next to the path to remove an existing mod.
1241-
/// </summary>
1242-
public string BlacklistedModsString { get; set; } = "";
1243-
/// <summary>
12441232
/// A character that resembles the upper left corner. Be sure to only input one character
12451233
/// </summary>
12461234
public char NotifyUpperLeftCornerChar
@@ -1321,10 +1309,6 @@ public char NotifyRightFrameChar
13211309
/// </summary>
13221310
public bool ShowShellCommandsCount { get; set; } = true;
13231311
/// <summary>
1324-
/// Show the mod commands count on help
1325-
/// </summary>
1326-
public bool ShowModCommandsCount { get; set; } = true;
1327-
/// <summary>
13281312
/// Show the aliases count on help
13291313
/// </summary>
13301314
public bool ShowShellAliasesCount { get; set; } = true;

0 commit comments

Comments
 (0)