Make mod loading non nullable, set certain properties to be read only after init (#506)
* Make mod loading non nullable, set certain properties to be read only after init - Breaks all mods, will require new nugets * Make mod assembly list IEnumerable * Convert checks to IsNullOrEmpty * Update comment, enforce ModGuid
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of metadata used to determine things such as author, version,
|
||||
/// pre-defined load order and incompatibilities. This record is required to be overriden by all mods.
|
||||
/// pre-defined load order and incompatibilities. This record is required to be overridden by all mods.
|
||||
/// All properties must be overridden. For properties, that you don't need, just assign null.
|
||||
/// </summary>
|
||||
public abstract record AbstractModMetadata
|
||||
@@ -13,17 +13,17 @@ public abstract record AbstractModMetadata
|
||||
/// It is recommended (but not mandatory) to use
|
||||
/// <see href="https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html">reverse domain name notation</see>.
|
||||
/// </summary>
|
||||
public abstract string ModGuid { get; set; }
|
||||
public abstract string ModGuid { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of this mod
|
||||
/// </summary>
|
||||
public abstract string Name { get; set; }
|
||||
public abstract string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Your username
|
||||
/// </summary>
|
||||
public abstract string Author { get; set; }
|
||||
public abstract string Author { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// People who have contributed to this mod
|
||||
@@ -33,12 +33,12 @@ public abstract record AbstractModMetadata
|
||||
/// <summary>
|
||||
/// Semantic version of this mod, this uses the semver standard
|
||||
/// </summary>
|
||||
public abstract string Version { get; set; }
|
||||
public abstract string Version { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// SPT version this mod was built for
|
||||
/// </summary>
|
||||
public abstract string SptVersion { get; set; }
|
||||
public abstract string SptVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// List of mods this mod should load before
|
||||
@@ -75,5 +75,5 @@ public abstract record AbstractModMetadata
|
||||
/// <summary>
|
||||
/// Name of the license this mod uses
|
||||
/// </summary>
|
||||
public abstract string? Licence { get; set; }
|
||||
public abstract string License { get; init; }
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ public class SptMod
|
||||
public Dictionary<string, object>? ExtensionData { get; set; }
|
||||
|
||||
[JsonPropertyName("directory")]
|
||||
public string Directory { get; set; }
|
||||
public required string Directory { get; init; }
|
||||
|
||||
[JsonPropertyName("modMetadata")]
|
||||
public AbstractModMetadata? ModMetadata { get; set; }
|
||||
public required AbstractModMetadata ModMetadata { get; init; }
|
||||
|
||||
[JsonPropertyName("assemblies")]
|
||||
public List<Assembly>? Assemblies { get; set; }
|
||||
public required IEnumerable<Assembly> Assemblies { get; init; }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ using Microsoft.Extensions.Hosting;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.DI;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
using SPTarkov.Server.Core.Servers;
|
||||
@@ -24,8 +23,7 @@ public class App(
|
||||
DatabaseService _databaseService,
|
||||
IHostApplicationLifetime _appLifeTime,
|
||||
IEnumerable<IOnLoad> _onLoadComponents,
|
||||
IEnumerable<IOnUpdate> _onUpdateComponents,
|
||||
HttpServerHelper _httpServerHelper
|
||||
IEnumerable<IOnUpdate> _onUpdateComponents
|
||||
)
|
||||
{
|
||||
protected readonly CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>();
|
||||
|
||||
@@ -53,14 +53,12 @@ public class ModDllLoader
|
||||
/// <returns>SptMod</returns>
|
||||
private static SptMod LoadMod(string path)
|
||||
{
|
||||
var result = new SptMod { Directory = path, Assemblies = [] };
|
||||
var assemblyCount = 0;
|
||||
List<Assembly> assemblyList = [];
|
||||
foreach (var file in new DirectoryInfo(path).GetFiles()) // Only search top level
|
||||
{
|
||||
if (string.Equals(file.Extension, ".dll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
assemblyCount++;
|
||||
result.Assemblies.Add(
|
||||
assemblyList.Add(
|
||||
AssemblyLoadContext.Default.LoadFromAssemblyPath(
|
||||
Path.GetFullPath(file.FullName)
|
||||
)
|
||||
@@ -68,30 +66,29 @@ public class ModDllLoader
|
||||
}
|
||||
}
|
||||
|
||||
if (assemblyCount == 0)
|
||||
if (assemblyList.Count == 0)
|
||||
{
|
||||
throw new Exception($"No Assemblies found in path: {Path.GetFullPath(path)}");
|
||||
}
|
||||
|
||||
result.ModMetadata = LoadModMetadata(result.Assemblies, path);
|
||||
|
||||
if (result.ModMetadata == null)
|
||||
SptMod result = new()
|
||||
{
|
||||
throw new Exception(
|
||||
$"Failed to load mod metadata for: {Path.GetFullPath(path)} \ndid you override `AbstractModMetadata`?"
|
||||
);
|
||||
}
|
||||
Directory = path,
|
||||
Assemblies = assemblyList,
|
||||
ModMetadata = LoadModMetadata(assemblyList, path),
|
||||
};
|
||||
|
||||
if (
|
||||
result.ModMetadata?.Name == null
|
||||
|| result.ModMetadata?.Author == null
|
||||
|| result.ModMetadata?.Version == null
|
||||
|| result.ModMetadata?.Licence == null
|
||||
|| result.ModMetadata?.SptVersion == null
|
||||
string.IsNullOrEmpty(result.ModMetadata.ModGuid)
|
||||
|| string.IsNullOrEmpty(result.ModMetadata.Name)
|
||||
|| string.IsNullOrEmpty(result.ModMetadata.Author)
|
||||
|| string.IsNullOrEmpty(result.ModMetadata.Version)
|
||||
|| string.IsNullOrEmpty(result.ModMetadata.License)
|
||||
|| string.IsNullOrEmpty(result.ModMetadata.SptVersion)
|
||||
)
|
||||
{
|
||||
throw new Exception(
|
||||
$"The mod metadata for: {Path.GetFullPath(path)} is missing one of these properties: name, author, licence, version or sptVersion"
|
||||
$"The mod metadata for: {Path.GetFullPath(path)} is missing one of these properties: ModGuid, Name, Author, License, Version or SptVersion"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -105,7 +102,7 @@ public class ModDllLoader
|
||||
/// <param name="path">Path of the mod directory</param>
|
||||
/// <returns>Mod metadata</returns>
|
||||
/// <exception cref="Exception">Thrown if duplicate metadata implementations are found</exception>
|
||||
private static AbstractModMetadata? LoadModMetadata(List<Assembly> assemblies, string path)
|
||||
private static AbstractModMetadata LoadModMetadata(List<Assembly> assemblies, string path)
|
||||
{
|
||||
AbstractModMetadata? result = null;
|
||||
|
||||
@@ -131,6 +128,13 @@ public class ModDllLoader
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Failed to load mod metadata for: {Path.GetFullPath(path)} \ndid you override `AbstractModMetadata`?"
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user