allow Kekno to run with sv_running not returning anything :upside_down:
make sure script plugins output correct errors instead of being swallowed prevent webfront error when webfront tab is left open on a server no longer being modified
This commit is contained in:
parent
c6d6bebeab
commit
06cdaef8a4
@ -5,7 +5,7 @@
|
|||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||||
<Version>2.3.1.0</Version>
|
<Version>2.3.2.0</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Product>IW4MAdmin</Product>
|
<Product>IW4MAdmin</Product>
|
||||||
|
@ -256,9 +256,25 @@ namespace IW4MAdmin.Application
|
|||||||
if (plugin is ScriptPlugin scriptPlugin)
|
if (plugin is ScriptPlugin scriptPlugin)
|
||||||
{
|
{
|
||||||
await scriptPlugin.Initialize(this);
|
await scriptPlugin.Initialize(this);
|
||||||
|
scriptPlugin.Watcher.Changed += async (sender, e) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await scriptPlugin.Initialize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.WriteError(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_IMPORTER_ERROR"].FormatExt(scriptPlugin.Name));
|
||||||
|
Logger.WriteDebug(ex.Message);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await plugin.OnLoadAsync(this);
|
else
|
||||||
|
{
|
||||||
|
await plugin.OnLoadAsync(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -881,9 +881,9 @@ namespace IW4MAdmin
|
|||||||
Version = RconParser.Version;
|
Version = RconParser.Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
var svRunning = await this.GetDvarAsync<int>("sv_running");
|
var svRunning = await this.GetDvarAsync<string>("sv_running");
|
||||||
|
|
||||||
if (svRunning.Value == 0)
|
if (!string.IsNullOrEmpty(svRunning.Value) && svRunning.Value != "1")
|
||||||
{
|
{
|
||||||
throw new ServerException(loc["SERVER_ERROR_NOT_RUNNING"]);
|
throw new ServerException(loc["SERVER_ERROR_NOT_RUNNING"]);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.Exceptions;
|
|||||||
using SharedLibraryCore.Helpers;
|
using SharedLibraryCore.Helpers;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -68,30 +69,9 @@ namespace IW4MAdmin.Application
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var services = ConfigureServices();
|
var services = ConfigureServices();
|
||||||
|
|
||||||
using (var builder = services.BuildServiceProvider())
|
|
||||||
{
|
|
||||||
translationLookup = builder.GetRequiredService<ITranslationLookup>();
|
|
||||||
var importer = builder.GetRequiredService<IPluginImporter>();
|
|
||||||
importer.Load();
|
|
||||||
|
|
||||||
foreach (var type in importer.CommandTypes)
|
|
||||||
{
|
|
||||||
services.AddTransient(typeof(IManagerCommand), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var commandDefinition in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes()
|
|
||||||
.Where(_command => _command.BaseType == typeof(Command)))
|
|
||||||
{
|
|
||||||
services.AddTransient(typeof(IManagerCommand), commandDefinition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceProvider = services.BuildServiceProvider();
|
serviceProvider = services.BuildServiceProvider();
|
||||||
var pluginImporter = serviceProvider.GetRequiredService<IPluginImporter>();
|
|
||||||
pluginImporter.Load();
|
|
||||||
|
|
||||||
ServerManager = (ApplicationManager)serviceProvider.GetRequiredService<IManager>();
|
ServerManager = (ApplicationManager)serviceProvider.GetRequiredService<IManager>();
|
||||||
|
translationLookup = serviceProvider.GetRequiredService<ITranslationLookup>();
|
||||||
|
|
||||||
// do any needed housekeeping file/folder migrations
|
// do any needed housekeeping file/folder migrations
|
||||||
ConfigurationMigration.MoveConfigFolder10518(null);
|
ConfigurationMigration.MoveConfigFolder10518(null);
|
||||||
@ -283,8 +263,8 @@ namespace IW4MAdmin.Application
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static IServiceCollection ConfigureServices()
|
private static IServiceCollection ConfigureServices()
|
||||||
{
|
{
|
||||||
var serviceProvider = new ServiceCollection();
|
var serviceCollection = new ServiceCollection();
|
||||||
serviceProvider.AddSingleton<IManager, ApplicationManager>()
|
serviceCollection.AddSingleton<IServiceCollection>(_serviceProvider => serviceCollection)
|
||||||
.AddSingleton(new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings") as IConfigurationHandler<ApplicationConfiguration>)
|
.AddSingleton(new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings") as IConfigurationHandler<ApplicationConfiguration>)
|
||||||
.AddSingleton(new BaseConfigurationHandler<CommandConfiguration>("CommandConfiguration") as IConfigurationHandler<CommandConfiguration>)
|
.AddSingleton(new BaseConfigurationHandler<CommandConfiguration>("CommandConfiguration") as IConfigurationHandler<CommandConfiguration>)
|
||||||
.AddSingleton(_serviceProvider => _serviceProvider.GetRequiredService<IConfigurationHandler<ApplicationConfiguration>>().Configuration())
|
.AddSingleton(_serviceProvider => _serviceProvider.GetRequiredService<IConfigurationHandler<ApplicationConfiguration>>().Configuration())
|
||||||
@ -292,14 +272,27 @@ namespace IW4MAdmin.Application
|
|||||||
.AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager"))
|
.AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager"))
|
||||||
.AddSingleton<IPluginImporter, PluginImporter>()
|
.AddSingleton<IPluginImporter, PluginImporter>()
|
||||||
.AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>()
|
.AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>()
|
||||||
|
.AddTransient(_serviceProvider =>
|
||||||
|
{
|
||||||
|
var importer = _serviceProvider.GetRequiredService<IPluginImporter>();
|
||||||
|
var config = _serviceProvider.GetRequiredService<CommandConfiguration>();
|
||||||
|
var layout = _serviceProvider.GetRequiredService<ITranslationLookup>();
|
||||||
|
|
||||||
|
// todo: this is disgusting, but I need it until I can figure out a way to dynamically load the plugins without creating an instance.
|
||||||
|
return importer.CommandTypes.
|
||||||
|
Union(typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes()
|
||||||
|
.Where(_command => _command.BaseType == typeof(Command)))
|
||||||
|
.Select(_cmdType => Activator.CreateInstance(_cmdType, config, layout) as IManagerCommand);
|
||||||
|
})
|
||||||
.AddSingleton(_serviceProvider =>
|
.AddSingleton(_serviceProvider =>
|
||||||
{
|
{
|
||||||
var config = _serviceProvider.GetRequiredService<IConfigurationHandler<ApplicationConfiguration>>().Configuration();
|
var config = _serviceProvider.GetRequiredService<IConfigurationHandler<ApplicationConfiguration>>().Configuration();
|
||||||
return Localization.Configure.Initialize(useLocalTranslation: config?.UseLocalTranslations ?? false,
|
return Localization.Configure.Initialize(useLocalTranslation: config?.UseLocalTranslations ?? false,
|
||||||
customLocale: config?.EnableCustomLocale ?? false ? (config.CustomLocale ?? "en-US") : "en-US");
|
customLocale: config?.EnableCustomLocale ?? false ? (config.CustomLocale ?? "en-US") : "en-US");
|
||||||
});
|
})
|
||||||
|
.AddSingleton<IManager, ApplicationManager>();
|
||||||
|
|
||||||
return serviceProvider;
|
return serviceCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,14 @@ namespace IW4MAdmin.Application.Helpers
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_translationLookup = translationLookup;
|
_translationLookup = translationLookup;
|
||||||
|
|
||||||
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads all the assembly and javascript plugins
|
/// Loads all the assembly and javascript plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Load()
|
private void Load()
|
||||||
{
|
{
|
||||||
string pluginDir = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}";
|
string pluginDir = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}";
|
||||||
string[] dllFileNames = null;
|
string[] dllFileNames = null;
|
||||||
|
@ -1315,7 +1315,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lists the loaded plugins
|
/// Lists the loaded plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ListPluginsCommand : Command
|
/*public class ListPluginsCommand : Command
|
||||||
{
|
{
|
||||||
private readonly IPluginImporter _pluginImporter;
|
private readonly IPluginImporter _pluginImporter;
|
||||||
public ListPluginsCommand(CommandConfiguration config, ITranslationLookup translationLookup, IPluginImporter pluginImporter) : base(config, translationLookup)
|
public ListPluginsCommand(CommandConfiguration config, ITranslationLookup translationLookup, IPluginImporter pluginImporter) : base(config, translationLookup)
|
||||||
@ -1337,7 +1337,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lists external IP
|
/// Lists external IP
|
||||||
|
@ -28,10 +28,5 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// All assemblies in the plugin folder
|
/// All assemblies in the plugin folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<Assembly> Assemblies { get; }
|
IList<Assembly> Assemblies { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads in plugin assemblies and script plugins
|
|
||||||
/// </summary>
|
|
||||||
void Load();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,46 +18,110 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public string Author { get; set; }
|
public string Author { get; set; }
|
||||||
|
|
||||||
|
public FileSystemWatcher Watcher { get; private set; }
|
||||||
|
|
||||||
private Engine ScriptEngine;
|
private Engine ScriptEngine;
|
||||||
private readonly string FileName;
|
private readonly string _fileName;
|
||||||
private IManager Manager;
|
|
||||||
private readonly FileSystemWatcher _watcher;
|
|
||||||
private readonly SemaphoreSlim _fileChanging;
|
private readonly SemaphoreSlim _fileChanging;
|
||||||
private bool successfullyLoaded;
|
private bool successfullyLoaded;
|
||||||
|
|
||||||
public ScriptPlugin(string fileName)
|
public ScriptPlugin(string filename)
|
||||||
{
|
{
|
||||||
FileName = fileName;
|
_fileName = filename;
|
||||||
_fileChanging = new SemaphoreSlim(1, 1);
|
Watcher = new FileSystemWatcher()
|
||||||
_watcher = new FileSystemWatcher()
|
|
||||||
{
|
{
|
||||||
Path = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}",
|
Path = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}",
|
||||||
NotifyFilter = NotifyFilters.Size,
|
NotifyFilter = NotifyFilters.Size,
|
||||||
Filter = fileName.Split(Path.DirectorySeparatorChar).Last()
|
Filter = _fileName.Split(Path.DirectorySeparatorChar).Last()
|
||||||
};
|
};
|
||||||
|
|
||||||
_watcher.Changed += Watcher_Changed;
|
Watcher.EnableRaisingEvents = true;
|
||||||
_watcher.EnableRaisingEvents = true;
|
_fileChanging = new SemaphoreSlim(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScriptPlugin()
|
~ScriptPlugin()
|
||||||
{
|
{
|
||||||
_watcher.Dispose();
|
Watcher.Dispose();
|
||||||
_fileChanging.Dispose();
|
_fileChanging.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Watcher_Changed(object sender, FileSystemEventArgs e)
|
|
||||||
|
public async Task Initialize(IManager manager)
|
||||||
{
|
{
|
||||||
|
await _fileChanging.WaitAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _fileChanging.WaitAsync();
|
// for some reason we get an event trigger when the file is not finished being modified.
|
||||||
await Initialize(Manager);
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
dynamic pluginObject = ScriptEngine.GetValue("plugin").ToObject();
|
||||||
|
|
||||||
|
Author = pluginObject.author;
|
||||||
|
Name = pluginObject.name;
|
||||||
|
Version = (float)pluginObject.version;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pluginObject.isParser)
|
||||||
|
{
|
||||||
|
await OnLoadAsync(manager);
|
||||||
|
IEventParser eventParser = (IEventParser)ScriptEngine.GetValue("eventParser").ToObject();
|
||||||
|
IRConParser rconParser = (IRConParser)ScriptEngine.GetValue("rconParser").ToObject();
|
||||||
|
manager.AdditionalEventParsers.Add(eventParser);
|
||||||
|
manager.AdditionalRConParsers.Add(rconParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
|
||||||
|
if (!firstRun)
|
||||||
|
{
|
||||||
|
await OnLoadAsync(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
successfullyLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Manager.GetLogger(0).WriteError(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_IMPORTER_ERROR"].FormatExt(Name));
|
throw;
|
||||||
Manager.GetLogger(0).WriteDebug(ex.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
@ -69,104 +133,20 @@ namespace SharedLibraryCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Initialize(IManager mgr)
|
|
||||||
{
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
successfullyLoaded = false;
|
|
||||||
Manager = mgr;
|
|
||||||
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);
|
|
||||||
dynamic pluginObject = ScriptEngine.GetValue("plugin").ToObject();
|
|
||||||
|
|
||||||
Author = pluginObject.author;
|
|
||||||
Name = pluginObject.name;
|
|
||||||
Version = (float)pluginObject.version;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(pluginObject.isParser)
|
|
||||||
{
|
|
||||||
await OnLoadAsync(mgr);
|
|
||||||
IEventParser eventParser = (IEventParser)ScriptEngine.GetValue("eventParser").ToObject();
|
|
||||||
IRConParser rconParser = (IRConParser)ScriptEngine.GetValue("rconParser").ToObject();
|
|
||||||
Manager.AdditionalEventParsers.Add(eventParser);
|
|
||||||
Manager.AdditionalRConParsers.Add(rconParser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
|
|
||||||
if (!firstRun)
|
|
||||||
{
|
|
||||||
await OnLoadAsync(mgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
successfullyLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task OnEventAsync(GameEvent E, Server S)
|
public async Task OnEventAsync(GameEvent E, Server S)
|
||||||
{
|
{
|
||||||
if (successfullyLoaded)
|
if (successfullyLoaded)
|
||||||
{
|
{
|
||||||
try
|
ScriptEngine.SetValue("_gameEvent", E);
|
||||||
{
|
ScriptEngine.SetValue("_server", S);
|
||||||
await _fileChanging.WaitAsync();
|
ScriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(S));
|
||||||
ScriptEngine.SetValue("_gameEvent", E);
|
await Task.FromResult(ScriptEngine.Execute("plugin.onEventAsync(_gameEvent, _server)").GetCompletionValue());
|
||||||
ScriptEngine.SetValue("_server", S);
|
|
||||||
ScriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(S));
|
|
||||||
ScriptEngine.Execute("plugin.onEventAsync(_gameEvent, _server)").GetCompletionValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (_fileChanging.CurrentCount == 0)
|
|
||||||
{
|
|
||||||
_fileChanging.Release(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task OnLoadAsync(IManager manager)
|
public Task OnLoadAsync(IManager manager)
|
||||||
{
|
{
|
||||||
Manager.GetLogger(0).WriteDebug($"OnLoad executing for {Name}");
|
manager.GetLogger(0).WriteDebug($"OnLoad executing for {Name}");
|
||||||
ScriptEngine.SetValue("_manager", manager);
|
ScriptEngine.SetValue("_manager", manager);
|
||||||
return Task.FromResult(ScriptEngine.Execute("plugin.onLoadAsync(_manager)").GetCompletionValue());
|
return Task.FromResult(ScriptEngine.Execute("plugin.onLoadAsync(_manager)").GetCompletionValue());
|
||||||
}
|
}
|
||||||
@ -181,7 +161,6 @@ namespace SharedLibraryCore
|
|||||||
{
|
{
|
||||||
if (successfullyLoaded)
|
if (successfullyLoaded)
|
||||||
{
|
{
|
||||||
Manager.GetLogger(0).WriteDebug($"OnUnLoad executing for {Name}");
|
|
||||||
await Task.FromResult(ScriptEngine.Execute("plugin.onUnloadAsync()").GetCompletionValue());
|
await Task.FromResult(ScriptEngine.Execute("plugin.onUnloadAsync()").GetCompletionValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
if (s == null)
|
if (s == null)
|
||||||
{
|
{
|
||||||
return View("Error", "Invalid server!");
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverInfo = new ServerInfo()
|
var serverInfo = new ServerInfo()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user