Merge pull request #97 from RaidMax/bugfix/issue-95-fix-restart-command

Bugfix/issue 95 fix restart command
This commit is contained in:
RaidMax 2020-01-14 18:59:22 -06:00 committed by GitHub
commit 01198b66ea
7 changed files with 76 additions and 39 deletions

View File

@ -42,8 +42,7 @@ namespace IW4MAdmin.Application
public CancellationToken CancellationToken => _tokenSource.Token; public CancellationToken CancellationToken => _tokenSource.Token;
public string ExternalIPAddress { get; private set; } public string ExternalIPAddress { get; private set; }
public bool IsRestartRequested { get; private set; } public bool IsRestartRequested { get; private set; }
public IMiddlewareActionHandler MiddlewareActionHandler { get; private set; } = new MiddlewareActionHandler(); public IMiddlewareActionHandler MiddlewareActionHandler { get; }
static ApplicationManager Instance;
private readonly List<Command> Commands; private readonly List<Command> Commands;
private readonly List<MessageToken> MessageTokens; private readonly List<MessageToken> MessageTokens;
private readonly ClientService ClientSvc; private readonly ClientService ClientSvc;
@ -52,14 +51,15 @@ namespace IW4MAdmin.Application
public BaseConfigurationHandler<ApplicationConfiguration> ConfigHandler; public BaseConfigurationHandler<ApplicationConfiguration> ConfigHandler;
GameEventHandler Handler; GameEventHandler Handler;
readonly IPageList PageList; readonly IPageList PageList;
readonly Dictionary<long, ILogger> Loggers = new Dictionary<long, ILogger>(); private readonly Dictionary<long, ILogger> _loggers = new Dictionary<long, ILogger>();
private readonly MetaService _metaService; private readonly MetaService _metaService;
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0); private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
private readonly CancellationTokenSource _tokenSource; private readonly CancellationTokenSource _tokenSource;
private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>(); private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>();
private ApplicationManager() public ApplicationManager(ILogger logger, IMiddlewareActionHandler actionHandler)
{ {
MiddlewareActionHandler = actionHandler;
_servers = new ConcurrentBag<Server>(); _servers = new ConcurrentBag<Server>();
Commands = new List<Command>(); Commands = new List<Command>();
MessageTokens = new List<MessageToken>(); MessageTokens = new List<MessageToken>();
@ -74,6 +74,7 @@ namespace IW4MAdmin.Application
TokenAuthenticator = new TokenAuthentication(); TokenAuthenticator = new TokenAuthentication();
_metaService = new MetaService(); _metaService = new MetaService();
_tokenSource = new CancellationTokenSource(); _tokenSource = new CancellationTokenSource();
_loggers.Add(0, logger);
} }
public async Task ExecuteEvent(GameEvent newEvent) public async Task ExecuteEvent(GameEvent newEvent)
@ -156,11 +157,6 @@ namespace IW4MAdmin.Application
return Commands; return Commands;
} }
public static ApplicationManager GetInstance()
{
return Instance ?? (Instance = new ApplicationManager());
}
public async Task UpdateServerStates() public async Task UpdateServerStates()
{ {
// store the server hash code and task for it // store the server hash code and task for it
@ -681,7 +677,6 @@ namespace IW4MAdmin.Application
{ {
_tokenSource.Cancel(); _tokenSource.Cancel();
Running = false; Running = false;
Instance = null;
} }
public void Restart() public void Restart()
@ -692,25 +687,16 @@ namespace IW4MAdmin.Application
public ILogger GetLogger(long serverId) public ILogger GetLogger(long serverId)
{ {
if (Loggers.ContainsKey(serverId)) if (_loggers.ContainsKey(serverId))
{ {
return Loggers[serverId]; return _loggers[serverId];
} }
else else
{ {
Logger newLogger; var newLogger = new Logger($"IW4MAdmin-Server-{serverId}");
if (serverId == 0) _loggers.Add(serverId, newLogger);
{
newLogger = new Logger("IW4MAdmin-Manager");
}
else
{
newLogger = new Logger($"IW4MAdmin-Server-{serverId}");
}
Loggers.Add(serverId, newLogger);
return newLogger; return newLogger;
} }
} }

View File

@ -1,4 +1,5 @@
using IW4MAdmin.Application.Migration; using IW4MAdmin.Application.Migration;
using IW4MAdmin.Application.Misc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using SharedLibraryCore; using SharedLibraryCore;
using SharedLibraryCore.Helpers; using SharedLibraryCore.Helpers;
@ -60,7 +61,13 @@ namespace IW4MAdmin.Application
restart: restart:
try try
{ {
ServerManager = ApplicationManager.GetInstance(); var services = ConfigureServices();
using (var builder = services.BuildServiceProvider())
{
ServerManager = (ApplicationManager)builder.GetRequiredService<IManager>();
}
var configuration = ServerManager.GetApplicationSettings().Configuration(); var configuration = ServerManager.GetApplicationSettings().Configuration();
Localization.Configure.Initialize(configuration?.EnableCustomLocale ?? false ? (configuration.CustomLocale ?? "en-US") : "en-US"); Localization.Configure.Initialize(configuration?.EnableCustomLocale ?? false ? (configuration.CustomLocale ?? "en-US") : "en-US");
@ -70,7 +77,7 @@ namespace IW4MAdmin.Application
ServerManager.Logger.WriteInfo(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_VERSION"].FormatExt(Version)); ServerManager.Logger.WriteInfo(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_VERSION"].FormatExt(Version));
ConfigureServices();
await CheckVersion(); await CheckVersion();
await ServerManager.Init(); await ServerManager.Init();
} }
@ -235,12 +242,17 @@ namespace IW4MAdmin.Application
{ } { }
} }
private static void ConfigureServices() /// <summary>
/// Configures the dependency injection services
/// </summary>
private static IServiceCollection ConfigureServices()
{ {
var serviceProvider = new ServiceCollection(); var serviceProvider = new ServiceCollection();
serviceProvider.AddSingleton<IManager>(ServerManager); serviceProvider.AddSingleton<IManager, ApplicationManager>()
var builder = serviceProvider.BuildServiceProvider(); .AddSingleton<ILogger>(_serviceProvider => new Logger("IW4MAdmin-Manager"))
builder.Dispose(); .AddSingleton<IMiddlewareActionHandler, MiddlewareActionHandler>();
return serviceProvider;
} }
} }
} }

