public ApplicationManager(ILogger <ApplicationManager> logger, IMiddlewareActionHandler actionHandler, IEnumerable <IManagerCommand> commands, ITranslationLookup translationLookup, IConfigurationHandler <CommandConfiguration> commandConfiguration, IConfigurationHandler <ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory, IEnumerable <IPlugin> plugins, IParserRegexFactory parserRegexFactory, IEnumerable <IRegisterEvent> customParserEvents, IEventHandler eventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory, IMetaService metaService, IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver, ClientService clientService, IServiceProvider serviceProvider, ChangeHistoryService changeHistoryService, ApplicationConfiguration appConfig, PenaltyService penaltyService) { MiddlewareActionHandler = actionHandler; _servers = new ConcurrentBag <Server>(); MessageTokens = new List <MessageToken>(); ClientSvc = clientService; PenaltySvc = penaltyService; ConfigHandler = appConfigHandler; StartTime = DateTime.UtcNow; PageList = new PageList(); AdditionalEventParsers = new List <IEventParser>() { new BaseEventParser(parserRegexFactory, logger, _appConfig) }; AdditionalRConParsers = new List <IRConParser>() { new BaseRConParser(serviceProvider.GetRequiredService <ILogger <BaseRConParser> >(), parserRegexFactory) }; TokenAuthenticator = new TokenAuthentication(); _logger = logger; _metaService = metaService; _tokenSource = new CancellationTokenSource(); _commands = commands.ToList(); _translationLookup = translationLookup; _commandConfiguration = commandConfiguration; _serverInstanceFactory = serverInstanceFactory; _parserRegexFactory = parserRegexFactory; _customParserEvents = customParserEvents; _eventHandler = eventHandler; _scriptCommandFactory = scriptCommandFactory; _metaRegistration = metaRegistration; _scriptPluginServiceResolver = scriptPluginServiceResolver; _serviceProvider = serviceProvider; _changeHistoryService = changeHistoryService; _appConfig = appConfig; Plugins = plugins; }
public async Task Initialize(IManager manager, IScriptCommandFactory scriptCommandFactory, IScriptPluginServiceResolver serviceResolver) { await _onProcessing.WaitAsync(); try { // for some reason we get an event trigger when the file is not finished being modified. // this must have been a change in .NET CORE 3.x // so if the new file is empty we can't process it yet if (new FileInfo(_fileName).Length == 0L) { return; } bool firstRun = _scriptEngine == null; // it's been loaded before so we need to call the unload event if (!firstRun) { await OnUnloadAsync(); foreach (string commandName in _registeredCommandNames) { manager.GetLogger(0).WriteDebug($"Removing plugin registered command \"{commandName}\""); manager.RemoveCommandByName(commandName); } _registeredCommandNames.Clear(); } successfullyLoaded = false; string script; using (var stream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var reader = new StreamReader(stream, Encoding.Default)) { script = await reader.ReadToEndAsync(); } } _scriptEngine = new Engine(cfg => cfg.AllowClr(new[] { typeof(System.Net.Http.HttpClient).Assembly, typeof(EFClient).Assembly, typeof(Utilities).Assembly, typeof(Encoding).Assembly }) .CatchClrExceptions()); _scriptEngine.Execute(script); _scriptEngine.SetValue("_localization", Utilities.CurrentLocalization); _scriptEngine.SetValue("_serviceResolver", serviceResolver); dynamic pluginObject = _scriptEngine.GetValue("plugin").ToObject(); Author = pluginObject.author; Name = pluginObject.name; Version = (float)pluginObject.version; var commands = _scriptEngine.GetValue("commands"); if (commands != JsValue.Undefined) { try { foreach (var command in GenerateScriptCommands(commands, scriptCommandFactory)) { manager.GetLogger(0).WriteDebug($"Adding plugin registered command \"{command.Name}\""); manager.AddAdditionalCommand(command); _registeredCommandNames.Add(command.Name); } } catch (RuntimeBinderException e) { throw new PluginException($"Not all required fields were found: {e.Message}") { PluginFile = _fileName }; } } await OnLoadAsync(manager); try { if (pluginObject.isParser) { IsParser = true; IEventParser eventParser = (IEventParser)_scriptEngine.GetValue("eventParser").ToObject(); IRConParser rconParser = (IRConParser)_scriptEngine.GetValue("rconParser").ToObject(); manager.AdditionalEventParsers.Add(eventParser); manager.AdditionalRConParsers.Add(rconParser); } } catch (RuntimeBinderException) { } if (!firstRun) { await OnLoadAsync(manager); } 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; } finally { if (_onProcessing.CurrentCount == 0) { _onProcessing.Release(1); } } }
/// <summary> /// finds declared script commands in the script plugin /// </summary> /// <param name="commands">commands value from jint parser</param> /// <param name="scriptCommandFactory">factory to create the command from</param> /// <returns></returns> public IEnumerable <IManagerCommand> GenerateScriptCommands(JsValue commands, IScriptCommandFactory scriptCommandFactory) { List <IManagerCommand> commandList = new List <IManagerCommand>(); // go through each defined command foreach (var command in commands.AsArray()) { dynamic dynamicCommand = command.ToObject(); string name = dynamicCommand.name; string alias = dynamicCommand.alias; string description = dynamicCommand.description; string permission = dynamicCommand.permission; bool targetRequired = false; List <(string, bool)> args = new List <(string, bool)>(); dynamic arguments = null; try { arguments = dynamicCommand.arguments; } catch (RuntimeBinderException) { // arguments are optional } try { targetRequired = dynamicCommand.targetRequired; } catch (RuntimeBinderException) { // arguments are optional } if (arguments != null) { foreach (var arg in dynamicCommand.arguments) { args.Add((arg.name, (bool)arg.required)); } } void execute(GameEvent e) { _scriptEngine.SetValue("_event", e); var jsEventObject = _scriptEngine.GetValue("_event"); try { dynamicCommand.execute.Target.Invoke(jsEventObject); } catch (JavaScriptException ex) { throw new PluginException($"An error occured while executing action for script plugin: {ex.Error} (Line: {ex.Location.Start.Line}, Character: {ex.Location.Start.Column})") { PluginFile = _fileName }; } } commandList.Add(scriptCommandFactory.CreateScriptCommand(name, alias, description, permission, targetRequired, args, execute)); } return(commandList); }