1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-10 15:20:48 -05:00

Misc Qodana cleanups

This commit is contained in:
Amos
2024-07-02 23:05:47 +01:00
committed by Ayymoss
parent e94a0ae691
commit f2b273b878
13 changed files with 150 additions and 154 deletions

View File

@ -47,7 +47,10 @@ namespace IW4MAdmin.Application
{ {
private readonly ConcurrentBag<Server> _servers; private readonly ConcurrentBag<Server> _servers;
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList(); public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
[Obsolete] public ObsoleteLogger Logger => _serviceProvider.GetRequiredService<ObsoleteLogger>();
[Obsolete("Use Microsoft.Extensions.Logging.ILogger instead")]
public ObsoleteLogger Logger => _serviceProvider.GetRequiredService<ObsoleteLogger>(); // TODO: Deprecate this.
public bool IsRunning { get; private set; } public bool IsRunning { get; private set; }
public bool IsInitialized { get; private set; } public bool IsInitialized { get; private set; }
public DateTime StartTime { get; private set; } public DateTime StartTime { get; private set; }
@ -55,6 +58,7 @@ namespace IW4MAdmin.Application
public IList<IRConParser> AdditionalRConParsers { get; } public IList<IRConParser> AdditionalRConParsers { get; }
public IList<IEventParser> AdditionalEventParsers { get; } public IList<IEventParser> AdditionalEventParsers { get; }
public IList<Func<GameEvent, bool>> CommandInterceptors { get; set; } = public IList<Func<GameEvent, bool>> CommandInterceptors { get; set; } =
new List<Func<GameEvent, bool>>(); new List<Func<GameEvent, bool>>();
public ITokenAuthentication TokenAuthenticator { get; } public ITokenAuthentication TokenAuthenticator { get; }
@ -90,13 +94,15 @@ namespace IW4MAdmin.Application
private readonly ApplicationConfiguration _appConfig; private readonly ApplicationConfiguration _appConfig;
public ConcurrentDictionary<long, GameEvent> ProcessingEvents { get; } = new(); public ConcurrentDictionary<long, GameEvent> ProcessingEvents { get; } = new();
public ApplicationManager(ILogger<ApplicationManager> logger, IMiddlewareActionHandler actionHandler, IEnumerable<IManagerCommand> commands, public ApplicationManager(ILogger<ApplicationManager> logger, IMiddlewareActionHandler actionHandler,
IEnumerable<IManagerCommand> commands,
ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration, ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration,
IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory, IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory,
IEnumerable<IPlugin> plugins, IParserRegexFactory parserRegexFactory, IEnumerable<IRegisterEvent> customParserEvents, IEnumerable<IPlugin> plugins, IParserRegexFactory parserRegexFactory, IEnumerable<IRegisterEvent> customParserEvents,
ICoreEventHandler coreEventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory, ICoreEventHandler coreEventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory,
IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver, ClientService clientService, IServiceProvider serviceProvider, IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver, ClientService clientService,
ChangeHistoryService changeHistoryService, ApplicationConfiguration appConfig, PenaltyService penaltyService, IAlertManager alertManager, IInteractionRegistration interactionRegistration, IEnumerable<IPluginV2> v2PLugins, IServiceProvider serviceProvider, ChangeHistoryService changeHistoryService, ApplicationConfiguration appConfig, PenaltyService penaltyService,
IAlertManager alertManager, IInteractionRegistration interactionRegistration, IEnumerable<IPluginV2> v2PLugins,
ConfigurationWatcher watcher) ConfigurationWatcher watcher)
{ {
MiddlewareActionHandler = actionHandler; MiddlewareActionHandler = actionHandler;
@ -302,22 +308,28 @@ namespace IW4MAdmin.Application
ExternalIPAddress = await Utilities.GetExternalIP(); ExternalIPAddress = await Utilities.GetExternalIP();
#region DATABASE #region DATABASE
_logger.LogInformation("Beginning database migration sync"); _logger.LogInformation("Beginning database migration sync");
Console.WriteLine(_translationLookup["MANAGER_MIGRATION_START"]); Console.WriteLine(_translationLookup["MANAGER_MIGRATION_START"]);
await ContextSeed.Seed(_serviceProvider.GetRequiredService<IDatabaseContextFactory>(), _isRunningTokenSource.Token); await ContextSeed.Seed(_serviceProvider.GetRequiredService<IDatabaseContextFactory>(), _isRunningTokenSource.Token);
await DatabaseHousekeeping.RemoveOldRatings(_serviceProvider.GetRequiredService<IDatabaseContextFactory>(), _isRunningTokenSource.Token); await DatabaseHousekeeping.RemoveOldRatings(_serviceProvider.GetRequiredService<IDatabaseContextFactory>(),
_isRunningTokenSource.Token);
_logger.LogInformation("Finished database migration sync"); _logger.LogInformation("Finished database migration sync");
Console.WriteLine(_translationLookup["MANAGER_MIGRATION_END"]); Console.WriteLine(_translationLookup["MANAGER_MIGRATION_END"]);
#endregion #endregion
#region EVENTS #region EVENTS
IGameServerEventSubscriptions.ServerValueRequested += OnServerValueRequested; IGameServerEventSubscriptions.ServerValueRequested += OnServerValueRequested;
IGameServerEventSubscriptions.ServerValueSetRequested += OnServerValueSetRequested; IGameServerEventSubscriptions.ServerValueSetRequested += OnServerValueSetRequested;
IGameServerEventSubscriptions.ServerCommandExecuteRequested += OnServerCommandExecuteRequested; IGameServerEventSubscriptions.ServerCommandExecuteRequested += OnServerCommandExecuteRequested;
await IManagementEventSubscriptions.InvokeLoadAsync(this, CancellationToken); await IManagementEventSubscriptions.InvokeLoadAsync(this, CancellationToken);
# endregion # endregion
#region PLUGINS #region PLUGINS
foreach (var plugin in Plugins) foreach (var plugin in Plugins)
{ {
try try
@ -336,7 +348,8 @@ namespace IW4MAdmin.Application
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_IMPORTER_ERROR"].FormatExt(scriptPlugin.Name)); Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_IMPORTER_ERROR"]
.FormatExt(scriptPlugin.Name));
_logger.LogError(ex, "Could not properly load plugin {plugin}", scriptPlugin.Name); _logger.LogError(ex, "Could not properly load plugin {plugin}", scriptPlugin.Name);
} }
}; };
@ -353,9 +366,11 @@ namespace IW4MAdmin.Application
_logger.LogError(ex, $"{_translationLookup["SERVER_ERROR_PLUGIN"]} {plugin.Name}"); _logger.LogError(ex, $"{_translationLookup["SERVER_ERROR_PLUGIN"]} {plugin.Name}");
} }
} }
#endregion #endregion
#region CONFIG #region CONFIG
// copy over default config if it doesn't exist // copy over default config if it doesn't exist
if (!_appConfig.Servers?.Any() ?? true) if (!_appConfig.Servers?.Any() ?? true)
{ {
@ -385,8 +400,9 @@ namespace IW4MAdmin.Application
serverConfig.AddEventParser(parser); serverConfig.AddEventParser(parser);
} }
_appConfig.Servers = _appConfig.Servers.Where(_servers => _servers != null).Append((ServerConfiguration)serverConfig.Generate()).ToArray(); _appConfig.Servers = _appConfig.Servers.Where(_servers => _servers != null)
} while (Utilities.PromptBool(_translationLookup["SETUP_SERVER_SAVE"])); .Append((ServerConfiguration)serverConfig.Generate()).ToArray();
} while (_translationLookup["SETUP_SERVER_SAVE"].PromptBool());
await ConfigHandler.Save(); await ConfigHandler.Save();
} }
@ -447,6 +463,7 @@ namespace IW4MAdmin.Application
serverConfig.ModifyParsers(); serverConfig.ModifyParsers();
} }
} }
await ConfigHandler.Save(); await ConfigHandler.Save();
} }
@ -456,7 +473,9 @@ namespace IW4MAdmin.Application
} }
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(_appConfig.CustomParserEncoding) ? _appConfig.CustomParserEncoding : "windows-1252"); Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(_appConfig.CustomParserEncoding)
? _appConfig.CustomParserEncoding
: "windows-1252");
foreach (var parser in AdditionalRConParsers) foreach (var parser in AdditionalRConParsers)
{ {
@ -472,6 +491,7 @@ namespace IW4MAdmin.Application
#endregion #endregion
#region COMMANDS #region COMMANDS
if (await ClientSvc.HasOwnerAsync(_isRunningTokenSource.Token)) if (await ClientSvc.HasOwnerAsync(_isRunningTokenSource.Token))
{ {
_commands.RemoveAll(_cmd => _cmd.GetType() == typeof(OwnerCommand)); _commands.RemoveAll(_cmd => _cmd.GetType() == typeof(OwnerCommand));
@ -503,6 +523,7 @@ namespace IW4MAdmin.Application
{ {
continue; continue;
} }
cmdConfig.Commands.Add(cmd.CommandConfigNameForType(), cmdConfig.Commands.Add(cmd.CommandConfigNameForType(),
new CommandProperties new CommandProperties
{ {
@ -516,12 +537,14 @@ namespace IW4MAdmin.Application
_commandConfiguration.Set(cmdConfig); _commandConfiguration.Set(cmdConfig);
await _commandConfiguration.Save(); await _commandConfiguration.Save();
#endregion #endregion
_metaRegistration.Register(); _metaRegistration.Register();
await _alertManager.Initialize(); await _alertManager.Initialize();
#region CUSTOM_EVENTS #region CUSTOM_EVENTS
foreach (var customEvent in _customParserEvents.SelectMany(_events => _events.Events)) foreach (var customEvent in _customParserEvents.SelectMany(_events => _events.Events))
{ {
foreach (var parser in AdditionalEventParsers) foreach (var parser in AdditionalEventParsers)
@ -529,6 +552,7 @@ namespace IW4MAdmin.Application
parser.RegisterCustomEvent(customEvent.Item1, customEvent.Item2, customEvent.Item3); parser.RegisterCustomEvent(customEvent.Item1, customEvent.Item2, customEvent.Item3);
} }
} }
#endregion #endregion
Console.WriteLine(_translationLookup["MANAGER_COMMUNICATION_INFO"]); Console.WriteLine(_translationLookup["MANAGER_COMMUNICATION_INFO"]);
@ -540,22 +564,40 @@ namespace IW4MAdmin.Application
private async Task InitializeServers() private async Task InitializeServers()
{ {
var config = ConfigHandler.Configuration(); var config = ConfigHandler.Configuration();
int successServers = 0; var successServers = 0;
Exception lastException = null; Exception lastException = null;
async Task Init(ServerConfiguration Conf) await Task.WhenAll(config.Servers.Select(LocalInit).ToArray());
if (successServers == 0)
{
throw lastException;
}
if (successServers != config.Servers.Length && !AppContext.TryGetSwitch("NoConfirmPrompt", out _))
{
if (!Utilities.CurrentLocalization.LocalizationIndex["MANAGER_START_WITH_ERRORS"].PromptBool())
{
throw lastException;
}
}
return;
async Task LocalInit(ServerConfiguration conf)
{ {
try try
{ {
// todo: this might not always be an IW4MServer // todo: this might not always be an IW4MServer
var serverInstance = _serverInstanceFactory.CreateServer(Conf, this) as IW4MServer; var serverInstance = _serverInstanceFactory.CreateServer(conf, this) as IW4MServer;
using (LogContext.PushProperty("Server", serverInstance!.ToString())) using (LogContext.PushProperty("Server", serverInstance!.ToString()))
{ {
_logger.LogInformation("Beginning server communication initialization"); _logger.LogInformation("Beginning server communication initialization");
await serverInstance.Initialize(); await serverInstance.Initialize();
_servers.Add(serverInstance); _servers.Add(serverInstance);
Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_MONITORING_TEXT"].FormatExt(serverInstance.Hostname.StripColors())); Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_MONITORING_TEXT"]
.FormatExt(serverInstance.Hostname.StripColors()));
_logger.LogInformation("Finishing initialization and now monitoring [{Server}]", serverInstance.Hostname); _logger.LogInformation("Finishing initialization and now monitoring [{Server}]", serverInstance.Hostname);
} }
@ -570,46 +612,30 @@ namespace IW4MAdmin.Application
catch (ServerException e) catch (ServerException e)
{ {
Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_UNFIXABLE"].FormatExt($"[{Conf.IPAddress}:{Conf.Port}]")); Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_UNFIXABLE"]
using (LogContext.PushProperty("Server", $"{Conf.IPAddress}:{Conf.Port}")) .FormatExt($"[{conf.IPAddress}:{conf.Port}]"));
using (LogContext.PushProperty("Server", $"{conf.IPAddress}:{conf.Port}"))
{ {
_logger.LogError(e, "Unexpected exception occurred during initialization"); _logger.LogError(e, "Unexpected exception occurred during initialization");
} }
lastException = e; lastException = e;
} }
} }
await Task.WhenAll(config.Servers.Select(c => Init(c)).ToArray());
if (successServers == 0)
{
throw lastException;
}
if (successServers != config.Servers.Length && !AppContext.TryGetSwitch("NoConfirmPrompt", out _))
{
if (!Utilities.CurrentLocalization.LocalizationIndex["MANAGER_START_WITH_ERRORS"].PromptBool())
{
throw lastException;
}
}
} }
public async Task Start() public async Task Start()
{ {
_eventHandlerTokenSource = new CancellationTokenSource(); _eventHandlerTokenSource = new CancellationTokenSource();
var eventHandlerThread = new Thread(() => var eventHandlerThread = new Thread(() => { _coreEventHandler.StartProcessing(_eventHandlerTokenSource.Token); })
{
_coreEventHandler.StartProcessing(_eventHandlerTokenSource.Token);
})
{ {
Name = nameof(CoreEventHandler) Name = nameof(CoreEventHandler)
}; };
eventHandlerThread.Start(); eventHandlerThread.Start();
await UpdateServerStates(); await UpdateServerStates();
_eventHandlerTokenSource.Cancel(); await _eventHandlerTokenSource.CancelAsync();
eventHandlerThread.Join(); eventHandlerThread.Join();
} }
@ -670,10 +696,10 @@ namespace IW4MAdmin.Application
return _servers.SelectMany(s => s.Clients).ToList().Where(p => p != null).ToList(); return _servers.SelectMany(s => s.Clients).ToList().Where(p => p != null).ToList();
} }
public EFClient FindActiveClient(EFClient client) => client.ClientNumber < 0 ? public EFClient FindActiveClient(EFClient client) => client.ClientNumber < 0
GetActiveClients() ? GetActiveClients()
.FirstOrDefault(c => c.NetworkId == client.NetworkId && c.GameName == client.GameName) ?? client : .FirstOrDefault(c => c.NetworkId == client.NetworkId && c.GameName == client.GameName) ?? client
client; : client;
public ClientService GetClientService() public ClientService GetClientService()
{ {
@ -715,7 +741,8 @@ namespace IW4MAdmin.Application
public IEventParser GenerateDynamicEventParser(string name) public IEventParser GenerateDynamicEventParser(string name)
{ {
return new DynamicEventParser(_parserRegexFactory, _logger, ConfigHandler.Configuration(), _serviceProvider.GetRequiredService<IGameScriptEventFactory>()) return new DynamicEventParser(_parserRegexFactory, _logger, ConfigHandler.Configuration(),
_serviceProvider.GetRequiredService<IGameScriptEventFactory>())
{ {
Name = name Name = name
}; };

View File

@ -22,16 +22,14 @@ namespace IW4MAdmin.Application.Commands
RequiresTarget = false; RequiresTarget = false;
} }
public override Task ExecuteAsync(GameEvent gameEvent) public override async Task ExecuteAsync(GameEvent gameEvent)
{ {
var clientList = gameEvent.Owner.GetClientsAsList() var clientList = gameEvent.Owner.GetClientsAsList()
.Select(client => .Select(client =>
$"[(Color::Accent){client.ClientPermission.Name}(Color::White){(string.IsNullOrEmpty(client.Tag) ? "" : $" {client.Tag}")}(Color::White)][(Color::Yellow)#{client.ClientNumber}(Color::White)] {client.Name}") $"[(Color::Accent){client.ClientPermission.Name}(Color::White){(string.IsNullOrEmpty(client.Tag) ? "" : $" {client.Tag}")}(Color::White)][(Color::Yellow)#{client.ClientNumber}(Color::White)] {client.Name}")
.ToArray(); .ToArray();
gameEvent.Origin.TellAsync(clientList, gameEvent.Owner.Manager.CancellationToken); await gameEvent.Origin.TellAsync(clientList, gameEvent.Owner.Manager.CancellationToken);
return Task.CompletedTask;
} }
} }
} }