View File

@ -1,15 +1,29 @@
using SharedLibraryCore.Interfaces; using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace IW4MAdmin.Application.Misc namespace IW4MAdmin.Application.Misc
{ {
class MiddlewareActionHandler : IMiddlewareActionHandler class MiddlewareActionHandler : IMiddlewareActionHandler
{ {
private static readonly IDictionary<string, IList<object>> _actions = new Dictionary<string, IList<object>>(); private readonly IDictionary<string, IList<object>> _actions;
private readonly ILogger _logger;
public MiddlewareActionHandler(ILogger logger)
{
_actions = new Dictionary<string, IList<object>>();
_logger = logger;
}
/// <summary>
/// Executes the action with the given name
/// </summary>
/// <typeparam name="T">Execution return type</typeparam>
/// <param name="value">Input value</param>
/// <param name="name">Name of action to execute</param>
/// <returns></returns>
public async Task<T> Execute<T>(T value, string name = null) public async Task<T> Execute<T>(T value, string name = null)
{ {
string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name; string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name;
@ -22,8 +36,11 @@ namespace IW4MAdmin.Application.Misc
{ {
value = await ((IMiddlewareAction<T>)action).Invoke(value); value = await ((IMiddlewareAction<T>)action).Invoke(value);
} }
// todo: probably log this somewhere catch (Exception e)
catch { } {
_logger.WriteWarning($"Failed to invoke middleware action {name}");
_logger.WriteDebug(e.GetExceptionInfo());
}
} }
return value; return value;
@ -32,6 +49,13 @@ namespace IW4MAdmin.Application.Misc
return value; return value;
} }
/// <summary>
/// Registers an action by name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="actionType">Action type specifier</param>
/// <param name="action">Action to perform</param>
/// <param name="name">Name of action</param>
public void Register<T>(T actionType, IMiddlewareAction<T> action, string name = null) public void Register<T>(T actionType, IMiddlewareAction<T> action, string name = null)
{ {
string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name; string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name;

View File

@ -2,6 +2,7 @@
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibraryCore; using SharedLibraryCore;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration; using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models; using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Exceptions; using SharedLibraryCore.Exceptions;
@ -42,13 +43,16 @@ namespace IW4MAdmin.Plugins.Login
E.Origin.Level == EFClient.Permission.Console) E.Origin.Level == EFClient.Permission.Console)
return Task.CompletedTask; return Task.CompletedTask;
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name && if (((Command)E.Extra).Name == new CSetPassword().Name &&
E.Origin?.Password == null) E.Origin?.Password == null)
return Task.CompletedTask; return Task.CompletedTask;
if (((Command)E.Extra).Name == new Commands.CLogin().Name) if (((Command)E.Extra).Name == new Commands.CLogin().Name)
return Task.CompletedTask; return Task.CompletedTask;
if (E.Extra.GetType() == typeof(RequestTokenCommand))
return Task.CompletedTask;
if (!AuthorizedClients[E.Origin.ClientId]) if (!AuthorizedClients[E.Origin.ClientId])
{ {
throw new AuthorizationException(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_LOGIN_AUTH"]); throw new AuthorizationException(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_LOGIN_AUTH"]);

View File

@ -48,8 +48,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
public const int HighSampleMinKills = 100; public const int HighSampleMinKills = 100;
public const double KillTimeThreshold = 0.2; public const double KillTimeThreshold = 0.2;
public const int LowSampleMinKillsRecoil = 5; public const int LowSampleMinKillsRecoil = 5;
public const double SnapFlagValue = 5.5; public const double SnapFlagValue = 7.6;
public const double SnapBanValue = 8.7; public const double SnapBanValue = 11.7;
public const double MaxStrainBan = 0.9; public const double MaxStrainBan = 0.9;

View File

@ -20,7 +20,7 @@ namespace Tests
File.WriteAllText(logFile, Environment.NewLine); File.WriteAllText(logFile, Environment.NewLine);
Manager = ApplicationManager.GetInstance(); Manager = null;
var config = new ApplicationConfiguration var config = new ApplicationConfiguration
{ {

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -8,6 +9,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SharedLibraryCore.Database; using SharedLibraryCore.Database;
using SharedLibraryCore.Interfaces; using SharedLibraryCore.Interfaces;
using System.Net;
using System.Threading.Tasks;
using WebfrontCore.Middleware; using WebfrontCore.Middleware;
namespace WebfrontCore namespace WebfrontCore
@ -95,7 +98,15 @@ namespace WebfrontCore
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{ {
app.UseStatusCodePagesWithRedirects("/Home/ResponseStatusCode?statusCode={0}"); app.UseStatusCodePages(_context =>
{
if (_context.HttpContext.Response.StatusCode == (int)HttpStatusCode.NotFound)
{
_context.HttpContext.Response.Redirect($"/Home/ResponseStatusCode?statusCode={_context.HttpContext.Response.StatusCode}");
}
return Task.CompletedTask;
});
if (env.EnvironmentName == "Development") if (env.EnvironmentName == "Development")
{ {