diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index 5a2d17f34..135e02562 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -67,13 +67,14 @@ public class ApplicationManager : IManager private readonly IEventHandler _eventHandler; private readonly IScriptCommandFactory _scriptCommandFactory; private readonly IMetaRegistration _metaRegistration; + private readonly IScriptPluginServiceResolver _scriptPluginServiceResolver; public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler, IEnumerable commands, ITranslationLookup translationLookup, IConfigurationHandler commandConfiguration, IConfigurationHandler appConfigHandler, IGameServerInstanceFactory serverInstanceFactory, IEnumerable plugins, IParserRegexFactory parserRegexFactory, IEnumerable customParserEvents, IEventHandler eventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory, IMetaService metaService, - IMetaRegistration metaRegistration) + IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver) { MiddlewareActionHandler = actionHandler; _servers = new ConcurrentBag(); @@ -100,6 +101,7 @@ public class ApplicationManager : IManager _eventHandler = eventHandler; _scriptCommandFactory = scriptCommandFactory; _metaRegistration = metaRegistration; + _scriptPluginServiceResolver = scriptPluginServiceResolver; Plugins = plugins; } @@ -277,12 +279,12 @@ public async Task Init() { if (plugin is ScriptPlugin scriptPlugin) { - await scriptPlugin.Initialize(this, _scriptCommandFactory); + await scriptPlugin.Initialize(this, _scriptCommandFactory, _scriptPluginServiceResolver); scriptPlugin.Watcher.Changed += async (sender, e) => { try { - await scriptPlugin.Initialize(this, _scriptCommandFactory); + await scriptPlugin.Initialize(this, _scriptCommandFactory, _scriptPluginServiceResolver); } catch (Exception ex) diff --git a/Application/Main.cs b/Application/Main.cs index bb91e45c9..9cdce81e5 100644 --- a/Application/Main.cs +++ b/Application/Main.cs @@ -249,6 +249,7 @@ private static IServiceCollection ConfigureServices(string[] args) .AddSingleton, ClientService>() .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton, ReceivedPenaltyResourceQueryHelper>() .AddSingleton, AdministeredPenaltyResourceQueryHelper>() .AddSingleton, UpdatedAliasResourceQueryHelper>() diff --git a/Application/Misc/ScriptPlugin.cs b/Application/Misc/ScriptPlugin.cs index 170edb44a..4a692d04f 100644 --- a/Application/Misc/ScriptPlugin.cs +++ b/Application/Misc/ScriptPlugin.cs @@ -61,7 +61,7 @@ public ScriptPlugin(string filename, string workingDirectory = null) _onProcessing.Dispose(); } - public async Task Initialize(IManager manager, IScriptCommandFactory scriptCommandFactory) + public async Task Initialize(IManager manager, IScriptCommandFactory scriptCommandFactory, IScriptPluginServiceResolver serviceResolver) { await _onProcessing.WaitAsync(); @@ -114,6 +114,7 @@ public async Task Initialize(IManager manager, IScriptCommandFactory scriptComma _scriptEngine.Execute(script); _scriptEngine.SetValue("_localization", Utilities.CurrentLocalization); + _scriptEngine.SetValue("_serviceResolver", serviceResolver); dynamic pluginObject = _scriptEngine.GetValue("plugin").ToObject(); Author = pluginObject.author; @@ -164,6 +165,11 @@ public async Task Initialize(IManager manager, IScriptCommandFactory scriptComma successfullyLoaded = true; } + catch (JavaScriptException ex) + { + throw new PluginException($"An error occured while initializing script plugin: {ex.Error} (Line: {ex.Location.Start.Line}, Character: {ex.Location.Start.Column})") { PluginFile = _fileName }; + } + catch { throw; diff --git a/Application/Misc/ScriptPluginServiceResolver.cs b/Application/Misc/ScriptPluginServiceResolver.cs new file mode 100644 index 000000000..f8f308ac7 --- /dev/null +++ b/Application/Misc/ScriptPluginServiceResolver.cs @@ -0,0 +1,31 @@ +using SharedLibraryCore.Interfaces; +using System; +using System.Linq; + +namespace IW4MAdmin.Application.Misc +{ + /// + /// implementation of IScriptPluginServiceResolver + /// + public class ScriptPluginServiceResolver : IScriptPluginServiceResolver + { + private readonly IServiceProvider _serviceProvider; + + public ScriptPluginServiceResolver(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public object ResolveService(string serviceName) + { + var serviceType = typeof(IScriptPluginServiceResolver).Assembly.GetTypes().FirstOrDefault(_type => _type.Name == serviceName); + + if (serviceType == null) + { + throw new InvalidOperationException($"No service type '{serviceName}' defined in IW4MAdmin assembly"); + } + + return _serviceProvider.GetService(serviceType); + } + } +} diff --git a/Plugins/ScriptPlugins/SampleScriptPluginCommand.js b/Plugins/ScriptPlugins/SampleScriptPluginCommand.js index 0b8ee4f05..b80724dad 100644 --- a/Plugins/ScriptPlugins/SampleScriptPluginCommand.js +++ b/Plugins/ScriptPlugins/SampleScriptPluginCommand.js @@ -44,6 +44,8 @@ let plugin = { }, onLoadAsync: function (manager) { + this.logger = _serviceResolver.ResolveService("ILogger"); + this.logger.WriteDebug("sample plugin loaded"); }, onUnloadAsync: function () { diff --git a/SharedLibraryCore/Interfaces/IScriptPluginServiceResolver.cs b/SharedLibraryCore/Interfaces/IScriptPluginServiceResolver.cs new file mode 100644 index 000000000..08883074d --- /dev/null +++ b/SharedLibraryCore/Interfaces/IScriptPluginServiceResolver.cs @@ -0,0 +1,10 @@ +namespace SharedLibraryCore.Interfaces +{ + /// + /// interface used to dynamically resolve services by string name + /// + public interface IScriptPluginServiceResolver + { + object ResolveService(string serviceName); + } +}