View File

@ -11,26 +11,15 @@ namespace IW4MAdmin.Application.Factories
/// <summary> /// <summary>
/// implementation of IGameServerInstanceFactory /// implementation of IGameServerInstanceFactory
/// </summary> /// </summary>
internal class GameServerInstanceFactory : IGameServerInstanceFactory
{
private readonly ITranslationLookup _translationLookup;
private readonly IMetaServiceV2 _metaService;
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// base constructor
/// </summary>
/// <param name="translationLookup"></param> /// <param name="translationLookup"></param>
/// <param name="rconConnectionFactory"></param> /// <param name="metaService"></param>
public GameServerInstanceFactory(ITranslationLookup translationLookup, /// <param name="serviceProvider"></param>
internal class GameServerInstanceFactory(
ITranslationLookup translationLookup,
IMetaServiceV2 metaService, IMetaServiceV2 metaService,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: IGameServerInstanceFactory
{ {
_translationLookup = translationLookup;
_metaService = metaService;
_serviceProvider = serviceProvider;
}
/// <summary> /// <summary>
/// creates an IW4MServer instance /// creates an IW4MServer instance
/// </summary> /// </summary>
@ -40,9 +29,9 @@ namespace IW4MAdmin.Application.Factories
public Server CreateServer(ServerConfiguration config, IManager manager) public Server CreateServer(ServerConfiguration config, IManager manager)
{ {
return new IW4MServer(config, return new IW4MServer(config,
_serviceProvider.GetRequiredService<CommandConfiguration>(), _translationLookup, _metaService, serviceProvider.GetRequiredService<CommandConfiguration>(), translationLookup, metaService,
_serviceProvider, _serviceProvider.GetRequiredService<IClientNoticeMessageFormatter>(), serviceProvider, serviceProvider.GetRequiredService<IClientNoticeMessageFormatter>(),
_serviceProvider.GetRequiredService<ILookupCache<EFServer>>()); serviceProvider.GetRequiredService<ILookupCache<EFServer>>());
} }
} }
} }

