Create wrapper for SptMod with assembly and package.json

This commit is contained in:
CWX
2025-02-07 21:20:53 +00:00
parent c7aea64a34
commit d6925e492c
5 changed files with 127 additions and 30 deletions
+34
View File
@@ -0,0 +1,34 @@
{
"Name": "ChangeMe",
"Author": "ChangeMe",
"Version": "ChangeMe",
"SptVersion": "ChangeMe",
"Licence": "ChangeMe",
"IsBundleMod": false,
"Url": "ChangeMe",
"Contributors": [
"ChamgeMe"
],
"Main": "ChangeMe",
"DevDependencies": {
"ChangeMe": "ChangeMe"
},
"Scripts": {
"ChangeMe": "ChangeMe"
},
"Dependencies": {
"ChangeMe": "ChangeMe"
},
"ModDependencies": {
"ChangeMe": "ChangeMe"
},
"LoadAfter": [
"ChangeMe"
],
"LoadBefore": [
"ChangeMe"
],
"Incompatibilities": [
"ChangeMe"
]
}
@@ -4,118 +4,99 @@ namespace Core.Models.Spt.Mod;
public record PackageJsonData
{
[JsonPropertyName("incompatibilities")]
public List<string>? Incompatibilities
{
get;
set;
}
[JsonPropertyName("loadBefore")]
public List<string>? LoadBefore
{
get;
set;
}
[JsonPropertyName("loadAfter")]
public List<string>? LoadAfter
{
get;
set;
}
[JsonPropertyName("dependencies")]
public Dictionary<string, string>? Dependencies
{
get;
set;
}
[JsonPropertyName("modDependencies")]
public Dictionary<string, string>? ModDependencies
{
get;
set;
}
[JsonPropertyName("name")]
public string? Name
{
get;
set;
}
[JsonPropertyName("url")]
public string? Url
{
get;
set;
}
[JsonPropertyName("author")]
public string? Author
{
get;
set;
}
[JsonPropertyName("version")]
public string? Version
{
get;
set;
}
[JsonPropertyName("sptVersion")]
public string? SptVersion
{
get;
set;
}
// We deliberately purge this data
[JsonPropertyName("scripts")]
public Dictionary<string, string>? Scripts
{
get;
set;
}
[JsonPropertyName("devDependencies")]
public Dictionary<string, string>? DevDependencies
{
get;
set;
}
[JsonPropertyName("licence")]
public string? Licence
{
get;
set;
}
[JsonPropertyName("main")]
public string? Main
{
get;
set;
}
[JsonPropertyName("isBundleMod")]
public bool? IsBundleMod
{
get;
set;
}
[JsonPropertyName("contributors")]
public List<string>? Contributors
{
get;
set;
}
}
// TODO: this will need changing to however we implement it in this project
+13
View File
@@ -0,0 +1,13 @@
using System.Reflection;
using System.Text.Json.Serialization;
namespace Core.Models.Spt.Mod;
public class SptMod
{
[JsonPropertyName("PackageJson")]
public PackageJsonData PackageJson { get; set; }
[JsonPropertyName("Assembly")]
public Assembly Assembly { get; set; }
}
+75 -7
View File
@@ -1,33 +1,101 @@
using System.Reflection;
using System.Text.Json;
using Core.Models.Spt.Mod;
using Core.Models.Utils;
namespace Server;
public class ModDllLoader
{
private const string ModPath = "./user/mods/";
private static ISptLogger<ModDllLoader> _logger;
public static List<Assembly> LoadAllMods()
public ModDllLoader(ISptLogger<ModDllLoader> logger)
{
_logger = logger;
}
public static List<SptMod> LoadAllMods()
{
if (!Directory.Exists(ModPath))
{
Directory.CreateDirectory(ModPath);
}
var mods = new List<Assembly>();
foreach (var file in Directory.GetFiles(ModPath, "*.dll", SearchOption.AllDirectories))
var mods = new List<SptMod>();
// foreach directory in /user/mods/
// treat this as the MOD
// should contain a dll and Package.json
// load both
// if either is missing Throw Warning and skip
var modDirectories = Directory.GetDirectories(ModPath);
foreach (var modDirectory in modDirectories)
{
try
{
mods.Add(Assembly.LoadFile(Path.GetFullPath(file)));
var name = file.Split(Path.DirectorySeparatorChar);
Console.WriteLine($"Loaded {name[^1]}");
mods.Add(LoadMod(modDirectory));
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine(e.Message);
}
}
return mods;
}
private static SptMod? LoadMod(string path)
{
var result = new SptMod();
var asmCount = 0;
var packCount = 0;
foreach (var file in new DirectoryInfo(path).GetFiles()) // only search top level
{
if (file.Name.ToLower() == "package.json")
{
packCount++;
// deal with package.json
var jjson = File.ReadAllText(file.FullName);
var json = JsonSerializer.Deserialize<PackageJsonData>(jjson);
result.PackageJson = json;
if (packCount > 1)
{
throw new Exception($"More than one package.json file found in path: {path}");
}
}
if (file.Extension.ToLower() == ".dll")
{
asmCount++;
result.Assembly = Assembly.LoadFile(Path.GetFullPath(file.FullName));
if (asmCount > 1)
{
throw new Exception($"More than one Assembly found in {path}");
}
}
}
if (packCount == 0)
{
throw new Exception($"No package.json found in path: {Path.GetFullPath(path)}");
}
if (asmCount == 0)
{
throw new Exception($"No Assemblies found in path: {Path.GetFullPath(path)}");
}
if (result.Assembly is not null && result.PackageJson is not null)
{
Console.WriteLine($"Loaded {result.PackageJson.Name}");
}
return result;
}
}
+5 -4
View File
@@ -1,5 +1,6 @@
using System.Runtime;
using Core.Context;
using Core.Models.Enums;
using Core.Models.External;
using Core.Models.Spt.Config;
using Core.Servers;
@@ -16,8 +17,8 @@ public static class Program
{
public static void Main(string[] args)
{
var assemblies = ModDllLoader.LoadAllMods();
HarmonyBootstrapper.LoadAllPatches(assemblies);
var mods = ModDllLoader.LoadAllMods();
// HarmonyBootstrapper.LoadAllPatches(assemblies);
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
@@ -28,7 +29,7 @@ public static class Program
ProgramStatics.Initialize();
DependencyInjectionRegistrator.RegisterSptComponents(typeof(Program).Assembly, typeof(App).Assembly, builder.Services);
DependencyInjectionRegistrator.RegisterModOverrideComponents(builder.Services, assemblies);
DependencyInjectionRegistrator.RegisterModOverrideComponents(builder.Services, mods.Select(a => a.Assembly).ToList());
var logger = new SerilogLoggerProvider(registeredLogger).CreateLogger("Server");
try
{
@@ -46,7 +47,7 @@ public static class Program
var appContext = serviceProvider.GetService<ApplicationContext>();
// Add the Loaded Mod Assemblies for later
appContext?.AddValue(ContextVariableType.LOADED_MOD_ASSEMBLIES, assemblies);
appContext?.AddValue(ContextVariableType.LOADED_MOD_ASSEMBLIES, mods);
// This is the builder that will get use by the HttpServer to start up the web application
appContext?.AddValue(ContextVariableType.APP_BUILDER, builder);