View File

@ -227,8 +227,8 @@ namespace IW4MAdmin.Application
logger.LogDebug(continuation.Exception, "Unable to start webfront task"); logger.LogDebug(continuation.Exception, "Unable to start webfront task");
onWebfrontErrored.Set(); // ReSharper disable once AccessToDisposedClosure
onWebfrontErrored.Set(); // TODO: Check if this dispose warning is a roslyn issue.
}) })
: Task.CompletedTask; : Task.CompletedTask;

View File

@ -52,14 +52,11 @@ namespace IW4MAdmin.Application.Misc
await _onSaving.WaitAsync(); await _onSaving.WaitAsync();
await using var fileStream = File.OpenRead(FileName); await using var fileStream = File.OpenRead(FileName);
_configuration = await JsonSerializer.DeserializeAsync<T>(fileStream, _serializerOptions); _configuration = await JsonSerializer.DeserializeAsync<T>(fileStream, _serializerOptions);
await fileStream.DisposeAsync();
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
_configuration = default; _configuration = default;
} }
catch (Exception e) catch (Exception e)
{ {
throw new ConfigurationException("Could not load configuration") throw new ConfigurationException("Could not load configuration")
@ -82,12 +79,9 @@ namespace IW4MAdmin.Application.Misc
try try
{ {
await _onSaving.WaitAsync(); await _onSaving.WaitAsync();
await using var fileStream = File.Create(FileName); await using var fileStream = File.Create(FileName);
await JsonSerializer.SerializeAsync(fileStream, _configuration, _serializerOptions); await JsonSerializer.SerializeAsync(fileStream, _configuration, _serializerOptions);
await fileStream.DisposeAsync();
} }
finally finally
{ {
if (_onSaving.CurrentCount == 0) if (_onSaving.CurrentCount == 0)

View File

@ -4,7 +4,7 @@ using ILogger = SharedLibraryCore.Interfaces.ILogger;
namespace IW4MAdmin.Application.Misc namespace IW4MAdmin.Application.Misc
{ {
[Obsolete] [Obsolete("Use Microsoft.Extensions.Logging.ILogger instead")]
public class Logger : ILogger public class Logger : ILogger
{ {
private readonly Microsoft.Extensions.Logging.ILogger _logger; private readonly Microsoft.Extensions.Logging.ILogger _logger;

View File

@ -7,16 +7,10 @@ using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace IW4MAdmin.Application.Misc namespace IW4MAdmin.Application.Misc
{ {
class MiddlewareActionHandler : IMiddlewareActionHandler internal class MiddlewareActionHandler(ILogger<MiddlewareActionHandler> logger) : IMiddlewareActionHandler
{ {
private readonly IDictionary<string, IList<object>> _actions; private readonly Dictionary<string, IList<object>> _actions = new();
private readonly ILogger _logger; private readonly ILogger _logger = logger;
public MiddlewareActionHandler(ILogger<MiddlewareActionHandler> logger)
{
_actions = new Dictionary<string, IList<object>>();
_logger = logger;
}
/// <summary> /// <summary>
/// Executes the action with the given name /// Executes the action with the given name
@ -27,11 +21,10 @@ namespace IW4MAdmin.Application.Misc
/// <returns></returns> /// <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; var key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name;
if (_actions.ContainsKey(key)) if (!_actions.TryGetValue(key, out var action1)) return value;
{ foreach (var action in action1)
foreach (var action in _actions[key])
{ {
try try
{ {
@ -39,16 +32,13 @@ namespace IW4MAdmin.Application.Misc
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogWarning(e, "Failed to invoke middleware action {name}", name); _logger.LogWarning(e, "Failed to invoke middleware action {Name}", name);
} }
} }
return value; return value;
} }
return value;
}
/// <summary> /// <summary>
/// Registers an action by name /// Registers an action by name
/// </summary> /// </summary>
@ -58,16 +48,15 @@ namespace IW4MAdmin.Application.Misc
/// <param name="name">Name of action</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; var key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name;
if (_actions.ContainsKey(key)) if (_actions.TryGetValue(key, out var action1))
{ {
_actions[key].Add(action); action1.Add(action);
} }
else else
{ {
_actions.Add(key, new[] { action }); _actions.Add(key, [action]);
} }
} }
} }

View File

@ -201,7 +201,7 @@ namespace Integrations.Cod
DontFragment = false, DontFragment = false,
Ttl = 100, Ttl = 100,
ExclusiveAddressUse = true, ExclusiveAddressUse = true,
}) }!) // Suppressing "Initialize object properties inside the 'using' statement to ensure that the object is disposed if an exception is thrown during initialization"
{ {
if (!token.IsCancellationRequested) if (!token.IsCancellationRequested)
{ {

View File

@ -107,9 +107,7 @@ namespace SharedLibraryCore.Helpers
private static int ParseVersion(string input) private static int ParseVersion(string input)
{ {
int version; if (!int.TryParse(input, out var version))
if (!int.TryParse(input, out version))
{ {
throw new FormatException( throw new FormatException(
"buildNumber string was not in a correct format"); "buildNumber string was not in a correct format");

View File

@ -2,7 +2,7 @@
namespace SharedLibraryCore.Interfaces namespace SharedLibraryCore.Interfaces
{ {
[Obsolete] [Obsolete("Use Microsoft.Extensions.Logging.ILogger instead")]
public interface ILogger public interface ILogger
{ {
void WriteVerbose(string msg); void WriteVerbose(string msg);

View File

@ -799,6 +799,8 @@ namespace SharedLibraryCore
} }
public static async Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName, public static async Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName,
// Suppressing as older plugins could reference old signature.
// ReSharper disable once MethodOverloadWithOptionalParameter
T fallbackValue = default, CancellationToken token = default) T fallbackValue = default, CancellationToken token = default)
{ {
return await server.RconParser.GetDvarAsync(server.RemoteConnection, dvarName, fallbackValue, token); return await server.RconParser.GetDvarAsync(server.RemoteConnection, dvarName, fallbackValue, token);
@ -818,9 +820,8 @@ namespace SharedLibraryCore
var mappedKey = server.RconParser.GetOverrideDvarName(dvarName); var mappedKey = server.RconParser.GetOverrideDvarName(dvarName);
var defaultValue = server.RconParser.GetDefaultDvarValue<T>(mappedKey) ?? overrideDefault; var defaultValue = server.RconParser.GetDefaultDvarValue<T>(mappedKey) ?? overrideDefault;
var foundKey = infoResponse?.Keys var foundKey = (infoResponse?.Keys ?? Enumerable.Empty<string>())
.Where(_key => new[] { mappedKey, dvarName, infoResponseName ?? dvarName }.Contains(_key)) .FirstOrDefault(key => new[] { mappedKey, dvarName, infoResponseName ?? dvarName }.Contains(key));
.FirstOrDefault();
if (!string.IsNullOrEmpty(foundKey)) if (!string.IsNullOrEmpty(foundKey))
{ {

View File

@ -129,7 +129,7 @@
.OrderBy(rating => rating.CreatedDateTime) .OrderBy(rating => rating.CreatedDateTime)
.Select(rating => new PerformanceHistory { Performance = rating.PerformanceMetric, OccurredAt = rating.CreatedDateTime }); .Select(rating => new PerformanceHistory { Performance = rating.PerformanceMetric, OccurredAt = rating.CreatedDateTime });
if (performance != null && performance != Model.Ratings.FirstOrDefault().PerformanceMetric) if (performance != null && !Model.Ratings.FirstOrDefault().PerformanceMetric.Equals(performance))
{ {
performanceHistory = performanceHistory.Append(new PerformanceHistory { Performance = performance.Value, OccurredAt = Model.Ratings.FirstOrDefault()?.CreatedDateTime ?? DateTime.UtcNow }); performanceHistory = performanceHistory.Append(new PerformanceHistory { Performance = performance.Value, OccurredAt = Model.Ratings.FirstOrDefault()?.CreatedDateTime ?? DateTime.UtcNow });
} }

View File

@ -89,7 +89,7 @@
else if (hasLinkedParent(property)) else if (hasLinkedParent(property))
{ {
<div id="@($"{property.Name}_content")" class="@(linkedPropertyNames.Length == 0 ? "hide" : "hide") bg-dark pl-3 pr-3 pb-2"> <div id="@($"{property.Name}_content")" class="hide bg-dark pl-3 pr-3 pb-2">
@if (linkedPropertyNames.Length == 0) @if (linkedPropertyNames.Length == 0)
{ {
@Html.Label(property.Name, null, new {@class = "mt-2 d-block"}) @Html.Label(property.Name, null, new {@class = "mt-2 d-block"})